1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-25 02:09:48 +01:00

Merge remote-tracking branch 'origin' into phonon

This commit is contained in:
Christian Muehlhaeuser 2011-03-14 00:21:17 +01:00
commit a91d0b3ea7
59 changed files with 607 additions and 310 deletions

View File

@ -44,6 +44,8 @@ macro_log_feature(QJSON_FOUND "QJson" "Qt library that maps JSON data to QVarian
macro_optional_find_package(Taglib 1.6.0)
macro_log_feature(TAGLIB_FOUND "TagLib" "Audio Meta-Data Library" "http://developer.kde.org/~wheeler/taglib.html" TRUE "" "taglib is needed for reading meta data from audio files")
# we need pthreads too
find_package(Threads)
FIND_PACKAGE( Taglib 1.6.0 REQUIRED )
include( CheckTagLibFileName )
@ -64,6 +66,10 @@ IF( ENABLE_JREEN AND NOT LIBJREEN_FOUND )
MESSAGE(STATUS "Internal libjreen: ${LIBJREEN_INCLUDE_DIR}, ${LIBJREEN_LIBRARY}")
ENDIF( ENABLE_JREEN AND NOT LIBJREEN_FOUND )
IF( WIN32 )
find_library(QTSPARKLE_LIBRARIES qtsparkle)
ENDIF( WIN32 )
macro_log_feature(JREEN_FOUND "Jreen" "Qt XMPP library" "http://gitorious.org/jreen" FALSE "" "Jreen is needed for the alternative/new Jabber SIP plugin. Built automatically inside Tomahawk, if not installed systemwide and ENABLE_JREEN is true")
macro_optional_find_package(Gloox 1.0)
@ -79,6 +85,11 @@ MESSAGE("add checks for libmad, libvorbis and libflac. Make sure they are instal
MESSAGE("")
MESSAGE("-----------------------------------------------------------------------------")
IF( NOT APPLE )
# Make linking as strict on linux as it is on osx. Then we don't break linking on mac so often
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" )
ENDIF( NOT APPLE )
ADD_SUBDIRECTORY( thirdparty )
ADD_SUBDIRECTORY( src/libtomahawk )
ADD_SUBDIRECTORY( src )

View File

@ -4,7 +4,7 @@
#
# CLUCENE_INCLUDE_DIR = where CLucene/StdHeader.h can be found
# CLUCENE_LIBRARY_DIR = where CLucene/clucene-config.h can be found
# CLUCENE_LIBRARY = the library to link against CLucene
# CLUCENE_LIBRARIES = the libraries to link against CLucene
# CLUCENE_VERSION = The CLucene version string
# CLucene_FOUND = set to 1 if clucene is found
#
@ -37,13 +37,25 @@ SET(TRIAL_INCLUDE_PATHS
/sw/include
/usr/pkg/include
)
FIND_LIBRARY_WITH_DEBUG(CLUCENE_LIBRARY
FIND_LIBRARY_WITH_DEBUG(CLUCENE_CORE_LIBRARY
WIN32_DEBUG_POSTFIX d
NAMES clucene clucene-core
NAMES clucene-core
PATHS ${TRIAL_LIBRARY_PATHS})
IF (CLUCENE_LIBRARY)
MESSAGE(STATUS "Found CLucene library: ${CLUCENE_LIBRARY}")
ENDIF (CLUCENE_LIBRARY)
IF (CLUCENE_CORE_LIBRARY)
MESSAGE(STATUS "Found CLucene core library: ${CLUCENE_CORE_LIBRARY}")
ENDIF (CLUCENE_CORE_LIBRARY)
FIND_LIBRARY_WITH_DEBUG(CLUCENE_SHARED_LIBRARY
WIN32_DEBUG_POSTFIX d
NAMES clucene-shared
PATHS ${TRIAL_LIBRARY_PATHS})
IF (CLUCENE_SHARED_LIBRARY)
MESSAGE(STATUS "Found CLucene shared library: ${CLUCENE_SHARED_LIBRARY}")
ENDIF (CLUCENE_SHARED_LIBRARY)
IF(CLUCENE_CORE_LIBRARY AND CLUCENE_SHARED_LIBRARY)
SET(CLUCENE_LIBRARIES ${CLUCENE_CORE_LIBRARY} ${CLUCENE_SHARED_LIBRARY})
ENDIF(CLUCENE_CORE_LIBRARY AND CLUCENE_SHARED_LIBRARY)
FIND_PATH(CLUCENE_INCLUDE_DIR
NAMES CLucene.h
PATHS ${TRIAL_INCLUDE_PATHS})
@ -59,31 +71,28 @@ ENDIF(WIN32)
SET(CLUCENE_GOOD_VERSION TRUE)
FIND_PATH(CLUCENE_LIBRARY_DIR
NAMES CLucene/clucene-config.h PATHS ${TRIAL_LIBRARY_PATHS} ${TRIAL_INCLUDE_PATHS} NO_DEFAULT_PATH)
NAMES CLuceneConfig.cmake/CLuceneConfig.cmake
PATHS ${TRIAL_LIBRARY_PATHS} ${TRIAL_INCLUDE_PATHS} NO_DEFAULT_PATH)
IF (CLUCENE_LIBRARY_DIR)
MESSAGE(STATUS "Found CLucene library dir: ${CLUCENE_LIBRARY_DIR}")
FILE(READ ${CLUCENE_LIBRARY_DIR}/CLucene/clucene-config.h CLCONTENT)
STRING(REGEX MATCH "_CL_VERSION +\".*\"" CLMATCH ${CLCONTENT})
IF (CLMATCH)
STRING(REGEX REPLACE "_CL_VERSION +\"(.*)\"" "\\1" CLUCENE_VERSION ${CLMATCH})
IF (CLUCENE_VERSION STRLESS "${CLUCENE_MIN_VERSION}")
MESSAGE(ERROR " CLucene version ${CLUCENE_VERSION} is less than the required minimum ${CLUCENE_MIN_VERSION}")
SET(CLUCENE_GOOD_VERSION FALSE)
ENDIF (CLUCENE_VERSION STRLESS "${CLUCENE_MIN_VERSION}")
IF (CLUCENE_VERSION STREQUAL "0.9.17")
MESSAGE(ERROR "CLucene version 0.9.17 is not supported.")
SET(CLUCENE_GOOD_VERSION FALSE)
ENDIF (CLUCENE_VERSION STREQUAL "0.9.17")
ENDIF (CLMATCH)
#INCLUDE(${CLUCENE_LIBRARY_DIR}/CLuceneConfig.cmake/CLuceneConfig.cmake)
IF (CLUCENE_VERSION STRLESS "${CLUCENE_MIN_VERSION}")
MESSAGE(ERROR " CLucene version ${CLUCENE_VERSION} is less than the required minimum ${CLUCENE_MIN_VERSION}")
SET(CLUCENE_GOOD_VERSION FALSE)
ENDIF (CLUCENE_VERSION STRLESS "${CLUCENE_MIN_VERSION}")
IF (CLUCENE_VERSION STREQUAL "0.9.17")
MESSAGE(ERROR "CLucene version 0.9.17 is not supported.")
SET(CLUCENE_GOOD_VERSION FALSE)
ENDIF (CLUCENE_VERSION STREQUAL "0.9.17")
ENDIF (CLUCENE_LIBRARY_DIR)
IF(CLUCENE_INCLUDE_DIR AND CLUCENE_LIBRARY AND CLUCENE_LIBRARY_DIR AND CLUCENE_GOOD_VERSION)
IF(CLUCENE_INCLUDE_DIR AND CLUCENE_LIBRARIES AND CLUCENE_LIBRARY_DIR AND CLUCENE_GOOD_VERSION)
SET(CLucene_FOUND TRUE)
ENDIF(CLUCENE_INCLUDE_DIR AND CLUCENE_LIBRARY AND CLUCENE_LIBRARY_DIR AND CLUCENE_GOOD_VERSION)
ENDIF(CLUCENE_INCLUDE_DIR AND CLUCENE_LIBRARIES AND CLUCENE_LIBRARY_DIR AND CLUCENE_GOOD_VERSION)
IF(CLucene_FOUND)
IF(NOT CLucene_FIND_QUIETLY)
MESSAGE(STATUS "Found CLucene: ${CLUCENE_LIBRARY} version ${CLUCENE_VERSION}")
MESSAGE(STATUS "Found CLucene: ${CLUCENE_LIBRARIES} version ${CLUCENE_VERSION}")
ENDIF(NOT CLucene_FIND_QUIETLY)
ELSE(CLucene_FOUND)
IF(CLucene_FIND_REQUIRED)
@ -94,5 +103,5 @@ ENDIF(CLucene_FOUND)
MARK_AS_ADVANCED(
CLUCENE_INCLUDE_DIR
CLUCENE_LIBRARY_DIR
CLUCENE_LIBRARY
CLUCENE_LIBRARIES
)

3
ChangeLog Normal file
View File

@ -0,0 +1,3 @@
Version 0.0.1:
Features:
* Knocks your socks off

View File

@ -47,7 +47,9 @@ CREATEDMG='1'
header deposx
$ROOT/../admin/mac/deposx.sh
header "Copying Sparkle pubkey"
header "Copying Sparkle pubkey and framework, and qt.conf"
cp $ROOT/../admin/mac/sparkle_pub.pem Contents/Resources
cp -R /Library/Frameworks/Sparkle.framework Contents/Frameworks
cp $ROOT/../admin/mac/qt.conf Contents/Resources
header Done!

View File

@ -61,7 +61,7 @@ function deposx_change
function deplib_change
{
install_name_tool -change /usr/local/Cellar/liblastfm/0.3.1/lib/liblastfm.0.dylib @executable_path/liblastfm.0.dylib $1
install_name_tool -change /usr/local/Cellar/liblastfm/0.3.3/lib/liblastfm.0.dylib @executable_path/liblastfm.0.dylib $1
install_name_tool -change /usr/local/Cellar/qjson/0.7.1/lib/libqjson.0.dylib @executable_path/libqjson.0.dylib $1
install_name_tool -change /usr/local/lib/libechonest.1.1.dylib @executable_path/libechonest.1.1.dylib $1
install_name_tool -change /usr/local/lib/libclucene-core.0.9.23.dylib @executable_path/libclucene-core.0.9.23.dylib $1
@ -100,7 +100,7 @@ do
done
import_lib /usr/local/Cellar/qjson/0.7.1/lib/libqjson.0.dylib
import_lib /usr/local/Cellar/liblastfm/0.3.1/lib/liblastfm.0.dylib
import_lib /usr/local/Cellar/liblastfm/0.3.3/lib/liblastfm.0.dylib
import_lib /usr/local/Cellar/gloox/1.0/lib/libgloox.8.dylib
import_lib /usr/local/Cellar/taglib/1.6.3/lib/libtag.1.dylib
import_lib /usr/local/Cellar/libogg/1.2.0/lib/libogg.0.dylib

2
admin/mac/qt.conf Normal file
View File

@ -0,0 +1,2 @@
[Paths]
Plugins = PlugIns

14
admin/mac/sign_bundle.rb Executable file
View File

@ -0,0 +1,14 @@
#!/usr/bin/ruby
if ARGV.length < 2
puts "Usage: ruby sign_update.rb version private_key_file"
puts "\nCall this from the build directory."
puts "If you don't have the tomahawk private key and you think you should, ask leo :)"
exit
end
tarball = "tomahawk#{ARGV[0]}.tar.bz2"
puts "Zipping: #{tarball}..."
`tar jcvf "#{tarball}" tomahawk.app`
puts "Signing..."
puts `openssl dgst -sha1 -binary < "#{tarball}" | openssl dgst -dss1 -sign "#{ARGV[1]}" | openssl enc -base64`

17
admin/mac/sparkle-beta.rss Executable file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Tomahawk Player Changelog</title>
<link>http://download.tomahawk-player.org/sparkle</link>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>Version 0.0.1 (Tomahawk Player - It Lives!)</title>
<sparkle:releaseNotesLink>
https://github.com/tomahawk-player/tomahawk/raw/master/ChangeLog
</sparkle:releaseNotesLink>
<pubDate>Fri, 04 Mar 2011 16:05:15 -0500</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparkle-debug/updates/tomahawk0.0.1.tar.bz2" sparkle:version="0.0.1" length="10627176" type="application/octet-stream" sparkle:dsaSignature="MC0CFAyYNZq58X7hPC7Qn+DtotVgym7pAhUA5hkLGllYxjOwwCf7i2LxUsvGyps=" />
</item>
</channel>
</rss>

View File

@ -8,7 +8,7 @@
<item>
<title>Version 0.0.1 (Tomahawk Player - It Lives!)</title>
<sparkle:releaseNotesLink>
<!-- http://you.com/app/2.0.html -->
https://github.com/tomahawk-player/tomahawk/raw/master/ChangeLog
</sparkle:releaseNotesLink>
<pubDate>Fri, 04 Mar 2011 16:05:15 -0500</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparkle/updates/tomahawk0.1.tar.bz2" sparkle:version="0.0.1" length="10627176" type="application/octet-stream" sparkle:dsaSignature="MC0CFAyYNZq58X7hPC7Qn+DtotVgym7pAhUA5hkLGllYxjOwwCf7i2LxUsvGyps=" />

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Tomahawk Player</title>
<link>http://www.gettomahawk.com</link>
<description>Tomahawk Player</description>
<language>en</language>
<item>
<title>Version 0.0.1 (Tomahawk Player - It Lives!)</title>
<sparkle:releaseNotesLink>
https://github.com/tomahawk-player/tomahawk/blob/master/ChangeLog
</sparkle:releaseNotesLink>
<pubDate>Fri, 04 Mar 2011 16:05:15 -0500</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparklewin/updates/tomahawk0.0.1.exe" sparkle:version="0.0.1" />
</item>
</channel>
</rss>

17
admin/win/sparklewin.rss Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Tomahawk Player</title>
<link>http://www.gettomahawk.com</link>
<description>Tomahawk Player</description>
<language>en</language>
<item>
<title>Version 0.0.1 (Tomahawk Player - It Lives!)</title>
<sparkle:releaseNotesLink>
https://github.com/tomahawk-player/tomahawk/blob/master/ChangeLog
</sparkle:releaseNotesLink>
<pubDate>Fri, 04 Mar 2011 16:05:15 -0500</pubDate>
<enclosure url="http://download.tomahawk-player.org/sparklewin/updates/tomahawk0.0.1.exe" sparkle:version="0.0.1" />
</item>
</channel>
</rss>

View File

@ -44,7 +44,7 @@
</head>
<body>
<a href="http://www.playdar.org/" title="Tomahawk - Powered by Playdar" id="head">
<img alt="Tomahawk - Powered by Playdar" src="/staticdata/tomahawk_auth_logo.png" width="233" height="68"/>
<img alt="Tomahawk - Powered by Playdar" src="/staticdata/tomahawk_auth_logo.png" width="196" height="45"/>
</a>
<div id="content">

View File

@ -32,8 +32,8 @@
</style>
</head>
<body>
<a href="http://www.playdar.org/" title="Tomahawk - Powered by Playdar" id="head">
<img alt="Tomahawk - Powered by Playdar" src="/static/playdar_auth_logo.gif" width="233" height="68"/>
<a href="http://www.gettomahawk.com/" title="Tomahawk - Powered by Playdar" id="head">
<img alt="Tomahawk - Powered by Playdar" src="/staticdata/tomahawk_auth_logo.png" width="196" height="45"/>
</a>
<div id="content">

View File

@ -30,4 +30,18 @@ if (APPLE)
elseif (DARWIN_VERSION GREATER 8)
SET(LEOPARD 1)
endif (DARWIN_VERSION GREATER 9)
# Use two different sparkle update tracks for debug and release
# We have to change the URL in the Info.plist file :-/
IF( NOT CMAKE_BUILD_TYPE STREQUAL "Release" )
FILE(READ ${CMAKE_SOURCE_DIR}/admin/mac/Info.plist plist)
STRING( REPLACE "http://download.tomahawk-player.org/sparkle" # match this
"http://download.tomahawk-player.org/sparkle-debug" #replace with debug url
edited_plist # save in this variable
"${plist}" # from the contents of this var
)
FILE( WRITE ${CMAKE_BINARY_DIR}/Info.plist "${edited_plist}" )
ELSE() # Just copy the release one
FILE( COPY ${CMAKE_SOURCE_DIR}/admin/mac/Info.plist DESTINATION ${CMAKE_BINARY_DIR} )
ENDIF()
endif (APPLE)

View File

@ -18,6 +18,10 @@ SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
SET( TOMAHAWK_INC_DIR "${CMAKE_SOURCE_DIR}/include/" )
IF( NOT CMAKE_BUILD_TYPE STREQUAL "Release" )
MESSAGE( "Building in debug mode, enabling all debug updates" )
SET( DEBUG_BUILD ON )
ENDIF()
# build plugins
# use glob, but hardcoded list for now:
@ -152,7 +156,7 @@ IF( APPLE )
SET( tomahawkSources ${tomahawkSources} mac/tomahawkapp_mac.mm mac/macshortcuthandler.cpp )
IF(HAVE_SPARKLE)
SET( tomahawkHeaders ${tomahawkHeaders} ${SPARKLE}/Headers )
SET( tomahawkHeaders ${tomahawkHeaders} ${SPARKLE}/Headers )
ENDIF(HAVE_SPARKLE)
ENDIF( APPLE )
@ -184,7 +188,7 @@ IF( UNIX AND NOT APPLE )
ENDIF( UNIX AND NOT APPLE )
IF( APPLE )
ADD_EXECUTABLE( tomahawk MACOSX_BUNDLE ${final_src} )
SET_TARGET_PROPERTIES(tomahawk PROPERTIES MACOSX_BUNDLE_INFO_PLIST "../admin/mac/Info.plist"
SET_TARGET_PROPERTIES(tomahawk PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_BINARY_DIR}/Info.plist"
)
ENDIF( APPLE )
IF( WIN32 )
@ -204,15 +208,16 @@ ENDIF(GLOOX_FOUND)
TARGET_LINK_LIBRARIES( tomahawk
${LINK_LIBRARIES}
${TOMAHAWK_LIBRARIES}
${OS_SPECIFIC_LINK_LIBRARIES}
${QT_LIBRARIES}
${MAC_EXTRA_LIBS}
${OS_SPECIFIC_LINK_LIBRARIES}
${LIBECHONEST_LIBRARY}
${QXTWEB_LIBRARIES}
${QTWEETLIB_LIBRARIES}
${QJSON_LIBRARIES}
${TAGLIB_LIBRARIES}
${QTWEETLIB_LIBRARIES}
${CLUCENE_LIBRARIES}
)
@ -220,7 +225,7 @@ IF( APPLE )
IF(HAVE_SPARKLE)
MESSAGE("Sparkle Found, installing framekwork in bundle")
INSTALL(DIRECTORY "${SPARKLE}/Versions/Current/Resources" DESTINATION "${CMAKE_BINARY_DIR}/tomahawk.app/Contents/Frameworks/Sparkle.framework")
INSTALL(FILES "${CMAKE_SOURCE_DIR}/admin/mac/sparkle_pub.pem" DESTINATION "${CMAKE_BINARY_DIR}/tomahawk.app/Contents/Resources")
ENDIF(HAVE_SPARKLE)
ENDIF( APPLE )

View File

@ -12,6 +12,8 @@ SET( QXTWEB_LIBRARIES ${CMAKE_BINARY_DIR}/thirdparty/qxt/qxtweb-standalone/libq
SET( OS_SPECIFIC_LINK_LIBRARIES
${OS_SPECIFIC_LINK_LIBRARIES}
${QTSPARKLE_LIBRARIES}
# third party shipped with tomahawk
# system libs

View File

@ -6,6 +6,7 @@
#cmakedefine APPLICATION_NAME "${APPLICATION_NAME}"
#cmakedefine VERSION "${VERSION}"
#cmakedefine DEBUG_BUILD
#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"

View File

@ -371,10 +371,11 @@ target_link_libraries( tomahawklib
# External deps
${TAGLIB_LIBRARIES}
${QJSON_LIBRARIES}
${CLUCENE_LIBRARY}
${CLUCENE_LIBRARIES}
${LIBECHONEST_LIBRARY}
${QT_LIBRARIES}
${OS_SPECIFIC_LINK_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
)
install( TARGETS tomahawklib DESTINATION lib )

View File

@ -40,12 +40,12 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr&
void
Album::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
Album::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks )
{
qDebug() << Q_FUNC_INFO;
m_queries << tracks;
emit tracksAdded( tracks, collection );
emit tracksAdded( tracks );
}
@ -75,8 +75,8 @@ Album::tracks()
cmd->setAlbum( this );
cmd->setSortOrder( DatabaseCommand_AllTracks::AlbumPosition );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}

View File

@ -47,12 +47,12 @@ signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& );
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks );
void trackCountChanged( unsigned int tracks );
void sourceTrackCountChanged( unsigned int tracks );
private slots:
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection );
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
private:
unsigned int m_id;

View File

@ -44,16 +44,17 @@ Artist::Artist( unsigned int id, const QString& name, const Tomahawk::collection
Tomahawk::collection_ptr
Artist::collection() const
{
return m_collection;
return m_collection;
}
void
Artist::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
Artist::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks )
{
qDebug() << Q_FUNC_INFO;
m_queries << tracks;
emit tracksAdded( tracks, collection );
emit tracksAdded( tracks );
}
@ -83,8 +84,8 @@ Artist::tracks()
cmd->setArtist( this );
cmd->setSortOrder( DatabaseCommand_AllTracks::Album );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}

