diff -Nru udj-desktop-client-0.5.1/.gitignore udj-desktop-client-0.6.3/.gitignore --- udj-desktop-client-0.5.1/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/.gitignore 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,2 @@ +build +.DS_Store diff -Nru udj-desktop-client-0.5.1/CMakeLists.txt udj-desktop-client-0.6.3/CMakeLists.txt --- udj-desktop-client-0.5.1/CMakeLists.txt 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/CMakeLists.txt 2012-11-15 20:49:42.000000000 +0000 @@ -18,9 +18,10 @@ cmake_minimum_required(VERSION 2.8.7) PROJECT(UDJ) -SET(PROJECT_VERSION_MAJOR 0) -SET(PROJECT_VERSION_MINOR 5) -SET(PROJECT_VERSION_PATCH 0) +include(VERSION.cmake) +SET(PROJECT_VERSION_MAJOR ${VERSION_MAJOR}) +SET(PROJECT_VERSION_MINOR ${VERSION_MINOR}) +SET(PROJECT_VERSION_PATCH ${VERSION_PATCH}) SET(PROJECT_COPYRIGHT_YEAR 2011) SET(PROJECT_VERNDOR "Bazaar Solutions") set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") @@ -28,12 +29,20 @@ set(PROJECT_DOMAIN_FIRST "klnusbaum") set(PROJECT_DOMAIN_SECOND "org") set(PROJECT_DOMAIN "${PROJECT_DOMAIN_FIRST}.${PROJECT_DOMAIN_SECOND}") +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") -FIND_PACKAGE(Qt4 4.4.3 - COMPONENTS QtMain QtCore QtGui Phonon QtSql QtNetwork QtXml REQUIRED) +FIND_PACKAGE(Qt4 4.7.1 + COMPONENTS QtMain QtCore QtGui QtSql QtNetwork QtXml REQUIRED) +FIND_PACKAGE(Phonon REQUIRED) +include_directories("${PHONON_INCLUDE_DIR}") +IF(WIN32) +FIND_LIBRARY(QTSPARKLE_LIBRARIES qtsparkle) +ENDIF(WIN32) include(UseQt4) +include(UDJCPack.cmake) + SET(CMAKE_AUTOMOC TRUE) FIND_LIBRARY(TAGLIB "tag" PATH) diff -Nru udj-desktop-client-0.5.1/CPackOptions.cmake.in udj-desktop-client-0.6.3/CPackOptions.cmake.in --- udj-desktop-client-0.5.1/CPackOptions.cmake.in 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/CPackOptions.cmake.in 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,77 @@ +# 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") + if( NOT EXISTS "@CMAKE_SOURCE_DIR@/admin/win/vlc/") + MESSAGE(FATAL_ERROR "\n You don't have vlc in your admin/win/ dir. \n Please change into that dir and execute 'sh update-vlc.sh'" ) + endif() + + #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@ ) \ No newline at end of file diff -Nru udj-desktop-client-0.5.1/ChangeLog udj-desktop-client-0.6.3/ChangeLog --- udj-desktop-client-0.5.1/ChangeLog 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/ChangeLog 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,19 @@ +Version 0.5.0 +Initial version of the UDJ Player + +Version 0.5.1 +Fixed playback issues for Windows player. Windows player now has an updater. + +Version 0.6.0 +Upgrade client to work with new API +Fixed numerous playback errors +Fixed numerous reauthentication errors + +Version 0.6.1 +Added view of current participants + +Version 0.6.2 +Fixed some linux things + +Version 0.6.3 +Fixed player creation diff -Nru udj-desktop-client-0.5.1/README.md udj-desktop-client-0.6.3/README.md --- udj-desktop-client-0.5.1/README.md 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/README.md 2012-11-15 20:49:42.000000000 +0000 @@ -28,6 +28,9 @@ via [homebrew][brew]. On Linux, most distributions have the taglib library in their repository. On Windows, shit is tough. I'll try to add some instructions on that later. +4. (Windows Only) OpenSSL is not bundled with Windows for severally reasons (all of which piss off the lead developer). +A binary distribution for windows can be found [here][win-openssl]. + ### Configuring If you've installed all of your libraries and cmake in default locations, configuring should be very straight forward. Simply use cmake to configure the project (we recommend an out of @@ -65,7 +68,18 @@ SET( QT_PHONON_BACKEND_PLUGINS phonon_ds9 ) ENDIF() +### Building on Ubuntu 12.04 LTS +1. Enter the command "sudo apt-get update" into Terminal to update the repository on your machine. +2. Enter the command "sudo apt-get install" with the following dependencies to build UDJ: + - cmake + - libqt4-dev + - libtag1-dev + - liphonon-dev + - phonon-backend-vlc + - build essentials +3. In the /build folder, enter "make" into the Terminal to create a MakeFile +4. Change into the /src folder and enter "./udj" to run the UDJ Desktop Application ### Building CMake will generate different projects base on your host system. On OSX and Linux the default is @@ -87,7 +101,7 @@ the [UDJ mailing list][mailing]. [home]:https://www.udjplayer.com -[server]:https://github.com/klnusbaum/UDJ +[server]:https://github.com/klnusbaum/UDJ-Server [kln]:https://github.com/klnusbaum/ [gpl]:https://github.com/klnusbaum/UDJ-Desktop-Client/blob/master/LICENSE [cmake]:http://www.cmake.org/cmake/resources/software.html @@ -97,3 +111,4 @@ [mailing]:mailto:udjdev@bazaarsolutions.com [deploypatch]:https://github.com/downloads/klnusbaum/UDJ-Desktop-Client/0001-DeployQt4-Set-executable_path-if-actually-passed.patch [findphononpatch]:https://github.com/downloads/klnusbaum/UDJ-Desktop-Client/0001-phonon-backend-tweak.patch +[win-openssl]:http://www.openssl.org/related/binaries.html diff -Nru udj-desktop-client-0.5.1/UDJCPack.cmake udj-desktop-client-0.6.3/UDJCPack.cmake --- udj-desktop-client-0.5.1/UDJCPack.cmake 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/UDJCPack.cmake 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,62 @@ +include( InstallRequiredSystemLibraries ) + +set( CPACK_PACKAGE_CONTACT "Kurtis Nusbaum " ) + +set( APPLICATION_NAME "UDJ") + +include( VERSION.cmake ) +set( CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR} ) +set( CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR} ) +set( CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH} ) +set( CPACK_PACKAGE_VERSION ${VERSION} ) + +if(APPLE) + set( CPACK_GENERATOR "DragNDrop" ) + set( CPACK_SOURCE_GENERATOR "") + set( CPACK_PACKAGE_FILE_NAME UDJSetup-${CPACK_PACKAGE_VERSION} ) + set( CPACK_PACKAGE_ICON ${CMAKE_BINARY_DIR}/icons/udjlauncher.icns) + + set( CPACK_DMG_DS_STORE "${CMAKE_SOURCE_DIR}/admin/osx/DS_Store.in") + set( CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/admin/osx/DMGBackground.png" ) + + set( CPACK_DMG_FORMAT "UDBZ" ) + set( CPACK_DMG_VOLUME_NAME "${APPLICATION_NAME}") + + # did not work with cmake 2.8.7, so we override MacOSXBundleInfo.plist.in + #set( CPACK_BUNDLE_PLIST ${CMAKE_SOURCE_DIR}/admin/osx/Info.plist ) + + # do we need these? + #set( CPACK_SYSTEM_NAME "OSX" ) + #set( CPACK_PACKAGE_NAME "FOO" ) + #set( CPACK_BUNDLE_NAME "BAR" ) +endif() + + + + +if(WIN32) + set( CPACK_PACKAGE_FILE_NAME UDJ-${CPACK_PACKAGE_VERSION}-setup ) + # 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.md" ) # File used as a description of a project /path/to/project/ReadMe.txt + set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "UDJ Desktop Player Client" ) # 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 ${APPLICATION_NAME} ) # Installation directory on the target system -> C:\Program Files\UDJ + set( CPACK_PACKAGE_INSTALL_REGISTRY_KEY ${APPLICATION_NAME} ) # Registry key used when installing this project CMake 2.5.0 + set( CPACK_PACKAGE_NAME ${APPLICATION_NAME} ) # Package name, defaults to the project name + set( CPACK_PACKAGE_VENDOR "http://udjplayer.com" ) # Package vendor name +endif() + +# 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 + + +set( CPACK_TOPLEVEL_TAG "unused" ) # Directory for the installed files. - needed to provide anything to avoid an error# CPACK_INSTALL_COMMANDS Extra commands to install components. + + +# Set the options file that needs to be included inside CMakeCPackOptions.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) diff -Nru udj-desktop-client-0.5.1/VERSION.cmake udj-desktop-client-0.6.3/VERSION.cmake --- udj-desktop-client-0.5.1/VERSION.cmake 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/VERSION.cmake 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,5 @@ +set( VERSION_MAJOR 0 ) +set( VERSION_MINOR 6 ) +set( VERSION_PATCH 3 ) +set( VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH} ) + diff -Nru udj-desktop-client-0.5.1/admin/mac/create-dmg.sh udj-desktop-client-0.6.3/admin/mac/create-dmg.sh --- udj-desktop-client-0.5.1/admin/mac/create-dmg.sh 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/admin/mac/create-dmg.sh 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,80 @@ +#!/bin/sh + +# === This file is part of Tomahawk Player - === +# +# Copyright 2011, John Maguire +# +# 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 . + +# author: max@last.fm, muesli@tomahawk-player.org +# brief: Produces a compressed DMG from a bundle directory +# usage: Pass the bundle directory as the only parameter +# note: This script depends on the UDJ build system, and must be run from +# the build directory +#Shamelessly stolen from the tomahawk project. Super thanks to them. +################################################################################ + + + +#if [ -z $VERSION ] +#then +# echo VERSION must be set +# exit 2 +#fi + +if [ -z "$1" ] +then + echo "Please pass the bundle.app directory as the first parameter." + exit 3 +fi +################################################################################ + + +NAME=$(basename "$1" | perl -pe 's/(.*).app/\1/') +IN="$1" +TMP="dmg/$NAME" +OUT="$NAME.dmg" +mkdir -p "$TMP" +################################################################################ + + +# clean up +rm -rf "$TMP" +rm -f "$OUT" + +# create DMG contents and copy files +mkdir "$TMP" +#mkdir -p "$TMP/.background" +#cp ../admin/mac/dmg_background.png "$TMP/.background/background.png" +#cp ../admin/mac/DS_Store.in "$TMP/.DS_Store" +#chmod go-rwx "$TMP/.DS_Store" +ln -s /Applications "$TMP/Applications" +# copies the prepared bundle into the dir that will become the DMG +cp -R "$IN" "$TMP" + +# create +hdiutil makehybrid -hfs -hfs-volume-name UDJ -hfs-openfolder "$TMP" "$TMP" -o tmp.dmg +hdiutil convert -format UDZO -imagekey zlib-level=9 tmp.dmg -o "$OUT" + +# cleanup +rm tmp.dmg + +#hdiutil create -srcfolder "$TMP" \ +# -format UDZO -imagekey zlib-level=9 \ +# -scrub \ +# "$OUT" \ +# || die "Error creating DMG :(" + +# done ! +echo 'DMG size:' `du -hs "$OUT" | awk '{print $1}'` diff -Nru udj-desktop-client-0.5.1/admin/mac/macdeploy.py udj-desktop-client-0.6.3/admin/mac/macdeploy.py --- udj-desktop-client-0.5.1/admin/mac/macdeploy.py 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/admin/mac/macdeploy.py 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,501 @@ +#!/usr/bin/python +# This file is part of UDJ. +# It was inspired in large part by the macdeploy script in Clementine. +# +# Copyright 2012, Kurtis L. Nusbaum +# Copyright 2010, David Sansome +# +# Clementine 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. +# +# Clementine 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 Clementine. If not, see . + +import os +import re +import subprocess +import commands +import sys + +FRAMEWORK_SEARCH_PATH=[ + '/Library/Frameworks', + os.path.join(os.environ['HOME'], 'Library/Frameworks') +] + +LIBRARY_SEARCH_PATH=['/usr/local/lib', '/usr/local/Cellar/gettext/0.18.1.1/lib', '.'] + +VLC_PLUGINS=[ + 'libaccess_attachment_plugin.dylib', + #'libaccess_avio_plugin.dylib', + #'libaccess_fake_plugin.dylib', + 'libaccess_ftp_plugin.dylib', + 'libaccess_http_plugin.dylib', + 'libaccess_imem_plugin.dylib', + #'libaccess_mmap_plugin.dylib', + 'libaccess_mms_plugin.dylib', + 'libaccess_realrtsp_plugin.dylib', + 'libaccess_tcp_plugin.dylib', + 'libaccess_udp_plugin.dylib', + 'libcdda_plugin.dylib', + 'libfilesystem_plugin.dylib', + 'libqtcapture_plugin.dylib', + 'librtp_plugin.dylib', + 'libzip_plugin.dylib', + 'libaccess_output_dummy_plugin.dylib', + 'libaccess_output_file_plugin.dylib', + 'libaccess_output_http_plugin.dylib', + 'libaccess_output_shout_plugin.dylib', + 'libaccess_output_udp_plugin.dylib', + 'liba52tofloat32_plugin.dylib', + 'liba52tospdif_plugin.dylib', + 'libaudio_format_plugin.dylib', + 'libaudiobargraph_a_plugin.dylib', + 'libchorus_flanger_plugin.dylib', + 'libconverter_fixed_plugin.dylib', + 'libdolby_surround_decoder_plugin.dylib', + 'libdtstofloat32_plugin.dylib', + 'libdtstospdif_plugin.dylib', + 'libequalizer_plugin.dylib', + 'libheadphone_channel_mixer_plugin.dylib', + 'libmono_plugin.dylib', + 'libmpgatofixed32_plugin.dylib', + 'libnormvol_plugin.dylib', + 'libparam_eq_plugin.dylib', + 'libscaletempo_plugin.dylib', + 'libsimple_channel_mixer_plugin.dylib', + 'libspatializer_plugin.dylib', + 'libtrivial_channel_mixer_plugin.dylib', + 'libugly_resampler_plugin.dylib', + 'libfloat32_mixer_plugin.dylib', + #'libspdif_mixer_plugin.dylib', + #'libtrivial_mixer_plugin.dylib', + 'libaout_file_plugin.dylib', + 'libauhal_plugin.dylib', + 'liba52_plugin.dylib', + 'libadpcm_plugin.dylib', + 'libaes3_plugin.dylib', + 'libaraw_plugin.dylib', + 'libavcodec_plugin.dylib', + 'libcc_plugin.dylib', + 'libcdg_plugin.dylib', + 'libdts_plugin.dylib', + 'libfaad_plugin.dylib', + #'libfake_plugin.dylib', + 'libflac_plugin.dylib', + 'libfluidsynth_plugin.dylib', + #'libinvmem_plugin.dylib', + 'liblpcm_plugin.dylib', + 'libmpeg_audio_plugin.dylib', + 'libpng_plugin.dylib', + 'librawvideo_plugin.dylib', + 'libspeex_plugin.dylib', + 'libspudec_plugin.dylib', + 'libtheora_plugin.dylib', + 'libtwolame_plugin.dylib', + 'libvorbis_plugin.dylib', + 'libgestures_plugin.dylib', + 'libhotkeys_plugin.dylib', + 'libmotion_plugin.dylib', + 'libnetsync_plugin.dylib', + #'libsignals_plugin.dylib', + 'libaiff_plugin.dylib', + 'libasf_plugin.dylib', + 'libau_plugin.dylib', + #'libavformat_plugin.dylib', + 'libavi_plugin.dylib', + 'libdemux_cdg_plugin.dylib', + 'libdemuxdump_plugin.dylib', + 'libdirac_plugin.dylib', + 'libes_plugin.dylib', + 'libflacsys_plugin.dylib', + 'liblive555_plugin.dylib', + 'libmkv_plugin.dylib', + 'libmod_plugin.dylib', + 'libmp4_plugin.dylib', + 'libmpc_plugin.dylib', + 'libmpgv_plugin.dylib', + 'libnsc_plugin.dylib', + 'libnsv_plugin.dylib', + 'libnuv_plugin.dylib', + 'libogg_plugin.dylib', + 'libplaylist_plugin.dylib', + 'libps_plugin.dylib', + 'libpva_plugin.dylib', + 'librawaud_plugin.dylib', + 'librawdv_plugin.dylib', + 'librawvid_plugin.dylib', + 'libreal_plugin.dylib', + 'libsmf_plugin.dylib', + 'libts_plugin.dylib', + 'libtta_plugin.dylib', + 'libty_plugin.dylib', + 'libvc1_plugin.dylib', + 'libvoc_plugin.dylib', + 'libwav_plugin.dylib', + 'libxa_plugin.dylib', + 'libfolder_plugin.dylib', + 'libtaglib_plugin.dylib', + 'libaudioscrobbler_plugin.dylib', + 'libdummy_plugin.dylib', + 'libexport_plugin.dylib', + 'libfreetype_plugin.dylib', + 'libgnutls_plugin.dylib', + 'liblogger_plugin.dylib', + 'liblua_plugin.dylib', + 'libosd_parser_plugin.dylib', + 'libquartztext_plugin.dylib', + 'libstats_plugin.dylib', + 'libvod_rtsp_plugin.dylib', + 'libxml_plugin.dylib', + #'libxtag_plugin.dylib', + 'libi420_rgb_mmx_plugin.dylib', + 'libi420_yuy2_mmx_plugin.dylib', + 'libi422_yuy2_mmx_plugin.dylib', + 'libmemcpymmx_plugin.dylib', + 'libmemcpymmxext_plugin.dylib', + 'libmux_asf_plugin.dylib', + 'libmux_avi_plugin.dylib', + 'libmux_dummy_plugin.dylib', + 'libmux_mp4_plugin.dylib', + 'libmux_mpjpeg_plugin.dylib', + 'libmux_ogg_plugin.dylib', + 'libmux_ps_plugin.dylib', + 'libmux_ts_plugin.dylib', + 'libmux_wav_plugin.dylib', + 'libpacketizer_copy_plugin.dylib', + 'libpacketizer_dirac_plugin.dylib', + 'libpacketizer_flac_plugin.dylib', + 'libpacketizer_h264_plugin.dylib', + 'libpacketizer_mlp_plugin.dylib', + 'libpacketizer_mpeg4audio_plugin.dylib', + 'libpacketizer_mpeg4video_plugin.dylib', + 'libpacketizer_mpegvideo_plugin.dylib', + 'libpacketizer_vc1_plugin.dylib', + 'libi420_rgb_sse2_plugin.dylib', + 'libi420_yuy2_sse2_plugin.dylib', + 'libi422_yuy2_sse2_plugin.dylib', + 'libdecomp_plugin.dylib', + 'libstream_filter_rar_plugin.dylib', + 'libstream_filter_record_plugin.dylib', + 'libvisual_plugin.dylib', +] + +VLC_SEARCH_PATH=[ + '/usr/local/lib/vlc/plugins/', +] + +QT_PLUGINS = [ + 'crypto/libqca-ossl.dylib', + 'phonon_backend/phonon_vlc.so', + 'sqldrivers/libqsqlite.dylib', + 'imageformats/libqgif.dylib', + 'imageformats/libqico.dylib', + 'imageformats/libqjpeg.dylib', + 'imageformats/libqmng.dylib', +] + +QT_PLUGINS_SEARCH_PATH=[ + '/usr/local/Cellar/qt/4.8.2/plugins', +] + + +class Error(Exception): + pass + + +class CouldNotFindQtPluginErrorFindFrameworkError(Error): + pass + + +class InstallNameToolError(Error): + pass + + +class CouldNotFindQtPluginError(Error): + pass + + +class CouldNotFindVLCPluginError(Error): + pass + + + + + +if len(sys.argv) < 2: + print 'Usage: %s ' % sys.argv[0] + +bundle_dir = sys.argv[1] + +bundle_name = os.path.basename(bundle_dir).split('.')[0] + +commands = [] + +binary_dir = os.path.join(bundle_dir, 'Contents', 'MacOS') +frameworks_dir = os.path.join(bundle_dir, 'Contents', 'Frameworks') +commands.append(['mkdir', '-p', frameworks_dir]) +resources_dir = os.path.join(bundle_dir, 'Contents', 'Resources') +commands.append(['mkdir', '-p', resources_dir]) +plugins_dir = os.path.join(bundle_dir, 'Contents', 'qt-plugins') +binary = os.path.join(bundle_dir, 'Contents', 'MacOS', bundle_name) + +fixed_libraries = [] +fixed_frameworks = [] + +def GetBrokenLibraries(binary): + #print "Checking libs for binary: %s" % binary + output = subprocess.Popen(['otool', '-L', binary], stdout=subprocess.PIPE).communicate()[0] + broken_libs = { + 'frameworks': [], + 'libs': []} + for line in [x.split(' ')[0].lstrip() for x in output.split('\n')[1:]]: + #print "Checking line: %s" % line + if not line: # skip empty lines + continue + if os.path.basename(binary) == os.path.basename(line): + #print "mnope %s-%s" % (os.path.basename(binary), os.path.basename(line)) + continue + if re.match(r'^\s*/System/', line): + continue # System framework + elif re.match(r'^\s*/usr/lib/', line): + #print "unix style system lib" + continue # unix style system library + elif re.match(r'Breakpad', line): + continue # Manually added by cmake. + elif re.match(r'^\s*@executable_path', line) or re.match(r'^\s*@loader_path', line): + # Potentially already fixed library + if '.framework' in line: + relative_path = os.path.join(*line.split('/')[3:]) + if not os.path.exists(os.path.join(frameworks_dir, relative_path)): + broken_libs['frameworks'].append(relative_path) + else: + relative_path = os.path.join(*line.split('/')[1:]) + #print "RELPATH %s %s" % (relative_path, os.path.join(binary_dir, relative_path)) + if not os.path.exists(os.path.join(binary_dir, relative_path)): + broken_libs['libs'].append(relative_path) + elif re.search(r'\w+\.framework', line): + broken_libs['frameworks'].append(line) + else: + broken_libs['libs'].append(line) + + return broken_libs + +def FindFramework(path): + for search_path in FRAMEWORK_SEARCH_PATH: + abs_path = os.path.join(search_path, path) + if os.path.exists(abs_path): + return abs_path + + raise CouldNotFindFrameworkError(path) + +def FindLibrary(path): + if os.path.exists(path): + return path + for search_path in LIBRARY_SEARCH_PATH: + abs_path = os.path.join(search_path, path) + if os.path.exists(abs_path): + return abs_path + else: # try harder---look for lib name in library folders + newpath = os.path.join(search_path,os.path.basename(path)) + if os.path.exists(newpath): + return newpath + + return "" + #raise CouldNotFindFrameworkError(path) + +def FixAllLibraries(broken_libs): + for framework in broken_libs['frameworks']: + FixFramework(framework) + for lib in broken_libs['libs']: + FixLibrary(lib) + +def FixFramework(path): + if path in fixed_libraries: + return + else: + fixed_libraries.append(path) + abs_path = FindFramework(path) + broken_libs = GetBrokenLibraries(abs_path) + FixAllLibraries(broken_libs) + + new_path = CopyFramework(abs_path) + id = os.sep.join(new_path.split(os.sep)[3:]) + FixFrameworkId(new_path, id) + for framework in broken_libs['frameworks']: + FixFrameworkInstallPath(framework, new_path) + for library in broken_libs['libs']: + FixLibraryInstallPath(library, new_path) + +def FixLibrary(path): + if path in fixed_libraries or FindSystemLibrary(os.path.basename(path)) is not None: + return + else: + fixed_libraries.append(path) + abs_path = FindLibrary(path) + if abs_path == "": + print "Could not resolve %s, not fixing!" % path + return + broken_libs = GetBrokenLibraries(abs_path) + FixAllLibraries(broken_libs) + + new_path = CopyLibrary(abs_path) + FixLibraryId(new_path) + for framework in broken_libs['frameworks']: + FixFrameworkInstallPath(framework, new_path) + for library in broken_libs['libs']: + FixLibraryInstallPath(library, new_path) + +def FixVLCPlugin(abs_path, subdir): + broken_libs = GetBrokenLibraries(abs_path) + FixAllLibraries(broken_libs) + + #print "Copying plugin....%s %s %s" % (plugins_dir, subdir, os.path.join(abs_path.split('/')[-2:])) + new_path = os.path.join(plugins_dir, subdir, os.path.basename(abs_path)) + args = ['mkdir', '-p', os.path.dirname(new_path)] + commands.append(args) + args = ['ditto', '--arch=i386', '--arch=x86_64', abs_path, new_path] + commands.append(args) + args = ['chmod', 'u+w', new_path] + commands.append(args) + for framework in broken_libs['frameworks']: + FixFrameworkInstallPath(framework, new_path) + for library in broken_libs['libs']: + FixLibraryInstallPath(library, new_path) + +def FixPlugin(abs_path, subdir): + broken_libs = GetBrokenLibraries(abs_path) + FixAllLibraries(broken_libs) + + new_path = CopyPlugin(abs_path, subdir) + for framework in broken_libs['frameworks']: + FixFrameworkInstallPath(framework, new_path) + for library in broken_libs['libs']: + FixLibraryInstallPath(library, new_path) + +def FixBinary(path): + broken_libs = GetBrokenLibraries(path) + FixAllLibraries(broken_libs) + for framework in broken_libs['frameworks']: + FixFrameworkInstallPath(framework, path) + for library in broken_libs['libs']: + FixLibraryInstallPath(library, path) + +def CopyLibrary(path): + new_path = os.path.join(frameworks_dir, os.path.basename(path)) + args = ['ditto', '--arch=i386', '--arch=x86_64', path, new_path] + commands.append(args) + args = ['chmod', 'u+w', new_path] + commands.append(args) + return new_path + +def CopyPlugin(path, subdir): + new_path = os.path.join(plugins_dir, subdir, os.path.basename(path)) + args = ['mkdir', '-p', os.path.dirname(new_path)] + commands.append(args) + args = ['ditto', '--arch=i386', '--arch=x86_64', path, new_path] + commands.append(args) + args = ['chmod', 'u+w', new_path] + commands.append(args) + return new_path + +def CopyFramework(path): + parts = path.split(os.sep) + for i, part in enumerate(parts): + if re.match(r'\w+\.framework', part): + full_path = os.path.join(frameworks_dir, *parts[i:-1]) + break + args = ['mkdir', '-p', full_path] + commands.append(args) + args = ['ditto', '--arch=i386', '--arch=x86_64', path, full_path] + commands.append(args) + args = ['chmod', 'u+w', os.path.join(full_path, parts[-1])] + commands.append(args) + + menu_nib = os.path.join(os.path.split(path)[0], 'Resources', 'qt_menu.nib') + if os.path.exists(menu_nib): + args = ['cp', '-r', menu_nib, resources_dir] + commands.append(args) + + return os.path.join(full_path, parts[-1]) + +def FixId(path, library_name): + id = '@executable_path/../Frameworks/%s' % library_name + args = ['install_name_tool', '-id', id, path] + commands.append(args) + +def FixLibraryId(path): + library_name = os.path.basename(path) + FixId(path, library_name) + +def FixFrameworkId(path, id): + FixId(path, id) + +def FixInstallPath(library_path, library, new_path): + args = ['install_name_tool', '-change', library_path, new_path, library] + commands.append(args) + +def FindSystemLibrary(library_name): + for path in ['/lib', '/usr/lib']: + full_path = os.path.join(path, library_name) + if os.path.exists(full_path): + return full_path + return None + +def FixLibraryInstallPath(library_path, library): + system_library = FindSystemLibrary(os.path.basename(library_path)) + if system_library is None: + new_path = '@executable_path/../Frameworks/%s' % os.path.basename(library_path) + FixInstallPath(library_path, library, new_path) + else: + FixInstallPath(library_path, library, system_library) + +def FixFrameworkInstallPath(library_path, library): + parts = library_path.split(os.sep) + for i, part in enumerate(parts): + if re.match(r'\w+\.framework', part): + full_path = os.path.join(*parts[i:]) + break + new_path = '@executable_path/../Frameworks/%s' % full_path + FixInstallPath(library_path, library, new_path) + +def FindQtPlugin(name): + for path in QT_PLUGINS_SEARCH_PATH: + if os.path.exists(path): + if os.path.exists(os.path.join(path, name)): + return os.path.join(path, name) + raise CouldNotFindQtPluginError(name) + + +def FindVLCPlugin(name): + for path in VLC_SEARCH_PATH: + if os.path.exists(path): + if os.path.exists(os.path.join(path, name)): + return os.path.join(path, name) + raise CouldNotFindVLCPluginError(name) + +FixBinary(binary) + +for plugin in VLC_PLUGINS: + FixVLCPlugin(FindVLCPlugin(plugin), '../plugins') + +for plugin in QT_PLUGINS: + FixPlugin(FindQtPlugin(plugin), os.path.dirname(plugin)) + +if len(sys.argv) <= 2: + print 'Would run %d commands:' % len(commands) + for command in commands: + print ' '.join(command) + + print 'OK?' + raw_input() + +for command in commands: + p = subprocess.Popen(command) + os.waitpid(p.pid, 0) diff -Nru udj-desktop-client-0.5.1/admin/mac/makeMacInstaller.sh udj-desktop-client-0.6.3/admin/mac/makeMacInstaller.sh --- udj-desktop-client-0.5.1/admin/mac/makeMacInstaller.sh 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/admin/mac/makeMacInstaller.sh 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright 2012 Kurtis L. Nusbaum +# +# This file is part of UDJ. +# +# UDJ 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 2 of the License, or +# (at your option) any later version. +# +# UDJ 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 UDJ. If not, see . + +python ../admin/mac/macdeploy.py src/UDJ.app +cp ../admin/mac/qt.conf src/UDJ.app/Contents/Resources/ +mv src/UDJ.app/Contents/plugins src/UDJ.app/Contents/Frameworks +#cp -R /Library/Frameworks/Sparkle.framework Contents/Frameworks +../admin/mac/create-dmg.sh src/UDJ.app diff -Nru udj-desktop-client-0.5.1/admin/mac/qt.conf udj-desktop-client-0.6.3/admin/mac/qt.conf --- udj-desktop-client-0.5.1/admin/mac/qt.conf 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/admin/mac/qt.conf 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,2 @@ +[Paths] +Plugins = qt-plugins diff -Nru udj-desktop-client-0.5.1/admin/win/nsi/RELEASE_NOTES.TXT udj-desktop-client-0.6.3/admin/win/nsi/RELEASE_NOTES.TXT --- udj-desktop-client-0.5.1/admin/win/nsi/RELEASE_NOTES.TXT 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/admin/win/nsi/RELEASE_NOTES.TXT 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1 @@ +No notes at this time Binary files /tmp/2fJn3HRETe/udj-desktop-client-0.5.1/admin/win/nsi/installer.ico and /tmp/s8fDTrg7pV/udj-desktop-client-0.6.3/admin/win/nsi/installer.ico differ Binary files /tmp/2fJn3HRETe/udj-desktop-client-0.5.1/admin/win/nsi/page_header.jpg and /tmp/s8fDTrg7pV/udj-desktop-client-0.6.3/admin/win/nsi/page_header.jpg differ Binary files /tmp/2fJn3HRETe/udj-desktop-client-0.5.1/admin/win/nsi/welcome.png and /tmp/s8fDTrg7pV/udj-desktop-client-0.6.3/admin/win/nsi/welcome.png differ diff -Nru udj-desktop-client-0.5.1/admin/win/update-vlc.sh udj-desktop-client-0.6.3/admin/win/update-vlc.sh --- udj-desktop-client-0.5.1/admin/win/update-vlc.sh 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/admin/win/update-vlc.sh 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,103 @@ +#!/bin/bash + +# === This file is part of Tomahawk Player - === +# +# Copyright 2011-2012, Dominik Schmidt +# +# 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 . + +# Shamelessly taken from the tomahawk project. All prasises to domme for setting +# this up. +# www.tomahawk-player.com + +if [ "$1" = "-c" ] ; then +echo "Continuing last download.." +rm -rvf vlc/ +else +echo "Update archive..." +fi + +rm -rvf vlc/ + + +echo "Download phonon archive..." +# wget -c "http://downloads.sourceforge.net/project/vlc/1.1.9/win32/vlc-1.1.9-win32.7z?r=http%3A%2F%2Fwww.videolan.org%2Fvlc%2Fdownload-windows.html&ts=1306272584&use_mirror=leaseweb" +# wget -c "http://download.tomahawk-player.org/tomahawk-vlc-0.1.zip" +# wget -c http://people.videolan.org/~jb/phonon/phonon-vlc-last.7z +# wget -c http://people.videolan.org/~jb/phonon/phonon_phonon-vlc_20111128.7z +wget -c http://download.tomahawk-player.org/test/pvlc.tar.bz2 + +echo "Extract binary..." +# 7z x phonon*.7z +# mv -v vlc-*/ vlc/ +# unzip tomahawk-vlc-0.1.zip +tar xvjf pvlc.tar.bz2 + +# echo "Download phonon_vlc_no_video.dll..." +# wget -c http://people.videolan.org/~jb/phonon/phonon_vlc_no_video.dll +# cp -v phonon_vlc_no_video.dll prefix/bin/phonon_backend/phonon_vlc.dll + +# echo "Strip unneeded plugins from vlc/plugins..." +# cd prefix/bin/plugins +# rm -rvf libold* libvcd* libdvd* liblibass* libx264* libschroe* liblibmpeg2* \ +# libstream_out_* libmjpeg_plugin* libh264_plugin* libzvbi_plugin* lib*sub* \ +# *qt4* *skins2* libaccess_bd_plugin.dll \ +# libaudiobargraph_* libball_plugin.dll \ +# libdirac_plugin.dll \ +# libgnutls_plugin.dll \ +# libcaca_plugin.dll \ +# libfreetype_plugin.dll \ +# libaccess_output_shout_plugin.dll \ +# libremoteosd_plugin.dll \ +# libsdl_image_plugin.dll \ +# libvout_sdl_plugin.dll \ +# libpng_plugin.dll \ +# libgoom_plugin.dll \ +# libatmo_plugin.dll \ +# libmux_ts_plugin.dll \ +# libkate_plugin.dll \ +# libtaglib_plugin.dll + + +# this is for vlc-2.x +rm -rvf \ + video_*/ \ + gui/ \ + **/libold* \ + **/libvcd* \ + **/libdvd* \ + **/liblibass* \ + **/libx264* \ + **/libschroe* \ + **/liblibmpeg2* \ + **/libstream_out_* \ + **/libmjpeg_plugin* \ + **/libh264_plugin* \ + **/libzvbi_plugin* \ + **/lib*sub* \ + services_discovery/ \ + visualization/ \ + control/ \ + misc/ \ + **/libi420* \ + **/libi422* \ + mux/ \ + stream_filter/ \ + **/libtheora_plugin* \ + **/liblibbluray_plugin* \ + **/libdtv_plugin* + + +echo "Downloaded and stripped VLC" + diff -Nru udj-desktop-client-0.5.1/admin_win_Toolchain-mingw32-openSUSE.cmake udj-desktop-client-0.6.3/admin_win_Toolchain-mingw32-openSUSE.cmake --- udj-desktop-client-0.5.1/admin_win_Toolchain-mingw32-openSUSE.cmake 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/admin_win_Toolchain-mingw32-openSUSE.cmake 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,34 @@ +SET(MINGW_PREFIX "i686-w64-mingw32") + +# this one is important +SET(CMAKE_SYSTEM_NAME Windows) + + +# specify the cross compiler +SET(CMAKE_C_COMPILER ${MINGW_PREFIX}-gcc) +SET(CMAKE_CXX_COMPILER ${MINGW_PREFIX}-g++) +SET(CMAKE_RC_COMPILER ${MINGW_PREFIX}-windres) + +# where is the target environment containing libraries +SET(CMAKE_FIND_ROOT_PATH /usr/${MINGW_PREFIX}/sys-root/mingw) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + + +## configure qt variables +# generic +SET(QMAKESPEC win32-g++-cross) + +# dirs +SET(QT_LIBRARY_DIR /usr/${MINGW_PREFIX}/bin) +SET(QT_PLUGINS_DIR ${CMAKE_FIND_ROOT_PATH}/lib/qt4/plugins) +SET(QT_MKSPECS_DIR ${CMAKE_FIND_ROOT_PATH}/share/qt4/mkspecs) +SET(QT_QT_INCLUDE_DIR ${CMAKE_FIND_ROOT_PATH}/include) + +# qt tools +SET(QT_QMAKE_EXECUTABLE ${MINGW_PREFIX}-qmake ) +SET(QT_MOC_EXECUTABLE ${MINGW_PREFIX}-moc) +SET(QT_RCC_EXECUTABLE ${MINGW_PREFIX}-rcc) +SET(QT_UIC_EXECUTABLE ${MINGW_PREFIX}-uic) +SET(QT_LRELEASE_EXECUTABLE ${MINGW_PREFIX}-lrelease) diff -Nru udj-desktop-client-0.5.1/cmake/modules/AddAppIconMacro.cmake udj-desktop-client-0.6.3/cmake/modules/AddAppIconMacro.cmake --- udj-desktop-client-0.5.1/cmake/modules/AddAppIconMacro.cmake 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/cmake/modules/AddAppIconMacro.cmake 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,114 @@ +SET(WINDRES_EXECUTABLE ${CMAKE_RC_COMPILER}) + +# This macro is taken from kdelibs/cmake/modules/KDE4Macros.cmake. +# +# Copyright (c) 2006-2009 Alexander Neundorf, +# Copyright (c) 2006, 2007, Laurent Montel, +# Copyright (c) 2007 Matthias Kretz +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file [in KDE repositories]. + + +# adds application icon to target source list +# for detailed documentation see the top of FindKDE4Internal.cmake +macro (KDE4_ADD_APP_ICON appsources pattern) + set (_outfilename ${CMAKE_CURRENT_BINARY_DIR}/${appsources}) + + if (WIN32) + if(NOT WINCE) + find_program(PNG2ICO_EXECUTABLE NAMES png2ico) + else(NOT WINCE) + find_program(PNG2ICO_EXECUTABLE NAMES png2ico PATHS ${HOST_BINDIR} NO_DEFAULT_PATH ) + endif(NOT WINCE) + find_program(WINDRES_EXECUTABLE NAMES windres) + if(MSVC) + set(WINDRES_EXECUTABLE TRUE) + endif(MSVC) + if (PNG2ICO_EXECUTABLE AND WINDRES_EXECUTABLE) + string(REPLACE "*" "(.*)" pattern_rx "${pattern}") + file(GLOB files "${pattern}") + foreach (it ${files}) + string(REGEX REPLACE "${pattern_rx}" "\\1" fn "${it}") + if (fn MATCHES ".*16.*" ) + list (APPEND _icons ${it}) + endif (fn MATCHES ".*16.*") + if (fn MATCHES ".*32.*" ) + list (APPEND _icons ${it}) + endif (fn MATCHES ".*32.*") + if (fn MATCHES ".*48.*" ) + list (APPEND _icons ${it}) + endif (fn MATCHES ".*48.*") + if (fn MATCHES ".*64.*" ) + list (APPEND _icons ${it}) + endif (fn MATCHES ".*64.*") + if (fn MATCHES ".*128.*" ) + list (APPEND _icons ${it}) + endif (fn MATCHES ".*128.*") + endforeach (it) + if (_icons) + add_custom_command(OUTPUT ${_outfilename}.ico ${_outfilename}.rc + COMMAND ${PNG2ICO_EXECUTABLE} ARGS --rcfile ${_outfilename}.rc ${_outfilename}.ico ${_icons} + DEPENDS ${PNG2ICO_EXECUTABLE} ${_icons} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + if (MINGW) + add_custom_command(OUTPUT ${_outfilename}_res.o + COMMAND ${WINDRES_EXECUTABLE} ARGS -i ${_outfilename}.rc -o ${_outfilename}_res.o --include-dir=${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${WINDRES_EXECUTABLE} ${_outfilename}.rc + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + list(APPEND ${appsources} ${_outfilename}_res.o) + else(MINGW) + list(APPEND ${appsources} ${_outfilename}.rc) + endif(MINGW) + else(_icons) + message(STATUS "Unable to find a related icon that matches pattern ${pattern} for variable ${appsources} - application will not have an application icon!") + endif(_icons) + else(PNG2ICO_EXECUTABLE AND WINDRES_EXECUTABLE) + message(STATUS "Unable to find the png2ico or windres utilities - application will not have an application icon!") + endif(PNG2ICO_EXECUTABLE AND WINDRES_EXECUTABLE) + endif(WIN32) + if (Q_WS_MAC) + # first convert image to a tiff using the Mac OS X "sips" utility, + # then use tiff2icns to convert to an icon + find_program(SIPS_EXECUTABLE NAMES sips) + find_program(TIFF2ICNS_EXECUTABLE NAMES tiff2icns) + if (SIPS_EXECUTABLE AND TIFF2ICNS_EXECUTABLE) + file(GLOB_RECURSE files "${pattern}") + # we can only test for the 128-icon like that - we don't use patterns anymore + foreach (it ${files}) + if (it MATCHES ".*128.*" ) + set (_icon ${it}) + endif (it MATCHES ".*128.*") + endforeach (it) + + if (_icon) + + # first, get the basename of our app icon + add_custom_command(OUTPUT ${_outfilename}.icns ${outfilename}.tiff + COMMAND ${SIPS_EXECUTABLE} -s format tiff ${_icon} --out ${outfilename}.tiff + COMMAND ${TIFF2ICNS_EXECUTABLE} ${outfilename}.tiff ${_outfilename}.icns + DEPENDS ${_icon} + ) + + # This will register the icon into the bundle + set(MACOSX_BUNDLE_ICON_FILE ${appsources}.icns) + + # Append the icns file to the sources list so it will be a dependency to the + # main target + list(APPEND ${appsources} ${_outfilename}.icns) + + # Install the icon into the Resources dir in the bundle + set_source_files_properties(${_outfilename}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + + else(_icon) + # TODO - try to scale a non-128 icon...? Try to convert an SVG on the fly? + message(STATUS "Unable to find an 128x128 icon that matches pattern ${pattern} for variable ${appsources} - application will not have an application icon!") + endif(_icon) + + else(SIPS_EXECUTABLE AND TIFF2ICNS_EXECUTABLE) + message(STATUS "Unable to find the sips and tiff2icns utilities - application will not have an application icon!") + endif(SIPS_EXECUTABLE AND TIFF2ICNS_EXECUTABLE) + endif(Q_WS_MAC) +endmacro (KDE4_ADD_APP_ICON) diff -Nru udj-desktop-client-0.5.1/cmake/modules/FindLIBVLC.cmake udj-desktop-client-0.6.3/cmake/modules/FindLIBVLC.cmake --- udj-desktop-client-0.5.1/cmake/modules/FindLIBVLC.cmake 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/cmake/modules/FindLIBVLC.cmake 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,96 @@ + +# CMake module to search for LIBVLC (VLC library) +# Authors: Rohit Yadav +# Harald Sitter +# +# If it's found it sets LIBVLC_FOUND to TRUE +# and following variables are set: +# LIBVLC_INCLUDE_DIR +# LIBVLC_LIBRARY +# LIBVLC_VERSION + +if(NOT LIBVLC_MIN_VERSION) + set(LIBVLC_MIN_VERSION "0.0") +endif(NOT LIBVLC_MIN_VERSION) + +# find_path and find_library normally search standard locations +# before the specified paths. To search non-standard paths first, +# FIND_* is invoked first with specified paths and NO_DEFAULT_PATH +# and then again with no specified paths to search the default +# locations. When an earlier FIND_* succeeds, subsequent FIND_*s +# searching for the same item do nothing. + +if (NOT WIN32) + find_package(PkgConfig) + pkg_check_modules(PC_LIBVLC libvlc) + set(LIBVLC_DEFINITIONS ${PC_LIBVLC_CFLAGS_OTHER}) +endif (NOT WIN32) + +#Put here path to custom location +#example: /home/user/vlc/include etc.. +find_path(LIBVLC_INCLUDE_DIR vlc/vlc.h +HINTS "$ENV{LIBVLC_INCLUDE_PATH}" +PATHS + "$ENV{LIB_DIR}/include" + "$ENV{LIB_DIR}/include/vlc" + "/usr/include" + "/usr/include/vlc" + "/usr/local/include" + "/usr/local/include/vlc" + #mingw + c:/msys/local/include +) +find_path(LIBVLC_INCLUDE_DIR PATHS "${CMAKE_INCLUDE_PATH}/vlc" NAMES vlc.h + HINTS ${PC_LIBVLC_INCLUDEDIR} ${PC_LIBVLC_INCLUDE_DIRS}) + +#Put here path to custom location +#example: /home/user/vlc/lib etc.. +find_library(LIBVLC_LIBRARY NAMES vlc libvlc +HINTS "$ENV{LIBVLC_LIBRARY_PATH}" ${PC_LIBVLC_LIBDIR} ${PC_LIBVLC_LIBRARY_DIRS} +PATHS + "$ENV{LIB_DIR}/lib" + #mingw + c:/msys/local/lib +) +find_library(LIBVLC_LIBRARY NAMES vlc libvlc) +find_library(LIBVLCCORE_LIBRARY NAMES vlccore libvlccore +HINTS "$ENV{LIBVLC_LIBRARY_PATH}" ${PC_LIBVLC_LIBDIR} ${PC_LIBVLC_LIBRARY_DIRS} +PATHS + "$ENV{LIB_DIR}/lib" + #mingw + c:/msys/local/lib +) +find_library(LIBVLCCORE_LIBRARY NAMES vlccore libvlccore) + +set(LIBVLC_VERSION ${PC_LIBVLC_VERSION}) +if (NOT LIBVLC_VERSION) +# TODO: implement means to detect version on windows (vlc --version && regex? ... ultimately we would get it from a header though...) +endif (NOT LIBVLC_VERSION) + +if (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY) +set(LIBVLC_FOUND TRUE) +else (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY) + message(STATUS "LIBVLC INCLUDE DIR: ${LIBVLC_INCLUDE_DIR}") + message(STATUS "LIBVLC LIBRARY : ${LIBVLC_LIBRARY}") + message(STATUS "LIBVLC CORE LIBRARY : ${LIBVLCCORE_LIBRARY}") +endif (LIBVLC_INCLUDE_DIR AND LIBVLC_LIBRARY AND LIBVLCCORE_LIBRARY) + +if (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") + message(WARNING "LibVLC version not found: version searched: ${LIBVLC_MIN_VERSION}, found ${LIBVLC_VERSION}\nUnless you are on Windows this is bound to fail.") +# TODO: only activate once version detection can be garunteed (which is currently not the case on windows) +# set(LIBVLC_FOUND FALSE) +endif (LIBVLC_VERSION STRLESS "${LIBVLC_MIN_VERSION}") + +if (LIBVLC_FOUND) + if (NOT LIBVLC_FIND_QUIETLY) + message(STATUS "Found LibVLC include-dir path: ${LIBVLC_INCLUDE_DIR}") + message(STATUS "Found LibVLC library path:${LIBVLC_LIBRARY}") + message(STATUS "Found LibVLCcore library path:${LIBVLCCORE_LIBRARY}") + message(STATUS "Found LibVLC version: ${LIBVLC_VERSION} (searched for: ${LIBVLC_MIN_VERSION})") + endif (NOT LIBVLC_FIND_QUIETLY) +else (LIBVLC_FOUND) + if (LIBVLC_FIND_REQUIRED) + message(FATAL_ERROR "Could not find LibVLC") + endif (LIBVLC_FIND_REQUIRED) +endif (LIBVLC_FOUND) + diff -Nru udj-desktop-client-0.5.1/cmake/modules/FindOpenSSLCross.cmake udj-desktop-client-0.6.3/cmake/modules/FindOpenSSLCross.cmake --- udj-desktop-client-0.5.1/cmake/modules/FindOpenSSLCross.cmake 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/cmake/modules/FindOpenSSLCross.cmake 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,306 @@ +# - Try to find the OpenSSL encryption library +# Once done this will define +# +# OPENSSL_ROOT_DIR - Set this variable to the root installation of OpenSSL +# +# Read-Only variables: +# OPENSSL_FOUND - system has the OpenSSL library +# OPENSSL_INCLUDE_DIR - the OpenSSL include directory +# OPENSSL_LIBRARIES - The libraries needed to use OpenSSL +# OPENSSL_VERSION - This is set to $major.$minor.$revision$path (eg. 0.9.8s) + +#============================================================================= +# Copyright 2006-2009 Kitware, Inc. +# Copyright 2006 Alexander Neundorf +# Copyright 2009-2011 Mathieu Malaterre +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +if (UNIX) + find_package(PkgConfig QUIET) + pkg_check_modules(_OPENSSL QUIET openssl) +endif (UNIX) + +# http://www.slproweb.com/products/Win32OpenSSL.html +SET(_OPENSSL_ROOT_HINTS + $ENV{OPENSSL_ROOT_DIR} + ${OPENSSL_ROOT_DIR} + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]" + ) +SET(_OPENSSL_ROOT_PATHS + "$ENV{PROGRAMFILES}/OpenSSL" + "$ENV{PROGRAMFILES}/OpenSSL-Win32" + "$ENV{PROGRAMFILES}/OpenSSL-Win64" + "C:/OpenSSL/" + "C:/OpenSSL-Win32/" + "C:/OpenSSL-Win64/" + ) +SET(_OPENSSL_ROOT_HINTS_AND_PATHS + HINTS ${_OPENSSL_ROOT_HINTS} + PATHS ${_OPENSSL_ROOT_PATHS} + ) + +FIND_PATH(OPENSSL_INCLUDE_DIR + NAMES + openssl/ssl.h + HINTS + ${_OPENSSL_INCLUDEDIR} + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + include +) + +IF(WIN32 AND NOT CYGWIN) + # MINGW should go here too + IF(MSVC) + # /MD and /MDd are the standard values - if someone wants to use + # others, the libnames have to change here too + # use also ssl and ssleay32 in debug as fallback for openssl < 0.9.8b + # TODO: handle /MT and static lib + # In Visual C++ naming convention each of these four kinds of Windows libraries has it's standard suffix: + # * MD for dynamic-release + # * MDd for dynamic-debug + # * MT for static-release + # * MTd for static-debug + + # Implementation details: + # We are using the libraries located in the VC subdir instead of the parent directory eventhough : + # libeay32MD.lib is identical to ../libeay32.lib, and + # ssleay32MD.lib is identical to ../ssleay32.lib + FIND_LIBRARY(LIB_EAY_DEBUG + NAMES + libeay32MDd + libeay32 + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib" + "VC" + "lib/VC" + ) + + FIND_LIBRARY(LIB_EAY_RELEASE + NAMES + libeay32MD + libeay32 + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib" + "VC" + "lib/VC" + ) + + FIND_LIBRARY(SSL_EAY_DEBUG + NAMES + ssleay32MDd + ssleay32 + ssl + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib" + "VC" + "lib/VC" + ) + + FIND_LIBRARY(SSL_EAY_RELEASE + NAMES + ssleay32MD + ssleay32 + ssl + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib" + "VC" + "lib/VC" + ) + + if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) + set( OPENSSL_LIBRARIES + optimized ${SSL_EAY_RELEASE} debug ${SSL_EAY_DEBUG} + optimized ${LIB_EAY_RELEASE} debug ${LIB_EAY_DEBUG} + ) + else() + set( OPENSSL_LIBRARIES ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE} ) + endif() + MARK_AS_ADVANCED(SSL_EAY_DEBUG SSL_EAY_RELEASE) + MARK_AS_ADVANCED(LIB_EAY_DEBUG LIB_EAY_RELEASE) + ELSEIF(MINGW) + # same player, for MingW + FIND_LIBRARY(LIB_EAY + NAMES + libeay32 + crypto + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib" + "lib/MinGW" + ) + + FIND_LIBRARY(SSL_EAY + NAMES + ssleay32 + ssl + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + "lib" + "lib/MinGW" + ) + + MARK_AS_ADVANCED(SSL_EAY LIB_EAY) + set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} ) + ELSE(MSVC) + # Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues: + FIND_LIBRARY(LIB_EAY + NAMES + libeay32 + HINTS + ${_OPENSSL_LIBDIR} + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + lib + ) + + FIND_LIBRARY(SSL_EAY + NAMES + ssleay32 + HINTS + ${_OPENSSL_LIBDIR} + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + lib + ) + + MARK_AS_ADVANCED(SSL_EAY LIB_EAY) + set( OPENSSL_LIBRARIES ${SSL_EAY} ${LIB_EAY} ) + ENDIF(MSVC) +ELSE(WIN32 AND NOT CYGWIN) + + FIND_LIBRARY(OPENSSL_SSL_LIBRARY + NAMES + ssl + ssleay32 + ssleay32MD + HINTS + ${_OPENSSL_LIBDIR} + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + lib + ) + + FIND_LIBRARY(OPENSSL_CRYPTO_LIBRARY + NAMES + crypto + HINTS + ${_OPENSSL_LIBDIR} + ${_OPENSSL_ROOT_HINTS_AND_PATHS} + PATH_SUFFIXES + lib + ) + + MARK_AS_ADVANCED(OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY) + + # compat defines + SET(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY}) + SET(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) + + SET(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}) + +ENDIF(WIN32 AND NOT CYGWIN) + +function(from_hex HEX DEC) + string(TOUPPER "${HEX}" HEX) + set(_res 0) + string(LENGTH "${HEX}" _strlen) + + while (_strlen GREATER 0) + math(EXPR _res "${_res} * 16") + string(SUBSTRING "${HEX}" 0 1 NIBBLE) + string(SUBSTRING "${HEX}" 1 -1 HEX) + if (NIBBLE STREQUAL "A") + math(EXPR _res "${_res} + 10") + elseif (NIBBLE STREQUAL "B") + math(EXPR _res "${_res} + 11") + elseif (NIBBLE STREQUAL "C") + math(EXPR _res "${_res} + 12") + elseif (NIBBLE STREQUAL "D") + math(EXPR _res "${_res} + 13") + elseif (NIBBLE STREQUAL "E") + math(EXPR _res "${_res} + 14") + elseif (NIBBLE STREQUAL "F") + math(EXPR _res "${_res} + 15") + else() + math(EXPR _res "${_res} + ${NIBBLE}") + endif() + + string(LENGTH "${HEX}" _strlen) + endwhile() + + set(${DEC} ${_res} PARENT_SCOPE) +endfunction(from_hex) + +if (OPENSSL_INCLUDE_DIR) + if (_OPENSSL_VERSION) + set(OPENSSL_VERSION "${_OPENSSL_VERSION}") + elseif(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") + file(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h" openssl_version_str + REGEX "^#define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])+.*") + + # The version number is encoded as 0xMNNFFPPS: major minor fix patch status + # The status gives if this is a developer or prerelease and is ignored here. + # Major, minor, and fix directly translate into the version numbers shown in + # the string. The patch field translates to the single character suffix that + # indicates the bug fix state, which 00 -> nothing, 01 -> a, 02 -> b and so + # on. + + string(REGEX REPLACE "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F][0-9a-fA-F])([0-9a-fA-F]).*$" + "\\1;\\2;\\3;\\4;\\5" OPENSSL_VERSION_LIST "${openssl_version_str}") + list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR) + list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR) + from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR) + list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX) + from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX) + list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH) + + if (NOT OPENSSL_VERSION_PATCH STREQUAL "00") + from_hex("${OPENSSL_VERSION_PATCH}" _tmp) + # 96 is the ASCII code of 'a' minus 1 + math(EXPR OPENSSL_VERSION_PATCH_ASCII "${_tmp} + 96") + unset(_tmp) + # Once anyone knows how OpenSSL would call the patch versions beyond 'z' + # this should be updated to handle that, too. This has not happened yet + # so it is simply ignored here for now. + string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING) + endif (NOT OPENSSL_VERSION_PATCH STREQUAL "00") + + set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}") + endif (_OPENSSL_VERSION) +endif (OPENSSL_INCLUDE_DIR) + +include(FindPackageHandleStandardArgs) + +if (OPENSSL_VERSION) + find_package_handle_standard_args(OpenSSL + REQUIRED_VARS + OPENSSL_LIBRARIES + OPENSSL_INCLUDE_DIR + VERSION_VAR + OPENSSL_VERSION + FAIL_MESSAGE + "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR" + ) +else (OPENSSL_VERSION) + find_package_handle_standard_args(OpenSSL "Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR" + OPENSSL_LIBRARIES + OPENSSL_INCLUDE_DIR + ) +endif (OPENSSL_VERSION) + +MARK_AS_ADVANCED(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES) diff -Nru udj-desktop-client-0.5.1/cmake/modules/FindPhonon.cmake udj-desktop-client-0.6.3/cmake/modules/FindPhonon.cmake --- udj-desktop-client-0.5.1/cmake/modules/FindPhonon.cmake 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/cmake/modules/FindPhonon.cmake 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,71 @@ +# Find libphonon +# Once done this will define +# +# PHONON_FOUND - system has Phonon Library +# PHONON_INCLUDES - the Phonon include directory +# PHONON_LIBS - link these to use Phonon +# PHONON_VERSION - the version of the Phonon Library + +# Copyright (c) 2008, Matthias Kretz +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +macro(_phonon_find_version) + set(_phonon_namespace_header_file "${PHONON_INCLUDE_DIR}/phonon/phononnamespace.h") + if (APPLE AND EXISTS "${PHONON_INCLUDE_DIR}/Headers/phononnamespace.h") + set(_phonon_namespace_header_file "${PHONON_INCLUDE_DIR}/Headers/phononnamespace.h") + endif (APPLE AND EXISTS "${PHONON_INCLUDE_DIR}/Headers/phononnamespace.h") + file(READ ${_phonon_namespace_header_file} _phonon_header LIMIT 5000 OFFSET 1000) + string(REGEX MATCH "define PHONON_VERSION_STR \"(4\\.[0-9]+\\.[0-9a-z]+)\"" _phonon_version_match "${_phonon_header}") + set(PHONON_VERSION "${CMAKE_MATCH_1}") + message(STATUS "Phonon Version: ${PHONON_VERSION}") +endmacro(_phonon_find_version) + +if(PHONON_FOUND) + # Already found, nothing more to do except figuring out the version + _phonon_find_version() +else(PHONON_FOUND) + if(PHONON_INCLUDE_DIR AND PHONON_LIBRARY) + set(PHONON_FIND_QUIETLY TRUE) + endif(PHONON_INCLUDE_DIR AND PHONON_LIBRARY) + + # As discussed on kde-buildsystem: first look at CMAKE_PREFIX_PATH, then at the suggested PATHS (kde4 install dir) + find_library(PHONON_LIBRARY NAMES phonon PATHS ${KDE4_LIB_INSTALL_DIR} ${QT_LIBRARY_DIR} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) + # then at the default system locations (CMAKE_SYSTEM_PREFIX_PATH, i.e. /usr etc.) + find_library(PHONON_LIBRARY NAMES phonon HINTS "$ENV{PHONON_DIR}" "$ENV{PHONON_DIR}/lib" ) + + find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h PATHS ${KDE4_INCLUDE_INSTALL_DIR} ${QT_INCLUDE_DIR} ${INCLUDE_INSTALL_DIR} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) + find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h HINTS "$ENV{PHONON_DIR}" "$ENV{PHONON_DIR}/include") + + if(PHONON_INCLUDE_DIR AND PHONON_LIBRARY) + set(PHONON_LIBS ${phonon_LIB_DEPENDS} ${PHONON_LIBRARY}) + set(PHONON_INCLUDES ${PHONON_INCLUDE_DIR}/KDE ${PHONON_INCLUDE_DIR}) + set(PHONON_FOUND TRUE) + _phonon_find_version() + else(PHONON_INCLUDE_DIR AND PHONON_LIBRARY) + set(PHONON_FOUND FALSE) + endif(PHONON_INCLUDE_DIR AND PHONON_LIBRARY) + + if(PHONON_FOUND) + if(NOT PHONON_FIND_QUIETLY) + message(STATUS "Found Phonon: ${PHONON_LIBRARY}") + message(STATUS "Found Phonon Includes: ${PHONON_INCLUDES}") + endif(NOT PHONON_FIND_QUIETLY) + else(PHONON_FOUND) + if(Phonon_FIND_REQUIRED) + if(NOT PHONON_INCLUDE_DIR) + message(STATUS "Phonon includes NOT found!") + endif(NOT PHONON_INCLUDE_DIR) + if(NOT PHONON_LIBRARY) + message(STATUS "Phonon library NOT found!") + endif(NOT PHONON_LIBRARY) + message(FATAL_ERROR "Phonon library or includes NOT found!") + else(Phonon_FIND_REQUIRED) + message(STATUS "Unable to find Phonon") + endif(Phonon_FIND_REQUIRED) + endif(PHONON_FOUND) + + + mark_as_advanced(PHONON_INCLUDE_DIR PHONON_LIBRARY PHONON_INCLUDES) +endif(PHONON_FOUND) diff -Nru udj-desktop-client-0.5.1/cmake/modules/FindPhononVLC.cmake udj-desktop-client-0.6.3/cmake/modules/FindPhononVLC.cmake --- udj-desktop-client-0.5.1/cmake/modules/FindPhononVLC.cmake 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/cmake/modules/FindPhononVLC.cmake 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,30 @@ +# CMake module to search for the Phonon VLC plugin +# Authors: Kurtis Nusbaum +# +# Copyright 2012 Kurtis Nusbaum. +# LICENSE: GPLv2 +# +# If it's found it sets PHONON_VLC_FOUND to TRUE +# and following variables are set: +# PHONON_VLC_DLL +# Please note this has only been tested on windows. Sorry. + + +find_path(PHONON_VLC_DLL bin/phonon_backend/phonon_vlc.dll +HINTS "$ENV{PHONON_VLC_ROOT_DIR}" +) +if (PHONON_VLC_DLL) +set(PHONON_VLC_FOUND TRUE) +endif (PHONON_VLC_DLL) + + +if (PHONON_VLC_FOUND) + if (NOT PhononVLC_FIND_QUIETLY) + message(STATUS "Found VLC DLL: ${PHONON_VLC_DLL}") + endif (NOT PhononVLC_FIND_QUIETLY) +else (PHONON_VLC_FOUND) + if (PhononVLC_REQUIRED) + message(FATAL_ERROR "Couldn't Phonon VLC") + endif (PhononVLC_REQUIRED) +endif (PHONON_VLC_FOUND) + diff -Nru udj-desktop-client-0.5.1/cmake/modules/NSIS.template.in udj-desktop-client-0.6.3/cmake/modules/NSIS.template.in --- udj-desktop-client-0.5.1/cmake/modules/NSIS.template.in 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/cmake/modules/NSIS.template.in 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,634 @@ +;UDJ installer script. +;Courtusy of the Tomahawk project (i.e. I shamelessly copied and pasted) +;www.tomahawk-player.com + +;----------------------------------------------------------------------------- +; 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 SOURCE_PATH "@CMAKE_SOURCE_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" + +; We use official release plugins +; mingw32-vlc from obs misses a lot and has even broken ones probably +!define VLC_PATH "${SOURCE_PATH}\admin\win\vlc\" ; SIC! ^ +!define VLC_BIN "${VLC_PATH}" +!define VLC_PLUGIN_PATH "${VLC_BIN}\plugins" + +!define NSI_PATH "${SOURCE_PATH}/admin/win/nsi" + + +;----------------------------------------------------------------------------- +; Installer version +;----------------------------------------------------------------------------- + +!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" + +;----------------------------------------------------------------------------- +; Initial installer setup and definitions. +;----------------------------------------------------------------------------- +Name "@CPACK_NSIS_PACKAGE_NAME@" +Caption "UDJ Installer" +BrandingText "UDJ ${VERSION} -- ${BUILD_TIME}" +OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@" +InstallDir "$PROGRAMFILES\@CPACK_PACKAGE_INSTALL_DIRECTORY@" +InstallDirRegKey HKCU "Software\UDJ" "" +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\UDJ + +;----------------------------------------------------------------------------- +; 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.png +!define MUI_WELCOMEPAGE_TITLE "@CPACK_PACKAGE_NAME@ ${VERSION} Setup$\r$\nInstaller" +!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.jpg +!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://@UDJ_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 "LaunchUDJ" +!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 LaunchUDJ + ${UAC.CallFunctionAsUser} LaunchUDJAsUser +FunctionEnd + +Function LaunchUDJAsUser + Exec "$INSTDIR\UDJ.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 EnsureUDJShutdown + !insertmacro CheckAndConfirmEndProcess "UDJ.exe" +FunctionEnd + +############################################################################## +# # +# RE-INSTALLER FUNCTIONS # +# # +############################################################################## + +Function PageReinstall + ReadRegStr $R0 HKLM "Software\UDJ" "" + StrCmp $R0 "" 0 +2 + Abort + + ;Detect version + ReadRegDWORD $R0 HKLM "Software\UDJ" "VersionMajor" + IntCmp $R0 ${VER_MAJOR} minor_check new_version older_version + minor_check: + ReadRegDWORD $R0 HKLM "Software\UDJ" "VersionMinor" + IntCmp $R0 ${VER_MINOR} build_check new_version older_version + build_check: + ReadRegDWORD $R0 HKLM "Software\UDJ" "VersionBuild" + IntCmp $R0 ${VER_BUILD} same_version new_version older_version + + new_version: + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 1" "Text" "An older version of UDJ 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 UDJ." + StrCpy $R0 "1" + Goto reinst_start + + older_version: + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 1" "Text" "A newer version of UDJ 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 UDJ." + StrCpy $R0 "1" + Goto reinst_start + + same_version: + !insertmacro INSTALLOPTIONS_WRITE "NSIS.InstallOptions.ini" "Field 1" "Text" "UDJ ${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 UDJ" + !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\UDJ" "UninstallString" + HideWindow + ClearErrors + ExecWait '$R1 _?=$INSTDIR' + IfErrors no_remove_uninstaller + IfFileExists "$INSTDIR\UDJ.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 "UDJ Player" SEC_UDJ_PLAYER + SectionIn 1 2 3 RO + SetDetailsPrint listonly + + SetDetailsPrint textonly + DetailPrint "Installing UDJ Player essentials." + SetDetailsPrint listonly + SetOutPath "$INSTDIR" + + !ifdef INSTALL_PATH + ;Main executable. + File "${INSTALL_PATH}\bin\UDJ.exe" + + !endif + !ifndef INSTALL_PATH + ;Main executable. + File "${BUILD_PATH}\src\UDJ.exe" + + !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" + + ;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 + File "${MING_BIN}\libphonon.dll" + SetOutPath "$INSTDIR\phonon_backend" + File "${VLC_BIN}\phonon_backend\phonon_vlc.dll" + SetOutPath "$INSTDIR" + + ;VLC + File "${VLC_BIN}\libvlc.dll" + File "${VLC_BIN}\libvlccore.dll" + SetOutPath "$INSTDIR\plugins" + File /r "${VLC_PLUGIN_PATH}\*.dll" + SetOutPath "$INSTDIR" + + ; Other + 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}\libqtsparkle.dll" + + + + ; Jabber + File "${MING_BIN}\libssl-8.dll" + File "${MING_BIN}\libcrypto-8.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 UDJ program group to the Start Menu." + SetDetailsPrint listonly + SetShellVarContext all + RMDir /r "$SMPROGRAMS\UDJ" + CreateDirectory "$SMPROGRAMS\UDJ" + CreateShortCut "$SMPROGRAMS\UDJ\LICENSE.lnk" "$INSTDIR\LICENSE.txt" + CreateShortCut "$SMPROGRAMS\UDJ\UDJ.lnk" "$INSTDIR\UDJ.exe" + CreateShortCut "$SMPROGRAMS\UDJ\Release notes.lnk" "$INSTDIR\NOTES.txt" + CreateShortCut "$SMPROGRAMS\UDJ\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\UDJ.lnk" "$INSTDIR\UDJ.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\UDJ.lnk" "$INSTDIR\UDJ.exe" + ${MementoSectionEnd} +!endif + +SectionGroupEnd + +${MementoSectionDone} + +; Installer section descriptions +;-------------------------------- +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN +!insertmacro MUI_DESCRIPTION_TEXT ${SEC_UDJ_PLAYER} "UDJ player essentials." +!insertmacro MUI_DESCRIPTION_TEXT ${SEC_START_MENU} "UDJ program group." +!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DESKTOP} "Desktop shortcut for UDJ." +!insertmacro MUI_DESCRIPTION_TEXT ${SEC_QUICK_LAUNCH} "Quick Launch shortcut for UDJ." +!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\UDJ" "" $INSTDIR + WriteRegDWORD HKLM "Software\UDJ" "VersionMajor" "${VER_MAJOR}" + WriteRegDWORD HKLM "Software\UDJ" "VersionMinor" "${VER_MINOR}" + WriteRegDWORD HKLM "Software\UDJ" "VersionRevision" "${REVISION}" + WriteRegDWORD HKLM "Software\UDJ" "VersionBuild" "${VER_BUILD}" + + ;Add or Remove Programs entry. + WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "UninstallString" '"$INSTDIR\Uninstall.exe"' + WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "InstallLocation" "$INSTDIR" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "DisplayName" "UDJ" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "Publisher" "UDJ-player.org" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "DisplayIcon" "$INSTDIR\Uninstall.exe,0" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "DisplayVersion" "${VERSION}" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "VersionMajor" "${VER_MAJOR}" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "VersionMinor" "${VER_MINOR}.${REVISION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "URLInfoAbout" "http://UDJ-player.org/" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "HelpLink" "http://UDJ-player.org/" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "NoModify" "1" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" "NoRepair" "1" + + ; Register UDJ:// protocol handler + WriteRegStr HKCR "UDJ" "" "URL:UDJ Protocol" + WriteRegStr HKCR "UDJ" "URL Protocol" "" + WriteRegStr HKCR "UDJ\DefaultIcon" "" $INSTDIR\UDJ.exe,1 + WriteRegStr HKCR "UDJ\shell" "" "open" + WriteRegStr HKCR "UDJ\shell\open\command" "" '"$INSTDIR\UDJ.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 UDJ" "Remove UDJ'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 UDJ's data folder?" + Pop $0 + + ${NSD_CreateText} 0 13u 100% 12u "$LOCALAPPDATA\UDJ" + 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\UDJ.exe" UDJ_installed + MessageBox MB_YESNO "It does not appear that UDJ is installed in the directory '$INSTDIR'.$\r$\nContinue anyway (not recommended)?" IDYES UDJ_installed + Abort "Uninstall aborted by user" + UDJ_installed: + + ;Delete registry keys. + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\UDJ" + DeleteRegValue HKLM "Software\UDJ" "VersionBuild" + DeleteRegValue HKLM "Software\UDJ" "VersionMajor" + DeleteRegValue HKLM "Software\UDJ" "VersionMinor" + DeleteRegValue HKLM "Software\UDJ" "VersionRevision" + DeleteRegValue HKLM "Software\UDJ" "" + DeleteRegKey HKLM "Software\UDJ" + + DeleteRegKey HKCR "UDJ" + + ;Start menu shortcuts. + !ifdef OPTION_SECTION_SC_START_MENU + SetShellVarContext all + RMDir /r "$SMPROGRAMS\UDJ" + SetShellVarContext current + !endif + + ;Desktop shortcut. + !ifdef OPTION_SECTION_SC_DESKTOP + IfFileExists "$DESKTOP\UDJ.lnk" 0 +2 + Delete "$DESKTOP\UDJ.lnk" + !endif + + ;Quick Launch shortcut. + !ifdef OPTION_SECTION_SC_QUICK_LAUNCH + IfFileExists "$QUICKLAUNCH\UDJ.lnk" 0 +2 + Delete "$QUICKLAUNCH\UDJ.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\UDJ" + ${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 "UDJInstaller") 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\UDJ" "InstallLocation" + StrCmp $R0 "" SkipSetInstDir + StrCpy $INSTDIR $R0 + SkipSetInstDir: + + ;Shutdown UDJ in case Add/Remove re-installer option used. + Call EnsureUDJShutdown +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 "UDJUninstaller") 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 diff -Nru udj-desktop-client-0.5.1/debian/changelog udj-desktop-client-0.6.3/debian/changelog --- udj-desktop-client-0.5.1/debian/changelog 2012-07-08 15:54:36.000000000 +0000 +++ udj-desktop-client-0.6.3/debian/changelog 2012-11-15 23:47:43.000000000 +0000 @@ -1,3 +1,23 @@ +udj-desktop-client (0.6.3-1) unstable; urgency=low + + * New upstream release + * debian/copyright: Add stanzas for new upstream files + * debian/rules: + - Do not install ./usr/share/doc/udj/UDJ.1 + - Remove /usr/share/doc/udj directory if it is empty + * debian/control: + - Bump Standards-Version to 3.9.4 (no changes) + - Use my @debian.org address for the Maintainer field + + -- Nathan Handler Wed, 14 Nov 2012 15:29:07 -0600 + +udj-desktop-client (0.6.1-1~exp1) experimental; urgency=low + + * New upstream release + - Adds support for new API + + -- Nathan Handler Tue, 09 Oct 2012 22:39:20 -0500 + udj-desktop-client (0.5.1-2) unstable; urgency=medium * Add libqt4-sql-sqlite as a Dependency (Closes: #680637) diff -Nru udj-desktop-client-0.5.1/debian/control udj-desktop-client-0.6.3/debian/control --- udj-desktop-client-0.5.1/debian/control 2012-07-08 15:54:36.000000000 +0000 +++ udj-desktop-client-0.6.3/debian/control 2012-11-15 23:46:54.000000000 +0000 @@ -1,10 +1,10 @@ Source: udj-desktop-client Section: sound Priority: optional -Maintainer: Nathan Handler +Maintainer: Nathan Handler Build-Depends: debhelper (>= 9.0.0), cmake, libqt4-dev, libphonon-dev, libtag1-dev, imagemagick, librsvg2-bin -Standards-Version: 3.9.3 +Standards-Version: 3.9.4 Homepage: https://www.udjplayer.com/ Vcs-Git: git://git.debian.org/collab-maint/udj-desktop-client.git Vcs-Browser: http://git.debian.org/?p=collab-maint/udj-desktop-client.git diff -Nru udj-desktop-client-0.5.1/debian/copyright udj-desktop-client-0.6.3/debian/copyright --- udj-desktop-client-0.5.1/debian/copyright 2012-07-08 15:54:36.000000000 +0000 +++ udj-desktop-client-0.6.3/debian/copyright 2012-10-18 01:56:38.000000000 +0000 @@ -4,7 +4,7 @@ Source: https://github.com/klnusbaum/UDJ-Desktop-Client Files: * -Copyright: Copyright 2011 Kurtis L. Nusbaum +Copyright: Copyright 2011-2012 Kurtis L. Nusbaum License: GPL-2+ Files: src/qt-json/* @@ -56,6 +56,19 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Files: admin/win/update-vlc.sh: +Copyright: Copyright 2011-2012, Dominik Schmidt +License: GPL-3+ + +Files: admin/mac/create-dmg.sh +Copyright: Copyright 2011, John Maguire +License: GPL-3+ + +Files: admin/mac/macdeploy.py +Copyright: Copyright 2010, David Sansome + Copyright 2012, Kurtis L. Nusbaum +License: GPL-3+ + Files: debian/* Copyright: Copyright 2012 Nathan Handler License: GPL-2+ @@ -81,3 +94,25 @@ On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/GPL-2'. + +License: GPL-3+ + This program 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. + . + This program 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 this package; if not, write to the Free + Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301 USA + . + On Debian systems, the full text of the GNU General Public + License version 3 can be found in the file + `/usr/share/common-licenses/GPL-3'. diff -Nru udj-desktop-client-0.5.1/debian/rules udj-desktop-client-0.6.3/debian/rules --- udj-desktop-client-0.5.1/debian/rules 2012-07-08 15:54:36.000000000 +0000 +++ udj-desktop-client-0.6.3/debian/rules 2012-11-14 21:23:25.000000000 +0000 @@ -12,3 +12,5 @@ override_dh_auto_install: dh_auto_install rm -f debian/udj-desktop-client/usr/share/doc/udj/LICENSE + rm -f debian/udj-desktop-client/usr/share/doc/udj/UDJ.1 + find debian/udj-desktop-client/usr/share/doc/udj -type d -empty -delete Binary files /tmp/2fJn3HRETe/udj-desktop-client-0.5.1/icons/udjlauncher128x128.png and /tmp/s8fDTrg7pV/udj-desktop-client-0.6.3/icons/udjlauncher128x128.png differ Binary files /tmp/2fJn3HRETe/udj-desktop-client-0.5.1/icons/udjlauncher16x16.png and /tmp/s8fDTrg7pV/udj-desktop-client-0.6.3/icons/udjlauncher16x16.png differ Binary files /tmp/2fJn3HRETe/udj-desktop-client-0.5.1/icons/udjlauncher256x256.png and /tmp/s8fDTrg7pV/udj-desktop-client-0.6.3/icons/udjlauncher256x256.png differ Binary files /tmp/2fJn3HRETe/udj-desktop-client-0.5.1/icons/udjlauncher32x32.png and /tmp/s8fDTrg7pV/udj-desktop-client-0.6.3/icons/udjlauncher32x32.png differ Binary files /tmp/2fJn3HRETe/udj-desktop-client-0.5.1/icons/udjlauncher512x512.png and /tmp/s8fDTrg7pV/udj-desktop-client-0.6.3/icons/udjlauncher512x512.png differ Binary files /tmp/2fJn3HRETe/udj-desktop-client-0.5.1/icons/udjlauncher64x64.png and /tmp/s8fDTrg7pV/udj-desktop-client-0.6.3/icons/udjlauncher64x64.png differ diff -Nru udj-desktop-client-0.5.1/src/AboutWidget.cpp udj-desktop-client-0.6.3/src/AboutWidget.cpp --- udj-desktop-client-0.5.1/src/AboutWidget.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/AboutWidget.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -19,12 +19,13 @@ #include "AboutWidget.hpp" #include #include +#include "ConfigDefs.hpp" namespace UDJ{ AboutWidget::AboutWidget(QWidget *parent):QWidget(parent){ QVBoxLayout *mainLayout = new QVBoxLayout(); - mainLayout->addWidget(new QLabel(tr("UDJ Player Client Version 0.5.0"))); + mainLayout->addWidget(new QLabel(tr("UDJ Player Client Version " UDJ_VERSION))); mainLayout->addSpacing(1); mainLayout->addWidget(new QLabel(tr("Written By Kurtis Nusbaum"))); mainLayout->addSpacing(1); diff -Nru udj-desktop-client-0.5.1/src/ActivePlaylistView.cpp udj-desktop-client-0.6.3/src/ActivePlaylistView.cpp --- udj-desktop-client-0.5.1/src/ActivePlaylistView.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/ActivePlaylistView.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -33,17 +33,19 @@ dataStore(dataStore) { setContextMenuPolicy(Qt::CustomContextMenu); + setFocusPolicy(Qt::TabFocus); setEditTriggers(QAbstractItemView::NoEditTriggers); model = new ActivePlaylistModel(getDataQuery(), dataStore, this); horizontalHeader()->setStretchLastSection(true); createActions(); setModel(model); setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::ContiguousSelection); configureHeaders(); connect( dataStore, SIGNAL(activePlaylistModified()), - model, + model, SLOT(refresh())); connect( this, @@ -100,16 +102,17 @@ contextMenu.addAction(removeSongAction); QAction *selected = contextMenu.exec(QCursor::pos()); if(selected==NULL){ - selectionModel()->clear(); + selectionModel()->clearSelection(); } } void ActivePlaylistView::removeSongs(){ - dataStore->removeSongsFromActivePlaylist( + QSet toRemove = Utils::getSelectedIds( this, model, - DataStore::getActivePlaylistLibIdColName())); + DataStore::getActivePlaylistLibIdColName()); + dataStore->removeSongsFromActivePlaylist(toRemove); selectionModel()->clearSelection(); } @@ -133,5 +136,12 @@ } } +void ActivePlaylistView::focusOutEvent(QFocusEvent *event){ + if(event->reason() != Qt::PopupFocusReason){ + selectionModel()->clearSelection(); + } +} + + } //end namespace diff -Nru udj-desktop-client-0.5.1/src/ActivePlaylistView.hpp udj-desktop-client-0.6.3/src/ActivePlaylistView.hpp --- udj-desktop-client-0.5.1/src/ActivePlaylistView.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/ActivePlaylistView.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -48,6 +48,16 @@ //@} +protected: + + /** @name Overridden From QTableView */ + //@{ + + /** \brief . */ + void focusOutEvent(QFocusEvent *event); + + //@} + private: /** @name Private Functions */ diff -Nru udj-desktop-client-0.5.1/src/ActivityList.cpp udj-desktop-client-0.6.3/src/ActivityList.cpp --- udj-desktop-client-0.5.1/src/ActivityList.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/ActivityList.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -32,6 +32,7 @@ QTreeView(parent), dataStore(dataStore) { setupUi(); + setFocusPolicy(Qt::TabFocus); connect( this, SIGNAL(clicked(const QModelIndex&)), @@ -47,6 +48,9 @@ else if(index == playlistItem->index()){ emit playlistClicked(); } + else if(index == participantsItem->index()){ + emit participantsClicked(); + } } void ActivityList::setupUi(){ @@ -57,10 +61,14 @@ playlistItem = new QStandardItem(getPlaylistTitle()); playlistItem->setEditable(false); + participantsItem = new QStandardItem(getParticipantsTitle()); + participantsItem->setEditable(false); + model = new QStandardItemModel(this); model->appendRow(libraryItem); model->appendRow(playlistItem); + model->appendRow(participantsItem); setModel(model); diff -Nru udj-desktop-client-0.5.1/src/ActivityList.hpp udj-desktop-client-0.6.3/src/ActivityList.hpp --- udj-desktop-client-0.5.1/src/ActivityList.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/ActivityList.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -65,15 +65,21 @@ /** @name Signals */ //@{ - /** + /** * \brief Emitted when the library activity is clicked. */ void libraryClicked(); /** - * \brief emited when the playlist activity is clicked. + * \brief Emitted when the playlist activity is clicked. */ void playlistClicked(); + + /** + * \brief Emitted when the participants item is clicked. + */ + void participantsClicked(); + //@} private: @@ -106,10 +112,20 @@ return playlistTitle; } + /** + * \brief Gets the name of the Participants activity. + * + * @return The name of the Participants activity. + */ + static const QString& getParticipantsTitle(){ + static const QString participantsTitle(tr("Participants")); + return participantsTitle; + } + //@} - /** @name Private Memeber */ + /** @name Private Members */ //@{ /** \brief Pointer to the DataStore backing this instance of UDJ */ @@ -124,6 +140,9 @@ /** \brief The item representing the playlist activity. */ QStandardItem *playlistItem; + /** \brief The item representing the participants activity. */ + QStandardItem *participantsItem; + //@} private slots: diff -Nru udj-desktop-client-0.5.1/src/AddressWidget.cpp udj-desktop-client-0.6.3/src/AddressWidget.cpp --- udj-desktop-client-0.5.1/src/AddressWidget.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/AddressWidget.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -39,8 +39,8 @@ setupStateCombo(state); zipcodeEdit = new QLineEdit(zipcode); QFormLayout *formLayout = new QFormLayout; - formLayout->addRow(tr("Address:"), streetAddressEdit); - formLayout->addRow(tr("City:"), cityEdit); + formLayout->addRow(tr("Address (Optional):"), streetAddressEdit); + formLayout->addRow(tr("City (Optional):"), cityEdit); formLayout->addRow(tr("State:"), stateCombo); formLayout->addRow(tr("Zipcode:"), zipcodeEdit); setLayout(formLayout); @@ -59,14 +59,14 @@ return stateCombo->currentText(); } -int AddressWidget::getZipcode() const{ - return zipcodeEdit->text().toInt(); +QString AddressWidget::getZipcode() const{ + return zipcodeEdit->text(); } QString AddressWidget::getBadInputs() const{ QString toReturn =""; - int errorCounter = 1; +/* int errorCounter = 1; if(streetAddressEdit->text() == ""){ toReturn += QString::number(errorCounter++) + ". You did not enter a street address.\n"; @@ -78,7 +78,7 @@ if(!getZipcodeRegex().exactMatch(zipcodeEdit->text())){ toReturn += QString::number(errorCounter++) + ". Zipcode invalid."; - } + }*/ return toReturn; } diff -Nru udj-desktop-client-0.5.1/src/AddressWidget.hpp udj-desktop-client-0.6.3/src/AddressWidget.hpp --- udj-desktop-client-0.5.1/src/AddressWidget.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/AddressWidget.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -61,7 +61,7 @@ QString getStreetAddress() const; QString getCity() const; QString getState() const; - int getZipcode() const; + QString getZipcode() const; QString getBadInputs() const; //@} diff -Nru udj-desktop-client-0.5.1/src/CMakeLists.txt udj-desktop-client-0.6.3/src/CMakeLists.txt --- udj-desktop-client-0.5.1/src/CMakeLists.txt 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/CMakeLists.txt 2012-11-15 20:49:42.000000000 +0000 @@ -21,6 +21,8 @@ "${PROJECT_BINARY_DIR}/src/ConfigDefs.hpp" ) +INCLUDE( AddAppIconMacro ) + SET(SOURCES main.cpp PlaybackWidget.cpp @@ -49,11 +51,16 @@ AboutWidget.cpp AddressWidget.cpp SetLocationDialog.cpp - SetPasswordDialog.cpp DialogWithLoaderWidget.cpp PlaybackErrorMessage.cpp + ParticipantsView.cpp + ParticipantsModel.cpp ) +#IF(APPLE) +#SET( SOURCES ${SOURCES} mac/UDJApp_Mac.mm) +#INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/mac) +#ENDIF(APPLE) include_directories("${PROJECT_BINARY_DIR}/src") include_directories("${PROJECT_SOURCE_DIR}/src") @@ -81,10 +88,9 @@ endif() endif() -set(RESOURCES_SOURCES "") -if(MSVC) - list(APPEND RESOURCES_SOURCES ${PROJECT_SOURCE_DIR}/src/udj.rc) -endif() +set(ICON_SOURCES "") +kde4_add_app_icon( ICON_SOURCES "${CMAKE_SOURCE_DIR}/icons/udjlauncher*.png" ) + if(APPLE) set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") @@ -92,7 +98,6 @@ set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") -set(MACOSX_BUNDLE_ICON_FILE "udjlauncher.icns") set(MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}") set(MACOSX_BUNDLE_RESOURCES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.app/Contents/Resources") @@ -101,9 +106,18 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${MACOSX_BUNDLE_ICON} ${MACOSX_BUNDLE_RESOURCES}) endif() +set(UDJ_EXTRA_LIBS "") +if(WIN32) + list(APPEND UDJ_EXTRA_LIBS ${QTSPARKLE_LIBRARIES}) +elseif(APPLE) + find_library(SPARKLE Sparkle) + list(APPEND UDJ_EXTRA_LIBS ${SPARKLE}) +endif(WIN32) + +message(STATUS "EXTRA ${UDJ_EXTRA_LIBS}") include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) -add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE ${SOURCES} ${MOC_SOURCES} ${RESOURCES_SOURCES}) -target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${TAGLIB}) +add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE ${SOURCES} ${MOC_SOURCES} ${ICON_SOURCES}) +target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${PHONON_LIBS} ${TAGLIB} ${UDJ_EXTRA_LIBS}) if(APPLE) set(CMAKE_INSTALL_PREFIX "/Applications") @@ -124,16 +138,33 @@ IF(WIN32) -#We need to look for and include the openssl libs because some asshole made -#openssl export controlled and isn't installed by default on windows - FIND_PACKAGE(OpenSSL) - if(NOT OPENSSL_FOUND) - message(fatal_error "Cannot find OpenSSL. This is required on windows") - endif() - get_filename_component(OPENSSL_ROOT ${OPENSSL_INCLUDE_DIR} PATH) - set(SSL_LIBS "${OPENSSL_ROOT}/bin/libeay32.dll" "${OPENSSL_ROOT}/bin/ssleay32.dll") - - INSTALL(FILES ${SSL_LIBS} DESTINATION ${BIN_INSTALL_DIR}) + #We need to look for and include the openssl libs because some asshole made + #openssl export controlled and isn't installed by default on windows + FIND_PACKAGE(OpenSSLCross REQUIRED) +# get_filename_component(OPENSSL_ROOT ${OPENSSL_INCLUDE_DIR} PATH) +# set(SSL_LIBS_DLLS "${OPENSSL_ROOT}/bin/libeay32.dll" "${OPENSSL_ROOT}/bin/ssleay32.dll") +# +# INSTALL(FILES ${SSL_LIBS_DLLS} DESTINATION ${BIN_INSTALL_DIR}) + + + #Do some fancy foot work to get phonon vlc working on widnows, this is so stupid and I hate it. + + + #vlc libs +# get_filename_component(LIBVLC_ROOT ${LIBVLC_LIBRARY} PATH) +# set(VLC_LIB_DLLS "${LIBVLC_ROOT}/libvlc.dll") +# INSTALL(FILES ${VLC_LIB_DLLS} DESTINATION ${BIN_INSTALL_DIR}) + + + #And the friggen PHONON_VLC_DLL +# find_file(PHONON_VLC_DLL phonon_vlc.dll +# HINT "$ENV{PHONON_VLC_ROOT_DIR}bin/phonon_backend" +# ) +# if(NOT PHONON_VLC_DLL) +# message(FATAL_ERROR "Could not find phonon vlc backend") +# else(NOT PHONON_VLC_DLL) +# message(STATUS "Found Phonon VLC Backend DLL: ${PHONON_VLC_DLL}") +# endif(NOT PHONON_VLC_DLL) endif() set(CPACK_PACKAGE_NAME "${PROJECT_NAME}") @@ -148,53 +179,3 @@ SET(CPACK_PACKAGE_CONTACT "klnusbaum@bazaarsolutions.com") SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "UDJ is a social music player that allows you and your friends to controll a single music player from your smart phones") SET(CPACK_DEBIAN_PACKAGE_SECTION "SOUND") -if(WIN32) - set(CPACK_GENERATOR "NSIS") - set(CPACK_PACKAGE_EXECUTABLES "${PROJECT_NAME}" "${PROJECT_NAME}") - set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME} ${PROJECT_VERSION}") - set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") - set(CPACK_NSIS_EXECUTABLES_DIRECTORY "${BIN_INSTALL_DIR}") - #set(CPACK_NSIS_MUI_ICON "${PROJECT_ICONS_DIRECTORY}/NSIS.ico") - #set(CPACK_PACKAGE_ICON "${PROJECT_ICONS_DIRECTORY}\\\\NSISHeader.bmp") - set(CPACK_NSIS_URL_INFO_ABOUT "http://${PROJECT_DOMAIN}") - #set(CPACK_NSIS_INSTALLED_ICON_NAME "${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") - #set(CPACK_NSIS_MENU_LINKS "${LICENSE_FILE}" "License" "${README_FILE}" "Readme") - #set(CPACK_NSIS_MUI_FINISHPAGE_RUN "${CPACK_NSIS_INSTALLED_ICON_NAME}") -endif() -if(APPLE) - set(CMAKE_INSTALL_PREFIX "/Applications") - set(CPACK_GENERATOR "DragNDrop") - set(CPACK_DMG_FORMAT "UDBZ") - set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}") - set(CPACK_SYSTEM_NAME "OSX") - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}") - set(CPACK_PACKAGE_ICON "${ICONS_DIR}/udjlauncher.icns") - #set(CPACK_DMG_DS_STORE "${ICONS_DIR}/DMGDSStore") - #set(CPACK_DMG_BACKGROUND_IMAGE "${ICONS_DIR}/DMGBackground.png") -endif() - -include(CPack) - - -set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "${BIN_INSTALL_DIR}") -include(InstallRequiredSystemLibraries) -if(APPLE) - set(EXECUTABLE "${PROJECT_NAME}.app") -elseif(WIN32) - set(EXECUTABLE "${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") -else() - set(EXECUTABLE "${BIN_INSTALL_DIR}/${PROJECT_NAME}${CMAKE_EXECUTABLE_SUFFIX}") -endif() - -set(UDJ_QT_PLUGINS "qsqlite") -if(APPLE) - list(APPEND UDJ_QT_PLUGINS phonon_qt7) -elseif(WIN32) - list(APPEND UDJ_QT_PLUGINS phonon_ds9) -endif() - -if(APPLE OR WIN32) - include(DeployQt4) - install_qt4_executable("${EXECUTABLE}" "${UDJ_QT_PLUGINS}") -endif() diff -Nru udj-desktop-client-0.5.1/src/ConfigDefs.hpp.in udj-desktop-client-0.6.3/src/ConfigDefs.hpp.in --- udj-desktop-client-0.5.1/src/ConfigDefs.hpp.in 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/ConfigDefs.hpp.in 2012-11-15 20:49:42.000000000 +0000 @@ -20,9 +20,11 @@ #ifndef CONFIG_DEFS_HPP #define CONFIG_DEFS_HPP +#define UDJ_WINDOWS_UPDATE_URL "http://www.udjplayer.com/windows/sparkle.xml" #define HAS_CUSTOM_CA_CERT @HAS_CUSTOM_CA_CERT@ #define IS_APPLE_BUILD @IS_APPLE_BUILD@ #define IS_WINDOWS_BUILD @IS_WINDOWS_BUILD@ +#define UDJ_VERSION "@PROJECT_VERSION@" #include diff -Nru udj-desktop-client-0.5.1/src/DataStore.cpp udj-desktop-client-0.6.3/src/DataStore.cpp --- udj-desktop-client-0.5.1/src/DataStore.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/DataStore.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -51,6 +51,8 @@ username(username), password(password), isReauthing(false), + changingPlayerState(false), + clearingCurrentSong(false), currentSongId(-1) { serverConnection = new UDJServerConnection(this); @@ -62,26 +64,26 @@ } activePlaylistRefreshTimer = new QTimer(this); activePlaylistRefreshTimer->setInterval(5000); + participantRefreshTimer = new QTimer(this); + participantRefreshTimer->setInterval(5000); setupDB(); - connect( - serverConnection, - SIGNAL(playerPasswordSet(const QString&)), - this, - SLOT(onPlayerPasswordSet(const QString&))); + connect(serverConnection, + SIGNAL(playerStateSet(const QString&)), + this, + SLOT(onPlayerStateSet(const QString&))); connect( serverConnection, - SIGNAL(playerPasswordSetError(const QString&, int, const QList&)), + SIGNAL(playerStateSetError(const QString&, const QString&, int, const QList&)), this, - SLOT(onPlayerPasswordSetError(const QString&, int, const QList&))); - + SLOT(onPlayerStateSetError(const QString&, const QString&, int, const QList&))); connect( serverConnection, - SIGNAL(playerLocationSet(const QString&, const QString&, const QString&, int)), + SIGNAL(playerPasswordSetError(const QString&, const QString&, int, const QList&)), this, - SLOT(onPlayerLocationSet(const QString&, const QString&, const QString&, int))); + SLOT(onPlayerPasswordSetError(const QString&, const QString&, int, const QList&))); connect( serverConnection, @@ -91,30 +93,12 @@ connect( serverConnection, - SIGNAL(playerPasswordRemoved()), - this, - SLOT(onPlayerPasswordRemoved())); - - connect( - serverConnection, SIGNAL(playerPasswordRemoveError(const QString&, int, const QList&)), this, SLOT(onPlayerPasswordRemoveError(const QString&, int, const QList&))); connect( serverConnection, - SIGNAL(playerNameChanged(const QString&)), - this, - SLOT(onPlayerNameChanged(const QString&))); - - connect( - serverConnection, - SIGNAL(playerNameChangeError(const QString&, int, const QList&)), - this, - SLOT(onPlayerNameChangeError(const QString&, int, const QList&))); - - connect( - serverConnection, SIGNAL(libSongsSyncedToServer(const QSet&)), this, SLOT(setLibSongsSynced(const QSet&))); @@ -155,10 +139,10 @@ SLOT(refreshActivePlaylist())); connect( - serverConnection, - SIGNAL(playerStateSet(const QString&)), + participantRefreshTimer, + SIGNAL(timeout()), this, - SLOT(onPlayerStateChanged(const QString&))); + SLOT(refreshParticipantList())); connect( serverConnection, @@ -203,6 +187,25 @@ this, SLOT(onAuthFail(const QString&))); + connect( + serverConnection, + SIGNAL(currentSongCleared()), + this, + SLOT(onCurrentSongCleared())); + + connect( + serverConnection, + SIGNAL(currentSongClearError(const QString&, int, const QList&)), + this, + SLOT(onCurrentSongClearError(const QString&, int, const QList&))); + + + connect( + serverConnection, + SIGNAL(newParticipantList(const QVariantList&)), + this, + SLOT(onNewParticipantList(const QVariantList&))); + } void DataStore::setupDB(){ @@ -243,59 +246,134 @@ } -void DataStore::removePlayerPassword(){ - serverConnection->removePlayerPassword(); +void DataStore::startPlaylistAutoRefresh(){ + Logger::instance()->log("Starting playlist auto refresh"); + activePlaylistRefreshTimer->start(); } -void DataStore::onPlayerPasswordRemoved(){ +void DataStore::startParticipantsAutoRefresh(){ + Logger::instance()->log("Starting particpants auto refresh"); + participantRefreshTimer->start(); +} + +void DataStore::clearCurrentSong(){ + currentSongId = -1; + clearingCurrentSong = true; + serverConnection->clearCurrentSong(); +} + +void DataStore::onCurrentSongCleared(){ + clearingCurrentSong = false; +} + +void DataStore::onCurrentSongClearError( + const QString& errMessage, + int errorCode, + const QList& headers) +{ + if(isTicketAuthError(errorCode, headers)){ + Logger::instance()->log("Got the ticket-hash challenge"); + reauthActions.insert(CLEAR_CURRENT_SONG); + initReauth(); + } + else{ + clearingCurrentSong = false; + emit clearCurrentSongError(errMessage); + } + +} + + +void DataStore::onPlayerStateSet(const QString& state){ + changingPlayerState = false; + if(state == getInactiveState()){ + emit playerSuccessfullySetInactive(); + } +} + +void DataStore::onPlayerStateSetError( + const QString& state, + const QString& errMessage, + int errorCode, + const QList& headers) +{ + if(isTicketAuthError(errorCode, headers)){ + Logger::instance()->log("Got the ticket-hash challenge"); + if(state != getInactiveState()){ + reauthActions.insert(SET_PLAYER_STATE); + } + else{ + reauthActions.insert(SET_PLAYER_INACTIVE); + } + initReauth(); + } + else{ + changingPlayerState = false; + if(state == getPlayingState()){ + emit playPlayerError(errMessage); + } + else if(state == getPausedState()){ + emit pausePlayerError(errMessage); + } + else if(state == getInactiveState()){ + emit playerSetInactiveError(errMessage); + } + } +} + + +void DataStore::removePlayerPassword(){ QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); - settings.remove(getPlayerPasswordSettingName()); + settings.setValue(getHasPlayerPasswordSettingName(), false); + serverConnection->removePlayerPassword(); emit playerPasswordRemoved(); } void DataStore::onPlayerPasswordRemoveError( const QString& errMessage, - int /*errorCode*/, - const QList& /*headers*/) + int errorCode, + const QList& headers) { - //TODO handle reauth error - emit playerPasswordRemoveError(errMessage); + if(isTicketAuthError(errorCode, headers)){ + Logger::instance()->log("Got the ticket-hash challenge"); + reauthActions.insert(REMOVE_PLAYER_PASSWORD); + initReauth(); + } + else{ + emit playerPasswordRemoveError(errMessage); + } } void DataStore::setPlayerPassword(const QString& newPassword){ - serverConnection->setPlayerPassword(newPassword); -} - -void DataStore::onPlayerPasswordSet(const QString& password){ QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); - settings.setValue(getPlayerPasswordSettingName(), password); + settings.setValue(getHasPlayerPasswordSettingName(), true); + serverConnection->setPlayerPassword(newPassword); emit playerPasswordSet(); } void DataStore::onPlayerPasswordSetError( + const QString& attemptedPassword, const QString& errMessage, - int /*errorCode*/, - const QList& /*headers*/) + int errorCode, + const QList& headers) { - emit playerPasswordSetError(errMessage); + if(isTicketAuthError(errorCode, headers)){ + Logger::instance()->log("Got the ticket-hash challenge"); + reauthActions.insert(SET_PLAYER_PASSWORD); + reauthPlayerPassword = attemptedPassword; + initReauth(); + } + else{ + emit playerPasswordSetError(errMessage); + } } void DataStore::setPlayerLocation( const QString& streetAddress, const QString& city, const QString& state, - int zipcode -) -{ - serverConnection->setPlayerLocation(streetAddress, city, state, zipcode); -} - -void DataStore::onPlayerLocationSet( - const QString& streetAddress, - const QString& city, - const QString& state, - int zipcode + const QString& zipcode ) { QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); @@ -303,46 +381,27 @@ settings.setValue(getCitySettingName(), city); settings.setValue(getStateSettingName(), state); settings.setValue(getZipCodeSettingName(), zipcode); + serverConnection->setPlayerLocation(streetAddress, city, state, zipcode); emit playerLocationSet(); } + void DataStore::onPlayerLocationSetError( const QString& errMessage, - int /*errorCode*/, - const QList& /*headers*/) -{ - //TODO handle reauth error - emit playerLocationSetError(errMessage); -} - -void DataStore::setPlayerName(const QString& newName){ - serverConnection->setPlayerName(newName); -} - -void DataStore::onPlayerNameChanged(const QString& newName){ - QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); - settings.setValue(getPlayerNameSettingName(), newName); - emit playerNameChanged(newName); -} - -void DataStore::onPlayerNameChangeError( - const QString& /*errMessage*/, int errorCode, - const QList& /*headers*/) + const QList& headers) { - //TODO if reauth error, should reauth - if(errorCode == 409){ - emit playerNameChangeError(tr( - "You already have a player with that name." - )); + if(isTicketAuthError(errorCode, headers)){ + Logger::instance()->log("Got the ticket-hash challenge"); + reauthActions.insert(SET_PLAYER_LOCATION); + initReauth(); } else{ - emit playerNameChangeError(tr( - "We seem to be having some techincal difficulties and couldn't change " - "the name of your player. Try again in a little bit." - )); + //TODO handle location not found error + emit playerLocationSetError(errMessage); } } + void DataStore::pausePlayer(){ setPlayerState(getPausedState()); } @@ -352,9 +411,16 @@ } void DataStore::setPlayerState(const QString& newState){ + QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); + settings.setValue(getPlayerStateSettingName(), newState); + changingPlayerState = true; serverConnection->setPlayerState(newState); } +void DataStore::setPlayerInactive(){ + serverConnection->setPlayerState(getInactiveState()); +} + void DataStore::addMusicToLibrary( const QList& songs, QProgressDialog* progress) @@ -452,6 +518,23 @@ library_song_id_t) } +bool DataStore::alreadyHaveSongInLibrary(const QString& fileName) const{ + QSqlQuery existsQuery(database); + existsQuery.prepare( + "SELECT * FROM "+getLibraryTableName()+ " WHERE " + + getLibIsDeletedColName() + "=0 and " + + getLibFileColName() + "=\""+fileName+"\";" + ); + + EXEC_SQL( + "Error executing already in library test query", + existsQuery.exec(), + existsQuery) + + return existsQuery.next(); + +} + void DataStore::removeSongsFromLibrary(const QSet& toRemove, QProgressDialog* progress) { @@ -530,6 +613,7 @@ "SELECT " + getLibFileColName() + ", " + getLibSongColName() + ", " + getLibArtistColName() + ", " + + getLibDurationColName() + ", " + getActivePlaylistLibIdColName() +" FROM " + getActivePlaylistViewName() + " LIMIT 1;", database); @@ -539,12 +623,11 @@ nextSongQuery) nextSongQuery.next(); if(!nextSongQuery.isValid()){ - currentSongId = -1; - song_info_t toReturn = {Phonon::MediaSource(""), "", "" }; + song_info_t toReturn = {Phonon::MediaSource(""), "", "", "" }; return toReturn; } currentSongId = - nextSongQuery.value(3).value(); + nextSongQuery.value(4).value(); deleteSongFromPlaylist(currentSongId); @@ -552,10 +635,12 @@ serverConnection->setCurrentSong(currentSongId); QString filePath = nextSongQuery.value(0).toString(); + QTime qtime(0, nextSongQuery.value(3).toInt()/60, nextSongQuery.value(3).toInt()%60); song_info_t toReturn = { Phonon::MediaSource(filePath), nextSongQuery.value(1).toString(), - nextSongQuery.value(2).toString() + nextSongQuery.value(2).toString(), + qtime.toString("mm:ss") }; return toReturn; @@ -578,7 +663,8 @@ QSqlQuery getSongQuery( "SELECT " + getLibFileColName() + ", " + getLibSongColName() + ", " + - getLibArtistColName() + " FROM " + + getLibArtistColName() + ", " + + getLibDurationColName() + " FROM " + getActivePlaylistViewName() + " WHERE " + getActivePlaylistLibIdColName() + " = " + QString::number(songToPlay) + ";", database); @@ -593,10 +679,12 @@ currentSongId = songToPlay; serverConnection->setCurrentSong(songToPlay); Logger::instance()->log("Retrieved Artist " + getSongQuery.value(2).toString()); + QTime qtime(0, getSongQuery.value(3).toInt()/60, getSongQuery.value(3).toInt()%60); song_info_t toEmit = { Phonon::MediaSource(filePath), getSongQuery.value(1).toString(), - getSongQuery.value(2).toString() + getSongQuery.value(2).toString(), + qtime.toString("mm:ss") }; emit manualSongChange(toEmit); } @@ -608,7 +696,7 @@ { QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); settings.setValue(getPlayerNameSettingName(), name); - settings.setValue(getPlayerPasswordSettingName(), password); + settings.setValue(getHasPlayerPasswordSettingName(), true); serverConnection->createPlayer(name, password); } @@ -618,11 +706,11 @@ const QString& streetAddress, const QString& city, const QString& state, - const int& zipcode) + const QString& zipcode) { QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); settings.setValue(getPlayerNameSettingName(), name); - settings.setValue(getPlayerPasswordSettingName(), password); + settings.setValue(getHasPlayerPasswordSettingName(), true); settings.setValue(getAddressSettingName(), streetAddress); settings.setValue(getCitySettingName(), city); settings.setValue(getStateSettingName(), state); @@ -636,7 +724,7 @@ zipcode); } -void DataStore::changeVolumeSilently(qreal newVolume){ +void DataStore::setVolume(qreal newVolume){ QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); Logger::instance()->log("Current volume " + QString::number(settings.value(getPlayerVolumeSettingName()).toReal())); Logger::instance()->log("New volume " + QString::number(newVolume)); @@ -668,7 +756,7 @@ while(needAddSongs.next()){ currentRecord = needAddSongs.record(); QVariantMap songToAdd; - songToAdd["id"] = currentRecord.value(getLibIdColName()); + songToAdd["id"] = currentRecord.value(getLibIdColName()).toString(); QString title = currentRecord.value(getLibSongColName()).toString(); title.truncate(199); songToAdd["title"] = title; @@ -698,7 +786,7 @@ QVariantList songsToDelete; while(needDeleteSongs.next()){ currentRecord = needDeleteSongs.record(); - songsToDelete.append(currentRecord.value(getLibIdColName())); + songsToDelete.append(currentRecord.value(getLibIdColName()).toString()); } Logger::instance()->log("Found " + QString::number(songsToDelete.size()) + " songs which need deleting"); @@ -824,15 +912,22 @@ emit volumeChanged(retrievedVolume/10.0); } - onPlayerStateChanged(newPlaylist["state"].toString()); + QString retrievedState = newPlaylist["state"].toString(); + if(!changingPlayerState && retrievedState != getPlayerState()){ + QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); + settings.setValue(getPlayerStateSettingName(), retrievedState); + emit playerStateChanged(retrievedState); + } + library_song_id_t retrievedCurrentId = newPlaylist["current_song"].toMap()["song"].toMap()["id"].value(); - if(retrievedCurrentId != currentSongId){ + if(retrievedCurrentId != currentSongId && !clearingCurrentSong){ QSqlQuery getSongQuery( "SELECT " + getLibFileColName() + ", " + getLibSongColName() + ", " + - getLibArtistColName() + " FROM " + + getLibArtistColName() + ", " + + getLibDurationColName() + " FROM " + getActivePlaylistViewName() + " WHERE " + getActivePlaylistLibIdColName() + " = " + QString::number(retrievedCurrentId) + ";", database); @@ -845,10 +940,12 @@ Logger::instance()->log("Got file, for manual song set"); QString filePath = getSongQuery.value(0).toString(); currentSongId = retrievedCurrentId; + QTime qtime(0, getSongQuery.value(3).toInt()/60, getSongQuery.value(3).toInt()%60); song_info_t toEmit = { Phonon::MediaSource(filePath), getSongQuery.value(1).toString(), - getSongQuery.value(2).toString() + getSongQuery.value(2).toString(), + qtime.toString("mm:ss") }; emit manualSongChange(toEmit); } @@ -903,12 +1000,15 @@ serverConnection->getActivePlaylist(); } +void DataStore::refreshParticipantList(){ + serverConnection->getParticipantList(); +} + void DataStore::onPlayerCreate(const player_id_t& issuedId){ QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); settings.setValue(getPlayerIdSettingName(), QVariant::fromValue(issuedId)); serverConnection->setPlayerId(issuedId); - setPlayerState(getPlayingState()); emit playerCreated(); } @@ -919,23 +1019,6 @@ emit playerCreationFailed(errMessage); } - -void DataStore::onPlayerStateChanged(const QString& newState){ - QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); - if(newState != settings.value(getPlayerStateSettingName())){ - settings.setValue(getPlayerStateSettingName(), newState); - emit playerStateChanged(newState); - } - - //If this player state change is the result of starting up the player for the first time - //we need to do a few things - if(!activePlaylistRefreshTimer->isActive()){ - refreshActivePlaylist(); - activePlaylistRefreshTimer->start(); - } -} - - void DataStore::onLibModError( const QString& errMessage, int errorCode, const QList& headers) { @@ -972,6 +1055,13 @@ reauthActions.insert(SET_CURRENT_VOLUME); initReauth(); } + else{ + emit setVolumeError(errMessage); + } +} + +void DataStore::onNewParticipantList(const QVariantList& newParticipants){ + emit newParticipantList(newParticipants); } @@ -992,6 +1082,7 @@ } void DataStore::doReauthAction(const ReauthAction& action){ + QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); switch(action){ case SYNC_LIB: syncLibrary(); @@ -1008,16 +1099,38 @@ serverConnection->modActivePlaylist(playlistIdsToAdd, playlistIdsToRemove); break; case SET_CURRENT_VOLUME: - QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); serverConnection->setVolume((int)(getPlayerVolume() * 10)); break; + case SET_PLAYER_STATE: + serverConnection->setPlayerState(getPlayerState()); + break; + case SET_PLAYER_INACTIVE: + serverConnection->setPlayerState(getInactiveState()); + break; + case SET_PLAYER_LOCATION: + serverConnection->setPlayerLocation( + settings.value(getAddressSettingName()).toString(), + settings.value(getCitySettingName()).toString(), + settings.value(getStateSettingName()).toString(), + settings.value(getZipCodeSettingName()).toString()); + break; + case SET_PLAYER_PASSWORD: + serverConnection->setPlayerPassword(reauthPlayerPassword); + reauthPlayerPassword=""; + break; + case REMOVE_PLAYER_PASSWORD: + serverConnection->removePlayerPassword(); + break; + case CLEAR_CURRENT_SONG: + serverConnection->clearCurrentSong(); + break; } } void DataStore::onAuthFail(const QString& /*errMessage*/){ - isReauthing=false; Logger::instance()->log("BAD STUFF, BAD AUTH CREDS, BAD REAUTH"); - //TODO need to do something here + setPasswordDirty(); + emit hardAuthFailure(); } void DataStore::initReauth(){ @@ -1052,42 +1165,51 @@ settings.setValue(getDontShowPlaybackErrorSettingName(), checked); } +void DataStore::saveUsername(const QString& username){ + QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); + SimpleCrypt crypt = Utils::getCryptoObject(); + QString cryptUsername = crypt.encryptToString(username); + settings.setValue(getUsernameSettingName(), cryptUsername); +} -void DataStore::saveCredentials( - const QString& username, const QString& password) +QString DataStore::getSavedUsername(){ + QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); + SimpleCrypt crypt = Utils::getCryptoObject(); + QString encryptedUsername = settings.value(getUsernameSettingName()).toString(); + return encryptedUsername == "" ? "" : crypt.decryptToString(encryptedUsername); +} + + + +void DataStore::savePassword(const QString& password) { QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); SimpleCrypt crypt = Utils::getCryptoObject(); - QString cryptUsername = crypt.encryptToString(username); QString cryptPassword = crypt.encryptToString(password); - settings.setValue(getHasValidCredsSettingName(), true); - settings.setValue(getUsernameSettingName(), cryptUsername); + settings.setValue(getHasValidSavedPasswordSettingName(), true); settings.setValue(getPasswordSettingName(), cryptPassword); } -void DataStore::setCredentialsDirty(){ +void DataStore::setPasswordDirty(){ QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); - settings.setValue(getHasValidCredsSettingName(), false); + settings.setValue(getHasValidSavedPasswordSettingName(), false); } -bool DataStore::hasValidSavedCredentials(){ +bool DataStore::hasValidSavedPassword(){ QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); - return settings.value(getHasValidCredsSettingName()).toBool(); + return settings.value(getHasValidSavedPasswordSettingName()).toBool(); } -void DataStore::getSavedCredentials(QString* username, QString* password){ +QString DataStore::getSavedPassword(){ QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); SimpleCrypt crypt = Utils::getCryptoObject(); - QString encryptedUsername = settings.value(getUsernameSettingName()).toString(); QString encryptedPassword = settings.value(getPasswordSettingName()).toString(); - *username = crypt.decryptToString(encryptedUsername); - *password = crypt.decryptToString(encryptedPassword); + return crypt.decryptToString(encryptedPassword); } -void DataStore::clearSavedCredentials(){ +void DataStore::clearSavedPassword(){ QSettings settings(QSettings::UserScope, getSettingsOrg(), getSettingsApp()); - settings.setValue(getHasValidCredsSettingName(), false); - settings.setValue(getUsernameSettingName(), ""); + settings.setValue(getHasValidSavedPasswordSettingName(), false); settings.setValue(getPasswordSettingName(), ""); } diff -Nru udj-desktop-client-0.5.1/src/DataStore.hpp udj-desktop-client-0.6.3/src/DataStore.hpp --- udj-desktop-client-0.5.1/src/DataStore.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/DataStore.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -51,7 +51,13 @@ GET_ACTIVE_PLAYLIST, SET_CURRENT_SONG, MOD_PLAYLIST, - SET_CURRENT_VOLUME + SET_CURRENT_VOLUME, + SET_PLAYER_STATE, + SET_PLAYER_INACTIVE, + SET_PLAYER_LOCATION, + SET_PLAYER_PASSWORD, + REMOVE_PLAYER_PASSWORD, + CLEAR_CURRENT_SONG }; /** @@ -61,6 +67,7 @@ Phonon::MediaSource source; QString title; QString artist; + QString duration; } song_info_t; //@} @@ -86,6 +93,26 @@ //@} + /** @name Accessors */ + //@{ + + /** + * \brief Checks to see if a particular song is already in + * the library and not deleted. + * + * @param fileName The file to be checked. + * @return True if the file is already in the library, false + * otherwise. + */ + bool alreadyHaveSongInLibrary(const QString& fileName) const; + + inline library_song_id_t getCurrentSongId() const{ + return currentSongId; + } + + //@} + + /** @name Modifiers */ //@{ @@ -101,6 +128,11 @@ QProgressDialog* progress=0); /** + * \brief Clears the current song that is playing. + */ + void clearCurrentSong(); + + /** * \brief Removes the password on the player. */ void removePlayerPassword(); @@ -124,22 +156,13 @@ const QString& streetAddress, const QString& city, const QString& state, - int zipcode + const QString& zipcode ); /** - * \brief Set player name. - * - * \param The new name the player should have. - */ - void setPlayerName(const QString& newName); - - /** - * \brief Set player state. - * - * \param State to which the player should be set. + * \brief Sets the player as inactive. */ - void setPlayerState(const QString& newState); + void setPlayerInactive(); /** * \brief Removes the given songs from the music library. @@ -175,7 +198,7 @@ * * @return The id of the player. */ - inline const player_id_t getPlayerId() const{ + inline player_id_t getPlayerId() const{ QSettings settings( QSettings::UserScope, getSettingsOrg(), getSettingsApp()); return settings.value(getPlayerIdSettingName()).value(); @@ -230,18 +253,7 @@ inline bool hasPlayerPassword() const{ QSettings settings( QSettings::UserScope, getSettingsOrg(), getSettingsApp()); - return settings.contains(getPlayerPasswordSettingName()); - } - - /** - * \brief Retreives the password for the player. - * - * @return The password for the player, if none is set a blank string is returned. - */ - inline QString getPlayerPassword() const{ - QSettings settings( - QSettings::UserScope, getSettingsOrg(), getSettingsApp()); - return settings.value(getPlayerPasswordSettingName()).toString(); + return settings.value(getHasPlayerPasswordSettingName(), false).toBool(); } /** @@ -339,44 +351,56 @@ * * \return True if the player has an id, false otherwise. */ - bool hasPlayerId() const{ + static bool hasPlayerId(){ QSettings settings( QSettings::UserScope, getSettingsOrg(), getSettingsApp()); return -1 != settings.value(getPlayerIdSettingName(), -1); } /** - * \brief Saves the given credentials to persistent storage in a secure manner. + * \brief Saves the given password to persistent storage in a "secure" manner. * - * @param username The username to save. * @param password The password to save. */ - static void saveCredentials(const QString& username, const QString& password); + static void savePassword(const QString& password); /** * \brief Marks the current saved credentials as invalid. */ - static void setCredentialsDirty(); + static void setPasswordDirty(); /** - * \brief Determines whether or not the currently saved credentials are valid. + * \brief Determines whether or not the currently saved password is valid. * - * @return True if the currently saved credentials are valide, false otherwise. + * @return True if the currently saved password is valid, false otherwise. */ - static bool hasValidSavedCredentials(); + static bool hasValidSavedPassword(); /** - * \brief Retrieves the currently saved credentials. + * \brief Retrieves the currently saved password. * - * @param username Pointer to the QString where the retreived username should be put. - * @param password Pointer to the QString where the retreived password should be put. + * @return The saved password. */ - static void getSavedCredentials(QString* username, QString* password); + static QString getSavedPassword(); /** * \brief Deletes all the saved credentials. */ - static void clearSavedCredentials(); + static void clearSavedPassword(); + + /** + * \brief Saves the given username to persistent storage + * + * \param username Username to save to presistent storage. + */ + static void saveUsername(const QString& username); + + /** + * \brief Retrieves the last username that was saved to presistent storage. + * + * \return The last username that was saved to persistent storage. + */ + static QString getSavedUsername(); static bool getDontShowPlaybackErrorSetting(); @@ -765,13 +789,13 @@ } /** - * \brief Name of the setting used to store the password being used for the player. + * \brief Name of the setting used to store whether or not the player has a password. * - * @return Name of the setting used to store the password being used for the player. + * @return Name of the setting used to store whether or not the player has a password. */ - static const QString& getPlayerPasswordSettingName(){ - static const QString playerPasswordSettingName = "playerPassword"; - return playerPasswordSettingName; + static const QString& getHasPlayerPasswordSettingName(){ + static const QString hasPlayerPasswordSettingName = "hasPlayerPassword"; + return hasPlayerPasswordSettingName; } /** @@ -875,6 +899,15 @@ //@{ public slots: + /** + * \brief Starts the datastore automatically refreshing the playlist. + */ + void startPlaylistAutoRefresh(); + + /** + * \brief Starts the datastore automatically refreshing the list of participants. + */ + void startParticipantsAutoRefresh(); /** * \brief Syncs the current state of the library with the server. @@ -896,6 +929,9 @@ */ void refreshActivePlaylist(); + /** \brief Refresh the participants list. */ + void refreshParticipantList(); + /** * \brief Adds the given song to the active playlist. * @@ -943,7 +979,7 @@ const QString& streetAddress, const QString& city, const QString& state, - const int& zipcode); + const QString& zipcode); /** * \brief Sets the current song to the speicified song. @@ -953,11 +989,11 @@ void setCurrentSong(const library_song_id_t& songToPlay); /** - * \brief Changes the volume without emtting a signal noting that the volume has changed. + * \brief Sets the volume for the player. * * @param newVolume The new player volume. */ - void changeVolumeSilently(qreal newVolume); + void setVolume(qreal newVolume); /** \brief Determines whether or not the library has unsynced songs.*/ bool hasUnsyncedSongs() const; @@ -973,7 +1009,38 @@ //@{ /** - * \brief Emitted when the player's password has been removed. + * \brief Emitted when the given user credentials do not work with the server. + */ + void hardAuthFailure(); + + /** + * \brief Emitted when the player state was succesfully changed to inactive. + */ + void playerSuccessfullySetInactive(); + + /** + * \brief Emitted when there was an error setting the player inactive. + * + * @param errMessage A message descibing the error. + */ + void playerSetInactiveError(const QString& errMessage); + + /** + * \brief Emitted when there was an error setting the player to "playing". + * + * @param errMessage A message descibing the error. + */ + void playPlayerError(const QString& errMessage); + + /** + * \brief Emitted when there was an error setting the player to "paused". + * + * @param errMessage A message descibing the error. + */ + void pausePlayerError(const QString& errMessage); + + /** + * \brief Emitted when the player's password has been removed by a component of this client. */ void playerPasswordRemoved(); @@ -985,7 +1052,7 @@ void playerPasswordRemoveError(const QString& errMessage); /** - * \brief Emitted when the player's password is set. + * \brief Emitted when the player's password is set by a compenent of this client. */ void playerPasswordSet(); @@ -997,7 +1064,7 @@ void playerPasswordSetError(const QString& errMessage); /** - * \brief Emitted when the players location has been set. + * \brief Emitted when the player's location is set by a component of this client. */ void playerLocationSet(); @@ -1009,20 +1076,6 @@ void playerLocationSetError(const QString& errMessage); /** - * \brief Emitted when the players name is succesfully changed. - * - * \param newName The new name the player was set to. - */ - void playerNameChanged(const QString& newName); - - /** - * \brief Emitted when changing the players name failes. - * - * \param errMessage An error message describing the failure. - */ - void playerNameChangeError(const QString& errMessage); - - /** * \brief Emitted when the library table is modified. */ void libSongsModified(const QSet& modifiedSongs); @@ -1052,11 +1105,16 @@ void playerCreationFailed(const QString errMessage); /** - * \brief Emitted when the active playlist is modified. + * \brief Emitted when the active playlist is modified by the server. */ void activePlaylistModified(); /** + * \brief Emitted when the participant list retrieved from server. + */ + void newParticipantList(const QVariantList& newParticipants); + + /** * \brief Emitted when the current song is manually changed. * * @param newSong The song that should be set as the current song. @@ -1064,19 +1122,33 @@ void manualSongChange(DataStore::song_info_t newSong); /** - * \brief Emitted when the players state is changed. + * \brief Emitted when the players state is changed by the server. * * \param newState The new state of the player. */ void playerStateChanged(const QString& newState); /** - * \brief Emitted when the volume of the player is changed. + * \brief Emitted when the volume of the player is changed by the server. * * @param newVolume The new volume of the player. */ void volumeChanged(qreal newVolume); + /** + * \brief Emitted when changing the volume on the server failed. + * + * @param errMessage A message describing the error. + */ + void setVolumeError(const QString& errMessage); + + /** + * \brief Emitted when clearing the current song on ther server failed. + * + * @param errMessage A message describing the error. + */ + void clearCurrentSongError(const QString& errMessage); + //@} private: @@ -1093,6 +1165,9 @@ /** \brief Timer used to refresh the active playlist. */ QTimer *activePlaylistRefreshTimer; + /** \brief Timer used to refresh the list of participants. */ + QTimer *participantRefreshTimer; + /** \brief Current username being used by the client */ QString username; @@ -1102,9 +1177,31 @@ /** \brief A set of actions to be performed once the client has succesfully reauthenticated. */ QSet reauthActions; + /** + * \brief If there is an auth error during the setting of a player password, this is the password that + * should be set on the player after the reauth is complete. + */ + QString reauthPlayerPassword; + /** \brief Whether or not the client is currently reauthenticating. */ bool isReauthing; + /** + * \brief Whether or not the client is currently setting the player's playback state. + * + * This is used to help us ignore playback states that are different from our own while + * we're in the process of changing the playback state. + */ + bool changingPlayerState; + + /** + * \brief Whether or not the client is currently setting the current song as cleared. + * + * This is used to help us ignore current song changes while we're clearing the current + * song. + */ + bool clearingCurrentSong; + /** \brief The current song being played. */ library_song_id_t currentSongId; @@ -1123,6 +1220,13 @@ void setupDB(); /** + * \brief Set player state. + * + * \param State to which the player should be set. + */ + void setPlayerState(const QString& newState); + + /** * \brief Deletes a single song from the active playlist. * * \param toDelete The library id of the song to delete from the playlist. @@ -1154,6 +1258,7 @@ */ void addSongToLibrary(const Phonon::MediaSource& song, QSqlQuery& addQuery); + /** * \brief Gets the value of a header. * @@ -1330,10 +1435,10 @@ * * @return Name of the setting used to store whether or not the current credentials are valid. */ - static const QString& getHasValidCredsSettingName(){ - static const QString hasValidSavedCredentialsSettingName = - "has_valid_creds"; - return hasValidSavedCredentialsSettingName; + static const QString& getHasValidSavedPasswordSettingName(){ + static const QString hasValidSavedPasswordSettingName = + "has_valid_password"; + return hasValidSavedPasswordSettingName; } //@} @@ -1343,85 +1448,79 @@ private slots: /** - * \brief Preforms appropriate tasks when a player's password has been removed. + * \brief Performs appropriate tasks when the player's state has been succesfully changed on the + * server. + * + * \param state The state the player was changed to on the server. */ - void onPlayerPasswordRemoved(); + void onPlayerStateSet(const QString& state); /** - * \brief Preforms appropriate tasks when there was an error removing the player's password. + * \brief Performs appropriate tasks when the player's state has been succesfully changed on the + * server. * + * \param state The state which was attempted to be set on the player. * \param errMessage A message describing the error. * \param errorCode HTTP error code describing error. * \param headers HTTP headers accompianing in the error response. */ - void onPlayerPasswordRemoveError( + void onPlayerStateSetError( + const QString& state, const QString& errMessage, int errorCode, const QList& headers); /** - * \brief Preforms appropriate tasks when a player's password is set. - * - * \brief password The password that has been set on the server. + * \brief Performs appropriate tasks when the current song has been succesfully cleared. */ - void onPlayerPasswordSet(const QString& password); + void onCurrentSongCleared(); /** - * \brief Preforms appropriate tasks when there was an error setting the player's location. + * \brief Preforms appropriate tasks when there was an error clearing the current song. * * \param errMessage A message describing the error. * \param errorCode HTTP error code describing error. * \param headers HTTP headers accompianing in the error response. */ - void onPlayerPasswordSetError( + void onCurrentSongClearError( const QString& errMessage, int errorCode, const QList& headers); - /** - * \brief Preforms appropriate tasks when a players location was succesfully set. + * \brief Preforms appropriate tasks when there was an error removing the player's password. * - * \brief streetAddress The street address of location that was set for the player. - * \brief city The city of location that was set for the player. - * \brief state The state of location that was set for the player. - * \brief zipcode The zipcode of location that was set for the player. + * \param errMessage A message describing the error. + * \param errorCode HTTP error code describing error. + * \param headers HTTP headers accompianing in the error response. */ - void onPlayerLocationSet( - const QString& streetAddress, - const QString& city, - const QString& state, - int zipcode - ); + void onPlayerPasswordRemoveError( + const QString& errMessage, + int errorCode, + const QList& headers); /** * \brief Preforms appropriate tasks when there was an error setting the player's location. * + * \param attemptedPassword The password that was attempted to be set on the server. * \param errMessage A message describing the error. * \param errorCode HTTP error code describing error. * \param headers HTTP headers accompianing in the error response. */ - void onPlayerLocationSetError( + void onPlayerPasswordSetError( + const QString& attemptedPassword, const QString& errMessage, int errorCode, const QList& headers); /** - * \brief Preforms appropriate tasks when a players name was succesfully changed on the - * server. - * - * \param newName The new name of the player. - */ - void onPlayerNameChanged(const QString& newName); - - /** - * \brief Preforms appropriate tasks when there was an error changing the player name. + * \brief Preforms appropriate tasks when there was an error setting the player's location. * * \param errMessage A message describing the error. * \param errorCode HTTP error code describing error. * \param headers HTTP headers accompianing in the error response. */ - void onPlayerNameChangeError( + void onPlayerLocationSetError( const QString& errMessage, int errorCode, const QList& headers); @@ -1500,12 +1599,6 @@ const QList& headers); /** - * \brief Takes appropriate action when the player state is changed. - */ - void onPlayerStateChanged(const QString& newState); - - - /** * \brief Takes appropriate action when modifiying the library on the server fails. * * @param errMessage A message describing the error. @@ -1578,6 +1671,14 @@ int errorCode, const QList& headers); + /** + * \brief Takes appropriate action when the particpants list is retrieved from the server. + * + * \param newParticipants The new list of participants. + */ + void onNewParticipantList(const QVariantList& newParticipants); + + //@} diff -Nru udj-desktop-client-0.5.1/src/JSONHelper.cpp udj-desktop-client-0.6.3/src/JSONHelper.cpp --- udj-desktop-client-0.5.1/src/JSONHelper.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/JSONHelper.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -105,7 +105,7 @@ const QString& streetAddress, const QString& city, const QString& state, - const int& zipcode) + const QString& zipcode) { bool success; return getCreatePlayerJSON(playerName, password, streetAddress, city, state, zipcode, success); @@ -117,7 +117,7 @@ const QString& streetAddress, const QString& city, const QString& state, - const int& zipcode, + const QString& zipcode, bool &success) { QVariantMap playerToCreate; @@ -128,9 +128,10 @@ QVariantMap location; location["address"] = streetAddress; - location["city"] = city; - location["state"] = state; - location["zipcode"] = zipcode; + location["locality"] = city; + location["region"] = state; + location["postal_code"] = zipcode; + location["country"] = "United States"; playerToCreate["location"] = location; return QtJson::Json::serialize(QVariant(playerToCreate),success); @@ -149,7 +150,7 @@ responseString.toStdString() << std::endl; } - return playerCreated["player_id"].value(); + return playerCreated["id"].value(); } QVariantMap JSONHelper::getActivePlaylistFromJSON(QNetworkReply *reply){ @@ -166,6 +167,20 @@ return activePlaylist; } +QVariantList JSONHelper::getParticipantListFromJSON(QNetworkReply *reply){ + QByteArray responseData = reply->readAll(); + QString responseString = QString::fromUtf8(responseData); + bool success; + QVariantList participantsList = + QtJson::Json::parse(responseString, success).toList(); + if(!success){ + std::cerr << "Error parsing json from a response to an get Participants List request" << + std::endl << + responseString.toStdString() << std::endl; + } + return participantsList; +} + QByteArray JSONHelper::getJSONLibIds(const QSet& libIds){ bool success; QVariantList idList; diff -Nru udj-desktop-client-0.5.1/src/JSONHelper.hpp udj-desktop-client-0.6.3/src/JSONHelper.hpp --- udj-desktop-client-0.5.1/src/JSONHelper.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/JSONHelper.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -129,7 +129,7 @@ const QString& streetAddress, const QString& city, const QString& state, - const int& zipcode); + const QString& zipcode); /** * \brief Gets the json needed for creating a player. @@ -150,7 +150,7 @@ const QString& streetAddress, const QString& city, const QString& state, - const int& zipcode, + const QString& zipcode, bool &success); /** @@ -188,6 +188,14 @@ static QVariantMap getActivePlaylistFromJSON(QNetworkReply *reply); /** + * \brief Gets the list of participants from the JSON given in the server reply. + * + * \param reply The reply from the server. + * \return A QVariantMap representing the participants given in the server reply. + */ + static QVariantList getParticipantListFromJSON(QNetworkReply *reply); + + /** * \brief Gets the auth data from a server authentication reply. * * \param reply The reply from the server. diff -Nru udj-desktop-client-0.5.1/src/LibraryWidget.cpp udj-desktop-client-0.6.3/src/LibraryWidget.cpp --- udj-desktop-client-0.5.1/src/LibraryWidget.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/LibraryWidget.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -33,6 +33,8 @@ searchEdit = new QLineEdit(this); QLabel *searchLabel = new QLabel(tr("Search:"),this); + setFocusPolicy(Qt::TabFocus); + QGridLayout *layout = new QGridLayout(this); layout->addWidget(searchLabel,0,1,1,8, Qt::AlignRight); diff -Nru udj-desktop-client-0.5.1/src/LoginWidget.cpp udj-desktop-client-0.6.3/src/LoginWidget.cpp --- udj-desktop-client-0.5.1/src/LoginWidget.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/LoginWidget.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -66,16 +66,19 @@ passwordLabel->setBuddy(passwordBox); - saveCreds = new QCheckBox(tr("Remember me")); + savePassword = new QCheckBox(tr("Remember password")); registerText = new QLabel(tr("No account? Register here")); registerText->setOpenExternalLinks(true); + forgotPasswordText = new QLabel(tr("Forgot your password?")); + forgotPasswordText->setOpenExternalLinks(true); + connect( - saveCreds, + savePassword, SIGNAL(toggled(bool)), this, - SLOT(saveCredsChanged(bool))); + SLOT(savePasswordChanged(bool))); QGridLayout *layout = new QGridLayout; @@ -84,8 +87,9 @@ layout->addWidget(usernameBox,1,1); layout->addWidget(passwordLabel,2,0); layout->addWidget(passwordBox,2,1); - layout->addWidget(saveCreds, 3, 1); - layout->addWidget(registerText, 4, 0, 1, 2, Qt::AlignCenter); + layout->addWidget(savePassword, 3, 1); + layout->addWidget(forgotPasswordText, 4, 0, 1, 2, Qt::AlignCenter); + layout->addWidget(registerText, 5, 0, 1, 2, Qt::AlignCenter); @@ -94,13 +98,25 @@ setMainWidget(loginDisplay); showMainWidget(); - if(DataStore::hasValidSavedCredentials()){ - QString username; - QString password; - DataStore::getSavedCredentials(&username, &password); - usernameBox->setText(username); - passwordBox->setText(password); - saveCreds->setChecked(true); + //If we already have a player id we can't let the sign in with a different user + //then the last one the signed in with. Otherwise bad things might happen because + //the user they sign in as may not have permission to do things like set the player state. + //The check for if they have a saved username or not is for people who are upgrading and may + //not have saved their username in older versions but have created a player. + if(DataStore::hasPlayerId() && DataStore::getSavedUsername() != "" ){ + QString alreadyAssociatedMessage(tr("You have already associated a player with this computer.\n" + "This means you have to login as the player's owner.")); + usernameBox->setEnabled(false); + usernameBox->setToolTip(alreadyAssociatedMessage); + usernameLabel->setEnabled(false); + usernameLabel->setToolTip(alreadyAssociatedMessage); + } + + usernameBox->setText(DataStore::getSavedUsername()); + + if(DataStore::hasValidSavedPassword()){ + passwordBox->setText(DataStore::getSavedPassword()); + savePassword->setChecked(true); } } @@ -112,10 +128,12 @@ void LoginWidget::startMainGUI( const QByteArray& ticketHash, const user_id_t& userId) { - if(saveCreds->isChecked()){ - DataStore::saveCredentials(usernameBox->text(), passwordBox->text()); + if(savePassword->isChecked()){ + DataStore::savePassword(passwordBox->text()); } + DataStore::saveUsername(usernameBox->text()); + MetaWindow *metaWindow = new MetaWindow( usernameBox->text(), passwordBox->text(), @@ -127,7 +145,7 @@ void LoginWidget::displayLoginFailedMessage(const QString errorMessage){ emit loginFailed(); - DataStore::setCredentialsDirty(); + DataStore::setPasswordDirty(); showMainWidget(); setCurrentWidget(loginDisplay); QMessageBox::critical( @@ -136,10 +154,9 @@ errorMessage); } -void LoginWidget::saveCredsChanged(bool newCreds){ - if(!newCreds && DataStore::hasValidSavedCredentials()){ - DataStore::clearSavedCredentials(); - usernameBox->setText(""); +void LoginWidget::savePasswordChanged(bool newSetting){ + if(!newSetting && DataStore::hasValidSavedPassword()){ + DataStore::clearSavedPassword(); passwordBox->setText(""); } } diff -Nru udj-desktop-client-0.5.1/src/LoginWidget.hpp udj-desktop-client-0.6.3/src/LoginWidget.hpp --- udj-desktop-client-0.5.1/src/LoginWidget.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/LoginWidget.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -85,12 +85,15 @@ /** \brief lineedit used for entering the password. */ QLineEdit *passwordBox; - /** \brief Checkbox for indicating whether or not credentials should be saved. */ - QCheckBox *saveCreds; + /** \brief Checkbox for indicating whether or not password should be saved. */ + QCheckBox *savePassword; /** \brief Label giving registration information. */ QLabel *registerText; + /** \brief Label giving forgotten password information. */ + QLabel *forgotPasswordText; + /** \brief Actual display for the login widget. */ QWidget *loginDisplay; @@ -136,11 +139,11 @@ void displayLoginFailedMessage(const QString errorMessage); /** - * \brief Takes appropriate action when the user clicks on the saveCreds check box. + * \brief Takes appropriate action when the user clicks on the savePassword check box. * - * \param newSetting The current state of the save credentials check box. + * \param newSetting The current state of the save password check box. */ - void saveCredsChanged(bool newSetting); + void savePasswordChanged(bool newSetting); //@} }; diff -Nru udj-desktop-client-0.5.1/src/MetaWindow.cpp udj-desktop-client-0.6.3/src/MetaWindow.cpp --- udj-desktop-client-0.5.1/src/MetaWindow.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/MetaWindow.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -28,7 +28,7 @@ #include "AboutWidget.hpp" #include "LogViewer.hpp" #include "SetLocationDialog.hpp" -#include "SetPasswordDialog.hpp" +#include "ParticipantsView.hpp" #include #include #include @@ -46,6 +46,7 @@ #include + namespace UDJ{ @@ -57,9 +58,15 @@ QWidget *parent, Qt::WindowFlags flags) :QMainWindow(parent,flags), - isQuiting(false) + isQuiting(false), + hasHardAuthFailure(false) { dataStore = new DataStore(username, password, ticketHash, userId, this); + #if IS_WINDOWS_BUILD + updater = new qtsparkle::Updater( + QUrl(UDJ_WINDOWS_UPDATE_URL), this); + #endif + createActions(); setupUi(); setupMenus(); @@ -75,7 +82,9 @@ setWindowState(Qt::WindowMaximized); } if(dataStore->hasPlayerId()){ - dataStore->setPlayerState(DataStore::getPlayingState()); + dataStore->playPlayer(); + dataStore->startPlaylistAutoRefresh(); + dataStore->startParticipantsAutoRefresh(); if(dataStore->hasUnsyncedSongs()){ syncLibrary(); } @@ -101,20 +110,52 @@ SIGNAL(playerCreated()), this, SLOT(checkForITunes())); + connect( + dataStore, + SIGNAL(playerCreated()), + dataStore, + SLOT(playPlayer())); + connect( + dataStore, + SIGNAL(playerCreated()), + dataStore, + SLOT(startPlaylistAutoRefresh())); + connect( + dataStore, + SIGNAL(playerCreated()), + dataStore, + SLOT(startParticipantsAutoRefresh())); + connect( + dataStore, + SIGNAL(hardAuthFailure()), + this, + SLOT(onHardAuthFailure())); + connect( + dataStore, + SIGNAL(playerLocationSetError(const QString&)), + this, + SLOT(onPlayerLocationSetError(const QString&))); + + connect( + dataStore, + SIGNAL(playerPasswordRemoveError(const QString&)), + this, + SLOT(onPlayerPasswordRemoveError(const QString&))); } void MetaWindow::closeEvent(QCloseEvent *event){ - if(!isQuiting){ + if(!isQuiting && !hasHardAuthFailure){ isQuiting = true; connect( dataStore, - SIGNAL(playerStateChanged(const QString&)), + SIGNAL(playerSuccessfullySetInactive()), this, SLOT(close())); + //NOTE NOT HANDLING IF THERE WAS AN ERROR SETTING THE PLAYER INACTIVE NEED TO HANDLE THIS quittingProgress = new QProgressDialog("Disconnecting...", "Cancel", 0, 0, this); quittingProgress->setWindowModality(Qt::WindowModal); quittingProgress->setMinimumDuration(250); - dataStore->setPlayerState(DataStore::getInactiveState()); + dataStore->setPlayerInactive(); event->ignore(); } else{ @@ -128,33 +169,54 @@ } } -void MetaWindow::checkForITunes(){ +bool MetaWindow::eventFilter(QObject* /*obj*/, QEvent *event){ + if(event->type() == QEvent::KeyRelease){ + QKeyEvent *keyEvent = static_cast(event); + if(keyEvent->key() == Qt::Key_Space){ + playbackWidget->togglePlaybackState(); + return true; + } + } + return false; +} + +bool MetaWindow::hasItunesLibrary(){ QString musicDir = QDesktopServices::storageLocation(QDesktopServices::MusicLocation); QDir iTunesDir = QDir(musicDir).filePath("iTunes"); - if(iTunesDir.exists("iTunes Music Library.xml")){ + return iTunesDir.exists("iTunes Music Library.xml"); +} + +void MetaWindow::checkForITunes(){ + if(hasItunesLibrary()){ QMessageBox::StandardButton response = QMessageBox::question( this, "Import iTunes Library", "Looks like you've got iTunes installed. Would you like" " us to try to import your iTunes Library?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(response == QMessageBox::Yes){ - QList musicToAdd = - MusicFinder::findItunesMusic(iTunesDir.filePath("iTunes Music Library.xml")); - Logger::instance()->log("Size of itunes was: " + QString::number(musicToAdd.size())); - addMediaSources(musicToAdd); + scanItunesLibrary(); } } else{ - Logger::instance()->log(iTunesDir.filePath("iTunes Music Library.xml") + " doesn't exist"); + Logger::instance()->log("iTunes dir doesn't exist"); } } +void MetaWindow::scanItunesLibrary(){ + QString musicDir = QDesktopServices::storageLocation(QDesktopServices::MusicLocation); + QDir iTunesDir = QDir(musicDir).filePath("iTunes"); + QList musicToAdd = + MusicFinder::findItunesMusic(iTunesDir.filePath("iTunes Music Library.xml"), dataStore); + Logger::instance()->log("Size of itunes was: " + QString::number(musicToAdd.size())); + addMediaSources(musicToAdd); +} + void MetaWindow::addMediaSources(const QList& musicToAdd){ if(musicToAdd.isEmpty()){ QMessageBox::information( this, "No Music Found", - "Sorry, but we couldn't find any music that we know how to play."); + "Sorry, but we couldn't find any new music that we know how to play."); return; } @@ -180,7 +242,7 @@ return; } QList musicToAdd = - MusicFinder::findMusicInDir(musicDir); + MusicFinder::findMusicInDir(musicDir, dataStore); addMediaSources(musicToAdd); } @@ -193,6 +255,13 @@ if(fileName == ""){ return; } + if(dataStore->alreadyHaveSongInLibrary(fileName)){ + QMessageBox::information( + this, + "Already In Library", + "You already have that song in your music library"); + return; + } QList songList; songList.append(Phonon::MediaSource(fileName)); dataStore->addMusicToLibrary(songList); @@ -204,15 +273,21 @@ playbackWidget = new PlaybackWidget(dataStore, this); libraryWidget = new LibraryWidget(dataStore, this); + libraryWidget->installEventFilter(this); activityList = new ActivityList(dataStore); playlistView = new ActivePlaylistView(dataStore, this); + playlistView->installEventFilter(this); + + participantsView = new ParticipantsView(dataStore, this); + participantsView->installEventFilter(this); QWidget* contentStackContainer = new QWidget(this); contentStack = new QStackedWidget(this); contentStack->addWidget(libraryWidget); contentStack->addWidget(playlistView); + contentStack->addWidget(participantsView); contentStack->setCurrentWidget(libraryWidget); QVBoxLayout *contentStackLayout = new QVBoxLayout; contentStackLayout->addWidget(contentStack, Qt::AlignCenter); @@ -250,6 +325,12 @@ SLOT(displayPlaylist())); connect( + activityList, + SIGNAL(participantsClicked()), + this, + SLOT(displayParticipants())); + + connect( libraryWidget, SIGNAL(libNeedsSync()), this, @@ -259,24 +340,33 @@ void MetaWindow::createActions(){ quitAction = new QAction(tr("&Quit"), this); quitAction->setShortcuts(QKeySequence::Quit); - addMusicAction = new QAction(tr("Add &Music"), this); + addMusicAction = new QAction(tr("Add &Music Folder"), this); addMusicAction->setShortcut(tr("Ctrl+M")); - addSongAction = new QAction(tr("A&dd Song"), this); + addSongAction = new QAction(tr("A&dd Single Song"), this); addSongAction->setShortcut(tr("Ctrl+D")); - viewLogAction = new QAction(tr("View &Log"), this); - viewLogAction->setShortcut(tr("Ctrl+L")); + viewLogAction = new QAction(tr("View Lo&g"), this); + viewLogAction->setShortcut(tr("Ctrl+G")); viewAboutAction = new QAction(tr("About"), this); + rescanItunesAction = new QAction(tr("Rescan iTunes Library"), this); + #if IS_WINDOWS_BUILD + checkUpdateAction = new QAction(tr("Check For Updates"), this); + connect(checkUpdateAction, SIGNAL(triggered()), updater, SLOT(CheckNow())); + #endif connect(addMusicAction, SIGNAL(triggered()), this, SLOT(addMusicToLibrary())); connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); connect(addSongAction, SIGNAL(triggered()), this, SLOT(addSongToLibrary())); connect(viewLogAction, SIGNAL(triggered()), this, SLOT(displayLogView())); connect(viewAboutAction, SIGNAL(triggered()), this, SLOT(displayAboutWidget())); + connect(rescanItunesAction, SIGNAL(triggered()), this, SLOT(scanItunesLibrary())); } void MetaWindow::setupMenus(){ QMenu *musicMenu = menuBar()->addMenu(tr("&Music")); musicMenu->addAction(addMusicAction); musicMenu->addAction(addSongAction); + if(hasItunesLibrary()){ + musicMenu->addAction(rescanItunesAction); + } musicMenu->addSeparator(); musicMenu->addAction(quitAction); @@ -285,16 +375,17 @@ QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(viewLogAction); helpMenu->addAction(viewAboutAction); + #if IS_WINDOWS_BUILD + helpMenu->addAction(checkUpdateAction); + #endif } void MetaWindow::configurePlayerMenu(){ QMenu *playerMenu = menuBar()->addMenu(tr("&Player")); - changeNameAction = new QAction(tr("Change Name"), this); - playerMenu->addAction(changeNameAction); - - setLocationAction = new QAction(tr("Set Location"), this); + setLocationAction = new QAction(tr("Set &Location"), this); + setLocationAction->setShortcut(tr("Ctrl+L")); playerMenu->addAction(setLocationAction); setPasswordAction = new QAction(tr("Set Password"), this); @@ -304,7 +395,6 @@ playerMenu->addAction(removePasswordAction); removePasswordAction->setEnabled(dataStore->hasPlayerPassword()); - connect(changeNameAction, SIGNAL(triggered()), this, SLOT(changePlayerName())); connect(setLocationAction, SIGNAL(triggered()), this, SLOT(setPlayerLocation())); connect(setPasswordAction, SIGNAL(triggered()), this, SLOT(setPlayerPassword())); connect(removePasswordAction, SIGNAL(triggered()), this, SLOT(removePlayerPassword())); @@ -315,47 +405,27 @@ this, tr("Remove password"), tr("Are you sure you want to remove the player password"), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok); if(response == QMessageBox::Ok){ - connect( - dataStore, - SIGNAL(playerPasswordRemoved()), - this, - SLOT(onPlayerPasswordRemoved())); - connect( - dataStore, - SIGNAL(playerPasswordRemoveError(const QString&)), - this, - SLOT(onPlayerPasswordRemoveError())); dataStore->removePlayerPassword(); } } -void MetaWindow::disconnectPlayerPasswordRemoveSignals(){ - disconnect( - dataStore, - SIGNAL(playerPasswordRemoved()), - this, - SLOT(onPlayerPasswordRemoved())); - disconnect( - dataStore, - SIGNAL(playerPasswordRemoveError(const QString&)), - this, - SLOT(onPlayerPasswordRemoveError())); -} - - -void MetaWindow::onPlayerPasswordRemoved(){ - disconnectPlayerPasswordRemoveSignals(); -} - -void MetaWindow::onPlayerPasswordRemoveError(){ - disconnectPlayerPasswordRemoveSignals(); +void MetaWindow::onPlayerPasswordRemoveError(const QString& /*errMessage*/){ QMessageBox::critical(this, tr("Error Removing Password"), tr("Oops. We couldn't remove the " "player's password. We're super sorry. Can you try it again in a little bit?")); } void MetaWindow::setPlayerPassword(){ - SetPasswordDialog *setPasswordDialog = new SetPasswordDialog(dataStore, this); - setPasswordDialog->show(); + bool ok; + QString newPlayerPassword = QInputDialog::getText(this, tr("Set Player Password"), + tr("Password:"), QLineEdit::Normal, tr("New Password"), &ok); + if(ok){ + if(newPlayerPassword != ""){ + dataStore->setPlayerPassword(newPlayerPassword); + } + else{ + QMessageBox::critical(this, "Player Password Error", "Player passwords can't be blank."); + } + } } void MetaWindow::setPlayerLocation(){ @@ -363,51 +433,6 @@ setLocationDialog->show(); } -void MetaWindow::changePlayerName(){ - bool gotNewName; - QString newName = QInputDialog::getText(this, tr("Set Player Name"), - tr("New Player Name:"), QLineEdit::Normal, "", &gotNewName); - if(gotNewName && !newName.isEmpty()){ - connect( - dataStore, - SIGNAL(playerNameChanged(const QString&)), - this, - SLOT(onPlayerNameChanged())); - connect( - dataStore, - SIGNAL(playerNameChangeError(const QString&)), - this, - SLOT(onPlayerNameChangeError(const QString&))); - dataStore->setPlayerName(newName); - } - else if(gotNewName){ - QMessageBox::critical(this, "Player Name Blank", "You must provided a non-blank name for your player"); - } - -} - -void MetaWindow::disconnectNameChangeSignals(){ - disconnect( - dataStore, - SIGNAL(playerNameChanged(const QString&)), - this, - SLOT(onPlayerNameChanged())); - disconnect( - dataStore, - SIGNAL(playerNameChangeError(const QString&)), - this, SLOT(onPlayerNameChangeError(const QString&))); -} - -void MetaWindow::onPlayerNameChanged(){ - disconnectNameChangeSignals(); -} - -void MetaWindow::onPlayerNameChangeError(const QString& errMessage){ - disconnectNameChangeSignals(); - QMessageBox::critical(this, "Error Changing Player Name", errMessage); -} - - void MetaWindow::displayLibrary(){ contentStack->setCurrentWidget(libraryWidget); } @@ -416,6 +441,10 @@ contentStack->setCurrentWidget(playlistView); } +void MetaWindow::displayParticipants(){ + contentStack->setCurrentWidget(participantsView); +} + void MetaWindow::syncLibrary(){ syncingProgress = new QProgressDialog( "Syncing Library...", "Cancel", 0, dataStore->getTotalUnsynced(), this); @@ -492,4 +521,17 @@ removePasswordAction->setEnabled(false); } +void MetaWindow::onHardAuthFailure(){ + hasHardAuthFailure = true; + QMessageBox::critical(this, tr("Bad password"), tr("It appears you have changed your password " + "since you last logged in. Please restart UDJ with your new password.")); + close(); +} + +void MetaWindow::onPlayerLocationSetError(const QString& errMessage){ + QMessageBox::critical(this, tr("Error Setting Location"), errMessage); + setPlayerLocation(); +} + + } //end namespace diff -Nru udj-desktop-client-0.5.1/src/MetaWindow.hpp udj-desktop-client-0.6.3/src/MetaWindow.hpp --- udj-desktop-client-0.5.1/src/MetaWindow.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/MetaWindow.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -25,6 +25,9 @@ #include #include "UDJServerConnection.hpp" #include "PlaybackWidget.hpp" +#if IS_WINDOWS_BUILD +#include +#endif class QTabWidget; class QPushButton; @@ -43,6 +46,7 @@ class EventWidget; class DataStore; class PlayerDashboard; +class ParticipantsView; /** * \brief A class that is the main point of interaction with the user. @@ -84,6 +88,9 @@ /** \brief . */ virtual void closeEvent(QCloseEvent *event); + /** \brief . */ + bool eventFilter(QObject *obj, QEvent *event); + //@} private slots: @@ -91,13 +98,21 @@ /** @name Private Slots */ //@{ - /** \brief Shows the logger view */ + /** \brief Inform the user their current credentials no longer work. */ + void onHardAuthFailure(); + + /** + * \brief Performs appropriate actions when there is an error setting the location of the player. + */ + void onPlayerLocationSetError(const QString& errMessage); + + /** \brief Shows the logger view. */ void displayLogView(); - /** \brief Shows the about widget*/ + /** \brief Shows the about widget. */ void displayAboutWidget(); - /** \brief Initiates the syncing of the library */ + /** \brief Initiates the syncing of the library. */ void syncLibrary(); /** @@ -121,6 +136,11 @@ void displayPlaylist(); /** + * \brief Displays the participants view in the main content panel. + */ + void displayParticipants(); + + /** * \brief Updates the syncprogress given the songs that have been updated. * * \param songs Songs that were updated. @@ -140,23 +160,6 @@ void syncError(const QString& errMessage); /** - * \brief Initiates the process for changing the players name. - */ - void changePlayerName(); - - /** - * \brief Preforms necessary actions when a players name is succesfully changed. - */ - void onPlayerNameChanged(); - - /** - * \brief Preforms necessary actions when changing a players name failed. - * - * \param errMessage A message describing the error. - */ - void onPlayerNameChangeError(const QString& errMessage); - - /** * \brief Preforms necessary actions in order to start setting the player's location. */ void setPlayerLocation(); @@ -167,19 +170,22 @@ void setPlayerPassword(); /** - * \brief Performs necessary actions in order to start removing the player's password. + * \brief Scans the iTunes library for any music that can be added to the music library and + * attempts to add them. */ - void removePlayerPassword(); + void scanItunesLibrary(); /** - * \brief Preforms necessary actions when the player password was sucesfully removed. + * \brief Performs necessary actions in order to start removing the player's password. */ - void onPlayerPasswordRemoved(); + void removePlayerPassword(); /** * \brief Preforms necessary actions when there was an error removing the player password. + * + * \param errMessage A message describing the error. */ - void onPlayerPasswordRemoveError(); + void onPlayerPasswordRemoveError(const QString& errMessage); /** * \brief Enables the ability to remove the player password. @@ -223,16 +229,12 @@ /** \brief Triggers display of the about widget */ QAction *viewAboutAction; - /** - * \brief Triggers the changing of the player name. - */ - QAction *changeNameAction; - - /** - * \brief Triggers the setting of the player location. - */ + /** \brief Triggers the setting of the player location. */ QAction *setLocationAction; + /** \brief Triggers rescanning of the iTunes Library. */ + QAction *rescanItunesAction; + /** * \brief Triggers the setting of the player password. */ @@ -243,6 +245,13 @@ */ QAction *removePasswordAction; + #if IS_WINDOWS_BUILD + /** + * \brief Checks to se if there is an update available for the player. + */ + QAction* checkUpdateAction; + #endif + // QFileSystemWatcher* fileWatcher; @@ -270,9 +279,22 @@ /** \brief Dashboard used to display information about the player. */ PlayerDashboard *dashboard; + /** \brief ParticipantsView used to display player participants. */ + ParticipantsView *participantsView; + /** \brief A flag indicating whether or not the client is in the process of quitting. */ bool isQuiting; + /** + * \brief A flag indicating whether or not the client is currently expeiriencing a hard + * authentication failure. + */ + bool hasHardAuthFailure; + +#if IS_WINDOWS_BUILD + qtsparkle::Updater* updater; +#endif + //@} /** @name Private Functions */ @@ -290,9 +312,12 @@ /** \brief Configures the menu for changing player settings. */ void configurePlayerMenu(); - /** + /** \brief Determines whether or not the user had an iTunes library. */ + bool hasItunesLibrary(); + + /** * \brief Attemps to add the given media sources to the library. - * + * * \param musicToAdd A list of media sources to be added to the library. */ void addMediaSources(const QList& musicToAdd); @@ -303,18 +328,6 @@ */ void disconnectSyncSignals(); - /** - * \brief Disconnects any signals that may have been setup when initiating a player - * name change operation. - */ - void disconnectNameChangeSignals(); - - /** - * \brief Disconnects any signals that may have been setup when initiating a player - * password removal operation. - */ - void disconnectPlayerPasswordRemoveSignals(); - //@} }; diff -Nru udj-desktop-client-0.5.1/src/MusicFinder.cpp udj-desktop-client-0.6.3/src/MusicFinder.cpp --- udj-desktop-client-0.5.1/src/MusicFinder.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/MusicFinder.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -19,6 +19,7 @@ #include "MusicFinder.hpp" #include "Logger.hpp" #include "ConfigDefs.hpp" +#include "DataStore.hpp" #include #include #include @@ -50,8 +51,20 @@ }; +QList MusicFinder::filterDuplicateSongs( + const QList& songsToFilter, const DataStore* dataStore) +{ + QList toReturn; + Phonon::MediaSource song; + Q_FOREACH(song, songsToFilter){ + if(!dataStore->alreadyHaveSongInLibrary(song.fileName())){ + toReturn.append(song); + } + } + return toReturn; +} -QList MusicFinder::findItunesMusic(const QString& itunesLibFileName){ +QList MusicFinder::findItunesMusic(const QString& itunesLibFileName, const DataStore* dataStore){ iTunesHandler handler; QFile itunesLibFile(itunesLibFileName); QXmlSimpleReader itunesReader; @@ -59,12 +72,12 @@ itunesReader.setContentHandler(&handler); itunesReader.setErrorHandler(&handler); itunesReader.parse(source); - return handler.foundFiles; + return filterDuplicateSongs(handler.foundFiles, dataStore); } -QList MusicFinder::findMusicInDir(const QString& musicDir){ +QList MusicFinder::findMusicInDir(const QString& musicDir, const DataStore* dataStore){ QRegExp fileMatcher = getMusicFileMatcher(); - return findMusicInDirWithMatcher(musicDir, fileMatcher); + return filterDuplicateSongs(findMusicInDirWithMatcher(musicDir, fileMatcher), dataStore); } QList MusicFinder::findMusicInDirWithMatcher( @@ -120,47 +133,10 @@ } QStringList MusicFinder::availableMusicTypes(){ - #if IS_APPLE_BUILD - Logger::instance()->log("On mac, just saying mp3s and m4as"); + //We be using vlc backend now. That means we can play ALL THE MUSICS!!!!! QStringList toReturn; - toReturn << "mp3" << "m4a"; - return toReturn; - #else - QStringList mimes = Phonon::BackendCapabilities::availableMimeTypes(); - if(mimes.size() == 0){ - Logger::instance()->log("Didn't find any mime types"); - } - Logger::instance()->log("Found mime types:"); - Q_FOREACH(QString s, mimes){ - Logger::instance()->log(s); - } - QStringList toReturn; - if(mimes.contains("audio/flac") || mimes.contains("audio/x-flac")){ - toReturn.append("flac"); - } - if(mimes.contains("audio/mp3") || mimes.contains("audio/x-mp3")){ - toReturn.append("mp3"); - } - if(mimes.contains("audio/mp4")){ - toReturn.append("mp4"); - } - if(mimes.contains("audio/m4a") - || ("audio/x-m4a") -|| mimes.contains("applications/x-qt-m4a")){ - toReturn.append("m4a"); - } - if(mimes.contains("audio/wav") || mimes.contains("audio/x-wav")){ - toReturn.append("wav"); - } - if(mimes.contains("audio/ogg") || -mimes.contains("application/ogg") || -mimes.contains("audio/x-vorbis") || -mimes.contains("audio/x-vorbis+ogg")) -{ - toReturn.append("ogg"); - } + toReturn << "flac" << "mp3" << "m4a" << "wav" << "ogg"; return toReturn; - #endif } } //end namespace diff -Nru udj-desktop-client-0.5.1/src/MusicFinder.hpp udj-desktop-client-0.6.3/src/MusicFinder.hpp --- udj-desktop-client-0.5.1/src/MusicFinder.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/MusicFinder.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -25,6 +25,8 @@ namespace UDJ{ +class DataStore; + /** * \brief A class used to find music on a machine. */ @@ -41,10 +43,10 @@ * which it found in the given iTunes library. * * @param itunesLibFileName The iTunes library file. + * @param dataStore The DataStore being used to back this instance of UDJ. * @return A list of MediaSources corresponding to all the songs found in the iTunes library. */ - - static QList findItunesMusic(const QString& itunesLibFileName); + static QList findItunesMusic(const QString& itunesLibFileName, const DataStore* dataStore); /** @@ -55,9 +57,10 @@ * returns a list of MediaSources representing all of the found songs. * * @param musicDir The directory in which to search for music. + * @param dataStore The DataStore being used to back this instance of UDJ. * @return A list of MediaSources corresponding to each found song. */ - static QList findMusicInDir(const QString& musicDir); + static QList findMusicInDir(const QString& musicDir, const DataStore* dataStore); /** * \brief Finds all the music in a given directory which matches certain criteria. @@ -103,6 +106,17 @@ */ static QStringList availableMusicTypes(); + /** + * Given a list of songs, this function returns the same list except all songs which + * are already in the library have been removed. + * + * @param songsToFilter The list of songs to be filtered. + * @param dataStore The DataStore backing this instance of UDJ. + * @return The list of songs given to the functions with all songs already in the + * library removed. + */ + static QList filterDuplicateSongs(const QList& songsToFilter, const DataStore* dataStore); + //@} }; diff -Nru udj-desktop-client-0.5.1/src/ParticipantsModel.cpp udj-desktop-client-0.6.3/src/ParticipantsModel.cpp --- udj-desktop-client-0.5.1/src/ParticipantsModel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/src/ParticipantsModel.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,75 @@ +/** + * Copyright 2011 Kurtis L. Nusbaum + * + * This file is part of UDJ. + * + * UDJ 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 2 of the License, or + * (at your option) any later version. + * + * UDJ 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 UDJ. If not, see . + */ +#include "ParticipantsModel.hpp" +#include "DataStore.hpp" +#include "Logger.hpp" + + +namespace UDJ{ + +ParticipantsModel::ParticipantsModel(DataStore* dataStore, QObject *parent) + :QStandardItemModel(parent), + dataStore(dataStore) +{ + setHeaders(); + connect( + dataStore, + SIGNAL(newParticipantList(const QVariantList&)), + this, + SLOT(onNewParticipantList(const QVariantList&))); +} + + +void ParticipantsModel::onNewParticipantList(const QVariantList& newParticipants){ + removeRows(0, rowCount()); + setHeaders(); + QVariantMap participant; + for(int i=0; i newRow; + newRow << newId << newUsername << newFirstName << newLastName; + appendRow(newRow); + } +} + +QString ParticipantsModel::getAttrWithDefault( + const QVariantMap& user, + const QString& attr, + const QString& defaultValue) +{ + QString value = user[attr].toString(); + if(value == ""){ + return defaultValue; + } + return value; +} + +void ParticipantsModel::setHeaders(){ + QStringList headers; + headers << tr("Id") << tr("Username") << tr("First Name") << tr("Last Name"); + setHorizontalHeaderLabels(headers); +} + +} // end namespace diff -Nru udj-desktop-client-0.5.1/src/ParticipantsModel.hpp udj-desktop-client-0.6.3/src/ParticipantsModel.hpp --- udj-desktop-client-0.5.1/src/ParticipantsModel.hpp 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/src/ParticipantsModel.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,48 @@ +/** + * Copyright 2011 Kurtis L. Nusbaum + * + * This file is part of UDJ. + * + * UDJ 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 2 of the License, or + * (at your option) any later version. + * + * UDJ 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 UDJ. If not, see . + */ +#ifndef PARTICIPANTS_MODEL_HPP +#define PARTICIPANTS_MODEL_HPP +#include + +namespace UDJ{ + +class DataStore; + +class ParticipantsModel : public QStandardItemModel{ +Q_OBJECT +public: + + ParticipantsModel(DataStore *dataStore, QObject *parent=0); + +private slots: + void onNewParticipantList(const QVariantList& newParticipants); + +private: + static QString getAttrWithDefault( + const QVariantMap& user, + const QString& attr, + const QString& defaultValue); + void setHeaders(); + DataStore *dataStore; +}; + + +} //end namespace UDJ + +#endif //PARTICIPANTS_MODEL_HPP diff -Nru udj-desktop-client-0.5.1/src/ParticipantsView.cpp udj-desktop-client-0.6.3/src/ParticipantsView.cpp --- udj-desktop-client-0.5.1/src/ParticipantsView.cpp 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/src/ParticipantsView.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,49 @@ +/** + * Copyright 2011 Kurtis L. Nusbaum + * + * This file is part of UDJ. + * + * UDJ 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 2 of the License, or + * (at your option) any later version. + * + * UDJ 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 UDJ. If not, see . + */ + +#include "ParticipantsView.hpp" +#include "ParticipantsModel.hpp" +#include +#include + + +namespace UDJ{ + + +ParticipantsView::ParticipantsView(DataStore* dataStore, QWidget* parent): + QTableView(parent), + dataStore(dataStore) +{ + setFocusPolicy(Qt::TabFocus); + setEditTriggers(QAbstractItemView::NoEditTriggers); + participantsModel = new ParticipantsModel(dataStore, this); + setModel(participantsModel); + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::ContiguousSelection); + configureHeaders(); +} + +void ParticipantsView::configureHeaders(){ + setColumnHidden(0, true); + horizontalHeader()->setResizeMode(QHeaderView::Stretch); + verticalHeader()->hide(); +} + + +} //end namesapce UDJ diff -Nru udj-desktop-client-0.5.1/src/ParticipantsView.hpp udj-desktop-client-0.6.3/src/ParticipantsView.hpp --- udj-desktop-client-0.5.1/src/ParticipantsView.hpp 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/src/ParticipantsView.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,72 @@ +/** + * Copyright 2011 Kurtis L. Nusbaum + * + * This file is part of UDJ. + * + * UDJ 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 2 of the License, or + * (at your option) any later version. + * + * UDJ 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 UDJ. If not, see . + */ +#ifndef PARTICIPANTS_VIEW_HPP +#define PARTICIPANTS_VIEW_HPP +#include "ConfigDefs.hpp" +#include "DataStore.hpp" +#include + + + +namespace UDJ{ + +class ParticipantsModel; + +class ParticipantsView : public QTableView{ +Q_OBJECT +public: + + /** @name Constructors */ + //@{ + + ParticipantsView(DataStore* dataStore, QWidget* parent=0); + + //@} + +private: + + + /** @name Private Members */ + //@{ + + /** + * \brief The data store containing music that could potentially be added + * to the playlist. + */ + DataStore* dataStore; + + ParticipantsModel *participantsModel; + + //@} + + /** @name Private Functions */ + //@{ + + /** + * \brief Configures how the headers in the view should look. + */ + void configureHeaders(); + + //@} + +}; + + +} //end namespace +#endif //PARTICIPANTS_VIEW_HPP diff -Nru udj-desktop-client-0.5.1/src/PlaybackWidget.cpp udj-desktop-client-0.6.3/src/PlaybackWidget.cpp --- udj-desktop-client-0.5.1/src/PlaybackWidget.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/PlaybackWidget.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -31,42 +31,6 @@ #include #include "PlaybackErrorMessage.hpp" -#if IS_WINDOWS_BUILD -#include -void removeTags(UDJ::DataStore::song_info_t& song){ - static int fileCount =0; - if(song.source.fileName().endsWith(".mp3")){ - UDJ::Logger::instance()->log("On windows and got mp3, copying and striping metadata tags"); - QString tempCopy = QDesktopServices::storageLocation(QDesktopServices::TempLocation) + "/striped" + QString::number(fileCount) +".mp3"; - if(QFile::exists(tempCopy)){ - UDJ::Logger::instance()->log("Prevoius file existed, deleting now"); - if(QFile::remove(tempCopy)){ - UDJ::Logger::instance()->log("File removal worked"); - } - } - bool fileCopyWorked = QFile::copy(song.source.fileName(), tempCopy); - if(!fileCopyWorked){ - UDJ::Logger::instance()->log("File copy didn't work"); - return; - } - - TagLib::MPEG::File file(tempCopy.toStdString().c_str()); - file.strip(); - file.save(); - Phonon::MediaSource newSource(tempCopy); - song.source = newSource; - if(fileCount == 3){ - fileCount =0; - } - else{ - fileCount++; - } - - } - -} -#endif - namespace UDJ{ @@ -77,6 +41,7 @@ { currentSongTitle = ""; currentSongArtist = ""; + currentSongDuration = ""; audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); mediaObject = new Phonon::MediaObject(this); createActions(); @@ -91,7 +56,7 @@ audioOutput, SIGNAL(volumeChanged(qreal)), dataStore, - SLOT(changeVolumeSilently(qreal))); + SLOT(setVolume(qreal))); connect( dataStore, @@ -135,7 +100,7 @@ void PlaybackWidget::tick(qint64 time){ QTime tickTime(0, (time/60000)%60, (time/1000)%60); - timeLabel->setText(tickTime.toString("mm:ss")); + timeLabel->setText(tickTime.toString("mm:ss")+"/"+currentSongDuration); } void PlaybackWidget::sourceChanged(const Phonon::MediaSource &/*source*/){ @@ -177,11 +142,17 @@ && nextSong.source.type() != Phonon::MediaSource::Invalid) { setSongInfo(nextSong); - #if IS_WINDOWS_BUILD - removeTags(nextSong); - #endif mediaObject->play(); } + else{ + //Nothing left to play at the moment. clear the current song. + if(dataStore->getCurrentSongId() != -1){ + Logger::instance()->log("playback widget is clearing current song"); + dataStore->clearCurrentSong(); + clearWidget(); + } + } + } void PlaybackWidget::handlePlaylistChange(){ @@ -231,6 +202,18 @@ } +void PlaybackWidget::togglePlaybackState(){ + if(currentPlaybackState == PLAYING){ + pause(); + dataStore->pausePlayer(); + } + else{ + play(); + dataStore->playPlayer(); + } + +} + void PlaybackWidget::play(){ currentPlaybackState = PLAYING; mediaObject->play(); @@ -240,6 +223,7 @@ } void PlaybackWidget::pause(){ + Logger::instance()->log("Setting playback widget as paused"); currentPlaybackState = PAUSED; mediaObject->pause(); playAction->setEnabled(true); @@ -270,31 +254,25 @@ skipAction = new QAction(style()->standardIcon(QStyle::SP_MediaSkipForward), tr("Skip"), this); connect(playAction, SIGNAL(triggered()), dataStore, SLOT(playPlayer())); + connect(playAction, SIGNAL(triggered()), this, SLOT(play())); connect(pauseAction, SIGNAL(triggered()), dataStore, SLOT(pausePlayer())); + connect(pauseAction, SIGNAL(triggered()), this, SLOT(pause())); connect(skipAction, SIGNAL(triggered()), this, SLOT(playNextSong())); } void PlaybackWidget::setNewSource(DataStore::song_info_t newSong){ setSongInfo(newSong); - Logger::instance()->log("Just set current title to " + currentSongTitle); - #ifdef WIN32 - //Phonon on windows doesn't like compressed id3 tags. so we have to - //uncrompress them. Tis a bitch. - removeTags(newSong); - #endif Logger::instance()->log("in set new source"); mediaObject->setCurrentSource(newSong.source); - if(dataStore->getPlayingState() == DataStore::getPausedState()){ + if(currentPlaybackState == PAUSED){ + Logger::instance()->log("in paused state, need to set to playing"); dataStore->playPlayer(); } - else{ - mediaObject->play(); - } + play(); } void PlaybackWidget::clearWidget(){ mediaObject->stop(); - mediaObject->clear(); songInfo->setText(""); timeLabel->setText("--:--"); } @@ -303,6 +281,7 @@ void PlaybackWidget::setSongInfo(const DataStore::song_info_t& newSong){ currentSongTitle = newSong.title; currentSongArtist = newSong.artist; + currentSongDuration = newSong.duration; songInfo->setText(newSong.title + " - " + newSong.artist); } diff -Nru udj-desktop-client-0.5.1/src/PlaybackWidget.hpp udj-desktop-client-0.6.3/src/PlaybackWidget.hpp --- udj-desktop-client-0.5.1/src/PlaybackWidget.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/PlaybackWidget.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -58,12 +58,29 @@ PlaybackWidget(DataStore *dataStore, QWidget *parent=0); //@} + +public slots: + /** @name Public Slots */ + //@{ + + /** + * \brief Toggles the playback state of playback widget. + */ + void togglePlaybackState(); + + //@} private slots: /** @name Private Slots */ //@{ + /** \brief Enables playback. */ + void play(); + + /** \brief Pauses playback. */ + void pause(); + /** * \brief Handles whenever the state of the primary * MediaObject is changed. @@ -117,12 +134,6 @@ /** @name Private Functions */ //@{ - /** \brief Enables playback. */ - void play(); - - /** \brief Pauses playback. */ - void pause(); - /** \brief Sets up all the actions used by the MetaWindow. */ void createActions(); @@ -158,6 +169,8 @@ /** \brief The artist of the current song being played. */ QString currentSongArtist; + /** \brief The duration of the current song being played. */ + QString currentSongDuration; /** \brief Causes playback to start */ QAction *playAction; diff -Nru udj-desktop-client-0.5.1/src/PlayerDashboard.cpp udj-desktop-client-0.6.3/src/PlayerDashboard.cpp --- udj-desktop-client-0.5.1/src/PlayerDashboard.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/PlayerDashboard.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -1,6 +1,5 @@ /** - * Copyright 2011 Kurtis L. Nusbaum - * + * Copyright 2011 Kurtis L. Nusbaum * * This file is part of UDJ. * * UDJ is free software: you can redistribute it and/or modify @@ -36,11 +35,6 @@ SLOT(setPlayerInfo())); connect( dataStore, - SIGNAL(playerNameChanged(const QString&)), - this, - SLOT(setPlayerInfo())); - connect( - dataStore, SIGNAL(playerLocationSet()), this, SLOT(setPlayerInfo())); @@ -72,9 +66,9 @@ void PlayerDashboard::setPlayerInfo(){ nameLabel->setText(tr("Player Name: ") + dataStore->getPlayerName()); - passwordLabel->setText(tr("Password: No Password")); + passwordLabel->setText(tr("No Password Set")); if(dataStore->hasPlayerPassword()){ - passwordLabel->setText(tr("Password: ") + dataStore->getPlayerPassword()); + passwordLabel->setText(tr("Password Set")); } locationLabel->setText(tr("Location: Not Set")); if(dataStore->hasLocation()){ diff -Nru udj-desktop-client-0.5.1/src/PlayerDashboard.hpp udj-desktop-client-0.6.3/src/PlayerDashboard.hpp --- udj-desktop-client-0.5.1/src/PlayerDashboard.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/PlayerDashboard.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -70,7 +70,7 @@ /** \brief Lable for player name */ QLabel *nameLabel; - /** \brief Label for player password */ + /** \brief Label for player password state */ QLabel *passwordLabel; /** \brief Label for player location */ diff -Nru udj-desktop-client-0.5.1/src/SetLocationDialog.cpp udj-desktop-client-0.6.3/src/SetLocationDialog.cpp --- udj-desktop-client-0.5.1/src/SetLocationDialog.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/SetLocationDialog.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -39,24 +39,9 @@ setWindowTitle(tr("Set Player Location")); setModal(true); setupUi(); - connect(dataStore, SIGNAL(playerLocationSet()), this, SLOT(closeDialog())); - connect( - dataStore, - SIGNAL(playerLocationSetError(const QString&)), - this, - SLOT(onChangeLocationError(const QString&))); } -void SetLocationDialog::onChangeLocationError(const QString& errMessage){ - this->showMainWidget(); - QMessageBox::critical( - this, - tr("Couldn't Change Location"), - errMessage - ); -} - void SetLocationDialog::accept(){ QString badInputs = addressWidget->getBadInputs(); if(badInputs == ""){ @@ -67,6 +52,7 @@ addressWidget->getState(), addressWidget->getZipcode() ); + closeDialog(); } else{ QMessageBox::critical( diff -Nru udj-desktop-client-0.5.1/src/SetLocationDialog.hpp udj-desktop-client-0.6.3/src/SetLocationDialog.hpp --- udj-desktop-client-0.5.1/src/SetLocationDialog.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/SetLocationDialog.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -78,18 +78,6 @@ //@} -private slots: - /** @name Private Slots */ - //@{ - - /** - * \brief Handles location change errors - * - * \param errMessage A message describing the error. - */ - void onChangeLocationError(const QString& errMessage); - - //@} }; diff -Nru udj-desktop-client-0.5.1/src/SetPasswordDialog.cpp udj-desktop-client-0.6.3/src/SetPasswordDialog.cpp --- udj-desktop-client-0.5.1/src/SetPasswordDialog.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/SetPasswordDialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -/** - * Copyright 2011 Kurtis L. Nusbaum - * - * This file is part of UDJ. - * - * UDJ 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 2 of the License, or - * (at your option) any later version. - * - * UDJ 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 UDJ. If not, see . - */ - -#include "SetPasswordDialog.hpp" -#include "DataStore.hpp" -#include -#include -#include - - -namespace UDJ{ - - -SetPasswordDialog::SetPasswordDialog(DataStore *dataStore, QWidget *parent, Qt::WindowFlags f) - :DialogWithLoaderWidget( - tr("Setting Player Password..."), - tr("Set Password"), - tr("Cancel"), - false, - parent, - f), - dataStore(dataStore) -{ - setWindowTitle(tr("Set Player Password")); - setModal(true); - setupUi(); - connect(dataStore, SIGNAL(playerPasswordSet()), this, SLOT(closeDialog())); - connect( - dataStore, - SIGNAL(playerPasswordSetError(const QString&)), - this, - SLOT(onPlayerPasswordSetError(const QString&))); - -} - -void SetPasswordDialog::onPlayerPasswordSetError(const QString& errMessage){ - this->showMainWidget(); - QMessageBox::critical( - this, - tr("Couldn't Change Password"), - errMessage - ); -} - -void SetPasswordDialog::accept(){ - QString password = passwordEdit->text(); - if(password!=""){ - this->showLoadingText(); - dataStore->setPlayerPassword(password); - } - else{ - QMessageBox::critical( - this, - tr("Blank Password"), - tr("The password must not be blank." ) - ); - } -} - -void SetPasswordDialog::setupUi(){ - QWidget *passwordWidget = new QWidget(); - passwordEdit = new QLineEdit(dataStore->getPlayerPassword()); - QFormLayout *layout = new QFormLayout(); - layout->addRow(tr("Password:"), passwordEdit); - passwordWidget->setLayout(layout); - setMainWidget(passwordWidget); -} - - - -} //end namespace UDJ - - diff -Nru udj-desktop-client-0.5.1/src/SetPasswordDialog.hpp udj-desktop-client-0.6.3/src/SetPasswordDialog.hpp --- udj-desktop-client-0.5.1/src/SetPasswordDialog.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/SetPasswordDialog.hpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ -/** - * Copyright 2011 Kurtis L. Nusbaum - * - * This file is part of UDJ. - * - * UDJ 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 2 of the License, or - * (at your option) any later version. - * - * UDJ 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 UDJ. If not, see . - */ -#ifndef SET_PASSWORD_DIALOG_HPP -#define SET_PASSWORD_DIALOG_HPP - -#include "DialogWithLoaderWidget.hpp" - -class QLineEdit; - -namespace UDJ{ - -class DataStore; - -/** \brief Dialog for setting a player's password. */ -class SetPasswordDialog : public DialogWithLoaderWidget{ -Q_OBJECT -public: - - /** @name Constructors */ - //@{ - - /** - * \brief Constructs a SetPasswordDialog - * - * \param dataStore The DataStore backing the client. - * \param parent The parent widget. - * \param f Window flags. - */ - SetPasswordDialog(DataStore *dataStore, QWidget *parent=0, Qt::WindowFlags f=0); - - //@} - -public slots: - - /** @name Overridden slots from QDialog */ - //@{ - - /** \brief . */ - virtual void accept(); - - //@} - -private: - - /** @name Private Members */ - //@{ - - QLineEdit *passwordEdit; - - /** \brief DataStore backing the client */ - DataStore *dataStore; - - //@} - - /** @name Private Functions */ - //@{ - - /** \brief Initializes UI. */ - void setupUi(); - - - //@} - -private slots: - /** @name Private Slots */ - //@{ - - /** - * \brief Handles password setting errors - * - * \param errMessage A message describing the error. - */ - void onPlayerPasswordSetError(const QString& errMessage); - - //@} -}; - - -} //end namespace UDJ - - -#endif //SET_PASSWORD_DIALOG_HPP diff -Nru udj-desktop-client-0.5.1/src/UDJServerConnection.cpp udj-desktop-client-0.6.3/src/UDJServerConnection.cpp --- udj-desktop-client-0.5.1/src/UDJServerConnection.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/UDJServerConnection.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -79,8 +79,10 @@ + "&to_delete=" + deleteJSON; Logger::instance()->log("Lib mod payload: " + QString::fromUtf8(payload)); QNetworkReply *reply = netAccessManager->post(modRequest, payload); + Logger::instance()->log("Issued request" + QString::fromUtf8(payload)); reply->setProperty(getSongsAddedPropertyName(), addJSON); reply->setProperty(getSongsDeletedPropertyName(), deleteJSON); + Logger::instance()->log("Set reply properties" + QString::fromUtf8(payload)); } void UDJServerConnection::createPlayer( @@ -97,7 +99,7 @@ const QString& streetAddress, const QString& city, const QString& state, - const int& zipcode) + const QString& zipcode) { const QByteArray playerJSON = JSONHelper::getCreatePlayerJSON(playerName, password, streetAddress, city, state, zipcode); @@ -131,16 +133,17 @@ const QString& streetAddress, const QString& city, const QString& state, - int zipcode + const QString& zipcode ) { QNetworkRequest setLocationRequest(getPlayerLocationUrl()); setLocationRequest.setRawHeader(getTicketHeaderName(), ticket_hash); QUrl params; params.addQueryItem("address", streetAddress); - params.addQueryItem("city", city); - params.addQueryItem("state", state); - params.addQueryItem("zipcode", QString::number(zipcode)); + params.addQueryItem("locality", city); + params.addQueryItem("region", state); + params.addQueryItem("postal_code", zipcode); + params.addQueryItem("country", "United States"); QByteArray payload = params.encodedQuery(); QNetworkReply *reply = netAccessManager->post(setLocationRequest, payload); reply->setProperty(getLocationAddressPropertyName(), streetAddress); @@ -149,16 +152,6 @@ reply->setProperty(getLocationZipcodePropertyName(), zipcode); } -void UDJServerConnection::setPlayerName(const QString& newName){ - QNetworkRequest setNameRequest(getPlayerNameUrl()); - setNameRequest.setRawHeader(getTicketHeaderName(), ticket_hash); - QUrl params; - params.addQueryItem("name", newName); - QByteArray payload = params.encodedQuery(); - QNetworkReply *reply = netAccessManager->post(setNameRequest, payload); - reply->setProperty(getPlayerNamePropertyName(), newName); -} - void UDJServerConnection::getActivePlaylist(){ QNetworkRequest getActivePlaylistRequest(getActivePlaylistUrl()); getActivePlaylistRequest.setRawHeader(getTicketHeaderName(), ticket_hash); @@ -212,6 +205,20 @@ reply->setProperty(getStatePropertyName(), newState); } +void UDJServerConnection::clearCurrentSong(){ + Logger::instance()->log("Clearing current song"); + QNetworkRequest clearCurrentSongRequest(getCurrentSongUrl()); + clearCurrentSongRequest.setRawHeader(getTicketHeaderName(), ticket_hash); + /*QNetworkReply *reply =*/ netAccessManager->deleteResource(clearCurrentSongRequest); +} + + +void UDJServerConnection::getParticipantList(){ + QNetworkRequest getParticipantListRequest(getParticipantsUrl()); + getParticipantListRequest.setRawHeader(getTicketHeaderName(), ticket_hash); + /*QNetworkReply *reply =*/ netAccessManager->get(getParticipantListRequest); +} + void UDJServerConnection::recievedReply(QNetworkReply *reply){ if(reply->request().url().path() == getAuthUrl().path()){ handleAuthReply(reply); @@ -219,15 +226,22 @@ else if(reply->request().url().path() == getPlayerStateUrl().path()){ handleSetStateReply(reply); } - else if(isPlayerCreateUrl(reply->request().url().path())){ + else if(reply->request().url().path() == getCreatePlayerUrl().path()){ handleCreatePlayerReply(reply); } else if(isGetActivePlaylistReply(reply)){ handleReceivedActivePlaylist(reply); } - else if(reply->request().url().path() == getCurrentSongUrl().path()){ + else if(reply->request().url().path() == getCurrentSongUrl().path() && + reply->operation() == QNetworkAccessManager::PostOperation) + { handleReceivedCurrentSongSet(reply); } + else if(reply->request().url().path() == getCurrentSongUrl().path() && + reply->operation() == QNetworkAccessManager::DeleteOperation) + { + handleRecievedClearCurrentSong(reply); + } else if(reply->request().url().path() == getLibModUrl().path()){ handleReceivedLibMod(reply); } @@ -237,9 +251,6 @@ else if(isModActivePlaylistReply(reply)){ handleReceivedPlaylistMod(reply); } - else if(reply->request().url().path() == getPlayerNameUrl().path()){ - handleNameSetReply(reply); - } else if(reply->request().url().path() == getPlayerLocationUrl().path()){ handleLocationSetReply(reply); } @@ -249,6 +260,9 @@ else if(isPasswordRemoveReply(reply)){ handlePlayerPasswordRemoveReply(reply); } + else if(reply->request().url().path() == getParticipantsUrl().path()){ + handleParticipantsResponse(reply); + } else{ Logger::instance()->log("Received unknown response"); Logger::instance()->log(reply->request().url().path()); @@ -266,6 +280,9 @@ else if(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 401){ emit authFailed(tr("Incorrect Username and password")); } + else if(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 501){ + emit authFailed(tr("Your version of the UDJ player is out of date. Please check www.udjplayer.com for an update.")); + } else{ QByteArray responseData = reply->readAll(); QString responseString = QString::fromUtf8(responseData); @@ -276,56 +293,75 @@ } } -void UDJServerConnection::handleSetStateReply(QNetworkReply *reply){ +void UDJServerConnection::handleRecievedClearCurrentSong(QNetworkReply *reply){ if(isResponseType(reply, 200)){ - emit playerStateSet(reply->property(getStatePropertyName()).toString()); + emit currentSongCleared(); } else{ - //TODO handle error + QString responseData = QString(reply->readAll()); + Logger::instance()->log("Clear current song failed " + responseData); + emit currentSongClearError( + responseData, + reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), + reply->rawHeaderPairs()); } + } -void UDJServerConnection::handlePlayerPasswordRemoveReply(QNetworkReply *reply){ +void UDJServerConnection::handleParticipantsResponse(QNetworkReply *reply){ if(isResponseType(reply, 200)){ - emit playerPasswordRemoved(); + emit newParticipantList(JSONHelper::getParticipantListFromJSON(reply)); } else{ QString responseData = QString(reply->readAll()); - Logger::instance()->log("Player password remove error " + responseData); - emit playerPasswordRemoveError( + Logger::instance()->log("Participan get error " + responseData); + emit getParticipantsError( responseData, reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), reply->rawHeaderPairs()); } -} +} -void UDJServerConnection::handlePlayerPasswordSetReply(QNetworkReply *reply){ +void UDJServerConnection::handleSetStateReply(QNetworkReply *reply){ if(isResponseType(reply, 200)){ - emit playerPasswordSet(reply->property(getPlayerPasswordPropertyName()).toString()); + emit playerStateSet(reply->property(getStatePropertyName()).toString()); } else{ QString responseData = QString(reply->readAll()); - Logger::instance()->log("Set player password error " + responseData); - emit playerPasswordSetError( + Logger::instance()->log("Player state set error " + responseData); + emit playerStateSetError( + reply->property(getStatePropertyName()).toString(), responseData, reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), reply->rawHeaderPairs()); } } -void UDJServerConnection::handleNameSetReply(QNetworkReply *reply){ +void UDJServerConnection::handlePlayerPasswordRemoveReply(QNetworkReply *reply){ if(isResponseType(reply, 200)){ - emit playerNameChanged(reply->property(getPlayerNamePropertyName()).toString()); + emit playerPasswordRemoved(); + } + else{ + QString responseData = QString(reply->readAll()); + Logger::instance()->log("Player password remove error " + responseData); + emit playerPasswordRemoveError( + responseData, + reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), + reply->rawHeaderPairs()); } - else if(isResponseType(reply, 409)){ - Logger::instance()->log("Change player name got 409"); - emit playerNameChangeError("Name already in use.", 409, reply->rawHeaderPairs()); +} + + +void UDJServerConnection::handlePlayerPasswordSetReply(QNetworkReply *reply){ + if(isResponseType(reply, 200)){ + emit playerPasswordSet(reply->property(getPlayerPasswordPropertyName()).toString()); } else{ QString responseData = QString(reply->readAll()); - Logger::instance()->log("Change player name got error " + responseData); - emit playerNameChangeError( + Logger::instance()->log("Set player password error " + responseData); + emit playerPasswordSetError( + reply->property(getPlayerPasswordPropertyName()).toString(), responseData, reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), reply->rawHeaderPairs()); @@ -338,7 +374,7 @@ reply->property(getLocationAddressPropertyName()).toString(), reply->property(getLocationCityPropertyName()).toString(), reply->property(getLocationStatePropertyName()).toString(), - reply->property(getLocationZipcodePropertyName()).toInt()); + reply->property(getLocationZipcodePropertyName()).toString()); } else{ QString responseData = QString(reply->readAll()); @@ -352,6 +388,7 @@ void UDJServerConnection::handleReceivedLibMod(QNetworkReply *reply){ if(isResponseType(reply, 200)){ + Logger::instance()->log("got good lib mod reply"); QVariant songsAdded = reply->property(getSongsAddedPropertyName()); QVariant songsDeleted = reply->property(getSongsDeletedPropertyName()); QSet addedIds = JSONHelper::getLibIds(songsAdded.toByteArray()); @@ -360,10 +397,6 @@ QSet allSynced = addedIds.unite(deletedIds); emit libSongsSyncedToServer(allSynced); } - else if(isResponseType(reply, 409)){ - QSet alreadyExistingIds = JSONHelper::convertLibIdArray(reply->readAll()); - emit libSongsSyncedToServer(alreadyExistingIds); - } else{ Logger::instance()->log("Got bad lib mod"); QByteArray response = reply->readAll(); @@ -463,44 +496,39 @@ } QUrl UDJServerConnection::getCreatePlayerUrl() const{ - return QUrl(getServerUrlPath()+ "users/" + QString::number(user_id) + "/players/player"); + return QUrl(getServerUrlPath()+ "players/player"); } QUrl UDJServerConnection::getPlayerStateUrl() const{ - return QUrl(getServerUrlPath()+ "users/" + QString::number(user_id) + "/players/" + + return QUrl(getServerUrlPath()+ "players/" + QString::number(playerId) + "/state"); } QUrl UDJServerConnection::getLibModUrl() const{ - return QUrl(getServerUrlPath()+ "users/" + QString::number(user_id) + "/players/" + + return QUrl(getServerUrlPath()+ "/players/" + QString::number(playerId) + "/library"); } QUrl UDJServerConnection::getVolumeUrl() const{ - return QUrl(getServerUrlPath()+ "users/" + QString::number(user_id) + "/players/" + + return QUrl(getServerUrlPath()+ "players/" + QString::number(playerId) + "/volume"); } -QUrl UDJServerConnection::getPlayerNameUrl() const{ - return QUrl(getServerUrlPath()+ "users/" + QString::number(user_id) + "/players/" + - QString::number(playerId) + "/name"); -} - QUrl UDJServerConnection::getPlayerLocationUrl() const{ - return QUrl(getServerUrlPath()+ "users/" + QString::number(user_id) + "/players/" + + return QUrl(getServerUrlPath()+ "players/" + QString::number(playerId) + "/location"); } QUrl UDJServerConnection::getPlayerPasswordUrl() const{ - return QUrl(getServerUrlPath()+ "users/" + QString::number(user_id) + "/players/" + + return QUrl(getServerUrlPath()+ "players/" + QString::number(playerId) + "/password"); } +QUrl UDJServerConnection::getParticipantsUrl() const{ + return QUrl(getServerUrlPath()+ "players/"+QString::number(playerId)+"/users"); +} -bool UDJServerConnection::isPlayerCreateUrl(const QString& path) const{ - return (path == "/udj/users/" + QString::number(user_id) + "/players/player"); -} bool UDJServerConnection::isResponseType(QNetworkReply *reply, int code){ return reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == code; @@ -531,4 +559,6 @@ } + + }//end namespace diff -Nru udj-desktop-client-0.5.1/src/UDJServerConnection.hpp udj-desktop-client-0.6.3/src/UDJServerConnection.hpp --- udj-desktop-client-0.5.1/src/UDJServerConnection.hpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/UDJServerConnection.hpp 2012-11-15 20:49:42.000000000 +0000 @@ -111,7 +111,7 @@ const QString& streetAddress, const QString& city, const QString& state, - int zipcode + const QString& zipcode ); /** @@ -127,13 +127,6 @@ void setPlayerPassword(const QString& newPassword); /** - * \brief Tells the server to change the players name to the new name. - * - * \param newName New name for the player. - */ - void setPlayerName(const QString& newName); - - /** * \brief Sets the player state. * * \param newState State to which the player should be set. @@ -170,7 +163,7 @@ const QString& streetAddress, const QString& city, const QString& state, - const int& zipcode); + const QString& zipcode); /** * \brief Creates a player on the server using the given JSON payload. @@ -208,6 +201,16 @@ */ void setVolume(int newVolume); + /** + * \brief Tells the server that current song has finished playing. + */ + void clearCurrentSong(); + + /** + * \brief Retrieves a list of active participants from the server. + */ + void getParticipantList(); + //@} signals: @@ -259,11 +262,13 @@ /** * \brief Emitted when there was an error setting the player's password. * + * @param attemptedPassword The password that was attempted to be set on the player. * @param errMessage A message describing the error. * @param errorCode The http status code that describes the error. * @param headers The headers from the http response that indicated a failure. */ void playerPasswordSetError( + const QString& attemptedPassword, const QString& errMessage, int errorCode, const QList& headers); @@ -280,7 +285,7 @@ const QString& streetAddress, const QString& city, const QString& state, - int zipcode); + const QString& zipcode); /** * \brief Emitted when there was an error setting the player's location. @@ -313,6 +318,20 @@ int errorCode, const QList& headers); + /** + * \brief Emitted when the current song was succesfully cleared on the server. + */ + void currentSongCleared(); + + /** + * \brief Emitted when there is an error clearing the current song on the server. + */ + void currentSongClearError( + const QString& errMessage, + int errorCode, + const QList& headers); + + /** * \brief Emitted when the state on the player was changed. @@ -322,6 +341,21 @@ void playerStateSet(const QString& newState); /** + * \brief Emitted when there was an error changing the players state. + * + * @param desiredState The state which failed to be set on the player. + * @param errMessage A message describing the error. + * @param errorCode The http status code that describes the error. + * @param headers The headers from the http response that indicated a failure. + */ + void playerStateSetError( + const QString& desiredState, + const QString& errMessage, + int errorCode, + const QList& headers); + + + /** * \brief Emitted when a set of songs was succesfully synced on the server. * * \param syncedIds The set of ids that were succesfully synced to the server. @@ -360,6 +394,8 @@ /** * \brief Emitted when a new version of the active playlist is retrieved from * the server. + * + * @param newPlaylist The new playlist that was retreived from the server. */ void newActivePlaylist(const QVariantMap& newPlaylist); @@ -376,6 +412,25 @@ const QList& headers); /** + * \brief Emitted when a new version of the participants list is retrieved from the server. + * + * @param newParticipants The new list of participants that was retrieved from the server. + */ + void newParticipantList(const QVariantList& newParticipants); + + /** + * \brief Emitted when there was an error getting the list of participants from the server. + * + * @param errMessage A message describing the error. + * @param errorCode The http status code that describes the error. + * @param headers The headers from the http response that indicated a failure. + */ + void getParticipantsError( + const QString& errMessage, + int errorCode, + const QList& headers); + + /** * \brief Emitted when the current song that the player is playing is * succesfully set on the server. */ @@ -559,16 +614,23 @@ /** * \brief Handle a response from the server regarding the setting of the player location. * - * @param reply Response from the server. + * @param reply response from the server. */ void handleLocationSetReply(QNetworkReply *reply); /** - * \brief Handle a response from the server regarding the setting of the player name. + * \brief Handles a response from the server regarding the clearing of the current song. * - * @param reply Response from the server. + * @param reply The response from the server. */ - void handleNameSetReply(QNetworkReply *reply); + void handleRecievedClearCurrentSong(QNetworkReply *reply); + + /** + * \brief Handles a response from the server regarding getting a list of active participants. + * + * @param reply The response from the server. + */ + void handleParticipantsResponse(QNetworkReply *reply); /** * \brief Prepares a network request that is going to include JSON. @@ -585,13 +647,6 @@ QUrl getPlayerPasswordUrl() const; /** - * \brief Gets the url used for accessing the player's name. - * - * \return The url used for accessing the player's name. - */ - QUrl getPlayerNameUrl() const; - - /** * \brief Gets the url used for accessing the player's location. * * \return The url used for accessing the player's location. @@ -620,6 +675,15 @@ QUrl getCurrentSongUrl() const; /** + * \brief Get the url to be used for retrieving the list of current participants. + * + * @return The url to be used for getting the current participants. + */ + QUrl getParticipantsUrl() const; + + + + /** * \brief Gets the url that should be used for creating a player on the server. * * \return The url that sholud be used for creating a player on the server. @@ -643,16 +707,6 @@ QUrl getVolumeUrl() const; /** - * \brief Determines whether or not the given path is the same one used by the - * player creation url. - * - * \param path The path in question. - * \return True if the path is the same as the path used by the player creation url, - * false otherwise. - */ - bool isPlayerCreateUrl(const QString& path) const; - - /** * \brief Determines if the given network reply is in response to a request to * obtain the active playlist. * @@ -720,7 +774,7 @@ * @return The port number to be used for communicating with the server. */ static const QString & getServerPortNumber(){ - static const QString serverPortNumber = "4898"; + static const QString serverPortNumber = "4897"; return serverPortNumber; } @@ -731,7 +785,7 @@ */ static const QString& getServerUrlPath(){ static const QString SERVER_URL_PATH= - "https://udjplayer.com:" + getServerPortNumber() + "/udj/"; + "https://udjplayer.com:" + getServerPortNumber() + "/udj/0_6/"; return SERVER_URL_PATH; } diff -Nru udj-desktop-client-0.5.1/src/mac/UDJApp_Mac.h udj-desktop-client-0.6.3/src/mac/UDJApp_Mac.h --- udj-desktop-client-0.5.1/src/mac/UDJApp_Mac.h 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/src/mac/UDJApp_Mac.h 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,26 @@ +/** + * Copyright 2011 Kurtis L. Nusbaum + * + * This file is part of UDJ. + * + * UDJ 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 2 of the License, or + * (at your option) any later version. + * + * UDJ 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 UDJ. If not, see . + */ +#ifndef UDJAPP_MAC_H +#define UDJAPP_MAC_H + + +void macMain(); +void checkForUdpates(); + +#endif diff -Nru udj-desktop-client-0.5.1/src/mac/UDJApp_Mac.mm udj-desktop-client-0.6.3/src/mac/UDJApp_Mac.mm --- udj-desktop-client-0.5.1/src/mac/UDJApp_Mac.mm 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/src/mac/UDJApp_Mac.mm 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,35 @@ +#include "UDJApp_Mac.h" + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#include +#include +#include +#include + + +void macMain() { + [[NSAutoreleasePool alloc] init]; + // Creates and sets the magic global variable so QApplication will find it. + //[MacApplication sharedApplication]; + [NSApplication sharedApplication]; + // Creates and sets the magic global variable for Sparkle. + [[SUUpdater sharedUpdater] setDelegate: NSApp]; +} + +void checkForUpdates() { + [[SUUpdater sharedUpdater] checkForUpdates: NSApp]; +} + diff -Nru udj-desktop-client-0.5.1/src/main.cpp udj-desktop-client-0.6.3/src/main.cpp --- udj-desktop-client-0.5.1/src/main.cpp 2012-06-26 18:33:22.000000000 +0000 +++ udj-desktop-client-0.6.3/src/main.cpp 2012-11-15 20:49:42.000000000 +0000 @@ -22,6 +22,10 @@ #include "ConfigDefs.hpp" #include "Logger.hpp" +#if IS_APPLE_BUILD +//#include "UDJApp_Mac.h" +#endif + #ifdef HAS_CUSTOM_CA_CERT #include #include @@ -29,11 +33,15 @@ #endif int main(int argc, char* argv[]){ + #if IS_APPLE_BUILD + //macMain(); + #endif QApplication app(argc, argv); //QIcon windowIcon("udjlauncher.svg"); //QApplication::setWindowIcon(windowIcon); app.setApplicationName("Udj"); + app.setApplicationVersion(UDJ_VERSION); app.setQuitOnLastWindowClosed(true); UDJ::LoginDialog loginDialog; loginDialog.show(); diff -Nru udj-desktop-client-0.5.1/windows_steps udj-desktop-client-0.6.3/windows_steps --- udj-desktop-client-0.5.1/windows_steps 1970-01-01 00:00:00.000000000 +0000 +++ udj-desktop-client-0.6.3/windows_steps 2012-11-15 20:49:42.000000000 +0000 @@ -0,0 +1,40 @@ +1. Add the following repos +sudo zypper addrepo http://download.opensuse.org/repositories/windows:/mingw/openSUSE_11.4/windows:mingw.repo +sudo zypper addrepo http://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_11.4/windows:mingw:win32.repo +sudo zypper addrepo http://download.tomahawk-player.org/packman/mingw:32/openSUSE_11.4/mingw:32.repo + +2. Refresh opensuse and make sure it's up to date +sudo zypper refresh +sudo zypper dist-upgrade + +3. Install package +sudo zypper install ccache +sudo zypper install mingw32-libopenssl-devel +sudo zypper install mingw32-phonon +sudo zypper install wget + +4. Get all the packages needed for compiling +sudo zypper source-install --build-deps-only mingw32-tomahawk-unstable + +5. Get the packages needed for builing the installer +sudo zypper source-install --build-deps-only mingw32-tomahawk-player-installer + +6. Also install the packages here: +Go to this URL: http://download.tomahawk-player.org/packman/mingw:32/openSUSE_12.1/x86_64/ +Download the 2 packages on them +install them: sudo zypper install + +7. Create a build directory +mkdir build/ +cd build/ + +8. Configure using: +cmake -DCMAKE_TOOLCHAIN_FILE=admin_win_Toolchain-mingw32-openSUSE.cmake .. + +9. Install the special vlc +cd ../admin/win/ +./update-vlc.sh + +10. Make Package +cd ../../build/ +make package \ No newline at end of file