Merge branch 'master' into gfw
Conflicts: src/libtomahawk/CMakeLists.txt
3
.gitignore
vendored
@@ -12,3 +12,6 @@ moc_*
|
||||
thirdparty/qtweetlib/WARNING-twitter-api-keys
|
||||
.kdev4
|
||||
tomahawk.kdev4
|
||||
clang/
|
||||
win/
|
||||
gcc/
|
||||
|
@@ -1,5 +1,6 @@
|
||||
PROJECT( tomahawk )
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
|
||||
SET( CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/CMakeModules" )
|
||||
|
||||
IF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 )
|
||||
CMAKE_POLICY(SET CMP0017 NEW)
|
||||
@@ -11,15 +12,43 @@ ENDIF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 )
|
||||
SET( TOMAHAWK_ORGANIZATION_NAME "Tomahawk" )
|
||||
SET( TOMAHAWK_ORGANIZATION_DOMAIN "tomahawk-player.org" )
|
||||
SET( TOMAHAWK_APPLICATION_NAME "Tomahawk" )
|
||||
SET( TOMAHAWK_VERSION "0.1.0" )
|
||||
SET( TOMAHAWK_DESCRIPTION_SUMMARY "The social media player" )
|
||||
|
||||
SET( TOMAHAWK_VERSION_MAJOR 0 )
|
||||
SET( TOMAHAWK_VERSION_MINOR 1 )
|
||||
SET( TOMAHAWK_VERSION_PATCH 0 )
|
||||
|
||||
# SET( TOMAHAWK_VERSION_RC 0 )
|
||||
|
||||
IF( NOT CMAKE_BUILD_TYPE STREQUAL "Release" )
|
||||
# Use the date as the tweak level.
|
||||
INCLUDE( ${CMAKE_MODULE_PATH}/kwsysDateStamp.cmake )
|
||||
SET( TOMAHAWK_VERSION_TWEAK "${KWSYS_DATE_STAMP_YEAR}${KWSYS_DATE_STAMP_MONTH}${KWSYS_DATE_STAMP_DAY}" )
|
||||
INCLUDE( ${CMAKE_MODULE_PATH}/CMakeVersionSource.cmake )
|
||||
ENDIF()
|
||||
|
||||
SET( TOMAHAWK_VERSION ${TOMAHAWK_VERSION_MAJOR}.${TOMAHAWK_VERSION_MINOR}.${TOMAHAWK_VERSION_PATCH} )
|
||||
|
||||
IF( ${TOMAHAWK_VERSION_TWEAK} GREATER 0)
|
||||
SET( TOMAHAWK_VERSION ${TOMAHAWK_VERSION}.${TOMAHAWK_VERSION_TWEAK} )
|
||||
ENDIF()
|
||||
IF( TOMAHAWK_VERSION_RC )
|
||||
SET( CMake_VERSION ${TOMAHAWK_VERSION}-rc${TOMAHAWK_VERSION_RC} )
|
||||
ENDIF()
|
||||
IF( CMAKE_VERSION_SOURCE )
|
||||
SET( TOMAHAWK_VERSION ${TOMAHAWK_VERSION}-${CMAKE_VERSION_SOURCE} )
|
||||
ENDIF()
|
||||
|
||||
|
||||
|
||||
# set paths
|
||||
SET( CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/CMakeModules" )
|
||||
SET( THIRDPARTY_DIR ${CMAKE_SOURCE_DIR}/thirdparty )
|
||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
|
||||
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
|
||||
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
|
||||
|
||||
# installer creation
|
||||
INCLUDE( CPack.cmake )
|
||||
|
||||
# Check if we need qtgui:
|
||||
IF( "${gui}" STREQUAL "no" )
|
||||
|
37
CMakeModules/CMakeVersionSource.cmake
Normal file
@@ -0,0 +1,37 @@
|
||||
# Try to identify the current development source version.
|
||||
set(CMAKE_VERSION_SOURCE "")
|
||||
if(EXISTS ${CMAKE_SOURCE_DIR}/.git/HEAD)
|
||||
find_program(GIT_EXECUTABLE NAMES git git.cmd)
|
||||
mark_as_advanced(GIT_EXECUTABLE)
|
||||
if(GIT_EXECUTABLE)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=4 HEAD
|
||||
OUTPUT_VARIABLE head
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
if(head)
|
||||
set(CMAKE_VERSION_SOURCE "g${head}")
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
|
||||
OUTPUT_VARIABLE dirty
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
)
|
||||
if(dirty)
|
||||
set(CMAKE_VERSION_SOURCE "${CMAKE_VERSION_SOURCE}-dirty")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
elseif(EXISTS ${CMAKE_SOURCE_DIR}/CVS/Repository)
|
||||
file(READ ${CMAKE_SOURCE_DIR}/CVS/Repository repo)
|
||||
set(branch "")
|
||||
if("${repo}" MATCHES "\\.git/")
|
||||
string(REGEX REPLACE ".*\\.git/([^\r\n]*).*" "-\\1" branch "${repo}")
|
||||
endif()
|
||||
set(CMAKE_VERSION_SOURCE "cvs${branch}")
|
||||
endif()
|
24
CMakeModules/NSIS.InstallOptions.ini.in
Normal file
@@ -0,0 +1,24 @@
|
||||
[Settings]
|
||||
NumFields=3
|
||||
|
||||
[Field 1]
|
||||
Type=Label
|
||||
Left=0
|
||||
Right=-1
|
||||
Top=0
|
||||
Bottom=24
|
||||
|
||||
[Field 2]
|
||||
Type=RadioButton
|
||||
Left=30
|
||||
Right=-1
|
||||
Top=50
|
||||
Bottom=58
|
||||
State=1
|
||||
|
||||
[Field 3]
|
||||
Type=RadioButton
|
||||
Left=30
|
||||
Right=-1
|
||||
Top=70
|
||||
Bottom=78
|
665
CMakeModules/NSIS.template.in
Normal file
@@ -0,0 +1,665 @@
|
||||
;Tomahawk installer script.
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Some installer script options (comment-out options not required)
|
||||
;-----------------------------------------------------------------------------
|
||||
;!define OPTION_LICENSE_AGREEMENT
|
||||
!define OPTION_UAC_PLUGIN_ENHANCED
|
||||
!define OPTION_SECTION_SC_START_MENU
|
||||
!define OPTION_SECTION_SC_DESKTOP
|
||||
!define OPTION_SECTION_SC_QUICK_LAUNCH
|
||||
!define OPTION_FINISHPAGE
|
||||
!define OPTION_FINISHPAGE_LAUNCHER
|
||||
!define OPTION_FINISHPAGE_RELEASE_NOTES
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Some paths.
|
||||
;-----------------------------------------------------------------------------
|
||||
!ifndef MING_PATH
|
||||
!define MING_PATH "/usr/i686-w64-mingw32/sys-root/mingw"
|
||||
!endif
|
||||
!define MING_BIN "${MING_PATH}/bin"
|
||||
!define MING_LIB "${MING_PATH}/lib"
|
||||
!define BUILD_PATH "@CMAKE_BINARY_DIR@"
|
||||
!define QT_DLL_PATH "${MING_BIN}"
|
||||
!define SQLITE_DLL_PATH "${MING_LIB}/qt4/plugins/sqldrivers"
|
||||
!define IMAGEFORMATS_DLL_PATH "${MING_LIB}/qt4/plugins/imageformats"
|
||||
!define VLC_PLUGIN_PATH "${MING_LIB}\vlc\plugins"
|
||||
!define NSI_PATH "@CMAKE_SOURCE_DIR@/admin/win/nsi"
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Increment installer revision number as part of this script.
|
||||
;-----------------------------------------------------------------------------
|
||||
!define /file REVISION_LAST ${NSI_PATH}/revision.txt
|
||||
!define /math REVISION ${REVISION_LAST} + 1
|
||||
!delfile revision.txt
|
||||
!appendfile revision.txt ${REVISION}
|
||||
|
||||
!define VER_MAJOR "@CPACK_PACKAGE_VERSION_MAJOR@"
|
||||
!define VER_MINOR "@CPACK_PACKAGE_VERSION_MINOR@"
|
||||
!define VER_BUILD "@CPACK_PACKAGE_VERSION_PATCH@"
|
||||
!define VERSION "@CPACK_PACKAGE_VERSION@"
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Installer build timestamp.
|
||||
;-----------------------------------------------------------------------------
|
||||
!define /date BUILD_TIME "built on %Y/%m/%d at %I:%M %p (rev. ${REVISION})"
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Initial installer setup and definitions.
|
||||
;-----------------------------------------------------------------------------
|
||||
Name "@CPACK_NSIS_PACKAGE_NAME@"
|
||||
Caption "Tomahawk Installer"
|
||||
BrandingText "Tomahawk ${VERSION} -- ${BUILD_TIME}"
|
||||
OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
|
||||
InstallDir "$PROGRAMFILES\@CPACK_PACKAGE_INSTALL_DIRECTORY@"
|
||||
InstallDirRegKey HKCU "Software\Tomahawk" ""
|
||||
InstType Standard
|
||||
InstType Full
|
||||
InstType Minimal
|
||||
CRCCheck On
|
||||
SetCompressor @CPACK_NSIS_COMPRESSOR@
|
||||
RequestExecutionLevel user ;Now using the UAC plugin.
|
||||
ReserveFile NSIS.InstallOptions.ini
|
||||
ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
|
||||
|
||||
@CPACK_NSIS_SECTION_SELECTED_VARS@
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Include some required header files.
|
||||
;-----------------------------------------------------------------------------
|
||||
!include LogicLib.nsh ;Used by APPDATA uninstaller.
|
||||
!include nsDialogs.nsh ;Used by APPDATA uninstaller.
|
||||
!include MUI2.nsh ;Used by APPDATA uninstaller.
|
||||
!include InstallOptions.nsh ;Required by MUI2 to support old MUI_INSTALLOPTIONS.
|
||||
!include Memento.nsh ;Remember user selections.
|
||||
!include WinVer.nsh ;Windows version detection.
|
||||
!include WordFunc.nsh ;Used by VersionCompare macro function.
|
||||
!include UAC.nsh ;Used by the UAC elevation to install as user or admin.
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Memento selections stored in registry.
|
||||
;-----------------------------------------------------------------------------
|
||||
!define MEMENTO_REGISTRY_ROOT HKLM
|
||||
!define MEMENTO_REGISTRY_KEY Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Modern User Interface (MUI) defintions and setup.
|
||||
;-----------------------------------------------------------------------------
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON ${NSI_PATH}\installer.ico
|
||||
!define MUI_UNICON ${NSI_PATH}\installer.ico
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP ${NSI_PATH}\welcome.bmp
|
||||
!define MUI_WELCOMEPAGE_TITLE "@CPACK_PACKAGE_NAME@ ${VERSION} Setup$\r$\nInstaller Build Revision ${REVISION}"
|
||||
!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation.$\r$\n$\r$\n$_CLICK"
|
||||
!define MUI_HEADERIMAGE
|
||||
!define MUI_HEADERIMAGE_BITMAP ${NSI_PATH}\page_header.bmp
|
||||
!define MUI_COMPONENTSPAGE_SMALLDESC
|
||||
!define MUI_FINISHPAGE_TITLE "@CPACK_PACKAGE_NAME@ Install Completed"
|
||||
!define MUI_FINISHPAGE_LINK "Click here to visit the @CPACK_PACKAGE_NAME@ website."
|
||||
!define MUI_FINISHPAGE_LINK_LOCATION "http://@TOMAHAWK_ORGANIZATION_DOMAIN@"
|
||||
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
|
||||
!ifdef OPTION_FINISHPAGE_RELEASE_NOTES
|
||||
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
|
||||
!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\NOTES.txt"
|
||||
!define MUI_FINISHPAGE_SHOWREADME_TEXT "Show release notes"
|
||||
!endif
|
||||
!ifdef OPTION_FINISHPAGE_LAUNCHER
|
||||
!define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||
!define MUI_FINISHPAGE_RUN
|
||||
!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchTomahawk"
|
||||
!endif
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Page macros.
|
||||
;-----------------------------------------------------------------------------
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!ifdef OPTION_LICENSE_AGREEMENT
|
||||
!insertmacro MUI_PAGE_LICENSE "LICENSE.txt"
|
||||
!endif
|
||||
Page custom PageReinstall PageLeaveReinstall
|
||||
!insertmacro MUI_PAGE_COMPONENTS
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!ifdef OPTION_FINISHPAGE
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
!endif
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
UninstPage custom un.UnPageUserAppData un.UnPageUserAppDataLeave
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
;-----------------------------------------------------------------------------
|
||||
; Other MUI macros.
|
||||
;-----------------------------------------------------------------------------
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
# FINISH PAGE LAUNCHER FUNCTIONS #
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
Function LaunchTomahawk
|
||||
${UAC.CallFunctionAsUser} LaunchTomahawkAsUser
|
||||
FunctionEnd
|
||||
|
||||
Function LaunchTomahawkAsUser
|
||||
Exec "$INSTDIR\tomahawk.exe"
|
||||
FunctionEnd
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
# PROCESS HANDLING FUNCTIONS AND MACROS #
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
!macro CheckForProcess processName gotoWhenFound gotoWhenNotFound
|
||||
Processes::FindProcess ${processName}
|
||||
StrCmp $R0 "0" ${gotoWhenNotFound} ${gotoWhenFound}
|
||||
!macroend
|
||||
|
||||
!macro ConfirmEndProcess processName
|
||||
MessageBox MB_YESNO|MB_ICONEXCLAMATION \
|
||||
"Found ${processName} process(s) which need to be stopped.$\nDo you want the installer to stop these for you?" \
|
||||
IDYES process_${processName}_kill IDNO process_${processName}_ended
|
||||
process_${processName}_kill:
|
||||
DetailPrint "Killing ${processName} processes."
|
||||
Processes::KillProcess ${processName}
|
||||
Sleep 1500
|
||||
StrCmp $R0 "1" process_${processName}_ended
|
||||
DetailPrint "Process to kill not found!"
|
||||
process_${processName}_ended:
|
||||
!macroend
|
||||
|
||||
!macro CheckAndConfirmEndProcess processName
|
||||
!insertmacro CheckForProcess ${processName} 0 no_process_${processName}_to_end
|
||||
!insertmacro ConfirmEndProcess ${processName}
|
||||
no_process_${processName}_to_end:
|
||||
!macroend
|
||||
|
||||
Function EnsureTomahawkShutdown
|
||||
!insertmacro CheckAndConfirmEndProcess "tomahawk.exe"
|
||||
FunctionEnd
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
# RE-INSTALLER FUNCTIONS #
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
Function PageReinstall
|
||||
ReadRegStr $R0 HKLM "Software\Tomahawk" ""
|
||||
StrCmp $R0 "" 0 +2
|
||||
Abort
|
||||
|
||||
;Detect version
|
||||
ReadRegDWORD $R0 HKLM "Software\Tomahawk" "VersionMajor"
|
||||
IntCmp $R0 ${VER_MAJOR} minor_check new_version older_version
|
||||
minor_check:
|
||||
ReadRegDWORD $R0 HKLM "Software\Tomahawk" "VersionMinor"
|
||||
IntCmp $R0 ${VER_MINOR} build_check new_version older_version
|
||||
build_check:
|
||||
ReadRegDWORD $R0 HKLM "Software\Tomahawk" "VersionBuild"
|
||||
IntCmp $R0 ${VER_BUILD} revision_check new_version older_version
|
||||
revision_check:
|
||||
ReadRegDWORD $R0 HKLM "Software\Tomahawk" "VersionRevision"
|
||||
IntCmp $R0 ${REVISION} same_version new_version older_version
|
||||
|
||||
new_version:
|
||||
!insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 1" "Text" "An older version of Tomahawk is installed on your system. It is recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
|
||||
!insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 2" "Text" "Uninstall before installing"
|
||||
!insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 3" "Text" "Do not uninstall"
|
||||
!insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install Tomahawk."
|
||||
StrCpy $R0 "1"
|
||||
Goto reinst_start
|
||||
|
||||
older_version:
|
||||
!insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 1" "Text" "A newer version of Tomahawk is already installed! It is not recommended that you install an older version. If you really want to install this older version, it is better to uninstall the current version first. Select the operation you want to perform and click Next to continue."
|
||||
!insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 2" "Text" "Uninstall before installing"
|
||||
!insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 3" "Text" "Do not uninstall"
|
||||
!insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install Tomahawk."
|
||||
StrCpy $R0 "1"
|
||||
Goto reinst_start
|
||||
|
||||
same_version:
|
||||
!insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 1" "Text" "Tomahawk ${VERSION} is already installed.\r\nSelect the operation you want to perform and click Next to continue."
|
||||
!insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 2" "Text" "Add/Reinstall components"
|
||||
!insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 3" "Text" "Uninstall Tomahawk"
|
||||
!insertmacro MUI_HEADER_TEXT "Already Installed" "Choose the maintenance option to perform."
|
||||
StrCpy $R0 "2"
|
||||
|
||||
reinst_start:
|
||||
!insertmacro INSTALLOPTIONS_DISPLAY "NSIS.InstallOptions.ini"
|
||||
FunctionEnd
|
||||
|
||||
Function PageLeaveReinstall
|
||||
!insertmacro INSTALLOPTIONS_READ $R1 "NSIS.InstallOptions.ini" "Field 2" "State"
|
||||
StrCmp $R0 "1" 0 +2
|
||||
StrCmp $R1 "1" reinst_uninstall reinst_done
|
||||
StrCmp $R0 "2" 0 +3
|
||||
StrCmp $R1 "1" reinst_done reinst_uninstall
|
||||
reinst_uninstall:
|
||||
ReadRegStr $R1 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "UninstallString"
|
||||
HideWindow
|
||||
ClearErrors
|
||||
ExecWait '$R1 _?=$INSTDIR'
|
||||
IfErrors no_remove_uninstaller
|
||||
IfFileExists "$INSTDIR\tomahawk.exe" no_remove_uninstaller
|
||||
Delete $R1
|
||||
RMDir $INSTDIR
|
||||
no_remove_uninstaller:
|
||||
StrCmp $R0 "2" 0 +3
|
||||
UAC::Unload
|
||||
Quit
|
||||
BringToFront
|
||||
reinst_done:
|
||||
FunctionEnd
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
# INSTALLER SECTIONS #
|
||||
# #
|
||||
##############################################################################
|
||||
Section "Tomahawk Player" SEC_TOMAHAWK_PLAYER
|
||||
SectionIn 1 2 3 RO
|
||||
SetDetailsPrint listonly
|
||||
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint "Installing Tomahawk Player essentials."
|
||||
SetDetailsPrint listonly
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
!ifdef INSTALL_PATH
|
||||
;Main executable.
|
||||
File "${INSTALL_PATH}\bin\tomahawk.exe"
|
||||
|
||||
File "${INSTALL_PATH}\bin\libqxtweb-standalone.dll"
|
||||
File "${INSTALL_PATH}\bin\libtomahawk_portfwd.dll"
|
||||
File "${INSTALL_PATH}\bin\libtomahawk_lastfm2.dll"
|
||||
File "${INSTALL_PATH}\bin\libtomahawklib.dll"
|
||||
File "${INSTALL_PATH}\lib\libtomahawk_sip*.dll"
|
||||
!endif
|
||||
!ifndef INSTALL_PATH
|
||||
;Main executable.
|
||||
File "${BUILD_PATH}\tomahawk.exe"
|
||||
|
||||
File "${BUILD_PATH}\libtomahawklib.dll"
|
||||
File "${BUILD_PATH}\libqxtweb-standalone.dll"
|
||||
File "${BUILD_PATH}\libtomahawk_portfwd.dll"
|
||||
File "${BUILD_PATH}\libtomahawk_lastfm2.dll"
|
||||
File "${BUILD_PATH}\libtomahawk_sip*.dll"
|
||||
!endif
|
||||
|
||||
;License & release notes.
|
||||
File "@CPACK_RESOURCE_FILE_LICENSE@"
|
||||
File /oname=NOTES.txt ${NSI_PATH}\RELEASE_NOTES.txt
|
||||
|
||||
;QT stuff:
|
||||
File "${QT_DLL_PATH}\QtCore4.dll"
|
||||
File "${QT_DLL_PATH}\QtGui4.dll"
|
||||
File "${QT_DLL_PATH}\QtNetwork4.dll"
|
||||
File "${QT_DLL_PATH}\QtSql4.dll"
|
||||
File "${QT_DLL_PATH}\QtXml4.dll"
|
||||
File "${QT_DLL_PATH}\QtWebKit4.dll"
|
||||
|
||||
;SQLite driver
|
||||
SetOutPath "$INSTDIR\sqldrivers"
|
||||
File "${SQLITE_DLL_PATH}\qsqlite4.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
;Image plugins
|
||||
SetOutPath "$INSTDIR\imageformats"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qgif4.dll"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qjpeg4.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
;Cygwin/c++ stuff
|
||||
;File "${MING_BIN}\cygmad-0.dll"
|
||||
;File "${MING_BIN}\libgcc_s_dw2-1.dll"
|
||||
;File "${MING_BIN}\mingwm10.dll"
|
||||
File "${MING_BIN}\libgcc_s_sjlj-1.dll"
|
||||
File "${MING_BIN}\libstdc++-6.dll"
|
||||
|
||||
;Phonon stuff
|
||||
|
||||
;Fix the phonon build to not use Dbus
|
||||
File "${QT_DLL_PATH}\QtDbus4.dll"
|
||||
File "${MING_BIN}\libdbus-1-3.dll"
|
||||
File "${MING_BIN}\dbus-daemon.exe"
|
||||
|
||||
File "${MING_BIN}\libphonon.dll"
|
||||
SetOutPath "$INSTDIR\phonon_backend"
|
||||
File "${MING_BIN}\phonon_backend\phonon_vlc.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
;VLC
|
||||
;SetOutPath "$INSTDIR\phonon_backend"
|
||||
File "${MING_BIN}\libvlc.dll"
|
||||
File "${MING_BIN}\libvlccore.dll"
|
||||
SetOutPath "$INSTDIR\plugins"
|
||||
File /r "${VLC_PLUGIN_PATH}\*.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
File "${MING_BIN}\libmad-0.dll" ; MP3
|
||||
File "${MING_BIN}\libFLAC-8.dll" ; FLAC
|
||||
File "${MING_BIN}\libogg-0.dll" ; OGG, FLAC
|
||||
File "${MING_BIN}\libvorbis-0.dll" ; OGG
|
||||
File "${MING_BIN}\libvorbisenc-2.dll" ; OGG
|
||||
|
||||
|
||||
|
||||
; Other
|
||||
File "${MING_BIN}\libqjson.dll"
|
||||
File "${MING_BIN}\libtag.dll"
|
||||
File "${MING_BIN}\libpng15-15.dll"
|
||||
File "${MING_BIN}\libjpeg-8.dll"
|
||||
File "${MING_BIN}\zlib1.dll"
|
||||
|
||||
File "${MING_BIN}\libechonest.dll"
|
||||
File "${MING_BIN}\libQTweetLib.dll"
|
||||
|
||||
; Jabber
|
||||
File "${MING_BIN}\libjreen.dll"
|
||||
File "${MING_BIN}\libqca.dll"
|
||||
SetOutPath "$INSTDIR\crypto"
|
||||
File "${MING_LIB}\qt4\plugins\crypto\libqca-ossl.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
File "${MING_BIN}\libssl-8.dll"
|
||||
File "${MING_BIN}\libcrypto-8.dll"
|
||||
|
||||
File "${MING_LIB}\libclucene-core.dll"
|
||||
File "${MING_LIB}\libclucene-shared.dll"
|
||||
|
||||
File "${MING_BIN}\libqtsparkle.dll"
|
||||
SectionEnd
|
||||
|
||||
SectionGroup "Shortcuts"
|
||||
|
||||
!ifdef OPTION_SECTION_SC_START_MENU
|
||||
${MementoSection} "Start Menu Program Group" SEC_START_MENU
|
||||
SectionIn 1 2
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint "Adding shortcuts for the Tomahawk program group to the Start Menu."
|
||||
SetDetailsPrint listonly
|
||||
SetShellVarContext all
|
||||
RMDir /r "$SMPROGRAMS\Tomahawk"
|
||||
CreateDirectory "$SMPROGRAMS\Tomahawk"
|
||||
CreateShortCut "$SMPROGRAMS\Tomahawk\LICENSE.lnk" "$INSTDIR\LICENSE.txt"
|
||||
CreateShortCut "$SMPROGRAMS\Tomahawk\Tomahawk.lnk" "$INSTDIR\tomahawk.exe"
|
||||
CreateShortCut "$SMPROGRAMS\Tomahawk\Release notes.lnk" "$INSTDIR\NOTES.txt"
|
||||
CreateShortCut "$SMPROGRAMS\Tomahawk\Uninstall.lnk" "$INSTDIR\uninstall.exe"
|
||||
SetShellVarContext current
|
||||
${MementoSectionEnd}
|
||||
!endif
|
||||
|
||||
!ifdef OPTION_SECTION_SC_DESKTOP
|
||||
${MementoSection} "Desktop Shortcut" SEC_DESKTOP
|
||||
SectionIn 1 2
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint "Creating Desktop Shortcuts"
|
||||
SetDetailsPrint listonly
|
||||
CreateShortCut "$DESKTOP\Tomahawk.lnk" "$INSTDIR\tomahawk.exe"
|
||||
${MementoSectionEnd}
|
||||
!endif
|
||||
|
||||
!ifdef OPTION_SECTION_SC_QUICK_LAUNCH
|
||||
${MementoSection} "Quick Launch Shortcut" SEC_QUICK_LAUNCH
|
||||
SectionIn 1 2
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint "Creating Quick Launch Shortcut"
|
||||
SetDetailsPrint listonly
|
||||
CreateShortCut "$QUICKLAUNCH\Tomahawk.lnk" "$INSTDIR\tomahawk.exe"
|
||||
${MementoSectionEnd}
|
||||
!endif
|
||||
|
||||
SectionGroupEnd
|
||||
|
||||
${MementoSectionDone}
|
||||
|
||||
; Installer section descriptions
|
||||
;--------------------------------
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_TOMAHAWK_PLAYER} "Tomahawk player essentials."
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_START_MENU} "Tomahawk program group."
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DESKTOP} "Desktop shortcut for Tomahawk."
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_QUICK_LAUNCH} "Quick Launch shortcut for Tomahawk."
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
|
||||
Section -post
|
||||
|
||||
;Uninstaller file.
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint "Writing Uninstaller"
|
||||
SetDetailsPrint listonly
|
||||
WriteUninstaller $INSTDIR\uninstall.exe
|
||||
|
||||
;Registry keys required for installer version handling and uninstaller.
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint "Writing Installer Registry Keys"
|
||||
SetDetailsPrint listonly
|
||||
|
||||
;Version numbers used to detect existing installation version for comparisson.
|
||||
WriteRegStr HKLM "Software\Tomahawk" "" $INSTDIR
|
||||
WriteRegDWORD HKLM "Software\Tomahawk" "VersionMajor" "${VER_MAJOR}"
|
||||
WriteRegDWORD HKLM "Software\Tomahawk" "VersionMinor" "${VER_MINOR}"
|
||||
WriteRegDWORD HKLM "Software\Tomahawk" "VersionRevision" "${REVISION}"
|
||||
WriteRegDWORD HKLM "Software\Tomahawk" "VersionBuild" "${VER_BUILD}"
|
||||
|
||||
;Add or Remove Programs entry.
|
||||
WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "UninstallString" '"$INSTDIR\Uninstall.exe"'
|
||||
WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "InstallLocation" "$INSTDIR"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "DisplayName" "Tomahawk"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "Publisher" "Tomahawk-player.org"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "DisplayIcon" "$INSTDIR\Uninstall.exe,0"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "DisplayVersion" "${VERSION}"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "VersionMajor" "${VER_MAJOR}"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "VersionMinor" "${VER_MINOR}.${REVISION}"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "URLInfoAbout" "http://tomahawk-player.org/"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "HelpLink" "http://tomahawk-player.org/"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "NoModify" "1"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "NoRepair" "1"
|
||||
|
||||
; Register tomahawk:// protocol handler
|
||||
WriteRegStr HKCR "tomahawk" "" "URL: Tomahawk Protocol"
|
||||
WriteRegStr HKCR "tomahawk\DefaultIcon" "" $INSTDIR\tomahawk.exe,1
|
||||
WriteRegStr HKCR "tomahawk\shell" "" "open"
|
||||
WriteRegStr HKCR "tomahawk\shell\open\command" "" '"$INSTDIR\tomahawk.exe" "%1"'
|
||||
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint "Finsihed."
|
||||
SectionEnd
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
# UNINSTALLER SECTION #
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
Var UnPageUserAppDataDialog
|
||||
Var UnPageUserAppDataCheckbox
|
||||
Var UnPageUserAppDataCheckbox_State
|
||||
Var UnPageUserAppDataEditBox
|
||||
|
||||
Function un.UnPageUserAppData
|
||||
!insertmacro MUI_HEADER_TEXT "Uninstall Tomahawk" "Remove Tomahawk's data folder from your computer."
|
||||
nsDialogs::Create /NOUNLOAD 1018
|
||||
Pop $UnPageUserAppDataDialog
|
||||
|
||||
${If} $UnPageUserAppDataDialog == error
|
||||
Abort
|
||||
${EndIf}
|
||||
|
||||
${NSD_CreateLabel} 0 0 100% 12u "Do you want to delete Tomahawk's data folder?"
|
||||
Pop $0
|
||||
|
||||
${NSD_CreateText} 0 13u 100% 12u "$LOCALAPPDATA\Tomahawk"
|
||||
Pop $UnPageUserAppDataEditBox
|
||||
SendMessage $UnPageUserAppDataEditBox ${EM_SETREADONLY} 1 0
|
||||
|
||||
${NSD_CreateLabel} 0 46u 100% 24u "Leave unchecked to keep the data folder for later use or check to delete the data folder."
|
||||
Pop $0
|
||||
|
||||
${NSD_CreateCheckbox} 0 71u 100% 8u "Yes, delete this data folder."
|
||||
Pop $UnPageUserAppDataCheckbox
|
||||
|
||||
nsDialogs::Show
|
||||
FunctionEnd
|
||||
|
||||
Function un.UnPageUserAppDataLeave
|
||||
${NSD_GetState} $UnPageUserAppDataCheckbox $UnPageUserAppDataCheckbox_State
|
||||
FunctionEnd
|
||||
|
||||
Section Uninstall
|
||||
IfFileExists "$INSTDIR\tomahawk.exe" tomahawk_installed
|
||||
MessageBox MB_YESNO "It does not appear that Tomahawk is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?" IDYES tomahawk_installed
|
||||
Abort "Uninstall aborted by user"
|
||||
tomahawk_installed:
|
||||
|
||||
;Delete registry keys.
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk"
|
||||
DeleteRegValue HKLM "Software\Tomahawk" "VersionBuild"
|
||||
DeleteRegValue HKLM "Software\Tomahawk" "VersionMajor"
|
||||
DeleteRegValue HKLM "Software\Tomahawk" "VersionMinor"
|
||||
DeleteRegValue HKLM "Software\Tomahawk" "VersionRevision"
|
||||
DeleteRegValue HKLM "Software\Tomahawk" ""
|
||||
DeleteRegKey HKLM "Software\Tomahawk"
|
||||
|
||||
DeleteRegKey HKCR "tomahawk"
|
||||
|
||||
;Start menu shortcuts.
|
||||
!ifdef OPTION_SECTION_SC_START_MENU
|
||||
SetShellVarContext all
|
||||
RMDir /r "$SMPROGRAMS\Tomahawk"
|
||||
SetShellVarContext current
|
||||
!endif
|
||||
|
||||
;Desktop shortcut.
|
||||
!ifdef OPTION_SECTION_SC_DESKTOP
|
||||
IfFileExists "$DESKTOP\Tomahawk.lnk" 0 +2
|
||||
Delete "$DESKTOP\Tomahawk.lnk"
|
||||
!endif
|
||||
|
||||
;Quick Launch shortcut.
|
||||
!ifdef OPTION_SECTION_SC_QUICK_LAUNCH
|
||||
IfFileExists "$QUICKLAUNCH\Tomahawk.lnk" 0 +2
|
||||
Delete "$QUICKLAUNCH\Tomahawk.lnk"
|
||||
!endif
|
||||
|
||||
;Remove all the Program Files.
|
||||
RMDir /r $INSTDIR
|
||||
|
||||
;Uninstall User Data if option is checked, otherwise skip.
|
||||
${If} $UnPageUserAppDataCheckbox_State == ${BST_CHECKED}
|
||||
RMDir /r "$LOCALAPPDATA\Tomahawk"
|
||||
${EndIf}
|
||||
|
||||
SetDetailsPrint textonly
|
||||
DetailPrint "Finsihed."
|
||||
SectionEnd
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
# NSIS Installer Event Handler Functions #
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
Function .onInit
|
||||
!insertmacro INSTALLOPTIONS_EXTRACT "NSIS.InstallOptions.ini"
|
||||
|
||||
;Remove Quick Launch option from Windows 7, as no longer applicable - usually.
|
||||
${IfNot} ${AtMostWinVista}
|
||||
SectionSetText ${SEC_QUICK_LAUNCH} "Quick Launch Shortcut (N/A)"
|
||||
SectionSetFlags ${SEC_QUICK_LAUNCH} ${SF_RO}
|
||||
SectionSetInstTypes ${SEC_QUICK_LAUNCH} 0
|
||||
${EndIf}
|
||||
|
||||
${MementoSectionRestore}
|
||||
|
||||
UAC_Elevate:
|
||||
UAC::RunElevated
|
||||
StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user?
|
||||
StrCmp 0 $0 0 UAC_Err ; Error?
|
||||
StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper?
|
||||
Quit
|
||||
|
||||
UAC_Err:
|
||||
MessageBox MB_ICONSTOP "Unable to elevate, error $0"
|
||||
Abort
|
||||
|
||||
UAC_ElevationAborted:
|
||||
Abort
|
||||
|
||||
UAC_Success:
|
||||
StrCmp 1 $3 +4 ;Admin?
|
||||
StrCmp 3 $1 0 UAC_ElevationAborted ;Try again?
|
||||
MessageBox MB_ICONSTOP "This installer requires admin access, try again"
|
||||
goto UAC_Elevate
|
||||
|
||||
;Prevent multiple instances.
|
||||
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "tomahawkInstaller") i .r1 ?e'
|
||||
Pop $R0
|
||||
StrCmp $R0 0 +3
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "The installer is already running."
|
||||
Abort
|
||||
|
||||
;Use available InstallLocation when possible. This is useful in the uninstaller
|
||||
;via re-install, which would otherwise use a default location - a bug.
|
||||
ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tomahawk" "InstallLocation"
|
||||
StrCmp $R0 "" SkipSetInstDir
|
||||
StrCpy $INSTDIR $R0
|
||||
SkipSetInstDir:
|
||||
|
||||
;Shutdown Tomahawk in case Add/Remove re-installer option used.
|
||||
Call EnsureTomahawkShutdown
|
||||
FunctionEnd
|
||||
|
||||
Function .onInstSuccess
|
||||
${MementoSectionSave}
|
||||
UAC::Unload ;Must call unload!
|
||||
FunctionEnd
|
||||
|
||||
Function .onInstFailed
|
||||
UAC::Unload ;Must call unload!
|
||||
FunctionEnd
|
||||
|
||||
##############################################################################
|
||||
# #
|
||||
# NSIS Uninstaller Event Handler Functions #
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
Function un.onInit
|
||||
UAC_Elevate:
|
||||
UAC::RunElevated
|
||||
StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user?
|
||||
StrCmp 0 $0 0 UAC_Err ; Error?
|
||||
StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper?
|
||||
Quit
|
||||
|
||||
UAC_Err:
|
||||
MessageBox MB_ICONSTOP "Unable to elevate, error $0"
|
||||
Abort
|
||||
|
||||
UAC_ElevationAborted:
|
||||
Abort
|
||||
|
||||
UAC_Success:
|
||||
StrCmp 1 $3 +4 ;Admin?
|
||||
StrCmp 3 $1 0 UAC_ElevationAborted ;Try again?
|
||||
MessageBox MB_ICONSTOP "This uninstaller requires admin access, try again"
|
||||
goto UAC_Elevate
|
||||
|
||||
;Prevent multiple instances.
|
||||
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "tomahawkUninstaller") i .r1 ?e'
|
||||
Pop $R0
|
||||
StrCmp $R0 0 +3
|
||||
MessageBox MB_OK|MB_ICONEXCLAMATION "This uninstaller is already running."
|
||||
Abort
|
||||
FunctionEnd
|
||||
|
||||
Function un.onUnInstSuccess
|
||||
UAC::Unload ;Must call unload!
|
||||
FunctionEnd
|
||||
|
||||
Function un.onUnInstFailed
|
||||
UAC::Unload ;Must call unload!
|
||||
FunctionEnd
|
21
CMakeModules/kwsysDateStamp.cmake
Normal file
@@ -0,0 +1,21 @@
|
||||
# Do not edit! Generated by kwsysDateStamp.py
|
||||
#=============================================================================
|
||||
# KWSys - Kitware System Library
|
||||
# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
#
|
||||
# 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.
|
||||
#=============================================================================
|
||||
|
||||
# KWSys version date year component. Format is CCYY.
|
||||
SET(KWSYS_DATE_STAMP_YEAR 2011)
|
||||
|
||||
# KWSys version date month component. Format is MM.
|
||||
SET(KWSYS_DATE_STAMP_MONTH 07)
|
||||
|
||||
# KWSys version date day component. Format is DD.
|
||||
SET(KWSYS_DATE_STAMP_DAY 06)
|
53
CPack.cmake
Normal file
@@ -0,0 +1,53 @@
|
||||
INCLUDE( InstallRequiredSystemLibraries )
|
||||
|
||||
SET( CPACK_PACKAGE_CONTACT "Dominik Schmidt <domme@tomahawk-player.org>" )
|
||||
|
||||
SET( CPACK_PACKAGE_FILE_NAME tomahawk-${TOMAHAWK_VERSION} ) # Package file name without extension. Also a directory of installer cmake-2.5.0-Linux-i686
|
||||
|
||||
# CPACK_GENERATOR CPack generator to be used STGZ;TGZ;TZ
|
||||
# CPACK_INCLUDE_TOPLEVEL_DIRECTORY Controls whether CPack adds a top-level directory, usually of the form ProjectName-Version-OS, to the top of package tree. 0 to disable, 1 to enable
|
||||
# CPACK_INSTALL_CMAKE_PROJECTS List of four values: Build directory, Project Name, Project Component, Directory in the package /home/andy/vtk/CMake-bin;CMake;ALL;/
|
||||
SET( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README" ) # File used as a description of a project /path/to/project/ReadMe.txt
|
||||
SET( CPACK_PACKAGE_DESCRIPTION_SUMMARY ${TOMAHAWK_DESCRIPTION_SUMMARY} ) # Description summary of a project
|
||||
# CPACK_PACKAGE_EXECUTABLES List of pairs of executables and labels. Used by the NSIS generator to create Start Menu shortcuts. ccmake;CMake
|
||||
SET( CPACK_PACKAGE_INSTALL_DIRECTORY ${TOMAHAWK_APPLICATION_NAME} ) # Installation directory on the target system -> C:\Program Files\fellody
|
||||
SET( CPACK_PACKAGE_INSTALL_REGISTRY_KEY ${TOMAHAWK_APPLICATION_NAME} ) # Registry key used when installing this project CMake 2.5.0
|
||||
SET( CPACK_PACKAGE_NAME ${TOMAHAWK_APPLICATION_NAME} ) # Package name, defaults to the project name
|
||||
SET( CPACK_PACKAGE_VENDOR ${TOMAHAWK_ORGANIZATION_NAME} ) # Package vendor name
|
||||
SET( CPACK_PACKAGE_VERSION_MAJOR ${TOMAHAWK_VERSION_MAJOR} )
|
||||
SET( CPACK_PACKAGE_VERSION_MINOR ${TOMAHAWK_VERSION_MINOR} )
|
||||
SET( CPACK_PACKAGE_VERSION_PATCH ${TOMAHAWK_VERSION_PATCH} )
|
||||
|
||||
# CPACK_SOURCE_GENERATOR List of generators used for the source package TGZ;TZ
|
||||
|
||||
SET( CPACK_SOURCE_GENERATOR TGZ )
|
||||
SET( CPACK_SOURCE_IGNORE_FILES "/\\\\.git/" ".*~$" ".kate-swp$" "/build_dir/" "/clang/" "/gcc/" "/build/" "/win/" ) # Pattern of files in the source tree that won't be packaged
|
||||
SET( CPACK_SOURCE_PACKAGE_FILE_NAME tomahawk-${TOMAHAWK_VERSION} ) # Name of the source package
|
||||
# CPACK_SOURCE_STRIP_FILES List of files in the source tree that will be stripped. Starting with CMake 2.6.0 CPACK_SOURCE_STRIP_FILES will be a boolean variable which enables stripping of all files (a list of files evaluates to TRUE in CMake, so this change is compatible).
|
||||
# CPACK_STRIP_FILES List of files to be stripped. Starting with CMake 2.6.0 CPACK_STRIP_FILES will be a boolean variable which enables stripping of all files (a list of files evaluates to TRUE in CMake, so this change is compatible). bin/ccmake;bin/cmake;bin/cpack;bin/ctest
|
||||
# CPACK_SYSTEM_NAME System name, defaults to the value of ${CMAKE_SYSTEM_NAME}. Linux-i686
|
||||
|
||||
# Advanced settings
|
||||
# CPACK_CMAKE_GENERATOR What CMake generator should be used if the project is CMake project. Defaults to the value of CMAKE_GENERATOR. Unix Makefiles
|
||||
SET( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt" ) # License file for the project, used by the STGZ, NSIS, and PackageMaker generators. /home/andy/vtk/CMake/Copyright.txt
|
||||
# CPACK_RESOURCE_FILE_README ReadMe file for the project, used by PackageMaker generator. /home/andy/vtk/CMake/Templates/CPack.GenericDescription.txt
|
||||
# CPACK_RESOURCE_FILE_WELCOME Welcome file for the project, used by PackageMaker generator. /home/andy/vtk/CMake/Templates/CPack.GenericWelcome.txt
|
||||
SET( CPACK_PACKAGE_VERSION ${TOMAHAWK_VERSION} )
|
||||
|
||||
SET( CPACK_TOPLEVEL_TAG "narf" ) # Directory for the installed files. - needed to provide anything to avoid an error# CPACK_INSTALL_COMMANDS Extra commands to install components.
|
||||
# CPACK_INSTALL_DIRECTORIES Extra directories to install.
|
||||
# CPACK_MONOLITHIC_INSTALL When set disables the component-based installer.
|
||||
# CPACK_PACKAGING_INSTALL_PREFIX Sets the default root that the generated package installs into, '/usr' is the default for the debian and redhat generators /usr/local
|
||||
|
||||
##
|
||||
# INSTALL DEPS
|
||||
##
|
||||
|
||||
|
||||
|
||||
# Set the options file that needs to be included inside CMakeCPackOptions.cmake
|
||||
#SET(QT_DIALOG_CPACK_OPTIONS_FILE ${CMake_BINARY_DIR}/Source/QtDialog/QtDialogCPack.cmake)
|
||||
configure_file("${CMAKE_SOURCE_DIR}/CPackOptions.cmake.in"
|
||||
"${CMAKE_BINARY_DIR}/CPackOptions.cmake" @ONLY)
|
||||
set(CPACK_PROJECT_CONFIG_FILE "${CMAKE_BINARY_DIR}/CPackOptions.cmake") # File included at cpack time, once per generator after setting CPACK_GENERATOR to the actual generator being used; allows per-generator setting of CPACK_* variables at cpack time. ${PROJECT_BINARY_DIR}/CPackOptions.cmake
|
||||
include(CPack)
|
73
CPackOptions.cmake.in
Normal file
@@ -0,0 +1,73 @@
|
||||
# This file is configured at cmake time, and loaded at cpack time.
|
||||
# To pass variables to cpack from cmake, they must be configured
|
||||
# in this file.
|
||||
|
||||
if(CPACK_GENERATOR MATCHES "NSIS")
|
||||
#SET(CPACK_NSIS_INSTALL_ROOT "@CPACK_NSIS_INSTALL_ROOT@")
|
||||
|
||||
# set the install/unistall icon used for the installer itself
|
||||
# There is a bug in NSI that does not handle full unix paths properly.
|
||||
#SET(CPACK_NSIS_MUI_ICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeLogo.ico")
|
||||
#SET(CPACK_NSIS_MUI_UNIICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeLogo.ico")
|
||||
# set the package header icon for MUI
|
||||
#SET(CPACK_PACKAGE_ICON "@CMake_SOURCE_DIR@/Utilities/Release\\CMakeInstall.bmp")
|
||||
# tell cpack to create links to the doc files
|
||||
#SET(CPACK_NSIS_MENU_LINKS
|
||||
# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-gui.html" "cmake-gui Help"
|
||||
# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html" "CMake Help"
|
||||
# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-properties.html"
|
||||
# "CMake Properties and Variables Help"
|
||||
# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/ctest.html" "CTest Help"
|
||||
# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-modules.html" "CMake Modules Help"
|
||||
# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake-commands.html" "CMake Commands Help"
|
||||
# "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cpack.html" "CPack Help"
|
||||
# "http://www.cmake.org" "CMake Web Site"
|
||||
# )
|
||||
# Use the icon from cmake-gui for add-remove programs
|
||||
#SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\cmake-gui.exe")
|
||||
#
|
||||
#SET(CPACK_NSIS_PACKAGE_NAME "@CPACK_NSIS_PACKAGE_NAME@")
|
||||
#SET(CPACK_NSIS_DISPLAY_NAME "@CPACK_NSIS_PACKAGE_NAME@, a cross-platform, open-source build system")
|
||||
#SET(CPACK_NSIS_HELP_LINK "http://www.cmake.org")
|
||||
#SET(CPACK_NSIS_URL_INFO_ABOUT "http://www.kitware.com")
|
||||
#SET(CPACK_NSIS_CONTACT @CPACK_PACKAGE_CONTACT@)
|
||||
#SET(CPACK_NSIS_MODIFY_PATH ON)
|
||||
|
||||
|
||||
|
||||
##### all options
|
||||
#CPACK_NSIS_MUI_ICON The icon file (.ico) for the generated install program. Both this and CPACK_NSIS_MUI_UNIICON need to set for this to have any effect. installer.ico
|
||||
#CPACK_NSIS_MUI_UNIICON The icon file (.ico) for the generated uninstall program. Both this and CPACK_NSIS_MUI_ICON need to set for this to have any effect. uninstaller.ico
|
||||
SET( CPACK_PACKAGE_ICON @CMAKE_SOURCE_DIR@/admin/win/nsi/installer.ico ) # A branding image that will be displayed on the top bar inside the installer. installer.bmp
|
||||
#CPACK_NSIS_EXTRA_INSTALL_COMMANDS Extra NSIS commands that will be added to the install Section. ExecWait '\\\"$INSTDIR\\\\vcredist_x86.exe\\\" /q:a'
|
||||
#CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS Extra NSIS commands that will be added to the uninstall Section.
|
||||
SET( CPACK_NSIS_COMPRESSOR "/SOLID lzma" ) # The arguments that will be passed to the NSIS SetCompressor command. /SOLID lzma
|
||||
#CPACK_NSIS_MODIFY_PATH If this is set to "ON", then an extra page will appear in the installer that will allow the user to choose whether the program directory should be added to the system PATH variable. ON
|
||||
#CPACK_NSIS_DISPLAY_NAME Undocumented. "${CPACK_PACKAGE_INSTALL_DIRECTORY} My Famous Project"
|
||||
#CPACK_NSIS_INSTALLED_ICON_NAME Set the icon used for the Windows "Add or Remove Programs" tool. "bin\\\\MyExecutable.exe"
|
||||
#CPACK_NSIS_HELP_LINK Adds link to registry. URI. "http:\\\\\\\\www.my-project-home-page.org"
|
||||
#CPACK_NSIS_URL_INFO_ABOUT Adds link to registry and the vendor in add/remove programs' "Click here for support information" in program entry links here. "http:\\\\\\\\www.my-personal-home-page.com"
|
||||
#CPACK_NSIS_CONTACT Adds link to add/remove programs' "Click here for support information" in program entry. "me@my-personal-home-page.com"
|
||||
#CPACK_NSIS_CREATE_ICONS_EXTRA Additional NSIS commands for creating start menu shortcuts. set(CPACK_NSIS_CREATE_ICONS "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${PROJECT_NAME}.lnk' '\$INSTDIR\\\\${PROJECT_NAME}.exe'")
|
||||
#CPACK_NSIS_DELETE_ICONS_EXTRA Undocumented. Possibly: Additional NSIS commands to uninstall start menu shortcuts.
|
||||
#CPACK_NSIS_MENU_LINKS Used to override the Start Menu links. "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/CMakeSetup.html" "CMakeSetup Help"
|
||||
#CPACK_NSIS_MUI_FINISHPAGE_RUN If used, will make it possible for user to choose (on an additional page, displayed at the end of the installation) to run intalled program. Should point to program name to run, seemingly without any sub-directories of the installation directory in case program installed in such sub-directories (but please check generated NSIS script if you can't make it work). "MyExecutable.exe"
|
||||
|
||||
endif(CPACK_GENERATOR MATCHES "NSIS")
|
||||
|
||||
## include the cpack options for qt dialog if they exisit
|
||||
## they might not if qt was not enabled for the build
|
||||
#INCLUDE("@QT_DIALOG_CPACK_OPTIONS_FILE@" OPTIONAL)
|
||||
|
||||
|
||||
#if("${CPACK_GENERATOR}" STREQUAL "PackageMaker")
|
||||
# if(CMAKE_PACKAGE_QTGUI)
|
||||
# set(CPACK_PACKAGE_DEFAULT_LOCATION "/Applications")
|
||||
# else(CMAKE_PACKAGE_QTGUI)
|
||||
# set(CPACK_PACKAGE_DEFAULT_LOCATION "/usr")
|
||||
# endif(CMAKE_PACKAGE_QTGUI)
|
||||
#endif("${CPACK_GENERATOR}" STREQUAL "PackageMaker")
|
||||
|
||||
|
||||
SET( CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@ )
|
||||
SET( CMAKE_BINARY_DIR @CMAKE_BINARY_DIR@ )
|
4
README
@@ -19,6 +19,10 @@ Detailed building instructions for OS X
|
||||
---------------------------------------
|
||||
See: http://wiki.tomahawk-player.org/mediawiki/index.php/Building_OS_X_Application_Bundle_on_Snow_Leopard_(10.6)
|
||||
|
||||
Doxygen Documentation
|
||||
---------------------
|
||||
See: http://dev.tomahawk-player.org/api/classes.html
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 7.3 KiB |
BIN
data/images/dashboard.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
BIN
data/images/post.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 13 KiB |
300
data/js/tomahawk.js
Normal file
@@ -0,0 +1,300 @@
|
||||
|
||||
// if run in phantomjs add fake Tomahawk environment
|
||||
if(window.Tomahawk === undefined)
|
||||
{
|
||||
alert("PHANTOMJS ENVIRONMENT");
|
||||
var Tomahawk = {
|
||||
fakeEnv: function()
|
||||
{
|
||||
return true;
|
||||
},
|
||||
resolverData: function()
|
||||
{
|
||||
return {
|
||||
scriptPath: function()
|
||||
{
|
||||
return "/home/tomahawk/resolver.js";
|
||||
}
|
||||
};
|
||||
},
|
||||
log: function( message )
|
||||
{
|
||||
console.log( message );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Tomahawk.resolver = {
|
||||
scriptPath: Tomahawk.resolverData().scriptPath
|
||||
};
|
||||
|
||||
Tomahawk.timestamp = function() {
|
||||
return Math.round( new Date()/1000 );
|
||||
}
|
||||
|
||||
Tomahawk.dumpResult = function( result ) {
|
||||
var results = result.results;
|
||||
Tomahawk.log("Dumping " + results.length + " results for query " + result.qid + "...");
|
||||
for(var i=0; i<results.length;i++)
|
||||
{
|
||||
var result = results[i];
|
||||
Tomahawk.log( result.artist + " - " + result.track + " | " + result.url );
|
||||
}
|
||||
|
||||
Tomahawk.log("Done.");
|
||||
}
|
||||
|
||||
// javascript part of Tomahawk-Object API
|
||||
Tomahawk.extend = function(object, members) {
|
||||
var F = function() {};
|
||||
F.prototype = object;
|
||||
var newObject = new F;
|
||||
|
||||
for(var key in members)
|
||||
{
|
||||
newObject[key] = members[key];
|
||||
}
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
|
||||
// Resolver BaseObject, inherit it to implement your own resolver
|
||||
var TomahawkResolver = {
|
||||
init: function()
|
||||
{
|
||||
},
|
||||
scriptPath: function()
|
||||
{
|
||||
return Tomahawk.resolverData().scriptPath;
|
||||
},
|
||||
getConfigUi: function()
|
||||
{
|
||||
return {};
|
||||
},
|
||||
getUserConfig: function()
|
||||
{
|
||||
var configJson = window.localStorage[ this.scriptPath() ];
|
||||
if( configJson === undefined )
|
||||
configJson = "{}";
|
||||
|
||||
var config = JSON.parse( configJson );
|
||||
|
||||
return config;
|
||||
},
|
||||
saveUserConfig: function()
|
||||
{
|
||||
var config = Tomahawk.resolverData().config;
|
||||
var configJson = JSON.stringify( config );
|
||||
|
||||
window.localStorage[ this.scriptPath() ] = configJson;
|
||||
},
|
||||
resolve: function( qid, artist, album, title )
|
||||
{
|
||||
return {
|
||||
qid: qid
|
||||
};
|
||||
},
|
||||
search: function( qid, searchString )
|
||||
{
|
||||
return this.resolve( qid, "", "", searchString );
|
||||
}
|
||||
};
|
||||
|
||||
/**** begin example implementation of a resolver ****/
|
||||
|
||||
|
||||
// implement the resolver
|
||||
/*
|
||||
* var DemoResolver = Tomahawk.extend(TomahawkResolver,
|
||||
* {
|
||||
* getSettings: function()
|
||||
* {
|
||||
* return {
|
||||
* name: "Demo Resolver",
|
||||
* weigth: 95,
|
||||
* timeout: 5,
|
||||
* limit: 10
|
||||
};
|
||||
},
|
||||
resolve: function( qid, artist, album, track )
|
||||
{
|
||||
return {
|
||||
qid: qid,
|
||||
results: [
|
||||
{
|
||||
artist: "Mokele",
|
||||
album: "You Yourself are Me Myself and I am in Love",
|
||||
track: "Hiding In Your Insides (php)",
|
||||
source: "Mokele.co.uk",
|
||||
url: "http://play.mokele.co.uk/music/Hiding%20In%20Your%20Insides.mp3",
|
||||
bitrate: 160,
|
||||
duration: 248,
|
||||
size: 4971780,
|
||||
score: 1.0,
|
||||
extension: "mp3",
|
||||
mimetype: "audio/mpeg"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// register the resolver
|
||||
Tomahawk.resolver.instance = DemoResolver;*/
|
||||
|
||||
/**** end example implementation of a resolver ****/
|
||||
|
||||
|
||||
// help functions
|
||||
|
||||
Tomahawk.valueForSubNode = function(node, tag)
|
||||
{
|
||||
if(node === undefined)
|
||||
throw new Error("Tomahawk.valueForSubnode: node is undefined!");
|
||||
|
||||
var element = node.getElementsByTagName(tag)[0];
|
||||
if( element === undefined )
|
||||
return undefined;
|
||||
|
||||
return element.textContent;
|
||||
};
|
||||
|
||||
|
||||
Tomahawk.syncRequest = function(url)
|
||||
{
|
||||
var xmlHttpRequest = new XMLHttpRequest();
|
||||
xmlHttpRequest.open('GET', url, false);
|
||||
xmlHttpRequest.send(null);
|
||||
return xmlHttpRequest.responseText;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Secure Hash Algorithm (SHA256)
|
||||
* http://www.webtoolkit.info/
|
||||
*
|
||||
* Original code by Angel Marin, Paul Johnston.
|
||||
*
|
||||
**/
|
||||
|
||||
Tomahawk.sha256=function(s){
|
||||
|
||||
var chrsz = 8;
|
||||
var hexcase = 0;
|
||||
|
||||
function safe_add (x, y) {
|
||||
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
|
||||
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
||||
return (msw << 16) | (lsw & 0xFFFF);
|
||||
}
|
||||
|
||||
function S (X, n) { return ( X >>> n ) | (X << (32 - n)); }
|
||||
function R (X, n) { return ( X >>> n ); }
|
||||
function Ch(x, y, z) { return ((x & y) ^ ((~x) & z)); }
|
||||
function Maj(x, y, z) { return ((x & y) ^ (x & z) ^ (y & z)); }
|
||||
function Sigma0256(x) { return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); }
|
||||
function Sigma1256(x) { return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); }
|
||||
function Gamma0256(x) { return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); }
|
||||
function Gamma1256(x) { return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); }
|
||||
|
||||
function core_sha256 (m, l) {
|
||||
var K = new Array(0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2);
|
||||
var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
|
||||
var W = new Array(64);
|
||||
var a, b, c, d, e, f, g, h, i, j;
|
||||
var T1, T2;
|
||||
|
||||
m[l >> 5] |= 0x80 << (24 - l % 32);
|
||||
m[((l + 64 >> 9) << 4) + 15] = l;
|
||||
|
||||
for ( var i = 0; i<m.length; i+=16 ) {
|
||||
a = HASH[0];
|
||||
b = HASH[1];
|
||||
c = HASH[2];
|
||||
d = HASH[3];
|
||||
e = HASH[4];
|
||||
f = HASH[5];
|
||||
g = HASH[6];
|
||||
h = HASH[7];
|
||||
|
||||
for ( var j = 0; j<64; j++) {
|
||||
if (j < 16) W[j] = m[j + i];
|
||||
else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
|
||||
|
||||
T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
|
||||
T2 = safe_add(Sigma0256(a), Maj(a, b, c));
|
||||
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = safe_add(d, T1);
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = safe_add(T1, T2);
|
||||
}
|
||||
|
||||
HASH[0] = safe_add(a, HASH[0]);
|
||||
HASH[1] = safe_add(b, HASH[1]);
|
||||
HASH[2] = safe_add(c, HASH[2]);
|
||||
HASH[3] = safe_add(d, HASH[3]);
|
||||
HASH[4] = safe_add(e, HASH[4]);
|
||||
HASH[5] = safe_add(f, HASH[5]);
|
||||
HASH[6] = safe_add(g, HASH[6]);
|
||||
HASH[7] = safe_add(h, HASH[7]);
|
||||
}
|
||||
return HASH;
|
||||
}
|
||||
|
||||
function str2binb (str) {
|
||||
var bin = Array();
|
||||
var mask = (1 << chrsz) - 1;
|
||||
for(var i = 0; i < str.length * chrsz; i += chrsz) {
|
||||
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
|
||||
}
|
||||
return bin;
|
||||
}
|
||||
|
||||
function Utf8Encode(string) {
|
||||
string = string.replace(/\r\n/g,"\n");
|
||||
var utftext = "";
|
||||
|
||||
for (var n = 0; n < string.length; n++) {
|
||||
|
||||
var c = string.charCodeAt(n);
|
||||
|
||||
if (c < 128) {
|
||||
utftext += String.fromCharCode(c);
|
||||
}
|
||||
else if((c > 127) && (c < 2048)) {
|
||||
utftext += String.fromCharCode((c >> 6) | 192);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
else {
|
||||
utftext += String.fromCharCode((c >> 12) | 224);
|
||||
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return utftext;
|
||||
}
|
||||
|
||||
function binb2hex (binarray) {
|
||||
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
|
||||
var str = "";
|
||||
for(var i = 0; i < binarray.length * 4; i++) {
|
||||
str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
|
||||
hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
s = Utf8Encode(s);
|
||||
return binb2hex(core_sha256(str2binb(s), s.length * chrsz));
|
||||
|
||||
}
|
18
data/sql/dbmigrate-24_to_25.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
-- Script to migate from db version 24 to 25.
|
||||
-- Added the social_attributes table.
|
||||
--
|
||||
-- Separate each command with %%
|
||||
|
||||
ALTER TABLE dynamic_playlist RENAME TO tmp_dynamic_playlist;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dynamic_playlist (
|
||||
guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
pltype TEXT, -- the generator type
|
||||
plmode INTEGER -- the mode of this playlist
|
||||
);
|
||||
|
||||
INSERT INTO dynamic_playlist( guid, pltype, plmode ) SELECT guid, pltype, plmode FROM tmp_dynamic_playlist;
|
||||
|
||||
DROP TABLE tmp_dynamic_playlist;
|
||||
|
||||
UPDATE settings SET v = '25' WHERE k == 'schema_version';
|
0
resource.qrc
Normal file
0
resources.prc
Normal file
@@ -96,5 +96,7 @@
|
||||
<file>./data/www/tomahawk_banner_small.png</file>
|
||||
<file>./data/sql/dbmigrate-22_to_23.sql</file>
|
||||
<file>./data/sql/dbmigrate-23_to_24.sql</file>
|
||||
<file>./data/sql/dbmigrate-24_to_25.sql</file>
|
||||
<file>./data/js/tomahawk.js</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -264,4 +264,5 @@ IF( UNIX AND NOT APPLE AND KDE4_INSTALLED ) #install protocol file
|
||||
ENDIF()
|
||||
INSTALL( FILES ${CMAKE_BINARY_DIR}/tomahawk.protocol DESTINATION ${PROTOCOL_INSTALL_DIR} )
|
||||
ENDIF()
|
||||
|
||||
#INCLUDE( "CPack.txt" )
|
||||
|
@@ -80,6 +80,7 @@ AudioControls::AudioControls( QWidget* parent )
|
||||
ui->volumeLowButton->setPixmap( RESPATH "images/volume-icon-muted.png" );
|
||||
ui->volumeHighButton->setPixmap( RESPATH "images/volume-icon-full.png" );
|
||||
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
|
||||
ui->loveButton->setCheckable( true );
|
||||
|
||||
ui->ownerLabel->setForegroundRole( QPalette::Dark );
|
||||
ui->metaDataArea->setStyleSheet( "QWidget#metaDataArea {\nborder-width: 4px;\nborder-image: url(" RESPATH "images/now-playing-panel.png) 4 4 4 4 stretch stretch; }" );
|
||||
@@ -151,7 +152,7 @@ AudioControls::AudioControls( QWidget* parent )
|
||||
connect( ui->artistTrackLabel, SIGNAL( clickedArtist() ), SLOT( onArtistClicked() ) );
|
||||
connect( ui->artistTrackLabel, SIGNAL( clickedTrack() ), SLOT( onTrackClicked() ) );
|
||||
connect( ui->albumLabel, SIGNAL( clickedAlbum() ), SLOT( onAlbumClicked() ) );
|
||||
connect( ui->loveButton, SIGNAL( clicked() ), SLOT( onLoveButtonClicked() ) );
|
||||
connect( ui->loveButton, SIGNAL( clicked( bool ) ), SLOT( onLoveButtonClicked( bool ) ) );
|
||||
|
||||
// <From AudioEngine>
|
||||
connect( AudioEngine::instance(), SIGNAL( loading( Tomahawk::result_ptr ) ), SLOT( onPlaybackLoading( Tomahawk::result_ptr ) ) );
|
||||
@@ -166,8 +167,8 @@ AudioControls::AudioControls( QWidget* parent )
|
||||
.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||
SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) );
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
@@ -217,20 +218,21 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result )
|
||||
trackInfo["artist"] = result->artist()->name();
|
||||
trackInfo["album"] = result->album()->name();
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo(
|
||||
s_acInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData;
|
||||
requestData.caller = s_acInfoIdentifier;
|
||||
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo );
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData )
|
||||
AudioControls::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
|
||||
{
|
||||
Q_UNUSED( input );
|
||||
Q_UNUSED( customData );
|
||||
|
||||
qDebug() << Q_FUNC_INFO << caller << type << s_acInfoIdentifier << Tomahawk::InfoSystem::InfoAlbumCoverArt;
|
||||
if ( caller != s_acInfoIdentifier || type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
|
||||
qDebug() << Q_FUNC_INFO << requestData.caller << requestData.type << s_acInfoIdentifier << Tomahawk::InfoSystem::InfoAlbumCoverArt;
|
||||
if ( requestData.caller != s_acInfoIdentifier || requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
|
||||
{
|
||||
qDebug() << "Info of wrong type or not with our identifier";
|
||||
return;
|
||||
@@ -242,13 +244,13 @@ AudioControls::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType ty
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !output.canConvert< Tomahawk::InfoSystem::InfoCustomData >() )
|
||||
if ( !output.canConvert< QVariantMap >() )
|
||||
{
|
||||
qDebug() << "Cannot convert fetched art from a QByteArray";
|
||||
return;
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >();
|
||||
QVariantMap returnedData = output.value< QVariantMap >();
|
||||
const QByteArray ba = returnedData["imgbytes"].toByteArray();
|
||||
if ( ba.length() )
|
||||
{
|
||||
@@ -282,7 +284,6 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result )
|
||||
ui->albumLabel->setResult( result );
|
||||
ui->ownerLabel->setText( result->friendlySource() );
|
||||
ui->coverImage->setPixmap( m_defaultCover );
|
||||
ui->loveButton->setVisible( true );
|
||||
|
||||
ui->timeLabel->setText( TomahawkUtils::timeToString( 0 ) );
|
||||
ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( result->duration() ) );
|
||||
@@ -298,6 +299,21 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result )
|
||||
ui->pauseButton->setVisible( true );
|
||||
ui->playPauseButton->setVisible( false );
|
||||
ui->playPauseButton->setEnabled( false );
|
||||
ui->loveButton->setEnabled( true );
|
||||
ui->loveButton->setVisible( true );
|
||||
|
||||
result->loadSocialActions();
|
||||
|
||||
if ( result->loved() )
|
||||
{
|
||||
ui->loveButton->setPixmap( RESPATH "images/loved.png" );
|
||||
ui->loveButton->setChecked( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
|
||||
ui->loveButton->setChecked( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -340,12 +356,13 @@ AudioControls::onPlaybackStopped()
|
||||
ui->timeLeftLabel->setText( "" );
|
||||
ui->coverImage->setPixmap( QPixmap() );
|
||||
ui->seekSlider->setVisible( false );
|
||||
ui->loveButton->setVisible( false );
|
||||
|
||||
ui->pauseButton->setVisible( false );
|
||||
ui->pauseButton->setEnabled( false );
|
||||
ui->playPauseButton->setEnabled( true );
|
||||
ui->playPauseButton->setVisible( true );
|
||||
ui->loveButton->setEnabled( false );
|
||||
ui->loveButton->setVisible( false );
|
||||
|
||||
/* m_pauseAction->setEnabled( false );
|
||||
m_playAction->setEnabled( true ); */
|
||||
@@ -489,18 +506,32 @@ AudioControls::onTrackClicked()
|
||||
|
||||
|
||||
void
|
||||
AudioControls::onLoveButtonClicked()
|
||||
AudioControls::onLoveButtonClicked( bool checked )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
|
||||
trackInfo["title"] = m_currentTrack->track();
|
||||
trackInfo["artist"] = m_currentTrack->artist()->name();
|
||||
trackInfo["album"] = m_currentTrack->album()->name();
|
||||
|
||||
if ( checked )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_acInfoIdentifier, Tomahawk::InfoSystem::InfoLove,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) );
|
||||
|
||||
DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ) );
|
||||
DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "true") );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
||||
ui->loveButton->setPixmap( RESPATH "images/loved.png" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_acInfoIdentifier, Tomahawk::InfoSystem::InfoUnLove,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) );
|
||||
|
||||
DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "false" ) );
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
||||
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -65,9 +65,9 @@ private slots:
|
||||
void onArtistClicked();
|
||||
void onAlbumClicked();
|
||||
void onTrackClicked();
|
||||
void onLoveButtonClicked();
|
||||
void onLoveButtonClicked( bool );
|
||||
|
||||
void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void infoSystemFinished( QString target );
|
||||
|
||||
private:
|
||||
|
@@ -251,6 +251,8 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="ImageButton" name="loveButton">
|
||||
<property name="sizePolicy">
|
||||
@@ -259,11 +261,29 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>love</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="ownerLabel">
|
||||
<property name="font">
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
|
||||
class DelegateConfigWrapper : public QDialog
|
||||
{
|
||||
@@ -39,6 +40,7 @@ public:
|
||||
v->addWidget( m_widget );
|
||||
|
||||
QDialogButtonBox* buttons = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this );
|
||||
m_okButton = buttons->button( QDialogButtonBox::Ok );
|
||||
connect( buttons, SIGNAL( clicked( QAbstractButton*) ), this, SLOT( closed( QAbstractButton* ) ) );
|
||||
connect( this, SIGNAL( rejected() ), this, SLOT( rejected() ) );
|
||||
v->addWidget( buttons );
|
||||
@@ -57,6 +59,11 @@ public:
|
||||
|
||||
}
|
||||
public slots:
|
||||
void toggleOkButton( bool dataError )
|
||||
{
|
||||
// if dataError is True we want to set the button enabled to false
|
||||
m_okButton->setEnabled( !dataError );
|
||||
}
|
||||
void closed( QAbstractButton* b )
|
||||
{
|
||||
// let the config widget live to see another day
|
||||
@@ -90,6 +97,7 @@ public slots:
|
||||
|
||||
private:
|
||||
QWidget* m_widget;
|
||||
QPushButton* m_okButton;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -22,8 +22,7 @@
|
||||
#ifdef ENABLE_HEADLESS
|
||||
|
||||
#define TOMAHAWK_APPLICATION QCoreApplication
|
||||
#define TOMAHAWK_HEADLESS
|
||||
#include <QApplication>>
|
||||
#include <QApplication>
|
||||
|
||||
#else
|
||||
|
||||
|
@@ -31,6 +31,7 @@ set( libSources
|
||||
viewpage.cpp
|
||||
viewmanager.cpp
|
||||
globalactionmanager.cpp
|
||||
contextMenu.cpp
|
||||
|
||||
sip/SipPlugin.cpp
|
||||
sip/SipHandler.cpp
|
||||
@@ -81,6 +82,7 @@ set( libSources
|
||||
database/databasecommand_addclientauth.cpp
|
||||
database/databasecommand_clientauthvalid.cpp
|
||||
database/databasecommand_socialaction.cpp
|
||||
database/databasecommand_loadsocialactions.cpp
|
||||
database/database.cpp
|
||||
|
||||
infosystem/infosystemcache.cpp
|
||||
@@ -169,7 +171,9 @@ set( libSources
|
||||
widgets/welcomewidget.cpp
|
||||
widgets/welcomeplaylistmodel.cpp
|
||||
widgets/overlaywidget.cpp
|
||||
widgets/HeaderLabel.cpp
|
||||
widgets/infowidgets/sourceinfowidget.cpp
|
||||
widgets/infowidgets/ArtistInfoWidget.cpp
|
||||
|
||||
kdsingleapplicationguard/kdsingleapplicationguard.cpp
|
||||
kdsingleapplicationguard/kdsharedmemorylocker.cpp
|
||||
@@ -191,9 +195,9 @@ set( libHeaders
|
||||
result.h
|
||||
source.h
|
||||
sourceplaylistinterface.h
|
||||
viewpage.h
|
||||
viewmanager.h
|
||||
globalactionmanager.h
|
||||
contextMenu.h
|
||||
|
||||
artist.h
|
||||
album.h
|
||||
@@ -249,6 +253,7 @@ set( libHeaders
|
||||
database/databasecommand_addclientauth.h
|
||||
database/databasecommand_clientauthvalid.h
|
||||
database/databasecommand_socialaction.h
|
||||
database/databasecommand_loadsocialactions.h
|
||||
|
||||
infosystem/infosystem.h
|
||||
infosystem/infosystemworker.h
|
||||
@@ -304,7 +309,6 @@ set( libHeaders
|
||||
|
||||
playlist/dynamic/DynamicPlaylist.h
|
||||
playlist/dynamic/DynamicControl.h
|
||||
playlist/dynamic/GeneratorFactory.h
|
||||
playlist/dynamic/GeneratorInterface.h
|
||||
playlist/dynamic/DynamicView.h
|
||||
playlist/dynamic/DynamicModel.h
|
||||
@@ -320,7 +324,6 @@ set( libHeaders
|
||||
playlist/dynamic/widgets/DynamicSetupWidget.h
|
||||
playlist/dynamic/widgets/LoadingSpinner.h
|
||||
|
||||
utils/tomahawkutils.h
|
||||
utils/querylabel.h
|
||||
utils/elidedlabel.h
|
||||
utils/animatedcounterlabel.h
|
||||
@@ -337,23 +340,31 @@ set( libHeaders
|
||||
widgets/welcomewidget.h
|
||||
widgets/welcomeplaylistmodel.h
|
||||
widgets/overlaywidget.h
|
||||
widgets/HeaderLabel.h
|
||||
widgets/infowidgets/sourceinfowidget.h
|
||||
widgets/infowidgets/ArtistInfoWidget.h
|
||||
|
||||
kdsingleapplicationguard/kdsingleapplicationguard.h
|
||||
kdsingleapplicationguard/kdsharedmemorylocker.h
|
||||
kdsingleapplicationguard/kdtoolsglobal.h
|
||||
kdsingleapplicationguard/kdlockedsharedmemorypointer.h
|
||||
)
|
||||
|
||||
set( libHeaders_NoMOC
|
||||
viewpage.h
|
||||
|
||||
infosystem/infoplugins/unix/imageconverter.h
|
||||
|
||||
playlist/dynamic/GeneratorInterface.h
|
||||
playlist/dynamic/GeneratorFactory.h
|
||||
|
||||
utils/tomahawkutils.h
|
||||
)
|
||||
|
||||
set( libUI ${libUI}
|
||||
widgets/playlisttypeselectordlg.ui
|
||||
widgets/newplaylistwidget.ui
|
||||
widgets/searchwidget.ui
|
||||
widgets/welcomewidget.ui
|
||||
widgets/infowidgets/sourceinfowidget.ui
|
||||
widgets/infowidgets/ArtistInfoWidget.ui
|
||||
playlist/topbar/topbar.ui
|
||||
playlist/infobar/infobar.ui
|
||||
)
|
||||
@@ -379,17 +390,21 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/.
|
||||
|
||||
IF( UNIX AND NOT APPLE )
|
||||
SET( libSources ${libSources}
|
||||
infosystem/infoplugins/win/gfwnotifyplugin.cpp
|
||||
infosystem/infoplugins/unix/fdonotifyplugin.cpp
|
||||
infosystem/infoplugins/unix/imageconverter.cpp )
|
||||
|
||||
SET( libHeaders ${libHeaders}
|
||||
infosystem/infoplugins/win/gfwnotifyplugin.h
|
||||
infosystem/infoplugins/unix/fdonotifyplugin.h
|
||||
infosystem/infoplugins/unix/imageconverter.h )
|
||||
ENDIF( UNIX AND NOT APPLE )
|
||||
|
||||
IF( WIN32 )
|
||||
SET( libSources ${libSources}
|
||||
infosystem/infoplugins/win/gfwnotifyplugin.cpp )
|
||||
|
||||
SET( libHeaders ${libHeaders}
|
||||
infosystem/infoplugins/win/gfwnotifyplugin.h )
|
||||
|
||||
SET( OS_SPECIFIC_LINK_LIBRARIES
|
||||
${OS_SPECIFIC_LINK_LIBRARIES}
|
||||
# System
|
||||
|
@@ -71,6 +71,8 @@ signals:
|
||||
void trackCountChanged( unsigned int tracks );
|
||||
void sourceTrackCountChanged( unsigned int tracks );
|
||||
|
||||
void nextTrackReady();
|
||||
|
||||
private slots:
|
||||
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
|
||||
|
||||
|
@@ -26,9 +26,27 @@
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
Artist::Artist() {}
|
||||
|
||||
Artist::~Artist() {}
|
||||
Artist::Artist()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Artist::~Artist()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
artist_ptr
|
||||
Artist::get( const QString& name, bool autoCreate )
|
||||
{
|
||||
int artid = Database::instance()->impl()->artistId( name, autoCreate );
|
||||
if ( artid < 1 )
|
||||
return artist_ptr();
|
||||
|
||||
return Artist::get( artid, name );
|
||||
}
|
||||
|
||||
|
||||
artist_ptr
|
||||
Artist::get( unsigned int id, const QString& name )
|
||||
|
@@ -36,6 +36,7 @@ class DLLEXPORT Artist : public QObject, public PlaylistInterface
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static artist_ptr get( const QString& name, bool autoCreate = false );
|
||||
static artist_ptr get( unsigned int id, const QString& name );
|
||||
Artist( unsigned int id, const QString& name );
|
||||
|
||||
@@ -71,6 +72,8 @@ signals:
|
||||
void trackCountChanged( unsigned int tracks );
|
||||
void sourceTrackCountChanged( unsigned int tracks );
|
||||
|
||||
void nextTrackReady();
|
||||
|
||||
private slots:
|
||||
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
|
||||
|
||||
|
@@ -22,10 +22,10 @@
|
||||
|
||||
#include "playlistinterface.h"
|
||||
#include "sourceplaylistinterface.h"
|
||||
#include "tomahawksettings.h"
|
||||
|
||||
#include "database/database.h"
|
||||
#include "database/databasecommand_logplayback.h"
|
||||
#include "infosystem/infosystem.h"
|
||||
#include "network/servent.h"
|
||||
|
||||
#include "album.h"
|
||||
@@ -51,6 +51,8 @@ AudioEngine::AudioEngine()
|
||||
, m_queue( 0 )
|
||||
, m_timeElapsed( 0 )
|
||||
, m_expectStop( false )
|
||||
, m_waitingOnNewTrack( false )
|
||||
, m_infoSystemConnected( false )
|
||||
{
|
||||
s_instance = this;
|
||||
qDebug() << "Init AudioEngine";
|
||||
@@ -74,17 +76,12 @@ AudioEngine::AudioEngine()
|
||||
// Since it's indendent, we'll set it to 75% since that's nicer
|
||||
setVolume( 75 );
|
||||
#endif
|
||||
|
||||
m_retryTimer.setInterval( 10000 );
|
||||
m_retryTimer.setSingleShot( false );
|
||||
connect( &m_retryTimer, SIGNAL( timeout() ), SLOT( loadNextTrack() ) );
|
||||
}
|
||||
|
||||
|
||||
AudioEngine::~AudioEngine()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
m_retryTimer.stop();
|
||||
m_mediaObject->stop();
|
||||
// stop();
|
||||
|
||||
@@ -133,18 +130,16 @@ AudioEngine::pause()
|
||||
|
||||
m_mediaObject->pause();
|
||||
emit paused();
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPaused, QVariant() );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPaused, QVariant() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::stop( bool sendNotification )
|
||||
AudioEngine::stop()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
m_mediaObject->stop();
|
||||
m_retryTimer.stop();
|
||||
|
||||
if ( m_playlist )
|
||||
m_playlist->reset();
|
||||
@@ -152,9 +147,19 @@ AudioEngine::stop( bool sendNotification )
|
||||
setCurrentTrack( Tomahawk::result_ptr() );
|
||||
emit stopped();
|
||||
|
||||
if ( sendNotification )
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowStopped, QVariant() );
|
||||
Tomahawk::InfoSystem::InfoTypeMap map;
|
||||
map[ Tomahawk::InfoSystem::InfoNowStopped ] = QVariant();
|
||||
|
||||
if ( m_waitingOnNewTrack )
|
||||
sendWaitingNotification();
|
||||
else if ( TomahawkSettings::instance()->verboseNotifications() )
|
||||
{
|
||||
QVariantMap stopInfo;
|
||||
stopInfo["message"] = QString( "Tomahawk is stopped." );
|
||||
map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< QVariantMap >( stopInfo );
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map );
|
||||
}
|
||||
|
||||
|
||||
@@ -232,6 +237,92 @@ AudioEngine::mute()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::sendWaitingNotification() const
|
||||
{
|
||||
QVariantMap retryInfo;
|
||||
retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track from this source." );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser,
|
||||
QVariant::fromValue< QVariantMap >( retryInfo ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::sendNowPlayingNotification()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( ! m_infoSystemConnected )
|
||||
{
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
m_infoSystemConnected = true;
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
|
||||
trackInfo["artist"] = m_currentTrack->album()->artist()->name();
|
||||
trackInfo["album"] = m_currentTrack->album()->name();
|
||||
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData;
|
||||
requestData.caller = s_aeInfoIdentifier;
|
||||
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo );
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( requestData.caller != s_aeInfoIdentifier ||
|
||||
requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << " not destined for us or wrong type, caller is " << requestData.caller << " and type is " << requestData.type;
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap playInfo;
|
||||
playInfo["message"] = QString( "Tomahawk is playing \"%1\" by %2 on album %3." )
|
||||
.arg( m_currentTrack->track() )
|
||||
.arg( m_currentTrack->artist()->name() )
|
||||
.arg( m_currentTrack->album()->name() );
|
||||
if ( !output.isNull() && output.isValid() )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << " output is valid";
|
||||
QVariantMap returnedData = output.value< QVariantMap >();
|
||||
const QByteArray ba = returnedData["imgbytes"].toByteArray();
|
||||
qDebug() << "ba.length = " << ba.length();
|
||||
if ( ba.length() )
|
||||
{
|
||||
QPixmap pm;
|
||||
pm.loadFromData( ba );
|
||||
playInfo["image"] = QVariant( pm.toImage() );
|
||||
}
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser,
|
||||
QVariant::fromValue< QVariantMap >( playInfo ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::infoSystemFinished( QString caller )
|
||||
{
|
||||
Q_UNUSED( caller );
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::onTrackAboutToFinish()
|
||||
{
|
||||
@@ -244,8 +335,6 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << thread() << result;
|
||||
|
||||
m_retryTimer.stop();
|
||||
|
||||
bool err = false;
|
||||
|
||||
{
|
||||
@@ -306,14 +395,17 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
|
||||
|
||||
trackInfo["title"] = m_currentTrack->track();
|
||||
trackInfo["artist"] = m_currentTrack->artist()->name();
|
||||
trackInfo["album"] = m_currentTrack->album()->name();
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPlaying,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) );
|
||||
|
||||
if ( TomahawkSettings::instance()->verboseNotifications() )
|
||||
sendNowPlayingNotification();
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier,
|
||||
Tomahawk::InfoSystem::InfoNowPlaying,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,6 +415,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
||||
return false;
|
||||
}
|
||||
|
||||
m_waitingOnNewTrack = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -331,8 +424,6 @@ AudioEngine::loadPreviousTrack()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
m_retryTimer.stop();
|
||||
|
||||
if ( !m_playlist )
|
||||
{
|
||||
stop();
|
||||
@@ -352,9 +443,6 @@ AudioEngine::loadNextTrack()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
bool wasRetrying = m_retryTimer.isActive();
|
||||
m_retryTimer.stop();
|
||||
|
||||
Tomahawk::result_ptr result;
|
||||
|
||||
if ( m_queue && m_queue->trackCount() )
|
||||
@@ -371,20 +459,9 @@ AudioEngine::loadNextTrack()
|
||||
loadTrack( result );
|
||||
else
|
||||
{
|
||||
stop( false );
|
||||
if ( m_playlist && m_playlist->retryMode() == Tomahawk::PlaylistInterface::Retry )
|
||||
{
|
||||
if ( !wasRetrying )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash retryInfo;
|
||||
retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will keep trying..." );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( retryInfo ) );
|
||||
}
|
||||
m_retryTimer.setInterval( m_playlist->retryInterval() );
|
||||
m_retryTimer.start();
|
||||
}
|
||||
m_waitingOnNewTrack = true;
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,19 +479,25 @@ AudioEngine::playItem( Tomahawk::PlaylistInterface* playlist, const Tomahawk::re
|
||||
|
||||
if ( !result.isNull() )
|
||||
loadTrack( result );
|
||||
else if ( m_playlist->retryMode() == PlaylistInterface::Retry )
|
||||
else if ( m_playlist && m_playlist->retryMode() == PlaylistInterface::Retry )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash retryInfo;
|
||||
retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will keep trying..." );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( retryInfo ) );
|
||||
m_retryTimer.setInterval( playlist->retryInterval() );
|
||||
m_retryTimer.start();
|
||||
m_waitingOnNewTrack = true;
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::playlistNextTrackReady()
|
||||
{
|
||||
if ( !m_waitingOnNewTrack )
|
||||
return;
|
||||
|
||||
m_waitingOnNewTrack = false;
|
||||
next();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::onAboutToFinish()
|
||||
{
|
||||
@@ -476,7 +559,12 @@ AudioEngine::setPlaylist( PlaylistInterface* playlist )
|
||||
{
|
||||
if ( m_playlist )
|
||||
m_playlist->reset();
|
||||
|
||||
m_playlist = playlist;
|
||||
|
||||
if ( m_playlist && m_playlist->object() && m_playlist->retryMode() == PlaylistInterface::Retry )
|
||||
connect( m_playlist->object(), SIGNAL( nextTrackReady() ), SLOT( playlistNextTrackReady() ) );
|
||||
|
||||
emit playlistChanged( playlist );
|
||||
}
|
||||
|
||||
@@ -500,7 +588,7 @@ AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
||||
bool
|
||||
AudioEngine::isHttpResult( const QString& url ) const
|
||||
{
|
||||
return url.startsWith( "http://" );
|
||||
return url.startsWith( "http://" ) || url.startsWith( "https://" );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -25,6 +25,8 @@
|
||||
#include <phonon/MediaObject>
|
||||
#include <phonon/AudioOutput>
|
||||
|
||||
#include "infosystem/infosystem.h"
|
||||
|
||||
#include "result.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
@@ -65,7 +67,7 @@ public slots:
|
||||
void playPause();
|
||||
void play();
|
||||
void pause();
|
||||
void stop( bool sendNotification = true );
|
||||
void stop();
|
||||
|
||||
void previous();
|
||||
void next();
|
||||
@@ -83,6 +85,11 @@ public slots:
|
||||
|
||||
void onTrackAboutToFinish();
|
||||
|
||||
void playlistNextTrackReady();
|
||||
|
||||
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void infoSystemFinished( QString caller );
|
||||
|
||||
signals:
|
||||
void loading( const Tomahawk::result_ptr& track );
|
||||
void started( const Tomahawk::result_ptr& track );
|
||||
@@ -115,6 +122,8 @@ private slots:
|
||||
private:
|
||||
bool isHttpResult( const QString& ) const;
|
||||
bool isLocalResult( const QString& ) const;
|
||||
void sendWaitingNotification() const;
|
||||
void sendNowPlayingNotification();
|
||||
|
||||
bool m_isPlayingHttp;
|
||||
QSharedPointer<QIODevice> m_input;
|
||||
@@ -130,8 +139,8 @@ private:
|
||||
|
||||
unsigned int m_timeElapsed;
|
||||
bool m_expectStop;
|
||||
|
||||
QTimer m_retryTimer;
|
||||
bool m_waitingOnNewTrack;
|
||||
bool m_infoSystemConnected;
|
||||
|
||||
static AudioEngine* s_instance;
|
||||
};
|
||||
|
218
src/libtomahawk/contextMenu.cpp
Normal file
@@ -0,0 +1,218 @@
|
||||
/* === 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 "contextMenu.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "globalactionmanager.h"
|
||||
#include "playlistview.h"
|
||||
#include "viewmanager.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
ContextMenu::ContextMenu( QWidget* parent )
|
||||
: QMenu( parent )
|
||||
{
|
||||
m_sigmap = new QSignalMapper( this );
|
||||
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( onTriggered( int ) ) );
|
||||
|
||||
m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContextMenu::clear()
|
||||
{
|
||||
QMenu::clear();
|
||||
|
||||
m_queries.clear();
|
||||
m_albums.clear();
|
||||
m_artists.clear();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
{
|
||||
if ( queries.isEmpty() )
|
||||
return;
|
||||
|
||||
QMenu::clear();
|
||||
m_queries.clear();
|
||||
m_queries << queries;
|
||||
|
||||
if ( m_supportedActions & ActionPlay && itemCount() == 1 )
|
||||
m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay );
|
||||
|
||||
if ( m_supportedActions & ActionQueue )
|
||||
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
|
||||
|
||||
//m_sigmap->setMapping( addAction( tr( "&Add to Playlist" ) ), ActionAddToPlaylist );
|
||||
|
||||
addSeparator();
|
||||
|
||||
if ( m_supportedActions & ActionCopyLink && itemCount() == 1 )
|
||||
m_sigmap->setMapping( addAction( tr( "Copy Track &Link" ) ), ActionCopyLink );
|
||||
|
||||
addSeparator();
|
||||
|
||||
if ( m_supportedActions & ActionDelete )
|
||||
m_sigmap->setMapping( addAction( queries.count() > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) ), ActionDelete );
|
||||
|
||||
foreach ( QAction* action, actions() )
|
||||
{
|
||||
connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContextMenu::setQuery( const Tomahawk::query_ptr& query )
|
||||
{
|
||||
QList<query_ptr> queries;
|
||||
queries << query;
|
||||
setQueries( queries );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContextMenu::setAlbums( const QList<Tomahawk::album_ptr>& albums )
|
||||
{
|
||||
if ( albums.isEmpty() )
|
||||
return;
|
||||
|
||||
QMenu::clear();
|
||||
m_albums.clear();
|
||||
m_albums << albums;
|
||||
|
||||
if ( m_supportedActions & ActionPlay && itemCount() == 1 )
|
||||
m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay );
|
||||
|
||||
if ( m_supportedActions & ActionQueue )
|
||||
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
|
||||
|
||||
//m_sigmap->setMapping( addAction( tr( "&Add to Playlist" ) ), ActionAddToPlaylist );
|
||||
|
||||
addSeparator();
|
||||
|
||||
/* if ( m_supportedActions & ActionCopyLink && itemCount() == 1 )
|
||||
m_sigmap->setMapping( addAction( tr( "Copy Album &Link" ) ), ActionCopyLink ); */
|
||||
|
||||
foreach ( QAction* action, actions() )
|
||||
{
|
||||
connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContextMenu::setAlbum( const Tomahawk::album_ptr& album )
|
||||
{
|
||||
QList<album_ptr> albums;
|
||||
albums << album;
|
||||
setAlbums( albums );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContextMenu::setArtists( const QList<Tomahawk::artist_ptr>& artists )
|
||||
{
|
||||
if ( artists.isEmpty() )
|
||||
return;
|
||||
|
||||
QMenu::clear();
|
||||
m_artists.clear();
|
||||
m_artists << artists;
|
||||
|
||||
if ( m_supportedActions & ActionPlay && itemCount() == 1 )
|
||||
m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay );
|
||||
|
||||
if ( m_supportedActions & ActionQueue )
|
||||
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
|
||||
|
||||
//m_sigmap->setMapping( addAction( tr( "&Add to Playlist" ) ), ActionAddToPlaylist );
|
||||
|
||||
addSeparator();
|
||||
|
||||
/* if ( m_supportedActions & ActionCopyLink && itemCount() == 1 )
|
||||
m_sigmap->setMapping( addAction( tr( "Copy Artist &Link" ) ), ActionCopyLink ); */
|
||||
|
||||
foreach ( QAction* action, actions() )
|
||||
{
|
||||
connect( action, SIGNAL( triggered() ), m_sigmap, SLOT( map() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContextMenu::setArtist( const Tomahawk::artist_ptr& artist )
|
||||
{
|
||||
QList<artist_ptr> artists;
|
||||
artists << artist;
|
||||
setArtists( artists );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContextMenu::onTriggered( int action )
|
||||
{
|
||||
switch ( action )
|
||||
{
|
||||
case ActionQueue:
|
||||
addToQueue();
|
||||
break;
|
||||
|
||||
case ActionCopyLink:
|
||||
copyLink();
|
||||
break;
|
||||
|
||||
default:
|
||||
emit triggered( action );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ContextMenu::addToQueue()
|
||||
{
|
||||
foreach ( const query_ptr& query, m_queries )
|
||||
{
|
||||
ViewManager::instance()->queue()->model()->append( query );
|
||||
}
|
||||
foreach ( const artist_ptr& artist, m_artists )
|
||||
{
|
||||
ViewManager::instance()->queue()->model()->append( artist );
|
||||
}
|
||||
foreach ( const album_ptr& album, m_albums )
|
||||
{
|
||||
ViewManager::instance()->queue()->model()->append( album );
|
||||
}
|
||||
|
||||
ViewManager::instance()->showQueue();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContextMenu::copyLink()
|
||||
{
|
||||
if ( m_queries.count() )
|
||||
{
|
||||
GlobalActionManager::instance()->copyToClipboard( m_queries.first() );
|
||||
}
|
||||
}
|
78
src/libtomahawk/contextMenu.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* === 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 CONTEXTMENU_H
|
||||
#define CONTEXTMENU_H
|
||||
|
||||
#include <QSignalMapper>
|
||||
#include <QMenu>
|
||||
|
||||
#include "typedefs.h"
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class DLLEXPORT ContextMenu : public QMenu
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum MenuActions
|
||||
{ ActionPlay = 1, ActionQueue = 2, ActionDelete = 4, ActionCopyLink = 8 };
|
||||
|
||||
explicit ContextMenu( QWidget* parent = 0 );
|
||||
|
||||
int supportedActions() const { return m_supportedActions; }
|
||||
void setSupportedActions( int actions ) { m_supportedActions = actions; }
|
||||
|
||||
void setQuery( const Tomahawk::query_ptr& query );
|
||||
void setQueries( const QList<Tomahawk::query_ptr>& queries );
|
||||
|
||||
void setArtist( const Tomahawk::artist_ptr& artist );
|
||||
void setArtists( const QList<Tomahawk::artist_ptr>& artists );
|
||||
|
||||
void setAlbum( const Tomahawk::album_ptr& album );
|
||||
void setAlbums( const QList<Tomahawk::album_ptr>& albums );
|
||||
|
||||
void clear();
|
||||
|
||||
unsigned int itemCount() const { return m_queries.count() + m_artists.count() + m_albums.count(); }
|
||||
|
||||
signals:
|
||||
void triggered( int action );
|
||||
|
||||
private slots:
|
||||
void onTriggered( int action );
|
||||
|
||||
void copyLink();
|
||||
void addToQueue();
|
||||
|
||||
private:
|
||||
QSignalMapper* m_sigmap;
|
||||
int m_supportedActions;
|
||||
|
||||
QList<Tomahawk::query_ptr> m_queries;
|
||||
QList<Tomahawk::artist_ptr> m_artists;
|
||||
QList<Tomahawk::album_ptr> m_albums;
|
||||
};
|
||||
|
||||
}; // ns
|
||||
|
||||
#endif
|
@@ -69,6 +69,8 @@ private slots:
|
||||
void setIsReadyTrue() { m_ready = true; }
|
||||
|
||||
private:
|
||||
DatabaseImpl* impl() const { return m_impl; }
|
||||
|
||||
bool m_ready;
|
||||
DatabaseImpl* m_impl;
|
||||
DatabaseWorker* m_workerRW;
|
||||
@@ -77,6 +79,8 @@ private:
|
||||
int m_maxConcurrentThreads;
|
||||
|
||||
static Database* s_instance;
|
||||
|
||||
friend class Tomahawk::Artist;
|
||||
};
|
||||
|
||||
#endif // DATABASE_H
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "databasecommand_deletedynamicplaylist.h"
|
||||
#include "databasecommand_setdynamicplaylistrevision.h"
|
||||
#include "databasecommand_socialaction.h"
|
||||
#include "databasecommand_loadsocialactions.h"
|
||||
|
||||
|
||||
DatabaseCommand::DatabaseCommand( QObject* parent )
|
||||
|
@@ -148,14 +148,16 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi )
|
||||
if( !source()->isLocal() )
|
||||
url = QString( "servent://%1\t%2" ).arg( source()->userName() ).arg( url );
|
||||
|
||||
bool isnew;
|
||||
artistid = dbi->artistId( artist, isnew );
|
||||
bool autoCreate = true;
|
||||
artistid = dbi->artistId( artist, autoCreate );
|
||||
if ( artistid < 1 )
|
||||
continue;
|
||||
trackid = dbi->trackId( artistid, track, isnew );
|
||||
autoCreate = true; // artistId overwrites autoCreate (reference)
|
||||
trackid = dbi->trackId( artistid, track, autoCreate );
|
||||
if ( trackid < 1 )
|
||||
continue;
|
||||
albumid = dbi->albumId( artistid, album, isnew );
|
||||
autoCreate = true; // trackId overwrites autoCreate (reference)
|
||||
albumid = dbi->albumId( artistid, album, autoCreate );
|
||||
|
||||
// Now add the association
|
||||
query_filejoin.bindValue( 0, fileid );
|
||||
|
@@ -0,0 +1,75 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christopher Reichert <creichert07@gmail.com>
|
||||
*
|
||||
* 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 "databasecommand_loadsocialactions.h"
|
||||
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include "database/database.h"
|
||||
#include "databaseimpl.h"
|
||||
#include "network/servent.h"
|
||||
#include "result.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
void
|
||||
DatabaseCommand_LoadSocialActions::exec( DatabaseImpl* dbi )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
Q_ASSERT( !source().isNull() );
|
||||
|
||||
TomahawkSqlQuery query = dbi->newquery();
|
||||
|
||||
QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id();
|
||||
|
||||
bool autoCreate = true;
|
||||
int artid = dbi->artistId( m_artist, autoCreate );
|
||||
if( artid < 1 )
|
||||
return;
|
||||
|
||||
autoCreate = true; // artistId overwrites autoCreate (reference)
|
||||
int trkid = dbi->trackId( artid, m_track, autoCreate );
|
||||
if( trkid < 1 )
|
||||
return;
|
||||
|
||||
QString whereToken;
|
||||
whereToken = QString( "WHERE id IS %1" ).arg( trkid );
|
||||
|
||||
QString sql = QString(
|
||||
"SELECT k, v, timestamp, source "
|
||||
"FROM social_attributes %1 "
|
||||
"ORDER BY timestamp ASC" ).arg( whereToken );
|
||||
|
||||
query.prepare( sql );
|
||||
query.exec();
|
||||
|
||||
QList< Tomahawk::SocialAction > allSocialActions;
|
||||
while ( query.next() ) {
|
||||
Tomahawk::SocialAction action;
|
||||
action.action = query.value( 0 ); // action
|
||||
action.value = query.value( 1 ); // comment
|
||||
action.timestamp = query.value( 2 ); // timestamp
|
||||
action.source = query.value( 3 ); // source
|
||||
|
||||
allSocialActions.append( action );
|
||||
}
|
||||
|
||||
m_result->setAllSocialActions( allSocialActions );
|
||||
}
|
||||
|
73
src/libtomahawk/database/databasecommand_loadsocialactions.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Christopher Reichert <creichert07@gmail.com>
|
||||
*
|
||||
* 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 DATABASECOMMAND_LOADSOCIALACTIONS_H
|
||||
#define DATABASECOMMAND_LOADSOCIALACTIONS_H
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QList>
|
||||
#include "database/databasecommand.h"
|
||||
|
||||
#include "sourcelist.h"
|
||||
#include "typedefs.h"
|
||||
#include "artist.h"
|
||||
#include "result.h"
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
|
||||
class DLLEXPORT DatabaseCommand_LoadSocialActions : public DatabaseCommand
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit DatabaseCommand_LoadSocialActions( QObject* parent = 0 )
|
||||
: DatabaseCommand( parent )
|
||||
{}
|
||||
|
||||
|
||||
explicit DatabaseCommand_LoadSocialActions( Tomahawk::Result* result, QObject* parent = 0 )
|
||||
: DatabaseCommand( parent ), m_result( result )
|
||||
{
|
||||
setSource( SourceList::instance()->getLocal() );
|
||||
setArtist( result->artist()->name() );
|
||||
setTrack( result->track() );
|
||||
}
|
||||
|
||||
virtual QString commandname() const { return "loadsocialactions"; }
|
||||
|
||||
virtual void exec( DatabaseImpl* );
|
||||
|
||||
QString artist() const { return m_artist; }
|
||||
void setArtist( const QString& s ) { m_artist = s; }
|
||||
|
||||
QString track() const { return m_track; }
|
||||
void setTrack( const QString& s ) { m_track = s; }
|
||||
|
||||
signals:
|
||||
void done( QList< Tomahawk::SocialAction >& allSocialActions );
|
||||
|
||||
private:
|
||||
Tomahawk::Result* m_result;
|
||||
QString m_artist;
|
||||
QString m_track;
|
||||
|
||||
};
|
||||
|
||||
#endif // DATABASECOMMAND_LOADSOCIALACTIONS_H
|
@@ -40,7 +40,7 @@ DatabaseCommand_LogPlayback::postCommitHook()
|
||||
|
||||
// do not auto resolve this track
|
||||
Tomahawk::query_ptr q = Tomahawk::Query::get( m_artist, m_track, QString() );
|
||||
q->setPlayedBy( source() );
|
||||
q->setPlayedBy( source(), m_playtime );
|
||||
|
||||
if ( m_action == Finished )
|
||||
{
|
||||
@@ -80,12 +80,13 @@ DatabaseCommand_LogPlayback::exec( DatabaseImpl* dbi )
|
||||
|
||||
query.bindValue( 0, srcid );
|
||||
|
||||
bool isnew;
|
||||
int artid = dbi->artistId( m_artist, isnew );
|
||||
bool autoCreate = true;
|
||||
int artid = dbi->artistId( m_artist, autoCreate );
|
||||
if( artid < 1 )
|
||||
return;
|
||||
|
||||
int trkid = dbi->trackId( artid, m_track, isnew );
|
||||
autoCreate = true; // artistId overwrites autoCreate (reference)
|
||||
int trkid = dbi->trackId( artid, m_track, autoCreate );
|
||||
if( trkid < 1 )
|
||||
return;
|
||||
|
||||
|
@@ -67,11 +67,11 @@ DatabaseCommand_PlaybackHistory::exec( DatabaseImpl* dbi )
|
||||
|
||||
if ( query.value( 3 ).toUInt() == 0 )
|
||||
{
|
||||
q->setPlayedBy( SourceList::instance()->getLocal() );
|
||||
q->setPlayedBy( SourceList::instance()->getLocal(), query.value( 1 ).toUInt() );
|
||||
}
|
||||
else
|
||||
{
|
||||
q->setPlayedBy( SourceList::instance()->get( query.value( 3 ).toUInt() ) );
|
||||
q->setPlayedBy( SourceList::instance()->get( query.value( 3 ).toUInt() ), query.value( 1 ).toUInt() );
|
||||
}
|
||||
|
||||
ql << q;
|
||||
|
@@ -51,12 +51,13 @@ DatabaseCommand_SocialAction::exec( DatabaseImpl* dbi )
|
||||
|
||||
QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id();
|
||||
|
||||
bool isnew;
|
||||
int artid = dbi->artistId( m_artist, isnew );
|
||||
bool autoCreate = true;
|
||||
int artid = dbi->artistId( m_artist, autoCreate );
|
||||
if( artid < 1 )
|
||||
return;
|
||||
|
||||
int trkid = dbi->trackId( artid, m_track, isnew );
|
||||
autoCreate = true; // artistId overwrites autoCreate (reference)
|
||||
int trkid = dbi->trackId( artid, m_track, autoCreate );
|
||||
if( trkid < 1 )
|
||||
return;
|
||||
|
||||
|
@@ -28,7 +28,17 @@
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
|
||||
/**
|
||||
* \class DatabaseCommand_SocialAction
|
||||
* \brief Database command used to write social actions to database.
|
||||
*
|
||||
* This Database command allows Tomahawk to write social actions to
|
||||
* the local database. These social actions can be interfaced with social
|
||||
* networking API's such as LastFm, Facebook, or Twitter to allow the user
|
||||
* to sync these actions with their accounts on these sites.
|
||||
*
|
||||
* \see DatabaseCommand_LoadSocialAction
|
||||
*/
|
||||
class DLLEXPORT DatabaseCommand_SocialAction : public DatabaseCommand
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -38,10 +48,24 @@ Q_PROPERTY( int timestamp READ timestamp WRITE setTimestamp )
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Default constructor for DatabaseCommand_SocialAction.
|
||||
*
|
||||
* Constructs an empty database command for a social action.
|
||||
*/
|
||||
explicit DatabaseCommand_SocialAction( QObject* parent = 0 )
|
||||
: DatabaseCommand( parent )
|
||||
{}
|
||||
|
||||
/**
|
||||
* \brief Overloaded constructor for DatabaseCommand_SocialAction.
|
||||
* \param result Pointer to a Tomahawk::Result.
|
||||
* \param action Name of the social action to be written to the database.
|
||||
* \param comment Comment associated with this social action.
|
||||
* \param parent Parent class.
|
||||
*
|
||||
* Constructor which creates a new database command for the specified social action.
|
||||
*/
|
||||
explicit DatabaseCommand_SocialAction( const Tomahawk::result_ptr& result, QString action, QString comment="", QObject* parent = 0 )
|
||||
: DatabaseCommand( parent ), m_result( result ), m_action( action )
|
||||
{
|
||||
@@ -53,26 +77,94 @@ public:
|
||||
setTimestamp( QDateTime::currentDateTime().toTime_t() );
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the name of this database command.
|
||||
* \return QString containing the database command name 'socialaction'.
|
||||
*/
|
||||
virtual QString commandname() const { return "socialaction"; }
|
||||
|
||||
virtual void exec( DatabaseImpl* );
|
||||
/**
|
||||
* \brief Executes the database command.
|
||||
* \param dbi Database instance.
|
||||
*
|
||||
* This method prepares an sql query to write this social action
|
||||
* into the local database.
|
||||
*/
|
||||
virtual void exec( DatabaseImpl* dbi );
|
||||
|
||||
/**
|
||||
* \brief Triggers a Database Sync.
|
||||
*/
|
||||
virtual void postCommitHook();
|
||||
|
||||
/**
|
||||
* \brief Returns the artist associated with this database command.
|
||||
* \return Name of the artist.
|
||||
* \see setArtist()
|
||||
*/
|
||||
QString artist() const { return m_artist; }
|
||||
|
||||
/**
|
||||
* \brief Sets the artist name for this database command.
|
||||
* \param s QString containing the artist name.
|
||||
* \see artist()
|
||||
*/
|
||||
void setArtist( const QString& s ) { m_artist = s; }
|
||||
|
||||
/**
|
||||
* \brief Returns the track name associated with this social action.
|
||||
* \return QString containing the track name.
|
||||
* \see setTrack()
|
||||
*/
|
||||
QString track() const { return m_track; }
|
||||
void setTrack( const QString& s ) { m_track = s; }
|
||||
|
||||
// key
|
||||
/**
|
||||
* \brief Sets the track name associated with this database command.
|
||||
* \param track QString containing the track name.
|
||||
* \see track()
|
||||
*/
|
||||
void setTrack( const QString& track ) { m_track = track; }
|
||||
|
||||
/**
|
||||
* \brief Returns the social action for this database command instance.
|
||||
* \return QString containing the action name.
|
||||
* \see setAction()
|
||||
*/
|
||||
QString action() const { return m_action; }
|
||||
|
||||
/**
|
||||
* \brief Sets the social actions
|
||||
* \param a QString containing action to be set in this class.
|
||||
* \see action()
|
||||
*/
|
||||
void setAction( QString a ) { m_action = a; }
|
||||
|
||||
// value
|
||||
/**
|
||||
* \brief Returns comment associated with this social action.
|
||||
* \return QString containing comment associated with this social action.
|
||||
* \see setComment()
|
||||
*/
|
||||
QString comment() const { return m_comment; }
|
||||
|
||||
/**
|
||||
* \brief Sets the comment associated with this social action.
|
||||
* \param com Comment associated with this social action.
|
||||
* \see comment()
|
||||
*/
|
||||
void setComment( const QString& com ) { m_comment = com; }
|
||||
|
||||
/**
|
||||
* \brief Returns the timestamp associated with this social action.
|
||||
* \return unsigned integer containing timestamp
|
||||
* \see setTimesetamp()
|
||||
*/
|
||||
int timestamp() const { return m_timestamp; }
|
||||
|
||||
/**
|
||||
* \brief Sets the timestamp associated with this social action.
|
||||
* \param ts unsigned integer associated with this social action.
|
||||
* \see timestamp()
|
||||
*/
|
||||
void setTimestamp( const int ts ) { m_timestamp = ts; }
|
||||
|
||||
private:
|
||||
|
@@ -38,7 +38,7 @@
|
||||
*/
|
||||
#include "schema.sql.h"
|
||||
|
||||
#define CURRENT_SCHEMA_VERSION 24
|
||||
#define CURRENT_SCHEMA_VERSION 25
|
||||
|
||||
|
||||
DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
|
||||
@@ -149,10 +149,10 @@ DatabaseImpl::updateSchema( int oldVersion )
|
||||
QStringList statements = sql.split( ";", QString::SkipEmptyParts );
|
||||
db.transaction();
|
||||
|
||||
foreach( const QString& sl, statements )
|
||||
foreach ( const QString& sl, statements )
|
||||
{
|
||||
QString s( sl.trimmed() );
|
||||
if( s.length() == 0 )
|
||||
if ( s.length() == 0 )
|
||||
continue;
|
||||
|
||||
qDebug() << "Executing:" << s;
|
||||
@@ -173,18 +173,18 @@ DatabaseImpl::updateSchema( int oldVersion )
|
||||
|
||||
QString path = QString( RESPATH "sql/dbmigrate-%1_to_%2.sql" ).arg( cur - 1 ).arg( cur );
|
||||
QFile script( path );
|
||||
if( !script.exists() || !script.open( QIODevice::ReadOnly ) )
|
||||
if ( !script.exists() || !script.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
qWarning() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade..";
|
||||
qWarning() << "Failed to find or open upgrade script from" << (cur-1) << "to" << cur << " (" << path << ")! Aborting upgrade...";
|
||||
return false;
|
||||
}
|
||||
|
||||
QString sql = QString::fromUtf8( script.readAll() ).trimmed();
|
||||
QStringList statements = sql.split( ";", QString::SkipEmptyParts );
|
||||
foreach( const QString& sql, statements )
|
||||
foreach ( const QString& sql, statements )
|
||||
{
|
||||
QString clean = cleanSql( sql ).trimmed();
|
||||
if( clean.isEmpty() )
|
||||
if ( clean.isEmpty() )
|
||||
continue;
|
||||
|
||||
qDebug() << "Executing upgrade statement:" << clean;
|
||||
@@ -224,7 +224,7 @@ DatabaseImpl::file( int fid )
|
||||
"WHERE file.id = file_join.file AND file.id = %1" )
|
||||
.arg( fid ) );
|
||||
|
||||
if( query.next() )
|
||||
if ( query.next() )
|
||||
{
|
||||
Tomahawk::source_ptr s;
|
||||
|
||||
@@ -266,10 +266,10 @@ DatabaseImpl::file( int fid )
|
||||
|
||||
|
||||
int
|
||||
DatabaseImpl::artistId( const QString& name_orig, bool& isnew )
|
||||
DatabaseImpl::artistId( const QString& name_orig, bool& autoCreate )
|
||||
{
|
||||
isnew = false;
|
||||
if( m_lastart == name_orig )
|
||||
bool isnew = false;
|
||||
if ( m_lastart == name_orig )
|
||||
return m_lastartid;
|
||||
|
||||
int id = 0;
|
||||
@@ -279,22 +279,24 @@ DatabaseImpl::artistId( const QString& name_orig, bool& isnew )
|
||||
query.prepare( "SELECT id FROM artist WHERE sortname = ?" );
|
||||
query.addBindValue( sortname );
|
||||
query.exec();
|
||||
if( query.next() )
|
||||
if ( query.next() )
|
||||
{
|
||||
id = query.value( 0 ).toInt();
|
||||
}
|
||||
if( id )
|
||||
if ( id )
|
||||
{
|
||||
m_lastart = name_orig;
|
||||
m_lastartid = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
if ( autoCreate )
|
||||
{
|
||||
// not found, insert it.
|
||||
query.prepare( "INSERT INTO artist(id,name,sortname) VALUES(NULL,?,?)" );
|
||||
query.addBindValue( name_orig );
|
||||
query.addBindValue( sortname );
|
||||
if( !query.exec() )
|
||||
if ( !query.exec() )
|
||||
{
|
||||
qDebug() << "Failed to insert artist:" << name_orig;
|
||||
return 0;
|
||||
@@ -304,6 +306,9 @@ DatabaseImpl::artistId( const QString& name_orig, bool& isnew )
|
||||
isnew = true;
|
||||
m_lastart = name_orig;
|
||||
m_lastartid = id;
|
||||
}
|
||||
|
||||
autoCreate = isnew;
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@@ -53,7 +53,7 @@ public:
|
||||
TomahawkSqlQuery newquery() { return TomahawkSqlQuery( db ); }
|
||||
QSqlDatabase& database() { return db; }
|
||||
|
||||
int artistId( const QString& name_orig, bool& isnew );
|
||||
int artistId( const QString& name_orig, bool& autoCreate );
|
||||
int trackId( int artistid, const QString& name_orig, bool& isnew );
|
||||
int albumId( int artistid, const QString& name_orig, bool& isnew );
|
||||
|
||||
|
@@ -106,7 +106,7 @@ CREATE TABLE IF NOT EXISTS playlist_revision (
|
||||
-- VALUES('revisionguid-11', 'dynamic_playlist-guid-2', '[]');
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dynamic_playlist (
|
||||
guid TEXT PRIMARY KEY,
|
||||
guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
|
||||
pltype TEXT, -- the generator type
|
||||
plmode INTEGER -- the mode of this playlist
|
||||
);
|
||||
@@ -282,4 +282,4 @@ CREATE TABLE IF NOT EXISTS settings (
|
||||
v TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
|
||||
INSERT INTO settings(k,v) VALUES('schema_version', '24');
|
||||
INSERT INTO settings(k,v) VALUES('schema_version', '25');
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
This file was automatically generated from ./schema.sql on Sun Jun 12 05:17:25 CEST 2011.
|
||||
This file was automatically generated from ./schema.sql on Fri Jun 24 09:10:23 CEST 2011.
|
||||
*/
|
||||
|
||||
static const char * tomahawk_schema_sql =
|
||||
@@ -76,7 +76,7 @@ static const char * tomahawk_schema_sql =
|
||||
" previous_revision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED"
|
||||
");"
|
||||
"CREATE TABLE IF NOT EXISTS dynamic_playlist ("
|
||||
" guid TEXT PRIMARY KEY,"
|
||||
" guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,"
|
||||
" pltype TEXT, "
|
||||
" plmode INTEGER "
|
||||
");"
|
||||
@@ -183,7 +183,7 @@ static const char * tomahawk_schema_sql =
|
||||
" k TEXT NOT NULL PRIMARY KEY,"
|
||||
" v TEXT NOT NULL DEFAULT ''"
|
||||
");"
|
||||
"INSERT INTO settings(k,v) VALUES('schema_version', '24');"
|
||||
"INSERT INTO settings(k,v) VALUES('schema_version', '25');"
|
||||
;
|
||||
|
||||
const char * get_tomahawk_sql()
|
||||
|
@@ -20,6 +20,10 @@
|
||||
#include <echonest/Artist.h>
|
||||
#include <echonest/ArtistTypes.h>
|
||||
|
||||
#include "utils/tomahawkutils.h"
|
||||
|
||||
#include <QNetworkConfiguration>
|
||||
|
||||
using namespace Tomahawk::InfoSystem;
|
||||
using namespace Echonest;
|
||||
|
||||
@@ -44,42 +48,55 @@ EchoNestPlugin::namChangedSlot( QNetworkAccessManager *nam )
|
||||
if( !nam )
|
||||
return;
|
||||
|
||||
m_nam = QWeakPointer< QNetworkAccessManager >( nam );
|
||||
Echonest::Config::instance()->setNetworkAccessManager( nam );
|
||||
QNetworkAccessManager* currNam = Echonest::Config::instance()->nam();
|
||||
TomahawkUtils::NetworkProxyFactory* oldProxyFactory = dynamic_cast< TomahawkUtils::NetworkProxyFactory* >( nam->proxyFactory() );
|
||||
|
||||
if ( !oldProxyFactory )
|
||||
{
|
||||
qDebug() << "Could not get old proxyFactory!";
|
||||
return;
|
||||
}
|
||||
|
||||
currNam->setConfiguration( nam->configuration() );
|
||||
currNam->setNetworkAccessible( nam->networkAccessible() );
|
||||
TomahawkUtils::NetworkProxyFactory* newProxyFactory = new TomahawkUtils::NetworkProxyFactory();
|
||||
newProxyFactory->setNoProxyHosts( oldProxyFactory->noProxyHosts() );
|
||||
newProxyFactory->setProxy( oldProxyFactory->proxy() );
|
||||
currNam->setProxyFactory( newProxyFactory );
|
||||
}
|
||||
|
||||
void
|
||||
EchoNestPlugin::getInfo(const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData)
|
||||
EchoNestPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
switch (type)
|
||||
switch ( requestData.type )
|
||||
{
|
||||
case Tomahawk::InfoSystem::InfoArtistBiography:
|
||||
return getArtistBiography(caller, input, customData);
|
||||
return getArtistBiography( requestId, requestData );
|
||||
case Tomahawk::InfoSystem::InfoArtistFamiliarity:
|
||||
return getArtistFamiliarity(caller, input, customData);
|
||||
return getArtistFamiliarity( requestId, requestData );
|
||||
case Tomahawk::InfoSystem::InfoArtistHotttness:
|
||||
return getArtistHotttnesss(caller, input, customData);
|
||||
return getArtistHotttnesss( requestId, requestData );
|
||||
case Tomahawk::InfoSystem::InfoArtistTerms:
|
||||
return getArtistTerms(caller, input, customData);
|
||||
return getArtistTerms( requestId, requestData );
|
||||
case Tomahawk::InfoSystem::InfoTrackEnergy:
|
||||
return getSongProfile(caller, input, customData, "energy");
|
||||
return getSongProfile( requestId, requestData, "energy" );
|
||||
case Tomahawk::InfoSystem::InfoMiscTopTerms:
|
||||
return getMiscTopTerms(caller, input, customData);
|
||||
return getMiscTopTerms( requestId, requestData );
|
||||
default:
|
||||
{
|
||||
emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData);
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EchoNestPlugin::getSongProfile(const QString &caller, const QVariant &input, const InfoCustomData &customData, const QString &item)
|
||||
EchoNestPlugin::getSongProfile( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData, const QString &item )
|
||||
{
|
||||
//WARNING: Totally not implemented yet
|
||||
Q_UNUSED( item );
|
||||
|
||||
if( !isValidTrackData( caller, input, customData ) )
|
||||
if( !isValidTrackData( requestId, requestData ) )
|
||||
return;
|
||||
|
||||
// Track track( input.toString() );
|
||||
@@ -91,74 +108,69 @@ EchoNestPlugin::getSongProfile(const QString &caller, const QVariant &input, con
|
||||
}
|
||||
|
||||
void
|
||||
EchoNestPlugin::getArtistBiography(const QString &caller, const QVariant &input, const InfoCustomData &customData)
|
||||
EchoNestPlugin::getArtistBiography( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
{
|
||||
if( !isValidArtistData( caller, input, customData ) )
|
||||
if( !isValidArtistData( requestId, requestData ) )
|
||||
return;
|
||||
|
||||
Echonest::Artist artist( input.toString() );
|
||||
Echonest::Artist artist( requestData.input.toString() );
|
||||
QNetworkReply *reply = artist.fetchBiographies();
|
||||
reply->setProperty("artist", QVariant::fromValue<Echonest::Artist>(artist));
|
||||
reply->setProperty( "input", input );
|
||||
m_replyMap[reply] = customData;
|
||||
m_callerMap[reply] = caller;
|
||||
connect(reply, SIGNAL(finished()), SLOT(getArtistBiographySlot()));
|
||||
reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) );
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
connect( reply, SIGNAL( finished() ), SLOT( getArtistBiographySlot() ) );
|
||||
}
|
||||
|
||||
void
|
||||
EchoNestPlugin::getArtistFamiliarity(const QString &caller, const QVariant &input, const InfoCustomData &customData)
|
||||
EchoNestPlugin::getArtistFamiliarity( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
{
|
||||
if( !isValidArtistData( caller, input, customData ) )
|
||||
if( !isValidArtistData( requestId, requestData ) )
|
||||
return;
|
||||
|
||||
qDebug() << "Fetching artist familiarity!" << input;
|
||||
Echonest::Artist artist( input.toString() );
|
||||
qDebug() << "Fetching artist familiarity!" << requestData.input;
|
||||
Echonest::Artist artist( requestData.input.toString() );
|
||||
QNetworkReply* reply = artist.fetchFamiliarity();
|
||||
reply->setProperty( "artist", QVariant::fromValue<Echonest::Artist>(artist));
|
||||
reply->setProperty( "input", input );
|
||||
m_replyMap[reply] = customData;
|
||||
m_callerMap[reply] = caller;
|
||||
connect(reply, SIGNAL(finished()), SLOT(getArtistFamiliaritySlot()));
|
||||
reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) );
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
connect( reply, SIGNAL( finished() ), SLOT( getArtistFamiliaritySlot() ) );
|
||||
}
|
||||
|
||||
void
|
||||
EchoNestPlugin::getArtistHotttnesss(const QString &caller, const QVariant &input, const InfoCustomData &customData)
|
||||
EchoNestPlugin::getArtistHotttnesss( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
{
|
||||
if( !isValidArtistData( caller, input, customData ) )
|
||||
if( !isValidArtistData( requestId, requestData ) )
|
||||
return;
|
||||
|
||||
Echonest::Artist artist( input.toString() );
|
||||
Echonest::Artist artist( requestData.input.toString() );
|
||||
QNetworkReply* reply = artist.fetchHotttnesss();
|
||||
reply->setProperty( "artist", QVariant::fromValue<Echonest::Artist>(artist));
|
||||
reply->setProperty( "input", input );
|
||||
m_replyMap[reply] = customData;
|
||||
m_callerMap[reply] = caller;
|
||||
connect(reply, SIGNAL(finished()), SLOT(getArtistHotttnesssSlot()));
|
||||
reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) );
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
connect( reply, SIGNAL( finished() ), SLOT( getArtistHotttnesssSlot() ) );
|
||||
}
|
||||
|
||||
void
|
||||
EchoNestPlugin::getArtistTerms(const QString &caller, const QVariant &input, const InfoCustomData &customData)
|
||||
EchoNestPlugin::getArtistTerms( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
{
|
||||
if( !isValidArtistData( caller, input, customData ) )
|
||||
if( !isValidArtistData( requestId, requestData ) )
|
||||
return;
|
||||
|
||||
Echonest::Artist artist( input.toString() );
|
||||
Echonest::Artist artist( requestData.input.toString() );
|
||||
QNetworkReply* reply = artist.fetchTerms( Echonest::Artist::Weight );
|
||||
reply->setProperty( "artist", QVariant::fromValue<Echonest::Artist>(artist));
|
||||
reply->setProperty( "input", input );
|
||||
m_replyMap[reply] = customData;
|
||||
m_callerMap[reply] = caller;
|
||||
connect(reply, SIGNAL(finished()), SLOT(getArtistTermsSlot()));
|
||||
reply->setProperty( "artist", QVariant::fromValue< Echonest::Artist >( artist ) );
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
connect( reply, SIGNAL( finished() ), SLOT( getArtistTermsSlot() ) );
|
||||
}
|
||||
|
||||
void
|
||||
EchoNestPlugin::getMiscTopTerms(const QString &caller, const QVariant &input, const InfoCustomData& customData)
|
||||
EchoNestPlugin::getMiscTopTerms( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
{
|
||||
Q_UNUSED( input );
|
||||
QNetworkReply* reply = Echonest::Artist::topTerms( 20 );
|
||||
m_replyMap[reply] = customData;
|
||||
m_callerMap[reply] = caller;
|
||||
connect( reply,SIGNAL(finished()), SLOT( getMiscTopSlot()));
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
connect( reply, SIGNAL( finished() ), SLOT( getMiscTopSlot() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -179,9 +191,10 @@ EchoNestPlugin::getArtistBiographySlot()
|
||||
biographyMap[biography.site()]["attribution"] = biography.license().url.toString();
|
||||
|
||||
}
|
||||
emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistBiography, reply->property( "input" ), QVariant::fromValue<Tomahawk::InfoSystem::InfoGenericMap>(biographyMap), m_replyMap[reply] );
|
||||
m_replyMap.remove(reply);
|
||||
m_callerMap.remove(reply);
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
emit info( reply->property( "requestId" ).toUInt(),
|
||||
requestData,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( biographyMap ) );
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
@@ -191,9 +204,10 @@ EchoNestPlugin::getArtistFamiliaritySlot()
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
|
||||
Echonest::Artist artist = artistFromReply( reply );
|
||||
qreal familiarity = artist.familiarity();
|
||||
emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistFamiliarity, reply->property( "input" ), familiarity, m_replyMap[reply] );
|
||||
m_replyMap.remove(reply);
|
||||
m_callerMap.remove(reply);
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
emit info( reply->property( "requestId" ).toUInt(),
|
||||
requestData,
|
||||
familiarity );
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
@@ -203,9 +217,10 @@ EchoNestPlugin::getArtistHotttnesssSlot()
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
|
||||
Echonest::Artist artist = artistFromReply( reply );
|
||||
qreal hotttnesss = artist.hotttnesss();
|
||||
emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistHotttness, reply->property( "input" ), hotttnesss, m_replyMap[reply] );
|
||||
m_replyMap.remove(reply);
|
||||
m_callerMap.remove(reply);
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
emit info( reply->property( "requestId" ).toUInt(),
|
||||
requestData,
|
||||
hotttnesss );
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
@@ -222,9 +237,10 @@ EchoNestPlugin::getArtistTermsSlot()
|
||||
termMap[ "frequency" ] = QString::number(term.frequency());
|
||||
termsMap[ term.name() ] = termMap;
|
||||
}
|
||||
emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoArtistTerms, reply->property( "input" ), QVariant::fromValue<Tomahawk::InfoSystem::InfoGenericMap>(termsMap), m_replyMap[reply] );
|
||||
m_replyMap.remove(reply);
|
||||
m_callerMap.remove(reply);
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
emit info( reply->property( "requestId" ).toUInt(),
|
||||
requestData,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ) );
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
@@ -240,57 +256,61 @@ EchoNestPlugin::getMiscTopSlot()
|
||||
termMap[ "frequency" ] = QString::number( term.frequency() );
|
||||
termsMap[ term.name().toLower() ] = termMap;
|
||||
}
|
||||
emit info( m_callerMap[reply], Tomahawk::InfoSystem::InfoMiscTopTerms, QVariant(), QVariant::fromValue<Tomahawk::InfoSystem::InfoGenericMap>(termsMap), m_replyMap[reply] );
|
||||
m_replyMap.remove(reply);
|
||||
m_callerMap.remove(reply);
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
emit info( reply->property( "requestId" ).toUInt(),
|
||||
requestData,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoGenericMap >( termsMap ) );
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
bool
|
||||
EchoNestPlugin::isValidArtistData(const QString &caller, const QVariant &input, const InfoCustomData &customData)
|
||||
EchoNestPlugin::isValidArtistData( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
{
|
||||
if (input.isNull() || !input.isValid() || !input.canConvert<QString>())
|
||||
if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QString >() )
|
||||
{
|
||||
emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData);
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return false;
|
||||
}
|
||||
QString artistName = input.toString();
|
||||
if (artistName.isEmpty() )
|
||||
QString artistName = requestData.input.toString();
|
||||
if ( artistName.isEmpty() )
|
||||
{
|
||||
emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData);
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
EchoNestPlugin::isValidTrackData(const QString &caller, const QVariant &input, const InfoCustomData &customData)
|
||||
EchoNestPlugin::isValidTrackData( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData )
|
||||
{
|
||||
if (input.isNull() || !input.isValid() || !input.canConvert<QString>())
|
||||
if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QString >() )
|
||||
{
|
||||
emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData);
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return false;
|
||||
}
|
||||
QString trackName = input.toString();
|
||||
if (trackName.isEmpty() )
|
||||
QString trackName = requestData.input.toString();
|
||||
if ( trackName.isEmpty() )
|
||||
{
|
||||
emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData);
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return false;
|
||||
}
|
||||
if (!customData.contains("artistName") ||
|
||||
customData["artistName"].toString().isEmpty())
|
||||
if ( !requestData.customData.contains( "artistName" ) || requestData.customData[ "artistName" ].toString().isEmpty() )
|
||||
{
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Artist
|
||||
EchoNestPlugin::artistFromReply(QNetworkReply* reply)
|
||||
EchoNestPlugin::artistFromReply( QNetworkReply* reply )
|
||||
{
|
||||
Echonest::Artist artist = reply->property("artist").value<Echonest::Artist>();
|
||||
try {
|
||||
artist.parseProfile(reply);
|
||||
artist.parseProfile( reply );
|
||||
} catch( const Echonest::ParseError& e ) {
|
||||
qWarning() << "Caught parser error from echonest!" << e.what();
|
||||
}
|
||||
return artist;
|
||||
}
|
||||
//
|
@@ -44,7 +44,7 @@ public:
|
||||
virtual ~EchoNestPlugin();
|
||||
|
||||
protected slots:
|
||||
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data )
|
||||
{
|
||||
@@ -53,28 +53,26 @@ protected slots:
|
||||
Q_UNUSED( data );
|
||||
}
|
||||
|
||||
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
||||
virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( requestId );
|
||||
Q_UNUSED( criteria );
|
||||
Q_UNUSED( caller );
|
||||
Q_UNUSED( type );
|
||||
Q_UNUSED( input );
|
||||
Q_UNUSED( customData );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
public slots:
|
||||
void namChangedSlot( QNetworkAccessManager *nam );
|
||||
|
||||
private:
|
||||
void getSongProfile( const QString &caller, const QVariant &input, const InfoCustomData &customData, const QString &item = QString() );
|
||||
void getArtistBiography ( const QString &caller, const QVariant &input, const InfoCustomData &customData );
|
||||
void getArtistFamiliarity( const QString &caller, const QVariant &input, const InfoCustomData &customData );
|
||||
void getArtistHotttnesss( const QString &caller, const QVariant &input, const InfoCustomData &customData );
|
||||
void getArtistTerms( const QString &caller, const QVariant &input, const InfoCustomData &customData );
|
||||
void getMiscTopTerms( const QString &caller, const QVariant &input, const InfoCustomData &customData );
|
||||
void getSongProfile( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData, const QString &item = QString() );
|
||||
void getArtistBiography( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
void getArtistFamiliarity( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
void getArtistHotttnesss( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
void getArtistTerms( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
void getMiscTopTerms( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
|
||||
bool isValidArtistData( const QString &caller, const QVariant &input, const InfoCustomData& customData );
|
||||
bool isValidTrackData( const QString &caller, const QVariant &input, const InfoCustomData& customData );
|
||||
bool isValidArtistData( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
bool isValidTrackData( uint requestId, const Tomahawk::InfoSystem::InfoRequestData &requestData );
|
||||
Echonest::Artist artistFromReply( QNetworkReply* );
|
||||
|
||||
private slots:
|
||||
@@ -83,11 +81,6 @@ private slots:
|
||||
void getArtistHotttnesssSlot();
|
||||
void getArtistTermsSlot();
|
||||
void getMiscTopSlot();
|
||||
|
||||
private:
|
||||
QHash< QNetworkReply*, InfoCustomData > m_replyMap;
|
||||
QHash< QNetworkReply*, QString > m_callerMap;
|
||||
QWeakPointer< QNetworkAccessManager > m_nam;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <QDir>
|
||||
#include <QSettings>
|
||||
#include <QCryptographicHash>
|
||||
#include <QNetworkConfiguration>
|
||||
|
||||
#include "album.h"
|
||||
#include "typedefs.h"
|
||||
@@ -45,8 +46,8 @@ LastFmPlugin::LastFmPlugin()
|
||||
: InfoPlugin()
|
||||
, m_scrobbler( 0 )
|
||||
{
|
||||
m_supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages << InfoLove;
|
||||
m_supportedPushTypes << InfoSubmitScrobble << InfoSubmitNowPlaying << InfoLove;
|
||||
m_supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages << InfoArtistSimilars << InfoArtistSongs;
|
||||
m_supportedPushTypes << InfoSubmitScrobble << InfoSubmitNowPlaying << InfoLove << InfoUnLove;
|
||||
|
||||
/*
|
||||
Your API Key is 7194b85b6d1f424fe1668173a78c0c4a
|
||||
@@ -93,39 +94,64 @@ void
|
||||
LastFmPlugin::namChangedSlot( QNetworkAccessManager *nam )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if( !nam )
|
||||
|
||||
if ( !nam )
|
||||
return;
|
||||
|
||||
m_nam = QWeakPointer< QNetworkAccessManager >( nam );
|
||||
QNetworkAccessManager* currNam = lastfm::nam();
|
||||
TomahawkUtils::NetworkProxyFactory* oldProxyFactory = dynamic_cast< TomahawkUtils::NetworkProxyFactory* >( nam->proxyFactory() );
|
||||
|
||||
if ( !oldProxyFactory )
|
||||
{
|
||||
qDebug() << "Could not get old proxyFactory!";
|
||||
return;
|
||||
}
|
||||
|
||||
currNam->setConfiguration( nam->configuration() );
|
||||
currNam->setNetworkAccessible( nam->networkAccessible() );
|
||||
TomahawkUtils::NetworkProxyFactory* newProxyFactory = new TomahawkUtils::NetworkProxyFactory();
|
||||
newProxyFactory->setNoProxyHosts( oldProxyFactory->noProxyHosts() );
|
||||
newProxyFactory->setProxy( oldProxyFactory->proxy() );
|
||||
currNam->setProxyFactory( newProxyFactory );
|
||||
//FIXME: on Mac/Win as liblastfm's network access manager also sets its overriding application proxy
|
||||
//may have to do a QNetworkProxy::setApplicationProxy and clobber our own factory to override it
|
||||
settingsChanged(); // to get the scrobbler set up
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData )
|
||||
LastFmPlugin::dataError( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
emit info( caller, type, input, QVariant(), customData );
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
||||
LastFmPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
switch ( type )
|
||||
switch ( requestData.type )
|
||||
{
|
||||
case InfoArtistImages:
|
||||
fetchArtistImages( caller, type, input, customData );
|
||||
fetchArtistImages( requestId, requestData );
|
||||
break;
|
||||
|
||||
case InfoAlbumCoverArt:
|
||||
fetchCoverArt( caller, type, input, customData );
|
||||
fetchCoverArt( requestId, requestData );
|
||||
break;
|
||||
|
||||
case InfoArtistSimilars:
|
||||
fetchSimilarArtists( requestId, requestData );
|
||||
break;
|
||||
|
||||
case InfoArtistSongs:
|
||||
fetchTopTracks( requestId, requestData );
|
||||
break;
|
||||
|
||||
default:
|
||||
dataError( caller, type, input, customData );
|
||||
dataError( requestId, requestData );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +172,8 @@ LastFmPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoTy
|
||||
break;
|
||||
|
||||
case InfoLove:
|
||||
sendLoveSong( input );
|
||||
case InfoUnLove:
|
||||
sendLoveSong( type, input );
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -171,7 +198,6 @@ LastFmPlugin::nowPlaying( const QVariant &input )
|
||||
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) || !hash.contains( "duration" ) )
|
||||
return;
|
||||
|
||||
qDebug() << "LastFmPlugin::nowPlaying valid criteria hash";
|
||||
m_track = lastfm::MutableTrack();
|
||||
m_track.stamp();
|
||||
|
||||
@@ -201,7 +227,7 @@ LastFmPlugin::scrobble()
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::sendLoveSong( QVariant input )
|
||||
LastFmPlugin::sendLoveSong( const InfoType type, QVariant input )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
@@ -224,23 +250,77 @@ LastFmPlugin::sendLoveSong( QVariant input )
|
||||
bool ok;
|
||||
track.setDuration( hash["duration"].toUInt( &ok ) );
|
||||
track.setSource( lastfm::Track::Player );
|
||||
|
||||
if ( type == Tomahawk::InfoSystem::InfoLove )
|
||||
{
|
||||
track.love();
|
||||
}
|
||||
else if ( type == Tomahawk::InfoSystem::InfoUnLove )
|
||||
{
|
||||
track.unlove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData )
|
||||
LastFmPlugin::fetchSimilarArtists( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
||||
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
||||
{
|
||||
dataError( caller, type, input, customData );
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
}
|
||||
InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
if ( !hash.contains( "artist" ) )
|
||||
{
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
|
||||
criteria["artist"] = hash["artist"];
|
||||
|
||||
emit getCachedInfo( requestId, criteria, 2419200000, requestData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::fetchTopTracks( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
||||
{
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
}
|
||||
InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
if ( !hash.contains( "artist" ) )
|
||||
{
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
|
||||
criteria["artist"] = hash["artist"];
|
||||
|
||||
emit getCachedInfo( requestId, criteria, 2419200000, requestData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::fetchCoverArt( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
||||
{
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
}
|
||||
InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
if ( !hash.contains( "artist" ) || !hash.contains( "album" ) )
|
||||
{
|
||||
dataError( caller, type, input, customData );
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -248,47 +328,69 @@ LastFmPlugin::fetchCoverArt( const QString &caller, const InfoType type, const Q
|
||||
criteria["artist"] = hash["artist"];
|
||||
criteria["album"] = hash["album"];
|
||||
|
||||
emit getCachedInfo( criteria, 2419200000, caller, type, input, customData );
|
||||
emit getCachedInfo( requestId, criteria, 2419200000, requestData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::fetchArtistImages( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData )
|
||||
LastFmPlugin::fetchArtistImages( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
||||
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
||||
{
|
||||
dataError( caller, type, input, customData );
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
}
|
||||
InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
if ( !hash.contains( "artist" ) )
|
||||
{
|
||||
dataError( caller, type, input, customData );
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
|
||||
criteria["artist"] = hash["artist"];
|
||||
|
||||
emit getCachedInfo( criteria, 2419200000, caller, type, input, customData );
|
||||
emit getCachedInfo( requestId, criteria, 2419200000, requestData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::notInCacheSlot( const QHash<QString, QString> criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
||||
LastFmPlugin::notInCacheSlot( uint requestId, QHash<QString, QString> criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << Q_FUNC_INFO << " for requestId " << requestId;
|
||||
|
||||
if ( m_nam.isNull() )
|
||||
if ( !lastfm::nam() )
|
||||
{
|
||||
qDebug() << "Have a null QNAM, uh oh";
|
||||
emit info( caller, type, input, QVariant(), customData );
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( type )
|
||||
switch ( requestData.type )
|
||||
{
|
||||
case InfoArtistSimilars:
|
||||
{
|
||||
lastfm::Artist a( criteria["artist"] );
|
||||
QNetworkReply* reply = a.getSimilar();
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
|
||||
connect( reply, SIGNAL( finished() ), SLOT( similarArtistsReturned() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
case InfoArtistSongs:
|
||||
{
|
||||
lastfm::Artist a( criteria["artist"] );
|
||||
QNetworkReply* reply = a.getTopTracks();
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
|
||||
connect( reply, SIGNAL( finished() ), SLOT( topTracksReturned() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
case InfoAlbumCoverArt:
|
||||
{
|
||||
QString artistName = criteria["artist"];
|
||||
@@ -296,11 +398,9 @@ LastFmPlugin::notInCacheSlot( const QHash<QString, QString> criteria, const QStr
|
||||
|
||||
QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=album.imageredirect&artist=%1&album=%2&autocorrect=1&size=large&api_key=7a90f6672a04b809ee309af169f34b8b";
|
||||
QNetworkRequest req( imgurl.arg( artistName ).arg( albumName ) );
|
||||
QNetworkReply* reply = m_nam.data()->get( req );
|
||||
reply->setProperty( "customData", QVariant::fromValue<Tomahawk::InfoSystem::InfoCustomData>( customData ) );
|
||||
reply->setProperty( "origData", input );
|
||||
reply->setProperty( "caller", caller );
|
||||
reply->setProperty( "type", (uint)(type) );
|
||||
QNetworkReply* reply = lastfm::nam()->get( req );
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
|
||||
connect( reply, SIGNAL( finished() ), SLOT( coverArtReturned() ) );
|
||||
return;
|
||||
@@ -310,13 +410,11 @@ LastFmPlugin::notInCacheSlot( const QHash<QString, QString> criteria, const QStr
|
||||
{
|
||||
QString artistName = criteria["artist"];
|
||||
|
||||
QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=artist.imageredirect&artist=%1&autocorrect=1&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b";
|
||||
QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=artist.imageredirect&artist=%1&autocorrect=1&size=large&api_key=7a90f6672a04b809ee309af169f34b8b";
|
||||
QNetworkRequest req( imgurl.arg( artistName ) );
|
||||
QNetworkReply* reply = m_nam.data()->get( req );
|
||||
reply->setProperty( "customData", QVariant::fromValue<Tomahawk::InfoSystem::InfoCustomData>( customData ) );
|
||||
reply->setProperty( "origData", input );
|
||||
reply->setProperty( "caller", caller );
|
||||
reply->setProperty( "type", (uint)(type) );
|
||||
QNetworkReply* reply = lastfm::nam()->get( req );
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
|
||||
connect( reply, SIGNAL( finished() ), SLOT( artistImagesReturned() ) );
|
||||
return;
|
||||
@@ -325,13 +423,78 @@ LastFmPlugin::notInCacheSlot( const QHash<QString, QString> criteria, const QStr
|
||||
default:
|
||||
{
|
||||
qDebug() << "Couldn't figure out what to do with this type of request after cache miss";
|
||||
emit info( caller, type, input, QVariant(), customData );
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::similarArtistsReturned()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
|
||||
|
||||
QMap< int, QString > similarArtists = lastfm::Artist::getSimilar( reply );
|
||||
QStringList al;
|
||||
QStringList sl;
|
||||
|
||||
foreach ( const QString& a, similarArtists.values() )
|
||||
{
|
||||
qDebug() << "Got sim-artist:" << a;
|
||||
al << a;
|
||||
}
|
||||
|
||||
QVariantMap returnedData;
|
||||
returnedData["artists"] = al;
|
||||
returnedData["score"] = sl;
|
||||
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
|
||||
emit info(
|
||||
reply->property( "requestId" ).toUInt(),
|
||||
requestData,
|
||||
returnedData
|
||||
);
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash>();
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
|
||||
criteria["artist"] = origData["artist"];
|
||||
emit updateCache( criteria, 2419200000, requestData.type, returnedData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::topTracksReturned()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
|
||||
|
||||
QStringList topTracks = lastfm::Artist::getTopTracks( reply );
|
||||
foreach ( const QString& t, topTracks )
|
||||
{
|
||||
qDebug() << "Got top-track:" << t;
|
||||
}
|
||||
|
||||
QVariantMap returnedData;
|
||||
returnedData["tracks"] = topTracks;
|
||||
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
|
||||
emit info(
|
||||
reply->property( "requestId" ).toUInt(),
|
||||
requestData,
|
||||
returnedData
|
||||
);
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash>();
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
|
||||
criteria["artist"] = origData["artist"];
|
||||
emit updateCache( criteria, 2419200000, requestData.type, returnedData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LastFmPlugin::coverArtReturned()
|
||||
{
|
||||
@@ -341,49 +504,49 @@ LastFmPlugin::coverArtReturned()
|
||||
if ( redir.isEmpty() )
|
||||
{
|
||||
QByteArray ba = reply->readAll();
|
||||
if ( ba.isNull() || !ba.length() )
|
||||
{
|
||||
qDebug() << "Uh oh, null byte array";
|
||||
emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||
return;
|
||||
}
|
||||
foreach ( const QUrl& url, m_badUrls )
|
||||
{
|
||||
if ( reply->url().toString().startsWith( url.toString() ) )
|
||||
ba = QByteArray();
|
||||
}
|
||||
|
||||
InfoCustomData returnedData;
|
||||
QVariantMap returnedData;
|
||||
returnedData["imgbytes"] = ba;
|
||||
returnedData["url"] = reply->url().toString();
|
||||
|
||||
InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >();
|
||||
InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt());
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
|
||||
emit info(
|
||||
reply->property( "caller" ).toString(),
|
||||
type,
|
||||
reply->property( "origData" ),
|
||||
returnedData,
|
||||
customData
|
||||
reply->property( "requestId" ).toUInt(),
|
||||
requestData,
|
||||
returnedData
|
||||
);
|
||||
|
||||
InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash>();
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
|
||||
criteria["artist"] = origData["artist"];
|
||||
criteria["album"] = origData["album"];
|
||||
emit updateCache( criteria, 2419200000, type, returnedData );
|
||||
emit updateCache( criteria, 2419200000, requestData.type, returnedData );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_nam.isNull() )
|
||||
if ( !lastfm::nam() )
|
||||
{
|
||||
qDebug() << "Uh oh, nam is null";
|
||||
InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt());
|
||||
InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >();
|
||||
emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData );
|
||||
emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||
return;
|
||||
}
|
||||
// Follow HTTP redirect
|
||||
QNetworkRequest req( redir );
|
||||
QNetworkReply* newReply = m_nam.data()->get( req );
|
||||
newReply->setProperty( "origData", reply->property( "origData" ) );
|
||||
newReply->setProperty( "customData", reply->property( "customData" ) );
|
||||
newReply->setProperty( "caller", reply->property( "caller" ) );
|
||||
newReply->setProperty( "type", reply->property( "type" ) );
|
||||
QNetworkReply* newReply = lastfm::nam()->get( req );
|
||||
newReply->setProperty( "requestId", reply->property( "requestId" ) );
|
||||
newReply->setProperty( "requestData", reply->property( "requestData" ) );
|
||||
connect( newReply, SIGNAL( finished() ), SLOT( coverArtReturned() ) );
|
||||
}
|
||||
|
||||
@@ -400,42 +563,43 @@ LastFmPlugin::artistImagesReturned()
|
||||
if ( redir.isEmpty() )
|
||||
{
|
||||
QByteArray ba = reply->readAll();
|
||||
if ( ba.isNull() || !ba.length() )
|
||||
{
|
||||
qDebug() << "Uh oh, null byte array";
|
||||
emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||
return;
|
||||
}
|
||||
foreach ( const QUrl& url, m_badUrls )
|
||||
{
|
||||
if ( reply->url().toString().startsWith( url.toString() ) )
|
||||
ba = QByteArray();
|
||||
}
|
||||
|
||||
InfoCustomData returnedData;
|
||||
QVariantMap returnedData;
|
||||
returnedData["imgbytes"] = ba;
|
||||
returnedData["url"] = reply->url().toString();
|
||||
|
||||
InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt());
|
||||
InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >();
|
||||
emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), returnedData, customData );
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
|
||||
InfoCriteriaHash origData = reply->property( "origData" ).value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
emit info( reply->property( "requestId" ).toUInt(), requestData, returnedData );
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash>();
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
|
||||
criteria["artist"] = origData["artist"];
|
||||
emit updateCache( criteria, 2419200000, type, returnedData );
|
||||
emit updateCache( criteria, 2419200000, requestData.type, returnedData );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_nam.isNull() )
|
||||
if ( !lastfm::nam() )
|
||||
{
|
||||
qDebug() << "Uh oh, nam is null";
|
||||
InfoType type = (Tomahawk::InfoSystem::InfoType)(reply->property( "type" ).toUInt());
|
||||
InfoCustomData customData = reply->property( "customData" ).value< Tomahawk::InfoSystem::InfoCustomData >();
|
||||
emit info( reply->property( "caller" ).toString(), type, reply->property( "origData" ), QVariant(), customData );
|
||||
emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||
return;
|
||||
}
|
||||
// Follow HTTP redirect
|
||||
QNetworkRequest req( redir );
|
||||
QNetworkReply* newReply = m_nam.data()->get( req );
|
||||
newReply->setProperty( "origData", reply->property( "origData" ) );
|
||||
newReply->setProperty( "customData", reply->property( "customData" ) );
|
||||
newReply->setProperty( "caller", reply->property( "caller" ) );
|
||||
newReply->setProperty( "type", reply->property( "type" ) );
|
||||
QNetworkReply* newReply = lastfm::nam()->get( req );
|
||||
newReply->setProperty( "requestId", reply->property( "requestId" ) );
|
||||
newReply->setProperty( "requestData", reply->property( "requestData" ) );
|
||||
connect( newReply, SIGNAL( finished() ), SLOT( artistImagesReturned() ) );
|
||||
}
|
||||
|
||||
|
@@ -49,33 +49,35 @@ public slots:
|
||||
void onAuthenticated();
|
||||
void coverArtReturned();
|
||||
void artistImagesReturned();
|
||||
void similarArtistsReturned();
|
||||
void topTracksReturned();
|
||||
|
||||
void namChangedSlot( QNetworkAccessManager *nam );
|
||||
|
||||
protected slots:
|
||||
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data );
|
||||
virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data );
|
||||
|
||||
private:
|
||||
void fetchCoverArt( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
||||
void fetchArtistImages( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
||||
void fetchCoverArt( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void fetchArtistImages( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void fetchSimilarArtists( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void fetchTopTracks( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
void createScrobbler();
|
||||
void nowPlaying( const QVariant &input );
|
||||
void scrobble();
|
||||
void sendLoveSong( const InfoType type, QVariant input );
|
||||
|
||||
void dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
||||
void sendLoveSong( QVariant input );
|
||||
void dataError( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
lastfm::MutableTrack m_track;
|
||||
lastfm::Audioscrobbler* m_scrobbler;
|
||||
QString m_pw;
|
||||
|
||||
QList< QUrl > m_badUrls;
|
||||
|
||||
QWeakPointer< QNetworkAccessManager > m_nam;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -51,53 +51,52 @@ MusixMatchPlugin::namChangedSlot( QNetworkAccessManager *nam )
|
||||
}
|
||||
|
||||
void
|
||||
MusixMatchPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
||||
MusixMatchPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if( !isValidTrackData(caller, input, customData) || !input.canConvert<Tomahawk::InfoSystem::InfoCustomData>() || m_nam.isNull() || type != Tomahawk::InfoSystem::InfoTrackLyrics )
|
||||
if( !isValidTrackData( requestId, requestData ) || !requestData.input.canConvert< QVariantMap >() || m_nam.isNull() || requestData.type != Tomahawk::InfoSystem::InfoTrackLyrics )
|
||||
return;
|
||||
Tomahawk::InfoSystem::InfoCustomData hash = input.value<Tomahawk::InfoSystem::InfoCustomData>();
|
||||
QVariantMap hash = requestData.input.value< QVariantMap >();
|
||||
QString artist = hash["artistName"].toString();
|
||||
QString track = hash["trackName"].toString();
|
||||
if( artist.isEmpty() || track.isEmpty() )
|
||||
{
|
||||
emit info(caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData);
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
qDebug() << "artist is " << artist << ", track is " << track;
|
||||
QString requestString("http://api.musixmatch.com/ws/1.1/track.search?format=xml&page_size=1&f_has_lyrics=1");
|
||||
QUrl url(requestString);
|
||||
url.addQueryItem("apikey", m_apiKey);
|
||||
url.addQueryItem("q_artist", artist);
|
||||
url.addQueryItem("q_track", track);
|
||||
QNetworkReply* reply = m_nam.data()->get(QNetworkRequest(url));
|
||||
reply->setProperty("customData", QVariant::fromValue<Tomahawk::InfoSystem::InfoCustomData>(customData));
|
||||
reply->setProperty("origData", input);
|
||||
reply->setProperty("caller", caller);
|
||||
QString requestString( "http://api.musixmatch.com/ws/1.1/track.search?format=xml&page_size=1&f_has_lyrics=1" );
|
||||
QUrl url( requestString );
|
||||
url.addQueryItem( "apikey", m_apiKey );
|
||||
url.addQueryItem( "q_artist", artist );
|
||||
url.addQueryItem( "q_track", track );
|
||||
QNetworkReply* reply = m_nam.data()->get( QNetworkRequest( url ) );
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
|
||||
connect(reply, SIGNAL(finished()), SLOT(trackSearchSlot()));
|
||||
connect( reply, SIGNAL( finished() ), SLOT( trackSearchSlot() ) );
|
||||
}
|
||||
|
||||
bool
|
||||
MusixMatchPlugin::isValidTrackData( const QString &caller, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData )
|
||||
MusixMatchPlugin::isValidTrackData( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if (input.isNull() || !input.isValid() || !input.canConvert<Tomahawk::InfoSystem::InfoCustomData>())
|
||||
if ( requestData.input.isNull() || !requestData.input.isValid() || !requestData.input.canConvert< QVariantMap >() )
|
||||
{
|
||||
emit info(caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData);
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
qDebug() << "MusixMatchPlugin::isValidTrackData: Data null, invalid, or can't convert";
|
||||
return false;
|
||||
}
|
||||
InfoCustomData hash = input.value<Tomahawk::InfoSystem::InfoCustomData>();
|
||||
if (hash["trackName"].toString().isEmpty() )
|
||||
QVariantMap hash = requestData.input.value< QVariantMap >();
|
||||
if ( hash[ "trackName" ].toString().isEmpty() )
|
||||
{
|
||||
emit info(caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData);
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
qDebug() << "MusixMatchPlugin::isValidTrackData: Track name is empty";
|
||||
return false;
|
||||
}
|
||||
if (hash["artistName"].toString().isEmpty() )
|
||||
if ( hash[ "artistName" ].toString().isEmpty() )
|
||||
{
|
||||
emit info(caller, Tomahawk::InfoSystem::InfoTrackLyrics, input, QVariant(), customData);
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
qDebug() << "MusixMatchPlugin::isValidTrackData: No artist name found";
|
||||
return false;
|
||||
}
|
||||
@@ -109,51 +108,46 @@ MusixMatchPlugin::trackSearchSlot()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QNetworkReply* oldReply = qobject_cast<QNetworkReply*>( sender() );
|
||||
if ( !oldReply || m_nam.isNull() )
|
||||
{
|
||||
emit info(QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), Tomahawk::InfoSystem::InfoCustomData());
|
||||
return;
|
||||
}
|
||||
if ( !oldReply )
|
||||
return; //timeout will handle it
|
||||
|
||||
QDomDocument doc;
|
||||
doc.setContent(oldReply->readAll());
|
||||
qDebug() << doc.toString();
|
||||
QDomNodeList domNodeList = doc.elementsByTagName("track_id");
|
||||
if (domNodeList.isEmpty())
|
||||
if ( domNodeList.isEmpty() )
|
||||
{
|
||||
emit info(oldReply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, oldReply->property("origData"), QVariant(), oldReply->property("customData").value<Tomahawk::InfoSystem::InfoCustomData>());
|
||||
emit info( oldReply->property( "requestId" ).toUInt(), oldReply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||
return;
|
||||
}
|
||||
QString track_id = domNodeList.at(0).toElement().text();
|
||||
QString requestString("http://api.musixmatch.com/ws/1.1/track.lyrics.get?track_id=%1&format=xml&apikey=%2");
|
||||
QUrl url(requestString);
|
||||
url.addQueryItem("apikey", m_apiKey);
|
||||
url.addQueryItem("track_id", track_id);
|
||||
QNetworkReply* newReply = m_nam.data()->get(QNetworkRequest(url));
|
||||
newReply->setProperty("origData", oldReply->property("origData"));
|
||||
newReply->setProperty("customData", oldReply->property("customData"));
|
||||
newReply->setProperty("caller", oldReply->property("caller"));
|
||||
connect(newReply, SIGNAL(finished()), SLOT(trackLyricsSlot()));
|
||||
QString requestString( "http://api.musixmatch.com/ws/1.1/track.lyrics.get?track_id=%1&format=xml&apikey=%2" );
|
||||
QUrl url( requestString );
|
||||
url.addQueryItem( "apikey", m_apiKey );
|
||||
url.addQueryItem( "track_id", track_id );
|
||||
QNetworkReply* newReply = m_nam.data()->get( QNetworkRequest( url ) );
|
||||
newReply->setProperty( "requestId", oldReply->property( "requestId" ) );
|
||||
newReply->setProperty( "requestData", oldReply->property( "requestData" ) );
|
||||
connect( newReply, SIGNAL( finished() ), SLOT( trackLyricsSlot() ) );
|
||||
}
|
||||
|
||||
void
|
||||
MusixMatchPlugin::trackLyricsSlot()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
|
||||
if (!reply)
|
||||
{
|
||||
emit info(QString(), Tomahawk::InfoSystem::InfoTrackLyrics, QVariant(), QVariant(), Tomahawk::InfoSystem::InfoCustomData());
|
||||
return;
|
||||
}
|
||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
||||
if ( !reply )
|
||||
return; //timeout will handle it
|
||||
|
||||
QDomDocument doc;
|
||||
doc.setContent(reply->readAll());
|
||||
QDomNodeList domNodeList = doc.elementsByTagName("lyrics_body");
|
||||
if (domNodeList.isEmpty())
|
||||
doc.setContent( reply->readAll() );
|
||||
QDomNodeList domNodeList = doc.elementsByTagName( "lyrics_body" );
|
||||
if ( domNodeList.isEmpty() )
|
||||
{
|
||||
emit info(reply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property("origData"), QVariant(), reply->property("customData").value<Tomahawk::InfoSystem::InfoCustomData>());
|
||||
emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant() );
|
||||
return;
|
||||
}
|
||||
QString lyrics = domNodeList.at(0).toElement().text();
|
||||
qDebug() << "Emitting lyrics: " << lyrics;
|
||||
emit info(reply->property("caller").toString(), Tomahawk::InfoSystem::InfoTrackLyrics, reply->property("origData"), QVariant(lyrics), reply->property("customData").value<Tomahawk::InfoSystem::InfoCustomData>());
|
||||
emit info( reply->property( "requestId" ).toUInt(), reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(), QVariant( lyrics ) );
|
||||
}
|
||||
|
@@ -45,26 +45,24 @@ public slots:
|
||||
void namChangedSlot( QNetworkAccessManager *nam );
|
||||
|
||||
protected slots:
|
||||
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data )
|
||||
virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data )
|
||||
{
|
||||
Q_UNUSED( caller );
|
||||
Q_UNUSED( type );
|
||||
Q_UNUSED( data );
|
||||
}
|
||||
|
||||
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
||||
virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( requestId );
|
||||
Q_UNUSED( criteria );
|
||||
Q_UNUSED( caller );
|
||||
Q_UNUSED( type );
|
||||
Q_UNUSED( input );
|
||||
Q_UNUSED( customData );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
private:
|
||||
bool isValidTrackData( const QString &caller, const QVariant &input, const InfoCustomData &customData );
|
||||
bool isValidTrackData( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
QString m_apiKey;
|
||||
|
||||
|
@@ -74,6 +74,7 @@ AdiumPlugin::AdiumPlugin()
|
||||
this, SLOT( clearStatus() ) );
|
||||
}
|
||||
|
||||
|
||||
AdiumPlugin::~AdiumPlugin()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
@@ -81,6 +82,7 @@ AdiumPlugin::~AdiumPlugin()
|
||||
setStatus( "" );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AdiumPlugin::clearStatus()
|
||||
{
|
||||
@@ -88,6 +90,7 @@ AdiumPlugin::clearStatus()
|
||||
setStatus( "" );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AdiumPlugin::settingsChanged()
|
||||
{
|
||||
@@ -96,21 +99,9 @@ AdiumPlugin::settingsChanged()
|
||||
setStatus( "" );
|
||||
}
|
||||
|
||||
void
|
||||
AdiumPlugin::getInfo( const QString caller, const InfoType type, const QVariant data, InfoCustomData customData )
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
{
|
||||
emit info(caller, Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariant(), customData);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AdiumPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input )
|
||||
AdiumPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
|
@@ -39,12 +39,23 @@ public:
|
||||
virtual ~AdiumPlugin();
|
||||
|
||||
protected slots:
|
||||
void getInfo( const QString caller, const InfoType type, const QVariant data, InfoCustomData customData );
|
||||
void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input );
|
||||
virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( requestId );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input );
|
||||
|
||||
public slots:
|
||||
void namChangedSlot( QNetworkAccessManager* /*nam*/ ) {} // unused
|
||||
void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash /*criteria*/, const QString /*caller*/, const Tomahawk::InfoSystem::InfoType /*type*/, const QVariant /*input*/, const Tomahawk::InfoSystem::InfoCustomData /*customData*/ ) {} // unused
|
||||
|
||||
virtual void notInCacheSlot( uint requestId, const Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( requestId );
|
||||
Q_UNUSED( criteria );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
private slots:
|
||||
void clearStatus();
|
||||
|
@@ -59,16 +59,16 @@ FdoNotifyPlugin::~FdoNotifyPlugin()
|
||||
}
|
||||
|
||||
void
|
||||
FdoNotifyPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant pushData )
|
||||
FdoNotifyPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant pushData )
|
||||
{
|
||||
Q_UNUSED( caller );
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if ( type != Tomahawk::InfoSystem::InfoNotifyUser || !pushData.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
||||
if ( type != Tomahawk::InfoSystem::InfoNotifyUser || !pushData.canConvert< QVariantMap >() )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << " not the right type or could not convert the hash";
|
||||
return;
|
||||
}
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash hash = pushData.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
QVariantMap hash = pushData.value< QVariantMap >();
|
||||
if ( !hash.contains( "message" ) )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << " hash did not contain a message";
|
||||
@@ -81,10 +81,17 @@ FdoNotifyPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::Inf
|
||||
arguments << quint32( 0 ); //notification_id
|
||||
arguments << QString(); //app_icon
|
||||
arguments << QString( "Tomahawk" ); //summary
|
||||
arguments << hash["message"]; //body
|
||||
arguments << hash["message"].toString(); //body
|
||||
arguments << QStringList(); //actions
|
||||
QVariantMap dict;
|
||||
dict["desktop-entry"] = QString( "tomahawk" );
|
||||
if ( hash.contains( "image" ) )
|
||||
{
|
||||
QVariant tempVariant = hash["image"];
|
||||
QImage tempImage = tempVariant.value< QImage >();
|
||||
dict["image_data"] = ImageConverter::variantForImage( tempImage );
|
||||
}
|
||||
else
|
||||
dict["image_data"] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-128x128.png" ) );
|
||||
arguments << dict; //hints
|
||||
arguments << qint32( -1 ); //expire_timeout
|
||||
|
@@ -38,23 +38,19 @@ public:
|
||||
virtual void namChangedSlot( QNetworkAccessManager* ) {}
|
||||
|
||||
protected slots:
|
||||
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
||||
virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( caller );
|
||||
Q_UNUSED( type );
|
||||
Q_UNUSED( input );
|
||||
Q_UNUSED( customData );
|
||||
Q_UNUSED( requestId );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
|
||||
virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant pushData );
|
||||
virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant pushData );
|
||||
|
||||
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
||||
virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_UNUSED( requestId );
|
||||
Q_UNUSED( criteria );
|
||||
Q_UNUSED( caller );
|
||||
Q_UNUSED( type );
|
||||
Q_UNUSED( input );
|
||||
Q_UNUSED( customData );
|
||||
Q_UNUSED( requestData );
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -50,8 +50,10 @@ InfoSystem::instance()
|
||||
}
|
||||
|
||||
|
||||
InfoSystem::InfoSystem(QObject *parent)
|
||||
: QObject(parent)
|
||||
InfoSystem::InfoSystem( QObject *parent )
|
||||
: QObject( parent )
|
||||
, m_infoSystemCacheThreadController( 0 )
|
||||
, m_infoSystemWorkerThreadController( 0 )
|
||||
{
|
||||
s_instance = this;
|
||||
|
||||
@@ -71,11 +73,12 @@ InfoSystem::InfoSystem(QObject *parent)
|
||||
|
||||
connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( newNam() ) );
|
||||
|
||||
connect( m_cache.data(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||
this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), Qt::UniqueConnection );
|
||||
connect( m_cache.data(), SIGNAL( info( uint, Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
m_worker.data(), SLOT( infoSlot( uint, Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
|
||||
|
||||
connect( m_worker.data(), SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||
this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), Qt::UniqueConnection );
|
||||
connect( m_worker.data(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
this, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
|
||||
connect( m_worker.data(), SIGNAL( finished( QString ) ), this, SIGNAL( finished( QString ) ), Qt::UniqueConnection );
|
||||
}
|
||||
|
||||
InfoSystem::~InfoSystem()
|
||||
@@ -116,21 +119,25 @@ InfoSystem::newNam() const
|
||||
|
||||
|
||||
void
|
||||
InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& input, InfoCustomData customData )
|
||||
InfoSystem::getInfo( const InfoRequestData &requestData, uint timeoutMillis )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
m_dataTracker[caller][type] = m_dataTracker[caller][type] + 1;
|
||||
qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[caller][type];
|
||||
QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( Tomahawk::InfoSystem::InfoCustomData, customData ) );
|
||||
QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ), Q_ARG( uint, timeoutMillis ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoSystem::getInfo( const QString &caller, const InfoMap &input, InfoCustomData customData )
|
||||
InfoSystem::getInfo( const QString &caller, const InfoTypeMap &inputMap, const QVariantMap &customData, const InfoTimeoutMap &timeoutMap )
|
||||
{
|
||||
Q_FOREACH( InfoType type, input.keys() )
|
||||
getInfo( caller, type, input[type], customData );
|
||||
InfoRequestData requestData;
|
||||
requestData.caller = caller;
|
||||
requestData.customData = customData;
|
||||
Q_FOREACH( InfoType type, inputMap.keys() )
|
||||
{
|
||||
requestData.type = type;
|
||||
requestData.input = inputMap[ type ];
|
||||
QMetaObject::invokeMethod( m_worker.data(), "getInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ), Q_ARG( uint, ( timeoutMap.contains( type ) ? timeoutMap[ type ] : 3000 ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -138,43 +145,15 @@ void
|
||||
InfoSystem::pushInfo( const QString &caller, const InfoType type, const QVariant& input )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
QMetaObject::invokeMethod( m_worker.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoSystem::pushInfo( const QString &caller, const InfoMap &input )
|
||||
InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input )
|
||||
{
|
||||
Q_FOREACH( InfoType type, input.keys() )
|
||||
pushInfo( caller, type, input[type] );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoSystem::infoSlot( QString target, InfoType type, QVariant input, QVariant output, InfoCustomData customData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << "current count in dataTracker is " << m_dataTracker[target][type];
|
||||
if (m_dataTracker[target][type] == 0)
|
||||
{
|
||||
qDebug() << "Caller was not waiting for that type of data!";
|
||||
return;
|
||||
}
|
||||
emit info(target, type, input, output, customData);
|
||||
|
||||
m_dataTracker[target][type] = m_dataTracker[target][type] - 1;
|
||||
qDebug() << "current count in dataTracker is " << m_dataTracker[target][type];
|
||||
Q_FOREACH(InfoType testtype, m_dataTracker[target].keys())
|
||||
{
|
||||
if (m_dataTracker[target][testtype] != 0)
|
||||
{
|
||||
qDebug() << "found outstanding request of type" << testtype;
|
||||
return;
|
||||
}
|
||||
}
|
||||
qDebug() << "emitting finished with target" << target;
|
||||
emit finished(target);
|
||||
QMetaObject::invokeMethod( m_worker.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input[ type ] ) );
|
||||
}
|
||||
|
||||
} //namespace InfoSystem
|
||||
|
@@ -75,8 +75,8 @@ enum InfoType { // as items are saved in cache, mark them here to not change the
|
||||
InfoArtistNews = 29,
|
||||
InfoArtistProfile = 30,
|
||||
InfoArtistReviews = 31,
|
||||
InfoArtistSongs = 32,
|
||||
InfoArtistSimilars = 33,
|
||||
InfoArtistSongs = 32, //cached -- do not change
|
||||
InfoArtistSimilars = 33, //cached -- do not change
|
||||
InfoArtistTerms = 34,
|
||||
InfoArtistLinks = 35,
|
||||
InfoArtistVideos = 36,
|
||||
@@ -107,9 +107,16 @@ enum InfoType { // as items are saved in cache, mark them here to not change the
|
||||
InfoNotifyUser = 55
|
||||
};
|
||||
|
||||
typedef QMap< InfoType, QVariant > InfoMap;
|
||||
struct InfoRequestData {
|
||||
QString caller;
|
||||
Tomahawk::InfoSystem::InfoType type;
|
||||
QVariant input;
|
||||
QVariantMap customData;
|
||||
};
|
||||
|
||||
typedef QMap< InfoType, QVariant > InfoTypeMap;
|
||||
typedef QMap< InfoType, uint > InfoTimeoutMap;
|
||||
typedef QMap< QString, QMap< QString, QString > > InfoGenericMap;
|
||||
typedef QHash< QString, QVariant > InfoCustomData;
|
||||
typedef QHash< QString, QString > InfoCriteriaHash;
|
||||
|
||||
class DLLEXPORT InfoPlugin : public QObject
|
||||
@@ -125,15 +132,15 @@ public:
|
||||
QSet< InfoType > supportedPushTypes() const { return m_supportedPushTypes; }
|
||||
|
||||
signals:
|
||||
void getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
void updateCache( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64, Tomahawk::InfoSystem::InfoType type, QVariant output );
|
||||
void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
void finished( QString, Tomahawk::InfoSystem::InfoType );
|
||||
void getCachedInfo( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void info( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
|
||||
void updateCache( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output );
|
||||
|
||||
protected slots:
|
||||
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data, const Tomahawk::InfoSystem::InfoCustomData customData ) = 0;
|
||||
virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) = 0;
|
||||
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) = 0;
|
||||
virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) = 0;
|
||||
virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data ) = 0;
|
||||
virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) = 0;
|
||||
|
||||
virtual void namChangedSlot( QNetworkAccessManager *nam ) = 0;
|
||||
|
||||
@@ -158,23 +165,19 @@ public:
|
||||
InfoSystem( QObject *parent );
|
||||
~InfoSystem();
|
||||
|
||||
void getInfo( const QString &caller, const InfoType type, const QVariant &input, InfoCustomData customData );
|
||||
void getInfo( const QString &caller, const InfoMap &input, InfoCustomData customData );
|
||||
void getInfo( const InfoRequestData &requestData, uint timeoutMillis = 3000 );
|
||||
void getInfo( const QString &caller, const InfoTypeMap &inputMap, const QVariantMap &customData, const InfoTimeoutMap &timeoutMap = InfoTimeoutMap() );
|
||||
void pushInfo( const QString &caller, const InfoType type, const QVariant &input );
|
||||
void pushInfo( const QString &caller, const InfoMap &input );
|
||||
void pushInfo( const QString &caller, const InfoTypeMap &input );
|
||||
|
||||
signals:
|
||||
void info( QString caller, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void finished( QString target );
|
||||
|
||||
public slots:
|
||||
void infoSlot( const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
|
||||
void newNam() const;
|
||||
|
||||
private:
|
||||
QHash< QString, QHash< InfoType, int > > m_dataTracker;
|
||||
|
||||
QWeakPointer< InfoSystemCache > m_cache;
|
||||
QWeakPointer< InfoSystemWorker > m_worker;
|
||||
QThread* m_infoSystemCacheThreadController;
|
||||
@@ -205,8 +208,8 @@ inline uint qHash( Tomahawk::InfoSystem::InfoCriteriaHash hash )
|
||||
return returnval;
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoRequestData );
|
||||
Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoGenericMap );
|
||||
Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoCustomData );
|
||||
Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoCriteriaHash );
|
||||
Q_DECLARE_METATYPE( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > );
|
||||
|
||||
|
@@ -84,26 +84,26 @@ InfoSystemCache::pruneTimerFired()
|
||||
|
||||
|
||||
void
|
||||
InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
||||
InfoSystemCache::getCachedInfoSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
const QString criteriaHashVal = criteriaMd5( criteria );
|
||||
QHash< QString, QString > fileLocationHash = m_fileLocationCache[type];
|
||||
QHash< QString, QString > fileLocationHash = m_fileLocationCache[ requestData.type ];
|
||||
if ( !fileLocationHash.contains( criteriaHashVal ) )
|
||||
{
|
||||
if ( !fileLocationHash.isEmpty() )
|
||||
{
|
||||
//We already know of some values, so no need to re-read the directory again as it's already happened
|
||||
emit notInCache( criteria, caller, type, input, customData );
|
||||
emit notInCache( requestId, criteria, requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
const QString cacheDir = m_cacheBaseDir + QString::number( (int)type );
|
||||
const QString cacheDir = m_cacheBaseDir + QString::number( (int)requestData.type );
|
||||
QDir dir( cacheDir );
|
||||
if ( !dir.exists() )
|
||||
{
|
||||
//Dir doesn't exist so clearly not in cache
|
||||
emit notInCache( criteria, caller, type, input, customData );
|
||||
emit notInCache( requestId, criteria, requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -111,20 +111,20 @@ InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash
|
||||
foreach ( QFileInfo file, fileList )
|
||||
{
|
||||
QString baseName = file.baseName();
|
||||
fileLocationHash[baseName] = file.canonicalFilePath();
|
||||
fileLocationHash[ baseName ] = file.canonicalFilePath();
|
||||
}
|
||||
|
||||
//Store what we've loaded up
|
||||
m_fileLocationCache[type] = fileLocationHash;
|
||||
m_fileLocationCache[ requestData.type ] = fileLocationHash;
|
||||
if ( !fileLocationHash.contains( criteriaHashVal ) )
|
||||
{
|
||||
//Still didn't fine it? It's really not in the cache then
|
||||
emit notInCache( criteria, caller, type, input, customData );
|
||||
emit notInCache( requestId, criteria, requestData );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QFileInfo file( fileLocationHash[criteriaHashVal] );
|
||||
QFileInfo file( fileLocationHash[ criteriaHashVal ] );
|
||||
qlonglong currMaxAge = file.suffix().toLongLong();
|
||||
|
||||
if ( currMaxAge < QDateTime::currentMSecsSinceEpoch() )
|
||||
@@ -135,10 +135,10 @@ InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash
|
||||
qDebug() << "Removed stale cache file " << file.canonicalFilePath();
|
||||
|
||||
fileLocationHash.remove( criteriaHashVal );
|
||||
m_fileLocationCache[type] = fileLocationHash;
|
||||
m_fileLocationCache[ requestData.type ] = fileLocationHash;
|
||||
m_dataCache.remove( criteriaHashVal );
|
||||
|
||||
emit notInCache( criteria, caller, type, input, customData );
|
||||
emit notInCache( requestId, criteria, requestData );
|
||||
return;
|
||||
}
|
||||
else if ( newMaxAge > 0 )
|
||||
@@ -148,29 +148,31 @@ InfoSystemCache::getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash
|
||||
if ( !QFile::rename( file.canonicalFilePath(), newFilePath ) )
|
||||
{
|
||||
qDebug() << "Failed to move old cache file to new location!";
|
||||
emit notInCache( criteria, caller, type, input, customData );
|
||||
emit notInCache( requestId, criteria, requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
fileLocationHash[criteriaHashVal] = newFilePath;
|
||||
m_fileLocationCache[type] = fileLocationHash;
|
||||
fileLocationHash[ criteriaHashVal ] = newFilePath;
|
||||
m_fileLocationCache[ requestData.type ] = fileLocationHash;
|
||||
}
|
||||
|
||||
if ( !m_dataCache.contains( criteriaHashVal ) )
|
||||
{
|
||||
QSettings cachedSettings( fileLocationHash[criteriaHashVal], QSettings::IniFormat );
|
||||
QSettings cachedSettings( fileLocationHash[ criteriaHashVal ], QSettings::IniFormat );
|
||||
QVariant output = cachedSettings.value( "data" );
|
||||
m_dataCache.insert( criteriaHashVal, new QVariant( output ) );
|
||||
|
||||
emit info( caller, type, input, output, customData );
|
||||
emit info( requestId, requestData, output );
|
||||
}
|
||||
else
|
||||
emit info( caller, type, input, QVariant( *(m_dataCache[criteriaHashVal]) ), customData );
|
||||
{
|
||||
emit info( requestId, requestData, QVariant( *(m_dataCache[criteriaHashVal]) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoSystemCache::updateCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 maxAge, const Tomahawk::InfoSystem::InfoType type, const QVariant output )
|
||||
InfoSystemCache::updateCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
|
@@ -43,12 +43,12 @@ public:
|
||||
virtual ~InfoSystemCache();
|
||||
|
||||
signals:
|
||||
void notInCache( Tomahawk::InfoSystem::InfoCriteriaHash criteria, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
void info( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
void notInCache( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void info( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
|
||||
public slots:
|
||||
void getCachedInfoSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 newMaxAge, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
void updateCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const qint64 maxAge, const Tomahawk::InfoSystem::InfoType type, const QVariant output );
|
||||
void getCachedInfoSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void updateCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 maxAge, Tomahawk::InfoSystem::InfoType type, QVariant output );
|
||||
|
||||
private slots:
|
||||
void pruneTimerFired();
|
||||
|
@@ -43,8 +43,15 @@ namespace InfoSystem
|
||||
{
|
||||
|
||||
InfoSystemWorker::InfoSystemWorker()
|
||||
: QObject()
|
||||
, m_nextRequest( 0 )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
m_checkTimeoutsTimer.setInterval( 1000 );
|
||||
m_checkTimeoutsTimer.setSingleShot( false );
|
||||
connect( &m_checkTimeoutsTimer, SIGNAL( timeout() ), SLOT( checkTimeoutsTimerFired() ) );
|
||||
m_checkTimeoutsTimer.start();
|
||||
}
|
||||
|
||||
|
||||
@@ -91,23 +98,23 @@ InfoSystemWorker::init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache> cac
|
||||
{
|
||||
connect(
|
||||
plugin.data(),
|
||||
SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||
InfoSystem::instance(),
|
||||
SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||
SIGNAL( info( uint, Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
this,
|
||||
SLOT( infoSlot( uint, Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
Qt::UniqueConnection
|
||||
);
|
||||
|
||||
connect(
|
||||
plugin.data(),
|
||||
SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||
SIGNAL( getCachedInfo( uint, Tomahawk::InfoSystem::InfoCriteriaHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ),
|
||||
cache.data(),
|
||||
SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) )
|
||||
SLOT( getCachedInfoSlot( uint, Tomahawk::InfoSystem::InfoCriteriaHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) )
|
||||
);
|
||||
connect(
|
||||
cache.data(),
|
||||
SIGNAL( notInCache( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||
SIGNAL( notInCache( uint, Tomahawk::InfoSystem::InfoCriteriaHash, Tomahawk::InfoSystem::InfoRequestData ) ),
|
||||
plugin.data(),
|
||||
SLOT( notInCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) )
|
||||
SLOT( notInCacheSlot( uint, Tomahawk::InfoSystem::InfoCriteriaHash, Tomahawk::InfoSystem::InfoRequestData ) )
|
||||
);
|
||||
connect(
|
||||
plugin.data(),
|
||||
@@ -151,33 +158,53 @@ InfoSystemWorker::determineOrderedMatches( const InfoType type ) const
|
||||
|
||||
|
||||
void
|
||||
InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, InfoCustomData customData )
|
||||
InfoSystemWorker::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData, uint timeoutMillis )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
QLinkedList< InfoPluginPtr > providers = determineOrderedMatches(type);
|
||||
QLinkedList< InfoPluginPtr > providers = determineOrderedMatches( requestData.type );
|
||||
if ( providers.isEmpty() )
|
||||
{
|
||||
emit info( caller, type, QVariant(), QVariant(), customData );
|
||||
emit info( requestData, QVariant() );
|
||||
checkFinished( requestData.caller );
|
||||
return;
|
||||
}
|
||||
|
||||
InfoPluginPtr ptr = providers.first();
|
||||
if ( !ptr )
|
||||
{
|
||||
emit info( caller, type, QVariant(), QVariant(), customData );
|
||||
emit info( requestData, QVariant() );
|
||||
checkFinished( requestData.caller );
|
||||
return;
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( Tomahawk::InfoSystem::InfoCustomData, customData ) );
|
||||
uint requestId = ++m_nextRequest;
|
||||
m_requestSatisfiedMap[ requestId ] = false;
|
||||
if ( timeoutMillis != 0 )
|
||||
{
|
||||
qint64 currMs = QDateTime::currentMSecsSinceEpoch();
|
||||
m_timeRequestMapper.insert( currMs + timeoutMillis, requestId );
|
||||
}
|
||||
qDebug() << "assigning request with requestId " << requestId << " and type " << requestData.type;
|
||||
m_dataTracker[ requestData.caller ][ requestData.type ] = m_dataTracker[ requestData.caller ][ requestData.type ] + 1;
|
||||
qDebug() << "current count in dataTracker for type" << requestData.type << "is" << m_dataTracker[ requestData.caller ][ requestData.type ];
|
||||
|
||||
InfoRequestData* data = new InfoRequestData;
|
||||
data->caller = requestData.caller;
|
||||
data->type = requestData.type;
|
||||
data->input = requestData.input;
|
||||
data->customData = requestData.customData;
|
||||
m_savedRequestMap[ requestId ] = data;
|
||||
|
||||
QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( uint, requestId ), Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoSystemWorker::pushInfo( const QString caller, const InfoType type, const QVariant input )
|
||||
InfoSystemWorker::pushInfo( QString caller, InfoType type, QVariant input )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
Q_FOREACH( InfoPluginPtr ptr, m_infoPushMap[type] )
|
||||
Q_FOREACH( InfoPluginPtr ptr, m_infoPushMap[ type ] )
|
||||
{
|
||||
if( ptr )
|
||||
QMetaObject::invokeMethod( ptr.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ) );
|
||||
@@ -185,6 +212,101 @@ InfoSystemWorker::pushInfo( const QString caller, const InfoType type, const QVa
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoSystemWorker::infoSlot( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << " with requestId " << requestId;
|
||||
if ( m_dataTracker[ requestData.caller ][ requestData.type ] == 0 )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << " caller was not waiting for that type of data!";
|
||||
return;
|
||||
}
|
||||
if ( !m_requestSatisfiedMap.contains( requestId ) || m_requestSatisfiedMap[ requestId ] )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << " request was already taken care of!";
|
||||
return;
|
||||
}
|
||||
|
||||
m_requestSatisfiedMap[ requestId ] = true;
|
||||
emit info( requestData, output );
|
||||
|
||||
m_dataTracker[ requestData.caller ][ requestData.type ] = m_dataTracker[ requestData.caller ][ requestData.type ] - 1;
|
||||
qDebug() << "current count in dataTracker for target " << requestData.caller << " is " << m_dataTracker[ requestData.caller ][ requestData.type ];
|
||||
delete m_savedRequestMap[ requestId ];
|
||||
m_savedRequestMap.remove( requestId );
|
||||
checkFinished( requestData.caller );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoSystemWorker::checkFinished( const QString &target )
|
||||
{
|
||||
Q_FOREACH( InfoType testtype, m_dataTracker[ target ].keys() )
|
||||
{
|
||||
if ( m_dataTracker[ target ][ testtype ] != 0)
|
||||
{
|
||||
qDebug() << "found outstanding request of type" << testtype;
|
||||
return;
|
||||
}
|
||||
}
|
||||
qDebug() << "emitting finished with target" << target;
|
||||
emit finished( target );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoSystemWorker::checkTimeoutsTimerFired()
|
||||
{
|
||||
qint64 currTime = QDateTime::currentMSecsSinceEpoch();
|
||||
Q_FOREACH( qint64 time, m_timeRequestMapper.keys() )
|
||||
{
|
||||
Q_FOREACH( uint requestId, m_timeRequestMapper.values( time ) )
|
||||
{
|
||||
if ( time < currTime )
|
||||
{
|
||||
if ( m_requestSatisfiedMap[ requestId ] )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << " removing mapping of " << requestId << " which expired at time " << time << " and was already satisfied";
|
||||
m_timeRequestMapper.remove( time, requestId );
|
||||
if ( !m_timeRequestMapper.count( time ) )
|
||||
m_timeRequestMapper.remove( time );
|
||||
continue;
|
||||
}
|
||||
|
||||
//doh, timed out
|
||||
qDebug() << Q_FUNC_INFO << " doh, timed out for requestId " << requestId;
|
||||
InfoRequestData *savedData = m_savedRequestMap[ requestId ];
|
||||
|
||||
InfoRequestData returnData;
|
||||
returnData.caller = savedData->caller;
|
||||
returnData.type = savedData->type;
|
||||
returnData.input = savedData->input;
|
||||
returnData.customData = savedData->customData;
|
||||
emit info( returnData, QVariant() );
|
||||
|
||||
delete savedData;
|
||||
m_savedRequestMap.remove( requestId );
|
||||
|
||||
m_dataTracker[ returnData.caller ][ returnData.type ] = m_dataTracker[ returnData.caller ][ returnData.type ] - 1;
|
||||
qDebug() << "current count in dataTracker for target " << returnData.caller << " is " << m_dataTracker[ returnData.caller ][ returnData.type ];
|
||||
|
||||
m_requestSatisfiedMap[ requestId ] = true;
|
||||
m_timeRequestMapper.remove( time, requestId );
|
||||
if ( !m_timeRequestMapper.count( time ) )
|
||||
m_timeRequestMapper.remove( time );
|
||||
|
||||
checkFinished( returnData.caller );
|
||||
}
|
||||
else
|
||||
{
|
||||
//we've caught up, the remaining requets still have time to work
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QNetworkAccessManager*
|
||||
InfoSystemWorker::nam() const
|
||||
{
|
||||
@@ -239,7 +361,6 @@ InfoSystemWorker::newNam()
|
||||
//FIXME: Currently leaking nam/proxyfactory above -- how to change in a thread-safe way?
|
||||
}
|
||||
|
||||
|
||||
} //namespace InfoSystem
|
||||
|
||||
} //namespace Tomahawk
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include <QtCore/QSet>
|
||||
#include <QtCore/QLinkedList>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
@@ -36,6 +37,7 @@ namespace Tomahawk {
|
||||
|
||||
namespace InfoSystem {
|
||||
|
||||
|
||||
class DLLEXPORT InfoSystemWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -48,16 +50,32 @@ public:
|
||||
QNetworkAccessManager* nam() const;
|
||||
|
||||
signals:
|
||||
void info( QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
void info( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void finished( QString target );
|
||||
|
||||
void namChanged( QNetworkAccessManager* );
|
||||
|
||||
public slots:
|
||||
void init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > cache );
|
||||
void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input );
|
||||
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData, uint timeoutMillis );
|
||||
void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input );
|
||||
|
||||
void infoSlot( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
|
||||
void newNam();
|
||||
|
||||
private slots:
|
||||
void checkTimeoutsTimerFired();
|
||||
|
||||
private:
|
||||
|
||||
void checkFinished( const QString &target );
|
||||
|
||||
QHash< QString, QHash< InfoType, int > > m_dataTracker;
|
||||
QMultiMap< qint64, uint > m_timeRequestMapper;
|
||||
QHash< uint, bool > m_requestSatisfiedMap;
|
||||
QHash< uint, InfoRequestData* > m_savedRequestMap;
|
||||
|
||||
QLinkedList< InfoPluginPtr > determineOrderedMatches( const InfoType type ) const;
|
||||
|
||||
// For now, statically instantiate plugins; this is just somewhere to keep them
|
||||
@@ -67,6 +85,10 @@ private:
|
||||
QMap< InfoType, QLinkedList< InfoPluginPtr > > m_infoPushMap;
|
||||
|
||||
QWeakPointer< QNetworkAccessManager> m_nam;
|
||||
|
||||
uint m_nextRequest;
|
||||
|
||||
QTimer m_checkTimeoutsTimer;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ namespace {
|
||||
}
|
||||
|
||||
static Version kdParseQtVersion( const char * const version ) {
|
||||
if ( !version || qstrlen( version ) < 5 || version[1] != '.' || version[3] != '.' || version[5] != 0 && version[5] != '.' && version[5] != '-' )
|
||||
if ( !version || qstrlen( version ) < 5 || version[1] != '.' || version[3] != '.' || ( version[5] != 0 && version[5] != '.' && version[5] != '-' ) )
|
||||
return Version(); // parse error
|
||||
const Version result = { { version[0] - '0', version[2] - '0', version[4] - '0' } };
|
||||
return result;
|
||||
|
@@ -195,12 +195,27 @@ Servent::createConnectionKey( const QString& name, const QString &nodeid, const
|
||||
void
|
||||
Servent::setExternalAddress( QHostAddress ha, unsigned int port )
|
||||
{
|
||||
QString ip = ha.toString();
|
||||
if ( !qApp->arguments().contains( "--lanhack" ) )
|
||||
{
|
||||
if ( ip.startsWith( "10." ) || ip.startsWith( "172.16." ) || ip.startsWith( "192.168." ) )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << "Tried to set an invalid ip as external address!";
|
||||
return;
|
||||
}
|
||||
|
||||
m_externalAddress = ha;
|
||||
m_externalPort = port;
|
||||
|
||||
if( m_externalPort == 0 || m_externalAddress.toString().isEmpty() )
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !TomahawkSettings::instance()->externalHostname().isEmpty() &&
|
||||
m_externalAddress = ha;
|
||||
m_externalPort = port;
|
||||
}
|
||||
|
||||
if ( m_externalPort == 0 || m_externalAddress.toString().isEmpty() )
|
||||
{
|
||||
if ( !TomahawkSettings::instance()->externalHostname().isEmpty() &&
|
||||
!TomahawkSettings::instance()->externalPort() == 0 )
|
||||
{
|
||||
qDebug() << "UPnP failed, have external address/port -- falling back";
|
||||
|
@@ -208,6 +208,8 @@ signals:
|
||||
void trackCountChanged( unsigned int tracks );
|
||||
void sourceTrackCountChanged( unsigned int tracks );
|
||||
|
||||
void nextTrackReady();
|
||||
|
||||
public slots:
|
||||
// want to update the playlist from the model?
|
||||
// generate a newrev using uuid() and call this:
|
||||
|
@@ -44,8 +44,8 @@ AlbumModel::AlbumModel( QObject* parent )
|
||||
.scaled( QSize( 120, 120 ), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||
SLOT( infoSystemInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ) );
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
|
||||
}
|
||||
@@ -311,26 +311,25 @@ AlbumModel::onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums )
|
||||
|
||||
|
||||
void
|
||||
AlbumModel::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData )
|
||||
AlbumModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
|
||||
{
|
||||
Q_UNUSED( customData );
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
qDebug() << Q_FUNC_INFO << " with caller " << requestData.caller;
|
||||
|
||||
if ( caller != s_tmInfoIdentifier ||
|
||||
( type != Tomahawk::InfoSystem::InfoAlbumCoverArt && type != Tomahawk::InfoSystem::InfoArtistImages ) )
|
||||
if ( requestData.caller != s_tmInfoIdentifier ||
|
||||
( requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt && requestData.type != Tomahawk::InfoSystem::InfoArtistImages ) )
|
||||
{
|
||||
qDebug() << "Info of wrong type or not with our identifier";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !output.canConvert< Tomahawk::InfoSystem::InfoCustomData >() )
|
||||
if ( !output.canConvert< QVariantMap >() )
|
||||
{
|
||||
qDebug() << "Cannot convert fetched art from a QByteArray";
|
||||
return;
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash pptr = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
Tomahawk::InfoSystem::InfoCustomData returnedData = output.value< Tomahawk::InfoSystem::InfoCustomData >();
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash pptr = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
QVariantMap returnedData = output.value< QVariantMap >();
|
||||
const QByteArray ba = returnedData["imgbytes"].toByteArray();
|
||||
if ( ba.length() )
|
||||
{
|
||||
|
@@ -97,7 +97,7 @@ private slots:
|
||||
void onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums );
|
||||
void onDataChanged();
|
||||
|
||||
void infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void infoSystemFinished( QString target );
|
||||
|
||||
private:
|
||||
|
@@ -40,6 +40,7 @@ AlbumProxyModel::AlbumProxyModel( QObject* parent )
|
||||
setSourceAlbumModel( 0 );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlbumProxyModel::setSourceModel( QAbstractItemModel* sourceModel )
|
||||
{
|
||||
@@ -48,6 +49,7 @@ AlbumProxyModel::setSourceModel( QAbstractItemModel* sourceModel )
|
||||
Q_ASSERT( false );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlbumProxyModel::setSourceAlbumModel( AlbumModel* sourceModel )
|
||||
{
|
||||
|
@@ -65,6 +65,8 @@ 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 ); }
|
||||
|
@@ -162,9 +162,13 @@ AlbumView::onScrollTimeout()
|
||||
trackInfo["album"] = item->album()->name();
|
||||
trackInfo["pptr"] = QString::number( (qlonglong)item );
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo(
|
||||
s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoAlbumCoverArt,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData;
|
||||
requestData.caller = s_tmInfoIdentifier;
|
||||
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo );
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -46,6 +46,7 @@ ArtistView::ArtistView( QWidget* parent )
|
||||
, m_proxyModel( 0 )
|
||||
// , m_delegate( 0 )
|
||||
, m_loadingSpinner( new LoadingSpinner( this ) )
|
||||
, m_contextMenu( new ContextMenu( this ) )
|
||||
, m_showModes( true )
|
||||
{
|
||||
setAlternatingRowColors( true );
|
||||
@@ -59,6 +60,7 @@ ArtistView::ArtistView( QWidget* parent )
|
||||
setAllColumnsShowFocus( true );
|
||||
setSelectionMode( QAbstractItemView::ExtendedSelection );
|
||||
setSelectionBehavior( QAbstractItemView::SelectRows );
|
||||
setContextMenuPolicy( Qt::CustomContextMenu );
|
||||
|
||||
setHeader( m_header );
|
||||
setProxyModel( new TreeProxyModel( this ) );
|
||||
@@ -81,6 +83,8 @@ ArtistView::ArtistView( QWidget* parent )
|
||||
connect( &m_timer, SIGNAL( timeout() ), SLOT( onScrollTimeout() ) );
|
||||
|
||||
connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
|
||||
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
|
||||
connect( m_contextMenu, SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +120,7 @@ ArtistView::setTreeModel( TreeModel* model )
|
||||
|
||||
if ( m_proxyModel )
|
||||
{
|
||||
m_proxyModel->setSourceModel( model );
|
||||
m_proxyModel->setSourceTreeModel( model );
|
||||
m_proxyModel->sort( 0 );
|
||||
}
|
||||
|
||||
@@ -238,14 +242,74 @@ ArtistView::onScrollTimeout()
|
||||
for ( int i = left.row(); i < max; i++ )
|
||||
{
|
||||
TreeModelItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( m_proxyModel->index( i, 0 ) ) );
|
||||
if ( item->artist().isNull() )
|
||||
continue;
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
|
||||
trackInfo["artist"] = item->artist()->name();
|
||||
trackInfo["pptr"] = QString::number( (qlonglong)item );
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo(
|
||||
s_tmInfoIdentifier, Tomahawk::InfoSystem::InfoArtistImages,
|
||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData;
|
||||
requestData.caller = s_tmInfoIdentifier;
|
||||
requestData.type = Tomahawk::InfoSystem::InfoArtistImages;
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo );
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ArtistView::onCustomContextMenu( const QPoint& pos )
|
||||
{
|
||||
m_contextMenu->clear();
|
||||
|
||||
QModelIndex idx = indexAt( pos );
|
||||
idx = idx.sibling( idx.row(), 0 );
|
||||
m_contextMenuIndex = idx;
|
||||
|
||||
if ( !idx.isValid() )
|
||||
return;
|
||||
|
||||
QList<query_ptr> queries;
|
||||
QList<artist_ptr> artists;
|
||||
QList<album_ptr> albums;
|
||||
|
||||
foreach ( const QModelIndex& index, selectedIndexes() )
|
||||
{
|
||||
if ( index.column() || selectedIndexes().contains( index.parent() ) )
|
||||
continue;
|
||||
|
||||
TreeModelItem* item = m_proxyModel->itemFromIndex( m_proxyModel->mapToSource( index ) );
|
||||
|
||||
if ( item && !item->result().isNull() )
|
||||
queries << item->result()->toQuery();
|
||||
if ( item && !item->artist().isNull() )
|
||||
artists << item->artist();
|
||||
if ( item && !item->album().isNull() )
|
||||
albums << item->album();
|
||||
}
|
||||
|
||||
m_contextMenu->setQueries( queries );
|
||||
m_contextMenu->setArtists( artists );
|
||||
m_contextMenu->setAlbums( albums );
|
||||
|
||||
m_contextMenu->exec( mapToGlobal( pos ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ArtistView::onMenuTriggered( int action )
|
||||
{
|
||||
switch ( action )
|
||||
{
|
||||
case ContextMenu::ActionPlay:
|
||||
onItemActivated( m_contextMenuIndex );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <QTreeView>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "contextMenu.h"
|
||||
#include "treemodel.h"
|
||||
#include "treeproxymodel.h"
|
||||
#include "viewpage.h"
|
||||
@@ -79,6 +80,9 @@ private slots:
|
||||
void onViewChanged();
|
||||
void onScrollTimeout();
|
||||
|
||||
void onCustomContextMenu( const QPoint& pos );
|
||||
void onMenuTriggered( int action );
|
||||
|
||||
private:
|
||||
TreeHeader* m_header;
|
||||
TreeModel* m_model;
|
||||
@@ -86,6 +90,8 @@ private:
|
||||
// PlaylistItemDelegate* m_delegate;
|
||||
|
||||
LoadingSpinner* m_loadingSpinner;
|
||||
QModelIndex m_contextMenuIndex;
|
||||
Tomahawk::ContextMenu* m_contextMenu;
|
||||
|
||||
bool m_showModes;
|
||||
QTimer m_timer;
|
||||
|
@@ -55,6 +55,8 @@ public:
|
||||
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 );
|
||||
|
@@ -38,9 +38,6 @@ CollectionView::CollectionView( QWidget* parent )
|
||||
|
||||
setDragDropMode( QAbstractItemView::DragOnly );
|
||||
setAcceptDrops( false );
|
||||
|
||||
setContextMenuPolicy( Qt::CustomContextMenu );
|
||||
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -80,42 +77,6 @@ CollectionView::dragEnterEvent( QDragEnterEvent* event )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionView::setupMenus()
|
||||
{
|
||||
m_itemMenu.clear();
|
||||
|
||||
m_playItemAction = m_itemMenu.addAction( tr( "&Play" ) );
|
||||
m_addItemsToQueueAction = m_itemMenu.addAction( tr( "Add to &Queue" ) );
|
||||
m_itemMenu.addSeparator();
|
||||
|
||||
foreach( QAction* a, actions() )
|
||||
m_itemMenu.addAction( a );
|
||||
// m_addItemsToPlaylistAction = m_itemMenu.addAction( tr( "&Add to Playlist" ) );
|
||||
|
||||
connect( m_playItemAction, SIGNAL( triggered() ), SLOT( playItem() ) );
|
||||
connect( m_addItemsToQueueAction, SIGNAL( triggered() ), SLOT( addItemsToQueue() ) );
|
||||
// connect( m_addItemsToPlaylistAction, SIGNAL( triggered() ), SLOT( addItemsToPlaylist() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionView::onCustomContextMenu( const QPoint& pos )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
setupMenus();
|
||||
|
||||
QModelIndex idx = indexAt( pos );
|
||||
idx = idx.sibling( idx.row(), 0 );
|
||||
setContextMenuIndex( idx );
|
||||
|
||||
if ( !idx.isValid() )
|
||||
return;
|
||||
|
||||
m_itemMenu.exec( mapToGlobal( pos ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionView::onTrackCountChanged( unsigned int tracks )
|
||||
{
|
||||
|
@@ -19,8 +19,6 @@
|
||||
#ifndef COLLECTIONVIEW_H
|
||||
#define COLLECTIONVIEW_H
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
#include "trackproxymodel.h"
|
||||
#include "trackmodel.h"
|
||||
#include "trackview.h"
|
||||
@@ -52,20 +50,10 @@ public:
|
||||
virtual bool jumpToCurrentTrack();
|
||||
|
||||
private slots:
|
||||
void onCustomContextMenu( const QPoint& pos );
|
||||
void onTrackCountChanged( unsigned int tracks );
|
||||
|
||||
protected:
|
||||
virtual void dragEnterEvent( QDragEnterEvent* event );
|
||||
|
||||
private:
|
||||
void setupMenus();
|
||||
|
||||
QMenu m_itemMenu;
|
||||
|
||||
QAction* m_playItemAction;
|
||||
QAction* m_addItemsToQueueAction;
|
||||
QAction* m_addItemsToPlaylistAction;
|
||||
};
|
||||
|
||||
#endif // COLLECTIONVIEW_H
|
||||
|
@@ -27,7 +27,6 @@ namespace Tomahawk
|
||||
|
||||
class StationModelItem;
|
||||
|
||||
|
||||
/**
|
||||
* Extends PlaylistModel with support for handling stations
|
||||
*/
|
||||
@@ -55,6 +54,9 @@ public:
|
||||
|
||||
// a batchof static tracks wre generated
|
||||
void tracksGenerated( const QList< query_ptr > entries, int limitResolvedTo = -1 );
|
||||
|
||||
using PlaylistModel::loadPlaylist;
|
||||
|
||||
signals:
|
||||
void collapseFromTo( int startRow, int num );
|
||||
void checkForOverflow();
|
||||
@@ -62,6 +64,7 @@ signals:
|
||||
void trackGenerationFailure( const QString& msg );
|
||||
|
||||
void tracksAdded();
|
||||
|
||||
private slots:
|
||||
void newTrackGenerated( const Tomahawk::query_ptr& query );
|
||||
|
||||
@@ -69,6 +72,7 @@ private slots:
|
||||
void newTrackLoading();
|
||||
|
||||
void filteringTrackResolved( bool successful );
|
||||
|
||||
private:
|
||||
void filterUnresolved( const QList< query_ptr >& entries );
|
||||
void addToPlaylist( const QList< query_ptr >& entries, bool clearFirst );
|
||||
|
@@ -43,18 +43,25 @@ InfoBar::InfoBar( QWidget* parent )
|
||||
|
||||
boldFont.setPixelSize( 12 );
|
||||
ui->descriptionLabel->setFont( boldFont );
|
||||
ui->descriptionLabel->setMargin( 10 );
|
||||
|
||||
QFont regFont = ui->longDescriptionLabel->font();
|
||||
regFont.setPixelSize( 11 );
|
||||
ui->longDescriptionLabel->setFont( regFont );
|
||||
|
||||
QPalette whitePal = ui->captionLabel->palette();
|
||||
whitePal.setColor( QPalette::Foreground, Qt::white );
|
||||
|
||||
ui->captionLabel->setPalette( whitePal );
|
||||
ui->descriptionLabel->setPalette( whitePal );
|
||||
ui->longDescriptionLabel->setPalette( whitePal );
|
||||
|
||||
ui->captionLabel->setMargin( 6 );
|
||||
ui->descriptionLabel->setMargin( 6 );
|
||||
ui->longDescriptionLabel->setMargin( 4 );
|
||||
|
||||
ui->captionLabel->setText( QString() );
|
||||
ui->captionLabel->setMargin( 6 );
|
||||
|
||||
ui->descriptionLabel->setText( QString() );
|
||||
ui->longDescriptionLabel->setText( QString() );
|
||||
ui->imageLabel->setText( QString() );
|
||||
|
||||
setAutoFillBackground( true );
|
||||
@@ -81,6 +88,13 @@ InfoBar::setDescription( const QString& s )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoBar::setLongDescription( const QString& s )
|
||||
{
|
||||
ui->longDescriptionLabel->setText( s );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoBar::setPixmap( const QPixmap& p )
|
||||
{
|
||||
|
@@ -39,6 +39,7 @@ public:
|
||||
public slots:
|
||||
void setCaption( const QString& s );
|
||||
void setDescription( const QString& s );
|
||||
void setLongDescription( const QString& s );
|
||||
void setPixmap( const QPixmap& p );
|
||||
|
||||
protected:
|
||||
|
@@ -36,7 +36,7 @@
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -65,7 +65,7 @@
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -73,10 +73,13 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="ElidedLabel" name="captionLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@@ -89,7 +92,7 @@
|
||||
<item>
|
||||
<widget class="ElidedLabel" name="descriptionLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
@@ -101,6 +104,73 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMaximumSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="longDescriptionLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>62</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>62</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
@@ -111,7 +181,7 @@
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
|
@@ -37,6 +37,8 @@
|
||||
|
||||
#define PLAYING_ICON QString( RESPATH "images/now-playing-speaker.png" )
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
PlaylistItemDelegate::PlaylistItemDelegate( TrackView* parent, TrackProxyModel* proxy )
|
||||
: QStyledItemDelegate( (QObject*)parent )
|
||||
@@ -147,6 +149,8 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem&
|
||||
|
||||
QPixmap pixmap;
|
||||
QString artist, track, upperText, lowerText;
|
||||
source_ptr source = item->query()->playedBy().first;
|
||||
|
||||
if ( item->query()->results().count() )
|
||||
{
|
||||
artist = item->query()->results().first()->artist()->name();
|
||||
@@ -158,7 +162,7 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem&
|
||||
track = item->query()->track();
|
||||
}
|
||||
|
||||
if ( item->query()->playedBy().isNull() )
|
||||
if ( source.isNull() )
|
||||
{
|
||||
upperText = artist;
|
||||
lowerText = track;
|
||||
@@ -166,13 +170,14 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem&
|
||||
else
|
||||
{
|
||||
upperText = QString( "%1 - %2" ).arg( artist ).arg( track );
|
||||
QString playtime = TomahawkUtils::ageToString( QDateTime::fromTime_t( item->query()->playedBy().second ) );
|
||||
|
||||
if ( item->query()->playedBy() == SourceList::instance()->getLocal() )
|
||||
lowerText = QString( "played by you" );
|
||||
if ( source == SourceList::instance()->getLocal() )
|
||||
lowerText = QString( "played %1 ago by you" ).arg( playtime );
|
||||
else
|
||||
lowerText = QString( "played by %1" ).arg( item->query()->playedBy()->friendlyName() );
|
||||
lowerText = QString( "played %1 ago by %2" ).arg( playtime ).arg( source->friendlyName() );
|
||||
|
||||
pixmap = item->query()->playedBy()->avatar();
|
||||
pixmap = source->avatar();
|
||||
}
|
||||
|
||||
if ( pixmap.isNull() )
|
||||
@@ -200,15 +205,16 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem&
|
||||
QFont boldFont = opt.font;
|
||||
boldFont.setBold( true );
|
||||
|
||||
r.adjust( ir.width() + 12, 0, 0, 0 );
|
||||
r.adjust( ir.width() + 12, 0, -12, 0 );
|
||||
QTextOption to( Qt::AlignTop );
|
||||
QString text = painter->fontMetrics().elidedText( upperText, Qt::ElideRight, r.width() - 3 );
|
||||
to.setWrapMode( QTextOption::NoWrap );
|
||||
painter->setFont( boldFont );
|
||||
QString text = painter->fontMetrics().elidedText( upperText, Qt::ElideRight, r.width() );
|
||||
painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, to );
|
||||
|
||||
to.setAlignment( Qt::AlignBottom );
|
||||
text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, r.width() - 3 );
|
||||
painter->setFont( opt.font );
|
||||
text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, r.width() );
|
||||
painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, to );
|
||||
}
|
||||
painter->restore();
|
||||
@@ -257,8 +263,8 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt
|
||||
if ( m_view->header()->visualIndex( index.column() ) == 0 )
|
||||
{
|
||||
r.adjust( 0, 0, 0, -3 );
|
||||
painter->drawPixmap( r.adjusted( 3, 3, 18 - r.width(), 0 ), m_nowPlayingIcon );
|
||||
r.adjust( 22, 0, 0, 3 );
|
||||
painter->drawPixmap( r.adjusted( 3, 1, 18 - r.width(), 1 ), m_nowPlayingIcon );
|
||||
r.adjust( 25, 0, 0, 3 );
|
||||
}
|
||||
|
||||
painter->setPen( opt.palette.text().color() );
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#include <QTreeView>
|
||||
|
||||
#include "album.h"
|
||||
|
||||
#include "pipeline.h"
|
||||
#include "database/database.h"
|
||||
#include "database/databasecommand_playbackhistory.h"
|
||||
#include "dynamic/GeneratorInterface.h"
|
||||
@@ -188,6 +188,9 @@ PlaylistModel::append( const Tomahawk::query_ptr& query )
|
||||
QList< Tomahawk::query_ptr > ql;
|
||||
ql << query;
|
||||
|
||||
if ( !query->resolvingFinished() )
|
||||
Pipeline::instance()->resolve( query );
|
||||
|
||||
onTracksAdded( ql );
|
||||
}
|
||||
|
||||
@@ -201,7 +204,8 @@ PlaylistModel::append( const Tomahawk::album_ptr& album )
|
||||
connect( album.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
|
||||
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
|
||||
|
||||
if( rowCount( QModelIndex() ) == 0 ) {
|
||||
if ( rowCount( QModelIndex() ) == 0 )
|
||||
{
|
||||
setTitle( album->name() );
|
||||
setDescription( tr( "All tracks by %1 on album %2" ).arg( album->artist()->name() ).arg( album->name() ) );
|
||||
m_isTemporary = true;
|
||||
@@ -220,7 +224,8 @@ PlaylistModel::append( const Tomahawk::artist_ptr& artist )
|
||||
connect( artist.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
|
||||
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
|
||||
|
||||
if( rowCount( QModelIndex() ) == 0 ) {
|
||||
if ( rowCount( QModelIndex() ) == 0 )
|
||||
{
|
||||
setTitle( artist->name() );
|
||||
setDescription( tr( "All tracks by %1" ).arg( artist->name() ) );
|
||||
m_isTemporary = true;
|
||||
|
@@ -32,16 +32,10 @@ using namespace Tomahawk;
|
||||
PlaylistView::PlaylistView( QWidget* parent )
|
||||
: TrackView( parent )
|
||||
, m_model( 0 )
|
||||
, m_itemMenu( 0 )
|
||||
, m_playItemAction( 0 )
|
||||
, m_addItemsToQueueAction( 0 )
|
||||
, m_addItemsToPlaylistAction( 0 )
|
||||
, m_deleteItemsAction( 0 )
|
||||
{
|
||||
setProxyModel( new PlaylistProxyModel( this ) );
|
||||
|
||||
setContextMenuPolicy( Qt::CustomContextMenu );
|
||||
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
|
||||
connect( contextMenu(), SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -81,54 +75,6 @@ PlaylistView::setPlaylistModel( PlaylistModel* model )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistView::setupMenus()
|
||||
{
|
||||
m_itemMenu.clear();
|
||||
|
||||
unsigned int i = 0;
|
||||
foreach( const QModelIndex& idx, selectedIndexes() )
|
||||
if ( idx.column() == 0 )
|
||||
i++;
|
||||
|
||||
m_playItemAction = m_itemMenu.addAction( tr( "&Play" ) );
|
||||
m_addItemsToQueueAction = m_itemMenu.addAction( tr( "Add to &Queue" ) );
|
||||
m_itemMenu.addSeparator();
|
||||
|
||||
foreach( QAction* a, actions() )
|
||||
m_itemMenu.addAction( a );
|
||||
|
||||
// m_addItemsToPlaylistAction = m_itemMenu.addAction( tr( "&Add to Playlist" ) );
|
||||
// m_itemMenu.addSeparator();
|
||||
m_deleteItemsAction = m_itemMenu.addAction( i > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) );
|
||||
|
||||
if ( model() )
|
||||
m_deleteItemsAction->setEnabled( !model()->isReadOnly() );
|
||||
|
||||
connect( m_playItemAction, SIGNAL( triggered() ), SLOT( playItem() ) );
|
||||
connect( m_addItemsToQueueAction, SIGNAL( triggered() ), SLOT( addItemsToQueue() ) );
|
||||
// connect( m_addItemsToPlaylistAction, SIGNAL( triggered() ), SLOT( addItemsToPlaylist() ) );
|
||||
connect( m_deleteItemsAction, SIGNAL( triggered() ), SLOT( deleteItems() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistView::onCustomContextMenu( const QPoint& pos )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
setupMenus();
|
||||
|
||||
QModelIndex idx = indexAt( pos );
|
||||
idx = idx.sibling( idx.row(), 0 );
|
||||
setContextMenuIndex( idx );
|
||||
|
||||
if ( !idx.isValid() )
|
||||
return;
|
||||
|
||||
m_itemMenu.exec( mapToGlobal( pos ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistView::keyPressEvent( QKeyEvent* event )
|
||||
{
|
||||
@@ -152,6 +98,7 @@ PlaylistView::deleteItems()
|
||||
proxyModel()->removeIndexes( selectedIndexes() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistView::onTrackCountChanged( unsigned int tracks )
|
||||
{
|
||||
@@ -196,3 +143,19 @@ PlaylistView::isTemporaryPage() const
|
||||
{
|
||||
return ( m_model && m_model->isTemporary() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistView::onMenuTriggered( int action )
|
||||
{
|
||||
switch ( action )
|
||||
{
|
||||
case ContextMenu::ActionDelete:
|
||||
deleteItems();
|
||||
break;
|
||||
|
||||
default:
|
||||
TrackView::onMenuTriggered( action );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -19,8 +19,6 @@
|
||||
#ifndef PLAYLISTVIEW_H
|
||||
#define PLAYLISTVIEW_H
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
#include "playlist/trackproxymodel.h"
|
||||
#include "playlist/playlistmodel.h"
|
||||
#include "trackview.h"
|
||||
@@ -62,26 +60,19 @@ protected:
|
||||
void keyPressEvent( QKeyEvent* event );
|
||||
|
||||
private slots:
|
||||
void onCustomContextMenu( const QPoint& pos );
|
||||
void onTrackCountChanged( unsigned int tracks );
|
||||
|
||||
void onMenuTriggered( int action );
|
||||
void deleteItems();
|
||||
|
||||
void onDeleted();
|
||||
void onChanged();
|
||||
private:
|
||||
void setupMenus();
|
||||
|
||||
private:
|
||||
PlaylistModel* m_model;
|
||||
|
||||
QMenu m_itemMenu;
|
||||
QString m_customTitle;
|
||||
QString m_customDescripton;
|
||||
|
||||
QAction* m_playItemAction;
|
||||
QAction* m_addItemsToQueueAction;
|
||||
QAction* m_addItemsToPlaylistAction;
|
||||
QAction* m_deleteItemsAction;
|
||||
};
|
||||
|
||||
#endif // PLAYLISTVIEW_H
|
||||
|
@@ -47,13 +47,12 @@ QueueProxyModel::siblingItem( int itemsAway )
|
||||
setCurrentIndex( QModelIndex() );
|
||||
Tomahawk::result_ptr res = PlaylistProxyModel::siblingItem( itemsAway );
|
||||
|
||||
qDebug() << "new rowcount:" << rowCount( QModelIndex() );
|
||||
|
||||
removeIndex( currentIndex() );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
QueueProxyModel::onTrackCountChanged( unsigned int count )
|
||||
{
|
||||
|
@@ -35,6 +35,8 @@ public:
|
||||
|
||||
virtual Tomahawk::result_ptr siblingItem( int itemsAway );
|
||||
|
||||
using PlaylistProxyModel::siblingItem;
|
||||
|
||||
private slots:
|
||||
void onTrackCountChanged( unsigned int count );
|
||||
};
|
||||
|
@@ -89,6 +89,8 @@ public:
|
||||
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;
|
||||
|
||||
|
@@ -300,8 +300,6 @@ TrackProxyModel::removeIndexes( const QList<QPersistentModelIndex>& indexes )
|
||||
bool
|
||||
TrackProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) const
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
TrackModelItem* p1 = itemFromIndex( left );
|
||||
TrackModelItem* p2 = itemFromIndex( right );
|
||||
|
||||
|
@@ -74,6 +74,8 @@ 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 ); }
|
||||
|
@@ -34,7 +34,6 @@
|
||||
#include "trackmodel.h"
|
||||
#include "trackproxymodel.h"
|
||||
#include "track.h"
|
||||
#include "globalactionmanager.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -49,6 +48,7 @@ TrackView::TrackView( QWidget* parent )
|
||||
, m_loadingSpinner( new LoadingSpinner( this ) )
|
||||
, m_resizing( false )
|
||||
, m_dragging( false )
|
||||
, m_contextMenu( new ContextMenu( this ) )
|
||||
{
|
||||
setAlternatingRowColors( true );
|
||||
setSelectionMode( QAbstractItemView::ExtendedSelection );
|
||||
@@ -67,6 +67,7 @@ TrackView::TrackView( QWidget* parent )
|
||||
setHeader( m_header );
|
||||
setSortingEnabled( true );
|
||||
sortByColumn( -1 );
|
||||
setContextMenuPolicy( Qt::CustomContextMenu );
|
||||
|
||||
#ifndef Q_WS_WIN
|
||||
QFont f = font();
|
||||
@@ -79,11 +80,9 @@ TrackView::TrackView( QWidget* parent )
|
||||
setFont( f );
|
||||
#endif
|
||||
|
||||
QAction* createLinkAction = new QAction( tr( "Copy Track Link" ), this );
|
||||
connect( createLinkAction, SIGNAL( triggered( bool ) ), this, SLOT( copyLink() ) );
|
||||
addAction( createLinkAction );
|
||||
|
||||
connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
|
||||
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
|
||||
connect( m_contextMenu, SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -200,24 +199,6 @@ TrackView::playItem()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::addItemsToQueue()
|
||||
{
|
||||
foreach( const QModelIndex& idx, selectedIndexes() )
|
||||
{
|
||||
if ( idx.column() )
|
||||
continue;
|
||||
|
||||
TrackModelItem* item = model()->itemFromIndex( proxyModel()->mapToSource( idx ) );
|
||||
if ( item && item->query()->numResults() )
|
||||
{
|
||||
ViewManager::instance()->queue()->model()->append( item->query() );
|
||||
ViewManager::instance()->showQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::resizeEvent( QResizeEvent* event )
|
||||
{
|
||||
@@ -374,17 +355,6 @@ TrackView::onFilterChanged( const QString& )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::copyLink()
|
||||
{
|
||||
TrackModelItem* item = model()->itemFromIndex( proxyModel()->mapToSource( contextMenuIndex() ) );
|
||||
if ( item && !item->query().isNull() )
|
||||
{
|
||||
GlobalActionManager::instance()->copyToClipboard( item->query() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::startDrag( Qt::DropActions supportedActions )
|
||||
{
|
||||
@@ -419,3 +389,49 @@ TrackView::startDrag( Qt::DropActions supportedActions )
|
||||
m_proxyModel->removeIndexes( pindexes );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::onCustomContextMenu( const QPoint& pos )
|
||||
{
|
||||
m_contextMenu->clear();
|
||||
|
||||
QModelIndex idx = indexAt( pos );
|
||||
idx = idx.sibling( idx.row(), 0 );
|
||||
setContextMenuIndex( idx );
|
||||
|
||||
if ( !idx.isValid() )
|
||||
return;
|
||||
|
||||
if ( model() && !model()->isReadOnly() )
|
||||
m_contextMenu->setSupportedActions( m_contextMenu->supportedActions() | ContextMenu::ActionDelete );
|
||||
|
||||
QList<query_ptr> queries;
|
||||
foreach ( const QModelIndex& index, selectedIndexes() )
|
||||
{
|
||||
if ( index.column() )
|
||||
continue;
|
||||
|
||||
TrackModelItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( index ) );
|
||||
if ( item && !item->query().isNull() )
|
||||
queries << item->query();
|
||||
}
|
||||
|
||||
m_contextMenu->setQueries( queries );
|
||||
m_contextMenu->exec( mapToGlobal( pos ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::onMenuTriggered( int action )
|
||||
{
|
||||
switch ( action )
|
||||
{
|
||||
case ContextMenu::ActionPlay:
|
||||
onItemActivated( m_contextMenuIndex );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <QTreeView>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "contextMenu.h"
|
||||
#include "playlistitemdelegate.h"
|
||||
|
||||
#include "dllmacro.h"
|
||||
@@ -53,6 +54,7 @@ explicit TrackView( QWidget* parent = 0 );
|
||||
PlaylistItemDelegate* delegate() const { return m_delegate; }
|
||||
TrackHeader* header() const { return m_header; }
|
||||
OverlayWidget* overlay() const { return m_overlay; }
|
||||
Tomahawk::ContextMenu* contextMenu() const { return m_contextMenu; }
|
||||
|
||||
QModelIndex contextMenuIndex() const { return m_contextMenuIndex; }
|
||||
void setContextMenuIndex( const QModelIndex& idx ) { m_contextMenuIndex = idx; }
|
||||
@@ -61,7 +63,7 @@ public slots:
|
||||
void onItemActivated( const QModelIndex& index );
|
||||
|
||||
void playItem();
|
||||
void addItemsToQueue();
|
||||
void onMenuTriggered( int action );
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent( QResizeEvent* event );
|
||||
@@ -77,10 +79,9 @@ protected:
|
||||
|
||||
private slots:
|
||||
void onItemResized( const QModelIndex& index );
|
||||
|
||||
void onFilterChanged( const QString& filter );
|
||||
|
||||
void copyLink();
|
||||
void onCustomContextMenu( const QPoint& pos );
|
||||
|
||||
private:
|
||||
QString m_guid;
|
||||
@@ -96,6 +97,7 @@ private:
|
||||
QRect m_dropRect;
|
||||
|
||||
QModelIndex m_contextMenuIndex;
|
||||
Tomahawk::ContextMenu* m_contextMenu;
|
||||
};
|
||||
|
||||
#endif // TRACKVIEW_H
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QAbstractItemView>
|
||||
#include <QHeaderView>
|
||||
|
||||
#include "query.h"
|
||||
#include "result.h"
|
||||
@@ -30,13 +31,15 @@
|
||||
|
||||
#include "treemodelitem.h"
|
||||
#include "treeproxymodel.h"
|
||||
#include "artistview.h"
|
||||
|
||||
|
||||
TreeItemDelegate::TreeItemDelegate( QAbstractItemView* parent, TreeProxyModel* proxy )
|
||||
TreeItemDelegate::TreeItemDelegate( ArtistView* parent, TreeProxyModel* proxy )
|
||||
: QStyledItemDelegate( (QObject*)parent )
|
||||
, m_view( parent )
|
||||
, m_model( proxy )
|
||||
{
|
||||
m_nowPlayingIcon = QPixmap( RESPATH "images/now-playing-speaker.png" );
|
||||
}
|
||||
|
||||
|
||||
@@ -74,8 +77,35 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
{
|
||||
QStyleOptionViewItemV4 o( *vioption );
|
||||
o.palette.setColor( QPalette::Text, textColor );
|
||||
return QStyledItemDelegate::paint( painter, o, index );
|
||||
|
||||
if ( item->isPlaying() )
|
||||
{
|
||||
o.palette.setColor( QPalette::Highlight, o.palette.color( QPalette::Mid ) );
|
||||
o.palette.setColor( QPalette::Text, o.palette.color( QPalette::HighlightedText ) );
|
||||
o.state |= QStyle::State_Selected;
|
||||
}
|
||||
|
||||
qApp->style()->drawControl( QStyle::CE_ItemViewItem, &o, painter );
|
||||
|
||||
{
|
||||
QRect r = o.rect.adjusted( 3, 0, 0, 0 );
|
||||
|
||||
// Paint Now Playing Speaker Icon
|
||||
if ( item->isPlaying() && m_view->header()->visualIndex( index.column() ) == 0 )
|
||||
{
|
||||
r.adjust( 0, 0, 0, -3 );
|
||||
painter->drawPixmap( r.adjusted( 3, 1, 18 - r.width(), 1 ), m_nowPlayingIcon );
|
||||
r.adjust( 25, 0, 0, 3 );
|
||||
}
|
||||
|
||||
painter->setPen( o.palette.text().color() );
|
||||
|
||||
QTextOption to( Qt::AlignVCenter );
|
||||
QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, r.width() - 3 );
|
||||
painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, to );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
class ArtistView;
|
||||
class TreeProxyModel;
|
||||
|
||||
class DLLEXPORT TreeItemDelegate : public QStyledItemDelegate
|
||||
@@ -30,7 +31,7 @@ class DLLEXPORT TreeItemDelegate : public QStyledItemDelegate
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TreeItemDelegate( QAbstractItemView* parent = 0, TreeProxyModel* proxy = 0 );
|
||||
TreeItemDelegate( ArtistView* parent = 0, TreeProxyModel* proxy = 0 );
|
||||
|
||||
protected:
|
||||
void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
@@ -39,8 +40,10 @@ protected:
|
||||
// QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
|
||||
private:
|
||||
QAbstractItemView* m_view;
|
||||
ArtistView* m_view;
|
||||
TreeProxyModel* m_model;
|
||||
|
||||
QPixmap m_nowPlayingIcon;
|
||||
};
|
||||
|
||||
#endif // TREEITEMDELEGATE_H
|
||||
|