View File

@ -23,11 +23,11 @@ public:
Artist();
virtual ~Artist();
unsigned int id() const { return m_id; }
QString name() const { return m_name; }
Tomahawk::collection_ptr collection() const;
Tomahawk::collection_ptr collection() const;
virtual QList<Tomahawk::query_ptr> tracks();
@ -48,12 +48,12 @@ signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& );
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks );
void trackCountChanged( unsigned int tracks );
void sourceTrackCountChanged( unsigned int tracks );
private slots:
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection );
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
private:
unsigned int m_id;

View File

@ -13,9 +13,10 @@ Collection::Collection( const source_ptr& source, const QString& name, QObject*
: QObject( parent )
, m_name( name )
, m_lastmodified( 0 )
, m_isLoaded( false )
, m_source( source )
{
// qDebug() << Q_FUNC_INFO;
qDebug() << Q_FUNC_INFO << name << source->friendlyName();
}
@ -127,7 +128,7 @@ Collection::dynamicPlaylist( const QString& guid )
if( pp->guid() == guid )
return pp;
}
return dynplaylist_ptr();
}
@ -146,26 +147,27 @@ void
Collection::setDynamicPlaylists( const QList< Tomahawk::dynplaylist_ptr >& plists )
{
qDebug() << Q_FUNC_INFO << plists.count();
m_dynplaylists.append( plists );
emit dynamicPlaylistsAdded( plists );
}
void
Collection::setTracks( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
Collection::setTracks( const QList<Tomahawk::query_ptr>& tracks )
{
qDebug() << Q_FUNC_INFO << tracks.count() << collection->name();
qDebug() << Q_FUNC_INFO << tracks.count() << name();
m_isLoaded = true;
m_tracks << tracks;
emit tracksAdded( tracks, collection );
emit tracksAdded( tracks );
}
void
Collection::delTracks( const QStringList& files, const Tomahawk::collection_ptr& collection )
Collection::delTracks( const QStringList& files )
{
qDebug() << Q_FUNC_INFO << files.count() << collection->name();
qDebug() << Q_FUNC_INFO << files.count() << name();
QList<Tomahawk::query_ptr> tracks;
@ -188,5 +190,5 @@ Collection::delTracks( const QStringList& files, const Tomahawk::collection_ptr&
i++;
}
emit tracksRemoved( tracks, collection );
emit tracksRemoved( tracks );
}

View File

@ -33,6 +33,7 @@ public:
Collection( const source_ptr& source, const QString& name, QObject* parent = 0 );
virtual ~Collection();
virtual bool isLoaded() const { return m_isLoaded; }
virtual QString name() const;
virtual void loadPlaylists() { qDebug() << Q_FUNC_INFO; }
@ -41,13 +42,13 @@ public:
virtual Tomahawk::playlist_ptr playlist( const QString& guid );
virtual Tomahawk::dynplaylist_ptr dynamicPlaylist( const QString& guid );
virtual void addPlaylist( const Tomahawk::playlist_ptr& p );
virtual void deletePlaylist( const Tomahawk::playlist_ptr& p );
virtual void addDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p );
virtual void deleteDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p );
virtual QList< Tomahawk::playlist_ptr > playlists() { return m_playlists; }
virtual QList< Tomahawk::dynplaylist_ptr > dynamicPlaylists() { return m_dynplaylists; }
virtual QList< Tomahawk::query_ptr > tracks() { return m_tracks; }
@ -56,13 +57,12 @@ public:
unsigned int lastmodified() const { return m_lastmodified; }
signals:
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& );
void tracksRemoved( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& );
void tracksFinished( const Tomahawk::collection_ptr& );
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks );
void tracksRemoved( const QList<Tomahawk::query_ptr>& tracks );
void playlistsAdded( const QList<Tomahawk::playlist_ptr>& );
void playlistsDeleted( const QList<Tomahawk::playlist_ptr>& );
void dynamicPlaylistsAdded( const QList<Tomahawk::dynplaylist_ptr>& );
void dynamicPlaylistsDeleted( const QList<Tomahawk::dynplaylist_ptr>& );
@ -72,15 +72,17 @@ public slots:
void setPlaylists( const QList<Tomahawk::playlist_ptr>& plists );
void setDynamicPlaylists( const QList< Tomahawk::dynplaylist_ptr >& dynplists );
void setTracks( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection );
void setTracks( const QList<Tomahawk::query_ptr>& tracks );
void delTracks( const QStringList& files, const Tomahawk::collection_ptr& collection );
void delTracks( const QStringList& files );
protected:
QString m_name;
unsigned int m_lastmodified; // unix time of last change to collection
private:
bool m_isLoaded;
source_ptr m_source;
QList< Tomahawk::query_ptr > m_tracks;
QList< Tomahawk::playlist_ptr > m_playlists;

