mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-09-12 23:12:05 +02:00
Compare commits
124 Commits
threadedau
...
0.3.2
Author | SHA1 | Date | |
---|---|---|---|
|
a05972e9ce | ||
|
5157e13ba1 | ||
|
9f97afc148 | ||
|
8b1b0091c6 | ||
|
3e9aee3687 | ||
|
48bb0a82f9 | ||
|
1efdf38085 | ||
|
3e4f4d2f38 | ||
|
a2f870f2b8 | ||
|
2ac167d438 | ||
|
c218695a3d | ||
|
fae5f1dbbe | ||
|
54d29cc05d | ||
|
5aea02def2 | ||
|
368aa20b75 | ||
|
d2a07f2b6c | ||
|
14253a9c66 | ||
|
6881f4218a | ||
|
17badb972e | ||
|
2ea09dd60d | ||
|
87f7b6b2c6 | ||
|
01986a4129 | ||
|
2b404b517f | ||
|
b21b2d10f7 | ||
|
04deaba788 | ||
|
5cabc62733 | ||
|
01c6c3f0b6 | ||
|
b1a5cd4dcb | ||
|
58f78725db | ||
|
4210e8eab8 | ||
|
115492d1cc | ||
|
edadbb0c95 | ||
|
6c67dfcab7 | ||
|
b9453ab77b | ||
|
9507ffdd86 | ||
|
ff768954f6 | ||
|
15729bb66a | ||
|
41f46aaeea | ||
|
9e0d884f80 | ||
|
d34491b85f | ||
|
45070fb4e1 | ||
|
18612b48d3 | ||
|
a38c0a544d | ||
|
d38c9730fb | ||
|
d25320833c | ||
|
d38600dd6a | ||
|
6fa48587e1 | ||
|
8da0f3e9a3 | ||
|
ab402c0867 | ||
|
545a915439 | ||
|
d026902d91 | ||
|
ff72157c5f | ||
|
faab306dbe | ||
|
57fef9f3f2 | ||
|
89fac77951 | ||
|
ef02e9b4ac | ||
|
99b09c1faa | ||
|
d66e86f5c6 | ||
|
9bd46984e0 | ||
|
3992392245 | ||
|
198e92bc2c | ||
|
2f899eed2a | ||
|
8cdd4bdea3 | ||
|
3d53b0c251 | ||
|
0ac9512eb9 | ||
|
3f0ac7c666 | ||
|
faf7d00fdd | ||
|
b31abb0979 | ||
|
f2009cf99b | ||
|
0d97a47cc5 | ||
|
7db6beb896 | ||
|
e56a629ad7 | ||
|
ef918bbbcf | ||
|
60911ab887 | ||
|
e10a96ecd5 | ||
|
e99973925a | ||
|
949c6f6341 | ||
|
e041723ffc | ||
|
89919928da | ||
|
d4fc504f3d | ||
|
05924b8deb | ||
|
6d4aa50596 | ||
|
7ee2755617 | ||
|
35406ceb5a | ||
|
9efb536e55 | ||
|
b8d27f1811 | ||
|
0939ba0705 | ||
|
3788bc7cbf | ||
|
54723abc07 | ||
|
900f57437f | ||
|
300c9d5d68 | ||
|
96c9996284 | ||
|
8a15bcaa66 | ||
|
d17d67869c | ||
|
c491f33ce4 | ||
|
1dee5c809c | ||
|
924ede61b4 | ||
|
0d64d9c42d | ||
|
6b6fb909cd | ||
|
b51ff46085 | ||
|
46ec23990f | ||
|
eb46feac2c | ||
|
2c206f4193 | ||
|
c1bd19b35b | ||
|
370154cc46 | ||
|
9a81ce8b89 | ||
|
c805d283d4 | ||
|
03379f361c | ||
|
c671c0e898 | ||
|
edaf49b4c5 | ||
|
682903b0cb | ||
|
53f7f599d5 | ||
|
cc669fc20f | ||
|
4e7496a38a | ||
|
5842cdceee | ||
|
b7e0be8d9d | ||
|
a203b60cbb | ||
|
2be08af321 | ||
|
ad4c229a6b | ||
|
b2e0206e34 | ||
|
743ae013ea | ||
|
767cf7c1b9 | ||
|
6be94ab81c | ||
|
b1ed304a61 |
@@ -16,7 +16,7 @@ SET( TOMAHAWK_DESCRIPTION_SUMMARY "The social media player" )
|
||||
|
||||
SET( TOMAHAWK_VERSION_MAJOR 0 )
|
||||
SET( TOMAHAWK_VERSION_MINOR 3 )
|
||||
SET( TOMAHAWK_VERSION_PATCH 99 )
|
||||
SET( TOMAHAWK_VERSION_PATCH 2 )
|
||||
|
||||
#SET( TOMAHAWK_VERSION_RC 0 )
|
||||
|
||||
@@ -108,7 +108,7 @@ macro_optional_find_package(LibAttica)
|
||||
macro_log_feature(LIBATTICA_FOUND "libattica" "Provides support for automatic fetching and managing of resolvers from the tomahawk website" "https://projects.kde.org/projects/kdesupport/attica" FALSE "" "")
|
||||
|
||||
macro_optional_find_package(QuaZip)
|
||||
macro_log_feature(QuaZip_FOUND "QuaZip" "Provides support for extracting downloaded resolvers autmatically. Will build internal copy instead." "http://quazip.sourceforge.net/" FALSE "" "")
|
||||
macro_log_feature(QuaZip_FOUND "QuaZip" "Provides support for extracting downloaded resolvers automatically." "http://quazip.sourceforge.net/" FALSE "" "")
|
||||
|
||||
IF( NOT QuaZip_FOUND )
|
||||
add_subdirectory( ${CMAKE_SOURCE_DIR}/src/libtomahawk/thirdparty/quazip )
|
||||
@@ -116,6 +116,7 @@ IF( NOT QuaZip_FOUND )
|
||||
SET( QuaZip_LIBRARY quazip )
|
||||
SET( QuaZip_LIBRARIES ${QuaZip_LIBRARY} )
|
||||
SET( QuaZip_FOUND true )
|
||||
macro_log_feature(QuaZip_FOUND "QuaZip" "Provides support for extracting downloaded resolvers automatically. Building internal copy" "http://quazip.sourceforge.net/" FALSE "" "")
|
||||
|
||||
# copy headers to build/quazip so we can use proper includes inside the code
|
||||
FILE( COPY ${CMAKE_SOURCE_DIR}/src/libtomahawk/thirdparty/quazip/quazip/ DESTINATION ${CMAKE_BINARY_DIR}/libtomahawk/thirdparty/quazip )
|
||||
@@ -211,6 +212,7 @@ ADD_SUBDIRECTORY( src/libtomahawk )
|
||||
SET( TOMAHAWK_LIBRARIES tomahawklib )
|
||||
ADD_SUBDIRECTORY( src )
|
||||
ADD_SUBDIRECTORY( admin )
|
||||
IF(BUILD_GUI)
|
||||
|
||||
IF( NOT DISABLE_CRASHREPORTER )
|
||||
ADD_SUBDIRECTORY( src/breakpad/CrashReporter )
|
||||
ENDIF()
|
||||
|
@@ -2,6 +2,7 @@
|
||||
# This module looks for clucene (http://clucene.sf.net) support
|
||||
# It will define the following values
|
||||
#
|
||||
# CLUCENE_INCLUDE_DIRS = CLUCENE_INCLUDE_DIR + CLUCENE_LIBRARY_DIR
|
||||
# CLUCENE_INCLUDE_DIR = where CLucene/StdHeader.h can be found
|
||||
# CLUCENE_LIBRARY_DIR = where CLucene/clucene-config.h can be found
|
||||
# CLUCENE_LIBRARIES = the libraries to link against CLucene
|
||||
@@ -17,6 +18,7 @@ FIND_PACKAGE(CLuceneUnstable)
|
||||
IF(CLUCENEUNSTABLE_FOUND)
|
||||
SET(CLucene_FOUND TRUE)
|
||||
SET(CLUCENE_INCLUDE_DIR ${CLUCENE_UNSTABLE_INCLUDE_DIRS})
|
||||
SET(CLUCENE_INCLUDE_DIRS ${CLUCENE_INCLUDE_DIR})
|
||||
SET(CLUCENE_LIBRARIES ${CLUCENE_UNSTABLE_LIBS})
|
||||
|
||||
#MESSAGE(FATAL_ERROR NARF)
|
||||
@@ -106,7 +108,9 @@ ENDIF (CLUCENE_LIBRARY_DIR)
|
||||
|
||||
IF(CLUCENE_INCLUDE_DIR AND CLUCENE_LIBRARIES AND CLUCENE_LIBRARY_DIR AND CLUCENE_GOOD_VERSION)
|
||||
SET(CLucene_FOUND TRUE)
|
||||
SET(CLUCENE_INCLUDE_DIRS ${CLUCENE_LIBRARY_DIR} ${CLUCENE_INCLUDE_DIR})
|
||||
ENDIF(CLUCENE_INCLUDE_DIR AND CLUCENE_LIBRARIES AND CLUCENE_LIBRARY_DIR AND CLUCENE_GOOD_VERSION)
|
||||
|
||||
ENDIF(CLUCENEUNSTABLE_FOUND)
|
||||
|
||||
IF(CLucene_FOUND)
|
||||
@@ -120,7 +124,8 @@ ELSE(CLucene_FOUND)
|
||||
ENDIF(CLucene_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
CLUCENE_INCLUDE_DIR
|
||||
CLUCENE_LIBRARY_DIR
|
||||
CLUCENE_INCLUDE_DIRS
|
||||
CLUCENE_INCLUDE_DIR
|
||||
CLUCENE_LIBRARY_DIR
|
||||
CLUCENE_LIBRARIES
|
||||
)
|
||||
|
182
CMakeModules/GNUInstallDirs.cmake
Normal file
182
CMakeModules/GNUInstallDirs.cmake
Normal file
@@ -0,0 +1,182 @@
|
||||
# - Define GNU standard installation directories
|
||||
# Provides install directory variables as defined for GNU software:
|
||||
# http://www.gnu.org/prep/standards/html_node/Directory-Variables.html
|
||||
# Inclusion of this module defines the following variables:
|
||||
# CMAKE_INSTALL_<dir> - destination for files of a given type
|
||||
# CMAKE_INSTALL_FULL_<dir> - corresponding absolute path
|
||||
# where <dir> is one of:
|
||||
# BINDIR - user executables (bin)
|
||||
# SBINDIR - system admin executables (sbin)
|
||||
# LIBEXECDIR - program executables (libexec)
|
||||
# SYSCONFDIR - read-only single-machine data (etc)
|
||||
# SHAREDSTATEDIR - modifiable architecture-independent data (com)
|
||||
# LOCALSTATEDIR - modifiable single-machine data (var)
|
||||
# LIBDIR - object code libraries (lib or lib64)
|
||||
# INCLUDEDIR - C header files (include)
|
||||
# OLDINCLUDEDIR - C header files for non-gcc (/usr/include)
|
||||
# DATAROOTDIR - read-only architecture-independent data root (share)
|
||||
# DATADIR - read-only architecture-independent data (DATAROOTDIR)
|
||||
# INFODIR - info documentation (DATAROOTDIR/info)
|
||||
# LOCALEDIR - locale-dependent data (DATAROOTDIR/locale)
|
||||
# MANDIR - man documentation (DATAROOTDIR/man)
|
||||
# DOCDIR - documentation root (DATAROOTDIR/doc/PROJECT_NAME)
|
||||
# Each CMAKE_INSTALL_<dir> value may be passed to the DESTINATION options of
|
||||
# install() commands for the corresponding file type. If the includer does
|
||||
# not define a value the above-shown default will be used and the value will
|
||||
# appear in the cache for editing by the user.
|
||||
# Each CMAKE_INSTALL_FULL_<dir> value contains an absolute path constructed
|
||||
# from the corresponding destination by prepending (if necessary) the value
|
||||
# of CMAKE_INSTALL_PREFIX.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Nikita Krupen'ko <krnekit@gmail.com>
|
||||
# Copyright 2011 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# Installation directories
|
||||
#
|
||||
if(NOT DEFINED CMAKE_INSTALL_BINDIR)
|
||||
set(CMAKE_INSTALL_BINDIR "bin" CACHE PATH "user executables (bin)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SBINDIR)
|
||||
set(CMAKE_INSTALL_SBINDIR "sbin" CACHE PATH "system admin executables (sbin)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBEXECDIR)
|
||||
set(CMAKE_INSTALL_LIBEXECDIR "libexec" CACHE PATH "program executables (libexec)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
|
||||
set(CMAKE_INSTALL_SYSCONFDIR "etc" CACHE PATH "read-only single-machine data (etc)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SHAREDSTATEDIR)
|
||||
set(CMAKE_INSTALL_SHAREDSTATEDIR "com" CACHE PATH "modifiable architecture-independent data (com)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LOCALSTATEDIR)
|
||||
set(CMAKE_INSTALL_LOCALSTATEDIR "var" CACHE PATH "modifiable single-machine data (var)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
|
||||
set(_LIBDIR_DEFAULT "lib")
|
||||
# Override this default 'lib' with 'lib64' iff:
|
||||
# - we are on Linux system but NOT cross-compiling
|
||||
# - we are NOT on debian
|
||||
# - we are on a 64 bits system
|
||||
# reason is: amd64 ABI: http://www.x86-64.org/documentation/abi.pdf
|
||||
# Note that the future of multi-arch handling may be even
|
||||
# more complicated than that: http://wiki.debian.org/Multiarch
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux"
|
||||
AND NOT CMAKE_CROSSCOMPILING
|
||||
AND NOT EXISTS "/etc/debian_version")
|
||||
if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
|
||||
message(AUTHOR_WARNING
|
||||
"Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
|
||||
"Please enable at least one language before including GNUInstallDirs.")
|
||||
else()
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
set(_LIBDIR_DEFAULT "lib64")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_INSTALL_LIBDIR "${_LIBDIR_DEFAULT}" CACHE PATH "object code libraries (${_LIBDIR_DEFAULT})")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
|
||||
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "C header files (include)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_OLDINCLUDEDIR)
|
||||
set(CMAKE_INSTALL_OLDINCLUDEDIR "/usr/include" CACHE PATH "C header files for non-gcc (/usr/include)")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_DATAROOTDIR)
|
||||
set(CMAKE_INSTALL_DATAROOTDIR "share" CACHE PATH "read-only architecture-independent data root (share)")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Values whose defaults are relative to DATAROOTDIR. Store empty values in
|
||||
# the cache and store the defaults in local variables if the cache values are
|
||||
# not set explicitly. This auto-updates the defaults as DATAROOTDIR changes.
|
||||
|
||||
if(NOT CMAKE_INSTALL_DATADIR)
|
||||
set(CMAKE_INSTALL_DATADIR "" CACHE PATH "read-only architecture-independent data (DATAROOTDIR)")
|
||||
set(CMAKE_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_INFODIR)
|
||||
set(CMAKE_INSTALL_INFODIR "" CACHE PATH "info documentation (DATAROOTDIR/info)")
|
||||
set(CMAKE_INSTALL_INFODIR "${CMAKE_INSTALL_DATAROOTDIR}/info")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_LOCALEDIR)
|
||||
set(CMAKE_INSTALL_LOCALEDIR "" CACHE PATH "locale-dependent data (DATAROOTDIR/locale)")
|
||||
set(CMAKE_INSTALL_LOCALEDIR "${CMAKE_INSTALL_DATAROOTDIR}/locale")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_MANDIR)
|
||||
set(CMAKE_INSTALL_MANDIR "" CACHE PATH "man documentation (DATAROOTDIR/man)")
|
||||
set(CMAKE_INSTALL_MANDIR "${CMAKE_INSTALL_DATAROOTDIR}/man")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_INSTALL_DOCDIR)
|
||||
set(CMAKE_INSTALL_DOCDIR "" CACHE PATH "documentation root (DATAROOTDIR/doc/PROJECT_NAME)")
|
||||
set(CMAKE_INSTALL_DOCDIR "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
mark_as_advanced(
|
||||
CMAKE_INSTALL_BINDIR
|
||||
CMAKE_INSTALL_SBINDIR
|
||||
CMAKE_INSTALL_LIBEXECDIR
|
||||
CMAKE_INSTALL_SYSCONFDIR
|
||||
CMAKE_INSTALL_SHAREDSTATEDIR
|
||||
CMAKE_INSTALL_LOCALSTATEDIR
|
||||
CMAKE_INSTALL_LIBDIR
|
||||
CMAKE_INSTALL_INCLUDEDIR
|
||||
CMAKE_INSTALL_OLDINCLUDEDIR
|
||||
CMAKE_INSTALL_DATAROOTDIR
|
||||
CMAKE_INSTALL_DATADIR
|
||||
CMAKE_INSTALL_INFODIR
|
||||
CMAKE_INSTALL_LOCALEDIR
|
||||
CMAKE_INSTALL_MANDIR
|
||||
CMAKE_INSTALL_DOCDIR
|
||||
)
|
||||
|
||||
# Result directories
|
||||
#
|
||||
foreach(dir
|
||||
BINDIR
|
||||
SBINDIR
|
||||
LIBEXECDIR
|
||||
SYSCONFDIR
|
||||
SHAREDSTATEDIR
|
||||
LOCALSTATEDIR
|
||||
LIBDIR
|
||||
INCLUDEDIR
|
||||
OLDINCLUDEDIR
|
||||
DATAROOTDIR
|
||||
DATADIR
|
||||
INFODIR
|
||||
LOCALEDIR
|
||||
MANDIR
|
||||
DOCDIR
|
||||
)
|
||||
if(NOT IS_ABSOLUTE ${CMAKE_INSTALL_${dir}})
|
||||
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_${dir}}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_FULL_${dir} "${CMAKE_INSTALL_${dir}}")
|
||||
endif()
|
||||
endforeach()
|
@@ -273,7 +273,7 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
;Main executable.
|
||||
File "${INSTALL_PATH}\bin\tomahawk.exe"
|
||||
|
||||
File "${INSTALL_PATH}\bin\CrashReporter.exe"
|
||||
File "${INSTALL_PATH}\bin\tomahawk_crash_reporter.exe"
|
||||
File "${INSTALL_PATH}\bin\libtomahawk_breakpad.dll"
|
||||
|
||||
File "${INSTALL_PATH}\bin\libqxtweb-standalone.dll"
|
||||
@@ -287,7 +287,7 @@ Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
;Main executable.
|
||||
File "${BUILD_PATH}\tomahawk.exe"
|
||||
|
||||
File "${BUILD_PATH}\CrashReporter.exe"
|
||||
File "${BUILD_PATH}\tomahawk_crash_reporter.exe"
|
||||
File "${BUILD_PATH}\libtomahawk_breakpad.dll"
|
||||
|
||||
File "${BUILD_PATH}\libtomahawklib.dll"
|
||||
|
28
ChangeLog
28
ChangeLog
@@ -1,3 +1,29 @@
|
||||
Version 0.3.2:
|
||||
* Improved syncing process, it's faster and more reliable now.
|
||||
* Fixed UPnP issues.
|
||||
* Fixed not updating collections and views after a collection changes.
|
||||
* Fixed not showing a source's proper name at all times.
|
||||
* Improved music scanner reliability.
|
||||
* Fixed various labels not being painted in the right color when selected.
|
||||
* Support .oga (ogg mimetype) files.
|
||||
* Fixed stuck Now Playing indicator icon.
|
||||
* Fixed sidebar width of settings dialog on Windows.
|
||||
* Fixed not always showing delete icon on hovered temporary pages.
|
||||
* Fixed inability to select externally mounted drives.
|
||||
* Fixed bug where speaker would be stuck next to a playlist.
|
||||
* Fixed bug where first startup would show a loading spinner in the
|
||||
Dashboard's "Recent Additions" forever.
|
||||
* Automatically upgrade resolvers when an update is found.
|
||||
* Fixed last played track of a friend never expiring.
|
||||
* Fixed parsing of rdio tracks.
|
||||
* Changed steering mechanism in stations to be user-friendlier.
|
||||
* Fixed loading biographies of artist names with special characters.
|
||||
* Fixed behaviour of dropping Spotify playlists on the sidebar.
|
||||
* Fixed hard to read source-name in the audio control area on OS X.
|
||||
* Fixed crashes when playing Grooveshark tracks.
|
||||
* Fixed bug where clicking the latch button would flicker and unlatch.
|
||||
* Fixed Jabber accounts not connecting properly when proxy is in use.
|
||||
|
||||
Version 0.3.1:
|
||||
* Fixed not resolving to local files.
|
||||
* Fixed shutdown crash on Windows.
|
||||
@@ -26,7 +52,7 @@ Version 0.3.0:
|
||||
* Added YouTube resolver.
|
||||
* Fixed bug where going offline then online would not re-connect to many
|
||||
peers.
|
||||
* Added support for auto-updating live XSPF playlists.
|
||||
* Added support for auto-updating live XSPF playlists.
|
||||
* Don't show an age of 41 years for tracks that have no age information.
|
||||
* Show config UI for resolvers that have them as soon as you add them.
|
||||
* Add support for Echo Nest Personal Catalogs and User Radio. Synchronize
|
||||
|
@@ -250,7 +250,7 @@ frameworks_dir = os.path.join(bundle_dir, 'Contents', 'Frameworks')
|
||||
commands.append(['mkdir', '-p', frameworks_dir])
|
||||
resources_dir = os.path.join(bundle_dir, 'Contents', 'Resources')
|
||||
commands.append(['mkdir', '-p', resources_dir])
|
||||
plugins_dir = os.path.join(bundle_dir, 'Contents', 'PlugIns')
|
||||
plugins_dir = os.path.join(bundle_dir, 'Contents', 'plugins')
|
||||
binary = os.path.join(bundle_dir, 'Contents', 'MacOS', bundle_name)
|
||||
|
||||
fixed_libraries = []
|
||||
@@ -502,9 +502,9 @@ except:
|
||||
print 'Failed to find spotify resolver'
|
||||
|
||||
try:
|
||||
FixPlugin('CrashReporter', '../MacOS')
|
||||
FixPlugin('tomahawk_crash_reporter', '../MacOS')
|
||||
except:
|
||||
print 'Failed to find CrashReporter'
|
||||
print 'Failed to find tomahawk_crash_reporter'
|
||||
|
||||
for plugin in QT_PLUGINS:
|
||||
FixPlugin(FindQtPlugin(plugin), os.path.dirname(plugin))
|
||||
|
BIN
data/images/apply-check.png
Normal file
BIN
data/images/apply-check.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
3028
lang/tomahawk_en.ts
Normal file
3028
lang/tomahawk_en.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/lang">
|
||||
<file>tomahawk_de.qm</file>
|
||||
<file>tomahawk_en.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -98,6 +98,7 @@
|
||||
<file>data/images/track-icon-22x22.png</file>
|
||||
<file>data/images/track-icon-32x32.png</file>
|
||||
<file>data/images/track-icon-16x16.png</file>
|
||||
<file>data/images/apply-check.png</file>
|
||||
<file>data/stylesheets/topbar-radiobuttons.css</file>
|
||||
<file>data/icons/tomahawk-icon-16x16.png</file>
|
||||
<file>data/icons/tomahawk-icon-32x32.png</file>
|
||||
|
@@ -97,8 +97,8 @@ IF(LIBLASTFM_FOUND)
|
||||
ENDIF(LIBLASTFM_FOUND)
|
||||
|
||||
IF(LIBATTICA_FOUND)
|
||||
SET( tomahawkSourcesGui ${tomahawkSourcesGui} GetNewStuffDialog.cpp GetNewStuffDelegate.cpp GetNewStuffModel.cpp )
|
||||
SET( tomahawkHeadersGui ${tomahawkHeadersGui} GetNewStuffDialog.h GetNewStuffDelegate.h GetNewStuffModel.h )
|
||||
SET( tomahawkSources ${tomahawkSources} GetNewStuffDialog.cpp GetNewStuffDelegate.cpp GetNewStuffModel.cpp )
|
||||
SET( tomahawkHeaders ${tomahawkHeaders} GetNewStuffDialog.h GetNewStuffDelegate.h GetNewStuffModel.h )
|
||||
INCLUDE_DIRECTORIES( ${LIBATTICA_INCLUDE_DIR} )
|
||||
ENDIF(LIBATTICA_FOUND)
|
||||
|
||||
@@ -200,6 +200,10 @@ IF(QCA2_FOUND)
|
||||
INCLUDE_DIRECTORIES( ${QCA2_INCLUDE_DIR} )
|
||||
ENDIF(QCA2_FOUND)
|
||||
|
||||
kde4_add_app_icon( tomahawkSources "${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon-*.png" )
|
||||
qt4_add_resources( RC_SRCS "../resources.qrc" )
|
||||
qt4_wrap_cpp( tomahawkMoc ${tomahawkHeaders} )
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
@@ -207,17 +211,13 @@ include( ${CMAKE_SOURCE_DIR}/lang/translations.cmake )
|
||||
|
||||
SET( final_src ${final_src} ${tomahawkMoc} ${tomahawkSources} ${tomahawkHeaders} ${trans_outfile})
|
||||
|
||||
IF( BUILD_GUI )
|
||||
LIST(APPEND tomahawkHeaders ${tomahawkHeadersGui})
|
||||
LIST(APPEND tomahawkSources ${tomahawkSourcesGui})
|
||||
IF( "${gui}" STREQUAL "no" )
|
||||
ELSE()
|
||||
qt4_wrap_ui( tomahawkUI_H ${tomahawkUI} )
|
||||
qt4_wrap_cpp( tomahawkMocGui ${tomahawkHeadersGui} )
|
||||
SET( final_src ${final_src} ${tomahawkUI_H} ${tomahawkMocGui} ${tomahawkSourcesGui} ${RC_SRCS} )
|
||||
ENDIF()
|
||||
|
||||
kde4_add_app_icon( tomahawkSources "${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon-*.png" )
|
||||
qt4_add_resources( RC_SRCS "../resources.qrc" )
|
||||
qt4_wrap_cpp( tomahawkMoc ${tomahawkHeaders} )
|
||||
SET( final_src ${final_src} ${tomahawkUI_H} ${tomahawkMoc} ${tomahawkSources} ${RC_SRCS} )
|
||||
|
||||
IF( UNIX AND NOT APPLE )
|
||||
ADD_EXECUTABLE( tomahawk ${final_src} )
|
||||
ENDIF( UNIX AND NOT APPLE )
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#include "GetNewStuffDelegate.h"
|
||||
#include "GetNewStuffModel.h"
|
||||
|
||||
GetNewStuffDialog::GetNewStuffDialog( QWidget *parent, Qt::WindowFlags f )
|
||||
GetNewStuffDialog::GetNewStuffDialog( QWidget* parent, Qt::WindowFlags f )
|
||||
: QDialog( parent, f )
|
||||
, ui( new Ui::GetNewStuffDialog )
|
||||
, m_model( new GetNewStuffModel( this ) )
|
||||
@@ -37,16 +37,17 @@ GetNewStuffDialog::GetNewStuffDialog( QWidget *parent, Qt::WindowFlags f )
|
||||
|
||||
ui->listView->setMouseTracking( true );
|
||||
|
||||
setMinimumSize( 560, 350 );
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
setMinimumSize( 510, 350 );
|
||||
setMaximumSize( 510, 350 );
|
||||
setMaximumSize( 560, 350 );
|
||||
setSizeGripEnabled( false );
|
||||
|
||||
ui->listView->setAttribute( Qt::WA_MacShowFocusRect, false );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
GetNewStuffDialog::~GetNewStuffDialog()
|
||||
{
|
||||
delete ui;
|
||||
|
@@ -34,9 +34,6 @@ LoadXSPFDialog::LoadXSPFDialog( QWidget* parent, Qt::WindowFlags f )
|
||||
m_ui->verticalLayout->setSpacing( 0 );
|
||||
#endif
|
||||
|
||||
connect( m_ui->buttonBox, SIGNAL( accepted() ), SLOT( accept() ) );
|
||||
connect( m_ui->buttonBox, SIGNAL( rejected() ), SLOT( reject() ) );
|
||||
|
||||
connect( m_ui->navigateButton, SIGNAL( clicked( bool ) ), this, SLOT( getLocalFile() ) );
|
||||
}
|
||||
|
||||
@@ -47,7 +44,7 @@ LoadXSPFDialog::~LoadXSPFDialog()
|
||||
void
|
||||
LoadXSPFDialog::getLocalFile()
|
||||
{
|
||||
QString url = QFileDialog::getOpenFileName( this, tr( "Load XSPF File" ), QDir::homePath(), ".xspf" );
|
||||
QString url = QFileDialog::getOpenFileName( this, tr( "Load XSPF File" ), QDir::homePath(), tr( "XSPF Files (*.xspf)" ) );
|
||||
m_ui->lineEdit->setText( url );
|
||||
}
|
||||
|
||||
|
@@ -19,9 +19,9 @@
|
||||
#include "audiocontrols.h"
|
||||
#include "ui_audiocontrols.h"
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QDropEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QtGui/QDropEvent>
|
||||
#include <QtGui/QMouseEvent>
|
||||
|
||||
#include "audio/audioengine.h"
|
||||
#include "playlist/playlistview.h"
|
||||
@@ -86,7 +86,11 @@ AudioControls::AudioControls( QWidget* parent )
|
||||
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
|
||||
ui->loveButton->setCheckable( true );
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
ui->ownerLabel->setForegroundRole( QPalette::Text );
|
||||
#else
|
||||
ui->ownerLabel->setForegroundRole( QPalette::Dark );
|
||||
#endif
|
||||
ui->metaDataArea->setStyleSheet( "QWidget#metaDataArea {\nborder-width: 4px;\nborder-image: url(" RESPATH "images/now-playing-panel.png) 4 4 4 4 stretch stretch; }" );
|
||||
|
||||
ui->seekSlider->setEnabled( true );
|
||||
@@ -204,9 +208,11 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result )
|
||||
m_sliderTimeLine.setFrameRange( 0, duration );
|
||||
m_sliderTimeLine.setCurrentTime( 0 );
|
||||
m_seekMsecs = -1;
|
||||
|
||||
|
||||
ui->seekSlider->setVisible( true );
|
||||
|
||||
m_noTimeChange = false;
|
||||
|
||||
Tomahawk::InfoSystem::InfoStringHash trackInfo;
|
||||
trackInfo["artist"] = result->artist()->name();
|
||||
trackInfo["album"] = result->album()->name();
|
||||
@@ -373,9 +379,22 @@ AudioControls::onPlaybackTimer( qint64 msElapsed )
|
||||
ui->timeLabel->setText( TomahawkUtils::timeToString( seconds ) );
|
||||
ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( m_currentTrack->duration() - seconds ) );
|
||||
|
||||
if ( m_sliderTimeLine.currentTime() > msElapsed || m_seekMsecs != -1 )
|
||||
if ( m_noTimeChange )
|
||||
{
|
||||
if ( m_sliderTimeLine.currentTime() != msElapsed )
|
||||
{
|
||||
m_noTimeChange = false;
|
||||
m_sliderTimeLine.resume();
|
||||
}
|
||||
}
|
||||
else if ( m_sliderTimeLine.currentTime() >= msElapsed || m_seekMsecs != -1 )
|
||||
{
|
||||
m_sliderTimeLine.setPaused( true );
|
||||
|
||||
m_noTimeChange = false;
|
||||
if ( m_sliderTimeLine.currentTime() == msElapsed )
|
||||
m_noTimeChange = true;
|
||||
|
||||
m_sliderTimeLine.setCurrentTime( msElapsed );
|
||||
m_seekMsecs = -1;
|
||||
if ( AudioEngine::instance()->state() != AudioEngine::Paused )
|
||||
|
@@ -19,8 +19,8 @@
|
||||
#ifndef AUDIOCONTROLS_H
|
||||
#define AUDIOCONTROLS_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTimeLine>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtCore/QTimeLine>
|
||||
|
||||
#include "result.h"
|
||||
#include "playlistinterface.h"
|
||||
@@ -95,6 +95,7 @@ private:
|
||||
|
||||
QTimeLine m_sliderTimeLine;
|
||||
qint64 m_seekMsecs;
|
||||
bool m_noTimeChange;
|
||||
};
|
||||
|
||||
#endif // AUDIOCONTROLS_H
|
||||
|
@@ -28,9 +28,6 @@
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
@@ -164,9 +161,6 @@
|
||||
<height>58</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
|
@@ -18,11 +18,17 @@
|
||||
|
||||
#include "BreakPad.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QString>
|
||||
#include <QFileInfo>
|
||||
#include <string.h>
|
||||
|
||||
#define CRASH_REPORTER_BINARY "CrashReporter"
|
||||
#define CRASH_REPORTER_BINARY "tomahawk_crash_reporter"
|
||||
|
||||
bool s_active = true;
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
@@ -38,8 +44,10 @@ LaunchUploader( const char* dump_dir, const char* minidump_id, void* that, bool
|
||||
return false;
|
||||
|
||||
const char* crashReporter = static_cast<BreakPad*>(that)->crashReporter();
|
||||
pid_t pid = fork();
|
||||
if ( !s_active || strlen( crashReporter ) == 0 )
|
||||
return false;
|
||||
|
||||
pid_t pid = fork();
|
||||
if ( pid == -1 ) // fork failed
|
||||
return false;
|
||||
if ( pid == 0 )
|
||||
@@ -63,14 +71,25 @@ LaunchUploader( const char* dump_dir, const char* minidump_id, void* that, bool
|
||||
}
|
||||
|
||||
|
||||
BreakPad::BreakPad( const QString& path )
|
||||
BreakPad::BreakPad( const QString& path, bool active )
|
||||
#ifdef Q_OS_LINUX
|
||||
: google_breakpad::ExceptionHandler( path.toStdString(), 0, LaunchUploader, this, true )
|
||||
#else
|
||||
: google_breakpad::ExceptionHandler( path.toStdString(), 0, LaunchUploader, this, true, 0 )
|
||||
#endif
|
||||
{
|
||||
QString reporter = QString( "%1/%2" ).arg( qApp->applicationDirPath() ).arg( CRASH_REPORTER_BINARY );
|
||||
s_active = active;
|
||||
|
||||
QString reporter;
|
||||
QString localReporter = QString( "%1/%2" ).arg( qApp->applicationDirPath() ).arg( CRASH_REPORTER_BINARY );
|
||||
QString globalReporter = QString( "%1/%2" ).arg( CMAKE_INSTALL_PREFIX "/" CMAKE_INSTALL_LIBEXECDIR ).arg( CRASH_REPORTER_BINARY );
|
||||
|
||||
if ( QFileInfo( localReporter ).exists() )
|
||||
reporter = localReporter;
|
||||
else if ( QFileInfo( globalReporter ).exists() )
|
||||
reporter = globalReporter;
|
||||
else
|
||||
tLog() << "Could not find \"" CRASH_REPORTER_BINARY "\" in \"" CMAKE_INSTALL_PREFIX "/" CMAKE_INSTALL_LIBEXECDIR "\" or application path";
|
||||
|
||||
char* creporter;
|
||||
std::string sreporter = reporter.toStdString();
|
||||
@@ -126,7 +145,7 @@ LaunchUploader( const wchar_t* dump_dir, const wchar_t* minidump_id, void* that,
|
||||
si.wShowWindow = SW_SHOWNORMAL;
|
||||
ZeroMemory( &pi, sizeof(pi) );
|
||||
|
||||
if (CreateProcess( NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
|
||||
if ( CreateProcess( NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) )
|
||||
{
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
@@ -137,9 +156,24 @@ LaunchUploader( const wchar_t* dump_dir, const wchar_t* minidump_id, void* that,
|
||||
}
|
||||
|
||||
|
||||
BreakPad::BreakPad( const QString& path )
|
||||
BreakPad::BreakPad( const QString& path, bool active )
|
||||
: google_breakpad::ExceptionHandler( path.toStdWString(), 0, LaunchUploader, this, true )
|
||||
{
|
||||
s_active = active;
|
||||
}
|
||||
|
||||
#endif // WIN32
|
||||
|
||||
|
||||
void
|
||||
BreakPad::setActive( bool enabled )
|
||||
{
|
||||
s_active = enabled;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BreakPad::isActive()
|
||||
{
|
||||
return s_active;
|
||||
}
|
||||
|
@@ -32,11 +32,14 @@ class BreakPad : public google_breakpad::ExceptionHandler
|
||||
const char* m_crashReporter; // again, const char[]
|
||||
|
||||
public:
|
||||
BreakPad( const QString &dump_write_dirpath );
|
||||
BreakPad( const QString& dump_write_dirpath, bool active );
|
||||
|
||||
~BreakPad()
|
||||
{}
|
||||
|
||||
static void setActive( bool enabled );
|
||||
static bool isActive();
|
||||
|
||||
void setProductName( const char* s ) { m_productName = s; };
|
||||
const char* productName() const { return m_productName; }
|
||||
|
||||
|
@@ -1,8 +1,10 @@
|
||||
PROJECT( CrashReporter )
|
||||
|
||||
|
||||
FIND_PACKAGE( Qt4 REQUIRED )
|
||||
SET( QT_USE_QTNETWORK TRUE )
|
||||
|
||||
|
||||
SET( crashreporter_SOURCES main.cpp CrashReporter.cpp )
|
||||
SET( crashreporter_HEADERS CrashReporter.h )
|
||||
SET( crashreporter_UI CrashReporter.ui )
|
||||
@@ -16,5 +18,8 @@ INCLUDE( ${QT_USE_FILE} )
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/src ../../libtomahawk )
|
||||
ADD_DEFINITIONS( ${QT_DEFINITIONS} )
|
||||
|
||||
ADD_EXECUTABLE( CrashReporter WIN32 ${crashreporter_SOURCES} ${crashreporter_HEADERS_MOC} ${crashreporter_UI_HEADERS} ${crashreporter_RC_RCC} )
|
||||
TARGET_LINK_LIBRARIES( CrashReporter ${QT_LIBRARIES} tomahawklib )
|
||||
ADD_EXECUTABLE( tomahawk_crash_reporter WIN32 ${crashreporter_SOURCES} ${crashreporter_HEADERS_MOC} ${crashreporter_UI_HEADERS} ${crashreporter_RC_RCC} )
|
||||
TARGET_LINK_LIBRARIES( tomahawk_crash_reporter ${QT_LIBRARIES} tomahawklib )
|
||||
|
||||
INCLUDE(GNUInstallDirs)
|
||||
install(TARGETS tomahawk_crash_reporter RUNTIME DESTINATION ${CMAKE_INSTALL_LIBEXECDIR})
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#cmakedefine DEBUG_BUILD
|
||||
|
||||
#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
|
||||
#define CMAKE_INSTALL_LIBEXECDIR "${CMAKE_INSTALL_LIBEXECDIR}"
|
||||
#define CMAKE_SYSTEM "${CMAKE_SYSTEM}"
|
||||
|
||||
#cmakedefine LION
|
||||
|
@@ -52,8 +52,7 @@ public:
|
||||
setMinimumSize( sizeHint() );
|
||||
setMaximumSize( sizeHint() ); // to remove the resize grip on osx this is the only way
|
||||
|
||||
if( conf->metaObject()->indexOfSignal( "sizeHintChanged()" ) > -1 )
|
||||
connect( conf, SIGNAL( sizeHintChanged() ), this, SLOT( updateSizeHint() ) );
|
||||
connect( conf, SIGNAL( sizeHintChanged() ), this, SLOT( updateSizeHint() ) );
|
||||
#else
|
||||
m_widget->setVisible( true );
|
||||
#endif
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#ifdef ENABLE_HEADLESS
|
||||
|
||||
#define TOMAHAWK_APPLICATION QCoreApplication
|
||||
#include <QCoreApplication>
|
||||
#include <QApplication>
|
||||
|
||||
#else
|
||||
|
||||
|
@@ -45,6 +45,8 @@ AtticaManager::AtticaManager( QObject* parent )
|
||||
|
||||
// resolvers
|
||||
m_manager.addProviderFile( QUrl( "http://bakery.tomahawk-player.org:10480/resolvers/providers.xml" ) );
|
||||
|
||||
qRegisterMetaType< Attica::Content >( "Attica::Content" );
|
||||
}
|
||||
|
||||
|
||||
@@ -149,6 +151,7 @@ AtticaManager::pathFromId( const QString& resolverId ) const
|
||||
return m_resolverStates.value( resolverId ).scriptPath;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::uploadRating( const Content& c )
|
||||
{
|
||||
@@ -175,6 +178,7 @@ AtticaManager::uploadRating( const Content& c )
|
||||
emit resolverStateChanged( c.id() );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AtticaManager::userHasRated( const Content& c ) const
|
||||
{
|
||||
@@ -245,6 +249,7 @@ AtticaManager::resolverIconFetched()
|
||||
m_resolverStates[ resolverId ].pixmap = icon;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::syncServerData()
|
||||
{
|
||||
@@ -271,62 +276,16 @@ AtticaManager::syncServerData()
|
||||
if ( ( r.state == Installed || r.state == NeedsUpgrade ) &&
|
||||
!upstream.version().isEmpty() )
|
||||
{
|
||||
if ( newerVersion( r.version, upstream.version() ) )
|
||||
if ( TomahawkUtils::newerVersion( r.version, upstream.version() ) )
|
||||
{
|
||||
m_resolverStates[ id ].state = NeedsUpgrade;
|
||||
QMetaObject::invokeMethod( this, "upgradeResolver", Qt::QueuedConnection, Q_ARG( Attica::Content, upstream ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AtticaManager::newerVersion( const QString& older, const QString& newer ) const
|
||||
{
|
||||
// Dumb version comparison. Expects two strings, X.Y and Z.V. Returns true if Z > v || Z == V && V > Y
|
||||
// DOES NOT support X.Y.Z version strings
|
||||
if ( older.isEmpty() || newer.isEmpty() )
|
||||
return false;
|
||||
|
||||
QPair<int, int> oldVer, newVer;
|
||||
QStringList parts = older.split( "." );
|
||||
|
||||
if ( parts.size() == 1 )
|
||||
{
|
||||
oldVer.first = parts[ 0 ].toInt();
|
||||
oldVer.second = 0;
|
||||
}
|
||||
else if ( parts.size() == 2 )
|
||||
{
|
||||
oldVer.first = parts[ 0 ].toInt();
|
||||
oldVer.second = parts[ 1 ].toInt();;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
parts = newer.split( "." );
|
||||
if ( parts.size() == 1 )
|
||||
{
|
||||
newVer.first = parts[ 0 ].toInt();
|
||||
newVer.second = 0;
|
||||
}
|
||||
else if ( parts.size() == 2 )
|
||||
{
|
||||
newVer.first = parts[ 0 ].toInt();
|
||||
newVer.second = parts[ 1 ].toInt();;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
// Do the comparison
|
||||
if ( newVer.first > oldVer.first )
|
||||
return true;
|
||||
if ( newVer.first == oldVer.first &&
|
||||
newVer.second > oldVer.second )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
AtticaManager::installResolver( const Content& resolver )
|
||||
@@ -347,6 +306,7 @@ AtticaManager::installResolver( const Content& resolver )
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AtticaManager::upgradeResolver( const Content& resolver )
|
||||
{
|
||||
|
@@ -83,8 +83,6 @@ public:
|
||||
ResolverState resolverState( const Attica::Content& resolver ) const;
|
||||
QPixmap iconForResolver( const Attica::Content& id ); // Looks up in icon cache
|
||||
|
||||
void installResolver( const Attica::Content& resolver );
|
||||
void upgradeResolver( const Attica::Content& resolver );
|
||||
void uninstallResolver( const Attica::Content& resolver );
|
||||
void uninstallResolver( const QString& pathToResolver );
|
||||
QString pathFromId( const QString& resolverId ) const;
|
||||
@@ -92,6 +90,9 @@ public:
|
||||
void uploadRating( const Attica::Content& c );
|
||||
bool userHasRated( const Attica::Content& c ) const;
|
||||
|
||||
public slots:
|
||||
void installResolver( const Attica::Content& resolver );
|
||||
void upgradeResolver( const Attica::Content& resolver );
|
||||
|
||||
signals:
|
||||
void resolversReloaded( const Attica::Content::List& resolvers );
|
||||
@@ -111,7 +112,6 @@ private slots:
|
||||
void resolverIconFetched();
|
||||
|
||||
void syncServerData();
|
||||
bool newerVersion( const QString& older, const QString& newer ) const;
|
||||
|
||||
private:
|
||||
QString extractPayload( const QString& filename, const QString& resolverId ) const;
|
||||
@@ -127,4 +127,8 @@ private:
|
||||
static AtticaManager* s_instance;
|
||||
};
|
||||
|
||||
#ifdef LIBATTICA_FOUND
|
||||
Q_DECLARE_METATYPE( Attica::Content );
|
||||
#endif
|
||||
|
||||
#endif // ATTICAMANAGER_H
|
||||
|
@@ -12,260 +12,6 @@ add_definitions( ${QT_DEFINITIONS} )
|
||||
add_definitions( -DQT_SHARED )
|
||||
add_definitions( -DDLLEXPORT_PRO )
|
||||
|
||||
set( libGuiSources
|
||||
contextmenu.cpp
|
||||
dropjob.cpp
|
||||
globalactionmanager.cpp
|
||||
viewpage.cpp
|
||||
viewmanager.cpp
|
||||
|
||||
context/ContextPage.cpp
|
||||
context/ContextWidget.cpp
|
||||
context/pages/TopTracksContext.cpp
|
||||
context/pages/RelatedArtistsContext.cpp
|
||||
context/pages/WikipediaContext.cpp
|
||||
context/pages/WebContext.cpp
|
||||
|
||||
jobview/JobStatusView.cpp
|
||||
jobview/JobStatusModel.cpp
|
||||
jobview/JobStatusDelegate.cpp
|
||||
jobview/PipelineStatusItem.cpp
|
||||
jobview/TransferStatusItem.cpp
|
||||
jobview/LatchedStatusItem.cpp
|
||||
|
||||
infobar/infobar.cpp
|
||||
|
||||
infosystem/infoplugins/generic/echonestplugin.cpp
|
||||
infosystem/infoplugins/generic/lastfmplugin.cpp
|
||||
infosystem/infoplugins/generic/chartsplugin.cpp
|
||||
infosystem/infoplugins/generic/spotifyPlugin.cpp
|
||||
infosystem/infoplugins/generic/hypemPlugin.cpp
|
||||
infosystem/infoplugins/generic/musixmatchplugin.cpp
|
||||
infosystem/infoplugins/generic/musicbrainzPlugin.cpp
|
||||
infosystem/infoplugins/generic/RoviPlugin.cpp
|
||||
|
||||
playlist/treemodel.cpp
|
||||
playlist/treeproxymodel.cpp
|
||||
playlist/treeheader.cpp
|
||||
playlist/treeitemdelegate.cpp
|
||||
playlist/collectionproxymodel.cpp
|
||||
playlist/collectionflatmodel.cpp
|
||||
playlist/collectionview.cpp
|
||||
playlist/playlistmodel.cpp
|
||||
playlist/playlistproxymodel.cpp
|
||||
playlist/playlistview.cpp
|
||||
playlist/playlistitemdelegate.cpp
|
||||
playlist/queueproxymodel.cpp
|
||||
playlist/queueview.cpp
|
||||
playlist/trackmodel.cpp
|
||||
playlist/trackmodelitem.cpp
|
||||
playlist/trackproxymodel.cpp
|
||||
playlist/trackview.cpp
|
||||
playlist/trackheader.cpp
|
||||
playlist/treemodelitem.cpp
|
||||
playlist/albumitem.cpp
|
||||
playlist/albummodel.cpp
|
||||
playlist/albumproxymodel.cpp
|
||||
playlist/albumitemdelegate.cpp
|
||||
playlist/albumview.cpp
|
||||
playlist/artistview.cpp
|
||||
playlist/customplaylistview.cpp
|
||||
playlist/ViewHeader.cpp
|
||||
|
||||
playlist/dynamic/DynamicPlaylist.cpp
|
||||
playlist/dynamic/DynamicView.cpp
|
||||
playlist/dynamic/DynamicModel.cpp
|
||||
playlist/dynamic/echonest/EchonestGenerator.cpp
|
||||
playlist/dynamic/echonest/EchonestControl.cpp
|
||||
playlist/dynamic/echonest/EchonestSteerer.cpp
|
||||
playlist/dynamic/widgets/DynamicWidget.cpp
|
||||
playlist/dynamic/widgets/DynamicControlWrapper.cpp
|
||||
playlist/dynamic/widgets/DynamicControlList.cpp
|
||||
playlist/dynamic/widgets/ReadOrWriteWidget.cpp
|
||||
playlist/dynamic/widgets/MiscControlWidgets.cpp
|
||||
playlist/dynamic/widgets/CollapsibleControls.cpp
|
||||
playlist/dynamic/widgets/DynamicSetupWidget.cpp
|
||||
playlist/dynamic/widgets/LoadingSpinner.cpp
|
||||
|
||||
playlist/topbar/topbar.cpp
|
||||
playlist/topbar/clearbutton.cpp
|
||||
playlist/topbar/searchlineedit.cpp
|
||||
playlist/topbar/lineedit.cpp
|
||||
playlist/topbar/searchbutton.cpp
|
||||
|
||||
resolvers/scriptresolver.cpp
|
||||
resolvers/qtscriptresolver.cpp
|
||||
|
||||
sip/SipModel.cpp
|
||||
|
||||
utils/widgetdragfilter.cpp
|
||||
utils/xspfgenerator.cpp
|
||||
utils/jspfloader.cpp
|
||||
utils/spotifyparser.cpp
|
||||
utils/itunesparser.cpp
|
||||
utils/rdioparser.cpp
|
||||
utils/shortenedlinkparser.cpp
|
||||
utils/stylehelper.cpp
|
||||
utils/dropjobnotifier.cpp
|
||||
utils/proxystyle.cpp
|
||||
|
||||
widgets/checkdirtree.cpp
|
||||
widgets/querylabel.cpp
|
||||
widgets/imagebutton.cpp
|
||||
widgets/animatedsplitter.cpp
|
||||
widgets/elidedlabel.cpp
|
||||
widgets/newplaylistwidget.cpp
|
||||
widgets/searchwidget.cpp
|
||||
widgets/SeekSlider.cpp
|
||||
widgets/playlisttypeselectordlg.cpp
|
||||
widgets/welcomewidget.cpp
|
||||
widgets/whatshotwidget.cpp
|
||||
widgets/RecentlyPlayedPlaylistsModel.cpp
|
||||
widgets/RecentPlaylistsModel.cpp
|
||||
widgets/OverlayButton.cpp
|
||||
widgets/overlaywidget.cpp
|
||||
widgets/HeaderLabel.cpp
|
||||
widgets/HeaderWidget.cpp
|
||||
widgets/combobox.cpp
|
||||
widgets/ToggleButton.cpp
|
||||
widgets/SocialPlaylistWidget.cpp
|
||||
widgets/infowidgets/sourceinfowidget.cpp
|
||||
widgets/infowidgets/ArtistInfoWidget.cpp
|
||||
widgets/infowidgets/AlbumInfoWidget.cpp
|
||||
widgets/Breadcrumb.cpp
|
||||
widgets/BreadcrumbButton.cpp
|
||||
)
|
||||
|
||||
set( libGuiHeaders
|
||||
contextmenu.h
|
||||
dropjob.h
|
||||
viewpage.h
|
||||
viewmanager.h
|
||||
globalactionmanager.h
|
||||
|
||||
context/ContextPage.h
|
||||
context/ContextWidget.h
|
||||
context/pages/TopTracksContext.h
|
||||
context/pages/RelatedArtistsContext.h
|
||||
context/pages/WikipediaContext.h
|
||||
context/pages/WebContext.h
|
||||
|
||||
infobar/infobar.h
|
||||
|
||||
infosystem/infoplugins/generic/echonestplugin.h
|
||||
infosystem/infoplugins/generic/lastfmplugin.h
|
||||
infosystem/infoplugins/generic/chartsplugin.h
|
||||
infosystem/infoplugins/generic/spotifyPlugin.h
|
||||
infosystem/infoplugins/generic/hypemPlugin.h
|
||||
infosystem/infoplugins/generic/musixmatchplugin.h
|
||||
infosystem/infoplugins/generic/musicbrainzPlugin.h
|
||||
infosystem/infoplugins/generic/RoviPlugin.h
|
||||
|
||||
playlist/topbar/topbar.h
|
||||
playlist/topbar/clearbutton.h
|
||||
playlist/topbar/searchlineedit.h
|
||||
playlist/topbar/lineedit.h
|
||||
playlist/topbar/lineedit_p.h
|
||||
playlist/topbar/searchbutton.h
|
||||
|
||||
playlist/treemodel.h
|
||||
playlist/treeproxymodel.h
|
||||
playlist/treeheader.h
|
||||
playlist/treeitemdelegate.h
|
||||
playlist/collectionproxymodel.h
|
||||
playlist/collectionflatmodel.h
|
||||
playlist/collectionview.h
|
||||
playlist/playlistmodel.h
|
||||
playlist/playlistproxymodel.h
|
||||
playlist/playlistview.h
|
||||
playlist/playlistitemdelegate.h
|
||||
playlist/queueproxymodel.h
|
||||
playlist/queueview.h
|
||||
playlist/trackmodel.h
|
||||
playlist/trackmodelitem.h
|
||||
playlist/trackproxymodel.h
|
||||
playlist/trackview.h
|
||||
playlist/trackheader.h
|
||||
playlist/treemodelitem.h
|
||||
playlist/albumitem.h
|
||||
playlist/albummodel.h
|
||||
playlist/albumproxymodel.h
|
||||
playlist/albumitemdelegate.h
|
||||
playlist/albumview.h
|
||||
playlist/artistview.h
|
||||
playlist/customplaylistview.h
|
||||
playlist/ViewHeader.h
|
||||
|
||||
playlist/dynamic/DynamicPlaylist.h
|
||||
playlist/dynamic/GeneratorInterface.h
|
||||
playlist/dynamic/DynamicView.h
|
||||
playlist/dynamic/DynamicModel.h
|
||||
playlist/dynamic/echonest/EchonestGenerator.h
|
||||
playlist/dynamic/echonest/EchonestControl.h
|
||||
playlist/dynamic/echonest/EchonestSteerer.h
|
||||
playlist/dynamic/widgets/DynamicWidget.h
|
||||
playlist/dynamic/widgets/DynamicControlWrapper.h
|
||||
playlist/dynamic/widgets/DynamicControlList.h
|
||||
playlist/dynamic/widgets/ReadOrWriteWidget.h
|
||||
playlist/dynamic/widgets/MiscControlWidgets.h
|
||||
playlist/dynamic/widgets/CollapsibleControls.h
|
||||
playlist/dynamic/widgets/DynamicSetupWidget.h
|
||||
playlist/dynamic/widgets/LoadingSpinner.h
|
||||
|
||||
resolvers/scriptresolver.h
|
||||
resolvers/qtscriptresolver.h
|
||||
|
||||
sip/SipModel.h
|
||||
|
||||
utils/widgetdragfilter.h
|
||||
utils/xspfgenerator.h
|
||||
utils/jspfloader.h
|
||||
utils/spotifyparser.h
|
||||
utils/itunesparser.h
|
||||
utils/rdioparser.h
|
||||
utils/shortenedlinkparser.h
|
||||
utils/dropjobnotifier.h
|
||||
|
||||
widgets/checkdirtree.h
|
||||
widgets/querylabel.h
|
||||
widgets/animatedcounterlabel.h
|
||||
widgets/imagebutton.h
|
||||
widgets/animatedsplitter.h
|
||||
widgets/elidedlabel.h
|
||||
widgets/newplaylistwidget.h
|
||||
widgets/searchwidget.h
|
||||
widgets/SeekSlider.h
|
||||
widgets/playlisttypeselectordlg.h
|
||||
widgets/welcomewidget.h
|
||||
widgets/whatshotwidget.h
|
||||
widgets/RecentlyPlayedPlaylistsModel.h
|
||||
widgets/RecentPlaylistsModel.h
|
||||
widgets/OverlayButton.h
|
||||
widgets/overlaywidget.h
|
||||
widgets/HeaderLabel.h
|
||||
widgets/HeaderWidget.h
|
||||
widgets/combobox.h
|
||||
widgets/ToggleButton.h
|
||||
widgets/SocialPlaylistWidget.h
|
||||
widgets/infowidgets/sourceinfowidget.h
|
||||
widgets/infowidgets/ArtistInfoWidget.h
|
||||
widgets/infowidgets/ArtistInfoWidget_p.h
|
||||
widgets/infowidgets/AlbumInfoWidget.h
|
||||
widgets/Breadcrumb.h
|
||||
widgets/BreadcrumbButton.h
|
||||
|
||||
jobview/JobStatusView.h
|
||||
jobview/JobStatusModel.h
|
||||
jobview/JobStatusDelegate.h
|
||||
jobview/JobStatusItem.h
|
||||
jobview/PipelineStatusItem.h
|
||||
jobview/TransferStatusItem.h
|
||||
jobview/LatchedStatusItem.h
|
||||
|
||||
thirdparty/Qocoa/qsearchfield.h
|
||||
|
||||
)
|
||||
|
||||
set( libSources
|
||||
tomahawksettings.cpp
|
||||
sourcelist.cpp
|
||||
@@ -282,6 +28,11 @@ set( libSources
|
||||
result.cpp
|
||||
source.cpp
|
||||
sourceplaylistinterface.cpp
|
||||
viewpage.cpp
|
||||
viewmanager.cpp
|
||||
globalactionmanager.cpp
|
||||
contextmenu.cpp
|
||||
dropjob.cpp
|
||||
playlistinterface.cpp
|
||||
LatchManager.cpp
|
||||
|
||||
@@ -289,10 +40,17 @@ set( libSources
|
||||
|
||||
sip/SipPlugin.cpp
|
||||
sip/SipHandler.cpp
|
||||
sip/SipModel.cpp
|
||||
sip/sipinfo.cpp
|
||||
|
||||
audio/audioengine.cpp
|
||||
audio/audioenginethread.cpp
|
||||
|
||||
context/ContextPage.cpp
|
||||
context/ContextWidget.cpp
|
||||
context/pages/TopTracksContext.cpp
|
||||
context/pages/RelatedArtistsContext.cpp
|
||||
context/pages/WikipediaContext.cpp
|
||||
context/pages/WebContext.cpp
|
||||
|
||||
database/database.cpp
|
||||
database/fuzzyindex.cpp
|
||||
@@ -346,9 +104,79 @@ set( libSources
|
||||
database/databasecommand_settrackattributes.cpp
|
||||
database/database.cpp
|
||||
|
||||
infosystem/infosystem.cpp
|
||||
infobar/infobar.cpp
|
||||
|
||||
infosystem/infosystemcache.cpp
|
||||
infosystem/infosystem.cpp
|
||||
infosystem/infosystemworker.cpp
|
||||
infosystem/infoplugins/generic/echonestplugin.cpp
|
||||
infosystem/infoplugins/generic/lastfmplugin.cpp
|
||||
infosystem/infoplugins/generic/chartsplugin.cpp
|
||||
infosystem/infoplugins/generic/spotifyPlugin.cpp
|
||||
infosystem/infoplugins/generic/hypemPlugin.cpp
|
||||
infosystem/infoplugins/generic/musixmatchplugin.cpp
|
||||
infosystem/infoplugins/generic/musicbrainzPlugin.cpp
|
||||
infosystem/infoplugins/generic/RoviPlugin.cpp
|
||||
|
||||
playlist/treemodel.cpp
|
||||
playlist/treeproxymodel.cpp
|
||||
playlist/treeheader.cpp
|
||||
playlist/treeitemdelegate.cpp
|
||||
playlist/collectionproxymodel.cpp
|
||||
playlist/collectionflatmodel.cpp
|
||||
playlist/collectionview.cpp
|
||||
playlist/playlistmodel.cpp
|
||||
playlist/playlistproxymodel.cpp
|
||||
playlist/playlistview.cpp
|
||||
playlist/playlistitemdelegate.cpp
|
||||
playlist/queueproxymodel.cpp
|
||||
playlist/queueview.cpp
|
||||
playlist/trackmodel.cpp
|
||||
playlist/trackmodelitem.cpp
|
||||
playlist/trackproxymodel.cpp
|
||||
playlist/trackview.cpp
|
||||
playlist/trackheader.cpp
|
||||
playlist/treemodelitem.cpp
|
||||
playlist/albumitem.cpp
|
||||
playlist/albummodel.cpp
|
||||
playlist/albumproxymodel.cpp
|
||||
playlist/albumitemdelegate.cpp
|
||||
playlist/albumview.cpp
|
||||
playlist/artistview.cpp
|
||||
playlist/customplaylistview.cpp
|
||||
playlist/ViewHeader.cpp
|
||||
playlist/PlaylistUpdaterInterface.cpp
|
||||
playlist/XspfUpdater.cpp
|
||||
|
||||
playlist/topbar/topbar.cpp
|
||||
playlist/topbar/clearbutton.cpp
|
||||
playlist/topbar/searchlineedit.cpp
|
||||
playlist/topbar/lineedit.cpp
|
||||
playlist/topbar/searchbutton.cpp
|
||||
|
||||
playlist/dynamic/DynamicPlaylist.cpp
|
||||
playlist/dynamic/DynamicControl.cpp
|
||||
playlist/dynamic/GeneratorFactory.cpp
|
||||
playlist/dynamic/GeneratorInterface.cpp
|
||||
playlist/dynamic/DynamicView.cpp
|
||||
playlist/dynamic/DynamicModel.cpp
|
||||
playlist/dynamic/DynamicPlaylistRevision.cpp
|
||||
playlist/dynamic/echonest/EchonestGenerator.cpp
|
||||
playlist/dynamic/echonest/EchonestControl.cpp
|
||||
playlist/dynamic/echonest/EchonestSteerer.cpp
|
||||
playlist/dynamic/widgets/DynamicWidget.cpp
|
||||
playlist/dynamic/widgets/DynamicControlWrapper.cpp
|
||||
playlist/dynamic/widgets/DynamicControlList.cpp
|
||||
playlist/dynamic/widgets/ReadOrWriteWidget.cpp
|
||||
playlist/dynamic/widgets/MiscControlWidgets.cpp
|
||||
playlist/dynamic/widgets/CollapsibleControls.cpp
|
||||
playlist/dynamic/widgets/DynamicSetupWidget.cpp
|
||||
playlist/dynamic/widgets/LoadingSpinner.cpp
|
||||
playlist/dynamic/database/DatabaseControl.cpp
|
||||
playlist/dynamic/database/DatabaseGenerator.cpp
|
||||
|
||||
resolvers/scriptresolver.cpp
|
||||
resolvers/qtscriptresolver.cpp
|
||||
|
||||
network/bufferiodevice.cpp
|
||||
network/msgprocessor.cpp
|
||||
@@ -360,20 +188,53 @@ set( libSources
|
||||
network/connection.cpp
|
||||
network/controlconnection.cpp
|
||||
|
||||
playlist/PlaylistUpdaterInterface.cpp
|
||||
playlist/dynamic/DynamicPlaylist.cpp
|
||||
playlist/dynamic/GeneratorFactory.cpp
|
||||
playlist/dynamic/GeneratorInterface.cpp
|
||||
playlist/dynamic/DynamicPlaylistRevision.cpp
|
||||
playlist/XspfUpdater.cpp
|
||||
playlist/dynamic/database/DatabaseGenerator.cpp
|
||||
playlist/dynamic/database/DatabaseControl.cpp
|
||||
playlist/dynamic/DynamicControl.cpp
|
||||
|
||||
utils/tomahawkutils.cpp
|
||||
utils/logger.cpp
|
||||
utils/qnr_iodevicestream.cpp
|
||||
utils/proxystyle.cpp
|
||||
utils/widgetdragfilter.cpp
|
||||
utils/xspfloader.cpp
|
||||
utils/xspfgenerator.cpp
|
||||
utils/jspfloader.cpp
|
||||
utils/spotifyparser.cpp
|
||||
utils/itunesparser.cpp
|
||||
utils/rdioparser.cpp
|
||||
utils/shortenedlinkparser.cpp
|
||||
utils/stylehelper.cpp
|
||||
utils/qnr_iodevicestream.cpp
|
||||
utils/dropjobnotifier.cpp
|
||||
|
||||
widgets/checkdirtree.cpp
|
||||
widgets/querylabel.cpp
|
||||
widgets/imagebutton.cpp
|
||||
widgets/animatedsplitter.cpp
|
||||
widgets/elidedlabel.cpp
|
||||
widgets/newplaylistwidget.cpp
|
||||
widgets/searchwidget.cpp
|
||||
widgets/SeekSlider.cpp
|
||||
widgets/playlisttypeselectordlg.cpp
|
||||
widgets/welcomewidget.cpp
|
||||
widgets/whatshotwidget.cpp
|
||||
widgets/RecentlyPlayedPlaylistsModel.cpp
|
||||
widgets/RecentPlaylistsModel.cpp
|
||||
widgets/OverlayButton.cpp
|
||||
widgets/overlaywidget.cpp
|
||||
widgets/HeaderLabel.cpp
|
||||
widgets/HeaderWidget.cpp
|
||||
widgets/combobox.cpp
|
||||
widgets/ToggleButton.cpp
|
||||
widgets/SocialPlaylistWidget.cpp
|
||||
widgets/infowidgets/sourceinfowidget.cpp
|
||||
widgets/infowidgets/ArtistInfoWidget.cpp
|
||||
widgets/infowidgets/AlbumInfoWidget.cpp
|
||||
widgets/Breadcrumb.cpp
|
||||
widgets/BreadcrumbButton.cpp
|
||||
|
||||
jobview/JobStatusView.cpp
|
||||
jobview/JobStatusModel.cpp
|
||||
jobview/JobStatusDelegate.cpp
|
||||
jobview/PipelineStatusItem.cpp
|
||||
jobview/TransferStatusItem.cpp
|
||||
jobview/LatchedStatusItem.cpp
|
||||
|
||||
thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.cpp
|
||||
thirdparty/kdsingleapplicationguard/kdsharedmemorylocker.cpp
|
||||
@@ -395,6 +256,11 @@ set( libHeaders
|
||||
result.h
|
||||
source.h
|
||||
sourceplaylistinterface.h
|
||||
viewmanager.h
|
||||
globalactionmanager.h
|
||||
contextmenu.h
|
||||
dropjob.h
|
||||
AtticaManager.h
|
||||
LatchManager.h
|
||||
|
||||
artist.h
|
||||
@@ -405,10 +271,17 @@ set( libHeaders
|
||||
|
||||
sip/SipPlugin.h
|
||||
sip/SipHandler.h
|
||||
sip/SipModel.h
|
||||
sip/sipinfo.h
|
||||
|
||||
audio/audioengine.h
|
||||
audio/audioenginethread.h
|
||||
|
||||
context/ContextPage.h
|
||||
context/ContextWidget.h
|
||||
context/pages/TopTracksContext.h
|
||||
context/pages/RelatedArtistsContext.h
|
||||
context/pages/WikipediaContext.h
|
||||
context/pages/WebContext.h
|
||||
|
||||
database/database.h
|
||||
database/fuzzyindex.h
|
||||
@@ -461,10 +334,19 @@ set( libHeaders
|
||||
database/databasecommand_trackattributes.h
|
||||
database/databasecommand_settrackattributes.h
|
||||
|
||||
infosystem/infosystem.h
|
||||
infobar/infobar.h
|
||||
|
||||
infosystem/infosystem.h
|
||||
infosystem/infosystemworker.h
|
||||
infosystem/infosystemcache.h
|
||||
infosystem/infoplugins/generic/echonestplugin.h
|
||||
infosystem/infoplugins/generic/lastfmplugin.h
|
||||
infosystem/infoplugins/generic/chartsplugin.h
|
||||
infosystem/infoplugins/generic/spotifyPlugin.h
|
||||
infosystem/infoplugins/generic/hypemPlugin.h
|
||||
infosystem/infoplugins/generic/musixmatchplugin.h
|
||||
infosystem/infoplugins/generic/musicbrainzPlugin.h
|
||||
infosystem/infoplugins/generic/RoviPlugin.h
|
||||
|
||||
network/bufferiodevice.h
|
||||
network/msgprocessor.h
|
||||
@@ -476,24 +358,125 @@ set( libHeaders
|
||||
network/controlconnection.h
|
||||
network/portfwdthread.h
|
||||
|
||||
playlist/treemodel.h
|
||||
playlist/treeproxymodel.h
|
||||
playlist/treeheader.h
|
||||
playlist/treeitemdelegate.h
|
||||
playlist/collectionproxymodel.h
|
||||
playlist/collectionflatmodel.h
|
||||
playlist/collectionview.h
|
||||
playlist/playlistmodel.h
|
||||
playlist/playlistproxymodel.h
|
||||
playlist/playlistview.h
|
||||
playlist/playlistitemdelegate.h
|
||||
playlist/queueproxymodel.h
|
||||
playlist/queueview.h
|
||||
playlist/trackmodel.h
|
||||
playlist/trackmodelitem.h
|
||||
playlist/trackproxymodel.h
|
||||
playlist/trackview.h
|
||||
playlist/trackheader.h
|
||||
playlist/treemodelitem.h
|
||||
playlist/albumitem.h
|
||||
playlist/albummodel.h
|
||||
playlist/albumproxymodel.h
|
||||
playlist/albumitemdelegate.h
|
||||
playlist/albumview.h
|
||||
playlist/artistview.h
|
||||
playlist/customplaylistview.h
|
||||
playlist/ViewHeader.h
|
||||
playlist/PlaylistUpdaterInterface.h
|
||||
playlist/dynamic/DynamicPlaylist.h
|
||||
playlist/dynamic/GeneratorInterface.h
|
||||
playlist/dynamic/GeneratorFactory.h
|
||||
playlist/XspfUpdater.h
|
||||
playlist/dynamic/database/DatabaseGenerator.h
|
||||
playlist/dynamic/database/DatabaseControl.h
|
||||
|
||||
playlist/topbar/topbar.h
|
||||
playlist/topbar/clearbutton.h
|
||||
playlist/topbar/searchlineedit.h
|
||||
playlist/topbar/lineedit.h
|
||||
playlist/topbar/lineedit_p.h
|
||||
playlist/topbar/searchbutton.h
|
||||
|
||||
playlist/dynamic/DynamicPlaylist.h
|
||||
playlist/dynamic/DynamicControl.h
|
||||
playlist/dynamic/GeneratorInterface.h
|
||||
playlist/dynamic/DynamicView.h
|
||||
playlist/dynamic/DynamicModel.h
|
||||
playlist/dynamic/echonest/EchonestGenerator.h
|
||||
playlist/dynamic/echonest/EchonestControl.h
|
||||
playlist/dynamic/echonest/EchonestSteerer.h
|
||||
playlist/dynamic/widgets/DynamicWidget.h
|
||||
playlist/dynamic/widgets/DynamicControlWrapper.h
|
||||
playlist/dynamic/widgets/DynamicControlList.h
|
||||
playlist/dynamic/widgets/ReadOrWriteWidget.h
|
||||
playlist/dynamic/widgets/MiscControlWidgets.h
|
||||
playlist/dynamic/widgets/CollapsibleControls.h
|
||||
playlist/dynamic/widgets/DynamicSetupWidget.h
|
||||
playlist/dynamic/widgets/LoadingSpinner.h
|
||||
playlist/dynamic/database/DatabaseControl.h
|
||||
playlist/dynamic/database/DatabaseGenerator.h
|
||||
|
||||
resolvers/scriptresolver.h
|
||||
resolvers/qtscriptresolver.h
|
||||
|
||||
utils/widgetdragfilter.h
|
||||
utils/xspfloader.h
|
||||
utils/xspfgenerator.h
|
||||
utils/jspfloader.h
|
||||
utils/spotifyparser.h
|
||||
utils/itunesparser.h
|
||||
utils/rdioparser.h
|
||||
utils/shortenedlinkparser.h
|
||||
utils/qnr_iodevicestream.h
|
||||
utils/dropjobnotifier.h
|
||||
|
||||
widgets/checkdirtree.h
|
||||
widgets/querylabel.h
|
||||
widgets/animatedcounterlabel.h
|
||||
widgets/imagebutton.h
|
||||
widgets/animatedsplitter.h
|
||||
widgets/elidedlabel.h
|
||||
widgets/newplaylistwidget.h
|
||||
widgets/searchwidget.h
|
||||
widgets/SeekSlider.h
|
||||
widgets/playlisttypeselectordlg.h
|
||||
widgets/welcomewidget.h
|
||||
widgets/whatshotwidget.h
|
||||
widgets/whatshotwidget_p.h
|
||||
widgets/RecentlyPlayedPlaylistsModel.h
|
||||
widgets/RecentPlaylistsModel.h
|
||||
widgets/OverlayButton.h
|
||||
widgets/overlaywidget.h
|
||||
widgets/HeaderLabel.h
|
||||
widgets/HeaderWidget.h
|
||||
widgets/combobox.h
|
||||
widgets/ToggleButton.h
|
||||
widgets/SocialPlaylistWidget.h
|
||||
widgets/infowidgets/sourceinfowidget.h
|
||||
widgets/infowidgets/ArtistInfoWidget.h
|
||||
widgets/infowidgets/ArtistInfoWidget_p.h
|
||||
widgets/infowidgets/AlbumInfoWidget.h
|
||||
widgets/Breadcrumb.h
|
||||
widgets/BreadcrumbButton.h
|
||||
|
||||
jobview/JobStatusView.h
|
||||
jobview/JobStatusModel.h
|
||||
jobview/JobStatusDelegate.h
|
||||
jobview/JobStatusItem.h
|
||||
jobview/PipelineStatusItem.h
|
||||
jobview/TransferStatusItem.h
|
||||
jobview/LatchedStatusItem.h
|
||||
|
||||
thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.h
|
||||
|
||||
utils/xspfloader.h
|
||||
utils/qnr_iodevicestream.h
|
||||
thirdparty/Qocoa/qsearchfield.h
|
||||
)
|
||||
|
||||
set( libHeaders_NoMOC
|
||||
viewpage.h
|
||||
|
||||
infosystem/infoplugins/unix/imageconverter.h
|
||||
|
||||
playlist/dynamic/GeneratorInterface.h
|
||||
playlist/dynamic/GeneratorFactory.h
|
||||
|
||||
utils/tomahawkutils.h
|
||||
)
|
||||
|
||||
@@ -519,7 +502,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.
|
||||
${QJSON_INCLUDE_DIR}
|
||||
${LIBECHONEST_INCLUDE_DIR}
|
||||
${LIBECHONEST_INCLUDE_DIR}/..
|
||||
${CLUCENE_INCLUDE_DIR}
|
||||
${CLUCENE_INCLUDE_DIRS}
|
||||
${PHONON_INCLUDES}
|
||||
${CMAKE_BINARY_DIR}/thirdparty/liblastfm2/src
|
||||
|
||||
@@ -535,20 +518,20 @@ IF(QCA2_FOUND)
|
||||
ENDIF(QCA2_FOUND)
|
||||
|
||||
IF(LIBATTICA_FOUND)
|
||||
SET( libGuiSources ${libGuiSources} AtticaManager.cpp )
|
||||
SET( libGuiHeaders ${libGuiHeaders} AtticaManager.h )
|
||||
SET( libSources ${libSources} AtticaManager.cpp )
|
||||
SET( libHeaders ${libHeaders} AtticaManager.h )
|
||||
INCLUDE_DIRECTORIES( ${LIBATTICA_INCLUDE_DIR} )
|
||||
ENDIF(LIBATTICA_FOUND)
|
||||
|
||||
IF( UNIX AND NOT APPLE )
|
||||
SET( libGuiSources ${libGuiSources}
|
||||
SET( libSources ${libSources}
|
||||
infosystem/infoplugins/unix/mprispluginrootadaptor.cpp
|
||||
infosystem/infoplugins/unix/mprispluginplayeradaptor.cpp
|
||||
infosystem/infoplugins/unix/mprisplugin.cpp
|
||||
infosystem/infoplugins/unix/fdonotifyplugin.cpp
|
||||
infosystem/infoplugins/unix/imageconverter.cpp )
|
||||
|
||||
SET( libGuiHeaders ${libGuiHeaders}
|
||||
SET( libHeaders ${libHeaders}
|
||||
infosystem/infoplugins/unix/mprispluginrootadaptor.h
|
||||
infosystem/infoplugins/unix/mprispluginplayeradaptor.h
|
||||
infosystem/infoplugins/unix/mprisplugin.h
|
||||
@@ -602,18 +585,13 @@ IF( APPLE )
|
||||
/System/Library/Frameworks/AppKit.framework
|
||||
)
|
||||
ELSE( APPLE )
|
||||
SET( libGuiSources ${libGuiSources} thirdparty/Qocoa/qsearchfield.cpp )
|
||||
SET( libSources ${libSources} thirdparty/Qocoa/qsearchfield.cpp )
|
||||
ENDIF( APPLE )
|
||||
|
||||
IF(LIBLASTFM_FOUND)
|
||||
SET(LINK_LIBRARIES ${LINK_LIBRARIES} tomahawk_lastfm2 )
|
||||
ENDIF(LIBLASTFM_FOUND)
|
||||
|
||||
IF(BUILD_GUI)
|
||||
LIST(APPEND libSources ${libGuiSources} )
|
||||
LIST(APPEND libHeaders ${libGuiHeaders} )
|
||||
ENDIF()
|
||||
|
||||
qt4_wrap_ui( libUI_H ${libUI} )
|
||||
qt4_wrap_cpp( libMoc ${libHeaders} )
|
||||
|
||||
|
@@ -42,7 +42,7 @@ ActionCollection::initActions()
|
||||
m_actionCollection[ "latchOff" ] = new QAction( tr( "&Stop Listening Along" ), this );
|
||||
|
||||
bool isPublic = TomahawkSettings::instance()->privateListeningMode() == TomahawkSettings::PublicListening;
|
||||
QAction *privacyToggle = new QAction( tr( QString( isPublic ? "&Listen Privately" : "&Listen Publicly" ).toAscii().constData() ), this );
|
||||
QAction *privacyToggle = new QAction( ( isPublic ? tr( "&Listen Privately" ) : tr( "&Listen Publicly" ) ), this );
|
||||
privacyToggle->setIcon( QIcon( RESPATH "images/private-listening.png" ) );
|
||||
privacyToggle->setIconVisibleInMenu( isPublic );
|
||||
m_actionCollection[ "togglePrivacy" ] = privacyToggle;
|
||||
|
@@ -100,14 +100,12 @@ AudioEngine::~AudioEngine()
|
||||
|
||||
delete m_audioOutput;
|
||||
delete m_mediaObject;
|
||||
s_instance = 0;
|
||||
}
|
||||
|
||||
|
||||
QStringList
|
||||
AudioEngine::supportedMimeTypes() const
|
||||
{
|
||||
QMutexLocker locker( &m_mimeTypeMutex );
|
||||
if ( m_supportedMimeTypes.isEmpty() )
|
||||
{
|
||||
m_supportedMimeTypes = Phonon::BackendCapabilities::availableMimeTypes();
|
||||
@@ -123,13 +121,7 @@ AudioEngine::supportedMimeTypes() const
|
||||
void
|
||||
AudioEngine::playPause()
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "playPause" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_mediaObject->state() == Phonon::PlayingState )
|
||||
if ( isPlaying() )
|
||||
pause();
|
||||
else
|
||||
play();
|
||||
@@ -139,21 +131,14 @@ AudioEngine::playPause()
|
||||
void
|
||||
AudioEngine::play()
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "play" );
|
||||
return;
|
||||
}
|
||||
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||
|
||||
if ( m_mediaObject->state() == Phonon::PausedState )
|
||||
if ( isPaused() )
|
||||
{
|
||||
m_mediaObject->play();
|
||||
emit resumed();
|
||||
Tomahawk::InfoSystem::InfoStringHash trackInfo;
|
||||
|
||||
QMutexLocker locker( &m_currentTrackMutex );
|
||||
trackInfo["title"] = m_currentTrack->track();
|
||||
trackInfo["artist"] = m_currentTrack->artist()->name();
|
||||
trackInfo["album"] = m_currentTrack->album()->name();
|
||||
@@ -169,12 +154,6 @@ AudioEngine::play()
|
||||
void
|
||||
AudioEngine::pause()
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "pause" );
|
||||
return;
|
||||
}
|
||||
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||
|
||||
m_mediaObject->pause();
|
||||
@@ -187,15 +166,8 @@ AudioEngine::pause()
|
||||
void
|
||||
AudioEngine::stop()
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "stop" );
|
||||
return;
|
||||
}
|
||||
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||
QMutexLocker locker( &m_playlistMutex );
|
||||
if ( m_mediaObject->state() == Phonon::StoppedState )
|
||||
if ( isStopped() )
|
||||
return;
|
||||
|
||||
setState( Stopped );
|
||||
@@ -203,11 +175,8 @@ AudioEngine::stop()
|
||||
|
||||
if ( !m_playlist.isNull() )
|
||||
m_playlist.data()->reset();
|
||||
|
||||
m_currentTrackMutex.lock();
|
||||
if ( !m_currentTrack.isNull() )
|
||||
emit timerPercentage( ( (double)m_timeElapsed / (double)m_currentTrack->duration() ) * 100.0 );
|
||||
m_currentTrackMutex.unlock();
|
||||
|
||||
emit stopped();
|
||||
setCurrentTrack( Tomahawk::result_ptr() );
|
||||
@@ -233,12 +202,6 @@ AudioEngine::stop()
|
||||
void
|
||||
AudioEngine::previous()
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "previous" );
|
||||
return;
|
||||
}
|
||||
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||
|
||||
if ( canGoPrevious() )
|
||||
@@ -249,12 +212,6 @@ AudioEngine::previous()
|
||||
void
|
||||
AudioEngine::next()
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "next" );
|
||||
return;
|
||||
}
|
||||
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||
|
||||
if ( canGoNext() )
|
||||
@@ -266,9 +223,6 @@ bool
|
||||
AudioEngine::canGoNext()
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||
QMutexLocker plocker( &m_playlistMutex );
|
||||
QMutexLocker qlocker( &m_queueMutex );
|
||||
QMutexLocker ctlocker( &m_currentTrackMutex );
|
||||
|
||||
if ( m_queue && m_queue->trackCount() )
|
||||
return true;
|
||||
@@ -296,7 +250,6 @@ AudioEngine::canGoNext()
|
||||
bool
|
||||
AudioEngine::canGoPrevious()
|
||||
{
|
||||
QMutexLocker locker( &m_playlistMutex );
|
||||
if ( m_playlist.isNull() )
|
||||
return false;
|
||||
|
||||
@@ -311,7 +264,6 @@ AudioEngine::canGoPrevious()
|
||||
bool
|
||||
AudioEngine::canSeek()
|
||||
{
|
||||
QMutexLocker locker( &m_playlistMutex );
|
||||
bool phononCanSeek = true;
|
||||
/* TODO: When phonon properly reports this, re-enable it
|
||||
if ( m_mediaObject && m_mediaObject->isValid() )
|
||||
@@ -324,19 +276,13 @@ AudioEngine::canSeek()
|
||||
void
|
||||
AudioEngine::seek( qint64 ms )
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "seek", Q_ARG( qint64, ms ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !canSeek() )
|
||||
{
|
||||
tDebug( LOGEXTRA ) << "Could not seek!";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_mediaObject->state() == Phonon::PlayingState || m_mediaObject->state() == Phonon::PausedState )
|
||||
if ( isPlaying() || isPaused() )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << ms;
|
||||
m_mediaObject->seek( ms );
|
||||
@@ -355,12 +301,6 @@ AudioEngine::seek( int ms )
|
||||
void
|
||||
AudioEngine::setVolume( int percentage )
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "setVolume", Q_ARG( int, percentage ) );
|
||||
return;
|
||||
}
|
||||
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << percentage;
|
||||
|
||||
percentage = qBound( 0, percentage, 100 );
|
||||
@@ -368,27 +308,6 @@ AudioEngine::setVolume( int percentage )
|
||||
emit volumeChanged( percentage );
|
||||
}
|
||||
|
||||
void
|
||||
AudioEngine::lowerVolume()
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "lowerVolume" );
|
||||
return;
|
||||
}
|
||||
setVolume( volume() - AUDIO_VOLUME_STEP );
|
||||
}
|
||||
|
||||
void
|
||||
AudioEngine::raiseVolume()
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "raiseVolume" );
|
||||
return;
|
||||
}
|
||||
setVolume( volume() + AUDIO_VOLUME_STEP );
|
||||
}
|
||||
|
||||
void
|
||||
AudioEngine::mute()
|
||||
@@ -424,7 +343,6 @@ AudioEngine::sendNowPlayingNotification()
|
||||
m_infoSystemConnected = true;
|
||||
}
|
||||
|
||||
QMutexLocker locker( &m_currentTrackMutex );
|
||||
Tomahawk::InfoSystem::InfoStringHash trackInfo;
|
||||
trackInfo["artist"] = m_currentTrack->album()->artist()->name();
|
||||
trackInfo["album"] = m_currentTrack->album()->name();
|
||||
@@ -442,7 +360,6 @@ AudioEngine::sendNowPlayingNotification()
|
||||
void
|
||||
AudioEngine::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
|
||||
{
|
||||
QMutexLocker locker( &m_currentTrackMutex );
|
||||
if ( requestData.caller != s_aeInfoIdentifier ||
|
||||
requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
|
||||
{
|
||||
@@ -496,7 +413,7 @@ AudioEngine::togglePrivateListeningMode()
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
QAction *privacyToggle = ActionCollection::instance()->getAction( "togglePrivacy" );
|
||||
bool isPublic = TomahawkSettings::instance()->privateListeningMode() == TomahawkSettings::PublicListening;
|
||||
privacyToggle->setText( tr( QString( isPublic ? "&Listen Privately" : "&Listen Publicly" ).toAscii().constData() ) );
|
||||
privacyToggle->setText( ( isPublic ? tr( "&Listen Privately" ) : tr( "&Listen Publicly" ) ) );
|
||||
privacyToggle->setIconVisibleInMenu( isPublic );
|
||||
#endif
|
||||
}
|
||||
@@ -516,7 +433,6 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
||||
{
|
||||
setCurrentTrack( result );
|
||||
|
||||
QMutexLocker locker( &m_currentTrackMutex );
|
||||
if ( !isHttpResult( m_currentTrack->url() ) && !isLocalResult( m_currentTrack->url() ) )
|
||||
{
|
||||
io = Servent::instance()->getIODeviceForUrl( m_currentTrack );
|
||||
@@ -531,7 +447,6 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
||||
|
||||
if ( !err )
|
||||
{
|
||||
QMutexLocker locker( &m_currentTrackMutex );
|
||||
tLog() << "Starting new song:" << m_currentTrack->url();
|
||||
emit loading( m_currentTrack );
|
||||
|
||||
@@ -615,8 +530,7 @@ void
|
||||
AudioEngine::loadPreviousTrack()
|
||||
{
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||
QMutexLocker locker( &m_playlistMutex );
|
||||
|
||||
|
||||
if ( m_playlist.isNull() )
|
||||
{
|
||||
stop();
|
||||
@@ -635,8 +549,6 @@ void
|
||||
AudioEngine::loadNextTrack()
|
||||
{
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
|
||||
QMutexLocker plocker( &m_playlistMutex );
|
||||
QMutexLocker qlocker( &m_queueMutex );
|
||||
|
||||
Tomahawk::result_ptr result;
|
||||
|
||||
@@ -649,9 +561,7 @@ AudioEngine::loadNextTrack()
|
||||
{
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << "Loading playlist's next item";
|
||||
result = m_playlist.data()->nextItem();
|
||||
m_currentTrackPlaylistMutex.lock();
|
||||
m_currentTrackPlaylist = m_playlist;
|
||||
m_currentTrackPlaylistMutex.unlock();
|
||||
}
|
||||
|
||||
if ( !result.isNull() )
|
||||
@@ -672,29 +582,20 @@ AudioEngine::loadNextTrack()
|
||||
void
|
||||
AudioEngine::playItem( Tomahawk::PlaylistInterface* playlist, const Tomahawk::result_ptr& result )
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "playItem", Q_ARG( Tomahawk::PlaylistInterface*, playlist ), Q_ARG( const Tomahawk::result_ptr&, result ) );
|
||||
return;
|
||||
}
|
||||
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() );
|
||||
QMutexLocker locker( &m_playlistMutex );
|
||||
|
||||
if ( !m_playlist.isNull() )
|
||||
m_playlist.data()->reset();
|
||||
|
||||
setPlaylist( playlist );
|
||||
m_currentTrackPlaylistMutex.lock();
|
||||
m_currentTrackPlaylist = playlist->getSharedPointer();
|
||||
m_currentTrackPlaylistMutex.unlock();
|
||||
|
||||
if ( !result.isNull() )
|
||||
loadTrack( result );
|
||||
else if ( !m_playlist.isNull() && m_playlist.data()->retryMode() == PlaylistInterface::Retry )
|
||||
{
|
||||
m_waitingOnNewTrack = true;
|
||||
if ( m_mediaObject->state() == Phonon::StoppedState )
|
||||
if ( isStopped() )
|
||||
sendWaitingNotification();
|
||||
else
|
||||
stop();
|
||||
@@ -725,21 +626,14 @@ void
|
||||
AudioEngine::onStateChanged( Phonon::State newState, Phonon::State oldState )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << oldState << newState << m_expectStop;
|
||||
QMutexLocker plocker( &m_playlistMutex );
|
||||
QMutexLocker vlocker( &m_volumeMutex );
|
||||
m_volume = m_audioOutput->volume() * 100.0;
|
||||
|
||||
|
||||
if ( newState == Phonon::ErrorState )
|
||||
{
|
||||
tLog() << "Phonon Error:" << m_mediaObject->errorString() << m_mediaObject->errorType();
|
||||
return;
|
||||
}
|
||||
if ( newState == Phonon::PlayingState )
|
||||
{
|
||||
QMutexLocker locker( &m_currentTrackMutex );
|
||||
m_currentTrackTotalTime = m_mediaObject->totalTime() > 0 ? m_mediaObject->totalTime() : m_currentTrack->duration() * 1000;
|
||||
setState( Playing );
|
||||
}
|
||||
|
||||
if ( oldState == Phonon::PlayingState )
|
||||
{
|
||||
@@ -748,7 +642,6 @@ AudioEngine::onStateChanged( Phonon::State newState, Phonon::State oldState )
|
||||
{
|
||||
case Phonon::PausedState:
|
||||
{
|
||||
QMutexLocker locker( &m_currentTrackMutex );
|
||||
qint64 duration = m_mediaObject->totalTime() > 0 ? m_mediaObject->totalTime() : m_currentTrack->duration() * 1000;
|
||||
stopped = ( duration - 1000 < m_mediaObject->currentTime() );
|
||||
if ( !stopped )
|
||||
@@ -785,8 +678,6 @@ AudioEngine::onStateChanged( Phonon::State newState, Phonon::State oldState )
|
||||
void
|
||||
AudioEngine::timerTriggered( qint64 time )
|
||||
{
|
||||
QMutexLocker locker( &m_currentTrackMutex );
|
||||
m_currentTime = time;
|
||||
emit timerMilliSeconds( time );
|
||||
|
||||
if ( m_timeElapsed != time / 1000 )
|
||||
@@ -812,14 +703,6 @@ AudioEngine::timerTriggered( qint64 time )
|
||||
void
|
||||
AudioEngine::setPlaylist( PlaylistInterface* playlist )
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "setPlaylist", Q_ARG( Tomahawk::PlaylistInterface*, playlist ) );
|
||||
return;
|
||||
}
|
||||
|
||||
QMutexLocker locker( &m_playlistMutex );
|
||||
|
||||
if ( !m_playlist.isNull() )
|
||||
{
|
||||
if ( m_playlist.data()->object() && m_playlist.data()->retryMode() == PlaylistInterface::Retry )
|
||||
@@ -843,25 +726,9 @@ AudioEngine::setPlaylist( PlaylistInterface* playlist )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::setQueue( Tomahawk::PlaylistInterface* queue )
|
||||
{
|
||||
if ( QThread::currentThread() != AudioEngine::instance()->thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( AudioEngine::instance(), "setQueue", Q_ARG( Tomahawk::PlaylistInterface*, queue ) );
|
||||
return;
|
||||
}
|
||||
|
||||
QMutexLocker locker( &m_queueMutex );
|
||||
|
||||
m_queue = queue;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
||||
{
|
||||
QMutexLocker locker( &m_currentTrackMutex );
|
||||
m_lastTrack = m_currentTrack;
|
||||
if ( !m_lastTrack.isNull() )
|
||||
{
|
||||
@@ -895,7 +762,6 @@ AudioEngine::isLocalResult( const QString& url ) const
|
||||
void
|
||||
AudioEngine::setState( AudioState state )
|
||||
{
|
||||
QMutexLocker locker( &m_stateMutex );
|
||||
AudioState oldState = m_state;
|
||||
m_state = state;
|
||||
|
||||
|
@@ -19,9 +19,8 @@
|
||||
#ifndef AUDIOENGINE_H
|
||||
#define AUDIOENGINE_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
|
||||
#include <phonon/MediaObject>
|
||||
#include <phonon/AudioOutput>
|
||||
@@ -55,23 +54,23 @@ public:
|
||||
~AudioEngine();
|
||||
|
||||
QStringList supportedMimeTypes() const;
|
||||
unsigned int volume() const { return m_volume; } // in percent
|
||||
unsigned int volume() const { return m_audioOutput->volume() * 100.0; } // in percent
|
||||
|
||||
AudioState state() const { QMutexLocker locker( &m_stateMutex ); return m_state; }
|
||||
bool isPlaying() const { QMutexLocker locker( &m_stateMutex ); return m_state == Playing; }
|
||||
bool isPaused() const { QMutexLocker locker( &m_stateMutex ); return m_state == Paused; }
|
||||
bool isStopped() const { QMutexLocker locker( &m_stateMutex ); return m_state == Stopped; }
|
||||
AudioState state() const { return m_state; }
|
||||
bool isPlaying() const { return m_state == Playing; }
|
||||
bool isPaused() const { return m_state == Paused; }
|
||||
bool isStopped() const { return m_state == Stopped; }
|
||||
|
||||
/* Returns the PlaylistInterface of the currently playing track. Note: This might be different to the current playlist! */
|
||||
Tomahawk::PlaylistInterface* currentTrackPlaylist() const { QMutexLocker locker( &m_currentTrackPlaylistMutex ); return m_currentTrackPlaylist.data(); }
|
||||
Tomahawk::PlaylistInterface* currentTrackPlaylist() const { return m_currentTrackPlaylist.data(); }
|
||||
|
||||
/* Returns the PlaylistInterface of the current playlist. Note: The currently playing track might still be from a different playlist! */
|
||||
Tomahawk::PlaylistInterface* playlist() const { QMutexLocker locker( &m_playlistMutex ); return m_playlist.data(); }
|
||||
Tomahawk::PlaylistInterface* playlist() const { return m_playlist.data(); }
|
||||
|
||||
Tomahawk::result_ptr currentTrack() const { QMutexLocker locker( &m_currentTrackMutex ); return m_currentTrack; }
|
||||
Tomahawk::result_ptr currentTrack() const { return m_currentTrack; }
|
||||
|
||||
qint64 currentTime() const { QMutexLocker locker( &m_currentTrackMutex ); return m_currentTime; }
|
||||
qint64 currentTrackTotalTime() const { QMutexLocker locker( &m_currentTrackMutex ); return m_currentTrackTotalTime; }
|
||||
qint64 currentTime() const { return m_mediaObject->currentTime(); }
|
||||
qint64 currentTrackTotalTime() const { return m_mediaObject->totalTime(); }
|
||||
|
||||
public slots:
|
||||
void playPause();
|
||||
@@ -89,14 +88,14 @@ public slots:
|
||||
void seek( qint64 ms );
|
||||
void seek( int ms ); // for compatibility with seekbar in audiocontrols
|
||||
void setVolume( int percentage );
|
||||
void lowerVolume();
|
||||
void raiseVolume();
|
||||
void onVolumeChanged( qreal volume ) { QMutexLocker locker( &m_volumeMutex ); m_volume = volume * 100; emit volumeChanged( volume * 100 ); }
|
||||
void lowerVolume() { setVolume( volume() - AUDIO_VOLUME_STEP ); }
|
||||
void raiseVolume() { setVolume( volume() + AUDIO_VOLUME_STEP ); }
|
||||
void onVolumeChanged( qreal volume ) { emit volumeChanged( volume * 100 ); }
|
||||
void mute();
|
||||
|
||||
void playItem( Tomahawk::PlaylistInterface* playlist, const Tomahawk::result_ptr& result );
|
||||
void setPlaylist( Tomahawk::PlaylistInterface* playlist );
|
||||
void setQueue( Tomahawk::PlaylistInterface* queue );
|
||||
void setQueue( Tomahawk::PlaylistInterface* queue ) { m_queue = queue; }
|
||||
|
||||
void playlistNextTrackReady();
|
||||
|
||||
@@ -167,18 +166,6 @@ private:
|
||||
AudioState m_state;
|
||||
|
||||
static AudioEngine* s_instance;
|
||||
|
||||
mutable QMutex m_stateMutex;
|
||||
mutable QMutex m_mimeTypeMutex;
|
||||
mutable QMutex m_currentTrackMutex;
|
||||
mutable QMutex m_currentTrackPlaylistMutex;
|
||||
mutable QMutex m_playlistMutex;
|
||||
mutable QMutex m_queueMutex;
|
||||
mutable QMutex m_volumeMutex;
|
||||
|
||||
qint64 m_currentTime;
|
||||
qint64 m_currentTrackTotalTime;
|
||||
unsigned int m_volume;
|
||||
};
|
||||
|
||||
#endif // AUDIOENGINE_H
|
||||
|
@@ -1,41 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "audioenginethread.h"
|
||||
#include <utils/logger.h>
|
||||
#include <audio/audioengine.h>
|
||||
|
||||
AudioEngineThread::AudioEngineThread( QObject *parent )
|
||||
: QThread( parent )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
AudioEngineThread::~AudioEngineThread()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
void
|
||||
AudioEngineThread::AudioEngineThread::run()
|
||||
{
|
||||
m_audioEngine = QWeakPointer< AudioEngine >( new AudioEngine() );
|
||||
exec();
|
||||
if( !m_audioEngine.isNull() )
|
||||
delete m_audioEngine.data();
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef AUDIOENGINETHREAD_H
|
||||
#define AUDIOENGINETHREAD_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QWeakPointer>
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
class AudioEngine;
|
||||
|
||||
class DLLEXPORT AudioEngineThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AudioEngineThread( QObject *parent = 0 );
|
||||
virtual ~AudioEngineThread();
|
||||
|
||||
void run();
|
||||
|
||||
private:
|
||||
QWeakPointer< AudioEngine > m_audioEngine;
|
||||
};
|
||||
|
||||
#endif // AUDIOENGINETHREAD_H
|
@@ -132,7 +132,6 @@ DatabaseCollection::stations()
|
||||
void
|
||||
DatabaseCollection::autoPlaylistCreated( const source_ptr& source, const QVariantList& data )
|
||||
{
|
||||
#ifndef ENABLE_HEADLESS
|
||||
dynplaylist_ptr p( new DynamicPlaylist( source, //src
|
||||
data[0].toString(), //current rev
|
||||
data[1].toString(), //title
|
||||
@@ -145,14 +144,12 @@ DatabaseCollection::autoPlaylistCreated( const source_ptr& source, const QVarian
|
||||
data[8].toInt(), //lastmod
|
||||
data[9].toString() ) ); //GUID
|
||||
addAutoPlaylist( p );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DatabaseCollection::stationCreated( const source_ptr& source, const QVariantList& data )
|
||||
{
|
||||
#ifndef ENABLE_HEADLESS
|
||||
dynplaylist_ptr p( new DynamicPlaylist( source, //src
|
||||
data[0].toString(), //current rev
|
||||
data[1].toString(), //title
|
||||
@@ -165,7 +162,6 @@ DatabaseCollection::stationCreated( const source_ptr& source, const QVariantList
|
||||
data[8].toInt(), //lastmod
|
||||
data[9].toString() ) ); //GUID
|
||||
addStation( p );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@@ -35,20 +35,21 @@ DatabaseCommand_addSource::DatabaseCommand_addSource( const QString& username, c
|
||||
void
|
||||
DatabaseCommand_addSource::exec( DatabaseImpl* dbi )
|
||||
{
|
||||
Q_ASSERT( !m_fname.isEmpty() );
|
||||
|
||||
TomahawkSqlQuery query = dbi->newquery();
|
||||
query.prepare( "SELECT id, friendlyname FROM source WHERE name = ?" );
|
||||
query.prepare( "SELECT id FROM source WHERE name = ?" );
|
||||
query.addBindValue( m_username );
|
||||
query.exec();
|
||||
|
||||
if ( query.next() )
|
||||
{
|
||||
unsigned int id = query.value( 0 ).toInt();
|
||||
QString fname = query.value( 1 ).toString();
|
||||
query.prepare( "UPDATE source SET isonline = 'true', friendlyname = ? WHERE id = ?" );
|
||||
query.addBindValue( m_fname );
|
||||
query.addBindValue( id );
|
||||
query.exec();
|
||||
emit done( id, fname );
|
||||
emit done( id, m_fname );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -28,13 +28,10 @@
|
||||
#include "dynamic/GeneratorInterface.h"
|
||||
|
||||
#include "source.h"
|
||||
#include "viewmanager.h"
|
||||
#include "network/servent.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include "viewmanager.h"
|
||||
#endif
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
@@ -114,13 +111,11 @@ DatabaseCommand_CreateDynamicPlaylist::postCommitHook()
|
||||
qDebug() << Q_FUNC_INFO << "..reporting..";
|
||||
if( m_playlist.isNull() ) {
|
||||
source_ptr src = source();
|
||||
#ifndef ENABLE_HEADLESS
|
||||
QMetaObject::invokeMethod( ViewManager::instance(),
|
||||
"createDynamicPlaylist",
|
||||
Qt::BlockingQueuedConnection,
|
||||
QGenericArgument( "Tomahawk::source_ptr", (const void*)&src ),
|
||||
Q_ARG( QVariant, m_v ) );
|
||||
#endif
|
||||
} else {
|
||||
m_playlist->reportCreated( m_playlist );
|
||||
}
|
||||
|
@@ -21,15 +21,12 @@
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include "source.h"
|
||||
#include "viewmanager.h"
|
||||
#include "databaseimpl.h"
|
||||
#include "tomahawksqlquery.h"
|
||||
#include "network/servent.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include "viewmanager.h"
|
||||
#endif
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
@@ -82,13 +79,11 @@ DatabaseCommand_CreatePlaylist::postCommitHook()
|
||||
if ( m_playlist.isNull() )
|
||||
{
|
||||
source_ptr src = source();
|
||||
#ifndef ENABLE_HEADLESS
|
||||
QMetaObject::invokeMethod( ViewManager::instance(),
|
||||
"createPlaylist",
|
||||
Qt::BlockingQueuedConnection,
|
||||
QGenericArgument( "Tomahawk::source_ptr", (const void*)&src ),
|
||||
Q_ARG( QVariant, m_v ) );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -100,7 +100,7 @@ DatabaseCommand_LoadDynamicPlaylistEntries::exec( DatabaseImpl* dbi )
|
||||
|
||||
if( mode == OnDemand )
|
||||
{
|
||||
Q_ASSERT( m_entrymap.isEmpty() ); // ondemand should have no entry
|
||||
// Q_ASSERT( m_entrymap.isEmpty() ); // ondemand should have no entry
|
||||
|
||||
emit done( revisionGuid(), m_islatest, type, controls, true );
|
||||
}
|
||||
|
@@ -36,8 +36,8 @@ using namespace Tomahawk;
|
||||
void
|
||||
DatabaseCommand_LogPlayback::postCommitHook()
|
||||
{
|
||||
connect( this, SIGNAL( trackPlaying( Tomahawk::query_ptr ) ),
|
||||
source().data(), SLOT( onPlaybackStarted( Tomahawk::query_ptr ) ), Qt::QueuedConnection );
|
||||
connect( this, SIGNAL( trackPlaying( Tomahawk::query_ptr, unsigned int ) ),
|
||||
source().data(), SLOT( onPlaybackStarted( Tomahawk::query_ptr, unsigned int ) ), Qt::QueuedConnection );
|
||||
connect( this, SIGNAL( trackPlayed( Tomahawk::query_ptr ) ),
|
||||
source().data(), SLOT( onPlaybackFinished( Tomahawk::query_ptr ) ), Qt::QueuedConnection );
|
||||
|
||||
@@ -60,7 +60,7 @@ DatabaseCommand_LogPlayback::postCommitHook()
|
||||
// if the play time is more than 10 minutes in the past, ignore
|
||||
else if ( m_action == Started && QDateTime::fromTime_t( playtime() ).secsTo( QDateTime::currentDateTime() ) < STARTED_THRESHOLD )
|
||||
{
|
||||
emit trackPlaying( q );
|
||||
emit trackPlaying( q, m_trackDuration );
|
||||
}
|
||||
|
||||
if ( source()->isLocal() )
|
||||
|
@@ -37,6 +37,7 @@ Q_PROPERTY( QString artist READ artist WRITE setArtist )
|
||||
Q_PROPERTY( QString track READ track WRITE setTrack )
|
||||
Q_PROPERTY( unsigned int playtime READ playtime WRITE setPlaytime )
|
||||
Q_PROPERTY( unsigned int secsPlayed READ secsPlayed WRITE setSecsPlayed )
|
||||
Q_PROPERTY( unsigned int trackDuration READ trackDuration WRITE setTrackDuration )
|
||||
Q_PROPERTY( int action READ action WRITE setAction )
|
||||
|
||||
public:
|
||||
@@ -47,13 +48,14 @@ public:
|
||||
};
|
||||
|
||||
explicit DatabaseCommand_LogPlayback( QObject* parent = 0 )
|
||||
: DatabaseCommandLoggable( parent )
|
||||
: DatabaseCommandLoggable( parent ), m_playtime( 0 ), m_secsPlayed( 0 ), m_trackDuration( 0 )
|
||||
{}
|
||||
|
||||
explicit DatabaseCommand_LogPlayback( const Tomahawk::result_ptr& result, Action action, unsigned int secsPlayed = 0, QObject* parent = 0 )
|
||||
: DatabaseCommandLoggable( parent ), m_result( result ), m_secsPlayed( secsPlayed ), m_action( action )
|
||||
{
|
||||
m_playtime = QDateTime::currentDateTimeUtc().toTime_t();
|
||||
m_trackDuration = result->duration();
|
||||
setSource( SourceList::instance()->getLocal() );
|
||||
|
||||
setArtist( result->artist()->name() );
|
||||
@@ -82,11 +84,14 @@ public:
|
||||
unsigned int secsPlayed() const { return m_secsPlayed; }
|
||||
void setSecsPlayed( unsigned int i ) { m_secsPlayed = i; }
|
||||
|
||||
unsigned int trackDuration() const { return m_trackDuration; }
|
||||
void setTrackDuration( unsigned int trackDuration ) { m_trackDuration = trackDuration; }
|
||||
|
||||
int action() const { return m_action; }
|
||||
void setAction( int a ) { m_action = (Action)a; }
|
||||
|
||||
signals:
|
||||
void trackPlaying( const Tomahawk::query_ptr& query );
|
||||
void trackPlaying( const Tomahawk::query_ptr& query, unsigned int duration );
|
||||
void trackPlayed( const Tomahawk::query_ptr& query );
|
||||
|
||||
private:
|
||||
@@ -96,6 +101,7 @@ private:
|
||||
QString m_track;
|
||||
unsigned int m_playtime;
|
||||
unsigned int m_secsPlayed;
|
||||
unsigned int m_trackDuration;
|
||||
Action m_action;
|
||||
};
|
||||
|
||||
|
@@ -87,7 +87,6 @@ DatabaseCommand_SetDynamicPlaylistRevision::controlsV()
|
||||
void
|
||||
DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
|
||||
{
|
||||
#ifndef ENABLE_HEADLESS
|
||||
if ( source().isNull() || source()->collection().isNull() )
|
||||
{
|
||||
tDebug() << "Source has gone offline, not emitting to GUI.";
|
||||
@@ -173,7 +172,6 @@ DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
|
||||
|
||||
if ( source()->isLocal() )
|
||||
Servent::instance()->triggerDBSync();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -251,8 +249,8 @@ DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib )
|
||||
|
||||
controlsQuery.exec();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( m_applied )
|
||||
{
|
||||
tLog() << "updating dynamic playlist, optimistic locking okay";
|
||||
|
@@ -104,6 +104,7 @@ DatabaseCommand_SetPlaylistRevision::exec( DatabaseImpl* lib )
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug() << "Playlist:" << m_playlistguid << m_currentRevision << source()->friendlyName() << source()->id();
|
||||
throw "No such playlist, WTF?";
|
||||
return;
|
||||
}
|
||||
|
@@ -21,13 +21,10 @@
|
||||
#include "localcollection.h"
|
||||
|
||||
#include "sourcelist.h"
|
||||
#include "viewmanager.h"
|
||||
#include <tomahawksettings.h>
|
||||
#include "utils/logger.h"
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include "viewmanager.h"
|
||||
#endif
|
||||
|
||||
|
||||
LocalCollection::LocalCollection( const Tomahawk::source_ptr& source, QObject* parent )
|
||||
: DatabaseCollection( source, parent )
|
||||
@@ -52,12 +49,10 @@ LocalCollection::createBookmarksPlaylist()
|
||||
if( bookmarksPlaylist().isNull() ) {
|
||||
QString guid = uuid();
|
||||
Tomahawk::playlist_ptr p = Tomahawk::Playlist::create( SourceList::instance()->getLocal(), guid, tr( "Bookmarks" ), tr( "Saved tracks" ), QString(), false );
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
ViewManager::instance()->createPageForPlaylist( p );
|
||||
// connect( p.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( loaded( Tomahawk::PlaylistRevision ) ), Qt::QueuedConnection );
|
||||
connect( p.data(), SIGNAL( created() ), this, SLOT( created() ) );
|
||||
#endif
|
||||
|
||||
TomahawkSettings::instance()->setBookmarkPlaylist( guid );
|
||||
// p->createNewRevision( uuid(), p->currentrevision(), QList< Tomahawk::plentry_ptr >() );
|
||||
}
|
||||
|
@@ -266,6 +266,7 @@ CREATE TABLE IF NOT EXISTS playback_log (
|
||||
playtime INTEGER NOT NULL, -- when playback finished (timestamp)
|
||||
secs_played INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX playback_log_source ON playback_log(source);
|
||||
CREATE INDEX playback_log_track ON playback_log(track);
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
This file was automatically generated from schema.sql on Thu Sep 29 17:28:17 EDT 2011.
|
||||
This file was automatically generated from schema.sql on Wed Nov 16 22:47:16 EST 2011.
|
||||
*/
|
||||
|
||||
static const char * tomahawk_schema_sql =
|
||||
|
@@ -34,10 +34,12 @@
|
||||
#include "utils/xspfloader.h"
|
||||
#include "jobview/JobStatusView.h"
|
||||
#include "jobview/JobStatusModel.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
bool DropJob::s_canParseSpotifyPlaylists = false;
|
||||
|
||||
|
||||
DropJob::DropJob( QObject *parent )
|
||||
: QObject( parent )
|
||||
, m_queryCount( 0 )
|
||||
@@ -50,11 +52,13 @@ DropJob::DropJob( QObject *parent )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DropJob::~DropJob()
|
||||
{
|
||||
qDebug() << "destryong DropJob";
|
||||
}
|
||||
|
||||
|
||||
/// QMIMEDATA HANDLING
|
||||
|
||||
QStringList
|
||||
@@ -68,15 +72,18 @@ DropJob::mimeTypes()
|
||||
<< "application/tomahawk.metadata.artist"
|
||||
<< "application/tomahawk.metadata.album"
|
||||
<< "application/tomahawk.mixed"
|
||||
<< "text/plain";
|
||||
<< "text/plain"
|
||||
<< "text/uri-list";
|
||||
|
||||
return mimeTypes;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType, DropJob::DropAction acceptedAction )
|
||||
{
|
||||
Q_UNUSED( acceptedAction );
|
||||
|
||||
if ( data->hasFormat( "application/tomahawk.query.list" )
|
||||
|| data->hasFormat( "application/tomahawk.plentry.list" )
|
||||
|| data->hasFormat( "application/tomahawk.result.list" )
|
||||
@@ -90,7 +97,8 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
||||
|
||||
// check plain text url types
|
||||
if ( !data->hasFormat( "text/plain" ) )
|
||||
return false;
|
||||
if ( !data->hasFormat( "text/uri-list" ) )
|
||||
return false;
|
||||
|
||||
const QString url = data->data( "text/plain" );
|
||||
|
||||
@@ -99,6 +107,9 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
||||
if( url.contains( "xspf" ) )
|
||||
return true;
|
||||
|
||||
if( data->data( "text/uri-list" ).contains( "xspf" ) )
|
||||
return true;
|
||||
|
||||
// Not the most elegant
|
||||
if ( url.contains( "spotify" ) && url.contains( "playlist" ) && s_canParseSpotifyPlaylists )
|
||||
return true;
|
||||
@@ -137,21 +148,22 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
||||
return true;
|
||||
}
|
||||
|
||||
// We whitelist t.co and bit.ly (and j.mp) since they do some link checking. Often playable (e.g. spotify..) links hide behind them,
|
||||
// so we do an extra level of lookup
|
||||
if ( url.contains( "bit.ly" ) || url.contains( "j.mp" ) || url.contains( "t.co" ) || url.contains( "rd.io" ) )
|
||||
// We whitelist certain url-shorteners since they do some link checking. Often playable (e.g. spotify) links hide behind them,
|
||||
// so we do an extra level of lookup
|
||||
if ( ShortenedLinkParser::handlesUrl( url ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DropJob::isDropType( DropJob::DropType desired, const QMimeData* data )
|
||||
{
|
||||
const QString url = data->data( "text/plain" );
|
||||
if ( desired == Playlist )
|
||||
{
|
||||
if( url.contains( "xspf" ) )
|
||||
if( url.contains( "xspf" ) || data->data( "text/uri-list").contains( "xspf" ) )
|
||||
return true;
|
||||
|
||||
// Not the most elegant
|
||||
@@ -161,11 +173,7 @@ DropJob::isDropType( DropJob::DropType desired, const QMimeData* data )
|
||||
if ( url.contains( "rdio.com" ) && url.contains( "people" ) && url.contains( "playlist" ) )
|
||||
return true;
|
||||
|
||||
// we don't know about these.. gotta say yes for now
|
||||
if ( url.contains( "bit.ly" ) ||
|
||||
url.contains( "j.mp" ) ||
|
||||
url.contains( "t.co" ) ||
|
||||
url.contains( "rd.io" ) )
|
||||
if ( ShortenedLinkParser::handlesUrl( url ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -179,6 +187,7 @@ DropJob::setGetWholeArtists( bool getWholeArtists )
|
||||
m_getWholeArtists = getWholeArtists;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::setGetWholeAlbums( bool getWholeAlbums )
|
||||
{
|
||||
@@ -208,6 +217,7 @@ DropJob::tracksFromMimeData( const QMimeData* data, bool allowDuplicates, bool o
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::parseMimeData( const QMimeData *data )
|
||||
{
|
||||
@@ -222,15 +232,21 @@ DropJob::parseMimeData( const QMimeData *data )
|
||||
results = tracksFromArtistMetaData( data );
|
||||
else if ( data->hasFormat( "application/tomahawk.mixed" ) )
|
||||
tracksFromMixedData( data );
|
||||
else if ( data->hasFormat( "text/plain" ) )
|
||||
else if ( data->hasFormat( "text/plain" ) && !data->data( "text/plain" ).isEmpty() )
|
||||
{
|
||||
const QString plainData = QString::fromUtf8( data->data( "text/plain" ) );
|
||||
handleAllUrls( plainData );
|
||||
|
||||
}else if ( data->hasFormat( "text/uri-list" ) )
|
||||
{
|
||||
const QString plainData = QString::fromUtf8( data->data( "text/uri-list" ).trimmed() );
|
||||
handleAllUrls( plainData );
|
||||
}
|
||||
|
||||
m_resultList.append( results );
|
||||
}
|
||||
|
||||
|
||||
QList< query_ptr >
|
||||
DropJob::tracksFromQueryList( const QMimeData* data )
|
||||
{
|
||||
@@ -270,6 +286,7 @@ DropJob::tracksFromQueryList( const QMimeData* data )
|
||||
return queries;
|
||||
}
|
||||
|
||||
|
||||
QList< query_ptr >
|
||||
DropJob::tracksFromResultList( const QMimeData* data )
|
||||
{
|
||||
@@ -311,6 +328,7 @@ DropJob::tracksFromResultList( const QMimeData* data )
|
||||
return queries;
|
||||
}
|
||||
|
||||
|
||||
QList< query_ptr >
|
||||
DropJob::tracksFromAlbumMetaData( const QMimeData *data )
|
||||
{
|
||||
@@ -335,6 +353,7 @@ DropJob::tracksFromAlbumMetaData( const QMimeData *data )
|
||||
return queries;
|
||||
}
|
||||
|
||||
|
||||
QList< query_ptr >
|
||||
DropJob::tracksFromArtistMetaData( const QMimeData *data )
|
||||
{
|
||||
@@ -359,6 +378,7 @@ DropJob::tracksFromArtistMetaData( const QMimeData *data )
|
||||
return queries;
|
||||
}
|
||||
|
||||
|
||||
QList< query_ptr >
|
||||
DropJob::tracksFromMixedData( const QMimeData *data )
|
||||
{
|
||||
@@ -407,32 +427,50 @@ DropJob::tracksFromMixedData( const QMimeData *data )
|
||||
return queries;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::handleXspfs( const QString& fileUrls )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "Got xspf playlist!!" << fileUrls;
|
||||
|
||||
QStringList urls = fileUrls.split( QRegExp( "\\s+" ), QString::SkipEmptyParts );
|
||||
bool error = false;
|
||||
QStringList urls = fileUrls.split( QRegExp( "\n" ), QString::SkipEmptyParts );
|
||||
|
||||
if ( dropAction() == Default )
|
||||
setDropAction( Create );
|
||||
|
||||
foreach ( const QString& url, urls )
|
||||
{
|
||||
XSPFLoader* l = 0;
|
||||
QFile xspfFile( QUrl::fromUserInput( url ).toLocalFile() );
|
||||
|
||||
if ( xspfFile.exists() )
|
||||
{
|
||||
XSPFLoader* l = new XSPFLoader( true, this );
|
||||
l = new XSPFLoader( dropAction() == Create, this );
|
||||
tDebug( LOGINFO ) << "Loading local xspf " << xspfFile.fileName();
|
||||
l->load( xspfFile );
|
||||
}
|
||||
else if ( QUrl( url ).isValid() )
|
||||
{
|
||||
l = new XSPFLoader( dropAction() == Create, this );
|
||||
tDebug( LOGINFO ) << "Loading remote xspf " << url;
|
||||
l->load( QUrl( url ) );
|
||||
}
|
||||
else
|
||||
tLog( LOGINFO ) << "Error Loading local xspf " << xspfFile.fileName();
|
||||
}
|
||||
{
|
||||
error = true;
|
||||
tLog() << "Failed to load or parse dropped XSPF";
|
||||
}
|
||||
|
||||
if ( dropAction() == Append && !error && l )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Trying to append xspf";
|
||||
connect( l, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( onTracksAdded( QList< Tomahawk::query_ptr > ) ) );
|
||||
m_queryCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::handleSpotifyUrls( const QString& urlsRaw )
|
||||
{
|
||||
@@ -458,6 +496,7 @@ DropJob::handleSpotifyUrls( const QString& urlsRaw )
|
||||
m_queryCount++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::handleRdioUrls( const QString& urlsRaw )
|
||||
{
|
||||
@@ -470,10 +509,10 @@ DropJob::handleRdioUrls( const QString& urlsRaw )
|
||||
RdioParser* rdio = new RdioParser( this );
|
||||
connect( rdio, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SLOT( onTracksAdded( QList< Tomahawk::query_ptr > ) ) );
|
||||
|
||||
m_queryCount++;
|
||||
rdio->setCreatePlaylist( dropAction() == Create );
|
||||
rdio->parse( urls );
|
||||
|
||||
m_queryCount++;
|
||||
}
|
||||
|
||||
|
||||
@@ -524,10 +563,8 @@ DropJob::handleTrackUrls( const QString& urls )
|
||||
m_queryCount++;
|
||||
|
||||
rdio->parse( tracks );
|
||||
} else if ( urls.contains( "bit.ly" ) ||
|
||||
urls.contains( "j.mp" ) ||
|
||||
urls.contains( "t.co" ) ||
|
||||
urls.contains( "rd.io" ) )
|
||||
}
|
||||
else if ( ShortenedLinkParser::handlesUrl( urls ) )
|
||||
{
|
||||
QStringList tracks = urls.split( QRegExp( "\\s+" ), QString::SkipEmptyParts );
|
||||
|
||||
@@ -538,6 +575,7 @@ DropJob::handleTrackUrls( const QString& urls )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::expandedUrls( QStringList urls )
|
||||
{
|
||||
@@ -545,6 +583,7 @@ DropJob::expandedUrls( QStringList urls )
|
||||
handleAllUrls( urls.join( "\n" ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::onTracksAdded( const QList<Tomahawk::query_ptr>& tracksList )
|
||||
{
|
||||
@@ -569,6 +608,7 @@ DropJob::onTracksAdded( const QList<Tomahawk::query_ptr>& tracksList )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::removeDuplicates()
|
||||
{
|
||||
@@ -587,6 +627,7 @@ DropJob::removeDuplicates()
|
||||
m_resultList = list;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::removeRemoteSources()
|
||||
{
|
||||
@@ -605,6 +646,7 @@ DropJob::removeRemoteSources()
|
||||
m_resultList = list;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
|
||||
{
|
||||
@@ -634,6 +676,7 @@ DropJob::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVar
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QList< query_ptr >
|
||||
DropJob::getArtist( const QString &artist )
|
||||
{
|
||||
@@ -649,6 +692,7 @@ DropJob::getArtist( const QString &artist )
|
||||
return artistPtr->tracks();
|
||||
}
|
||||
|
||||
|
||||
QList< query_ptr >
|
||||
DropJob::getAlbum(const QString &artist, const QString &album)
|
||||
{
|
||||
@@ -672,6 +716,7 @@ DropJob::getAlbum(const QString &artist, const QString &album)
|
||||
return albumPtr->tracks();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropJob::getTopTen( const QString &artist )
|
||||
{
|
||||
|
@@ -108,6 +108,7 @@ public:
|
||||
|
||||
static bool canParseSpotifyPlaylists() { return s_canParseSpotifyPlaylists; }
|
||||
static void setCanParseSpotifyPlaylists( bool parseable ) { s_canParseSpotifyPlaylists = parseable; }
|
||||
|
||||
signals:
|
||||
/// QMimeData parsing results
|
||||
void tracks( const QList< Tomahawk::query_ptr >& tracks );
|
||||
|
@@ -18,10 +18,8 @@
|
||||
|
||||
#include "globalactionmanager.h"
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QClipboard>
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QMimeData>
|
||||
#include <QUrl>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
@@ -33,10 +31,13 @@
|
||||
#include "album.h"
|
||||
#include "sourcelist.h"
|
||||
#include "pipeline.h"
|
||||
#include "viewmanager.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "audio/audioengine.h"
|
||||
#include "database/localcollection.h"
|
||||
#include "playlist/dynamic/GeneratorInterface.h"
|
||||
#include "playlist/topbar/topbar.h"
|
||||
#include "playlist/playlistview.h"
|
||||
|
||||
#include "echonest/Playlist.h"
|
||||
|
||||
@@ -49,15 +50,7 @@
|
||||
#include "utils/spotifyparser.h"
|
||||
#include "utils/shortenedlinkparser.h"
|
||||
#include "utils/rdioparser.h"
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QApplication>
|
||||
#include "widgets/searchwidget.h"
|
||||
#include "viewmanager.h"
|
||||
#include "playlist/topbar/topbar.h"
|
||||
#include "playlist/playlistview.h"
|
||||
|
||||
#endif
|
||||
#include "widgets/searchwidget.h"
|
||||
|
||||
GlobalActionManager* GlobalActionManager::s_instance = 0;
|
||||
|
||||
@@ -304,12 +297,12 @@ GlobalActionManager::handlePlaylistCommand( const QUrl& url )
|
||||
tDebug() << "No xspf to load...";
|
||||
return false;
|
||||
}
|
||||
QUrl xspf = QUrl( url.queryItemValue( "xspf" ) );
|
||||
QUrl xspf = QUrl::fromUserInput( url.queryItemValue( "xspf" ) );
|
||||
QString title = url.hasQueryItem( "title" ) ? url.queryItemValue( "title" ) : QString();
|
||||
XSPFLoader* l= new XSPFLoader( true, this );
|
||||
l->setOverrideTitle( title );
|
||||
l->load( xspf );
|
||||
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), ViewManager::instance(), SLOT( show( Tomahawk::playlist_ptr ) ) );
|
||||
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), this, SLOT( playlistCreatedToShow( Tomahawk::playlist_ptr) ) );
|
||||
|
||||
} else if( parts [ 0 ] == "new" ) {
|
||||
if( !url.hasQueryItem( "title" ) ) {
|
||||
@@ -330,6 +323,22 @@ GlobalActionManager::handlePlaylistCommand( const QUrl& url )
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
GlobalActionManager::playlistCreatedToShow( const playlist_ptr& pl )
|
||||
{
|
||||
connect( pl.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( playlistReadyToShow() ) );
|
||||
pl->setProperty( "sharedptr", QVariant::fromValue<Tomahawk::playlist_ptr>( pl ) );
|
||||
}
|
||||
|
||||
void GlobalActionManager::playlistReadyToShow()
|
||||
{
|
||||
playlist_ptr pl = sender()->property( "sharedptr" ).value<Tomahawk::playlist_ptr>();
|
||||
if ( !pl.isNull() )
|
||||
ViewManager::instance()->show( pl );
|
||||
|
||||
disconnect( sender(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( playlistReadyToShow() ) );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GlobalActionManager::handleCollectionCommand( const QUrl& url )
|
||||
@@ -415,6 +424,7 @@ GlobalActionManager::doQueueAdd( const QStringList& parts, const QList< QPair< Q
|
||||
|
||||
QString title, artist, album, urlStr;
|
||||
foreach( pair, queryItems ) {
|
||||
pair.second = pair.second.replace( "+", " " ); // QUrl::queryItems doesn't decode + to a space :(
|
||||
if( pair.first == "title" )
|
||||
title = pair.second;
|
||||
else if( pair.first == "artist" )
|
||||
@@ -438,7 +448,7 @@ GlobalActionManager::doQueueAdd( const QStringList& parts, const QList< QPair< Q
|
||||
foreach( pair, queryItems ) {
|
||||
if( pair.first != "url" )
|
||||
continue;
|
||||
QUrl track = QUrl::fromUserInput( pair.second );
|
||||
QUrl track = QUrl::fromUserInput( pair.second );
|
||||
//FIXME: isLocalFile is Qt 4.8
|
||||
if( track.toString().startsWith( "file://" ) ) { // it's local, so we see if it's in the DB and load it if so
|
||||
// TODO
|
||||
|
@@ -81,6 +81,8 @@ private slots:
|
||||
void playOrQueueNow( const Tomahawk::query_ptr& );
|
||||
void playNow( const Tomahawk::query_ptr& );
|
||||
|
||||
void playlistCreatedToShow( const Tomahawk::playlist_ptr& pl );
|
||||
void playlistReadyToShow();
|
||||
private:
|
||||
explicit GlobalActionManager( QObject* parent = 0 );
|
||||
void doBookmark( const Tomahawk::playlist_ptr& pl, const Tomahawk::query_ptr& q );
|
||||
|
@@ -39,9 +39,6 @@
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@@ -76,9 +73,6 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
@@ -92,9 +86,6 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
@@ -143,9 +134,6 @@
|
||||
<height>62</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
|
@@ -32,7 +32,7 @@
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#define CHART_URL "http://charts.tomahawk-player.org:10080/"
|
||||
#define CHART_URL "http://charts.tomahawk-player.org/"
|
||||
//#define CHART_URL "http://localhost:8080/"
|
||||
#include <qjson/parser.h>
|
||||
#include <qjson/serializer.h>
|
||||
|
@@ -32,7 +32,7 @@
|
||||
#include "utils/logger.h"
|
||||
#include "chartsplugin_data_p.h"
|
||||
|
||||
#define SPOTIFY_API_URL "http://spotikea.tomahawk-player.org:10380/"
|
||||
#define SPOTIFY_API_URL "http://spotikea.tomahawk-player.org/"
|
||||
#include <qjson/parser.h>
|
||||
#include <qjson/serializer.h>
|
||||
|
||||
|
@@ -17,15 +17,11 @@
|
||||
*/
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QDir>
|
||||
#include <QSettings>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QDesktopServices>
|
||||
#endif
|
||||
|
||||
#include "infosystemcache.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "utils/logger.h"
|
||||
@@ -40,11 +36,7 @@ namespace InfoSystem
|
||||
|
||||
InfoSystemCache::InfoSystemCache( QObject* parent )
|
||||
: QObject( parent )
|
||||
#ifndef ENABLE_HEADLESS
|
||||
, m_cacheBaseDir( QDesktopServices::storageLocation( QDesktopServices::CacheLocation ) + "/InfoSystemCache/" )
|
||||
#else
|
||||
, m_cacheBaseDir( QDir::tempPath() )
|
||||
#endif
|
||||
, m_cacheVersion( 2 )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
|
@@ -78,7 +78,7 @@ void
|
||||
InfoSystemWorker::init( Tomahawk::InfoSystem::InfoSystemCache* cache )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
#ifndef ENABLE_HEADLESS
|
||||
|
||||
InfoPluginPtr enptr( new EchoNestPlugin() );
|
||||
m_plugins.append( enptr );
|
||||
registerInfoTypes( enptr, enptr.data()->supportedGetTypes(), enptr.data()->supportedPushTypes() );
|
||||
@@ -103,14 +103,13 @@ InfoSystemWorker::init( Tomahawk::InfoSystem::InfoSystemCache* cache )
|
||||
InfoPluginPtr hypeptr( new hypemPlugin() );
|
||||
m_plugins.append( hypeptr );
|
||||
registerInfoTypes( hypeptr, hypeptr.data()->supportedGetTypes(), hypeptr.data()->supportedPushTypes() );
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
InfoPluginPtr admptr( new AdiumPlugin() );
|
||||
m_plugins.append( admptr );
|
||||
registerInfoTypes( admptr, admptr.data()->supportedGetTypes(), admptr.data()->supportedPushTypes() );
|
||||
#endif
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#ifdef Q_WS_X11
|
||||
InfoPluginPtr fdonotifyptr( new FdoNotifyPlugin() );
|
||||
m_plugins.append( fdonotifyptr );
|
||||
@@ -119,7 +118,7 @@ InfoSystemWorker::init( Tomahawk::InfoSystem::InfoSystemCache* cache )
|
||||
m_plugins.append( mprisptr );
|
||||
registerInfoTypes( mprisptr, mprisptr.data()->supportedGetTypes(), mprisptr.data()->supportedPushTypes() );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Q_FOREACH( InfoPluginPtr plugin, m_plugins )
|
||||
{
|
||||
connect(
|
||||
@@ -277,7 +276,7 @@ InfoSystemWorker::checkFinished( const Tomahawk::InfoSystem::InfoRequestData &re
|
||||
{
|
||||
if ( m_dataTracker[ requestData.caller ][ requestData.type ] == 0 )
|
||||
emit finished( requestData.caller, requestData.type );
|
||||
|
||||
|
||||
Q_FOREACH( InfoType testtype, m_dataTracker[ requestData.caller ].keys() )
|
||||
{
|
||||
if ( m_dataTracker[ requestData.caller ][ testtype ] != 0 )
|
||||
|
@@ -81,6 +81,7 @@ JobStatusModel::data( const QModelIndex& index, int role ) const
|
||||
{
|
||||
case Qt::DecorationRole:
|
||||
return item->icon();
|
||||
case Qt::ToolTipRole:
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
if ( m_collapseCount.contains( item->type() ) )
|
||||
@@ -114,7 +115,7 @@ JobStatusModel::itemFinished()
|
||||
JobStatusItem* item = qobject_cast< JobStatusItem* >( sender() );
|
||||
Q_ASSERT( item );
|
||||
|
||||
tDebug() << "Got item finished:" << item->type() << item->mainText() << item;
|
||||
// tDebug() << "Got item finished:" << item->type() << item->mainText() << item;
|
||||
if ( !m_items.contains( item ) && !m_collapseCount.contains( item->type() ) )
|
||||
return;
|
||||
|
||||
@@ -140,7 +141,7 @@ JobStatusModel::itemFinished()
|
||||
// qDebug() << "Replaced" << m_collapseCount[ item->type() ].first() << "with:" << m_collapseCount[ item->type() ][ 1 ] << m_items;
|
||||
}
|
||||
m_collapseCount[ item->type() ].removeAll( item );
|
||||
tDebug() << "New collapse count list:" << m_collapseCount[ item->type() ];
|
||||
// tDebug() << "New collapse count list:" << m_collapseCount[ item->type() ];
|
||||
if ( m_collapseCount[ item->type() ].isEmpty() )
|
||||
m_collapseCount.remove( item->type() );
|
||||
else
|
||||
|
@@ -18,8 +18,8 @@
|
||||
|
||||
#include "connection.h"
|
||||
|
||||
#include <QTime>
|
||||
#include <QThread>
|
||||
#include <QtCore/QTime>
|
||||
#include <QtCore/QThread>
|
||||
|
||||
#include "network/servent.h"
|
||||
#include "utils/logger.h"
|
||||
@@ -82,7 +82,7 @@ Connection::handleIncomingQueueEmpty()
|
||||
// << "m_peer_disconnected" << m_peer_disconnected
|
||||
// << "bytes rx" << bytesReceived();
|
||||
|
||||
if( m_sock->bytesAvailable() == 0 && m_peer_disconnected )
|
||||
if( !m_sock.isNull() && m_sock->bytesAvailable() == 0 && m_peer_disconnected )
|
||||
{
|
||||
qDebug() << "No more data to read, peer disconnected. shutting down connection."
|
||||
<< "bytesavail" << m_sock->bytesAvailable()
|
||||
@@ -276,14 +276,15 @@ Connection::socketDisconnected()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Connection::socketDisconnectedError(QAbstractSocket::SocketError e)
|
||||
Connection::socketDisconnectedError( QAbstractSocket::SocketError e )
|
||||
{
|
||||
qDebug() << "SOCKET ERROR CODE" << e << this->name() << "CALLING Connection::shutdown(false)";
|
||||
|
||||
if ( e == QAbstractSocket::RemoteHostClosedError )
|
||||
return;
|
||||
|
||||
qDebug() << "SOCKET ERROR CODE" << e << this->name() << "CALLING Connection::shutdown(false)";
|
||||
|
||||
m_peer_disconnected = true;
|
||||
|
||||
emit socketErrored(e);
|
||||
|
@@ -19,17 +19,17 @@
|
||||
#ifndef CONNECTION_H
|
||||
#define CONNECTION_H
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QTcpSocket>
|
||||
#include <QHostAddress>
|
||||
#include <QVariant>
|
||||
#include <QVariantMap>
|
||||
#include <QString>
|
||||
#include <QDataStream>
|
||||
#include <QtEndian>
|
||||
#include <QTimer>
|
||||
#include <QTime>
|
||||
#include <QPointer>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtNetwork/QTcpSocket>
|
||||
#include <QtNetwork/QHostAddress>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QVariantMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QtCore/QtEndian>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QTime>
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#include <qjson/parser.h>
|
||||
#include <qjson/serializer.h>
|
||||
@@ -87,6 +87,8 @@ public:
|
||||
void setMsgProcessorModeOut( quint32 m ) { m_msgprocessor_out.setMode( m ); }
|
||||
void setMsgProcessorModeIn( quint32 m ) { m_msgprocessor_in.setMode( m ); }
|
||||
|
||||
const QHostAddress peerIpAddress() const { return m_peerIpAddress; }
|
||||
|
||||
signals:
|
||||
void ready();
|
||||
void failed();
|
||||
@@ -128,6 +130,7 @@ protected:
|
||||
bool m_outbound, m_ready, m_onceonly;
|
||||
msg_ptr m_firstmsg;
|
||||
QString m_name;
|
||||
QHostAddress m_peerIpAddress;
|
||||
|
||||
private:
|
||||
void handleReadMsg();
|
||||
|
@@ -33,7 +33,7 @@
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
ControlConnection::ControlConnection( Servent* parent )
|
||||
ControlConnection::ControlConnection( Servent* parent, const QHostAddress &ha )
|
||||
: Connection( parent )
|
||||
, m_dbsyncconn( 0 )
|
||||
, m_registered( false )
|
||||
@@ -47,6 +47,38 @@ ControlConnection::ControlConnection( Servent* parent )
|
||||
|
||||
this->setMsgProcessorModeIn( MsgProcessor::UNCOMPRESS_ALL | MsgProcessor::PARSE_JSON );
|
||||
this->setMsgProcessorModeOut( MsgProcessor::COMPRESS_IF_LARGE );
|
||||
|
||||
m_peerIpAddress = ha;
|
||||
}
|
||||
|
||||
|
||||
ControlConnection::ControlConnection( Servent* parent, const QString &ha )
|
||||
: Connection( parent )
|
||||
, m_dbsyncconn( 0 )
|
||||
, m_registered( false )
|
||||
, m_pingtimer( 0 )
|
||||
{
|
||||
qDebug() << "CTOR controlconnection";
|
||||
setId("ControlConnection()");
|
||||
|
||||
// auto delete when connection closes:
|
||||
connect( this, SIGNAL( finished() ), SLOT( deleteLater() ) );
|
||||
|
||||
this->setMsgProcessorModeIn( MsgProcessor::UNCOMPRESS_ALL | MsgProcessor::PARSE_JSON );
|
||||
this->setMsgProcessorModeOut( MsgProcessor::COMPRESS_IF_LARGE );
|
||||
|
||||
if ( !ha.isEmpty() )
|
||||
{
|
||||
QHostAddress qha( ha );
|
||||
if ( !qha.isNull() )
|
||||
m_peerIpAddress = qha;
|
||||
else
|
||||
{
|
||||
QHostInfo qhi = QHostInfo::fromName( ha );
|
||||
if ( !qhi.addresses().isEmpty() )
|
||||
m_peerIpAddress = qhi.addresses().first();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +104,7 @@ ControlConnection::source() const
|
||||
Connection*
|
||||
ControlConnection::clone()
|
||||
{
|
||||
ControlConnection* clone = new ControlConnection( servent() );
|
||||
ControlConnection* clone = new ControlConnection( servent(), m_peerIpAddress.toString() );
|
||||
clone->setOnceOnly( onceOnly() );
|
||||
clone->setName( name() );
|
||||
return clone;
|
||||
@@ -102,6 +134,8 @@ ControlConnection::setup()
|
||||
else
|
||||
friendlyName = name();
|
||||
|
||||
tDebug() << "Detected name:" << name() << friendlyName << m_sock->peerAddress();
|
||||
|
||||
// setup source and remote collection for this peer
|
||||
m_source = SourceList::instance()->get( id(), friendlyName );
|
||||
m_source->setControlConnection( this );
|
||||
@@ -130,13 +164,11 @@ ControlConnection::registerSource()
|
||||
Q_UNUSED( source )
|
||||
Q_ASSERT( source == m_source.data() );
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
// qDebug() << Q_FUNC_INFO << "Setting avatar ... " << name() << !SipHandler::instance()->avatar( name() ).isNull();
|
||||
if( !SipHandler::instance()->avatar( name() ).isNull() )
|
||||
{
|
||||
source->setAvatar( SipHandler::instance()->avatar( name() ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
m_registered = true;
|
||||
m_servent->registerControlConnection( this );
|
||||
|
@@ -39,7 +39,8 @@ class DLLEXPORT ControlConnection : public Connection
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ControlConnection( Servent* parent = 0 );
|
||||
explicit ControlConnection( Servent* parent = 0, const QHostAddress &ha = QHostAddress() );
|
||||
explicit ControlConnection( Servent* parent = 0, const QString &ha = QString() );
|
||||
~ControlConnection();
|
||||
Connection* clone();
|
||||
|
||||
|
@@ -63,7 +63,7 @@ DBSyncConnection::DBSyncConnection( Servent* s, const source_ptr& src )
|
||||
|
||||
DBSyncConnection::~DBSyncConnection()
|
||||
{
|
||||
tDebug() << "DTOR" << Q_FUNC_INFO << m_source->friendlyName();
|
||||
tDebug() << "DTOR" << Q_FUNC_INFO << m_source->id() << m_source->friendlyName();
|
||||
m_state = SHUTDOWN;
|
||||
}
|
||||
|
||||
@@ -117,8 +117,6 @@ DBSyncConnection::check()
|
||||
}
|
||||
|
||||
m_uscache.clear();
|
||||
m_us.clear();
|
||||
|
||||
changeState( CHECKING );
|
||||
|
||||
// load last-modified etc data for our collection and theirs from our DB:
|
||||
@@ -144,7 +142,7 @@ DBSyncConnection::check()
|
||||
void
|
||||
DBSyncConnection::gotUs( const QVariantMap& m )
|
||||
{
|
||||
m_us = m;
|
||||
Q_UNUSED( m )
|
||||
if ( !m_uscache.empty() )
|
||||
sendOps();
|
||||
}
|
||||
@@ -227,8 +225,7 @@ DBSyncConnection::handleMsg( msg_ptr msg )
|
||||
if ( m.value( "method" ).toString() == "fetchops" )
|
||||
{
|
||||
m_uscache = m;
|
||||
if ( !m_us.empty() )
|
||||
sendOps();
|
||||
sendOps();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -278,6 +275,7 @@ DBSyncConnection::sendOpsData( QString sinceguid, QString lastguid, QList< dbop_
|
||||
m_lastSentOp = lastguid;
|
||||
if ( ops.length() == 0 )
|
||||
{
|
||||
tLog( LOGVERBOSE ) << "Sending ok" << m_source->id() << m_source->friendlyName();
|
||||
sendMsg( Msg::factory( "ok", Msg::DBOP ) );
|
||||
return;
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ private:
|
||||
void changeState( State newstate );
|
||||
|
||||
Tomahawk::source_ptr m_source;
|
||||
QVariantMap m_us, m_uscache;
|
||||
QVariantMap m_uscache;
|
||||
|
||||
QString m_lastSentOp;
|
||||
|
||||
|
@@ -18,8 +18,7 @@
|
||||
|
||||
#include "portfwdthread.h"
|
||||
|
||||
#include "headlesscheck.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QNetworkInterface>
|
||||
#include <QStringList>
|
||||
#include <QTime>
|
||||
|
@@ -26,11 +26,8 @@
|
||||
#include <QNetworkProxy>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QPushButton>
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
#include <QPushButton>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "result.h"
|
||||
#include "source.h"
|
||||
@@ -164,7 +161,7 @@ Servent::createConnectionKey( const QString& name, const QString &nodeid, const
|
||||
Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||
|
||||
QString _key = ( key.isEmpty() ? uuid() : key );
|
||||
ControlConnection* cc = new ControlConnection( this );
|
||||
ControlConnection* cc = new ControlConnection( this, name );
|
||||
cc->setName( name.isEmpty() ? QString( "KEY(%1)" ).arg( key ) : name );
|
||||
if ( !nodeid.isEmpty() )
|
||||
cc->setId( nodeid );
|
||||
@@ -354,7 +351,7 @@ Servent::readyRead()
|
||||
|
||||
foreach( ControlConnection* con, m_controlconnections )
|
||||
{
|
||||
tDebug() << "known connection:" << con->id() << con->source()->friendlyName();
|
||||
tLog( LOGVERBOSE ) << "known connection:" << con->id() << con->source()->friendlyName();
|
||||
if( con->id() == nodeid )
|
||||
{
|
||||
dupe = true;
|
||||
@@ -382,6 +379,7 @@ Servent::readyRead()
|
||||
if( conntype == "accept-offer" || "push-offer" )
|
||||
{
|
||||
sock->_msg.clear();
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << key << nodeid << "socket peer address = " << sock->peerAddress() << "socket peer name = " << sock->peerName();
|
||||
Connection* conn = claimOffer( cc, nodeid, key, sock->peerAddress() );
|
||||
if( !conn )
|
||||
{
|
||||
@@ -415,7 +413,7 @@ closeconnection:
|
||||
void
|
||||
Servent::createParallelConnection( Connection* orig_conn, Connection* new_conn, const QString& key )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << "Servent::createParallelConnection, key:" << key << thread() << orig_conn;
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << ", key:" << key << thread() << orig_conn;
|
||||
// if we can connect to them directly:
|
||||
if( orig_conn && orig_conn->outbound() )
|
||||
{
|
||||
@@ -448,7 +446,7 @@ Servent::socketConnected()
|
||||
{
|
||||
QTcpSocketExtra* sock = (QTcpSocketExtra*)sender();
|
||||
|
||||
tDebug( LOGVERBOSE ) << "Servent::SocketConnected" << thread() << "socket:" << sock;
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << thread() << "socket: " << sock << ", hostaddr: " << sock->peerAddress() << ", hostname: " << sock->peerName();
|
||||
|
||||
Connection* conn = sock->_conn.data();
|
||||
handoverSocket( conn, sock );
|
||||
@@ -512,7 +510,7 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, const Q
|
||||
{
|
||||
Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||
|
||||
ControlConnection* conn = new ControlConnection( this );
|
||||
ControlConnection* conn = new ControlConnection( this, ha );
|
||||
QVariantMap m;
|
||||
m["conntype"] = "accept-offer";
|
||||
m["key"] = key;
|
||||
@@ -564,7 +562,10 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, Connect
|
||||
connect( sock, SIGNAL( error( QAbstractSocket::SocketError ) ),
|
||||
SLOT( socketError( QAbstractSocket::SocketError ) ) );
|
||||
|
||||
sock->connectToHost( ha, port, QTcpSocket::ReadWrite );
|
||||
if ( !conn->peerIpAddress().isNull() )
|
||||
sock->connectToHost( conn->peerIpAddress(), port, QTcpSocket::ReadWrite );
|
||||
else
|
||||
sock->connectToHost( ha, port, QTcpSocket::ReadWrite );
|
||||
sock->moveToThread( thread() );
|
||||
}
|
||||
|
||||
@@ -631,7 +632,7 @@ Servent::claimOffer( ControlConnection* cc, const QString &nodeid, const QString
|
||||
if( isIPWhitelisted( peer ) )
|
||||
{
|
||||
tDebug() << "Connection is from whitelisted IP range (LAN)";
|
||||
Connection* conn = new ControlConnection( this );
|
||||
Connection* conn = new ControlConnection( this, peer.toString() );
|
||||
conn->setName( peer.toString() );
|
||||
return conn;
|
||||
}
|
||||
@@ -677,7 +678,7 @@ Servent::claimOffer( ControlConnection* cc, const QString &nodeid, const QString
|
||||
else if ( noauth )
|
||||
{
|
||||
Connection* conn;
|
||||
conn = new ControlConnection( this );
|
||||
conn = new ControlConnection( this, peer );
|
||||
conn->setName( key );
|
||||
return conn;
|
||||
}
|
||||
@@ -699,7 +700,7 @@ Servent::checkACL( const Connection* conn, const QString &nodeid, bool showDialo
|
||||
if( peerStatus == ACLSystem::Deny )
|
||||
return false;
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
//FIXME: Actually enable it when it makes sense
|
||||
return true;
|
||||
if( peerStatus == ACLSystem::NotFound )
|
||||
@@ -814,11 +815,11 @@ Servent::isIPWhitelisted( QHostAddress ip )
|
||||
static QList<range> whitelist;
|
||||
if( whitelist.isEmpty() )
|
||||
{
|
||||
whitelist << range( QHostAddress( "10.0.0.0" ), 8 )
|
||||
<< range( QHostAddress( "172.16.0.0" ), 12 )
|
||||
<< range( QHostAddress( "192.168.0.0" ), 16 )
|
||||
<< range( QHostAddress( "169.254.0.0" ), 16 )
|
||||
<< range( QHostAddress( "127.0.0.0" ), 24 );
|
||||
whitelist << range( QHostAddress( "10.0.0.0" ), 8 )
|
||||
<< range( QHostAddress( "172.16.0.0" ), 12 )
|
||||
<< range( QHostAddress( "192.168.0.0" ), 16 )
|
||||
<< range( QHostAddress( "169.254.0.0" ), 16 )
|
||||
<< range( QHostAddress( "127.0.0.0" ), 24 );
|
||||
|
||||
// tDebug( LOGVERBOSE ) << "Loaded whitelist IP range:" << whitelist;
|
||||
}
|
||||
|
@@ -22,15 +22,15 @@
|
||||
// time before new connection terminates if no auth received
|
||||
#define AUTH_TIMEOUT 180000
|
||||
|
||||
#include <QObject>
|
||||
#include <QTcpServer>
|
||||
#include <QHostInfo>
|
||||
#include <QMap>
|
||||
#include <QMutex>
|
||||
#include <QSharedPointer>
|
||||
#include <QTcpSocket>
|
||||
#include <QTimer>
|
||||
#include <QPointer>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtNetwork/QTcpServer>
|
||||
#include <QtNetwork/QTcpSocket>
|
||||
#include <QtNetwork/QHostInfo>
|
||||
|
||||
#include <qjson/parser.h>
|
||||
#include <qjson/serializer.h>
|
||||
|
@@ -118,7 +118,6 @@ Tomahawk::ExternalResolver*
|
||||
Pipeline::addScriptResolver( const QString& path, bool start )
|
||||
{
|
||||
ExternalResolver* res = 0;
|
||||
#ifndef ENABLE_HEADLESS
|
||||
const QFileInfo fi( path );
|
||||
|
||||
if ( fi.suffix() == "js" || fi.suffix() == "script" )
|
||||
@@ -129,7 +128,6 @@ Pipeline::addScriptResolver( const QString& path, bool start )
|
||||
m_scriptResolvers << res;
|
||||
if ( start )
|
||||
res->start();
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@@ -293,7 +293,8 @@ Playlist::loadRevision( const QString& rev )
|
||||
void
|
||||
Playlist::createNewRevision( const QString& newrev, const QString& oldrev, const QList< plentry_ptr >& entries )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << newrev << oldrev << entries.count();
|
||||
tDebug() << Q_FUNC_INFO << newrev << oldrev << entries.count();
|
||||
Q_ASSERT( m_source->isLocal() || newrev == oldrev );
|
||||
|
||||
if ( busy() )
|
||||
{
|
||||
@@ -387,34 +388,32 @@ Playlist::setNewRevision( const QString& rev,
|
||||
bool is_newest_rev,
|
||||
const QMap< QString, Tomahawk::plentry_ptr >& addedmap )
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << rev << is_newest_rev << m_title << addedmap.count() << neworderedguids.count() << oldorderedguids.count();
|
||||
|
||||
// build up correctly ordered new list of plentry_ptrs from
|
||||
// existing ones, and the ones that have been added
|
||||
QMap<QString, plentry_ptr> entriesmap;
|
||||
foreach( const plentry_ptr& p, m_entries )
|
||||
foreach ( const plentry_ptr& p, m_entries )
|
||||
entriesmap.insert( p->guid(), p );
|
||||
|
||||
QList<plentry_ptr> entries;
|
||||
foreach( const QString& id, neworderedguids )
|
||||
foreach ( const QString& id, neworderedguids )
|
||||
{
|
||||
if( entriesmap.contains( id ) )
|
||||
if ( entriesmap.contains( id ) )
|
||||
{
|
||||
entries.append( entriesmap.value( id ) );
|
||||
}
|
||||
else if( addedmap.contains( id ) )
|
||||
else if ( addedmap.contains( id ) )
|
||||
{
|
||||
entries.append( addedmap.value( id ) );
|
||||
if( is_newest_rev )
|
||||
if ( is_newest_rev )
|
||||
m_entries.append( addedmap.value( id ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* qDebug() << "id:" << id;
|
||||
* qDebug() << "newordered:" << neworderedguids.count() << neworderedguids;
|
||||
* qDebug() << "entriesmap:" << entriesmap.count() << entriesmap;
|
||||
* qDebug() << "addedmap:" << addedmap.count() << addedmap;
|
||||
* qDebug() << "m_entries" << m_entries; */
|
||||
tDebug() << "id:" << id;
|
||||
tDebug() << "newordered:" << neworderedguids.count() << neworderedguids;
|
||||
tDebug() << "entriesmap:" << entriesmap.count() << entriesmap;
|
||||
tDebug() << "addedmap:" << addedmap.count() << addedmap;
|
||||
tDebug() << "m_entries" << m_entries;
|
||||
|
||||
tLog() << "Playlist error for playlist with guid" << guid() << "from source" << author()->friendlyName();
|
||||
Q_ASSERT( false ); // XXX
|
||||
@@ -428,19 +427,19 @@ Playlist::setNewRevision( const QString& rev,
|
||||
// entries that have been removed:
|
||||
QSet<QString> removedguids = oldorderedguids.toSet().subtract( neworderedguids.toSet() );
|
||||
//qDebug() << "Removedguids:" << removedguids << "oldorederedguids" << oldorderedguids << "newog" << neworderedguids;
|
||||
foreach( QString remid, removedguids )
|
||||
foreach ( QString remid, removedguids )
|
||||
{
|
||||
// NB: entriesmap will contain old/removed entries only if the removal was done
|
||||
// in the same session - after a restart, history is not in memory.
|
||||
if( entriesmap.contains( remid ) )
|
||||
if ( entriesmap.contains( remid ) )
|
||||
{
|
||||
pr.removed << entriesmap.value( remid );
|
||||
if( is_newest_rev )
|
||||
if ( is_newest_rev )
|
||||
{
|
||||
//qDebug() << "Removing from m_entries" << remid;
|
||||
for( int k = 0 ; k < m_entries.length(); ++k )
|
||||
for ( int k = 0 ; k < m_entries.length(); ++k )
|
||||
{
|
||||
if( m_entries.at( k )->guid() == remid )
|
||||
if ( m_entries.at( k )->guid() == remid )
|
||||
{
|
||||
//qDebug() << "removed at" << k;
|
||||
m_entries.removeAt( k );
|
||||
@@ -452,8 +451,8 @@ Playlist::setNewRevision( const QString& rev,
|
||||
}
|
||||
|
||||
pr.added = addedmap.values();
|
||||
|
||||
pr.newlist = entries;
|
||||
|
||||
return pr;
|
||||
}
|
||||
|
||||
|
@@ -159,13 +159,19 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
r.setTop( r.bottom() - painter->fontMetrics().height() );
|
||||
r.adjust( 4, 0, -4, -1 );
|
||||
if ( m_hoveringOver == index )
|
||||
{
|
||||
TomahawkUtils::drawQueryBackground( painter, opt.palette, r, 1.5 );
|
||||
|
||||
painter->setPen( opt.palette.color( QPalette::HighlightedText ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef Q_WS_MAC
|
||||
painter->setPen( opt.palette.color( QPalette::Dark ).darker( 200 ) );
|
||||
painter->setPen( opt.palette.color( QPalette::Dark ).darker( 200 ) );
|
||||
#else
|
||||
painter->setPen( opt.palette.color( QPalette::Dark ) );
|
||||
painter->setPen( opt.palette.color( QPalette::Dark ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
to.setAlignment( Qt::AlignHCenter | Qt::AlignBottom );
|
||||
text = painter->fontMetrics().elidedText( item->album()->artist()->name(), Qt::ElideRight, textRect.width() - 3 );
|
||||
painter->drawText( textRect, text, to );
|
||||
@@ -177,9 +183,11 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AlbumItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index )
|
||||
{
|
||||
Q_UNUSED( model );
|
||||
Q_UNUSED( option );
|
||||
|
||||
if ( event->type() != QEvent::MouseButtonRelease &&
|
||||
@@ -217,7 +225,8 @@ AlbumItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const
|
||||
|
||||
event->accept();
|
||||
return true;
|
||||
} else if ( event->type() == QEvent::MouseButtonPress )
|
||||
}
|
||||
else if ( event->type() == QEvent::MouseButtonPress )
|
||||
{
|
||||
// Stop the whole album from having a down click action as we just want the artist name to be clicked
|
||||
event->accept();
|
||||
@@ -231,6 +240,7 @@ AlbumItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlbumItemDelegate::whitespaceMouseEvent()
|
||||
{
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "artist.h"
|
||||
#include "albumitem.h"
|
||||
#include "source.h"
|
||||
#include "sourcelist.h"
|
||||
#include "database/database.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
@@ -247,6 +248,7 @@ AlbumModel::addCollection( const collection_ptr& collection, bool overwrite )
|
||||
|
||||
DatabaseCommand_AllAlbums* cmd = new DatabaseCommand_AllAlbums( collection );
|
||||
m_overwriteOnAdd = overwrite;
|
||||
m_collection = collection;
|
||||
|
||||
connect( cmd, SIGNAL( albums( QList<Tomahawk::album_ptr>, QVariant ) ),
|
||||
SLOT( addAlbums( QList<Tomahawk::album_ptr> ) ) );
|
||||
@@ -255,6 +257,21 @@ AlbumModel::addCollection( const collection_ptr& collection, bool overwrite )
|
||||
|
||||
m_title = tr( "All albums from %1" ).arg( collection->source()->friendlyName() );
|
||||
|
||||
if ( collection.isNull() )
|
||||
{
|
||||
connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
|
||||
|
||||
QList<Tomahawk::source_ptr> sources = SourceList::instance()->sources();
|
||||
foreach ( const source_ptr& source, sources )
|
||||
{
|
||||
connect( source->collection().data(), SIGNAL( changed() ), SLOT( onCollectionChanged() ), Qt::UniqueConnection );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
connect( collection.data(), SIGNAL( changed() ), SLOT( onCollectionChanged() ), Qt::UniqueConnection );
|
||||
}
|
||||
|
||||
emit loadingStarted();
|
||||
}
|
||||
|
||||
@@ -290,14 +307,14 @@ AlbumModel::addFilteredCollection( const collection_ptr& collection, unsigned in
|
||||
void
|
||||
AlbumModel::addAlbums( const QList<Tomahawk::album_ptr>& albums )
|
||||
{
|
||||
emit loadingFinished();
|
||||
|
||||
if ( !albums.count() )
|
||||
return;
|
||||
|
||||
if ( m_overwriteOnAdd )
|
||||
clear();
|
||||
|
||||
emit loadingFinished();
|
||||
|
||||
int c = rowCount( QModelIndex() );
|
||||
QPair< int, int > crows;
|
||||
crows.first = c;
|
||||
@@ -318,6 +335,23 @@ AlbumModel::addAlbums( const QList<Tomahawk::album_ptr>& albums )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlbumModel::onSourceAdded( const Tomahawk::source_ptr& source )
|
||||
{
|
||||
connect( source->collection().data(), SIGNAL( changed() ), SLOT( onCollectionChanged() ), Qt::UniqueConnection );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlbumModel::onCollectionChanged()
|
||||
{
|
||||
if ( m_collection )
|
||||
addCollection( m_collection, true );
|
||||
else
|
||||
addCollection( m_collection, true );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlbumModel::clear()
|
||||
{
|
||||
|
@@ -96,9 +96,13 @@ signals:
|
||||
|
||||
void loadingStarted();
|
||||
void loadingFinished();
|
||||
|
||||
private slots:
|
||||
void onDataChanged();
|
||||
|
||||
void onSourceAdded( const Tomahawk::source_ptr& source );
|
||||
void onCollectionChanged();
|
||||
|
||||
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void infoSystemFinished( QString target );
|
||||
|
||||
@@ -110,6 +114,8 @@ private:
|
||||
QString m_description;
|
||||
bool m_overwriteOnAdd;
|
||||
|
||||
Tomahawk::collection_ptr m_collection;
|
||||
|
||||
QHash<qlonglong, QPersistentModelIndex> m_coverHash;
|
||||
};
|
||||
|
||||
|
@@ -369,6 +369,9 @@ ArtistView::onMenuTriggered( int action )
|
||||
bool
|
||||
ArtistView::jumpToCurrentTrack()
|
||||
{
|
||||
if ( !m_proxyModel )
|
||||
return false;
|
||||
|
||||
scrollTo( m_proxyModel->currentIndex(), QAbstractItemView::PositionAtCenter );
|
||||
return true;
|
||||
}
|
||||
|
@@ -18,9 +18,6 @@
|
||||
|
||||
#include "collectionflatmodel.h"
|
||||
|
||||
#include <QMimeData>
|
||||
#include <QTreeView>
|
||||
|
||||
#include "database/database.h"
|
||||
#include "sourcelist.h"
|
||||
#include "utils/logger.h"
|
||||
@@ -31,9 +28,6 @@ using namespace Tomahawk;
|
||||
CollectionFlatModel::CollectionFlatModel( QObject* parent )
|
||||
: TrackModel( parent )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
connect( SourceList::instance(), SIGNAL( sourceRemoved( Tomahawk::source_ptr ) ), SLOT( onSourceOffline( Tomahawk::source_ptr ) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +39,6 @@ CollectionFlatModel::~CollectionFlatModel()
|
||||
void
|
||||
CollectionFlatModel::addCollections( const QList< collection_ptr >& collections )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Adding collections!";
|
||||
foreach( const collection_ptr& col, collections )
|
||||
{
|
||||
addCollection( col );
|
||||
@@ -64,12 +57,7 @@ CollectionFlatModel::addCollection( const collection_ptr& collection, bool sendN
|
||||
<< collection->source()->id()
|
||||
<< collection->source()->userName();
|
||||
|
||||
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> ) ) );
|
||||
|
||||
if( sendNotifications )
|
||||
if ( sendNotifications )
|
||||
emit loadingStarted();
|
||||
|
||||
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( collection );
|
||||
@@ -107,143 +95,32 @@ CollectionFlatModel::addFilteredCollection( const collection_ptr& collection, un
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionFlatModel::removeCollection( const collection_ptr& collection )
|
||||
{
|
||||
return; // FIXME
|
||||
|
||||
disconnect( collection.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
|
||||
this, SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
|
||||
|
||||
QTime timer;
|
||||
timer.start();
|
||||
|
||||
// QList<TrackModelItem*> plitems = m_collectionIndex.values( collection );
|
||||
QList< QPair< int, int > > rows;
|
||||
QList< QPair< int, int > > sortrows;
|
||||
QPair< int, int > row;
|
||||
QPair< int, int > rowf;
|
||||
rows = m_collectionRows.values( collection );
|
||||
|
||||
while ( rows.count() )
|
||||
{
|
||||
int x = -1;
|
||||
int j = 0;
|
||||
foreach( row, rows )
|
||||
{
|
||||
if ( x < 0 || row.first > rows.at( x ).first )
|
||||
x = j;
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
sortrows.append( rows.at( x ) );
|
||||
rows.removeAt( x );
|
||||
}
|
||||
|
||||
foreach( row, sortrows )
|
||||
{
|
||||
QMap< Tomahawk::collection_ptr, QPair< int, int > > newrows;
|
||||
foreach ( const collection_ptr& col, m_collectionRows.uniqueKeys() )
|
||||
{
|
||||
if ( col.data() == collection.data() )
|
||||
continue;
|
||||
|
||||
foreach ( rowf, m_collectionRows.values( col ) )
|
||||
{
|
||||
if ( rowf.first > row.first )
|
||||
{
|
||||
rowf.first -= ( row.second - row.first ) + 1;
|
||||
rowf.second -= ( row.second - row.first ) + 1;
|
||||
}
|
||||
newrows.insertMulti( col, rowf );
|
||||
}
|
||||
}
|
||||
m_collectionRows = newrows;
|
||||
|
||||
qDebug() << "Removing rows:" << row.first << row.second;
|
||||
emit beginRemoveRows( QModelIndex(), row.first, row.second );
|
||||
for ( int i = row.second; i >= row.first; i-- )
|
||||
{
|
||||
TrackModelItem* item = itemFromIndex( index( i, 0, QModelIndex() ) );
|
||||
delete item;
|
||||
}
|
||||
emit endRemoveRows();
|
||||
}
|
||||
|
||||
qDebug() << "Collection removed, time elapsed:" << timer.elapsed();
|
||||
|
||||
// emit trackCountChanged( rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionFlatModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << tracks.count() << rowCount( QModelIndex() );
|
||||
|
||||
if( !m_loadingCollections.isEmpty() && sender() && qobject_cast< Collection* >( sender() ) )
|
||||
if ( !m_loadingCollections.isEmpty() && sender() && qobject_cast< Collection* >( sender() ) )
|
||||
{
|
||||
// we are keeping track and are called as a slot
|
||||
m_loadingCollections.removeAll( qobject_cast< Collection* >( sender() ) );
|
||||
}
|
||||
|
||||
bool kickOff = m_tracksToAdd.isEmpty();
|
||||
m_tracksToAdd << tracks;
|
||||
append( tracks );
|
||||
|
||||
emit trackCountChanged( trackCount() );
|
||||
|
||||
if ( m_tracksToAdd.count() && kickOff )
|
||||
processTracksToAdd();
|
||||
else if ( m_tracksToAdd.isEmpty() && m_loadingCollections.isEmpty() )
|
||||
if ( m_loadingCollections.isEmpty() )
|
||||
emit loadingFinished();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionFlatModel::processTracksToAdd()
|
||||
{
|
||||
int chunkSize = 5000;
|
||||
int maxc = qMin( chunkSize, m_tracksToAdd.count() );
|
||||
int c = rowCount( QModelIndex() );
|
||||
|
||||
emit beginInsertRows( QModelIndex(), c, c + maxc - 1 );
|
||||
//beginResetModel();
|
||||
|
||||
TrackModelItem* plitem;
|
||||
QList< Tomahawk::query_ptr >::iterator iter = m_tracksToAdd.begin();
|
||||
|
||||
for( int i = 0; i < maxc; ++i )
|
||||
{
|
||||
plitem = new TrackModelItem( *iter, m_rootItem );
|
||||
plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem );
|
||||
|
||||
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
m_tracksToAdd.erase( m_tracksToAdd.begin(), iter );
|
||||
|
||||
if ( m_tracksToAdd.isEmpty() && m_loadingCollections.isEmpty() )
|
||||
emit loadingFinished();
|
||||
|
||||
//endResetModel();
|
||||
emit endInsertRows();
|
||||
qDebug() << Q_FUNC_INFO << rowCount( QModelIndex() );
|
||||
|
||||
if ( m_tracksToAdd.count() )
|
||||
QTimer::singleShot( 250, this, SLOT( processTracksToAdd() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionFlatModel::onTracksRemoved( const QList<Tomahawk::query_ptr>& tracks )
|
||||
{
|
||||
QList<Tomahawk::query_ptr> t = tracks;
|
||||
for ( int i = rowCount( QModelIndex() ); i >= 0 && t.count(); i-- )
|
||||
{
|
||||
TrackModelItem* item = itemFromIndex( index( i, 0, QModelIndex() ) );
|
||||
QModelIndex idx = index( i, 0, QModelIndex() );
|
||||
TrackModelItem* item = itemFromIndex( idx );
|
||||
if ( !item )
|
||||
continue;
|
||||
|
||||
@@ -252,11 +129,7 @@ CollectionFlatModel::onTracksRemoved( const QList<Tomahawk::query_ptr>& tracks )
|
||||
{
|
||||
if ( item->query().data() == query.data() )
|
||||
{
|
||||
qDebug() << "Removing row:" << i << query->toString();
|
||||
emit beginRemoveRows( QModelIndex(), i, i );
|
||||
delete item;
|
||||
emit endRemoveRows();
|
||||
|
||||
remove( idx );
|
||||
t.removeAt( j );
|
||||
break;
|
||||
}
|
||||
@@ -264,9 +137,6 @@ CollectionFlatModel::onTracksRemoved( const QList<Tomahawk::query_ptr>& tracks )
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
// emit trackCountChanged( rowCount( QModelIndex() ) );
|
||||
qDebug() << Q_FUNC_INFO << rowCount( QModelIndex() );
|
||||
}
|
||||
|
||||
|
||||
@@ -274,20 +144,7 @@ void
|
||||
CollectionFlatModel::onDataChanged()
|
||||
{
|
||||
TrackModelItem* p = (TrackModelItem*)sender();
|
||||
// emit itemSizeChanged( p->index );
|
||||
|
||||
if ( p )
|
||||
emit dataChanged( p->index, p->index.sibling( p->index.row(), columnCount( QModelIndex() ) - 1 ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionFlatModel::onSourceOffline( const Tomahawk::source_ptr& src )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( m_collectionRows.contains( src->collection() ) )
|
||||
{
|
||||
removeCollection( src->collection() );
|
||||
}
|
||||
}
|
||||
|
@@ -46,16 +46,9 @@ public:
|
||||
virtual int trackCount() const { return rowCount( QModelIndex() ) + m_tracksToAdd.count(); }
|
||||
|
||||
void addCollections( const QList< Tomahawk::collection_ptr >& collections );
|
||||
|
||||
void addCollection( const Tomahawk::collection_ptr& collection, bool sendNotifications = true );
|
||||
void removeCollection( const Tomahawk::collection_ptr& collection );
|
||||
|
||||
void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllTracks::SortOrder order );
|
||||
|
||||
virtual void append( const Tomahawk::query_ptr& /*query*/ ) {}
|
||||
virtual void append( const Tomahawk::artist_ptr& /*artist*/ ) {}
|
||||
virtual void append( const Tomahawk::album_ptr& /*album*/ ) {}
|
||||
|
||||
signals:
|
||||
void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode );
|
||||
void shuffleModeChanged( bool enabled );
|
||||
@@ -70,10 +63,6 @@ private slots:
|
||||
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
|
||||
void onTracksRemoved( const QList<Tomahawk::query_ptr>& tracks );
|
||||
|
||||
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;
|
||||
|
@@ -313,9 +313,9 @@ DynamicModel::removeIndex(const QModelIndex& idx, bool moreToCome)
|
||||
if( !moreToCome && idx == index( rowCount( QModelIndex() ) - 1, 0, QModelIndex() ) ) { // if the user is manually removing the last one, re-add as we're a station
|
||||
newTrackLoading();
|
||||
}
|
||||
TrackModel::removeIndex( idx );
|
||||
TrackModel::remove( idx );
|
||||
} else
|
||||
PlaylistModel::removeIndex( idx, moreToCome );
|
||||
PlaylistModel::remove( idx, moreToCome );
|
||||
// don't call onPlaylistChanged.
|
||||
|
||||
if( !moreToCome )
|
||||
|
@@ -172,7 +172,7 @@ DynamicPlaylist::createNewRevision( const QString& newUuid )
|
||||
}
|
||||
else if( mode() == OnDemand )
|
||||
{
|
||||
createNewRevision( newUuid.isEmpty() ? uuid() : newUuid, currentrevision(), type(), generator()->controls());
|
||||
createNewRevision( newUuid.isEmpty() ? uuid() : newUuid, currentrevision(), type(), generator()->controls() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,6 +185,8 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
|
||||
const QList< dyncontrol_ptr>& controls,
|
||||
const QList< plentry_ptr >& entries )
|
||||
{
|
||||
Q_ASSERT( m_source->isLocal() || newrev == oldrev );
|
||||
|
||||
if ( busy() )
|
||||
{
|
||||
m_revisionQueue.enqueue( DynQueueItem( newrev, oldrev, type, controls, (int)Static, entries, oldrev == currentrevision() ) );
|
||||
@@ -230,6 +232,8 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
|
||||
const QString& type,
|
||||
const QList< dyncontrol_ptr>& controls )
|
||||
{
|
||||
Q_ASSERT( m_source->isLocal() || newrev == oldrev );
|
||||
|
||||
if ( busy() )
|
||||
{
|
||||
m_revisionQueue.enqueue( DynQueueItem( newrev, oldrev, type, controls, (int)OnDemand, QList< plentry_ptr >(), oldrev == currentrevision() ) );
|
||||
@@ -533,8 +537,15 @@ DynamicPlaylist::checkRevisionQueue()
|
||||
if ( item.oldRev != currentrevision() && item.applyToTip )
|
||||
{
|
||||
// this was applied to the then-latest, but the already-running operation changed it so it's out of date now. fix it
|
||||
if ( item.oldRev == item.newRev )
|
||||
{
|
||||
checkRevisionQueue();
|
||||
return;
|
||||
}
|
||||
|
||||
item.oldRev = currentrevision();
|
||||
}
|
||||
|
||||
if( item.mode == Static )
|
||||
createNewRevision( item.newRev, item.oldRev, item.type, item.controls, item.entries );
|
||||
else
|
||||
|
@@ -264,7 +264,7 @@ DynamicView::collapseEntries( int startRow, int num, int numToKeep )
|
||||
todel << proxyModel()->index( startRow + i, k );
|
||||
}
|
||||
}
|
||||
proxyModel()->removeIndexes( todel );
|
||||
proxyModel()->remove( todel );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -102,6 +102,10 @@ public:
|
||||
* If this generator doesn't support this (and returns false for
|
||||
* \c onDemandSteerable) this will be null. The generator is responsible
|
||||
* for reacting to changes in the widget.
|
||||
*
|
||||
* Steering widgets may emit a \c steeringChanged() signal, which will cause the model to toss any
|
||||
* upcoming tracks and re-fetch them.
|
||||
*
|
||||
*/
|
||||
virtual QWidget* steeringWidget() { return 0; }
|
||||
|
||||
|
@@ -389,9 +389,6 @@ EchonestGenerator::dynamicFetched()
|
||||
|
||||
resetSteering();
|
||||
|
||||
if( !m_steerer.isNull() )
|
||||
m_steerer.data()->resetSteering( true );
|
||||
|
||||
try
|
||||
{
|
||||
Echonest::Song song = m_dynPlaylist->parseNextSong( reply );
|
||||
|
@@ -60,10 +60,10 @@ EchonestSteerer::EchonestSteerer( QWidget* parent )
|
||||
f.setBold( true );
|
||||
m_steerTop->setFont( f );
|
||||
m_textL->addWidget( m_steerTop );
|
||||
m_steerBottom = new QLabel( tr( "Takes effect on track change" ), this );
|
||||
f.setPointSize( f.pointSize() - 3 );
|
||||
m_steerBottom->setFont( f );
|
||||
m_textL->addWidget( m_steerBottom );
|
||||
// m_steerBottom = new QLabel( tr( "Takes effect on track change" ), this );
|
||||
// f.setPointSize( f.pointSize() - 3 );
|
||||
// m_steerBottom->setFont( f );
|
||||
// m_textL->addWidget( m_steerBottom );
|
||||
|
||||
m_layout->addLayout( m_textL, 1 );
|
||||
|
||||
@@ -97,6 +97,12 @@ EchonestSteerer::EchonestSteerer( QWidget* parent )
|
||||
|
||||
connect( m_description, SIGNAL( textChanged( QString ) ), this, SLOT( changed() ) );
|
||||
|
||||
m_apply = initButton( this );
|
||||
m_apply->setIcon( QIcon( RESPATH "images/apply-check.png" ) );
|
||||
m_apply->setToolTip( tr( "Apply steering command" ) );
|
||||
m_layout->addWidget( m_apply );
|
||||
connect( m_apply, SIGNAL( clicked( bool ) ), this, SLOT( applySteering() ) );
|
||||
|
||||
m_reset = initButton( this );
|
||||
m_reset->setIcon( QIcon( RESPATH "images/view-refresh.png" ) );
|
||||
m_reset->setToolTip( tr( "Reset all steering commands" ) );
|
||||
@@ -165,19 +171,7 @@ EchonestSteerer::fadeOut()
|
||||
void
|
||||
EchonestSteerer::changed()
|
||||
{
|
||||
bool keep = false;
|
||||
if( m_amplifier->itemData( m_amplifier->currentIndex() ).toString().isEmpty() ) { // Keep Current
|
||||
keep = true;
|
||||
|
||||
emit reset();
|
||||
}
|
||||
|
||||
if( m_field->itemData( m_field->currentIndex() ).toString() != "desc" ) {
|
||||
if( !keep ) {
|
||||
QString steer = m_field->itemData( m_field->currentIndex() ).toString() + m_amplifier->itemData( m_amplifier->currentIndex() ).toString();
|
||||
emit steerField( steer );
|
||||
}
|
||||
|
||||
// if description was shown, animate to shrink
|
||||
if( m_layout->indexOf( m_description ) > 0 ) {
|
||||
m_expanding = false;
|
||||
@@ -190,15 +184,8 @@ EchonestSteerer::changed()
|
||||
|
||||
m_resizeAnim.setFrameRange( start, end );
|
||||
m_resizeAnim.start();
|
||||
|
||||
qDebug() << "COLLAPSING FROM" << start << "TO" << end;
|
||||
}
|
||||
} else { // description, so put in the description field
|
||||
if( !m_description->text().isEmpty() && !keep ) {
|
||||
QString steer = m_description->text() + m_amplifier->itemData( m_amplifier->currentIndex() ).toString();
|
||||
emit steerDescription( steer );
|
||||
}
|
||||
|
||||
if( m_layout->indexOf( m_description ) == -1 ) {
|
||||
// animate to expand
|
||||
m_layout->insertWidget( m_layout->count() - 1, m_description, 1 );
|
||||
@@ -210,12 +197,32 @@ EchonestSteerer::changed()
|
||||
int end = start + m_layout->spacing() + m_description->sizeHint().width();
|
||||
m_resizeAnim.setFrameRange( start, end );
|
||||
m_resizeAnim.start();
|
||||
|
||||
qDebug() << "EXPANDING FROM" << start << "TO" << end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EchonestSteerer::applySteering()
|
||||
{
|
||||
if ( m_field->itemData( m_field->currentIndex() ).toString() != "desc" )
|
||||
{
|
||||
QString steer = m_field->itemData( m_field->currentIndex() ).toString() + m_amplifier->itemData( m_amplifier->currentIndex() ).toString();
|
||||
emit steerField( steer );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !m_description->text().isEmpty() )
|
||||
{
|
||||
QString steer = m_description->text() + m_amplifier->itemData( m_amplifier->currentIndex() ).toString();
|
||||
emit steerDescription( steer );
|
||||
}
|
||||
}
|
||||
|
||||
emit steeringChanged();
|
||||
|
||||
resetSteering( true );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EchonestSteerer::resizeFrame( int width )
|
||||
|
@@ -44,6 +44,7 @@ public:
|
||||
virtual void paintEvent(QPaintEvent* );
|
||||
|
||||
public slots:
|
||||
void applySteering();
|
||||
void resetSteering( bool automatic = false );
|
||||
|
||||
void fadeIn();
|
||||
@@ -56,6 +57,9 @@ signals:
|
||||
void reset();
|
||||
|
||||
void resized();
|
||||
|
||||
// interface to DynamicWidget
|
||||
void steeringChanged();
|
||||
private slots:
|
||||
void changed();
|
||||
|
||||
@@ -77,6 +81,7 @@ private:
|
||||
QLabel* m_steerBottom;
|
||||
|
||||
// icons on the right
|
||||
QToolButton* m_apply;
|
||||
QToolButton* m_reset;
|
||||
|
||||
// animations
|
||||
|
@@ -324,6 +324,8 @@ DynamicWidget::startStation()
|
||||
m_steering = m_playlist->generator()->steeringWidget();
|
||||
Q_ASSERT( m_steering );
|
||||
|
||||
connect( m_steering, SIGNAL( steeringChanged() ), this, SLOT( steeringChanged() ) );
|
||||
|
||||
int x = ( width() / 2 ) - ( m_steering->size().width() / 2 );
|
||||
int y = height() - m_steering->size().height() - 40; // padding
|
||||
|
||||
@@ -394,6 +396,25 @@ DynamicWidget::controlChanged( const Tomahawk::dyncontrol_ptr& control )
|
||||
emit descriptionChanged( m_playlist->generator()->sentenceSummary() );
|
||||
}
|
||||
|
||||
void
|
||||
DynamicWidget::steeringChanged()
|
||||
{
|
||||
// When steering changes, toss all the tracks that are upcoming, and re-fetch.
|
||||
QModelIndex cur = m_view->currentIndex();
|
||||
const int upcoming = m_view->proxyModel()->rowCount( QModelIndex() ) - 1 - cur.row();
|
||||
tDebug() << "Removing tracks after current in station, found" << upcoming;
|
||||
|
||||
QModelIndexList toRemove;
|
||||
for ( int i = cur.row() + 1; i < m_view->proxyModel()->rowCount( QModelIndex() ); i++ )
|
||||
{
|
||||
toRemove << m_view->proxyModel()->index( i, 0, QModelIndex() );
|
||||
}
|
||||
|
||||
m_view->proxyModel()->remove( toRemove );
|
||||
|
||||
m_playlist->generator()->fetchNext();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DynamicWidget::showPreview()
|
||||
|
@@ -103,6 +103,7 @@ private slots:
|
||||
|
||||
void controlsChanged( bool added );
|
||||
void controlChanged( const Tomahawk::dyncontrol_ptr& control );
|
||||
void steeringChanged();
|
||||
void showPreview();
|
||||
|
||||
void layoutFloatingWidgets();
|
||||
|
@@ -185,9 +185,9 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem&
|
||||
QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->query()->playedBy().second ), true );
|
||||
|
||||
if ( source == SourceList::instance()->getLocal() )
|
||||
lowerText = QString( "played %1 by you" ).arg( playtime );
|
||||
lowerText = QString( tr( "played %1 by you" ) ).arg( playtime );
|
||||
else
|
||||
lowerText = QString( "played %1 by %2" ).arg( playtime ).arg( source->friendlyName() );
|
||||
lowerText = QString( tr( "played %1 by %2" ) ).arg( playtime ).arg( source->friendlyName() );
|
||||
|
||||
if ( useAvatars )
|
||||
pixmap = source->avatar( Source::FancyStyle );
|
||||
|
@@ -39,9 +39,8 @@ using namespace Tomahawk;
|
||||
PlaylistModel::PlaylistModel( QObject* parent )
|
||||
: TrackModel( parent )
|
||||
, m_isTemporary( false )
|
||||
, m_changesOngoing( false )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
m_dropStorage.parent = QPersistentModelIndex();
|
||||
m_dropStorage.row = -10;
|
||||
|
||||
@@ -54,34 +53,9 @@ PlaylistModel::~PlaylistModel()
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PlaylistModel::columnCount( const QModelIndex& parent ) const
|
||||
{
|
||||
return TrackModel::columnCount( parent );
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
PlaylistModel::data( const QModelIndex& index, int role ) const
|
||||
{
|
||||
return TrackModel::data( index, role );
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
PlaylistModel::headerData( int section, Qt::Orientation orientation, int role ) const
|
||||
{
|
||||
return TrackModel::headerData( section, orientation, role );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries )
|
||||
{
|
||||
QString currentuuid;
|
||||
if ( currentItem().isValid() )
|
||||
currentuuid = itemFromIndex( currentItem() )->query()->id();
|
||||
|
||||
if ( !m_playlist.isNull() )
|
||||
{
|
||||
disconnect( m_playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) );
|
||||
@@ -89,10 +63,8 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn
|
||||
disconnect( m_playlist.data(), SIGNAL( changed() ), this, SIGNAL( playlistChanged() ) );
|
||||
}
|
||||
|
||||
if ( rowCount( QModelIndex() ) && loadEntries )
|
||||
{
|
||||
if ( loadEntries )
|
||||
clear();
|
||||
}
|
||||
|
||||
m_playlist = playlist;
|
||||
connect( playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) );
|
||||
@@ -109,45 +81,8 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn
|
||||
if ( !loadEntries )
|
||||
return;
|
||||
|
||||
TrackModelItem* plitem;
|
||||
QList<plentry_ptr> entries = playlist->entries();
|
||||
if ( entries.count() )
|
||||
{
|
||||
int c = rowCount( QModelIndex() );
|
||||
|
||||
qDebug() << "Starting loading" << playlist->title();
|
||||
emit beginInsertRows( QModelIndex(), c, c + entries.count() - 1 );
|
||||
|
||||
m_waitingForResolved.clear();
|
||||
foreach( const plentry_ptr& entry, entries )
|
||||
{
|
||||
// qDebug() << entry->query()->toString();
|
||||
plitem = new TrackModelItem( entry, m_rootItem );
|
||||
plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem );
|
||||
|
||||
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
|
||||
|
||||
if ( entry->query()->id() == currentuuid )
|
||||
setCurrentItem( plitem->index );
|
||||
|
||||
if ( !entry->query()->resolvingFinished() && !entry->query()->playable() )
|
||||
{
|
||||
m_waitingForResolved.append( entry->query().data() );
|
||||
connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), SLOT( trackResolved( bool ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
emit endInsertRows();
|
||||
}
|
||||
else
|
||||
qDebug() << "Playlist seems empty:" << playlist->title();
|
||||
|
||||
if ( !m_waitingForResolved.isEmpty() )
|
||||
{
|
||||
emit loadingStarted();
|
||||
}
|
||||
|
||||
emit trackCountChanged( rowCount( QModelIndex() ) );
|
||||
append( entries );
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +100,7 @@ PlaylistModel::loadHistory( const Tomahawk::source_ptr& source, unsigned int amo
|
||||
cmd->setLimit( amount );
|
||||
|
||||
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ),
|
||||
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ), Qt::QueuedConnection );
|
||||
SLOT( append( QList<Tomahawk::query_ptr> ) ), Qt::QueuedConnection );
|
||||
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
||||
}
|
||||
@@ -174,22 +109,23 @@ PlaylistModel::loadHistory( const Tomahawk::source_ptr& source, unsigned int amo
|
||||
void
|
||||
PlaylistModel::clear()
|
||||
{
|
||||
if ( rowCount( QModelIndex() ) )
|
||||
{
|
||||
emit loadingFinished();
|
||||
TrackModel::clear();
|
||||
|
||||
emit beginResetModel();
|
||||
delete m_rootItem;
|
||||
m_rootItem = 0;
|
||||
m_rootItem = new TrackModelItem( 0, this );
|
||||
emit endResetModel();
|
||||
}
|
||||
m_waitingForResolved.clear();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::append( const QList< plentry_ptr >& entries )
|
||||
{
|
||||
insert( entries, rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::append( const QList< query_ptr >& queries )
|
||||
{
|
||||
onTracksAdded( queries );
|
||||
insert( queries, rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -199,13 +135,10 @@ PlaylistModel::append( const Tomahawk::query_ptr& query )
|
||||
if ( query.isNull() )
|
||||
return;
|
||||
|
||||
QList< Tomahawk::query_ptr > ql;
|
||||
ql << query;
|
||||
|
||||
if ( !query->resolvingFinished() )
|
||||
Pipeline::instance()->resolve( query );
|
||||
|
||||
onTracksAdded( ql );
|
||||
TrackModel::append( query );
|
||||
}
|
||||
|
||||
|
||||
@@ -225,7 +158,7 @@ PlaylistModel::append( const Tomahawk::album_ptr& album )
|
||||
m_isTemporary = true;
|
||||
}
|
||||
|
||||
onTracksAdded( album->tracks() );
|
||||
append( album->tracks() );
|
||||
}
|
||||
|
||||
|
||||
@@ -245,20 +178,83 @@ PlaylistModel::append( const Tomahawk::artist_ptr& artist )
|
||||
m_isTemporary = true;
|
||||
}
|
||||
|
||||
onTracksAdded( artist->tracks() );
|
||||
append( artist->tracks() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::insert( unsigned int row, const Tomahawk::query_ptr& query )
|
||||
PlaylistModel::insert( const Tomahawk::query_ptr& query, int row )
|
||||
{
|
||||
if ( query.isNull() )
|
||||
TrackModel::insert( query, row );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::insert( const QList< Tomahawk::query_ptr >& queries, int row )
|
||||
{
|
||||
if ( !queries.count() )
|
||||
return;
|
||||
|
||||
QList< Tomahawk::query_ptr > ql;
|
||||
ql << query;
|
||||
QList< Tomahawk::plentry_ptr > entries;
|
||||
foreach( const query_ptr& query, queries )
|
||||
{
|
||||
plentry_ptr entry = plentry_ptr( new PlaylistEntry() );
|
||||
|
||||
onTracksInserted( row, ql );
|
||||
if ( query->results().count() )
|
||||
entry->setDuration( query->results().at( 0 )->duration() );
|
||||
else
|
||||
entry->setDuration( 0 );
|
||||
|
||||
entry->setLastmodified( 0 );
|
||||
entry->setAnnotation( "" ); // FIXME
|
||||
entry->setQuery( query );
|
||||
entry->setGuid( uuid() );
|
||||
|
||||
entries << entry;
|
||||
}
|
||||
|
||||
insert( entries, row );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::insert( const QList< Tomahawk::plentry_ptr >& entries, int row )
|
||||
{
|
||||
if ( !entries.count() )
|
||||
return;
|
||||
|
||||
int c = row;
|
||||
QPair< int, int > crows;
|
||||
crows.first = c;
|
||||
crows.second = c + entries.count() - 1;
|
||||
|
||||
emit beginInsertRows( QModelIndex(), crows.first, crows.second );
|
||||
|
||||
int i = 0;
|
||||
TrackModelItem* plitem;
|
||||
foreach( const plentry_ptr& entry, entries )
|
||||
{
|
||||
plitem = new TrackModelItem( entry, m_rootItem, row + i );
|
||||
plitem->index = createIndex( row + i, 0, plitem );
|
||||
i++;
|
||||
|
||||
if ( entry->query()->id() == currentItemUuid() )
|
||||
setCurrentItem( plitem->index );
|
||||
|
||||
if ( !entry->query()->resolvingFinished() && !entry->query()->playable() )
|
||||
{
|
||||
m_waitingForResolved.append( entry->query().data() );
|
||||
connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ), SLOT( trackResolved( bool ) ) );
|
||||
}
|
||||
|
||||
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
|
||||
}
|
||||
|
||||
if ( !m_waitingForResolved.isEmpty() )
|
||||
emit loadingStarted();
|
||||
|
||||
emit endInsertRows();
|
||||
emit trackCountChanged( rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -282,53 +278,9 @@ PlaylistModel::trackResolved( bool )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks )
|
||||
{
|
||||
onTracksInserted( rowCount( QModelIndex() ), tracks );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks )
|
||||
{
|
||||
if ( !tracks.count() )
|
||||
{
|
||||
emit trackCountChanged( rowCount( QModelIndex() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
int c = row;
|
||||
QPair< int, int > crows;
|
||||
crows.first = c;
|
||||
crows.second = c + tracks.count() - 1;
|
||||
|
||||
emit beginInsertRows( QModelIndex(), crows.first, crows.second );
|
||||
|
||||
int i = 0;
|
||||
TrackModelItem* plitem;
|
||||
foreach( const query_ptr& query, tracks )
|
||||
{
|
||||
plentry_ptr entry = plentry_ptr( new PlaylistEntry() );
|
||||
entry->setQuery( query );
|
||||
|
||||
plitem = new TrackModelItem( entry, m_rootItem, row + i );
|
||||
plitem->index = createIndex( row + i, 0, plitem );
|
||||
|
||||
i++;
|
||||
|
||||
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
|
||||
}
|
||||
|
||||
emit endInsertRows();
|
||||
emit trackCountChanged( rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::onDataChanged()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
TrackModelItem* p = (TrackModelItem*)sender();
|
||||
if ( p && p->index.isValid() )
|
||||
emit dataChanged( p->index, p->index.sibling( p->index.row(), columnCount() - 1 ) );
|
||||
@@ -384,14 +336,16 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r
|
||||
// so check if the drag originated in this playlist to determine whether or not to copy
|
||||
#ifdef Q_WS_MAC
|
||||
if ( !data->hasFormat( "application/tomahawk.playlist.id" ) ||
|
||||
( !m_playlist.isNull() && data->data( "application/tomahawk.playlist.id" ) != m_playlist->guid() ) )
|
||||
( !m_playlist.isNull() && data->data( "application/tomahawk.playlist.id" ) != m_playlist->guid() ) )
|
||||
{
|
||||
dj->setDropAction( DropJob::Append );
|
||||
}
|
||||
#else
|
||||
if ( action & Qt::CopyAction )
|
||||
dj->setDropAction( DropJob::Append );
|
||||
#endif
|
||||
|
||||
connect( dj, SIGNAL( tracks( QList< Tomahawk::query_ptr > ) ), this, SLOT( parsedDroppedTracks( QList< Tomahawk::query_ptr > ) ) );
|
||||
connect( dj, SIGNAL( tracks( QList< Tomahawk::query_ptr > ) ), SLOT( parsedDroppedTracks( QList< Tomahawk::query_ptr > ) ) );
|
||||
dj->tracksFromMimeData( data );
|
||||
|
||||
return true;
|
||||
@@ -412,44 +366,13 @@ PlaylistModel::parsedDroppedTracks( QList< query_ptr > tracks )
|
||||
else
|
||||
beginRow = rowCount( QModelIndex() );
|
||||
|
||||
// qDebug() << data->formats();
|
||||
QString currentuuid;
|
||||
if ( currentItem().isValid() )
|
||||
currentuuid = itemFromIndex( currentItem() )->query()->id();
|
||||
|
||||
if ( tracks.count() )
|
||||
{
|
||||
emit beginInsertRows( QModelIndex(), beginRow, beginRow + tracks.count() - 1 );
|
||||
foreach( const Tomahawk::query_ptr& query, tracks )
|
||||
{
|
||||
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 );
|
||||
|
||||
TrackModelItem* plitem = new TrackModelItem( e, m_rootItem, beginRow );
|
||||
plitem->index = createIndex( beginRow++, 0, plitem );
|
||||
|
||||
if ( query->id() == currentuuid )
|
||||
setCurrentItem( plitem->index );
|
||||
|
||||
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
|
||||
}
|
||||
emit endInsertRows();
|
||||
|
||||
if ( m_dropStorage.action & Qt::CopyAction || m_dropStorage.action & Qt::MoveAction )
|
||||
{
|
||||
onPlaylistChanged();
|
||||
emit trackCountChanged( rowCount( QModelIndex() ) );
|
||||
}
|
||||
bool update = ( m_dropStorage.action & Qt::CopyAction || m_dropStorage.action & Qt::MoveAction );
|
||||
if ( update )
|
||||
beginPlaylistChanges();
|
||||
|
||||
insert( tracks, beginRow );
|
||||
}
|
||||
|
||||
m_dropStorage.parent = QPersistentModelIndex();
|
||||
@@ -458,11 +381,32 @@ PlaylistModel::parsedDroppedTracks( QList< query_ptr > tracks )
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::onPlaylistChanged()
|
||||
PlaylistModel::beginPlaylistChanges()
|
||||
{
|
||||
if ( m_playlist.isNull() )
|
||||
if ( m_playlist.isNull() || !m_playlist->author()->isLocal() )
|
||||
return;
|
||||
|
||||
Q_ASSERT( !m_changesOngoing );
|
||||
m_changesOngoing = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::endPlaylistChanges()
|
||||
{
|
||||
if ( m_playlist.isNull() || !m_playlist->author()->isLocal() )
|
||||
return;
|
||||
|
||||
if ( m_changesOngoing )
|
||||
{
|
||||
m_changesOngoing = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug() << "Called" << Q_FUNC_INFO << "unexpectedly!";
|
||||
Q_ASSERT( false );
|
||||
}
|
||||
|
||||
QList<plentry_ptr> l = playlistEntries();
|
||||
QString newrev = uuid();
|
||||
m_waitForRevision << newrev;
|
||||
@@ -505,16 +449,17 @@ PlaylistModel::playlistEntries() const
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::remove( unsigned int row, bool moreToCome )
|
||||
PlaylistModel::remove( int row, bool moreToCome )
|
||||
{
|
||||
removeIndex( index( row, 0, QModelIndex() ), moreToCome );
|
||||
TrackModel::remove( row, moreToCome );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
||||
PlaylistModel::remove( const QModelIndex& index, bool moreToCome )
|
||||
{
|
||||
TrackModelItem* item = itemFromIndex( index );
|
||||
|
||||
if ( item && m_waitingForResolved.contains( item->query().data() ) )
|
||||
{
|
||||
m_waitingForResolved.removeAll( item->query().data() );
|
||||
@@ -522,12 +467,27 @@ PlaylistModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
||||
emit loadingFinished();
|
||||
}
|
||||
|
||||
TrackModel::removeIndex( index );
|
||||
if ( !m_changesOngoing )
|
||||
beginPlaylistChanges();
|
||||
|
||||
if ( !moreToCome && !m_playlist.isNull() )
|
||||
{
|
||||
onPlaylistChanged();
|
||||
}
|
||||
TrackModel::remove( index, moreToCome );
|
||||
|
||||
if ( !moreToCome )
|
||||
endPlaylistChanges();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::remove( const QList<QModelIndex>& indexes )
|
||||
{
|
||||
TrackModel::remove( indexes );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistModel::remove( const QList<QPersistentModelIndex>& indexes )
|
||||
{
|
||||
TrackModel::remove( indexes );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -47,11 +47,6 @@ public:
|
||||
explicit PlaylistModel( QObject* parent = 0 );
|
||||
~PlaylistModel();
|
||||
|
||||
int columnCount( const QModelIndex& parent = QModelIndex() ) const;
|
||||
|
||||
QVariant data( const QModelIndex& index, int role ) const;
|
||||
QVariant headerData( int section, Qt::Orientation orientation, int role ) const;
|
||||
|
||||
virtual QMimeData* mimeData ( const QModelIndexList& indexes ) const;
|
||||
virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent );
|
||||
|
||||
@@ -60,44 +55,47 @@ public:
|
||||
virtual void loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEntries = true );
|
||||
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 );
|
||||
|
||||
void append( const QList< Tomahawk::query_ptr >& queries );
|
||||
|
||||
void insert( unsigned int row, const Tomahawk::query_ptr& query );
|
||||
|
||||
void remove( unsigned int row, bool moreToCome = false );
|
||||
virtual void removeIndex( const QModelIndex& index, bool moreToCome = false );
|
||||
bool isTemporary() const;
|
||||
|
||||
public slots:
|
||||
virtual void clear();
|
||||
|
||||
virtual void append( const Tomahawk::query_ptr& query );
|
||||
virtual void append( const Tomahawk::album_ptr& album );
|
||||
virtual void append( const Tomahawk::artist_ptr& artist );
|
||||
virtual void append( const QList< Tomahawk::query_ptr >& queries );
|
||||
virtual void append( const QList< Tomahawk::plentry_ptr >& entries );
|
||||
|
||||
virtual void insert( const Tomahawk::query_ptr& query, int row = 0 );
|
||||
virtual void insert( const QList< Tomahawk::query_ptr >& queries, int row = 0 );
|
||||
virtual void insert( const QList< Tomahawk::plentry_ptr >& entries, int row = 0 );
|
||||
|
||||
virtual void remove( int row, bool moreToCome = false );
|
||||
virtual void remove( const QModelIndex& index, bool moreToCome = false );
|
||||
virtual void remove( const QList<QModelIndex>& indexes );
|
||||
virtual void remove( const QList<QPersistentModelIndex>& indexes );
|
||||
|
||||
signals:
|
||||
void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode );
|
||||
void shuffleModeChanged( bool enabled );
|
||||
void itemSizeChanged( const QModelIndex& index );
|
||||
void playlistDeleted();
|
||||
void playlistChanged();
|
||||
|
||||
private slots:
|
||||
void onDataChanged();
|
||||
|
||||
void onRevisionLoaded( Tomahawk::PlaylistRevision revision );
|
||||
void onPlaylistChanged();
|
||||
|
||||
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
|
||||
void onTracksInserted( unsigned int row, const QList<Tomahawk::query_ptr>& tracks );
|
||||
void parsedDroppedTracks( QList<Tomahawk::query_ptr> );
|
||||
|
||||
void trackResolved( bool );
|
||||
|
||||
private:
|
||||
void beginPlaylistChanges();
|
||||
void endPlaylistChanges();
|
||||
|
||||
QList<Tomahawk::plentry_ptr> playlistEntries() const;
|
||||
|
||||
Tomahawk::playlist_ptr m_playlist;
|
||||
bool m_isTemporary;
|
||||
bool m_changesOngoing;
|
||||
QList< Tomahawk::Query* > m_waitingForResolved;
|
||||
QStringList m_waitForRevision;
|
||||
|
||||
|
@@ -94,7 +94,7 @@ PlaylistView::keyPressEvent( QKeyEvent* event )
|
||||
if ( ( event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace ) && !model()->isReadOnly() )
|
||||
{
|
||||
qDebug() << "Removing selected items";
|
||||
proxyModel()->removeIndexes( selectedIndexes() );
|
||||
proxyModel()->remove( selectedIndexes() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,9 +102,10 @@ PlaylistView::keyPressEvent( QKeyEvent* event )
|
||||
void
|
||||
PlaylistView::deleteItems()
|
||||
{
|
||||
proxyModel()->removeIndexes( selectedIndexes() );
|
||||
proxyModel()->remove( selectedIndexes() );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PlaylistView::canAutoUpdate() const
|
||||
{
|
||||
@@ -114,6 +115,7 @@ PlaylistView::canAutoUpdate() const
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PlaylistView::autoUpdate() const
|
||||
{
|
||||
|
@@ -44,7 +44,7 @@ void
|
||||
QueueProxyModel::onIndexActivated( const QModelIndex& index )
|
||||
{
|
||||
setCurrentIndex( QModelIndex() );
|
||||
removeIndex( index );
|
||||
remove( index );
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ QueueProxyModel::siblingItem( int itemsAway )
|
||||
setCurrentIndex( QModelIndex() );
|
||||
Tomahawk::result_ptr res = PlaylistProxyModel::siblingItem( itemsAway );
|
||||
|
||||
removeIndex( currentIndex() );
|
||||
remove( currentIndex() );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
@@ -39,16 +39,13 @@ TrackModel::TrackModel( QObject* parent )
|
||||
, m_readOnly( true )
|
||||
, m_style( Detailed )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
connect( AudioEngine::instance(), SIGNAL( finished( Tomahawk::result_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::result_ptr ) ), Qt::DirectConnection );
|
||||
connect( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), SLOT( onPlaybackStarted( Tomahawk::result_ptr ) ), Qt::DirectConnection );
|
||||
connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackStopped() ), Qt::DirectConnection );
|
||||
}
|
||||
|
||||
|
||||
TrackModel::~TrackModel()
|
||||
{
|
||||
// delete m_rootItem;
|
||||
}
|
||||
|
||||
|
||||
@@ -230,6 +227,7 @@ QVariant
|
||||
TrackModel::headerData( int section, Qt::Orientation orientation, int role ) const
|
||||
{
|
||||
Q_UNUSED( orientation );
|
||||
|
||||
QStringList headers;
|
||||
headers << tr( "Artist" ) << tr( "Title" ) << tr( "Album" ) << tr( "Track" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ) << tr( "Score" );
|
||||
if ( role == Qt::DisplayRole && section >= 0 )
|
||||
@@ -244,7 +242,6 @@ TrackModel::headerData( int section, Qt::Orientation orientation, int role ) con
|
||||
void
|
||||
TrackModel::setCurrentItem( const QModelIndex& index )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
TrackModelItem* oldEntry = itemFromIndex( m_currentIndex );
|
||||
if ( oldEntry )
|
||||
{
|
||||
@@ -252,14 +249,16 @@ TrackModel::setCurrentItem( const QModelIndex& index )
|
||||
}
|
||||
|
||||
TrackModelItem* entry = itemFromIndex( index );
|
||||
if ( entry )
|
||||
if ( index.isValid() && entry && !entry->query().isNull() )
|
||||
{
|
||||
m_currentIndex = index;
|
||||
m_currentUuid = entry->query()->id();
|
||||
entry->setIsPlaying( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentIndex = QModelIndex();
|
||||
m_currentUuid = QString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,16 +321,96 @@ TrackModel::mimeData( const QModelIndexList &indexes ) const
|
||||
|
||||
|
||||
void
|
||||
TrackModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
||||
TrackModel::clear()
|
||||
{
|
||||
if ( rowCount( QModelIndex() ) )
|
||||
{
|
||||
emit loadingFinished();
|
||||
|
||||
emit beginResetModel();
|
||||
delete m_rootItem;
|
||||
m_rootItem = 0;
|
||||
m_rootItem = new TrackModelItem( 0, this );
|
||||
emit endResetModel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackModel::append( const Tomahawk::query_ptr& query )
|
||||
{
|
||||
insert( query, rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackModel::append( const QList< Tomahawk::query_ptr >& queries )
|
||||
{
|
||||
insert( queries, rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackModel::insert( const Tomahawk::query_ptr& query, int row )
|
||||
{
|
||||
if ( query.isNull() )
|
||||
return;
|
||||
|
||||
QList< Tomahawk::query_ptr > ql;
|
||||
ql << query;
|
||||
|
||||
insert( ql, row );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackModel::insert( const QList< Tomahawk::query_ptr >& queries, int row )
|
||||
{
|
||||
if ( !queries.count() )
|
||||
return;
|
||||
|
||||
int c = row;
|
||||
QPair< int, int > crows;
|
||||
crows.first = c;
|
||||
crows.second = c + queries.count() - 1;
|
||||
|
||||
emit beginInsertRows( QModelIndex(), crows.first, crows.second );
|
||||
|
||||
int i = 0;
|
||||
TrackModelItem* plitem;
|
||||
foreach( const query_ptr& query, queries )
|
||||
{
|
||||
plitem = new TrackModelItem( query, m_rootItem, row + i );
|
||||
plitem->index = createIndex( row + i, 0, plitem );
|
||||
i++;
|
||||
|
||||
if ( query->id() == currentItemUuid() )
|
||||
setCurrentItem( plitem->index );
|
||||
|
||||
connect( plitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
|
||||
}
|
||||
|
||||
emit endInsertRows();
|
||||
emit trackCountChanged( rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackModel::remove( int row, bool moreToCome )
|
||||
{
|
||||
remove( index( row, 0, QModelIndex() ), moreToCome );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackModel::remove( const QModelIndex& index, bool moreToCome )
|
||||
{
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
// qDebug() << "Reinvoking in correct thread:" << Q_FUNC_INFO;
|
||||
QMetaObject::invokeMethod( this, "removeIndex",
|
||||
QMetaObject::invokeMethod( this, "remove",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(const QModelIndex, index),
|
||||
Q_ARG(bool, moreToCome)
|
||||
);
|
||||
Q_ARG(bool, moreToCome) );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -346,24 +425,49 @@ TrackModel::removeIndex( const QModelIndex& index, bool moreToCome )
|
||||
emit endRemoveRows();
|
||||
}
|
||||
|
||||
emit trackCountChanged( rowCount( QModelIndex() ) );
|
||||
if ( !moreToCome )
|
||||
emit trackCountChanged( rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackModel::removeIndexes( const QList<QModelIndex>& indexes )
|
||||
TrackModel::remove( const QList<QModelIndex>& indexes )
|
||||
{
|
||||
foreach( const QModelIndex& idx, indexes )
|
||||
QList<QPersistentModelIndex> pil;
|
||||
foreach ( const QModelIndex& idx, indexes )
|
||||
{
|
||||
removeIndex( idx );
|
||||
pil << idx;
|
||||
}
|
||||
|
||||
remove( pil );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackModel::remove( const QList<QPersistentModelIndex>& indexes )
|
||||
{
|
||||
QList<QPersistentModelIndex> finalIndexes;
|
||||
foreach ( const QPersistentModelIndex index, indexes )
|
||||
{
|
||||
if ( index.column() > 0 )
|
||||
continue;
|
||||
finalIndexes << index;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < finalIndexes.count(); i++ )
|
||||
{
|
||||
remove( finalIndexes.at( i ), i + 1 != finalIndexes.count() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TrackModelItem*
|
||||
TrackModel::itemFromIndex( const QModelIndex& index ) const
|
||||
{
|
||||
if ( index.isValid() )
|
||||
{
|
||||
return static_cast<TrackModelItem*>( index.internalPointer() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rootItem;
|
||||
@@ -372,10 +476,10 @@ TrackModel::itemFromIndex( const QModelIndex& index ) const
|
||||
|
||||
|
||||
void
|
||||
TrackModel::onPlaybackFinished( const Tomahawk::result_ptr& result )
|
||||
TrackModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
|
||||
{
|
||||
TrackModelItem* oldEntry = itemFromIndex( m_currentIndex );
|
||||
if ( oldEntry && !oldEntry->query().isNull() && oldEntry->query()->results().contains( result ) )
|
||||
if ( oldEntry && ( oldEntry->query().isNull() || !oldEntry->query()->numResults() || oldEntry->query()->results().first().data() != result.data() ) )
|
||||
{
|
||||
oldEntry->setIsPlaying( false );
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "playlistinterface.h"
|
||||
#include "trackmodelitem.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
@@ -84,16 +85,13 @@ public:
|
||||
virtual Qt::ItemFlags flags( const QModelIndex& index ) const;
|
||||
|
||||
virtual QPersistentModelIndex currentItem() { return m_currentIndex; }
|
||||
virtual Tomahawk::QID currentItemUuid() { return m_currentUuid; }
|
||||
|
||||
virtual Tomahawk::PlaylistInterface::RepeatMode repeatMode() const { return Tomahawk::PlaylistInterface::NoRepeat; }
|
||||
virtual bool shuffled() const { return false; }
|
||||
|
||||
virtual void ensureResolved();
|
||||
|
||||
virtual void append( const Tomahawk::query_ptr& query ) = 0;
|
||||
virtual void append( const Tomahawk::artist_ptr& artist ) = 0;
|
||||
virtual void append( const Tomahawk::album_ptr& album ) = 0;
|
||||
|
||||
TrackModelItem* itemFromIndex( const QModelIndex& index ) const;
|
||||
TrackModelItem* m_rootItem;
|
||||
|
||||
@@ -109,18 +107,32 @@ signals:
|
||||
public slots:
|
||||
virtual void setCurrentItem( const QModelIndex& index );
|
||||
|
||||
virtual void removeIndex( const QModelIndex& index, bool moreToCome = false );
|
||||
virtual void removeIndexes( const QList<QModelIndex>& indexes );
|
||||
virtual void clear();
|
||||
|
||||
virtual void append( const QList< Tomahawk::query_ptr >& queries );
|
||||
virtual void append( const Tomahawk::query_ptr& query );
|
||||
virtual void append( const Tomahawk::artist_ptr& artist ) { Q_UNUSED( artist ); }
|
||||
virtual void append( const Tomahawk::album_ptr& album ) { Q_UNUSED( album ); }
|
||||
|
||||
virtual void insert( const QList< Tomahawk::query_ptr >& queries, int row = 0 );
|
||||
virtual void insert( const Tomahawk::query_ptr& query, int row = 0 );
|
||||
|
||||
virtual void remove( int row, bool moreToCome = false );
|
||||
virtual void remove( const QModelIndex& index, bool moreToCome = false );
|
||||
virtual void remove( const QList<QModelIndex>& indexes );
|
||||
virtual void remove( const QList<QPersistentModelIndex>& indexes );
|
||||
|
||||
virtual void setRepeatMode( Tomahawk::PlaylistInterface::RepeatMode /*mode*/ ) {}
|
||||
virtual void setShuffled( bool /*shuffled*/ ) {}
|
||||
|
||||
private slots:
|
||||
void onPlaybackFinished( const Tomahawk::result_ptr& result );
|
||||
void onPlaybackStarted( const Tomahawk::result_ptr& result );
|
||||
void onPlaybackStopped();
|
||||
|
||||
private:
|
||||
QPersistentModelIndex m_currentIndex;
|
||||
Tomahawk::QID m_currentUuid;
|
||||
|
||||
bool m_readOnly;
|
||||
|
||||
QString m_title;
|
||||
|
@@ -227,66 +227,48 @@ TrackProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParen
|
||||
|
||||
|
||||
void
|
||||
TrackProxyModel::removeIndex( const QModelIndex& index )
|
||||
TrackProxyModel::remove( const QModelIndex& index )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( !sourceModel() )
|
||||
return;
|
||||
if ( !index.isValid() )
|
||||
return;
|
||||
|
||||
sourceModel()->removeIndex( mapToSource( index ) );
|
||||
sourceModel()->remove( mapToSource( index ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackProxyModel::removeIndexes( const QModelIndexList& indexes )
|
||||
TrackProxyModel::remove( const QModelIndexList& indexes )
|
||||
{
|
||||
if ( !sourceModel() )
|
||||
return;
|
||||
|
||||
QList<QPersistentModelIndex> pil;
|
||||
foreach( const QModelIndex& idx, indexes )
|
||||
foreach ( const QModelIndex& idx, indexes )
|
||||
{
|
||||
if ( idx.isValid() && idx.column() == 0 )
|
||||
if ( idx.isValid() )
|
||||
pil << mapToSource( idx );
|
||||
}
|
||||
|
||||
bool b = true;
|
||||
foreach( const QPersistentModelIndex& idx, pil )
|
||||
{
|
||||
if ( idx == pil.last() )
|
||||
b = false;
|
||||
|
||||
qDebug() << "b is:" << b;
|
||||
sourceModel()->removeIndex( idx, b );
|
||||
}
|
||||
sourceModel()->remove( pil );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackProxyModel::removeIndexes( const QList<QPersistentModelIndex>& indexes )
|
||||
TrackProxyModel::remove( const QList< QPersistentModelIndex >& indexes )
|
||||
{
|
||||
if ( !sourceModel() )
|
||||
return;
|
||||
|
||||
QList<QPersistentModelIndex> pil;
|
||||
foreach( const QModelIndex& idx, indexes )
|
||||
foreach ( const QPersistentModelIndex& idx, indexes )
|
||||
{
|
||||
if ( idx.isValid() && idx.column() == 0 )
|
||||
if ( idx.isValid() )
|
||||
pil << mapToSource( idx );
|
||||
}
|
||||
|
||||
bool b = true;
|
||||
foreach( const QPersistentModelIndex& idx, pil )
|
||||
{
|
||||
if ( idx == pil.last() )
|
||||
b = false;
|
||||
|
||||
qDebug() << "b is:" << b;
|
||||
sourceModel()->removeIndex( idx, b );
|
||||
}
|
||||
sourceModel()->remove( pil );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -45,9 +45,9 @@ public:
|
||||
virtual int unfilteredTrackCount() const { return sourceModel()->trackCount(); }
|
||||
virtual int trackCount() const { return rowCount( QModelIndex() ); }
|
||||
|
||||
virtual void removeIndex( const QModelIndex& index );
|
||||
virtual void removeIndexes( const QModelIndexList& indexes );
|
||||
virtual void removeIndexes( const QList<QPersistentModelIndex>& indexes );
|
||||
virtual void remove( const QModelIndex& index );
|
||||
virtual void remove( const QModelIndexList& indexes );
|
||||
virtual void remove( const QList< QPersistentModelIndex >& indexes );
|
||||
|
||||
virtual Tomahawk::result_ptr currentItem() const;
|
||||
virtual Tomahawk::result_ptr siblingItem( int itemsAway );
|
||||
@@ -75,7 +75,7 @@ signals:
|
||||
void filterChanged( const QString& filter );
|
||||
|
||||
void nextTrackReady();
|
||||
|
||||
|
||||
public slots:
|
||||
virtual void setRepeatMode( RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); }
|
||||
virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); }
|
||||
|
@@ -411,7 +411,7 @@ TrackView::startDrag( Qt::DropActions supportedActions )
|
||||
Qt::DropAction action = drag->exec( supportedActions, Qt::CopyAction );
|
||||
if ( action == Qt::MoveAction )
|
||||
{
|
||||
m_proxyModel->removeIndexes( pindexes );
|
||||
m_proxyModel->remove( pindexes );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -43,7 +43,7 @@ TreeModel::TreeModel( QObject* parent )
|
||||
{
|
||||
setIcon( QPixmap( RESPATH "images/music-icon.png" ) );
|
||||
|
||||
connect( AudioEngine::instance(), SIGNAL( finished( Tomahawk::result_ptr ) ), SLOT( onPlaybackFinished( Tomahawk::result_ptr ) ), Qt::DirectConnection );
|
||||
connect( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), SLOT( onPlaybackStarted( Tomahawk::result_ptr ) ), Qt::DirectConnection );
|
||||
connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackStopped() ), Qt::DirectConnection );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
@@ -948,11 +948,10 @@ TreeModel::infoSystemFinished( QString target )
|
||||
|
||||
|
||||
void
|
||||
TreeModel::onPlaybackFinished( const Tomahawk::result_ptr& result )
|
||||
TreeModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
|
||||
{
|
||||
TreeModelItem* oldEntry = itemFromIndex( m_currentIndex );
|
||||
qDebug() << oldEntry->result().data() << result.data();
|
||||
if ( oldEntry && !oldEntry->result().isNull() && oldEntry->result().data() == result.data() )
|
||||
if ( oldEntry && ( oldEntry->result().isNull() || oldEntry->result().data() != result.data() ) )
|
||||
{
|
||||
oldEntry->setIsPlaying( false );
|
||||
}
|
||||
|
@@ -149,7 +149,7 @@ private slots:
|
||||
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void infoSystemFinished( QString target );
|
||||
|
||||
void onPlaybackFinished( const Tomahawk::result_ptr& result );
|
||||
void onPlaybackStarted( const Tomahawk::result_ptr& result );
|
||||
void onPlaybackStopped();
|
||||
|
||||
void onDataChanged();
|
||||
|
@@ -43,6 +43,15 @@ TreeProxyModel::TreeProxyModel( QObject* parent )
|
||||
setSourceTreeModel( 0 );
|
||||
}
|
||||
|
||||
QPersistentModelIndex
|
||||
TreeProxyModel::currentIndex() const
|
||||
{
|
||||
if ( !m_model )
|
||||
return QPersistentModelIndex();
|
||||
|
||||
return mapFromSource( m_model->currentItem() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TreeProxyModel::setSourceModel( QAbstractItemModel* sourceModel )
|
||||
|
@@ -39,7 +39,7 @@ public:
|
||||
virtual void setSourceTreeModel( TreeModel* sourceModel );
|
||||
virtual void setSourceModel( QAbstractItemModel* sourceModel );
|
||||
|
||||
virtual QPersistentModelIndex currentIndex() const { return mapFromSource( m_model->currentItem() ); }
|
||||
virtual QPersistentModelIndex currentIndex() const;
|
||||
virtual void setCurrentIndex( const QModelIndex& index ) { m_model->setCurrentItem( mapToSource( index ) ); }
|
||||
|
||||
virtual QList<Tomahawk::query_ptr> tracks() { Q_ASSERT( FALSE ); QList<Tomahawk::query_ptr> queries; return queries; }
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#define PLAYLISTINTERFACE_H
|
||||
|
||||
#include <QModelIndex>
|
||||
#include <QWidget>
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "dllmacro.h"
|
||||
@@ -67,6 +68,10 @@ public:
|
||||
|
||||
virtual void reset() {}
|
||||
|
||||
// Some playlist interfaces can wrap other interfaces. When checking for top-level
|
||||
// equality (say, to compare the currently playing interface) this might be needed
|
||||
virtual bool hasChildInterface( PlaylistInterface* ) { return false; }
|
||||
|
||||
QObject* object() const { return m_object; }
|
||||
|
||||
static void dontDelete( Tomahawk::PlaylistInterface* obj )
|
||||
|
@@ -102,8 +102,6 @@ Query::Query( const QString& query, const QID& qid )
|
||||
|
||||
Query::~Query()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << toString();
|
||||
|
||||
if ( !id().isEmpty() )
|
||||
{
|
||||
QMutexLocker lock( &s_mutex );
|
||||
|
@@ -18,26 +18,21 @@
|
||||
|
||||
#include "resolver.h"
|
||||
|
||||
|
||||
#include <QWidget>
|
||||
#include <QtUiTools/QUiLoader>
|
||||
#include <QMetaProperty>
|
||||
#include <QBuffer>
|
||||
#include <QDir>
|
||||
#include <QIcon>
|
||||
|
||||
#include "utils/logger.h"
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QIcon>
|
||||
#include <QWidget>
|
||||
#endif
|
||||
#include <QUiLoader>
|
||||
|
||||
Tomahawk::ExternalResolver::ErrorState
|
||||
Tomahawk::ExternalResolver::error() const
|
||||
{
|
||||
return NoError;
|
||||
}
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
QVariant
|
||||
Tomahawk::ExternalResolver::configMsgFromWidget( QWidget* w )
|
||||
{
|
||||
@@ -50,7 +45,7 @@ Tomahawk::ExternalResolver::configMsgFromWidget( QWidget* w )
|
||||
// qDebug() << "Generated widget variant:" << widgetMap;
|
||||
return widgetMap;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
Tomahawk::ExternalResolver::addChildProperties( QObject* widget, QVariantMap& m )
|
||||
|
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "artist.h"
|
||||
#include "album.h"
|
||||
#include "config.h"
|
||||
#include "pipeline.h"
|
||||
#include "sourcelist.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
@@ -31,10 +32,7 @@
|
||||
#include <network/servent.h>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
#include <QMessageBox>
|
||||
|
||||
// FIXME: bloody hack, remove this for 0.3
|
||||
// this one adds new functionality to old resolvers
|
||||
@@ -192,13 +190,9 @@ void
|
||||
ScriptEngine::javaScriptConsoleMessage( const QString& message, int lineNumber, const QString& sourceID )
|
||||
{
|
||||
tLog() << "JAVASCRIPT:" << m_scriptPath << message << lineNumber << sourceID;
|
||||
/// I guess there is somereason for a assert in here, maybe fatal js errors, but
|
||||
/// undefined is not so fatal
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#ifdef QT_DEBUG
|
||||
#ifdef DEBUG_BUILD
|
||||
QMessageBox::critical( 0, "Script Resolver Error", QString( "%1 %2 %3 %4" ).arg( m_scriptPath ).arg( message ).arg( lineNumber ).arg( sourceID ) );
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QThread>
|
||||
|
@@ -22,10 +22,7 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QPluginLoader>
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "functimeout.h"
|
||||
|
||||
@@ -71,7 +68,6 @@ SipHandler::~SipHandler()
|
||||
}
|
||||
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
const QPixmap
|
||||
SipHandler::avatar( const QString& name ) const
|
||||
{
|
||||
@@ -88,7 +84,7 @@ SipHandler::avatar( const QString& name ) const
|
||||
return QPixmap();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
const SipInfo
|
||||
SipHandler::sipInfo(const QString& peerId) const
|
||||
@@ -377,13 +373,13 @@ SipHandler::enablePlugin( SipPlugin* p )
|
||||
void
|
||||
SipHandler::connectPlugin( bool startup, const QString &pluginId )
|
||||
{
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
if ( !TomahawkSettings::instance()->acceptedLegalWarning() )
|
||||
{
|
||||
int result = QMessageBox::question(
|
||||
//TomahawkApp::instance()->mainWindow(),
|
||||
0, tr( "Legal Warning" ),
|
||||
tr( "By pressing OK below, you agree that your use of Tomahawk will be in accordance with any applicable laws, including copyright and intellectual property laws, in effect in your country of residence, and indemnify the Tomahawk developers and project from liability should you choose to break those laws.\n\nFor more information, please see http://gettomahawk.com/legal" ),
|
||||
tr( "By pressing I Agree below, you agree that your use of Tomahawk will be in accordance with any applicable laws, including copyright and intellectual property laws, in effect in your country of residence, and indemnify the Tomahawk developers and project from liability should you choose to break those laws.\n\nFor more information, please see http://gettomahawk.com/legal" ),
|
||||
tr( "I Do Not Agree" ), tr( "I Agree" )
|
||||
);
|
||||
if ( result != 1 )
|
||||
@@ -475,16 +471,10 @@ SipHandler::onPeerOnline( const QString& jid )
|
||||
if( Servent::instance()->visibleExternally() )
|
||||
{
|
||||
QString key = uuid();
|
||||
ControlConnection* conn = new ControlConnection( Servent::instance() );
|
||||
ControlConnection* conn = new ControlConnection( Servent::instance(), QString() );
|
||||
|
||||
const QString& nodeid = Database::instance()->dbid();
|
||||
|
||||
//TODO: this is a terrible assumption, help me clean this up, mighty muesli!
|
||||
if ( jid.contains( "@conference.") )
|
||||
conn->setName( jid );
|
||||
else
|
||||
conn->setName( jid.left( jid.indexOf( "/" ) ) );
|
||||
|
||||
conn->setName( jid.left( jid.indexOf( "/" ) ) );
|
||||
conn->setId( nodeid );
|
||||
|
||||
Servent::instance()->registerOffer( key, conn );
|
||||
@@ -603,7 +593,7 @@ SipHandler::onStateChanged( SipPlugin::ConnectionState state )
|
||||
emit stateChanged( sip, state );
|
||||
}
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
|
||||
void
|
||||
SipHandler::onAvatarReceived( const QString& from, const QPixmap& avatar )
|
||||
{
|
||||
@@ -648,7 +638,6 @@ SipHandler::onAvatarReceived( const QPixmap& avatar )
|
||||
// qDebug() << Q_FUNC_INFO << "Set own avatar on MyCollection";
|
||||
SourceList::instance()->getLocal()->setAvatar( avatar );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
QString
|
||||
|
@@ -24,13 +24,9 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QPixmap>
|
||||
#include <QString>
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
#include <QPixmap>
|
||||
#endif
|
||||
|
||||
|
||||
class DLLEXPORT SipHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -53,10 +49,7 @@ public:
|
||||
bool hasPluginType( const QString& factoryId ) const;
|
||||
SipPluginFactory* factoryFromPlugin( SipPlugin* p ) const;
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
const QPixmap avatar( const QString& name ) const;
|
||||
#endif
|
||||
|
||||
//TODO: implement a proper SipInfo class and maybe attach it to the source
|
||||
const SipInfo sipInfo( const QString& peerId ) const;
|
||||
const QString versionString( const QString& peerId ) const;
|
||||
@@ -104,13 +97,11 @@ private slots:
|
||||
|
||||
void onSettingsChanged();
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
// set data for local source
|
||||
void onAvatarReceived( const QPixmap& avatar );
|
||||
|
||||
// set data for other sources
|
||||
void onAvatarReceived( const QString& from, const QPixmap& avatar );
|
||||
#endif
|
||||
|
||||
private:
|
||||
static SipHandler *s_instance;
|
||||
@@ -131,10 +122,8 @@ private:
|
||||
|
||||
//TODO: move this to source
|
||||
QHash<QString, SipInfo> m_peersSipInfos;
|
||||
QHash<QString, QString> m_peersSoftwareVersions;
|
||||
#ifndef ENABLE_HEADLESS
|
||||
QHash<QString, QPixmap> m_usernameAvatars;
|
||||
#endif
|
||||
QHash<QString, QString> m_peersSoftwareVersions;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -52,7 +52,6 @@ SipPlugin::pluginId() const
|
||||
}
|
||||
|
||||
|
||||
#ifndef ENABLE_HEADLESS
|
||||
QMenu*
|
||||
SipPlugin::menu()
|
||||
{
|
||||
@@ -67,14 +66,6 @@ SipPlugin::configWidget()
|
||||
}
|
||||
|
||||
|
||||
QIcon
|
||||
SipPlugin::icon() const
|
||||
{
|
||||
return QIcon();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
QString
|
||||
SipPlugin::errorMessage() const
|
||||
{
|
||||
@@ -82,6 +73,13 @@ SipPlugin::errorMessage() const
|
||||
}
|
||||
|
||||
|
||||
QIcon
|
||||
SipPlugin::icon() const
|
||||
{
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
|
||||
const QStringList
|
||||
SipPlugin::peersOnline() const
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user