Merge branch 'master' of https://github.com/tomahawk-player/tomahawk
@ -1,6 +1,6 @@
|
||||
PROJECT( tomahawk )
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
|
||||
SET( CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/CMakeModules" )
|
||||
SET( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules" )
|
||||
|
||||
IF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 )
|
||||
CMAKE_POLICY(SET CMP0017 NEW)
|
||||
@ -15,10 +15,10 @@ SET( TOMAHAWK_APPLICATION_NAME "Tomahawk" )
|
||||
SET( TOMAHAWK_DESCRIPTION_SUMMARY "The social media player" )
|
||||
|
||||
SET( TOMAHAWK_VERSION_MAJOR 0 )
|
||||
SET( TOMAHAWK_VERSION_MINOR 1 )
|
||||
SET( TOMAHAWK_VERSION_MINOR 2 )
|
||||
SET( TOMAHAWK_VERSION_PATCH 0 )
|
||||
|
||||
# SET( TOMAHAWK_VERSION_RC 0 )
|
||||
SET( TOMAHAWK_VERSION_RC 1 )
|
||||
|
||||
|
||||
# build options
|
||||
@ -28,9 +28,9 @@ option(BUILD_GUI "Build Tomahawk with GUI" ON)
|
||||
# generate version string
|
||||
IF( NOT CMAKE_BUILD_TYPE STREQUAL "Release" )
|
||||
# Use the date as the tweak level.
|
||||
INCLUDE( ${CMAKE_MODULE_PATH}/CMakeDateStamp.cmake )
|
||||
INCLUDE( CMakeDateStamp )
|
||||
SET( TOMAHAWK_VERSION_TWEAK "${CMAKE_DATESTAMP_YEAR}${CMAKE_DATESTAMP_MONTH}${CMAKE_DATESTAMP_DAY}" )
|
||||
INCLUDE( ${CMAKE_MODULE_PATH}/CMakeVersionSource.cmake )
|
||||
INCLUDE( CMakeVersionSource )
|
||||
ENDIF()
|
||||
|
||||
SET( TOMAHAWK_VERSION ${TOMAHAWK_VERSION_MAJOR}.${TOMAHAWK_VERSION_MINOR}.${TOMAHAWK_VERSION_PATCH} )
|
||||
@ -54,7 +54,7 @@ SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
|
||||
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
|
||||
|
||||
# installer creation
|
||||
INCLUDE( CPack.cmake )
|
||||
INCLUDE( CPack )
|
||||
|
||||
#deps
|
||||
INCLUDE( MacroOptionalFindPackage )
|
||||
@ -67,11 +67,11 @@ IF( NOT BUILD_GUI )
|
||||
MESSAGE( STATUS "Building Tomahawk ${TOMAHAWK_VERSION} in HEADLESS mode ***" )
|
||||
ELSE()
|
||||
MESSAGE( STATUS "Building Tomahawk ${TOMAHAWK_VERSION} full GUI version ***" )
|
||||
LIST(APPEND NEEDED_QT4_COMPONENTS "QtGui")
|
||||
LIST(APPEND NEEDED_QT4_COMPONENTS "QtGui" "QtWebkit" )
|
||||
ENDIF()
|
||||
|
||||
macro_optional_find_package(Qt4 4.7.0 COMPONENTS ${NEEDED_QT4_COMPONENTS} )
|
||||
macro_log_feature(QT4_FOUND "Qt" "A cross-platform application and UI framework" "http://qt.nokia.com" TRUE "" "")
|
||||
macro_log_feature(QT4_FOUND "Qt" "A cross-platform application and UI framework" "http://qt.nokia.com" TRUE "" "If you see this, although libqt4-devel is installed, check whether \n the qtwebkit-devel package is installed as well")
|
||||
|
||||
macro_optional_find_package(Phonon 4.5.0)
|
||||
macro_log_feature(PHONON_FOUND "Phonon" "The Phonon multimedia library" "http://phonon.kde.org" TRUE "" "")
|
||||
@ -93,6 +93,11 @@ macro_log_feature(TAGLIB_FOUND "TagLib" "Audio Meta-Data Library" "http://develo
|
||||
include( CheckTagLibFileName )
|
||||
check_taglib_filename( COMPLEX_TAGLIB_FILENAME )
|
||||
|
||||
macro_optional_find_package(Boost)
|
||||
macro_log_feature(Boost_FOUND "Boost" "Provides free peer-reviewed portable C++ source libraries" "http://www.boost.org" TRUE "" "") #FIXME: give useful explaination
|
||||
|
||||
|
||||
|
||||
# required
|
||||
#While we distribute our own liblastfm2, don't need to look for it
|
||||
#macro_optional_find_package(LibLastFm 0.3.3)
|
||||
@ -111,7 +116,7 @@ IF( INTERNAL_JREEN )
|
||||
ELSE( INTERNAL_JREEN )
|
||||
macro_optional_find_package(Jreen)
|
||||
ENDIF( INTERNAL_JREEN )
|
||||
macro_log_feature(LIBJREEN_FOUND "Jreen" "Qt XMPP Library" "http://gitorious.org/jreen/jreen" FALSE "" "Jreen is needed for the Jabber SIP plugin. \n\n Use -DINTERNAL_JREEN=ON to build the git submodule inside Tomahawk \n Be aware this installs a full jreen with headers and everything!\n")
|
||||
macro_log_feature(LIBJREEN_FOUND "Jreen" "Qt XMPP Library" "https://github.com/euroelessar/jreen" FALSE "" "Jreen is needed for the Jabber SIP plugin. \n\n Use -DINTERNAL_JREEN=ON to build the git submodule inside Tomahawk \n Be aware this installs a full jreen with headers and everything!\n")
|
||||
|
||||
# this installs headers and such and should really be handled in a separate package by packagers
|
||||
IF( INTERNAL_QTWEETLIB )
|
||||
|
@ -1,3 +1,5 @@
|
||||
SET(WINDRES_EXECUTABLE ${CMAKE_RC_COMPILER})
|
||||
|
||||
# This macro is taken from kdelibs/cmake/modules/KDE4Macros.cmake.
|
||||
#
|
||||
# Copyright (c) 2006-2009 Alexander Neundorf, <neundorf@kde.org>
|
||||
@ -76,9 +78,9 @@ macro (KDE4_ADD_APP_ICON appsources pattern)
|
||||
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 ".*512.*" )
|
||||
if (it MATCHES ".*128.*" )
|
||||
set (_icon ${it})
|
||||
endif (it MATCHES ".*512.*")
|
||||
endif (it MATCHES ".*128.*")
|
||||
endforeach (it)
|
||||
|
||||
if (_icon)
|
||||
@ -101,8 +103,8 @@ macro (KDE4_ADD_APP_ICON appsources pattern)
|
||||
set_source_files_properties(${_outfilename}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
|
||||
else(_icon)
|
||||
# TODO - try to scale a non-512 icon...? Try to convert an SVG on the fly?
|
||||
message(STATUS "Unable to find an 512x512 icon that matches pattern ${pattern} for variable ${appsources} - application will not have an application 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)
|
||||
|
23
ChangeLog
@ -1,4 +1,20 @@
|
||||
Version 0.2.0:
|
||||
* Fix inability to create Echonest playlists based solely on style or mood.
|
||||
* Created new Album page (that shows other albums from that artist available in your Super Collection)
|
||||
* Update playlists in dashboard to keep them in sync
|
||||
* Added support for "playing" Rdio track URLs and ability to drag/drop them into Tomahawk
|
||||
* Change "Recently Played" page to "Dashboard"
|
||||
* Prioritize resolving newer queries to make GUI more responsive
|
||||
* Automatically expand local collection node in sidebar on launch
|
||||
* Display spinner animation while searching for tracks
|
||||
* Fix for occasionally flashing play control buttons
|
||||
* Remove horizontal scrollbars when they aren't needed
|
||||
* Let headless-Tomahawk users trigger a rescan with --filescan
|
||||
* Removed "test login" button from Last.fm settings (OS X only)
|
||||
* Fix font and image sizes from being too big/small on some OSes
|
||||
* Include Stations and Automatic Playlists in News Stations and Playlists widget
|
||||
* When click through to station or playlist ensure that sidebar navigation reflects it
|
||||
* Even more design tweaks, new placeholder icons (and use them in right places)
|
||||
* Show search and artist page temporary navigation in sidebar when on those pages
|
||||
* Fixed bug where drop indicator wouldn't show under last track if that was drop zone
|
||||
* Fixed cross-wiring of Previous and Next song in "Music Player" menu (OS X)
|
||||
@ -19,8 +35,7 @@ Version 0.2.0:
|
||||
* Fixed a few crashes that could occur when fetching data from Last.fm.
|
||||
* Made Twitter dialog more readable/understandable.
|
||||
* Added Artist pages (and links to them from now playing metadata and from collection track list views)
|
||||
with artist bio snippet, related artists, top tracks and view of all tracks/albums from that
|
||||
artist in user's Super Collection
|
||||
with artist bio snippet, related artists, top tracks and view of all tracks/albums from that artist in user's Super Collection
|
||||
* Fixed streaming from https:// links
|
||||
* Desktop notifications for now playing (Linux only)
|
||||
* Implement new javascript resolver API and ability to present configuration options for resolvers
|
||||
@ -47,11 +62,11 @@ Version 0.2.0:
|
||||
* Don't require @foo.com domains for jabber and google
|
||||
* Added global search function that searches all available sources (super collection and all enabled resolvers)
|
||||
* Cleaned up Preference Window and styling
|
||||
* Collection scanner now can now run automatically, watching files and
|
||||
* Collection scanner now can run automatically, watching files and
|
||||
directories for changes. On by default.
|
||||
* Added Pipeline view window
|
||||
* Allow seeking in songs - if possible
|
||||
* Added ability to make a copy of a sources' playlists and add to your own playlists
|
||||
* Added ability to make a copy of a peer's playlists and add to your own playlists
|
||||
* Added MediaKey support on OS X
|
||||
* Shuffle and Repeat settings are stored on a playlist by playlist basis
|
||||
|
||||
|
@ -1,64 +0,0 @@
|
||||
#!/bin/sh
|
||||
# author: max@last.fm
|
||||
# usage: Run from inside the bundle root directory, eg. Last.fm.app
|
||||
# The first parameter should be the QtFrameworks to copy.
|
||||
# Remaining parameters are plugins to copy, directories and files are
|
||||
# valid.
|
||||
# eg: add-Qt-to-bundle.sh 'QtCore QtGui QtXml' \
|
||||
# imageformats \
|
||||
# sqldrivers/libsqlite.dylib
|
||||
################################################################################
|
||||
|
||||
QT_FRAMEWORKS_DIR="$QTDIR/lib"
|
||||
QT_PLUGINS_DIR="$QTDIR/plugins"
|
||||
|
||||
if [[ ! -d "$QTDIR/lib/QtCore.framework" ]]
|
||||
then
|
||||
# this dir is the location of install for the official Trolltech dmg
|
||||
if [[ -d /Library/Frameworks/QtCore.framework ]]
|
||||
then
|
||||
QT_FRAMEWORKS_DIR=/Library/Frameworks
|
||||
QT_PLUGINS_DIR=/Developer/Applications/Qt/plugins
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Plugins go to: $QT_PLUGINS_DIR"
|
||||
|
||||
if [ -z $QTDIR ]
|
||||
then
|
||||
echo QTDIR must be set, or install the official Qt dmg
|
||||
exit 1
|
||||
fi
|
||||
################################################################################
|
||||
|
||||
|
||||
#first frameworks
|
||||
mkdir -p Contents/Frameworks
|
||||
for x in $1
|
||||
do
|
||||
echo "C $x"
|
||||
cp -R $QT_FRAMEWORKS_DIR/$x.framework Contents/Frameworks/
|
||||
chmod -R u+rw Contents/Frameworks/
|
||||
done
|
||||
|
||||
#plugins
|
||||
shift
|
||||
mkdir -p Contents/MacOS
|
||||
mkdir -p Contents/MacOS/sqldrivers
|
||||
mkdir -p Contents/MacOS/imageformats
|
||||
mkdir -p Contents/MacOS/phonon_backend
|
||||
mkdir -p Contents/MacOS/crypto
|
||||
|
||||
cp -R $QT_PLUGINS_DIR/sqldrivers/libqsqlite.dylib Contents/MacOS/sqldrivers/
|
||||
cp -R $QT_PLUGINS_DIR/imageformats/libqgif.dylib Contents/MacOS/imageformats/
|
||||
cp -R $QT_PLUGINS_DIR/imageformats/libqjpeg.dylib Contents/MacOS/imageformats/
|
||||
cp -R $QT_PLUGINS_DIR/imageformats/libqico.dylib Contents/MacOS/imageformats/
|
||||
cp -R $QT_PLUGINS_DIR/imageformats/libqmng.dylib Contents/MacOS/imageformats/
|
||||
#cp -R $QT_PLUGINS_DIR/imageformats/libqsvg.dylib Contents/MacOS/imageformats/
|
||||
#cp -R $QT_PLUGINS_DIR/imageformats/libqtiff.dylib Contents/MacOS/imageformats/
|
||||
cp -R $QT_PLUGINS_DIR/crypto/libqca-ossl.dylib Contents/MacOS/crypto/
|
||||
cp -R $QT_PLUGINS_DIR/phonon_backend/phonon_vlc.so Contents/MacOS/phonon_backend/
|
||||
|
||||
#cleanup
|
||||
find Contents/Frameworks -name Headers -o -name \*.prl -o -name \*_debug | xargs rm -rf
|
||||
find Contents -name \*_debug -o -name \*_debug.dylib | xargs rm
|
@ -1,16 +0,0 @@
|
||||
#!/bin/sh
|
||||
# author: lfranchi@kde.org
|
||||
# usage: Run from inside the bundle root directory, eg. Tomahawk.app
|
||||
# The first parameter should be the spotify resolver binary to copy.
|
||||
# eg: add-spotify.sh /path/to/spotify_tomahawkresolver
|
||||
################################################################################
|
||||
|
||||
mkdir -p Contents/Frameworks
|
||||
cp -R /Library/Frameworks/libspotify.framework Contents/Frameworks
|
||||
|
||||
install_name_tool -change /usr/local/Cellar/qt/4.7.3/lib/QtCore.framework/Versions/4/QtCore @executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore $1
|
||||
install_name_tool -change /usr/local/Cellar/qt/4.7.3/lib/QtNetwork.framework/Versions/4/QtNetwork @executable_path/../Frameworks/QtNetwork.framework/Versions/4/QtNetwork $1
|
||||
install_name_tool -change libqjson.0.dylib @executable_path/libqjson.0.7.1.dylib $1
|
||||
install_name_tool -change /usr/local/Cellar/qjson/0.7.1/lib/libqjson.0.7.1.dylib @executable_path/libqjson.0.7.1.dylib $1
|
||||
mkdir -p Contents/MacOS
|
||||
cp $1 Contents/MacOS/
|
@ -23,65 +23,26 @@ then
|
||||
fi
|
||||
|
||||
ROOT=`pwd`
|
||||
|
||||
QTDIR=`which qmake`
|
||||
LINKDIR=`readlink $QTDIR`
|
||||
QTDIR=`dirname $QTDIR`
|
||||
QTDIR=$QTDIR/`dirname $LINKDIR`
|
||||
QTDIR=`dirname $QTDIR`
|
||||
test -L "$QTDIR" && QTDIR=`readlink $QTDIR`
|
||||
|
||||
echo "Goes here: $QTDIR"
|
||||
|
||||
export QMAKESPEC='macx-g++'
|
||||
export QTDIR
|
||||
export VERSION
|
||||
export QTVERSION='4.7.3'
|
||||
################################################################################
|
||||
|
||||
|
||||
CLEAN='1'
|
||||
BUILD='1'
|
||||
NOTQUICK='1'
|
||||
CREATEDMG='1'
|
||||
VERSION=$1
|
||||
|
||||
header "Adding Qt to app bundle"
|
||||
cd tomahawk.app
|
||||
$ROOT/../admin/mac/add-Qt-to-bundle.sh \
|
||||
'QtCore QtGui QtXml QtNetwork QtSql QtXmlPatterns QtWebKit phonon'
|
||||
# 'QtCore QtGui QtXml QtNetwork QtSql QtXmlPatterns QtWebKit QtDbus phonon'
|
||||
################################################################################
|
||||
|
||||
header "Renaming files"
|
||||
mv tomahawk.app Tomahawk.app
|
||||
mv Tomahawk.app/Contents/MacOS/tomahawk Tomahawk.app/Contents/MacOS/Tomahawk
|
||||
|
||||
header "Fixing and copying libraries"
|
||||
$ROOT/../admin/mac/macdeploy.py Tomahawk.app quiet
|
||||
|
||||
cd Tomahawk.app
|
||||
|
||||
header "Renaming icon"
|
||||
mv Contents/Resources/tomahawkSources.icns Contents/Resources/Tomahawk.icns
|
||||
mv Contents/MacOS/tomahawk Contents/MacOS/Tomahawk
|
||||
# cp $ROOT/../admin/mac/Info.plist Contents/Info.plist
|
||||
cp $ROOT/../admin/mac/qt.conf Contents/Resources/qt.conf
|
||||
|
||||
header "Copying VLC plugins into bundle"
|
||||
mkdir -p Contents/plugins
|
||||
cp -R /usr/local/Cellar/vlc-git/HEAD/lib/vlc/plugins/ Contents/plugins
|
||||
rm -rf Contents/plugins/video_* Contents/plugins/gui Contents/plugins/*/libold* Contents/plugins/*/libvcd* Contents/plugins/*/libdvd* \
|
||||
Contents/plugins/*/liblibass* Contents/plugins/*/libx264* Contents/plugins/*/libschroe* Contents/plugins/*/liblibmpeg2* \
|
||||
Contents/plugins/*/libstream_out_* Contents/plugins/*/libmjpeg_plugin* Contents/plugins/*/libh264_plugin* Contents/plugins/*/libzvbi_plugin* Contents/plugins/*/lib*sub*
|
||||
|
||||
header "Running install_name_tool"
|
||||
$ROOT/../admin/mac/deposx.sh
|
||||
|
||||
header "Copying Sparkle pubkey & framework, and qt.conf"
|
||||
cp $ROOT/../admin/mac/sparkle_pub.pem Contents/Resources
|
||||
cp -R /Library/Frameworks/Sparkle.framework Contents/Frameworks
|
||||
cp $ROOT/../admin/mac/qt.conf Contents/Resources
|
||||
|
||||
header "Adding spotify resolver to bundle if spotify_tomahawkresolver found in $ROOT"
|
||||
if [ -e $ROOT/spotify_tomahawkresolver ]
|
||||
then
|
||||
header "Found, so adding spotify resolver."ac
|
||||
$ROOT/../admin/mac/add-spotify.sh $ROOT/spotify_tomahawkresolver
|
||||
fi
|
||||
|
||||
header "Creating DMG"
|
||||
cd ..
|
||||
mv tomahawk.app Tomahawk.app
|
||||
|
||||
$ROOT/../admin/mac/create-dmg.sh Tomahawk.app
|
||||
mv Tomahawk.dmg Tomahawk-$VERSION.dmg
|
||||
|
||||
|
@ -1,169 +0,0 @@
|
||||
#!/bin/sh
|
||||
# author: max@last.fm, chris@last.fm
|
||||
################################################################################
|
||||
|
||||
|
||||
if [ -z $QTDIR ]
|
||||
then
|
||||
echo QTDIR must be set
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z $QTVERSION ]
|
||||
then
|
||||
echo QTVERSION must be set
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ..
|
||||
ORIGROOT=`pwd`
|
||||
cd -
|
||||
|
||||
cd Contents
|
||||
|
||||
QTLIBS=`ls Frameworks | cut -d. -f1`
|
||||
LIBS=`cd MacOS && ls -fR1 | grep dylib`
|
||||
PLUGINFOLDERS=`ls plugins | cut -d. -f1`
|
||||
|
||||
################################################################################
|
||||
|
||||
|
||||
function import_lib
|
||||
{
|
||||
echo "L \`$1'"
|
||||
cp -R -L $1 MacOS/`basename $1`
|
||||
chmod u+rw MacOS/`basename $1`
|
||||
deplib_change MacOS/`basename $1`
|
||||
deposx_change MacOS/`basename $1`
|
||||
}
|
||||
|
||||
function deposx_change
|
||||
{
|
||||
echo "D \`$1'"
|
||||
echo $QTDIR
|
||||
|
||||
for y in $QTLIBS
|
||||
do
|
||||
install_name_tool -change $QTDIR/lib/$y.framework/Versions/4/$y \
|
||||
@executable_path/../Frameworks/$y.framework/Versions/4/$y \
|
||||
"$1"
|
||||
|
||||
install_name_tool -change /usr/local/Cellar/qt/$QTVERSION/lib/$y.framework/Versions/4/$y \
|
||||
@executable_path/../Frameworks/$y.framework/Versions/4/$y \
|
||||
"$1"
|
||||
|
||||
install_name_tool -change /usr/X11/lib/libpng12.0.dylib \
|
||||
@executable_path/libpng12.0.dylib \
|
||||
"$1"
|
||||
done
|
||||
|
||||
for y in $LIBS
|
||||
do
|
||||
install_name_tool -change $y \
|
||||
@executable_path/$y \
|
||||
"$1"
|
||||
done
|
||||
}
|
||||
|
||||
function deplib_change
|
||||
{
|
||||
install_name_tool -change /usr/local/Cellar/qjson/0.7.1/lib/libqjson.0.7.1.dylib @executable_path/libqjson.0.7.1.dylib $1
|
||||
install_name_tool -change /usr/local/lib/libechonest.1.1.dylib @executable_path/libechonest.1.1.dylib $1
|
||||
install_name_tool -change /usr/local/lib/libclucene-core.1.dylib @executable_path/libclucene-core.1.dylib $1
|
||||
install_name_tool -change /usr/local/lib/libclucene-shared.1.dylib @executable_path/libclucene-shared.1.dylib $1
|
||||
install_name_tool -change /usr/local/Cellar/taglib/1.7/lib/libtag.1.7.0.dylib @executable_path/libtag.1.7.0.dylib $1
|
||||
# install_name_tool -change /usr/local/Cellar/gloox/1.0/lib/libgloox.8.dylib @executable_path/libgloox.8.dylib $1
|
||||
# install_name_tool -change /usr/local/Cellar/libogg/1.2.0/lib/libogg.0.dylib @executable_path/libogg.0.dylib $1
|
||||
# install_name_tool -change /usr/local/Cellar/libvorbis/1.3.1/lib/libvorbis.0.dylib @executable_path/libvorbis.0.dylib $1
|
||||
# install_name_tool -change /usr/local/Cellar/libvorbis/1.3.1/lib/libvorbisfile.3.dylib @executable_path/libvorbisfile.3.dylib $1
|
||||
# install_name_tool -change /usr/local/Cellar/mad/0.15.1b/lib/libmad.0.dylib @executable_path/libmad.0.dylib $1
|
||||
# install_name_tool -change /usr/local/Cellar/flac/1.2.1/lib/libFLAC++.6.dylib @executable_path/libFLAC++.6.dylib $1
|
||||
# install_name_tool -change /usr/local/Cellar/flac/1.2.1/lib/libFLAC.8.dylib @executable_path/libFLAC.8.dylib $1
|
||||
install_name_tool -change /usr/local/Cellar/kde-phonon/4.5.0/lib/libphonon.4.dylib @executable_path/libphonon.4.dylib $1
|
||||
install_name_tool -change /usr/local/Cellar/kde-phonon/4.5.0/lib/libphonon.4.5.0.dylib @executable_path/libphonon.4.dylib $1
|
||||
|
||||
install_name_tool -change $ORIGROOT/libtomahawklib.dylib @executable_path/libtomahawklib.dylib $1
|
||||
install_name_tool -change $ORIGROOT/libtomahawk_sipjabber.dylib @executable_path/libtomahawk_sipjabber.dylib $1
|
||||
install_name_tool -change $ORIGROOT/libtomahawk_sipgoogle.dylib @executable_path/libtomahawk_sipgoogle.dylib $1
|
||||
install_name_tool -change $ORIGROOT/libtomahawk_siptwitter.dylib @executable_path/libtomahawk_siptwitter.dylib $1
|
||||
install_name_tool -change $ORIGROOT/libtomahawk_sipzeroconf.dylib @executable_path/libtomahawk_sipzeroconf.dylib $1
|
||||
install_name_tool -change $ORIGROOT/libtomahawk_qtweetlib.dylib @executable_path/libtomahawk_qtweetlib.dylib $1
|
||||
install_name_tool -change $ORIGROOT/libtomahawk_portfwd.dylib @executable_path/libtomahawk_portfwd.dylib $1
|
||||
install_name_tool -change $ORIGROOT/libjreen.dylib @executable_path/libjreen.dylib $1
|
||||
install_name_tool -change /usr/local/Cellar/jreen/HEAD/lib/libjreen.dylib @executable_path/libjreen.dylib $1
|
||||
install_name_tool -change /usr/local/Cellar/qca/2.0.2/lib/qca.framework/Versions/2/qca @executable_path/../Frameworks/qca.framework/Versions/2/qca $1
|
||||
install_name_tool -change /usr/local/Cellar/gettext/0.18.1.1/lib/libintl.8.dylib @executable_path/libintl.8.dylib $1
|
||||
install_name_tool -change /usr/local/Cellar/vlc-git/HEAD/lib/libvlc.5.dylib @executable_path/libvlc.5.dylib $1
|
||||
install_name_tool -change /usr/local/Cellar/vlc-git/HEAD/lib/libvlccore.4.dylib @executable_path/libvlccore.4.dylib $1
|
||||
|
||||
install_name_tool -change libqjson.0.dylib @executable_path/libqjson.0.7.1.dylib $1
|
||||
install_name_tool -change libechonest.1.1.dylib @executable_path/libechonest.1.1.dylib $1
|
||||
install_name_tool -change libclucene-core.1.dylib @executable_path/libclucene-core.1.dylib $1
|
||||
install_name_tool -change libclucene-shared.1.dylib @executable_path/libclucene-shared.1.dylib $1
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
||||
|
||||
# first all libraries and executables
|
||||
find MacOS -type f -a -perm -100 | while read x
|
||||
do
|
||||
echo $x
|
||||
y=$(file "$x" | grep 'Mach-O')
|
||||
deposx_change "$x"
|
||||
deplib_change "$x"
|
||||
done
|
||||
|
||||
import_lib /usr/local/Cellar/qjson/0.7.1/lib/libqjson.0.7.1.dylib
|
||||
import_lib /usr/local/Cellar/taglib/1.7/lib/libtag.1.7.0.dylib
|
||||
#import_lib /usr/local/Cellar/gloox/1.0/lib/libgloox.8.dylib
|
||||
#import_lib /usr/local/Cellar/libogg/1.2.0/lib/libogg.0.dylib
|
||||
#import_lib /usr/local/Cellar/libvorbis/1.3.1/lib/libvorbis.0.dylib
|
||||
#import_lib /usr/local/Cellar/libvorbis/1.3.1/lib/libvorbisfile.3.dylib
|
||||
#import_lib /usr/local/Cellar/mad/0.15.1b/lib/libmad.0.dylib
|
||||
#import_lib /usr/local/Cellar/flac/1.2.1/lib/libFLAC++.6.dylib
|
||||
#import_lib /usr/local/Cellar/flac/1.2.1/lib/libFLAC.8.dylib
|
||||
import_lib /usr/local/lib/libechonest.1.1.dylib
|
||||
import_lib /usr/local/lib/libclucene-core.1.dylib
|
||||
import_lib /usr/local/lib/libclucene-shared.1.dylib
|
||||
import_lib /usr/local/Cellar/kde-phonon/4.5.0/lib/libphonon.4.dylib
|
||||
import_lib /usr/local/Cellar/vlc-git/HEAD/lib/libvlc.5.dylib
|
||||
import_lib /usr/local/Cellar/vlc-git/HEAD/lib/libvlccore.4.dylib
|
||||
import_lib /usr/local/Cellar/gettext/0.18.1.1/lib/libintl.8.dylib
|
||||
import_lib /usr/X11/lib/libpng12.0.dylib
|
||||
|
||||
import_lib $ORIGROOT/libjreen.dylib
|
||||
import_lib $ORIGROOT/libtomahawklib.dylib
|
||||
import_lib $ORIGROOT/libtomahawk_sipjabber.dylib
|
||||
import_lib $ORIGROOT/libtomahawk_sipgoogle.dylib
|
||||
import_lib $ORIGROOT/libtomahawk_siptwitter.dylib
|
||||
import_lib $ORIGROOT/libtomahawk_sipzeroconf.dylib
|
||||
import_lib $ORIGROOT/libtomahawk_qtweetlib.dylib
|
||||
import_lib $ORIGROOT/libtomahawk_portfwd.dylib
|
||||
|
||||
cp -R /usr/local/Cellar/qca/2.0.2/lib/qca.framework Frameworks/
|
||||
chmod 644 Frameworks/qca.framework/Versions/2/qca
|
||||
deplib_change Frameworks/qca.framework/Versions/2/qca
|
||||
deposx_change Frameworks/qca.framework/Versions/2/qca
|
||||
|
||||
# now Qt
|
||||
for x in $QTLIBS
|
||||
do
|
||||
echo `pwd`
|
||||
# ls -l Frameworks/$x.framework/Versions/4/$x
|
||||
deposx_change Frameworks/$x.framework/Versions/4/$x
|
||||
install_name_tool -id @executable_path/../Frameworks/$x.framework/Versions/4/$x \
|
||||
Frameworks/$x.framework/Versions/4/$x
|
||||
deplib_change "Frameworks/$x.framework/Versions/4/$x"
|
||||
done
|
||||
|
||||
# now VLC plugins
|
||||
for x in plugins/$PLUGINFOLDERS
|
||||
do
|
||||
for plugin in `ls plugins/$x | cut -f1`
|
||||
do
|
||||
echo "Fixing VLC plugin: $plugin"
|
||||
chmod 644 plugins/$x/$plugin
|
||||
deplib_change plugins/$x/$plugin
|
||||
done
|
||||
done
|
517
admin/mac/macdeploy.py
Executable file
@ -0,0 +1,517 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# This file is part of Clementine.
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
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=[
|
||||
'access/libaccess_attachment_plugin.dylib',
|
||||
#'access/libaccess_avio_plugin.dylib',
|
||||
'access/libaccess_fake_plugin.dylib',
|
||||
'access/libaccess_ftp_plugin.dylib',
|
||||
'access/libaccess_http_plugin.dylib',
|
||||
'access/libaccess_imem_plugin.dylib',
|
||||
'access/libaccess_mmap_plugin.dylib',
|
||||
'access/libaccess_mms_plugin.dylib',
|
||||
'access/libaccess_realrtsp_plugin.dylib',
|
||||
'access/libaccess_tcp_plugin.dylib',
|
||||
'access/libaccess_udp_plugin.dylib',
|
||||
'access/libcdda_plugin.dylib',
|
||||
'access/libfilesystem_plugin.dylib',
|
||||
'access/libqtcapture_plugin.dylib',
|
||||
'access/librtp_plugin.dylib',
|
||||
'access/libzip_plugin.dylib',
|
||||
'access_output/libaccess_output_dummy_plugin.dylib',
|
||||
'access_output/libaccess_output_file_plugin.dylib',
|
||||
'access_output/libaccess_output_http_plugin.dylib',
|
||||
'access_output/libaccess_output_shout_plugin.dylib',
|
||||
'access_output/libaccess_output_udp_plugin.dylib',
|
||||
'audio_filter/liba52tofloat32_plugin.dylib',
|
||||
'audio_filter/liba52tospdif_plugin.dylib',
|
||||
'audio_filter/libaudio_format_plugin.dylib',
|
||||
'audio_filter/libaudiobargraph_a_plugin.dylib',
|
||||
'audio_filter/libchorus_flanger_plugin.dylib',
|
||||
'audio_filter/libconverter_fixed_plugin.dylib',
|
||||
'audio_filter/libdolby_surround_decoder_plugin.dylib',
|
||||
'audio_filter/libdtstofloat32_plugin.dylib',
|
||||
'audio_filter/libdtstospdif_plugin.dylib',
|
||||
'audio_filter/libequalizer_plugin.dylib',
|
||||
'audio_filter/libheadphone_channel_mixer_plugin.dylib',
|
||||
'audio_filter/libmono_plugin.dylib',
|
||||
'audio_filter/libmpgatofixed32_plugin.dylib',
|
||||
'audio_filter/libnormvol_plugin.dylib',
|
||||
'audio_filter/libparam_eq_plugin.dylib',
|
||||
'audio_filter/libscaletempo_plugin.dylib',
|
||||
'audio_filter/libsimple_channel_mixer_plugin.dylib',
|
||||
'audio_filter/libspatializer_plugin.dylib',
|
||||
'audio_filter/libtrivial_channel_mixer_plugin.dylib',
|
||||
'audio_filter/libugly_resampler_plugin.dylib',
|
||||
'audio_mixer/libfloat32_mixer_plugin.dylib',
|
||||
'audio_mixer/libspdif_mixer_plugin.dylib',
|
||||
'audio_mixer/libtrivial_mixer_plugin.dylib',
|
||||
'audio_output/libaout_file_plugin.dylib',
|
||||
'audio_output/libauhal_plugin.dylib',
|
||||
'codec/liba52_plugin.dylib',
|
||||
'codec/libadpcm_plugin.dylib',
|
||||
'codec/libaes3_plugin.dylib',
|
||||
'codec/libaraw_plugin.dylib',
|
||||
'codec/libavcodec_plugin.dylib',
|
||||
'codec/libcc_plugin.dylib',
|
||||
'codec/libcdg_plugin.dylib',
|
||||
'codec/libdts_plugin.dylib',
|
||||
'codec/libfaad_plugin.dylib',
|
||||
'codec/libfake_plugin.dylib',
|
||||
'codec/libflac_plugin.dylib',
|
||||
'codec/libfluidsynth_plugin.dylib',
|
||||
'codec/libinvmem_plugin.dylib',
|
||||
'codec/liblpcm_plugin.dylib',
|
||||
'codec/libmpeg_audio_plugin.dylib',
|
||||
'codec/libpng_plugin.dylib',
|
||||
'codec/librawvideo_plugin.dylib',
|
||||
'codec/libspeex_plugin.dylib',
|
||||
'codec/libspudec_plugin.dylib',
|
||||
'codec/libtheora_plugin.dylib',
|
||||
'codec/libtwolame_plugin.dylib',
|
||||
'codec/libvorbis_plugin.dylib',
|
||||
'control/libgestures_plugin.dylib',
|
||||
'control/libhotkeys_plugin.dylib',
|
||||
'control/libmotion_plugin.dylib',
|
||||
'control/libnetsync_plugin.dylib',
|
||||
'control/libsignals_plugin.dylib',
|
||||
'demux/libaiff_plugin.dylib',
|
||||
'demux/libasf_plugin.dylib',
|
||||
'demux/libau_plugin.dylib',
|
||||
#'demux/libavformat_plugin.dylib',
|
||||
'demux/libavi_plugin.dylib',
|
||||
'demux/libdemux_cdg_plugin.dylib',
|
||||
'demux/libdemuxdump_plugin.dylib',
|
||||
'demux/libdirac_plugin.dylib',
|
||||
'demux/libes_plugin.dylib',
|
||||
'demux/libflacsys_plugin.dylib',
|
||||
'demux/liblive555_plugin.dylib',
|
||||
'demux/libmkv_plugin.dylib',
|
||||
'demux/libmod_plugin.dylib',
|
||||
'demux/libmp4_plugin.dylib',
|
||||
'demux/libmpc_plugin.dylib',
|
||||
'demux/libmpgv_plugin.dylib',
|
||||
'demux/libnsc_plugin.dylib',
|
||||
'demux/libnsv_plugin.dylib',
|
||||
'demux/libnuv_plugin.dylib',
|
||||
'demux/libogg_plugin.dylib',
|
||||
'demux/libplaylist_plugin.dylib',
|
||||
'demux/libps_plugin.dylib',
|
||||
'demux/libpva_plugin.dylib',
|
||||
'demux/librawaud_plugin.dylib',
|
||||
'demux/librawdv_plugin.dylib',
|
||||
'demux/librawvid_plugin.dylib',
|
||||
'demux/libreal_plugin.dylib',
|
||||
'demux/libsmf_plugin.dylib',
|
||||
'demux/libts_plugin.dylib',
|
||||
'demux/libtta_plugin.dylib',
|
||||
'demux/libty_plugin.dylib',
|
||||
'demux/libvc1_plugin.dylib',
|
||||
'demux/libvoc_plugin.dylib',
|
||||
'demux/libwav_plugin.dylib',
|
||||
'demux/libxa_plugin.dylib',
|
||||
'meta_engine/libfolder_plugin.dylib',
|
||||
'meta_engine/libtaglib_plugin.dylib',
|
||||
'misc/libaudioscrobbler_plugin.dylib',
|
||||
'misc/libdummy_plugin.dylib',
|
||||
'misc/libexport_plugin.dylib',
|
||||
'misc/libfreetype_plugin.dylib',
|
||||
'misc/libgnutls_plugin.dylib',
|
||||
'misc/liblogger_plugin.dylib',
|
||||
'misc/liblua_plugin.dylib',
|
||||
'misc/libosd_parser_plugin.dylib',
|
||||
'misc/libquartztext_plugin.dylib',
|
||||
'misc/libstats_plugin.dylib',
|
||||
'misc/libvod_rtsp_plugin.dylib',
|
||||
'misc/libxml_plugin.dylib',
|
||||
'misc/libxtag_plugin.dylib',
|
||||
'mmx/libi420_rgb_mmx_plugin.dylib',
|
||||
'mmx/libi420_yuy2_mmx_plugin.dylib',
|
||||
'mmx/libi422_yuy2_mmx_plugin.dylib',
|
||||
'mmx/libmemcpymmx_plugin.dylib',
|
||||
'mmxext/libmemcpymmxext_plugin.dylib',
|
||||
'mux/libmux_asf_plugin.dylib',
|
||||
'mux/libmux_avi_plugin.dylib',
|
||||
'mux/libmux_dummy_plugin.dylib',
|
||||
'mux/libmux_mp4_plugin.dylib',
|
||||
'mux/libmux_mpjpeg_plugin.dylib',
|
||||
'mux/libmux_ogg_plugin.dylib',
|
||||
'mux/libmux_ps_plugin.dylib',
|
||||
'mux/libmux_ts_plugin.dylib',
|
||||
'mux/libmux_wav_plugin.dylib',
|
||||
'packetizer/libpacketizer_copy_plugin.dylib',
|
||||
'packetizer/libpacketizer_dirac_plugin.dylib',
|
||||
'packetizer/libpacketizer_flac_plugin.dylib',
|
||||
'packetizer/libpacketizer_h264_plugin.dylib',
|
||||
'packetizer/libpacketizer_mlp_plugin.dylib',
|
||||
'packetizer/libpacketizer_mpeg4audio_plugin.dylib',
|
||||
'packetizer/libpacketizer_mpeg4video_plugin.dylib',
|
||||
'packetizer/libpacketizer_mpegvideo_plugin.dylib',
|
||||
'packetizer/libpacketizer_vc1_plugin.dylib',
|
||||
'sse2/libi420_rgb_sse2_plugin.dylib',
|
||||
'sse2/libi420_yuy2_sse2_plugin.dylib',
|
||||
'sse2/libi422_yuy2_sse2_plugin.dylib',
|
||||
'stream_filter/libdecomp_plugin.dylib',
|
||||
'stream_filter/libstream_filter_rar_plugin.dylib',
|
||||
'stream_filter/libstream_filter_record_plugin.dylib',
|
||||
'visualization/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',
|
||||
]
|
||||
|
||||
TOMAHAWK_PLUGINS = [
|
||||
'libtomahawk_sipjabber.dylib',
|
||||
'libtomahawk_sipgoogle.dylib',
|
||||
'libtomahawk_siptwitter.dylib',
|
||||
'libtomahawk_sipzeroconf.dylib',
|
||||
'libtomahawk_qtweetlib.dylib',
|
||||
]
|
||||
|
||||
QT_PLUGINS_SEARCH_PATH=[
|
||||
'/usr/local/Cellar/qt/4.7.3/plugins',
|
||||
]
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class CouldNotFindQtPluginErrorFindFrameworkError(Error):
|
||||
pass
|
||||
|
||||
|
||||
class InstallNameToolError(Error):
|
||||
pass
|
||||
|
||||
|
||||
class CouldNotFindQtPluginError(Error):
|
||||
pass
|
||||
|
||||
|
||||
class CouldNotFindVLCPluginError(Error):
|
||||
pass
|
||||
|
||||
|
||||
class CouldNotFindScriptPluginError(Error):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print 'Usage: %s <bundle.app>' % 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', '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:]))
|
||||
plugindir = abs_path.split('/')[-2]
|
||||
new_path = os.path.join(plugins_dir, subdir, plugindir, 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), '.')
|
||||
|
||||
for plugin in TOMAHAWK_PLUGINS:
|
||||
FixPlugin(plugin, '../MacOS')
|
||||
|
||||
try:
|
||||
FixPlugin('spotify_tomahawkresolver', '../MacOS')
|
||||
except:
|
||||
print 'Failed to find spotify resolver'
|
||||
|
||||
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)
|
@ -1,2 +1,2 @@
|
||||
[Paths]
|
||||
Plugins = plugins
|
||||
Plugins = PlugIns
|
||||
|
@ -1,20 +1,27 @@
|
||||
SET(MINGW_PREFIX "i686-w64-mingw32")
|
||||
|
||||
# this one is important
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
|
||||
# specify the cross compiler
|
||||
SET(CMAKE_C_COMPILER ccache i686-w64-mingw32-gcc)
|
||||
SET(CMAKE_CXX_COMPILER ccache i686-w64-mingw32-g++)
|
||||
SET(CMAKE_C_COMPILER ccache ${MINGW_PREFIX}-gcc)
|
||||
SET(CMAKE_CXX_COMPILER ccache ${MINGW_PREFIX}-g++)
|
||||
SET(CMAKE_RC_COMPILER /usr/bin/${MINGW_PREFIX}-windres)
|
||||
|
||||
# where is the target environment containing libraries
|
||||
SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32/sys-root/mingw)
|
||||
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)
|
||||
|
||||
# windres executable for application icon support
|
||||
SET(WINDRES_EXECUTABLE /usr/bin/i686-w64-mingw32-windres)
|
||||
|
||||
|
||||
# libs with broken find modules
|
||||
SET(TAGLIB_FOUND true)
|
||||
SET(TAGLIB_LIBRARIES ${CMAKE_FIND_ROOT_PATH}/lib/libtag.dll.a)
|
||||
SET(TAGLIB_INCLUDES ${CMAKE_FIND_ROOT_PATH}/include/taglib)
|
||||
|
||||
SET(QT_PLUGINS_DIR ${CMAKE_FIND_ROOT_PATH}/lib/qt4/plugins/)
|
||||
SET(QT_QTUITOOLS_LIBRARY_RELEASE ${CMAKE_FIND_ROOT_PATH}/lib/libQtUiTools.a)
|
||||
SET(QT_QTUITOOLS_LIBRARY_DEBUG ${CMAKE_FIND_ROOT_PATH}/lib/libQtUiToolsd.a)
|
||||
SET(QT_QTUITOOLS_LIBRARY ${QT_QTUITOOLS_LIBRARY_RELEASE})
|
BIN
data/images/album-shadow.png
Normal file
After Width: | Height: | Size: 204 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.1 KiB |
BIN
data/images/track-placeholder.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 3.1 KiB |
@ -10,6 +10,7 @@
|
||||
<file>data/images/not-loved.png</file>
|
||||
<file>data/images/no-album-art-placeholder.png</file>
|
||||
<file>data/images/no-artist-image-placeholder.png</file>
|
||||
<file>data/images/track-placeholder.png</file>
|
||||
<file>data/images/now-playing-panel.png</file>
|
||||
<file>data/images/now-playing-speaker.png</file>
|
||||
<file>data/images/pause-pressed.png</file>
|
||||
@ -85,6 +86,7 @@
|
||||
<file>data/images/station.png</file>
|
||||
<file>data/images/new-additions.png</file>
|
||||
<file>data/images/loved_playlist.png</file>
|
||||
<file>data/images/dashboard.png</file>
|
||||
<file>data/stylesheets/topbar-radiobuttons.css</file>
|
||||
<file>data/icons/tomahawk-icon-16x16.png</file>
|
||||
<file>data/icons/tomahawk-icon-32x32.png</file>
|
||||
|
@ -49,4 +49,8 @@ if (APPLE)
|
||||
)
|
||||
ENDIF()
|
||||
FILE( WRITE ${CMAKE_BINARY_DIR}/Info.plist "${edited_plist}" )
|
||||
|
||||
FILE(COPY ${CMAKE_SOURCE_DIR}/admin/mac/sparkle_pub.pem
|
||||
DESTINATION "${CMAKE_BINARY_DIR}/tomahawk.app/Contents/Resources")
|
||||
|
||||
endif (APPLE)
|
||||
|
@ -14,7 +14,7 @@ SET( QT_USE_QTXML TRUE )
|
||||
SET( QT_USE_QTWEBKIT TRUE )
|
||||
|
||||
INCLUDE( ${QT_USE_FILE} )
|
||||
INCLUDE( ${CMAKE_MODULE_PATH}/AddAppIconMacro.cmake )
|
||||
INCLUDE( AddAppIconMacro )
|
||||
|
||||
#SET( CMAKE_BUILD_TYPE "Release" )
|
||||
SET( CMAKE_VERBOSE_MAKEFILE ON )
|
||||
|
@ -43,6 +43,7 @@ PipelineStatusView::PipelineStatusView( AnimatedSplitter* parent )
|
||||
headers << tr( "Searching For" ) << tr( "Pending" );
|
||||
m_tree->setHeaderLabels( headers );
|
||||
|
||||
m_tree->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
m_tree->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Ignored );
|
||||
m_tree->setColumnCount( 2 );
|
||||
m_tree->setColumnWidth( 0, 200 );
|
||||
@ -59,6 +60,17 @@ PipelineStatusView::PipelineStatusView( AnimatedSplitter* parent )
|
||||
connect( Pipeline::instance(), SIGNAL( resolving( Tomahawk::query_ptr ) ), SLOT( onPipelineUpdate( Tomahawk::query_ptr ) ) );
|
||||
connect( Pipeline::instance(), SIGNAL( idle() ), SLOT( onPipelineUpdate() ) );
|
||||
|
||||
#ifndef Q_WS_WIN
|
||||
QFont f = font();
|
||||
f.setPointSize( f.pointSize() - 1 );
|
||||
setFont( f );
|
||||
#endif
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
f.setPointSize( f.pointSize() - 2 );
|
||||
setFont( f );
|
||||
#endif
|
||||
|
||||
onPipelineUpdate();
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,6 @@ AudioControls::AudioControls( QWidget* parent )
|
||||
ui->setupUi( this );
|
||||
setAcceptDrops( true );
|
||||
|
||||
ui->buttonAreaLayout->setSpacing( 2 );
|
||||
|
||||
QFont font( ui->artistTrackLabel->font() );
|
||||
font.setPixelSize( 12 );
|
||||
|
||||
@ -181,6 +179,15 @@ AudioControls::AudioControls( QWidget* parent )
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
|
||||
ui->buttonAreaLayout->setSpacing( 0 );
|
||||
ui->stackedLayout->setSpacing( 0 );
|
||||
ui->stackedLayout->setContentsMargins( 0, 0, 0, 0 );
|
||||
ui->stackedLayout->setMargin( 0 );
|
||||
ui->playPauseButton->setContentsMargins( 0, 0, 0, 0 );
|
||||
ui->pauseButton->setContentsMargins( 0, 0, 0, 0 );
|
||||
ui->stackedLayout->setSizeConstraint( QLayout::SetFixedSize );
|
||||
|
||||
onPlaybackStopped(); // initial state
|
||||
}
|
||||
|
||||
@ -301,10 +308,8 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result )
|
||||
/* m_playAction->setEnabled( false );
|
||||
m_pauseAction->setEnabled( true ); */
|
||||
|
||||
ui->pauseButton->setEnabled( true );
|
||||
ui->pauseButton->setVisible( true );
|
||||
ui->playPauseButton->setVisible( false );
|
||||
ui->playPauseButton->setEnabled( false );
|
||||
ui->stackedLayout->setCurrentWidget( ui->pauseButton );
|
||||
|
||||
ui->loveButton->setEnabled( true );
|
||||
ui->loveButton->setVisible( true );
|
||||
|
||||
@ -341,23 +346,16 @@ AudioControls::onPlaybackPaused()
|
||||
/* m_pauseAction->setEnabled( false );
|
||||
m_playAction->setEnabled( true ); */
|
||||
|
||||
ui->pauseButton->setVisible( false );
|
||||
ui->pauseButton->setEnabled( false );
|
||||
ui->playPauseButton->setEnabled( true );
|
||||
ui->playPauseButton->setVisible( true );
|
||||
ui->stackedLayout->setCurrentWidget( ui->playPauseButton );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioControls::onPlaybackResumed()
|
||||
{
|
||||
/* m_playAction->setEnabled( false );
|
||||
m_pauseAction->setEnabled( true ); */
|
||||
|
||||
ui->playPauseButton->setVisible( false );
|
||||
ui->playPauseButton->setEnabled( false );
|
||||
ui->pauseButton->setVisible( true );
|
||||
ui->pauseButton->setEnabled( true );
|
||||
ui->stackedLayout->setCurrentWidget( ui->pauseButton );
|
||||
ui->loveButton->setVisible( true );
|
||||
}
|
||||
|
||||
@ -375,10 +373,7 @@ AudioControls::onPlaybackStopped()
|
||||
ui->coverImage->setPixmap( QPixmap() );
|
||||
ui->seekSlider->setVisible( false );
|
||||
|
||||
ui->pauseButton->setVisible( false );
|
||||
ui->pauseButton->setEnabled( false );
|
||||
ui->playPauseButton->setEnabled( true );
|
||||
ui->playPauseButton->setVisible( true );
|
||||
ui->stackedLayout->setCurrentWidget( ui->playPauseButton );
|
||||
ui->loveButton->setEnabled( false );
|
||||
ui->loveButton->setVisible( false );
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>939</width>
|
||||
<width>929</width>
|
||||
<height>80</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -60,7 +60,7 @@
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="buttonAreaLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@ -80,18 +80,25 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ImageButton" name="playPauseButton">
|
||||
<property name="text">
|
||||
<string>Play</string>
|
||||
<layout class="QStackedLayout" name="stackedLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ImageButton" name="pauseButton">
|
||||
<property name="text">
|
||||
<string>Pause</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item>
|
||||
<widget class="ImageButton" name="playPauseButton">
|
||||
<property name="text">
|
||||
<string>Play</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ImageButton" name="pauseButton">
|
||||
<property name="text">
|
||||
<string>Pause</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ImageButton" name="nextButton">
|
||||
@ -101,7 +108,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
|
@ -173,6 +173,7 @@ set( libSources
|
||||
utils/xspfgenerator.cpp
|
||||
utils/jspfloader.cpp
|
||||
utils/spotifyparser.cpp
|
||||
utils/rdioparser.cpp
|
||||
utils/shortenedlinkparser.cpp
|
||||
|
||||
widgets/newplaylistwidget.cpp
|
||||
@ -185,6 +186,7 @@ set( libSources
|
||||
widgets/SocialPlaylistWidget.cpp
|
||||
widgets/infowidgets/sourceinfowidget.cpp
|
||||
widgets/infowidgets/ArtistInfoWidget.cpp
|
||||
widgets/infowidgets/AlbumInfoWidget.cpp
|
||||
|
||||
kdsingleapplicationguard/kdsingleapplicationguard.cpp
|
||||
kdsingleapplicationguard/kdsharedmemorylocker.cpp
|
||||
@ -352,6 +354,7 @@ set( libHeaders
|
||||
utils/xspfgenerator.h
|
||||
utils/jspfloader.h
|
||||
utils/spotifyparser.h
|
||||
utils/rdioparser.h
|
||||
utils/shortenedlinkparser.h
|
||||
|
||||
widgets/newplaylistwidget.h
|
||||
@ -364,6 +367,7 @@ set( libHeaders
|
||||
widgets/SocialPlaylistWidget.h
|
||||
widgets/infowidgets/sourceinfowidget.h
|
||||
widgets/infowidgets/ArtistInfoWidget.h
|
||||
widgets/infowidgets/AlbumInfoWidget.h
|
||||
|
||||
kdsingleapplicationguard/kdsingleapplicationguard.h
|
||||
)
|
||||
@ -387,6 +391,7 @@ set( libUI ${libUI}
|
||||
widgets/SocialPlaylistWidget.ui
|
||||
widgets/infowidgets/sourceinfowidget.ui
|
||||
widgets/infowidgets/ArtistInfoWidget.ui
|
||||
widgets/infowidgets/AlbumInfoWidget.ui
|
||||
playlist/topbar/topbar.ui
|
||||
playlist/infobar/infobar.ui
|
||||
)
|
||||
@ -488,7 +493,9 @@ target_link_libraries( tomahawklib
|
||||
${TAGLIB_LIBRARIES}
|
||||
${CLUCENE_LIBRARIES}
|
||||
${LIBECHONEST_LIBRARY}
|
||||
${QT_QTUITOOLS_LIBRARY}
|
||||
${QT_LIBRARIES}
|
||||
${QT_QTUITOOLS_LIBRARY} # We really need to link twice against it for windows, maybe QTBUG-20498 is related
|
||||
${OS_SPECIFIC_LINK_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${LINK_LIBRARIES}
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "utils/jspfloader.h"
|
||||
#include "utils/spotifyparser.h"
|
||||
#include "utils/shortenedlinkparser.h"
|
||||
#include "utils/rdioparser.h"
|
||||
|
||||
GlobalActionManager* GlobalActionManager::s_instance = 0;
|
||||
|
||||
@ -791,14 +792,20 @@ GlobalActionManager::acceptsMimeData( const QMimeData* data, bool tracksOnly )
|
||||
|
||||
// crude check for spotify tracks
|
||||
if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "spotify" ) &&
|
||||
( tracksOnly ? data->data( "text/plain" ).contains( "track" ) : true ) )
|
||||
( tracksOnly ? data->data( "text/plain" ).contains( "track" ) : true ) )
|
||||
return true;
|
||||
|
||||
// crude check for rdio tracks
|
||||
if ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "rdio.com" ) &&
|
||||
( tracksOnly ? data->data( "text/plain" ).contains( "track" ) : true ) )
|
||||
return true;
|
||||
|
||||
// We whitelist t.co and bit.ly (and j.mp) since they do some link checking. Often playable (e.g. spotify..) links hide behind them,
|
||||
// so we do an extra level of lookup
|
||||
if ( ( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "bit.ly" ) ) ||
|
||||
( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "j.mp" ) ) ||
|
||||
( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "t.co" ) ) )
|
||||
( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "t.co" ) ) ||
|
||||
( data->hasFormat( "text/plain" ) && data->data( "text/plain" ).contains( "rd.io" ) ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -831,9 +838,18 @@ GlobalActionManager::handleTrackUrls( const QString& urls )
|
||||
tDebug() << "Got a list of spotify urls!" << tracks;
|
||||
SpotifyParser* spot = new SpotifyParser( tracks, this );
|
||||
connect( spot, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ) );
|
||||
} else if ( urls.contains( "rdio.com" ) )
|
||||
{
|
||||
QStringList tracks = urls.split( "\n" );
|
||||
|
||||
tDebug() << "Got a list of rdio urls!" << tracks;
|
||||
RdioParser* rdio = new RdioParser( this );
|
||||
connect( rdio, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ), this, SIGNAL( tracks( QList<Tomahawk::query_ptr> ) ) );
|
||||
rdio->parse( tracks );
|
||||
} else if ( urls.contains( "bit.ly" ) ||
|
||||
urls.contains( "j.mp" ) ||
|
||||
urls.contains( "t.co" ) )
|
||||
urls.contains( "t.co" ) ||
|
||||
urls.contains( "rd.io" ) )
|
||||
{
|
||||
QStringList tracks = urls.split( "\n" );
|
||||
|
||||
@ -909,3 +925,14 @@ GlobalActionManager::openSpotifyLink( const QString& link )
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalActionManager::openRdioLink( const QString& link )
|
||||
{
|
||||
RdioParser* rdio = new RdioParser( this );
|
||||
connect( rdio, SIGNAL( track( Tomahawk::query_ptr ) ), this, SLOT( handleOpenTrack( Tomahawk::query_ptr ) ) );
|
||||
rdio->parse( link );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,9 @@ public:
|
||||
/// Takes a spotify link and performs the default open action on it
|
||||
bool openSpotifyLink( const QString& link );
|
||||
|
||||
/// Takes a spotify link and performs the default open action on it
|
||||
bool openRdioLink( const QString& link );
|
||||
|
||||
void copyToClipboard( const Tomahawk::query_ptr& query ) const;
|
||||
QString copyPlaylistToClipboard( const Tomahawk::dynplaylist_ptr& playlist );
|
||||
void savePlaylistToFile( const Tomahawk::playlist_ptr& playlist, const QString& filename );
|
||||
|
@ -66,9 +66,9 @@ public:
|
||||
}
|
||||
|
||||
public slots:
|
||||
void resolve( const query_ptr& q, bool prioritized = false, bool temporaryQuery = false );
|
||||
void resolve( const QList<query_ptr>& qlist, bool prioritized = false, bool temporaryQuery = false );
|
||||
void resolve( QID qid, bool prioritized = false, bool temporaryQuery = false );
|
||||
void resolve( const query_ptr& q, bool prioritized = true, bool temporaryQuery = false );
|
||||
void resolve( const QList<query_ptr>& qlist, bool prioritized = true, bool temporaryQuery = false );
|
||||
void resolve( QID qid, bool prioritized = true, bool temporaryQuery = false );
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
|
@ -43,6 +43,7 @@ CustomPlaylistView::CustomPlaylistView( CustomPlaylistView::PlaylistType type, c
|
||||
connect( m_source.data(), SIGNAL( socialAttributesChanged() ), this, SLOT( reload() ) );
|
||||
else if ( m_type == AllLovedTracks )
|
||||
{
|
||||
connect( SourceList::instance()->getLocal().data(), SIGNAL( socialAttributesChanged() ), this, SLOT( reload() ) );
|
||||
foreach ( const source_ptr& s, SourceList::instance()->sources( true ) )
|
||||
connect( s.data(), SIGNAL( socialAttributesChanged() ), this, SLOT( reload() ) );
|
||||
|
||||
|
@ -219,4 +219,6 @@ private:
|
||||
|
||||
}; // namespace
|
||||
|
||||
Q_DECLARE_METATYPE( QSharedPointer< Tomahawk::DynamicPlaylist > )
|
||||
|
||||
#endif
|
||||
|
@ -401,8 +401,8 @@ EchonestGenerator::appendRadioType( Echonest::DynamicPlaylist::PlaylistParams& p
|
||||
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistRadioType ) );
|
||||
else if( onlyThisArtistType( Echonest::DynamicPlaylist::SongRadioType ) )
|
||||
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::SongRadioType ) );
|
||||
else // no artist or song or description types. default to song-radio
|
||||
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::SongRadioType ) );
|
||||
else // no artist or song or description types. default to artist-description
|
||||
params.append( Echonest::DynamicPlaylist::PlaylistParamData( Echonest::DynamicPlaylist::Type, Echonest::DynamicPlaylist::ArtistDescriptionType ) );
|
||||
|
||||
return static_cast< Echonest::DynamicPlaylist::ArtistTypeEnum >( params.last().second.toInt() );
|
||||
}
|
||||
|
@ -427,6 +427,17 @@ DynamicWidget::paintRoundedFilledRect( QPainter& p, QPalette& pal, QRect& r, qre
|
||||
p.drawRoundedRect( r, 10, 10 );
|
||||
}
|
||||
|
||||
QPixmap
|
||||
DynamicWidget::pixmap() const
|
||||
{
|
||||
if ( m_playlist->mode() == OnDemand )
|
||||
return QPixmap( RESPATH "images/station.png" );
|
||||
else if ( m_playlist->mode() == Static )
|
||||
return QPixmap( RESPATH "images/automatic-playlist.png" );
|
||||
else
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DynamicWidget::jumpToCurrentTrack()
|
||||
|
@ -77,7 +77,7 @@ public:
|
||||
|
||||
virtual QString title() const { return m_model->title(); }
|
||||
virtual QString description() const { return m_model->description(); }
|
||||
virtual QPixmap pixmap() const { return QPixmap( RESPATH "images/playlist-icon.png" ); }
|
||||
virtual QPixmap pixmap() const;
|
||||
|
||||
virtual bool jumpToCurrentTrack();
|
||||
|
||||
|
@ -57,6 +57,8 @@ PlaylistItemDelegate::PlaylistItemDelegate( TrackView* parent, TrackProxyModel*
|
||||
|
||||
m_centerOption = QTextOption( Qt::AlignVCenter );
|
||||
m_centerOption.setWrapMode( QTextOption::NoWrap );
|
||||
|
||||
m_defaultAvatar = TomahawkUtils::createAvatarFrame( QPixmap( RESPATH "images/user-avatar.png" ) );
|
||||
}
|
||||
|
||||
|
||||
@ -75,7 +77,7 @@ PlaylistItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModel
|
||||
if ( index.isValid() )
|
||||
{
|
||||
int style = index.data( TrackModel::StyleRole ).toInt();
|
||||
if ( style == TrackModel::Short )
|
||||
if ( style == TrackModel::Short || style == TrackModel::ShortWithAvatars )
|
||||
size.setHeight( 44 );
|
||||
}
|
||||
|
||||
@ -135,12 +137,14 @@ PlaylistItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& opti
|
||||
case TrackModel::Short:
|
||||
paintShort( painter, option, index );
|
||||
break;
|
||||
case TrackModel::ShortWithAvatars:
|
||||
paintShort( painter, option, index, true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, bool useAvatars ) const
|
||||
{
|
||||
TrackModelItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
@ -184,11 +188,14 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem&
|
||||
else
|
||||
lowerText = QString( "played %1 ago by %2" ).arg( playtime ).arg( source->friendlyName() );
|
||||
|
||||
pixmap = source->avatar();
|
||||
if ( useAvatars )
|
||||
pixmap = source->avatar( Source::FancyStyle );
|
||||
}
|
||||
|
||||
if ( pixmap.isNull() )
|
||||
pixmap = QPixmap( RESPATH "images/user-avatar.png" );
|
||||
if ( pixmap.isNull() && !useAvatars )
|
||||
pixmap = QPixmap( RESPATH "images/track-placeholder.png" );
|
||||
else if ( pixmap.isNull() && useAvatars )
|
||||
pixmap = m_defaultAvatar;
|
||||
|
||||
painter->save();
|
||||
{
|
||||
@ -227,7 +234,8 @@ PlaylistItemDelegate::paintShort( QPainter* painter, const QStyleOptionViewItem&
|
||||
QString text = painter->fontMetrics().elidedText( upperText, Qt::ElideRight, r.width() );
|
||||
painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, m_topOption );
|
||||
|
||||
painter->setFont( opt.font );
|
||||
|
||||
painter->setFont( opt.font);
|
||||
text = painter->fontMetrics().elidedText( lowerText, Qt::ElideRight, r.width() );
|
||||
painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, m_bottomOption );
|
||||
}
|
||||
@ -261,11 +269,7 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt
|
||||
|
||||
if ( index.column() == TrackModel::Score )
|
||||
{
|
||||
#ifdef Q_OS_MAC // On Mac, highlight color is very bright and stands out a lot
|
||||
QColor barColor( 167, 183, 211 ); // This matches the sidebar (sourcetreeview.cpp:672)
|
||||
#else
|
||||
QColor barColor = opt.palette.highlight().color();
|
||||
#endif
|
||||
if ( opt.state & QStyle::State_Selected )
|
||||
painter->setPen( opt.palette.brightText().color() );
|
||||
else
|
||||
|
@ -50,12 +50,12 @@ private:
|
||||
void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, TrackModelItem* item ) const;
|
||||
|
||||
void paintDetailed( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
void paintShort( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
void paintShort( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, bool useAvatars = false ) const;
|
||||
|
||||
unsigned int m_removalProgress;
|
||||
|
||||
mutable QHash< qint64, QPixmap > m_cache;
|
||||
QPixmap m_nowPlayingIcon;
|
||||
QPixmap m_nowPlayingIcon, m_defaultAvatar;
|
||||
mutable QPixmap m_arrowIcon;
|
||||
|
||||
QTextOption m_topOption;
|
||||
|
@ -116,7 +116,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn
|
||||
m_waitingForResolved.clear();
|
||||
foreach( const plentry_ptr& entry, entries )
|
||||
{
|
||||
qDebug() << entry->query()->toString();
|
||||
// qDebug() << entry->query()->toString();
|
||||
plitem = new TrackModelItem( entry, m_rootItem );
|
||||
plitem->index = createIndex( m_rootItem->children.count() - 1, 0, plitem );
|
||||
|
||||
|
@ -34,7 +34,7 @@ Q_OBJECT
|
||||
|
||||
public:
|
||||
enum TrackItemStyle
|
||||
{ Detailed = 0, Short = 1 };
|
||||
{ Detailed = 0, Short = 1, ShortWithAvatars = 2 };
|
||||
|
||||
enum TrackModelRole
|
||||
{ StyleRole = Qt::UserRole + 1 };
|
||||
|
@ -56,6 +56,7 @@ explicit TrackView( QWidget* parent = 0 );
|
||||
TrackHeader* header() const { return m_header; }
|
||||
OverlayWidget* overlay() const { return m_overlay; }
|
||||
Tomahawk::ContextMenu* contextMenu() const { return m_contextMenu; }
|
||||
LoadingSpinner* loadingSpinner() const { return m_loadingSpinner; }
|
||||
|
||||
QModelIndex hoveredIndex() const { return m_hoveredIndex; }
|
||||
QModelIndex contextMenuIndex() const { return m_contextMenuIndex; }
|
||||
|
@ -38,9 +38,12 @@ using namespace Tomahawk;
|
||||
query_ptr
|
||||
Query::get( const QString& artist, const QString& track, const QString& album, const QID& qid, bool autoResolve )
|
||||
{
|
||||
if ( qid.isEmpty() )
|
||||
autoResolve = false;
|
||||
|
||||
query_ptr q = query_ptr( new Query( artist, track, album, qid, autoResolve ) );
|
||||
|
||||
if ( autoResolve && !qid.isEmpty() )
|
||||
if ( autoResolve )
|
||||
Pipeline::instance()->resolve( q );
|
||||
return q;
|
||||
}
|
||||
|
@ -127,10 +127,17 @@ Source::setAvatar( const QPixmap& avatar )
|
||||
|
||||
|
||||
QPixmap
|
||||
Source::avatar() const
|
||||
Source::avatar( AvatarStyle style ) const
|
||||
{
|
||||
if( !m_avatar.isNull() )
|
||||
return TomahawkUtils::createAvatarFrame( m_avatar );
|
||||
if ( style == FancyStyle &&
|
||||
!m_avatar.isNull() &&
|
||||
m_fancyAvatar.isNull() )
|
||||
m_fancyAvatar = TomahawkUtils::createAvatarFrame( m_avatar );
|
||||
|
||||
if ( style == Original && !m_avatar.isNull() )
|
||||
return m_avatar;
|
||||
else if ( style == FancyStyle && !m_fancyAvatar.isNull() )
|
||||
return m_fancyAvatar;
|
||||
else
|
||||
return QPixmap();
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ friend class ::DBSyncConnection;
|
||||
friend class ::DatabaseCommand_SocialAction;
|
||||
|
||||
public:
|
||||
enum AvatarStyle { Original, FancyStyle };
|
||||
|
||||
explicit Source( int id, const QString& username = QString() );
|
||||
virtual ~Source();
|
||||
|
||||
@ -58,7 +60,7 @@ public:
|
||||
void setFriendlyName( const QString& fname );
|
||||
|
||||
void setAvatar( const QPixmap& avatar );
|
||||
QPixmap avatar() const;
|
||||
QPixmap avatar( AvatarStyle style = Original ) const;
|
||||
|
||||
collection_ptr collection() const;
|
||||
void addCollection( const Tomahawk::collection_ptr& c );
|
||||
@ -132,6 +134,7 @@ private:
|
||||
ControlConnection* m_cc;
|
||||
|
||||
QPixmap m_avatar;
|
||||
mutable QPixmap m_fancyAvatar;
|
||||
|
||||
Tomahawk::playlistinterface_ptr m_playlistInterface;
|
||||
};
|
||||
|
@ -80,6 +80,13 @@ ProxyStyle::drawControl( ControlElement ce, const QStyleOption* opt, QPainter* p
|
||||
p->setPen( QColor( 0x8c, 0x8c, 0x8c ) );
|
||||
p->drawLine( opt->rect.topLeft(), opt->rect.bottomRight() );
|
||||
}
|
||||
#ifndef Q_WS_MAC
|
||||
else
|
||||
{
|
||||
p->setPen( QColor( 0xff, 0xff, 0xff ) );
|
||||
p->drawLine( opt->rect.topLeft(), opt->rect.bottomRight() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
QProxyStyle::drawControl( ce, opt, p, w );
|
||||
|
101
src/libtomahawk/utils/rdioparser.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "rdioparser.h"
|
||||
|
||||
#include <QUrl>
|
||||
#include <QStringList>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
RdioParser::RdioParser( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_count( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
RdioParser::~RdioParser()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RdioParser::parse( const QString& url )
|
||||
{
|
||||
m_multi = false;
|
||||
m_total = 1;
|
||||
parseUrl( url );
|
||||
}
|
||||
|
||||
void
|
||||
RdioParser::parse( const QStringList& urls )
|
||||
{
|
||||
m_multi = true;
|
||||
m_total = urls.count();
|
||||
|
||||
foreach( const QString& url, urls )
|
||||
parseUrl( url );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RdioParser::parseUrl( const QString& url )
|
||||
{
|
||||
query_ptr query;
|
||||
m_count++;
|
||||
|
||||
if ( url.contains( "artist" ) && url.contains( "album" ) )
|
||||
{
|
||||
// this is a "full" url, no redirection needed
|
||||
QString realUrl = QUrl::fromUserInput( url ).toString().replace( "_", " " );
|
||||
|
||||
QString artist, trk, album;
|
||||
QString matchStr = "/%1/([^/]*)/";
|
||||
QRegExp r( QString( matchStr ).arg( "artist" ) );
|
||||
|
||||
int loc = r.indexIn( realUrl );
|
||||
if ( loc >= 0 )
|
||||
artist = r.cap( 1 );
|
||||
|
||||
r = QRegExp( QString( matchStr ).arg( "album" ) );
|
||||
loc = r.indexIn( realUrl );
|
||||
if ( loc >= 0 )
|
||||
album = r.cap( 1 );
|
||||
|
||||
r = QRegExp( QString( matchStr ).arg( "track" ) );
|
||||
loc = r.indexIn( realUrl );
|
||||
if ( loc >= 0 )
|
||||
trk = r.cap( 1 );
|
||||
|
||||
if ( !trk.isEmpty() && !artist.isEmpty() )
|
||||
{
|
||||
query = Query::get( artist, trk, album, uuid(), true );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_multi )
|
||||
{
|
||||
if ( !query.isNull() )
|
||||
m_queries << query;
|
||||
|
||||
if ( m_count == m_total )
|
||||
emit tracks( m_queries );
|
||||
}
|
||||
if ( !m_multi && !query.isNull() )
|
||||
emit track( query );
|
||||
}
|
||||
|
62
src/libtomahawk/utils/rdioparser.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RDIOPARSER_H
|
||||
#define RDIOPARSER_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QStringList>
|
||||
|
||||
#include "query.h"
|
||||
#include "source.h"
|
||||
|
||||
class QNetworkReply;
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
/**
|
||||
* Small class to parse spotify links into query_ptrs
|
||||
*
|
||||
* Connect to the signals to get the results
|
||||
*/
|
||||
|
||||
class RdioParser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RdioParser( QObject* parent = 0 );
|
||||
virtual ~RdioParser();
|
||||
|
||||
void parse( const QString& url );
|
||||
void parse( const QStringList& urls );
|
||||
|
||||
signals:
|
||||
void track( const Tomahawk::query_ptr& track );
|
||||
void tracks( const QList< Tomahawk::query_ptr > tracks );
|
||||
|
||||
private:
|
||||
void parseUrl( const QString& url );
|
||||
|
||||
bool m_multi;
|
||||
int m_count, m_total;
|
||||
QList< query_ptr > m_queries;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // RDIOPARSER_H
|
@ -44,7 +44,8 @@ ShortenedLinkParser::lengthenUrl( const QString& url )
|
||||
// Whitelisted links
|
||||
if ( !( url.contains( "t.co" ) ||
|
||||
url.contains( "bit.ly" ) ||
|
||||
url.contains( "j.mp" ) ) )
|
||||
url.contains( "j.mp" ) ||
|
||||
url.contains( "rd.io" ) ) )
|
||||
return;
|
||||
|
||||
tDebug() << "Looking up..." << url;
|
||||
|
@ -349,6 +349,46 @@ createDragPixmap( int itemCount )
|
||||
return dragPixmap;
|
||||
}
|
||||
|
||||
void
|
||||
drawBackgroundAndNumbers( QPainter* painter, const QString& text, const QRect& figRectIn )
|
||||
{
|
||||
QRect figRect = figRectIn;
|
||||
if ( text.length() == 1 )
|
||||
figRect.adjust( -painter->fontMetrics().averageCharWidth(), 0, 0, 0 );
|
||||
|
||||
QPen origpen = painter->pen();
|
||||
QPen pen = origpen;
|
||||
pen.setWidth( 1.0 );
|
||||
painter->setPen( pen );
|
||||
painter->drawRect( figRect );
|
||||
|
||||
// circles look bad. make it an oval. (thanks, apple)
|
||||
const int bulgeWidth = 8;
|
||||
const int offset = 0; // number of pixels to begin, counting inwards from figRect.x() and figRect.width(). 0 means start at each end, negative means start inside the rect.
|
||||
|
||||
QPainterPath ppath;
|
||||
ppath.moveTo( QPoint( figRect.x() + offset, figRect.y() + figRect.height() / 2 ) );
|
||||
QRect leftArcRect( figRect.x() + offset - bulgeWidth, figRect.y(), 2*bulgeWidth, figRect.height() );
|
||||
ppath.arcTo( leftArcRect, 90, 180 );
|
||||
painter->drawPath( ppath );
|
||||
|
||||
ppath = QPainterPath();
|
||||
ppath.moveTo( figRect.x() + figRect.width() - offset, figRect.y() + figRect.height() / 2 );
|
||||
leftArcRect = QRect( figRect.x() + figRect.width() - offset - bulgeWidth, figRect.y(), 2*bulgeWidth, figRect.height() );
|
||||
ppath.arcTo( leftArcRect, 270, 180 );
|
||||
painter->drawPath( ppath );
|
||||
|
||||
painter->setPen( origpen );
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
figRect.adjust( -1, 0, 0, 0 );
|
||||
#endif
|
||||
|
||||
QTextOption to( Qt::AlignCenter );
|
||||
painter->setPen( Qt::white );
|
||||
painter->drawText( figRect.adjusted( -5, 0, 6, 0 ), text, to );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
unmarginLayout( QLayout* layout )
|
||||
|
@ -25,9 +25,11 @@
|
||||
#include <QThread>
|
||||
#include <QNetworkProxy>
|
||||
#include <QStringList>
|
||||
#include <QRect>
|
||||
|
||||
#define RESPATH ":/data/"
|
||||
|
||||
class QPainter;
|
||||
class QColor;
|
||||
class QDir;
|
||||
class QDateTime;
|
||||
@ -74,6 +76,8 @@ namespace TomahawkUtils
|
||||
DLLEXPORT QColor alphaBlend( const QColor& colorFrom, const QColor& colorTo, float opacity );
|
||||
DLLEXPORT QPixmap createDragPixmap( int itemCount = 1 );
|
||||
|
||||
DLLEXPORT void drawBackgroundAndNumbers( QPainter* p, const QString& text, const QRect& rect );
|
||||
|
||||
DLLEXPORT void unmarginLayout( QLayout* layout );
|
||||
|
||||
DLLEXPORT NetworkProxyFactory* proxyFactory();
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "widgets/welcomewidget.h"
|
||||
#include "widgets/infowidgets/sourceinfowidget.h"
|
||||
#include "widgets/infowidgets/ArtistInfoWidget.h"
|
||||
#include "widgets/infowidgets/AlbumInfoWidget.h"
|
||||
#include "widgets/newplaylistwidget.h"
|
||||
|
||||
#include "utils/logger.h"
|
||||
@ -79,10 +80,12 @@ ViewManager::ViewManager( QObject* parent )
|
||||
m_infobar = new InfoBar();
|
||||
m_stack = new QStackedWidget();
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
QFrame* line = new QFrame();
|
||||
line->setFrameStyle( QFrame::HLine );
|
||||
line->setStyleSheet( "border: 1px solid gray;" );
|
||||
line->setMaximumHeight( 1 );
|
||||
#endif
|
||||
|
||||
m_splitter = new AnimatedSplitter();
|
||||
m_splitter->setOrientation( Qt::Vertical );
|
||||
@ -100,7 +103,9 @@ ViewManager::ViewManager( QObject* parent )
|
||||
|
||||
m_widget->layout()->addWidget( m_infobar );
|
||||
m_widget->layout()->addWidget( m_topbar );
|
||||
#ifdef Q_OS_MAC
|
||||
m_widget->layout()->addWidget( line );
|
||||
#endif
|
||||
m_widget->layout()->addWidget( m_splitter );
|
||||
|
||||
m_superCollectionView = new ArtistView();
|
||||
@ -237,27 +242,19 @@ ViewManager::show( const Tomahawk::artist_ptr& artist )
|
||||
Tomahawk::ViewPage*
|
||||
ViewManager::show( const Tomahawk::album_ptr& album )
|
||||
{
|
||||
PlaylistView* view;
|
||||
AlbumInfoWidget* swidget;
|
||||
if ( !m_albumViews.contains( album ) )
|
||||
{
|
||||
view = new PlaylistView();
|
||||
PlaylistModel* model = new PlaylistModel();
|
||||
model->append( album );
|
||||
view->setPlaylistModel( model );
|
||||
view->setFrameShape( QFrame::NoFrame );
|
||||
view->setAttribute( Qt::WA_MacShowFocusRect, 0 );
|
||||
|
||||
m_albumViews.insert( album, view );
|
||||
swidget = new AlbumInfoWidget( album );
|
||||
m_albumViews.insert( album, swidget );
|
||||
}
|
||||
else
|
||||
{
|
||||
view = m_albumViews.value( album );
|
||||
swidget = m_albumViews.value( album );
|
||||
}
|
||||
|
||||
setPage( view );
|
||||
emit numSourcesChanged( 1 );
|
||||
|
||||
return view;
|
||||
setPage( swidget );
|
||||
return swidget;
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
class AnimatedSplitter;
|
||||
class AlbumModel;
|
||||
class AlbumView;
|
||||
class AlbumInfoWidget;
|
||||
class ArtistInfoWidget;
|
||||
class ArtistView;
|
||||
class CollectionModel;
|
||||
@ -188,7 +189,7 @@ private:
|
||||
QHash< Tomahawk::collection_ptr, ArtistView* > m_treeViews;
|
||||
QHash< Tomahawk::collection_ptr, AlbumView* > m_collectionAlbumViews;
|
||||
QHash< Tomahawk::artist_ptr, ArtistInfoWidget* > m_artistViews;
|
||||
QHash< Tomahawk::album_ptr, PlaylistView* > m_albumViews;
|
||||
QHash< Tomahawk::album_ptr, AlbumInfoWidget* > m_albumViews;
|
||||
QHash< Tomahawk::playlist_ptr, PlaylistView* > m_playlistViews;
|
||||
QHash< Tomahawk::source_ptr, SourceInfoWidget* > m_sourceViews;
|
||||
|
||||
|
162
src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AlbumInfoWidget.h"
|
||||
#include "ui_AlbumInfoWidget.h"
|
||||
|
||||
#include "viewmanager.h"
|
||||
#include "playlist/treemodel.h"
|
||||
#include "playlist/albummodel.h"
|
||||
|
||||
#include "database/databasecommand_alltracks.h"
|
||||
#include "database/databasecommand_allalbums.h"
|
||||
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#include "widgets/overlaywidget.h"
|
||||
|
||||
static QString s_aiInfoIdentifier = QString( "AlbumInfoWidget" );
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
AlbumInfoWidget::AlbumInfoWidget( const Tomahawk::album_ptr& album, QWidget* parent )
|
||||
: QWidget( parent )
|
||||
, ui( new Ui::AlbumInfoWidget )
|
||||
, m_album( album )
|
||||
{
|
||||
ui->setupUi( this );
|
||||
|
||||
ui->albumsView->setFrameShape( QFrame::NoFrame );
|
||||
ui->albumsView->setAttribute( Qt::WA_MacShowFocusRect, 0 );
|
||||
ui->tracksView->setFrameShape( QFrame::NoFrame );
|
||||
ui->tracksView->setAttribute( Qt::WA_MacShowFocusRect, 0 );
|
||||
|
||||
TomahawkUtils::unmarginLayout( layout() );
|
||||
|
||||
m_albumsModel = new AlbumModel( ui->albumsView );
|
||||
ui->albumsView->setAlbumModel( m_albumsModel );
|
||||
|
||||
m_tracksModel = new TreeModel( ui->tracksView );
|
||||
ui->tracksView->setTreeModel( m_tracksModel );
|
||||
|
||||
m_pixmap = QPixmap( RESPATH "images/no-album-art-placeholder.png" ).scaledToWidth( 48, Qt::SmoothTransformation );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
|
||||
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
|
||||
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
load( album );
|
||||
}
|
||||
|
||||
|
||||
AlbumInfoWidget::~AlbumInfoWidget()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlbumInfoWidget::load( const album_ptr& album )
|
||||
{
|
||||
m_title = album->name();
|
||||
m_description = album->artist()->name();
|
||||
m_tracksModel->addTracks( album, QModelIndex() );
|
||||
|
||||
QList<album_ptr> al;
|
||||
al << album;
|
||||
m_albumsModel->addAlbums( al );
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash trackInfo;
|
||||
trackInfo["artist"] = album->artist()->name();
|
||||
trackInfo["album"] = album->name();
|
||||
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData;
|
||||
requestData.caller = s_aiInfoIdentifier;
|
||||
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
|
||||
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo );
|
||||
requestData.customData = QVariantMap();
|
||||
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlbumInfoWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
|
||||
{
|
||||
if ( requestData.caller != s_aiInfoIdentifier )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InfoSystem::InfoCriteriaHash trackInfo;
|
||||
trackInfo = requestData.input.value< InfoSystem::InfoCriteriaHash >();
|
||||
|
||||
if ( output.canConvert< QVariantMap >() )
|
||||
{
|
||||
if ( trackInfo["album"] != m_album->name() )
|
||||
{
|
||||
qDebug() << "Returned info was for:" << trackInfo["album"] << "- was looking for:" << m_album->name();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap returnedData = output.value< QVariantMap >();
|
||||
switch ( requestData.type )
|
||||
{
|
||||
case Tomahawk::InfoSystem::InfoAlbumCoverArt:
|
||||
{
|
||||
QVariantMap returnedData = output.value< QVariantMap >();
|
||||
const QByteArray ba = returnedData["imgbytes"].toByteArray();
|
||||
if ( ba.length() )
|
||||
{
|
||||
m_pixmap.loadFromData( ba );
|
||||
emit pixmapChanged( m_pixmap );
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlbumInfoWidget::infoSystemFinished( QString target )
|
||||
{
|
||||
Q_UNUSED( target );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlbumInfoWidget::changeEvent( QEvent* e )
|
||||
{
|
||||
QWidget::changeEvent( e );
|
||||
switch ( e->type() )
|
||||
{
|
||||
case QEvent::LanguageChange:
|
||||
ui->retranslateUi( this );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
106
src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.h
Normal file
@ -0,0 +1,106 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \class AlbumInfoWidget
|
||||
* \brief ViewPage, which displays an album for an artist and recommends others.
|
||||
*
|
||||
* This Tomahawk ViewPage displays the tracks of any given album
|
||||
* It is our default ViewPage when showing an artist via ViewManager.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ALBUMINFOWIDGET_H
|
||||
#define ALBUMINFOWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "artist.h"
|
||||
#include "result.h"
|
||||
#include "playlistinterface.h"
|
||||
#include "viewpage.h"
|
||||
#include "infosystem/infosystem.h"
|
||||
|
||||
#include "dllmacro.h"
|
||||
|
||||
class AlbumModel;
|
||||
class TreeModel;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class AlbumInfoWidget;
|
||||
}
|
||||
|
||||
class DLLEXPORT AlbumInfoWidget : public QWidget, public Tomahawk::ViewPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AlbumInfoWidget( const Tomahawk::album_ptr& album, QWidget* parent = 0 );
|
||||
~AlbumInfoWidget();
|
||||
|
||||
/** \brief Loads information for a given album.
|
||||
* \param album The album that you want to load information for.
|
||||
*
|
||||
* Calling this method will make AlbumInfoWidget load information about
|
||||
* an album, and related other albums. This method will be automatically
|
||||
* called by the constructor, but you can use it to load another album's
|
||||
* information at any point.
|
||||
*/
|
||||
void load( const Tomahawk::album_ptr& album );
|
||||
|
||||
virtual QWidget* widget() { return this; }
|
||||
virtual Tomahawk::PlaylistInterface* playlistInterface() const { return 0; }
|
||||
|
||||
virtual QString title() const { return m_title; }
|
||||
virtual QString description() const { return m_description; }
|
||||
virtual QString longDescription() const { return m_longDescription; }
|
||||
virtual QPixmap pixmap() const { if ( m_pixmap.isNull() ) return Tomahawk::ViewPage::pixmap(); else return m_pixmap; }
|
||||
|
||||
virtual bool isTemporaryPage() const { return true; }
|
||||
virtual bool showStatsBar() const { return false; }
|
||||
|
||||
virtual bool jumpToCurrentTrack() { return false; }
|
||||
|
||||
signals:
|
||||
void longDescriptionChanged( const QString& description );
|
||||
void descriptionChanged( const QString& description );
|
||||
void pixmapChanged( const QPixmap& pixmap );
|
||||
|
||||
protected:
|
||||
void changeEvent( QEvent* e );
|
||||
|
||||
private slots:
|
||||
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void infoSystemFinished( QString target );
|
||||
|
||||
private:
|
||||
Ui::AlbumInfoWidget *ui;
|
||||
|
||||
Tomahawk::album_ptr m_album;
|
||||
|
||||
AlbumModel* m_albumsModel;
|
||||
TreeModel* m_tracksModel;
|
||||
|
||||
QString m_title;
|
||||
QString m_description;
|
||||
QString m_longDescription;
|
||||
QPixmap m_pixmap;
|
||||
};
|
||||
|
||||
#endif // ALBUMINFOWIDGET_H
|
55
src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.ui
Normal file
@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AlbumInfoWidget</class>
|
||||
<widget class="QWidget" name="AlbumInfoWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>902</width>
|
||||
<height>696</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="ArtistView" name="tracksView"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="HeaderLabel" name="albumsLabel">
|
||||
<property name="text">
|
||||
<string>Other Albums by Artist</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AlbumView" name="albumsView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>HeaderLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header location="global">widgets/HeaderLabel.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ArtistView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header location="global">artistview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>AlbumView</class>
|
||||
<extends>QListView</extends>
|
||||
<header>playlist/albumview.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -59,6 +59,8 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget*
|
||||
|
||||
m_relatedModel = new TreeModel( ui->relatedArtists );
|
||||
ui->relatedArtists->setTreeModel( m_relatedModel );
|
||||
ui->relatedArtists->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
ui->relatedArtists->header()->setVisible( false );
|
||||
|
||||
m_topHitsModel = new PlaylistModel( ui->topHits );
|
||||
m_topHitsModel->setStyle( TrackModel::Short );
|
||||
@ -72,12 +74,10 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget*
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
// Apparently headers can only be removed when it's already visible / layed-out
|
||||
QTimer::singleShot( 0, this ,SLOT( removeHeaders() ) );
|
||||
|
||||
load( artist );
|
||||
}
|
||||
|
||||
|
||||
ArtistInfoWidget::~ArtistInfoWidget()
|
||||
{
|
||||
delete ui;
|
||||
@ -125,7 +125,6 @@ ArtistInfoWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestD
|
||||
// qDebug() << "Info of wrong type or not with our identifier";
|
||||
return;
|
||||
}
|
||||
qDebug() << Q_FUNC_INFO << requestData.caller << requestData.type << s_aiInfoIdentifier;
|
||||
|
||||
InfoSystem::InfoCriteriaHash trackInfo;
|
||||
trackInfo = requestData.input.value< InfoSystem::InfoCriteriaHash >();
|
||||
@ -207,7 +206,6 @@ void
|
||||
ArtistInfoWidget::infoSystemFinished( QString target )
|
||||
{
|
||||
Q_UNUSED( target );
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
|
||||
@ -225,10 +223,3 @@ ArtistInfoWidget::changeEvent( QEvent* e )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ArtistInfoWidget::removeHeaders()
|
||||
{
|
||||
for ( int i = 1; i < ui->relatedArtists->header()->count(); i++ )
|
||||
ui->relatedArtists->header()->hideSection( ui->relatedArtists->header()->logicalIndex( i ) );
|
||||
}
|
||||
|
@ -90,7 +90,6 @@ private slots:
|
||||
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
|
||||
void infoSystemFinished( QString target );
|
||||
|
||||
void removeHeaders();
|
||||
private:
|
||||
Ui::ArtistInfoWidget *ui;
|
||||
|
||||
@ -106,4 +105,4 @@ private:
|
||||
QPixmap m_pixmap;
|
||||
};
|
||||
|
||||
#endif // SOURCEINFOWIDGET_H
|
||||
#endif // ARTISTINFOWIDGET_H
|
||||
|
@ -51,7 +51,7 @@
|
||||
<item>
|
||||
<widget class="HeaderLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Latest Additions to their Collection</string>
|
||||
<string>Latest Additions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -65,7 +65,7 @@
|
||||
<item>
|
||||
<widget class="HeaderLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Recently played Tracks</string>
|
||||
<string>Recently Played Tracks</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>985</width>
|
||||
<width>729</width>
|
||||
<height>460</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -16,11 +16,6 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enter a title for the new playlist:</string>
|
||||
</property>
|
||||
@ -38,11 +33,6 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Tomahawk offers a variety of ways to help you create playlists and find music you enjoy!</string>
|
||||
</property>
|
||||
@ -53,14 +43,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>13</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Just enter a genre or tag name and Tomahawk will suggest a few songs to get you started with your new playlist:</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "sourcelist.h"
|
||||
#include "viewmanager.h"
|
||||
#include "dynamic/widgets/LoadingSpinner.h"
|
||||
#include "playlist/playlistmodel.h"
|
||||
#include "widgets/overlaywidget.h"
|
||||
|
||||
@ -48,11 +49,13 @@ SearchWidget::SearchWidget( const QString& search, QWidget* parent )
|
||||
ui->resultsView->setFrameShape( QFrame::NoFrame );
|
||||
ui->resultsView->setAttribute( Qt::WA_MacShowFocusRect, 0 );
|
||||
|
||||
ui->resultsView->loadingSpinner()->fadeIn();
|
||||
m_queries << Tomahawk::Query::get( search, uuid() );
|
||||
|
||||
foreach ( const Tomahawk::query_ptr& query, m_queries )
|
||||
{
|
||||
connect( query.data(), SIGNAL( resultsAdded( QList<Tomahawk::result_ptr> ) ), SLOT( onResultsFound( QList<Tomahawk::result_ptr> ) ) );
|
||||
connect( query.data(), SIGNAL( resolvingFinished( bool ) ), SLOT( onQueryFinished() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,9 +94,17 @@ SearchWidget::onResultsFound( const QList<Tomahawk::result_ptr>& results )
|
||||
rl << result;
|
||||
|
||||
Tomahawk::query_ptr q = result->toQuery();
|
||||
q->setResolveFinished( true );
|
||||
q->addResults( rl );
|
||||
qDebug() << result->toString();
|
||||
|
||||
m_resultsModel->append( q );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SearchWidget::onQueryFinished()
|
||||
{
|
||||
ui->resultsView->loadingSpinner()->fadeOut();
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ signals:
|
||||
|
||||
private slots:
|
||||
void onResultsFound( const QList<Tomahawk::result_ptr>& results );
|
||||
void onQueryFinished();
|
||||
|
||||
private:
|
||||
Ui::SearchWidget *ui;
|
||||
|
@ -70,7 +70,13 @@ WelcomePlaylistModel::loadFromSettings()
|
||||
m_recplaylists << pl;
|
||||
|
||||
if( !m_cached.contains( playlist_guids[i] ) )
|
||||
{
|
||||
if ( pl.dynamicCast< DynamicPlaylist >().isNull() )
|
||||
connect( pl.data(), SIGNAL(revisionLoaded(Tomahawk::PlaylistRevision)), this, SLOT(playlistRevisionLoaded()) );
|
||||
else
|
||||
connect( pl.data(), SIGNAL(dynamicRevisionLoaded(Tomahawk::DynamicPlaylistRevision)), this, SLOT(playlistRevisionLoaded()) );
|
||||
m_cached[playlist_guids[i]] = pl;
|
||||
}
|
||||
} else
|
||||
m_waitingForSome = true;
|
||||
}
|
||||
@ -110,21 +116,78 @@ WelcomePlaylistModel::data( const QModelIndex& index, int role ) const
|
||||
|
||||
return m_artists[pl];
|
||||
}
|
||||
case PlaylistTypeRole:
|
||||
{
|
||||
if ( !pl.dynamicCast< Tomahawk::DynamicPlaylist >().isNull() )
|
||||
{
|
||||
dynplaylist_ptr dynp = pl.dynamicCast< Tomahawk::DynamicPlaylist >();
|
||||
if ( dynp->mode() == Static )
|
||||
return AutoPlaylist;
|
||||
else if ( dynp->mode() == OnDemand )
|
||||
return Station;
|
||||
} else
|
||||
{
|
||||
return StaticPlaylist;
|
||||
}
|
||||
}
|
||||
case DynamicPlaylistRole:
|
||||
{
|
||||
dynplaylist_ptr dynp = pl.dynamicCast< Tomahawk::DynamicPlaylist >();
|
||||
return QVariant::fromValue< Tomahawk::dynplaylist_ptr >( dynp );
|
||||
}
|
||||
case TrackCountRole:
|
||||
return pl->entries().count();
|
||||
{
|
||||
if ( !pl.dynamicCast< Tomahawk::DynamicPlaylist >().isNull() && pl.dynamicCast< Tomahawk::DynamicPlaylist >()->mode() == OnDemand )
|
||||
return QString( QChar( 0x221E ) );
|
||||
else
|
||||
return pl->entries().count();
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WelcomePlaylistModel::playlistRevisionLoaded()
|
||||
{
|
||||
Playlist* p = qobject_cast< Playlist* >( sender() );
|
||||
Q_ASSERT( p );
|
||||
|
||||
for ( int i = 0; i < m_recplaylists.size(); i++ )
|
||||
{
|
||||
if ( m_recplaylists[ i ]->guid() == p->guid() )
|
||||
{
|
||||
QModelIndex idx = index( i, 0, QModelIndex() );
|
||||
emit dataChanged( idx, idx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WelcomePlaylistModel::onSourceAdded( const Tomahawk::source_ptr& source )
|
||||
{
|
||||
connect( source.data(), SIGNAL( online() ), this, SLOT( sourceOnline() ) );
|
||||
connect( source->collection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ), SLOT( loadFromSettings() ) );
|
||||
connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ), SLOT( onPlaylistsRemoved( QList<Tomahawk::playlist_ptr> ) ) );
|
||||
}
|
||||
|
||||
void
|
||||
WelcomePlaylistModel::sourceOnline()
|
||||
{
|
||||
Source* s = qobject_cast< Source* >( sender() );
|
||||
Q_ASSERT( s );
|
||||
|
||||
for ( int i = 0; i < m_recplaylists.size(); i++ )
|
||||
{
|
||||
if ( m_recplaylists[ i ]->author().data() == s )
|
||||
{
|
||||
QModelIndex idx = index( i, 0, QModelIndex() );
|
||||
emit dataChanged( idx, idx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WelcomePlaylistModel::onPlaylistsRemoved( QList< playlist_ptr > playlists )
|
||||
|
@ -30,7 +30,9 @@ class WelcomePlaylistModel : public QAbstractListModel
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ItemRoles
|
||||
{ ArtistRole = Qt::UserRole, TrackCountRole, PlaylistRole };
|
||||
{ ArtistRole = Qt::UserRole, TrackCountRole, PlaylistRole, PlaylistTypeRole, DynamicPlaylistRole };
|
||||
enum PlaylistTypes
|
||||
{ StaticPlaylist, AutoPlaylist, Station };
|
||||
|
||||
explicit WelcomePlaylistModel( QObject* parent = 0 );
|
||||
|
||||
@ -49,6 +51,7 @@ private slots:
|
||||
void loadFromSettings();
|
||||
|
||||
void plAdded( const Tomahawk::playlist_ptr& );
|
||||
void playlistRevisionLoaded();
|
||||
|
||||
private:
|
||||
QList< Tomahawk::playlist_ptr > m_recplaylists;
|
||||
@ -57,6 +60,8 @@ private:
|
||||
|
||||
unsigned int m_maxPlaylists;
|
||||
bool m_waitingForSome;
|
||||
public slots:
|
||||
void sourceOnline();
|
||||
};
|
||||
|
||||
#endif // WELCOMEPLAYLISTMODEL_H
|
||||
|
@ -32,9 +32,10 @@
|
||||
#include "widgets/overlaywidget.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
#include <dynamic/GeneratorInterface.h>
|
||||
|
||||
#define HISTORY_TRACK_ITEMS 25
|
||||
#define HISTORY_PLAYLIST_ITEMS 5
|
||||
#define HISTORY_PLAYLIST_ITEMS 10
|
||||
#define HISTORY_RESOLVING_TIMEOUT 2500
|
||||
|
||||
using namespace Tomahawk;
|
||||
@ -70,13 +71,18 @@ WelcomeWidget::WelcomeWidget( QWidget* parent )
|
||||
ui->playlistWidget->setItemDelegate( new PlaylistDelegate() );
|
||||
ui->playlistWidget->setModel( model );
|
||||
ui->playlistWidget->overlay()->resize( 380, 86 );
|
||||
#ifdef Q_OS_MAC
|
||||
ui->playlistWidget->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
|
||||
#endif
|
||||
|
||||
connect( model, SIGNAL( emptinessChanged( bool) ), this, SLOT( updatePlaylists() ) );
|
||||
|
||||
m_tracksModel = new PlaylistModel( ui->tracksView );
|
||||
m_tracksModel->setStyle( TrackModel::Short );
|
||||
m_tracksModel->setStyle( TrackModel::ShortWithAvatars );
|
||||
ui->tracksView->overlay()->setEnabled( false );
|
||||
ui->tracksView->setPlaylistModel( m_tracksModel );
|
||||
ui->tracksView->setHeaderHidden( true );
|
||||
ui->tracksView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
|
||||
m_recentAlbumsModel = new AlbumModel( ui->additionsView );
|
||||
ui->additionsView->setAlbumModel( m_recentAlbumsModel );
|
||||
@ -189,6 +195,7 @@ WelcomeWidget::changeEvent( QEvent* e )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QSize
|
||||
PlaylistDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
@ -217,23 +224,82 @@ PlaylistDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
QTextOption to;
|
||||
to.setAlignment( Qt::AlignCenter );
|
||||
QFont font = opt.font;
|
||||
QFont boldFont = opt.font;
|
||||
#ifdef Q_OS_MAC
|
||||
font.setPointSize( font.pointSize() - 2 );
|
||||
#endif
|
||||
|
||||
QFont boldFont = font;
|
||||
boldFont.setBold( true );
|
||||
QFont italicFont = opt.font;
|
||||
italicFont.setItalic( true );
|
||||
|
||||
painter->drawPixmap( option.rect.adjusted( 10, 13, -option.rect.width() + 48, -13 ), m_playlistIcon );
|
||||
QPixmap icon;
|
||||
WelcomePlaylistModel::PlaylistTypes type = (WelcomePlaylistModel::PlaylistTypes)index.data( WelcomePlaylistModel::PlaylistTypeRole ).toInt();
|
||||
if( type == WelcomePlaylistModel::StaticPlaylist )
|
||||
icon = m_playlistIcon;
|
||||
else if( type == WelcomePlaylistModel::AutoPlaylist )
|
||||
icon = m_autoIcon;
|
||||
else if( type == WelcomePlaylistModel::Station )
|
||||
icon = m_stationIcon;
|
||||
|
||||
painter->drawText( option.rect.adjusted( 56, 26, -100, -8 ), index.data( WelcomePlaylistModel::ArtistRole ).toString() );
|
||||
QRect pixmapRect = option.rect.adjusted( 10, 13, -option.rect.width() + 48, -13 );
|
||||
icon = icon.scaled( pixmapRect.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation );
|
||||
|
||||
QString trackCount = tr( "%1 tracks" ).arg( index.data( WelcomePlaylistModel::TrackCountRole ).toString() );
|
||||
painter->drawText( option.rect.adjusted( option.rect.width() - 96, 12, 0, -2 - opt.rect.height() / 2 ), trackCount, to );
|
||||
painter->drawPixmap( pixmapRect, icon );
|
||||
|
||||
QString author = index.data( WelcomePlaylistModel::PlaylistRole ).value< Tomahawk::playlist_ptr >()->author()->friendlyName();
|
||||
QRect r = option.rect.adjusted( option.rect.width() - 96, 2 + opt.rect.height() / 2, 0, -12);
|
||||
painter->setFont( italicFont );
|
||||
author = painter->fontMetrics().elidedText( author, Qt::ElideRight, r.width() );
|
||||
painter->drawText( r, author, to );
|
||||
QString descText;
|
||||
if ( type == WelcomePlaylistModel::Station )
|
||||
{
|
||||
descText = index.data( WelcomePlaylistModel::DynamicPlaylistRole ).value< Tomahawk::dynplaylist_ptr >()->generator()->sentenceSummary();
|
||||
} else
|
||||
{
|
||||
descText = index.data( WelcomePlaylistModel::ArtistRole ).toString();
|
||||
}
|
||||
QColor c = painter->pen().color();
|
||||
painter->setPen( QColor( Qt::gray ).darker() );
|
||||
QFont font2 = font;
|
||||
#ifdef Q_OS_MAC
|
||||
font2.setPointSize( font2.pointSize() - 1 );
|
||||
#endif
|
||||
painter->setFont( font2 );
|
||||
|
||||
QRect rectText = option.rect.adjusted( 66, 20, -100, -8 );
|
||||
#ifdef Q_OS_MAC
|
||||
rectText.adjust( 0, 1, 0, 0 );
|
||||
#elif Q_OS_WIN
|
||||
rectText.adjust( 0, 2, 0, 0 );
|
||||
#endif
|
||||
|
||||
painter->drawText( rectText, descText );
|
||||
painter->setPen( c );
|
||||
painter->setFont( font );
|
||||
|
||||
if ( type != WelcomePlaylistModel::Station )
|
||||
{
|
||||
painter->save();
|
||||
QString tracks = index.data( WelcomePlaylistModel::TrackCountRole ).toString();
|
||||
int width = painter->fontMetrics().width( tracks );
|
||||
// int bottomEdge = pixmapRect
|
||||
// right edge 10px past right edge of pixmapRect
|
||||
// bottom edge flush with bottom of pixmap
|
||||
QRect rect( pixmapRect.right() - width , 0, width - 8, 0 );
|
||||
rect.adjust( -1, 0, 0, 0 );
|
||||
rect.setTop( pixmapRect.bottom() - painter->fontMetrics().height() - 1 );
|
||||
rect.setBottom( pixmapRect.bottom() + 1 );
|
||||
|
||||
QColor figColor( 153, 153, 153 );
|
||||
painter->setPen( figColor );
|
||||
painter->setBrush( figColor );
|
||||
painter->setFont( boldFont );
|
||||
|
||||
TomahawkUtils::drawBackgroundAndNumbers( painter, tracks, rect );
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
|
||||
QPixmap avatar = index.data( WelcomePlaylistModel::PlaylistRole ).value< Tomahawk::playlist_ptr >()->author()->avatar( Source::FancyStyle );
|
||||
if ( avatar.isNull() )
|
||||
avatar = m_defaultAvatar;
|
||||
QRect r( option.rect.width() - avatar.width() - 10, option.rect.top() + option.rect.height()/2 - avatar.height()/2, avatar.width(), avatar.height() );
|
||||
painter->drawPixmap( r, avatar );
|
||||
|
||||
painter->setFont( boldFont );
|
||||
painter->drawText( option.rect.adjusted( 56, 6, -100, -option.rect.height() + 20 ), index.data().toString() );
|
||||
|
@ -50,6 +50,9 @@ public:
|
||||
PlaylistDelegate()
|
||||
{
|
||||
m_playlistIcon = QPixmap( RESPATH "images/playlist-icon.png" );
|
||||
m_autoIcon = QPixmap( RESPATH "images/automatic-playlist.png" );
|
||||
m_stationIcon = QPixmap( RESPATH "images/station.png" );
|
||||
m_defaultAvatar = TomahawkUtils::createAvatarFrame( QPixmap( RESPATH "images/user-avatar.png" ) );
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -57,7 +60,7 @@ protected:
|
||||
QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
|
||||
private:
|
||||
QPixmap m_playlistIcon;
|
||||
QPixmap m_playlistIcon, m_autoIcon, m_stationIcon, m_defaultAvatar;
|
||||
};
|
||||
|
||||
class DLLEXPORT PlaylistWidget : public QListView
|
||||
|
@ -325,6 +325,12 @@ JabberPlugin::onDisconnect( Jreen::Client::DisconnectReason reason )
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JabberPlugin::onError( const Jreen::Connection::SocketError& e )
|
||||
{
|
||||
tLog() << "JABBER error:" << e;
|
||||
}
|
||||
|
||||
QString
|
||||
JabberPlugin::errorMessage( Jreen::Client::DisconnectReason reason )
|
||||
{
|
||||
|
@ -111,10 +111,7 @@ private slots:
|
||||
void onSubscriptionRequestConfirmed( int result );
|
||||
|
||||
void onNewMessage( const Jreen::Message& message );
|
||||
void onError( const Jreen::Connection::SocketError& e )
|
||||
{
|
||||
qDebug() << e;
|
||||
}
|
||||
void onError( const Jreen::Connection::SocketError& e );
|
||||
void onNewIq( const Jreen::IQ &iq );
|
||||
void onNewAvatar( const QString &jid );
|
||||
void onCheckJidExists( QString jid );
|
||||
|
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
@ -56,7 +58,7 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons
|
||||
connect( ViewManager::instance(), SIGNAL( tempPageActivated( Tomahawk::ViewPage*) ), this, SLOT( tempPageActivated( Tomahawk::ViewPage* ) ) );
|
||||
|
||||
// add misc children of root node
|
||||
GenericPageItem* recent = new GenericPageItem( model(), this, tr( "Recently Played" ), QIcon( RESPATH "images/recently-played.png" ),
|
||||
GenericPageItem* recent = new GenericPageItem( model(), this, tr( "Dashboard" ), QIcon( RESPATH "images/dashboard.png" ),
|
||||
boost::bind( &ViewManager::showWelcomePage, ViewManager::instance() ),
|
||||
boost::bind( &ViewManager::welcomeWidget, ViewManager::instance() )
|
||||
);
|
||||
@ -69,6 +71,7 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons
|
||||
// );
|
||||
// m_coolPlaylistsItem->setSortValue( 200 );
|
||||
|
||||
m_superCol = TomahawkUtils::createAvatarFrame( QPixmap( RESPATH "images/supercollection.png" ) );
|
||||
|
||||
return;
|
||||
}
|
||||
@ -99,6 +102,8 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons
|
||||
if( ViewManager::instance()->pageForCollection( source->collection() ) )
|
||||
model()->linkSourceItemToPage( this, ViewManager::instance()->pageForCollection( source->collection() ) );
|
||||
|
||||
m_defaultAvatar = TomahawkUtils::createAvatarFrame( QPixmap( RESPATH "images/user-avatar.png" ) );
|
||||
|
||||
// load auto playlists and stations!
|
||||
|
||||
connect( source.data(), SIGNAL( stats( QVariantMap ) ), this, SIGNAL( updated() ) );
|
||||
@ -114,6 +119,9 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons
|
||||
SLOT( onAutoPlaylistsAdded( QList<Tomahawk::dynplaylist_ptr> ) ), Qt::QueuedConnection );
|
||||
connect( source->collection().data(), SIGNAL( stationsAdded( QList<Tomahawk::dynplaylist_ptr> ) ),
|
||||
SLOT( onStationsAdded( QList<Tomahawk::dynplaylist_ptr> ) ), Qt::QueuedConnection );
|
||||
|
||||
if ( m_source->isLocal() )
|
||||
QTimer::singleShot(0, this, SLOT(requestExpanding()));
|
||||
}
|
||||
|
||||
|
||||
@ -160,13 +168,13 @@ QIcon
|
||||
CollectionItem::icon() const
|
||||
{
|
||||
if( m_source.isNull() )
|
||||
return QIcon( RESPATH "images/supercollection.png" );
|
||||
return m_superCol;
|
||||
else
|
||||
{
|
||||
if( m_source->avatar().isNull() )
|
||||
return QIcon( RESPATH "images/user-avatar.png" );
|
||||
return m_defaultAvatar;
|
||||
else
|
||||
return QIcon( m_source->avatar() );
|
||||
return m_source->avatar( Source::FancyStyle );
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,6 +349,13 @@ CollectionItem::onStationDeleted( const dynplaylist_ptr& station )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionItem::requestExpanding()
|
||||
{
|
||||
emit expandRequest(this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionItem::tempPageActivated( Tomahawk::ViewPage* v )
|
||||
{
|
||||
|
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
@ -51,6 +53,8 @@ private slots:
|
||||
void onStationsAdded( const QList<Tomahawk::dynplaylist_ptr>& stations );
|
||||
void onStationDeleted( const Tomahawk::dynplaylist_ptr& stations );
|
||||
|
||||
void requestExpanding();
|
||||
|
||||
void tempPageActivated( Tomahawk::ViewPage* );
|
||||
Tomahawk::ViewPage* tempItemClicked();
|
||||
Tomahawk::ViewPage* getTempPage() const;
|
||||
@ -70,6 +74,7 @@ private:
|
||||
void playlistDeletedInternal( SourceTreeItem* parent, const T& playlists );
|
||||
|
||||
Tomahawk::source_ptr m_source;
|
||||
QPixmap m_superCol, m_defaultAvatar;
|
||||
CategoryItem* m_playlists;
|
||||
CategoryItem* m_stations;
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
|
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
|
@ -1,4 +1,7 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
|
@ -1,4 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
|
@ -1,4 +1,6 @@
|
||||
/*
|
||||
Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
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 2 of the License, or
|
||||
@ -33,6 +35,7 @@ SourceTreeItem::SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, Sou
|
||||
connect( this, SIGNAL( childRowsRemoved() ), m_model, SLOT( onItemRowsRemovedDone() ) );
|
||||
connect( this, SIGNAL( updated() ), m_model, SLOT( itemUpdated() ) );
|
||||
connect( this, SIGNAL( selectRequest( SourceTreeItem* ) ), m_model, SLOT( itemSelectRequest( SourceTreeItem* ) ) );
|
||||
connect( this, SIGNAL( expandRequest( SourceTreeItem* ) ), m_model, SLOT( itemExpandRequest( SourceTreeItem* ) ) );
|
||||
if( !m_parent )
|
||||
return;
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
/*
|
||||
Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
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 2 of the License, or
|
||||
@ -63,6 +65,7 @@ public:
|
||||
signals:
|
||||
void updated();
|
||||
void selectRequest( SourceTreeItem* );
|
||||
void expandRequest( SourceTreeItem* );
|
||||
|
||||
void beginChildRowsAdded( int fromRow, int toRow );
|
||||
void childRowsAdded();
|
||||
|
@ -493,3 +493,10 @@ SourcesModel::itemSelectRequest( SourceTreeItem* item )
|
||||
{
|
||||
emit selectRequest( indexFromItem( item ) );
|
||||
}
|
||||
|
||||
void
|
||||
SourcesModel::itemExpandRequest( SourceTreeItem *item )
|
||||
{
|
||||
qDebug() << "expanding source" << indexFromItem( item ) << item;
|
||||
emit expandRequest( indexFromItem( item ) );
|
||||
}
|
||||
|
@ -102,8 +102,11 @@ public slots:
|
||||
void viewPageActivated( Tomahawk::ViewPage* );
|
||||
|
||||
void itemSelectRequest( SourceTreeItem* item );
|
||||
void itemExpandRequest( SourceTreeItem* item );
|
||||
|
||||
signals:
|
||||
void selectRequest( const QModelIndex& idx );
|
||||
void expandRequest( const QModelIndex& idx );
|
||||
|
||||
private slots:
|
||||
void onSourcesAdded( const QList<Tomahawk::source_ptr>& sources );
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -37,8 +37,8 @@ SourcesProxyModel::SourcesProxyModel( SourcesModel* model, QObject* parent )
|
||||
setSourceModel( model );
|
||||
|
||||
|
||||
if ( model && model->metaObject()->indexOfSignal( "trackCountChanged(QModelIndex)" ) > -1 )
|
||||
connect( model, SIGNAL( askForExpand( QModelIndex ) ), this, SLOT( askedToExpand( QModelIndex ) ) );
|
||||
if ( model && model->metaObject()->indexOfSignal( "expandRequest(QModelIndex)" ) > -1 )
|
||||
connect( model, SIGNAL( expandRequest( QModelIndex ) ), this, SLOT( expandRequested( QModelIndex ) ) );
|
||||
if ( model && model->metaObject()->indexOfSignal( "selectRequest(QModelIndex)" ) > -1 )
|
||||
connect( model, SIGNAL( selectRequest( QModelIndex ) ), this, SLOT( selectRequested( QModelIndex ) ) );
|
||||
}
|
||||
@ -73,6 +73,14 @@ SourcesProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourcePar
|
||||
void
|
||||
SourcesProxyModel::selectRequested( const QModelIndex& idx )
|
||||
{
|
||||
qDebug() << "selectRequested for idx" << idx << idx.data(Qt::DisplayRole).toString() << mapFromSource( idx );
|
||||
emit selectRequest( mapFromSource( idx ) );
|
||||
}
|
||||
|
||||
void
|
||||
SourcesProxyModel::expandRequested( const QModelIndex& idx )
|
||||
{
|
||||
qDebug() << "emitting expand for idx" << idx << idx.data(Qt::DisplayRole).toString() << mapFromSource( idx );
|
||||
emit expandRequest( mapFromSource( idx ) );
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -34,9 +34,11 @@ public slots:
|
||||
void showOfflineSources( bool offlineSourcesShown );
|
||||
|
||||
void selectRequested( const QModelIndex& );
|
||||
void expandRequested( const QModelIndex& );
|
||||
|
||||
signals:
|
||||
void selectRequest( const QModelIndex& idx );
|
||||
void expandRequest( const QModelIndex& idx );
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const;
|
||||
|
@ -108,6 +108,7 @@ SourceTreeView::SourceTreeView( QWidget* parent )
|
||||
m_model = new SourcesModel( this );
|
||||
m_proxyModel = new SourcesProxyModel( m_model, this );
|
||||
connect( m_proxyModel, SIGNAL( selectRequest( QModelIndex ) ), this, SLOT( selectRequest( QModelIndex ) ), Qt::QueuedConnection );
|
||||
connect( m_proxyModel, SIGNAL( expandRequest( QModelIndex ) ), this, SLOT( expandRequest( QModelIndex ) ), Qt::QueuedConnection );
|
||||
|
||||
setModel( m_proxyModel );
|
||||
|
||||
@ -246,6 +247,13 @@ SourceTreeView::selectRequest( const QModelIndex& idx )
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceTreeView::expandRequest( const QModelIndex &idx )
|
||||
{
|
||||
qDebug() << "Expanding idx" << idx;
|
||||
expand( idx );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourceTreeView::loadPlaylist()
|
||||
@ -665,34 +673,19 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
|
||||
{
|
||||
painter->setRenderHint( QPainter::Antialiasing );
|
||||
|
||||
QRect figRect = o.rect.adjusted( o.rect.width() - figWidth - 18, 0, -10, -o.rect.height() + 16 );
|
||||
QRect figRect = o.rect.adjusted( o.rect.width() - figWidth - 8, 0, -13, -o.rect.height() + 16 );
|
||||
int hd = ( option.rect.height() - figRect.height() ) / 2;
|
||||
figRect.adjust( 0, hd, 0, hd );
|
||||
#ifdef Q_OS_WIN
|
||||
figRect.adjust( -3, 0, 3, 0 );
|
||||
#endif
|
||||
painter->setFont( bold );
|
||||
|
||||
QColor figColor( 167, 183, 211 );
|
||||
painter->setPen( figColor );
|
||||
painter->setBrush( figColor );
|
||||
|
||||
QPen origpen = painter->pen();
|
||||
QPen pen = origpen;
|
||||
pen.setWidth( 1.0 );
|
||||
painter->setPen( pen );
|
||||
painter->drawRect( figRect );
|
||||
|
||||
QPainterPath ppath;
|
||||
ppath.moveTo( QPoint( figRect.x(), figRect.y() ) );
|
||||
ppath.quadTo( QPoint( figRect.x() - 8, figRect.y() + figRect.height() / 2 ), QPoint( figRect.x(), figRect.y() + figRect.height() ) );
|
||||
painter->drawPath( ppath );
|
||||
ppath.moveTo( QPoint( figRect.x() + figRect.width(), figRect.y() ) );
|
||||
ppath.quadTo( QPoint( figRect.x() + figRect.width() + 8, figRect.y() + figRect.height() / 2 ), QPoint( figRect.x() + figRect.width(), figRect.y() + figRect.height() ) );
|
||||
painter->drawPath( ppath );
|
||||
|
||||
painter->setPen( origpen );
|
||||
|
||||
QTextOption to( Qt::AlignCenter );
|
||||
painter->setFont( bold );
|
||||
painter->setPen( Qt::white );
|
||||
painter->drawText( figRect, tracks, to );
|
||||
TomahawkUtils::drawBackgroundAndNumbers( painter, tracks, figRect );
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
|
@ -49,6 +49,7 @@ private slots:
|
||||
void onItemExpanded( const QModelIndex& idx );
|
||||
void onItemActivated( const QModelIndex& index );
|
||||
void selectRequest( const QModelIndex& idx );
|
||||
void expandRequest( const QModelIndex& idx );
|
||||
|
||||
void loadPlaylist();
|
||||
void deletePlaylist( const QModelIndex& = QModelIndex() );
|
||||
|
@ -124,6 +124,12 @@ TomahawkApp::TomahawkApp( int& argc, char *argv[] )
|
||||
void
|
||||
TomahawkApp::init()
|
||||
{
|
||||
if ( arguments().contains( "--help" ) || arguments().contains( "-h" ) )
|
||||
{
|
||||
printHelp();
|
||||
::exit(0);
|
||||
}
|
||||
|
||||
Logger::setupLogfile();
|
||||
qsrand( QTime( 0, 0, 0 ).secsTo( QTime::currentTime() ) );
|
||||
|
||||
@ -241,6 +247,11 @@ TomahawkApp::init()
|
||||
tDebug() << "Init Scrobbler.";
|
||||
m_scrobbler = new Scrobbler( this );
|
||||
#endif
|
||||
|
||||
if ( arguments().contains( "--filescan" ) )
|
||||
{
|
||||
m_scanManager.data()->runScan( true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -292,6 +303,20 @@ TomahawkApp::instance()
|
||||
return (TomahawkApp*)TOMAHAWK_APPLICATION::instance();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkApp::printHelp()
|
||||
{
|
||||
std::cout << QString( "usage: " + arguments().at( 0 ) + " [options] [url]\n" ).toAscii().data();
|
||||
std::cout << QString( "options are:\n" ).toAscii().data();
|
||||
std::cout << QString( " --help Show this help\n" ).toAscii().data();
|
||||
std::cout << QString( " --http Initialize HTTP server\n" ).toAscii().data();
|
||||
std::cout << QString( " --filescan Scan for files on startup\n" ).toAscii().data();
|
||||
std::cout << QString( " --testdb Use a test database instead of real collection\n" ).toAscii().data();
|
||||
std::cout << QString( " --noupnp Disable UPNP\n" ).toAscii().data();
|
||||
std::cout << QString( " --nosip Disable SIP\n" ).toAscii().data();
|
||||
std::cout << QString( "\nurl is a tomahawk:// command or alternatively a url that Tomahawk can recognize.\n" ).toAscii().data();
|
||||
std::cout << QString( "For more documentation, see http://wiki.tomahawk-player.org/mediawiki/index.php/Tomahawk://_Links\n" ).toAscii().data();
|
||||
}
|
||||
|
||||
#ifndef TOMAHAWK_HEADLESS
|
||||
AudioControls*
|
||||
@ -520,6 +545,8 @@ TomahawkApp::loadUrl( const QString& url )
|
||||
return GlobalActionManager::instance()->parseTomahawkLink( url );
|
||||
else if ( url.contains( "open.spotify.com" ) || url.contains( "spotify:track" ) )
|
||||
return GlobalActionManager::instance()->openSpotifyLink( url );
|
||||
else if ( url.contains( "www.rdio.com" ) )
|
||||
return GlobalActionManager::instance()->openRdioLink( url );
|
||||
else
|
||||
{
|
||||
QFile f( url );
|
||||
|
@ -108,6 +108,8 @@ private slots:
|
||||
private:
|
||||
void registerMetaTypes();
|
||||
|
||||
void printHelp();
|
||||
|
||||
// Start-up order: database, collection, pipeline, servent, http
|
||||
void initDatabase();
|
||||
void initLocalCollection();
|
||||
|
@ -93,6 +93,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent )
|
||||
ui->centralWidget->setContentsMargins( 0, 0, 0, 0 );
|
||||
ui->centralWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
|
||||
ui->centralWidget->layout()->setMargin( 0 );
|
||||
ui->centralWidget->layout()->setSpacing( 0 );
|
||||
|
||||
setupSideBar();
|
||||
setupToolBar();
|
||||
@ -174,6 +175,16 @@ TomahawkWindow::applyPlatformTweaks()
|
||||
#ifdef Q_WS_MAC
|
||||
setUnifiedTitleAndToolBarOnMac( true );
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
ui->hline1->setMaximumHeight( 0 );
|
||||
ui->hline2->setMaximumHeight( 0 );
|
||||
ui->hline1->hide();
|
||||
ui->hline2->hide();
|
||||
#else
|
||||
ui->hline1->setStyleSheet( "border: 1px solid gray;" );
|
||||
ui->hline2->setStyleSheet( "border: 1px solid gray;" );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,6 +15,22 @@
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QFrame" name="hline1">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::HLine</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
@ -27,6 +43,22 @@
|
||||
<widget class="QWidget" name="playlistWidget" native="true"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="hline2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::HLine</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
@ -35,7 +67,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1000</width>
|
||||
<height>22</height>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuSettings">
|
||||
|
@ -47,6 +47,7 @@ TransferView::TransferView( AnimatedSplitter* parent )
|
||||
headers << tr( "Peer" ) << tr( "Rate" ) << tr( "Track" );
|
||||
m_tree->setHeaderLabels( headers );
|
||||
|
||||
m_tree->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
m_tree->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Ignored );
|
||||
m_tree->setColumnCount( 3 );
|
||||
m_tree->setColumnWidth( 0, 80 );
|
||||
@ -58,6 +59,17 @@ TransferView::TransferView( AnimatedSplitter* parent )
|
||||
|
||||
m_tree->setFrameShape( QFrame::NoFrame );
|
||||
m_tree->setAttribute( Qt::WA_MacShowFocusRect, 0 );
|
||||
|
||||
#ifndef Q_WS_WIN
|
||||
QFont f = font();
|
||||
f.setPointSize( f.pointSize() - 1 );
|
||||
setFont( f );
|
||||
#endif
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
f.setPointSize( f.pointSize() - 2 );
|
||||
setFont( f );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|