View File

@ -51,8 +51,8 @@ DatabaseCollection::loadTracks()
m_loadedTracks = true;
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( source()->collection() );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( setTracks( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ),
SLOT( setTracks( QList<Tomahawk::query_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
@ -73,7 +73,7 @@ DatabaseCollection::removeTracks( const QDir& dir )
{
qDebug() << Q_FUNC_INFO << dir;
DatabaseCommand_DeleteFiles* cmd = new DatabaseCommand_DeleteFiles( dir, source() );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}

View File

@ -31,7 +31,7 @@ public:
public slots:
virtual void addTracks( const QList<QVariant>& newitems );
virtual void removeTracks( const QDir& dir );
private slots:
void dynamicPlaylistCreated( const Tomahawk::source_ptr& source, const QVariantList& data );

View File

@ -60,6 +60,7 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
while( query.next() )
{
Tomahawk::result_ptr result = Tomahawk::result_ptr( new Tomahawk::Result() );
QVariantMap attr;
TomahawkSqlQuery attrQuery = dbi->newquery();
@ -89,7 +90,7 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
result->setAlbumPos( query.value( 11 ).toUInt() );
result->setScore( 1.0 );
result->setCollection( m_collection );
attrQuery.prepare( "SELECT k, v FROM track_attributes WHERE id = ?" );
attrQuery.bindValue( 0, result->dbid() );
attrQuery.exec();
@ -105,16 +106,10 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
qry->addResults( results );
ql << qry;
if ( ++i % 5000 == 0 )
{
emit tracks( ql, m_collection );
ql.clear();
}
}
qDebug() << Q_FUNC_INFO << ql.length();
emit tracks( ql, m_collection );
emit tracks( ql );
emit done( m_collection );
}

View File

@ -45,7 +45,7 @@ public:
void setSortDescending( bool descending ) { m_sortDescending = descending; }
signals:
void tracks( const QList<Tomahawk::query_ptr>&, const Tomahawk::collection_ptr& );
void tracks( const QList<Tomahawk::query_ptr>& );
void done( const Tomahawk::collection_ptr& );
private:

View File

@ -29,6 +29,8 @@ DatabaseCommand_RenamePlaylist::exec( DatabaseImpl* lib )
cre.bindValue( ":id", m_playlistguid );
cre.bindValue( ":title", m_playlistTitle );
qDebug() << Q_FUNC_INFO << m_playlistTitle << m_playlistguid;
cre.exec();
}
@ -46,6 +48,7 @@ DatabaseCommand_RenamePlaylist::postCommitHook()
playlist_ptr playlist = source()->collection()->playlist( m_playlistguid );
Q_ASSERT( !playlist.isNull() );
qDebug() << "Renaming old playlist" << playlist->title() << "to" << m_playlistTitle << m_playlistguid;
playlist->setTitle( m_playlistTitle );
if( source()->isLocal() )

View File

@ -389,7 +389,7 @@ Playlist::setNewRevision( const QString& rev,
source_ptr
Playlist::author()
Playlist::author() const
{
return m_source;
}

View File

@ -33,10 +33,10 @@ Q_PROPERTY( QVariant query READ queryVariant WRITE setQueryVariant )
public:
PlaylistEntry();
virtual ~PlaylistEntry();
void setQuery( const Tomahawk::query_ptr& q );
const Tomahawk::query_ptr& query() const;
// I wish Qt did this for me once i specified the Q_PROPERTIES:
void setQueryVariant( const QVariant& v );
QVariant queryVariant() const;
@ -59,7 +59,7 @@ public:
source_ptr lastSource() const;
void setLastSource( source_ptr s );
private:
private:
QString m_guid;
Tomahawk::query_ptr m_query;
QString m_annotation;
@ -97,7 +97,7 @@ friend class ::DatabaseCommand_CreatePlaylist;
public:
~Playlist();
static Tomahawk::playlist_ptr load( const QString& guid );
// one CTOR is private, only called by DatabaseCommand_LoadAllPlaylists
@ -113,14 +113,14 @@ public:
virtual void loadRevision( const QString& rev = "" );
source_ptr author();
const QString& currentrevision() { return m_currentrevision; }
const QString& title() { return m_title; }
const QString& info() { return m_info; }
const QString& creator() { return m_creator; }
unsigned int lastmodified() { return m_lastmodified; }
const QString& guid() { return m_guid; }
bool shared() const { return m_shared; }
source_ptr author() const;
QString currentrevision() const { return m_currentrevision; }
QString title() const { return m_title; }
QString info() const { return m_info; }
QString creator() const { return m_creator; }
QString guid() const { return m_guid; }
bool shared() const { return m_shared; }
unsigned int lastmodified() const { return m_lastmodified; }
const QList< plentry_ptr >& entries() { return m_entries; }
virtual void addEntry( const Tomahawk::query_ptr& query, const QString& oldrev );
@ -132,7 +132,7 @@ public:
// maybe friend QObjectHelper and make them private?
explicit Playlist( const source_ptr& author );
void setCurrentrevision( const QString& s ) { m_currentrevision = s; }
void setTitle( const QString& s ) { m_title = s; }
void setTitle( const QString& s ) { m_title = s; emit changed(); }
void setInfo( const QString& s ) { m_info = s; }
void setCreator( const QString& s ) { m_creator = s; }
void setGuid( const QString& s ) { m_guid = s; }
@ -148,12 +148,12 @@ public:
virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; }
virtual bool shuffled() const { return false; }
virtual void setRepeatMode( PlaylistInterface::RepeatMode ) {}
virtual void setShuffled( bool ) {}
virtual void setFilter( const QString& pattern ) {}
signals:
/// emitted when the playlist revision changes (whenever the playlist changes)
void revisionLoaded( Tomahawk::PlaylistRevision );
@ -161,6 +161,9 @@ signals:
/// watch for this to see when newly created playlist is synced to DB (if you care)
void created();
/// renamed etc.
void changed();
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
@ -201,24 +204,24 @@ protected:
const QString& info,
const QString& creator,
bool shared );
QList< plentry_ptr > newEntries( const QList< plentry_ptr >& entries );
PlaylistRevision setNewRevision( const QString& rev,
const QList<QString>& neworderedguids,
const QList<QString>& oldorderedguids,
bool is_newest_rev,
const QMap< QString, Tomahawk::plentry_ptr >& addedmap );
QList<plentry_ptr> addEntriesInternal( const QList<Tomahawk::query_ptr>& queries );
private slots:
void onResultsFound( const QList<Tomahawk::result_ptr>& results );
void onResolvingFinished();
private:
Playlist();
void init();
source_ptr m_source;
QString m_currentrevision;
QString m_guid, m_title, m_info, m_creator;

View File

@ -52,17 +52,16 @@ CollectionFlatModel::addCollection( const collection_ptr& collection )
<< collection->source()->id()
<< collection->source()->userName();
emit loadingStarts();
connect( collection.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
connect( collection.data(), SIGNAL( tracksRemoved( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksRemoved( QList<Tomahawk::query_ptr> ) ) );
onTracksAdded( collection->tracks(), collection );
if ( collection->isLoaded() )
onTracksAdded( collection->tracks() );
else
collection->tracks(); // data will arrive via signals
connect( collection.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
connect( collection.data(), SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ),
SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) );
connect( collection.data(), SIGNAL( tracksRemoved( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( onTracksRemoved( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
if ( collection->source()->isLocal() )
setTitle( tr( "Your Collection" ) );
else
@ -78,8 +77,6 @@ CollectionFlatModel::addFilteredCollection( const collection_ptr& collection, un
<< collection->source()->userName()
<< amount << order;
emit loadingStarts();
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( collection );
cmd->setLimit( amount );
cmd->setSortOrder( order );
@ -97,10 +94,8 @@ CollectionFlatModel::removeCollection( const collection_ptr& collection )
{
return; // FIXME
disconnect( collection.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
this, SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
disconnect( collection.data(), SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ),
this, SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) );
disconnect( collection.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
this, SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
QTime timer;
timer.start();
@ -160,56 +155,62 @@ CollectionFlatModel::removeCollection( const collection_ptr& collection )
qDebug() << "Collection removed, time elapsed:" << timer.elapsed();
emit trackCountChanged( rowCount( QModelIndex() ) );
// emit trackCountChanged( rowCount( QModelIndex() ) );
}
void
CollectionFlatModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
CollectionFlatModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks )
{
qDebug() << Q_FUNC_INFO;
qDebug() << Q_FUNC_INFO << tracks.count() << rowCount( QModelIndex() );
if ( !tracks.count() )
{
emit trackCountChanged( rowCount( QModelIndex() ) );
return;
}
bool kickOff = m_tracksToAdd.isEmpty();
m_tracksToAdd << tracks;
emit trackCountChanged( trackCount() );
if ( m_tracksToAdd.count() && kickOff )
processTracksToAdd();
}
void
CollectionFlatModel::processTracksToAdd()
{
int chunkSize = 500000;
int maxc = qMin( chunkSize, m_tracksToAdd.count() );
int c = rowCount( QModelIndex() );
QPair< int, int > crows;
crows.first = c;
crows.second = c + tracks.count() - 1;
emit beginInsertRows( QModelIndex(), crows.first, crows.second );
//emit beginInsertRows( QModelIndex(), c, c + maxc - 1 );
beginResetModel();
PlItem* plitem;
foreach( const query_ptr& query, tracks )
QList< Tomahawk::query_ptr >::iterator iter = m_tracksToAdd.begin();
for( int i = 0; i < maxc; ++i )
{
plitem = new PlItem( query, m_rootItem );
plitem = new PlItem( *iter, m_rootItem );
plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem );
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
++iter;
}
m_collectionRows.insertMulti( collection, crows );
emit endInsertRows();
m_tracksToAdd.erase( m_tracksToAdd.begin(), iter );
emit trackCountChanged( rowCount( QModelIndex() ) );
endResetModel();
//emit endInsertRows();
qDebug() << Q_FUNC_INFO << rowCount( QModelIndex() );
if ( m_tracksToAdd.count() )
QTimer::singleShot( 250, this, SLOT( processTracksToAdd() ) );
}
void
CollectionFlatModel::onTracksAddingFinished( const Tomahawk::collection_ptr& collection )
{
qDebug() << "Finished loading tracks" << collection->source()->friendlyName();
emit loadingFinished();
}
void
CollectionFlatModel::onTracksRemoved( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
CollectionFlatModel::onTracksRemoved( const QList<Tomahawk::query_ptr>& tracks )
{
QList<Tomahawk::query_ptr> t = tracks;
for ( int i = rowCount( QModelIndex() ); i >= 0 && t.count(); i-- )
@ -235,8 +236,8 @@ CollectionFlatModel::onTracksRemoved( const QList<Tomahawk::query_ptr>& tracks,
j++;
}
}
emit trackCountChanged( rowCount( QModelIndex() ) );
// emit trackCountChanged( rowCount( QModelIndex() ) );
qDebug() << Q_FUNC_INFO << rowCount( QModelIndex() );
}

View File

@ -29,6 +29,8 @@ public:
int columnCount( const QModelIndex& parent = QModelIndex() ) const;
virtual int trackCount() const { return rowCount( QModelIndex() ) + m_tracksToAdd.count(); }
QVariant data( const QModelIndex& index, int role ) const;
QVariant headerData( int section, Qt::Orientation orientation, int role ) const;
@ -45,21 +47,19 @@ signals:
void itemSizeChanged( const QModelIndex& index );
void loadingStarts();
void loadingFinished();
private slots:
void onDataChanged();
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection );
void onTracksAddingFinished( const Tomahawk::collection_ptr& collection );
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
void onTracksRemoved( const QList<Tomahawk::query_ptr>& tracks );
void onTracksRemoved( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection );
void onSourceOffline( const Tomahawk::source_ptr& src );
void processTracksToAdd();
private:
QMap< Tomahawk::collection_ptr, QPair< int, int > > m_collectionRows;
QList<Tomahawk::query_ptr> m_tracksToAdd;
};
#endif // COLLECTIONFLATMODEL_H

View File

@ -23,10 +23,11 @@ using namespace Tomahawk;
DynamicModel::DynamicModel( QObject* parent )
: PlaylistModel( parent )
, m_startOnResolved( false )
, m_onDemandRunning( false )
, m_changeOnNext( false )
, m_searchingForNext( false )
, m_filterUnresolvable( true )
, m_startingAfterFailed( false )
, m_currentAttempts( 0 )
, m_lastResolvedRow( 0 )
{
@ -68,9 +69,6 @@ DynamicModel::startOnDemand()
m_playlist->generator()->startOnDemand();
m_onDemandRunning = true;
m_startOnResolved = false; // not anymore---user clicks a track to start it
m_currentAttempts = 0;
m_lastResolvedRow = rowCount( QModelIndex() );
}
void
@ -78,7 +76,7 @@ DynamicModel::newTrackGenerated( const Tomahawk::query_ptr& query )
{
if( m_onDemandRunning ) {
connect( query.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( trackResolveFinished( bool ) ) );
connect( query.data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ), this, SLOT( trackResolved() ) );
connect( query.data(), SIGNAL( solvedStateChanged( bool ) ), this, SLOT( trackResolved( bool ) ) );
append( query );
}
@ -105,20 +103,20 @@ DynamicModel::changeStation()
void
DynamicModel::trackResolved()
DynamicModel::trackResolved( bool resolved )
{
if( !resolved )
return;
Query* q = qobject_cast<Query*>(sender());
qDebug() << "Got successful resolved track:" << q->track() << q->artist() << m_lastResolvedRow << m_currentAttempts;
if( m_startOnResolved ) { // on first start
m_startOnResolved = false;
AudioEngine::instance()->play();
}
if( m_currentAttempts > 0 ) {
qDebug() << "EMITTING AN ASK FOR COLLAPSE:" << m_lastResolvedRow << m_currentAttempts;
emit collapseFromTo( m_lastResolvedRow, m_currentAttempts );
}
m_currentAttempts = 0;
m_searchingForNext = false;
emit checkForOverflow();
}
@ -130,9 +128,13 @@ DynamicModel::trackResolveFinished( bool success )
Query* q = qobject_cast<Query*>(sender());
qDebug() << "Got not resolved track:" << q->track() << q->artist() << m_lastResolvedRow << m_currentAttempts;
m_currentAttempts++;
if( m_currentAttempts < 20 ) {
int curAttempts = m_startingAfterFailed ? m_currentAttempts - 20 : m_currentAttempts; // if we just failed, m_currentAttempts includes those failures
if( curAttempts < 20 ) {
qDebug() << "FETCHING MORE!";
m_playlist->generator()->fetchNext();
} else {
m_startingAfterFailed = true;
emit trackGenerationFailure( tr( "Could not find a playable track.\n\nPlease change the filters or try again." ) );
}
}
@ -142,11 +144,15 @@ DynamicModel::trackResolveFinished( bool success )
void
DynamicModel::newTrackLoading()
{
qDebug() << "Got NEW TRACK LOADING signal";
if( m_changeOnNext ) { // reset instead of getting the next one
m_lastResolvedRow = rowCount( QModelIndex() );
m_searchingForNext = true;
m_playlist->generator()->startOnDemand();
} else if( m_onDemandRunning && m_currentAttempts == 0 ) { // if we're in dynamic mode and we're also currently idle
} else if( m_onDemandRunning && m_currentAttempts == 0 && !m_searchingForNext ) { // if we're in dynamic mode and we're also currently idle
m_lastResolvedRow = rowCount( QModelIndex() );
m_searchingForNext = true;
qDebug() << "IDLE fetching new track!";
m_playlist->generator()->fetchNext();
}
}
@ -154,11 +160,15 @@ DynamicModel::newTrackLoading()
void
DynamicModel::tracksGenerated( const QList< query_ptr > entries, int limitResolvedTo )
{
if( m_filterUnresolvable ) { // wait till we get them resolved
if( m_filterUnresolvable && m_playlist->mode() == OnDemand ) { // wait till we get them resolved (for previewing stations)
m_limitResolvedTo = limitResolvedTo;
filterUnresolved( entries );
} else {
addToPlaylist( entries, m_playlist->mode() == OnDemand ); // if ondemand, we're previewing, so clear old
if( m_playlist->mode() == OnDemand ) {
m_lastResolvedRow = rowCount( QModelIndex() );
}
}
}
@ -202,6 +212,10 @@ DynamicModel::filteringTrackResolved( bool successful )
addToPlaylist( m_resolvedList, true );
m_toResolveList.clear();
m_resolvedList.clear();
if( m_playlist->mode() == OnDemand ) {
m_lastResolvedRow = rowCount( QModelIndex() );
}
}
}

View File

@ -64,7 +64,7 @@ private slots:
void newTrackGenerated( const Tomahawk::query_ptr& query );
void trackResolveFinished( bool );
void trackResolved();
void trackResolved( bool );
void newTrackLoading();
void filteringTrackResolved( bool successful );
@ -78,12 +78,12 @@ private:
QList< query_ptr > m_toResolveList;
QList< query_ptr > m_resolvedList;
bool m_startOnResolved;
bool m_onDemandRunning;
bool m_changeOnNext;
bool m_searchingForNext;
bool m_firstTrackGenerated;
bool m_filterUnresolvable;
bool m_startingAfterFailed;
int m_currentAttempts;
int m_lastResolvedRow;
};

View File

@ -75,7 +75,7 @@ DynamicWidget::DynamicWidget( const Tomahawk::dynplaylist_ptr& playlist, QWidget
m_setup = new DynamicSetupWidget( playlist, this );
m_setup->fadeIn();
connect( m_model, SIGNAL( tracksAdded() ), m_setup, SLOT( fadeOut() ) );
connect( m_model, SIGNAL( tracksAdded() ), this, SLOT( tracksAdded() ) );
loadDynamicPlaylist( playlist );
@ -262,6 +262,14 @@ DynamicWidget::trackStarted()
}
}
void
DynamicWidget::tracksAdded()
{
if( m_playlist->mode() == OnDemand && m_runningOnDemand && m_setup->isVisible() )
m_setup->fadeOut();
}
void
DynamicWidget::stopStation( bool stopPlaying )
{
@ -348,8 +356,8 @@ DynamicWidget::controlChanged( const Tomahawk::dyncontrol_ptr& control )
void
DynamicWidget::showPreview()
{
if( m_playlist->mode() == OnDemand && !m_runningOnDemand ) { // if this is a not running station, preview matching tracks
generate( 40 ); // ask for more, we'll filter how many we actually want
if( m_playlist->mode() == OnDemand && !m_runningOnDemand && m_model->rowCount( QModelIndex() ) == 0 ) { // if this is a not running station, preview matching tracks
generate( 20 ); // ask for more, we'll filter how many we actually want
}
}

View File

@ -89,6 +89,7 @@ public slots:
void stationFailed( const QString& );
void playlistStopped( PlaylistInterface* );
void tracksAdded();
private slots:
void generate( int = -1 );

View File

@ -22,6 +22,7 @@
#include "albummodel.h"
#include "sourcelist.h"
#include "tomahawksettings.h"
#include "utils/widgetdragfilter.h"
#include "dynamic/widgets/DynamicWidget.h"
@ -57,6 +58,8 @@ PlaylistManager::PlaylistManager( QObject* parent )
m_infobar = new InfoBar();
m_stack = new QStackedWidget();
m_infobar->installEventFilter( new WidgetDragFilter( m_infobar ) );
QFrame* line = new QFrame();
line->setFrameStyle( QFrame::HLine );
line->setStyleSheet( "border: 1px solid gray;" );
@ -576,7 +579,12 @@ PlaylistManager::updateView()
if ( currentPage()->showStatsBar() && currentPlaylistInterface() )
{
emit numTracksChanged( currentPlaylistInterface()->unfilteredTrackCount() );
emit numShownChanged( currentPlaylistInterface()->trackCount() );
if ( !currentPlaylistInterface()->filter().isEmpty() )
emit numShownChanged( currentPlaylistInterface()->trackCount() );
else
emit numShownChanged( currentPlaylistInterface()->unfilteredTrackCount() );
emit repeatModeChanged( currentPlaylistInterface()->repeatMode() );
emit shuffleModeChanged( currentPlaylistInterface()->shuffled() );
emit modeChanged( currentPlaylistInterface()->viewMode() );
@ -586,7 +594,7 @@ PlaylistManager::updateView()
m_queueView->show();
else
m_queueView->hide();
emit statsAvailable( currentPage()->showStatsBar() );
emit modesAvailable( currentPage()->showModes() );
@ -687,7 +695,7 @@ PlaylistManager::positionInHistory( ViewPage* page ) const
if ( page == m_pageHistory.at( i ) )
return i;
}
return -1;
}
@ -747,7 +755,7 @@ PlaylistManager::dynamicPlaylistForInterface( PlaylistInterface* interface ) con
return m_dynamicWidgets.key( view );
}
}
return dynplaylist_ptr();
}
@ -769,7 +777,7 @@ PlaylistManager::collectionForInterface( PlaylistInterface* interface ) const
return m_collectionAlbumViews.key( view );
}
}
return collection_ptr();
}

View File

@ -155,10 +155,10 @@ PlaylistModel::append( const Tomahawk::album_ptr& album )
if ( album.isNull() )
return;
connect( album.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
connect( album.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
onTracksAdded( album->tracks(), album->collection() );
onTracksAdded( album->tracks() );
}
@ -168,10 +168,10 @@ PlaylistModel::append( const Tomahawk::artist_ptr& artist )
if ( artist.isNull() )
return;
connect( artist.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::collection_ptr ) ) );
connect( artist.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
onTracksAdded( artist->tracks(), artist->collection() );
onTracksAdded( artist->tracks() );
}
@ -189,14 +189,14 @@ PlaylistModel::insert( unsigned int row, const Tomahawk::query_ptr& query )
void
PlaylistModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
PlaylistModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks )
{
onTracksInserted( rowCount( QModelIndex() ), tracks, collection );
onTracksInserted( rowCount( QModelIndex() ), tracks );
}
void
PlaylistModel::onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection )
PlaylistModel::onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks )
{
if ( !tracks.count() )
{

View File

@ -37,7 +37,7 @@ public:
void loadHistory( const Tomahawk::source_ptr& source, unsigned int amount = 50 );
void clear();
void append( const Tomahawk::query_ptr& query );
void append( const Tomahawk::album_ptr& album );
void append( const Tomahawk::artist_ptr& artist );
@ -61,8 +61,8 @@ private slots:
void onRevisionLoaded( Tomahawk::PlaylistRevision revision );
void onPlaylistChanged( bool waitForUpdate = true );
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() );
void onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::collection_ptr& collection = Tomahawk::collection_ptr() );
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
void onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks );
private:
QList<Tomahawk::plentry_ptr> playlistEntries() const;

View File

@ -39,7 +39,7 @@ public:
virtual void setTitle( const QString& title ) { m_title = title; }
virtual QString description() const { return m_description; }
virtual void setDescription( const QString& description ) { m_description = description; }
virtual int trackCount() const { return rowCount( QModelIndex() ); }
virtual int rowCount( const QModelIndex& parent ) const;

View File

@ -118,7 +118,7 @@ TrackProxyModel::siblingItem( int itemsAway )
{
PlItem* item = itemFromIndex( mapToSource( idx ) );
qDebug() << item->query()->toString();
if ( item && item->query()->numResults() )
if ( item && item->query()->solved() )
{
qDebug() << "Next PlaylistItem found:" << item->query()->toString() << item->query()->results().at( 0 )->url();
setCurrentItem( idx );
@ -137,9 +137,6 @@ TrackProxyModel::siblingItem( int itemsAway )
bool
TrackProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const
{
if ( filterRegExp().isEmpty() )
return true;
PlItem* pi = itemFromIndex( sourceModel()->index( sourceRow, 0, sourceParent ) );
if ( !pi )
return false;
@ -147,34 +144,39 @@ TrackProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParen
const Tomahawk::query_ptr& q = pi->query();
Tomahawk::result_ptr r;
if ( q->numResults() )
r = q->results().at( 0 );
r = q->results().first();
// if ( !r.isNull() && !r->collection()->source()->isOnline() )
// return false;
if ( filterRegExp().isEmpty() )
return true;
QStringList sl = filterRegExp().pattern().split( " ", QString::SkipEmptyParts );
bool found = true;
foreach( const QString& s, sl )
foreach( QString s, sl )
{
s = s.toLower();
if ( !r.isNull() )
{
if ( !r->artist()->name().contains( s, Qt::CaseInsensitive ) &&
!r->album()->name().contains( s, Qt::CaseInsensitive ) &&
!r->track() .contains( s, Qt::CaseInsensitive ) )
if ( !r->artist()->name().toLower().contains( s ) &&
!r->album()->name().toLower().contains( s ) &&
!r->track().toLower().contains( s ) )
{
found = false;
return false;
}
}
else
{
if ( !q->artist().contains( s, Qt::CaseInsensitive ) &&
!q->album() .contains( s, Qt::CaseInsensitive ) &&
!q->track() .contains( s, Qt::CaseInsensitive ) )
if ( !q->artist().toLower().contains( s ) &&
!q->album().toLower().contains( s ) &&
!q->track().toLower().contains( s ) )
{
found = false;
return false;
}
}
}
return found;
return true;
}

View File

@ -23,7 +23,7 @@ public:
virtual QList<Tomahawk::query_ptr> tracks();
virtual int unfilteredTrackCount() const { return sourceModel()->rowCount( QModelIndex() ); }
virtual int unfilteredTrackCount() const { return sourceModel()->trackCount(); }
virtual int trackCount() const { return rowCount( QModelIndex() ); }
virtual void removeIndex( const QModelIndex& index );

View File

@ -44,7 +44,7 @@ Query::addResults( const QList< Tomahawk::result_ptr >& newresults )
{
bool becameSolved = false;
{
QMutexLocker lock( &m_mut );
// QMutexLocker lock( &m_mut );
m_results.append( newresults );
qStableSort( m_results.begin(), m_results.end(), Query::resultSorter );
@ -70,7 +70,8 @@ Query::refreshResults()
void
Query::onResultStatusChanged()
{
qStableSort( m_results.begin(), m_results.end(), Query::resultSorter );
if ( m_results.count() )
qStableSort( m_results.begin(), m_results.end(), Query::resultSorter );
checkResults();
emit resultsChanged();
@ -81,7 +82,7 @@ void
Query::removeResult( const Tomahawk::result_ptr& result )
{
{
QMutexLocker lock( &m_mut );
// QMutexLocker lock( &m_mut );
m_results.removeAll( result );
}
@ -94,14 +95,14 @@ void
Query::onResolvingFinished()
{
// qDebug() << Q_FUNC_INFO << "Finished resolving." << toString();
emit resolvingFinished( !m_results.isEmpty() );
emit resolvingFinished( m_solved );
}
QList< result_ptr >
Query::results() const
{
QMutexLocker lock( &m_mut );
// QMutexLocker lock( &m_mut );
return m_results;
}
@ -109,7 +110,7 @@ Query::results() const
unsigned int
Query::numResults() const
{
QMutexLocker lock( &m_mut );
// QMutexLocker lock( &m_mut );
return m_results.length();
}
@ -148,16 +149,16 @@ Query::checkResults()
{
bool becameSolved = false;
bool becameUnsolved = true;
// hook up signals, and check solved status
foreach( const result_ptr& rp, m_results )
{
if ( !m_solved && rp->score() > 0.99 )
if ( !m_solved && rp->score() > 0.99 && rp->collection()->source()->isOnline() )
{
m_solved = true;
becameSolved = true;
}
if ( rp->score() > 0.99 )
if ( rp->score() > 0.99 && rp->collection()->source()->isOnline() )
{
becameUnsolved = false;
}
@ -166,7 +167,7 @@ Query::checkResults()
if ( m_solved && becameUnsolved )
{
m_solved = false;
emit solvedStateChanged( true );
emit solvedStateChanged( false );
}
if( becameSolved )

View File

@ -84,8 +84,7 @@ private slots:
private:
void clearResults();
void checkResults();
mutable QMutex m_mut;
QList< Tomahawk::result_ptr > m_results;
bool m_solved;
mutable QID m_qid;

View File

@ -19,7 +19,7 @@ SourceList::instance()
{
s_instance = new SourceList();
}
return s_instance;
}
@ -43,10 +43,10 @@ SourceList::loadSources()
{
qDebug() << Q_FUNC_INFO;
DatabaseCommand_LoadAllSources* cmd = new DatabaseCommand_LoadAllSources();
connect( cmd, SIGNAL( done( const QList<Tomahawk::source_ptr>& ) ),
SLOT( setSources( const QList<Tomahawk::source_ptr>& ) ) );
connect( cmd, SIGNAL( done( QList<Tomahawk::source_ptr> ) ),
SLOT( setSources( QList<Tomahawk::source_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
@ -70,7 +70,7 @@ SourceList::setLocal( const Tomahawk::source_ptr& localSrc )
{
Q_ASSERT( localSrc->isLocal() );
Q_ASSERT( m_local.isNull() );
{
QMutexLocker lock( &m_mut );
m_sources.insert( localSrc->userName(), localSrc );
@ -92,11 +92,11 @@ SourceList::add( const source_ptr& source )
if ( source->id() > 0 )
m_sources_id2name.insert( source->id(), source->userName() );
connect( source.data(), SIGNAL( syncedWithDatabase() ), SLOT( sourceSynced() ) );
collection_ptr coll( new RemoteCollection( source ) );
source->addCollection( coll );
source->collection()->tracks();
// source->collection()->tracks();
emit sourceAdded( source );
}

View File

@ -76,36 +76,66 @@ XSPFLoader::gotBody()
qDebug() << Q_FUNC_INFO;
QDomDocument xmldoc;
xmldoc.setContent( m_body );
bool namespaceProcessing = true;
xmldoc.setContent( m_body, namespaceProcessing );
QDomElement docElement( xmldoc.documentElement() );
QString origTitle;
origTitle = docElement.firstChildElement( "title" ).text();
m_info = docElement.firstChildElement( "creator" ).text();
m_creator = docElement.firstChildElement( "info" ).text();
QDomNodeList tracklist;
QDomElement n = docElement.firstChildElement();
for ( ; !n.isNull(); n = n.nextSiblingElement() ) {
if (n.namespaceURI() == m_NS && n.localName() == "title") {
origTitle = n.text();
} else if (n.namespaceURI() == m_NS && n.localName() == "creator") {
m_creator = n.text();
} else if (n.namespaceURI() == m_NS && n.localName() == "info") {
m_info = n.text();
} else if (n.namespaceURI() == m_NS && n.localName() == "trackList") {
tracklist = n.childNodes();
}
}
m_title = origTitle;
if ( m_title.isEmpty() )
m_title = tr( "New Playlist" );
QDomNodeList tracklist = docElement.elementsByTagName( "track" );
bool shownError = false;
for ( unsigned int i = 0; i < tracklist.length(); i++ )
{
QDomNode e = tracklist.at( i );
QString artist, album, track, duration, annotation;
QDomElement n = e.firstChildElement();
for ( ; !n.isNull(); n = n.nextSiblingElement() ) {
if (n.namespaceURI() == m_NS && n.localName() == "duration") {
duration = n.text();
} else if (n.namespaceURI() == m_NS && n.localName() == "annotation") {
annotation = n.text();
} else if (n.namespaceURI() == m_NS && n.localName() == "creator") {
artist = n.text();
} else if (n.namespaceURI() == m_NS && n.localName() == "album") {
album = n.text();
} else if (n.namespaceURI() == m_NS && n.localName() == "title") {
track = n.text();
}
}
if( artist.isEmpty() || track.isEmpty() ) {
if( !shownError ) {
QMessageBox::warning( 0, tr( "Failed to save tracks" ), tr( "Some tracks in the playlist do not contain an artist and a title. They will be ignored." ), QMessageBox::Ok );
shownError = true;
}
continue;
}
plentry_ptr p( new PlaylistEntry );
p->setGuid( uuid() );
p->setDuration( e.firstChildElement( "duration" ).text().toInt() / 1000 );
p->setDuration( duration.toInt() / 1000 );
p->setLastmodified( 0 );
p->setAnnotation( e.firstChildElement( "annotation" ).text() );
QString artist, album, track;
artist = e.firstChildElement( "creator" ).text();
album = e.firstChildElement( "album" ).text();
track = e.firstChildElement( "title" ).text();
p->setAnnotation( annotation );
p->setQuery( Tomahawk::Query::get( artist, track, album, uuid() ) );
p->query()->setDuration( e.firstChildElement( "duration" ).text().toInt() / 1000 );
p->query()->setDuration( duration.toInt() / 1000 );
m_entries << p;
}

View File

@ -25,6 +25,7 @@ public:
explicit XSPFLoader( bool autoCreate = true, QObject* parent = 0 )
: QObject( parent )
, m_autoCreate( autoCreate )
, m_NS("http://xspf.org/ns/0/")
{}
virtual ~XSPFLoader()
@ -51,6 +52,7 @@ private:
void gotBody();
bool m_autoCreate;
QString m_NS;
QList< Tomahawk::plentry_ptr > m_entries;
QString m_title, m_info, m_creator;

View File

@ -12,6 +12,7 @@ ScriptResolver::ScriptResolver(const QString& exe) :
, m_num_restarts( 0 )
, m_msgsize( 0 )
, m_ready( false )
, m_stopped( false )
{
qDebug() << Q_FUNC_INFO << exe;
connect( &m_proc, SIGNAL(readyReadStandardError()), SLOT(readStderr()) );
@ -116,6 +117,14 @@ void ScriptResolver::cmdExited(int code, QProcess::ExitStatus status)
qDebug() << Q_FUNC_INFO << "SCRIPT EXITED, code" << code << "status" << status << m_cmd;
Tomahawk::Pipeline::instance()->removeResolver( this );
if( m_stopped )
{
qDebug() << "*** Script resolver stopped ";
emit finished();
return;
}
if( m_num_restarts < 10 )
{
m_num_restarts++;
@ -154,3 +163,11 @@ void ScriptResolver::doSetup( const QVariantMap& m )
m_ready = true;
Tomahawk::Pipeline::instance()->addResolver( this );
}
void
ScriptResolver::stop()
{
m_stopped = true;
m_proc.kill();
}

View File

@ -25,9 +25,12 @@ public:
virtual void resolve( const Tomahawk::query_ptr& query );
void stop();
QString exe() const { return m_cmd; }
signals:
void finished();
public slots:
private slots:
@ -47,7 +50,7 @@ private:
quint32 m_msgsize;
QByteArray m_msg;
bool m_ready;
bool m_ready, m_stopped;
QJson::Parser m_parser;
QJson::Serializer m_serializer;

View File

@ -8,9 +8,12 @@
#include <QLineEdit>
JabberPlugin::JabberPlugin()
: p( 0 )
: p( 0 ),
m_menu ( 0 )
{
m_menu = new QMenu(QString("Jabber (").append(accountName()).append(")"));
if( !accountName().isEmpty() )
m_menu = new QMenu(QString("Jabber (").append(accountName()).append(")"));
m_addFriendAction = m_menu->addAction("Add Friend...");
connect(m_addFriendAction, SIGNAL(triggered()),

View File

@ -148,12 +148,11 @@ Jabber_p::go()
// Handle proxy
qDebug() << "Connecting to the XMPP server...";
//FIXME: This call blocks and locks up the whole GUI if the network is down
if( m_client->connect( false ) )
{
qDebug() << "Connected to the XMPP server";
emit connected();
QTimer::singleShot( 0, this, SLOT( doJabberRecv() ) );
int sock = static_cast<ConnectionTCPClient*>( m_client->connectionImpl() )->socket();
m_notifier.reset( new QSocketNotifier( sock, QSocketNotifier::Read ) );
connect( m_notifier.data(), SIGNAL( activated(int) ), SLOT( doJabberRecv() ));
}
else
qDebug() << "Could not connect to the XMPP server!";
@ -171,10 +170,6 @@ Jabber_p::doJabberRecv()
{
qDebug() << "Jabber_p::Recv failed, disconnected";
}
else
{
QTimer::singleShot( 100, this, SLOT( doJabberRecv() ) );
}
}
@ -260,6 +255,7 @@ Jabber_p::addContact( const QString& jid, const QString& msg )
void
Jabber_p::onConnect()
{
qDebug() << "Connected to the XMPP server";
// update jid resource, servers like gtalk use resource binding and may
// have changed our requested /resource
if ( m_client->resource() != m_jid.resource() )
@ -270,6 +266,7 @@ Jabber_p::onConnect()
}
qDebug() << "Connected as:" << m_jid.full().c_str();
emit connected();
}

View File

@ -7,7 +7,9 @@
#define JABBER_P_H
#include <QObject>
#include <QScopedPointer>
#include <QSharedPointer>
#include <QSocketNotifier>
#include <QMap>
#include <QNetworkProxy>
@ -137,6 +139,7 @@ private:
QMap<QString, gloox::Presence::PresenceType> m_peers;
QSharedPointer<gloox::VCardManager> m_vcardManager;
QString m_server;
QScopedPointer<QSocketNotifier> m_notifier;
};
#endif // JABBER_H

View File

@ -41,7 +41,7 @@ SourceTreeItem::SourceTreeItem( const source_ptr& source, QObject* parent )
SLOT( onPlaylistsAdded( QList<Tomahawk::playlist_ptr> ) ) );
connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ),
SLOT( onPlaylistsDeleted( QList<Tomahawk::playlist_ptr> ) ) );
connect( source->collection().data(), SIGNAL( dynamicPlaylistsAdded( QList<Tomahawk::dynplaylist_ptr> ) ),
SLOT( onDynamicPlaylistsAdded( QList<Tomahawk::dynplaylist_ptr> ) ) );
connect( source->collection().data(), SIGNAL( dynamicPlaylistsDeleted( QList<Tomahawk::dynplaylist_ptr> ) ),
@ -88,14 +88,14 @@ SourceTreeItem::onPlaylistsAdded( const QList<playlist_ptr>& playlists )
{
m_playlists.append( p );
qlonglong ptr = reinterpret_cast<qlonglong>( &m_playlists.last() );
qDebug() << "Setting playlist ptr to:" << ptr;
connect( p.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ),
SLOT( onPlaylistLoaded( Tomahawk::PlaylistRevision ) ),
Qt::QueuedConnection);
SLOT( onPlaylistLoaded( Tomahawk::PlaylistRevision ) ), Qt::QueuedConnection );
connect( p.data(), SIGNAL( changed() ),
SLOT( onPlaylistChanged() ), Qt::QueuedConnection );
qDebug() << "Playlist added:" << p->title() << p->creator() << p->info() << ptr;
playlistAddedInternal( ptr, p, false );
}
}
@ -109,7 +109,7 @@ SourceTreeItem::onPlaylistsDeleted( const QList<playlist_ptr>& playlists )
{
qlonglong ptr = qlonglong( p.data() );
qDebug() << "Playlist removed:" << p->title() << p->creator() << p->info() << ptr;
QStandardItem* item = m_columns.at( 0 );
int rows = item->rowCount();
for ( int i = rows - 1; i >= 0; i-- )
@ -118,7 +118,7 @@ SourceTreeItem::onPlaylistsDeleted( const QList<playlist_ptr>& playlists )
qlonglong piptr = pi->data( PlaylistPointer ).toLongLong();
playlist_ptr* pl = reinterpret_cast<playlist_ptr*>(piptr);
SourcesModel::SourceType type = static_cast<SourcesModel::SourceType>( pi->data( Type ).toInt() );
if ( type == SourcesModel::PlaylistSource && ptr == qlonglong( pl->data() ) )
{
m_playlists.removeAll( p );
@ -133,8 +133,7 @@ void
SourceTreeItem::onPlaylistLoaded( Tomahawk::PlaylistRevision revision )
{
qlonglong ptr = reinterpret_cast<qlonglong>( sender() );
qDebug() << "sender ptr:" << ptr;
QStandardItem* item = m_columns.at( 0 );
int rows = item->rowCount();
for ( int i = 0; i < rows; i++ )
@ -143,10 +142,9 @@ SourceTreeItem::onPlaylistLoaded( Tomahawk::PlaylistRevision revision )
qlonglong piptr = pi->data( PlaylistPointer ).toLongLong();
playlist_ptr* pl = reinterpret_cast<playlist_ptr*>(piptr);
SourcesModel::SourceType type = static_cast<SourcesModel::SourceType>( pi->data( Type ).toInt() );
if ( type == SourcesModel::PlaylistSource && ptr == qlonglong( pl->data() ) )
{
qDebug() << "Found normal playlist!";
pi->setEnabled( true );
m_current_revisions.insert( pl->data()->guid(), revision.revisionguid );
}
@ -154,6 +152,38 @@ SourceTreeItem::onPlaylistLoaded( Tomahawk::PlaylistRevision revision )
}
void
SourceTreeItem::onPlaylistChanged()
{
qlonglong ptr = reinterpret_cast<qlonglong>( sender() );
QStandardItem* item = m_columns.at( 0 );
int rows = item->rowCount();
for ( int i = 0; i < rows; i++ )
{
QStandardItem* pi = item->child( i );
SourcesModel::SourceType type = static_cast<SourcesModel::SourceType>( pi->data( Type ).toInt() );
if ( type == SourcesModel::PlaylistSource )
{
qlonglong piptr = pi->data( PlaylistPointer ).toLongLong();
playlist_ptr* pl = reinterpret_cast<playlist_ptr*>(piptr);
if ( ptr == qlonglong( pl->data() ) )
pi->setText( pl->data()->title() );
}
if ( type == SourcesModel::DynamicPlaylistSource )
{
qlonglong piptr = pi->data( DynamicPlaylistPointer ).toLongLong();
dynplaylist_ptr* pl = reinterpret_cast<dynplaylist_ptr*>(piptr);
if ( ptr == qlonglong( pl->data() ) )
pi->setText( pl->data()->title() );
}
}
}
void
SourceTreeItem::onDynamicPlaylistsAdded( const QList< dynplaylist_ptr >& playlists )
{
@ -162,13 +192,14 @@ SourceTreeItem::onDynamicPlaylistsAdded( const QList< dynplaylist_ptr >& playlis
{
m_dynplaylists.append( p );
qlonglong ptr = reinterpret_cast<qlonglong>( &m_dynplaylists.last() );
// qDebug() << "Setting dynamic ptr to:" << ptr;
connect( p.data(), SIGNAL( dynamicRevisionLoaded( Tomahawk::DynamicPlaylistRevision) ),
SLOT( onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision ) ),
Qt::QueuedConnection);
SLOT( onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision ) ), Qt::QueuedConnection );
connect( p.data(), SIGNAL( changed() ),
SLOT( onPlaylistChanged() ), Qt::QueuedConnection );
// qDebug() << "Dynamic Playlist added:" << p->title() << p->creator() << p->info() << p->currentrevision() << ptr;
playlistAddedInternal( ptr, p, true );
}
}
@ -182,7 +213,7 @@ SourceTreeItem::onDynamicPlaylistsDeleted( const QList< dynplaylist_ptr >& playl
{
qlonglong ptr = qlonglong( p.data() );
// qDebug() << "dynamic playlist removed:" << p->title() << p->creator() << p->info() << ptr;
QStandardItem* item = m_columns.at( 0 );
int rows = item->rowCount();
for ( int i = rows - 1; i >= 0; i-- )
@ -191,7 +222,8 @@ SourceTreeItem::onDynamicPlaylistsDeleted( const QList< dynplaylist_ptr >& playl
qlonglong piptr = pi->data( DynamicPlaylistPointer ).toLongLong();
dynplaylist_ptr* pl = reinterpret_cast<dynplaylist_ptr*>(piptr);
SourcesModel::SourceType type = static_cast<SourcesModel::SourceType>( pi->data( Type ).toInt() );
//qDebug() << "Deleting dynamic playlsit:" << pl->isNull();
//qDebug() << "Deleting dynamic playlist:" << pl->isNull();
if ( type == SourcesModel::DynamicPlaylistSource && ptr == qlonglong( pl->data() ) )
{
m_dynplaylists.removeAll( p );
@ -206,7 +238,7 @@ void
SourceTreeItem::onDynamicPlaylistLoaded( DynamicPlaylistRevision revision )
{
qlonglong ptr = reinterpret_cast<qlonglong>( sender() );
QStandardItem* item = m_columns.at( 0 );
int rows = item->rowCount();
for ( int i = 0; i < rows; i++ )
@ -215,10 +247,9 @@ SourceTreeItem::onDynamicPlaylistLoaded( DynamicPlaylistRevision revision )
qlonglong piptr = pi->data( DynamicPlaylistPointer ).toLongLong();
playlist_ptr* pl = reinterpret_cast<playlist_ptr*>(piptr);
SourcesModel::SourceType type = static_cast<SourcesModel::SourceType>( pi->data( Type ).toInt() );
// qDebug() << "found dynamic playlist:" << (*pl)->title() << type;
if ( type == SourcesModel::DynamicPlaylistSource && ptr == qlonglong( pl->data() ) )
{
//qDebug() << "Found dynamicplaylist!";
pi->setEnabled( true );
m_current_dynamic_revisions.insert( pl->data()->guid(), revision.revisionguid );
}
@ -235,10 +266,10 @@ void SourceTreeItem::playlistAddedInternal( qlonglong ptr, const Tomahawk::playl
subitem->setData( ptr, dynamic ? DynamicPlaylistPointer : PlaylistPointer );
subitem->setData( dynamic ? SourcesModel::DynamicPlaylistSource : SourcesModel::PlaylistSource, Type );
subitem->setData( (qlonglong)this, SourceItemPointer );
m_columns.at( 0 )->appendRow( subitem );
// Q_ASSERT( qobject_cast<QTreeView*>((parent()->parent()) ) );
// qobject_cast<QTreeView*>((parent()->parent()))->expandAll();
p->loadRevision();
}

View File

@ -47,13 +47,15 @@ private slots:
void onPlaylistsAdded( const QList<Tomahawk::playlist_ptr>& playlists );
void onPlaylistsDeleted( const QList<Tomahawk::playlist_ptr>& playlists );
void onPlaylistLoaded( Tomahawk::PlaylistRevision revision );
void onPlaylistChanged();
void onDynamicPlaylistsAdded( const QList<Tomahawk::dynplaylist_ptr>& playlists );
void onDynamicPlaylistsDeleted( const QList<Tomahawk::dynplaylist_ptr>& playlists );
void onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision revision );
private:
void playlistAddedInternal( qlonglong ptr, const Tomahawk::playlist_ptr& pl, bool dynamic );
QList<QStandardItem*> m_columns;
Tomahawk::source_ptr m_source;
SourceTreeItemWidget* m_widget;

View File

@ -407,8 +407,8 @@ TomahawkApp::removeScriptResolver( const QString& path )
foreach( ScriptResolver* r, m_scriptResolvers ) {
if( r->exe() == path ) {
m_scriptResolvers.removeAll( r );
delete r;
connect( r, SIGNAL( finished() ), r, SLOT( deleteLater() ) );
r->stop();
return;
}
}
@ -422,7 +422,7 @@ TomahawkApp::initLocalCollection()
src->addCollection( coll );
SourceList::instance()->setLocal( src );
src->collection()->tracks();
// src->collection()->tracks();
// to make the stats signal be emitted by our local source
// this will update the sidebar, etc.

View File

@ -39,6 +39,10 @@
#include "playlist/dynamic/GeneratorInterface.h"
#include "scanmanager.h"
#ifdef Q_OS_WIN32
#include <qtsparkle/Updater>
#endif
using namespace Tomahawk;
@ -123,11 +127,25 @@ TomahawkWindow::TomahawkWindow( QWidget* parent )
toolbar->setIconSize( QSize( 32, 32 ) );
toolbar->setToolButtonStyle( Qt::ToolButtonFollowStyle );
toolbar->installEventFilter( new WidgetDragFilter( toolbar ) );
#if defined( Q_OS_DARWIN ) && defined( HAVE_SPARKLE )
QAction* checkForUpdates = ui->menu_Help->addAction( tr( "Check for updates...") );
checkForUpdates->setMenuRole( QAction::ApplicationSpecificRole );
connect(checkForUpdates, SIGNAL( triggered( bool ) ), SLOT( checkForUpdates() ) );
QAction* checkForUpdates = ui->menu_Help->addAction( tr( "Check for updates...") );
checkForUpdates->setMenuRole( QAction::ApplicationSpecificRole );
connect(checkForUpdates, SIGNAL( triggered( bool ) ), SLOT( checkForUpdates() ) );
#elif defined( WIN32 )
QUrl updaterUrl;
#ifdef DEBUG_BUILD
updaterUrl.setUrl( "http://download.tomahawk-player.org/sparklewin-debug" );
#else
updaterUrl.setUrl( "http://download.tomahawk-player.org/sparklewin" );
#endif
qtsparkle::Updater* updater = new qtsparkle::Updater( updaterUrl, this );
updater->SetNetworkAccessManager( TomahawkUtils::nam() );
updater->SetVersion( VERSION );
ui->menu_Help->addSeparator();
QAction* checkForUpdates = ui->menu_Help->addAction( tr( "Check for updates...") );
connect( checkForUpdates, SIGNAL( triggered() ), updater, SLOT( CheckNow() ) );
#endif
m_backAvailable = toolbar->addAction( QIcon( RESPATH "images/back.png" ), tr( "Back" ), PlaylistManager::instance(), SLOT( historyBack() ) );
@ -163,12 +181,33 @@ TomahawkWindow::loadSettings()
{
TomahawkSettings* s = TomahawkSettings::instance();
// Workaround for broken window geometry restoring on Qt Cocoa when setUnifiedTitleAndToolBarOnMac is true.
// See http://bugreports.qt.nokia.com/browse/QTBUG-3116 and
// http://lists.qt.nokia.com/pipermail/qt-interest/2009-August/011491.html
// for the 'fix'
#ifdef QT_MAC_USE_COCOA
bool workaround = !isVisible();
if( workaround ) {
// make "invisible"
setWindowOpacity( 0 );
// let Qt update its frameStruts
show();
}
#endif
if ( !s->mainWindowGeometry().isEmpty() )
restoreGeometry( s->mainWindowGeometry() );
if ( !s->mainWindowState().isEmpty() )
restoreState( s->mainWindowState() );
if ( !s->mainWindowSplitterState().isEmpty() )
ui->splitter->restoreState( s->mainWindowSplitterState() );
#ifdef QT_MAC_USE_COCOA
if( workaround ) {
// Make it visible again
setWindowOpacity( 1 );
}
#endif
}
@ -329,6 +368,7 @@ TomahawkWindow::createAutomaticPlaylist()
dynplaylist_ptr playlist = DynamicPlaylist::create( author, id, name, info, creator, false );
playlist->setMode( Static );
playlist->createNewRevision( uuid(), playlist->currentrevision(), playlist->type(), playlist->generator()->controls(), playlist->entries() );
PlaylistManager::instance()->show( playlist );
}
@ -347,6 +387,7 @@ TomahawkWindow::createStation()
dynplaylist_ptr playlist = DynamicPlaylist::create( author, id, name, info, creator, false );
playlist->setMode( OnDemand );
playlist->createNewRevision( uuid(), playlist->currentrevision(), playlist->type(), playlist->generator()->controls() );
PlaylistManager::instance()->show( playlist );
}
@ -425,7 +466,7 @@ TomahawkWindow::showAboutTomahawk()
{
QMessageBox::about( this, "About Tomahawk",
tr( "<h2><b>Tomahawk %1</h2>Copyright 2010, 2011<br/>Christian Muehlhaeuser &lt;muesli@tomahawk-player.org&gt;<br/><br/>"
"Thanks to: Leo Franchi, Jeff Mitchell, Dominik Schmidt, Alejandro Wainzinger, Harald Sitter and Steve Robertson" )
"Thanks to: Leo Franchi, Jeff Mitchell, Dominik Schmidt, Jason Herskowitz, Alejandro Wainzinger, Harald Sitter and Steve Robertson" )
.arg( qApp->applicationVersion() ) );
}

View File

@ -1,10 +1,11 @@
#include "api_v1.h"
#include <QHash>
void
Api_v1::auth_1( QxtWebRequestEvent* event )
Api_v1::auth_1( QxtWebRequestEvent* event, QString arg )
{
qDebug() << "AUTH_1 HTTP" << event->url.toString();
qDebug() << "AUTH_1 HTTP" << event->url.toString() << arg;
if ( !event->url.hasQueryItem( "website" ) || !event->url.hasQueryItem( "name" ) )
{
@ -38,29 +39,37 @@ Api_v1::auth_1( QxtWebRequestEvent* event )
void
Api_v1::auth_2( QxtWebRequestEvent* event )
Api_v1::auth_2( QxtWebRequestEvent* event, QString arg )
{
qDebug() << "AUTH_2 HTTP" << event->url.toString();
QUrl url = event->url;
url.setEncodedQuery( event->content->readAll() );
if( !url.hasQueryItem( "website" ) || !url.hasQueryItem( "name" ) || !url.hasQueryItem( "formtoken" ) )
qDebug() << "AUTH_2 HTTP" << event->url.toString() << arg;
QString params = QUrl::fromPercentEncoding( event->content->readAll() );
params = params.mid( params.indexOf( '?' ) );
QStringList pieces = params.split( '&' );
QHash< QString, QString > queryItems;
foreach( const QString& part, pieces ) {
QStringList keyval = part.split( '=' );
if( keyval.size() == 2 )
queryItems.insert( keyval.first(), keyval.last() );
else
qDebug() << "Failed parsing url parameters: " << part;
}
qDebug() << "has query items:" << pieces;
if( !params.contains( "website" ) || !params.contains( "name" ) || !params.contains( "formtoken" ) )
{
qDebug() << "Malformed HTTP resolve request";
qDebug() << url.hasQueryItem( "website" ) << url.hasQueryItem( "name" ) << url.hasQueryItem( "formtoken" );
send404( event );
return;
}
QString website = QUrl::fromPercentEncoding( url.queryItemValue( "website" ).toUtf8() );
QString name = QUrl::fromPercentEncoding( url.queryItemValue( "name" ).toUtf8() );
QString website = queryItems[ "website" ];
QString name = queryItems[ "name" ];
QByteArray authtoken = uuid().toLatin1();
qDebug() << "HEADERS:" << event->headers;
if( !url.hasQueryItem( "receiverurl" ) && url.queryItemValue( "receiverurl" ).isEmpty() )
if( !queryItems.contains( "receiverurl" ) || queryItems.value( "receiverurl" ).isEmpty() )
{
//no receiver url, so do it ourselves
QString receiverUrl = QUrl::fromPercentEncoding( url.queryItemValue( "receiverurl" ).toUtf8() );
if( url.hasQueryItem( "json" ) )
if( queryItems.contains( "json" ) )
{
QVariantMap m;
m[ "authtoken" ] = authtoken;
@ -71,16 +80,16 @@ Api_v1::auth_2( QxtWebRequestEvent* event )
{
QString authPage = RESPATH "www/auth.na.html";
QHash< QString, QString > args;
args[ "authcode" ] = authPage;
args[ "website" ] = QUrl::fromPercentEncoding( url.queryItemValue( "website" ).toUtf8() );
args[ "name" ] = QUrl::fromPercentEncoding( url.queryItemValue( "name" ).toUtf8() );
args[ "authcode" ] = authtoken;
args[ "website" ] = website;
args[ "name" ] = name;
sendWebpageWithArgs( event, authPage, args );
}
}
else
{
// do what the client wants
QUrl receiverurl = QUrl( url.queryItemValue( "receiverurl" ).toUtf8(), QUrl::TolerantMode );
QUrl receiverurl = QUrl( queryItems.value( "receiverurl" ), QUrl::TolerantMode );
receiverurl.addEncodedQueryItem( "authtoken", "#" + authtoken );
qDebug() << "Got receiver url:" << receiverurl.toString();
@ -308,6 +317,10 @@ Api_v1::sendWebpageWithArgs( QxtWebRequestEvent* event, const QString& filenameS
{
html.replace( QString( "<%%1%>" ).arg( param.toUpper() ), args.value( param ).toUtf8() );
}
// workaround for receiverurl
if( !args.keys().contains( "URL" ) )
html.replace( QString( "<%URL%>" ).toLatin1(), QByteArray() );
QxtWebPageEvent* e = new QxtWebPageEvent( event->sessionID, event->requestID, html );
postEvent( e );

View File

@ -41,8 +41,8 @@ public:
public slots:
// authenticating uses /auth_1
// we redirect to /auth_2 for the callback
void auth_1( QxtWebRequestEvent* event );
void auth_2( QxtWebRequestEvent* event );
void auth_1( QxtWebRequestEvent* event, QString unused = QString() );
void auth_2( QxtWebRequestEvent* event, QString unused = QString() );
// all v1 api calls go to /api/
void api( QxtWebRequestEvent* event );