diff -Nru cantata-1.4.2.ds1/cantata.desktop cantata-1.5.2.ds2/cantata.desktop
--- cantata-1.4.2.ds1/cantata.desktop 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/cantata.desktop 1970-01-01 00:00:00.000000000 +0000
@@ -1,28 +0,0 @@
-[Desktop Entry]
-Type=Application
-Name=Cantata
-GenericName=Music Player Client
-GenericName[bs]=Muzički player klijent
-GenericName[da]=Musik afspiller
-GenericName[de]=Grafischer Musik Player Client
-GenericName[es]=Cliente de reproducción de música
-GenericName[fi]=Musiikkisoitinasiakas
-GenericName[fr]=Client de lecture de musique
-GenericName[gl]=Cliente de reprodución de música
-GenericName[hu]=Zenelejátszókliens
-GenericName[jv]=Musik Player Client
-GenericName[ms]=Klien Pemain Musik
-GenericName[nb]=Musikkavspiller-klient
-GenericName[oc]=Client de lectura de musica
-GenericName[pl]=Odtwarzacz muzyki
-GenericName[pt]=Um reprodutor de música
-GenericName[pt_BR]=Reprodutor Multimídia
-GenericName[ru]=Клиент музыкального проигрывателя
-GenericName[sq]=Clienti player muzike
-GenericName[tr]=Muzik Çalıcı İstemcisi
-Icon=cantata
-Exec=cantata %U
-Categories=Qt;KDE;AudioVideo;Player;
-X-DBUS-StartupType=Unique
-X-DBUS-ServiceName=com.googlecode.cantata
-Keywords=Music;MPD;
diff -Nru cantata-1.4.2.ds1/cantata.desktop.cmake cantata-1.5.2.ds2/cantata.desktop.cmake
--- cantata-1.4.2.ds1/cantata.desktop.cmake 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/cantata.desktop.cmake 2015-03-23 20:09:43.000000000 +0000
@@ -0,0 +1,109 @@
+[Desktop Entry]
+Type=Application
+Name=Cantata
+GenericName=Music Player Client
+GenericName[bs]=Muzički player klijent
+GenericName[da]=Musik afspiller
+GenericName[de]=Grafischer Musik Player Client
+GenericName[es]=Cliente de reproducción de música
+GenericName[fi]=Musiikkisoitinasiakas
+GenericName[fr]=Client de lecture de musique
+GenericName[gl]=Cliente de reprodución de música
+GenericName[hu]=Zenelejátszókliens
+GenericName[jv]=Musik Player Client
+GenericName[ko]=음악 플레이어 클라이언트
+GenericName[ms]=Klien Pemain Musik
+GenericName[nb]=Musikkavspiller-klient
+GenericName[oc]=Client de lectura de musica
+GenericName[pl]=Odtwarzacz muzyki
+GenericName[pt]=Um reprodutor de música
+GenericName[pt_BR]=Reprodutor Multimídia
+GenericName[ru]=Клиент музыкального проигрывателя
+GenericName[sq]=Clienti player muzike
+GenericName[tr]=Muzik Çalıcı İstemcisi
+Icon=cantata
+Exec=cantata %U
+Categories=Qt;KDE;AudioVideo;Player;
+X-DBUS-StartupType=Unique
+X-DBUS-ServiceName=com.googlecode.cantata
+Keywords=Music;MPD;
+Actions=Previous;Play;Pause;Stop;StopAfterCurrent;Next;
+
+[Desktop Action Previous]
+Name=Previous Track
+Name[cs]=Předchozí skladba
+Name[de]=Vorheriges Stück
+Name[es]=Pista anterior
+Name[hu]=Előző szám
+Name[ko]=이전 곡
+Name[pl]=Poprzedni utwór
+Name[ru]=Предыдущий трек
+Name[zh_CN]=上一个
+Exec=@CMAKE_INSTALL_PREFIX@/share/@CMAKE_PROJECT_NAME@/scripts/cantata-remote Previous
+OnlyShowIn=Unity;
+
+[Desktop Action Play]
+Name=Play
+Name[cs]=Přehrát
+Name[de]=Abspielen
+Name[es]=Reproducir
+Name[hu]=Lejátszás
+Name[ko]=연주
+Name[pl]=Odtwarzaj
+Name[ru]=Воспроизвести
+Name[zh_CN]=播放
+Exec=@CMAKE_INSTALL_PREFIX@/share/@CMAKE_PROJECT_NAME@/scripts/cantata-remote Play
+OnlyShowIn=Unity;
+
+[Desktop Action Pause]
+Name=Pause
+Name[cs]=Pozastavit
+Name[de]=Pause
+Name[es]=Pausa
+Name[hu]=Szünet
+Name[ko]=멈춤
+Name[pl]=Wstrzymaj
+Name[ru]=Пауза
+Name[zh_CN]=暂停
+Exec=@CMAKE_INSTALL_PREFIX@/share/@CMAKE_PROJECT_NAME@/scripts/cantata-remote Pause
+OnlyShowIn=Unity;
+
+[Desktop Action Stop]
+Name=Stop
+Name[cs]=Zastavit
+Name[de]=Stopp
+Name[es]=Detener
+Name[hu]=Állj
+Name[ko]=정지
+Name[pl]=Stop
+Name[ru]=Остановить
+Name[zh_CN]=停止
+Exec=@CMAKE_INSTALL_PREFIX@/share/@CMAKE_PROJECT_NAME@/scripts/cantata-remote Stop
+OnlyShowIn=Unity;
+
+[Desktop Action StopAfterCurrent]
+Name=Stop After Current Track
+Name[cs]=Zastavit po současné skladbě
+Name[de]=Stoppe nach Stück
+Name[es]=Detener después de la pista actual
+Name[hu]=A mostani szám után leáll
+Name[ko]=지금 곡 다음 정지
+Name[pl]=Zatrzymaj po obecnym utworze
+Name[ru]=Остановить после текущего трека
+Name[zh_CN]=当前音轨后停止
+Exec=@CMAKE_INSTALL_PREFIX@/share/@CMAKE_PROJECT_NAME@/scripts/cantata-remote StopAfterCurrent
+OnlyShowIn=Unity;
+
+[Desktop Action Next]
+Name=Next Track
+Name[cs]=Další skladba
+Name[de]=Nächstes Stück
+Name[es]=Pista siguiente
+Name[hu]=Következő szám
+Name[ko]=다음 곡
+Name[pl]=Następny utwór
+Name[ru]=Следующий трек
+Name[zh_CN]=下一个
+Exec=@CMAKE_INSTALL_PREFIX@/share/@CMAKE_PROJECT_NAME@/scripts/cantata-remote Next
+OnlyShowIn=Unity;
+
diff -Nru cantata-1.4.2.ds1/cantata_media.qrc cantata-1.5.2.ds2/cantata_media.qrc
--- cantata-1.4.2.ds1/cantata_media.qrc 2014-09-28 16:30:15.000000000 +0000
+++ cantata-1.5.2.ds2/cantata_media.qrc 2015-03-23 20:09:43.000000000 +0000
@@ -1,20 +1,16 @@
icons/media-next-dark.svg
-icons/media-next-rtl-dark.svg
icons/media-pause-dark.svg
icons/media-play-dark.svg
icons/media-play-rtl-dark.svg
icons/media-prev-dark.svg
-icons/media-prev-rtl-dark.svg
icons/media-stop-dark.svg
icons/media-next-light.svg
-icons/media-next-rtl-light.svg
icons/media-pause-light.svg
icons/media-play-light.svg
icons/media-play-rtl-light.svg
icons/media-prev-light.svg
-icons/media-prev-rtl-light.svg
icons/media-stop-light.svg
diff -Nru cantata-1.4.2.ds1/cantata-play-audiocd.desktop cantata-1.5.2.ds2/cantata-play-audiocd.desktop
--- cantata-1.4.2.ds1/cantata-play-audiocd.desktop 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/cantata-play-audiocd.desktop 2015-03-23 20:09:35.000000000 +0000
@@ -7,5 +7,6 @@
[Desktop Action Play]
Name=Play Audio CD with Cantata
Name[de]=Audio CD mit Cantata abspielen
+Name[pl]=Odtwarzaj płytę audio przy użyciu Cantaty
Icon=cantata
Exec=cantata cdda://?dev=%d
diff -Nru cantata-1.4.2.ds1/cantata.qrc cantata-1.5.2.ds2/cantata.qrc
--- cantata-1.4.2.ds1/cantata.qrc 2014-09-28 16:30:15.000000000 +0000
+++ cantata-1.5.2.ds2/cantata.qrc 2015-03-23 20:09:43.000000000 +0000
@@ -1,15 +1,16 @@
scrobbling/lastfm.svg
+icons/stars.svg
icons/view-media-repeat16.png
icons/view-media-repeat22.png
+icons/view-media-repeat24.png
icons/view-media-repeat32.png
-icons/view-media-repeat48.png
icons/view-media-shuffle16.png
icons/view-media-shuffle22.png
+icons/view-media-shuffle24.png
icons/view-media-shuffle32.png
-icons/view-media-shuffle48.png
icons/sidebar-albums-dark.svg
icons/sidebar-artists-dark.svg
@@ -47,19 +48,7 @@
streams/icons/tunein.svg
streams/icons/dirble.svg
-icons/view-media-artist-various16.png
-icons/view-media-artist-various22.png
-icons/view-media-artist-various32.png
-icons/view-media-artist-various48.png
-icons/view-media-artist-various64.png
-icons/view-media-artist-various128.png
icons/view-media-artist-various.svg
-icons/view-media-artist16.png
-icons/view-media-artist22.png
-icons/view-media-artist32.png
-icons/view-media-artist48.png
-icons/view-media-artist64.png
-icons/view-media-artist128.png
icons/view-media-artist.svg
icons/view-radiostream16.png
icons/view-radiostream22.png
diff -Nru cantata-1.4.2.ds1/cantata-remote.cmake cantata-1.5.2.ds2/cantata-remote.cmake
--- cantata-1.4.2.ds1/cantata-remote.cmake 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/cantata-remote.cmake 2015-03-23 20:09:34.000000000 +0000
@@ -0,0 +1,61 @@
+#!/bin/bash
+
+#
+# cantata-remote
+#
+# Copyright (c) 2011-2014 Craig Drummond
+#
+# ----
+#
+# 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
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+#
+# ---------------------------------------------------------------------
+#
+# This shell scrpt is intended to be invoked from the Cantata badge on
+# the unity task bar.
+#
+
+if [ $# -ne 1 ] ; then
+ exit
+fi
+
+service=@PROJECT_REV_URL@
+
+# If we have qdbus use that...
+qt=`which qdbus`
+if [ "$qt" != "" ] ; then
+ $qt $service > /dev/null
+ if [ $? -ne 0 ] ; then
+ # Cantata not started? Try to start...
+ cantata &
+ sleep 1s
+ fi
+ $qt $service /org/mpris/MediaPlayer2 $1 > /dev/null
+ exit
+fi
+
+# No qdbus so try dbus-send...
+dbus=`which dbus-send`
+if [ "$dbus" != "" ] ; then
+ status=`$dbus --print-reply --reply-timeout=250 --type=method_call --session --dest=$service /org/mpris/MediaPlayer2 org.freedesktop.DBus.Peer.Ping 2>&1 | grep "org.freedesktop.DBus.Error.ServiceUnknown" | wc -l`
+ if [ "$status" != "0" ] ; then
+ # Cantata not started? Try to start...
+ cantata &
+ sleep 1s
+ fi
+ dbus-send --type=method_call --session --dest=$service /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.$1
+fi
+
diff -Nru cantata-1.4.2.ds1/ChangeLog cantata-1.5.2.ds2/ChangeLog
--- cantata-1.4.2.ds1/ChangeLog 2014-09-28 16:30:15.000000000 +0000
+++ cantata-1.5.2.ds2/ChangeLog 2015-03-23 20:09:43.000000000 +0000
@@ -1,3 +1,165 @@
+1.5.2
+-----
+ 1. Fix Ubuntu Touch builds.
+ 2. When refreshing search menu, clear items first!
+ 3. Fix setting of cover when existing cover is embedded in music file.
+ 4. Fix OSX executable name for case-sensitive filesystems.
+ 5. Hide ratings widgets, etc, in tag editor for devices and Mopidy, etc.
+ 6. Use Control+Alt+Number as shortcut to toggle an output.
+ 7. Don't allow to set short-cuts for actions that are menus.
+ 8. Add high-dpi support to Linux and Windows Qt5.4 builds.
+ 9. When calculating ReplayGain, if peak value is less than 0.00001 then assume
+ the calculation is invalid.
+10. When parsing podcast RSS, if episode is marked as video (e.g. video/mp4) but
+ the url ends in an audio extension then it is proably an audio podcast.
+11. Correctly initialise seach category.
+12. Fix potential crashes on refresh.
+13. Fix duplicate notification when Cantata is started whilst playing, or when
+ 'Replace Play Queue' is used.
+14. Only show output change notification if outputs menu was not previously
+ empty.
+15. Construct a new config object, rather than changing group, to avoid any
+ race conditions.
+16. If fading volume on stop, then reset volume just before stopping. Some
+ outputs (e.g. pulse audio) only allow setting a volume whilst playing.
+17. If 'url' entry is empty in 'enclosure' section of podcast RSS file, then
+ use 'guid' text as url - if possible.
+18. Fix copying of covers to UMS, etc, devices if song is transcoded.
+19. Add an option for 64 bit non KDE linux builds to install helper apps to
+ lib64 instead of just lib. Pass -DCANTATA_HELPERS_LIB_DIR=lib64 to cmake.
+20. In tag editor, only mark rating as changed if it has been.
+21. For Linux non-KDE builds, use login1 interface to detect system resuming.
+22. Enable scrobble 'love' button even if scrobbling is disabled.
+23. Don't crash when detecting an audio CD with no tracks.
+24. When playing a digitally imported (or JazzRadiom, etc) stream from the
+ favourites section, then modify the URL if the user has a premium account
+ (to match what existing behaviour is stream is played from the station
+ list)
+25. Workaround build issues with SpeexDSP 1.2rc2
+26. Use correct stream icon in playqueue for streams with no song details.
+27. Fix FreeBSD build.
+28. Respect carriage returns when displaying comments in context view.
+29. Fix replaygain calculation when ffmpeg is using planar formats.
+30. Enable 'save' button when reading ratings from multiple files.
+31. Fix cantata-remote script (used for Unity launcher integration) when this
+ uses qdbus.
+32. Fix display of rating in tag dialog when only 1 file is being edited.
+33. Fix fetching of ratings in table style playqueue.
+34. Don't convert -ve track, disc, or years to unsigned - set to 0.
+35. Bundle openSSL libs with windows builds.
+
+1.5.1
+-----
+1. Show correct separators for windows builds.
+2. Supply TagLib 1.9.1 for windows builds.
+3. Convert filename to UTF16 before passing to TagLib for windows builds.
+4. When emiting signal to say cover is loaded, need to adjust size by pixel
+ ratio.
+5. Fix updating of toolbar coverwidget if cover is downloaded after song has
+ started.
+6. Fix compilation when online services disabled.
+7. Fix dynamic playlists with no include rules.
+8. Re-add option to show artist images in tree and list views.
+
+1.5.0.1
+-------
+1. Add missing libtag.dll to windows setup.
+
+1.5.0
+-----
+ 1. Remove cover size setting, set automatically.
+ 2. Artist images only shown in grid view.
+ 3. No images, or icons, shown in basic tree view.
+ 4. Remove GUI option to control saving of scaled covers. This is enabled by
+ default, and can be toggled via the config file.
+ 5. Don't re-load view when sort changes.
+ 6. Simplify view config pages.
+ 7. Use QUrl with server details to build HTTP address used to compare MPD http
+ file paths against.
+ 8. Store song ratings in MPD's sticker DB. Ratings stored using 'rating' key
+ and values 0 to 10. In the UI, ratings are show as 5 stars.
+ 9. If we fail to download a cover, don't keep trying next time song is played.
+10. Simplify toolbar cover widget, no border.
+11. Allow preference dialog to shrink smaller. If screen size is less than
+ 800px, then views page is re-arranged to allow much smaller dialog,
+ category selector uses smaller icons, and headers are removed.. You can
+ check this setting by calling cantata as follows: CANTATA_NETBOOK=1 cantata
+12. Support MPDs "find modified-since" with MPD 0.19 and newer. If a number is
+ entered it is taken to be 'modified since X days in past', otherwise a date
+ should be entered (e.g. 01/12/2001 to find all tracks since 1st Dec 2001)
+ Cantata will first try to convert from your locale date format, default
+ date format, and then ISO date format.
+13. Show covers in search results.
+14. Show performer in cover tooltip if this is set and different to album
+ artist.
+15. Always large action icons for grid view.
+16. Increase gap between add and play icons in grid view.
+17. Disable volume fade on stop by default - this is really something MPD
+ itself should implement.
+18. Remove 'Add albums in random order' from view context menus.
+19. Reorganize playqueue context menu.
+20. Use 'Metadata' and not 'Tags' as metadata/tags view in context song pane.
+21. Minor changes to song progress slider.
+22. Show covers in playlist tree and list views.
+23. Use read-only editable combo for filename in tag editor, so that text can
+ be selected.
+24. Also read /com/canonical/desktop/interface/scrollbar-mode to determine if
+ overlay scrollbars have been disabled.
+25. Add note about 'AlbumArtist' tag to initial settings wizard.
+26. Use QDesktopWidget::logicalDpiX()/96.0 to set DPI scale factor.
+27. Expand ~/ to QDir::homePath() when read from UI.
+28. Save QDir::homePath()/ as ~ in config file, and convert when read.
+29. Allow all bar title and artist columns to be hidden in playqueue.
+30. Add option to disable song info tooltips.
+31. Only show icons in message widget buttons if style uses icons for dialog
+ buttons.
+32. Add option to have separate play queue search action - enabled by default.
+33. Revert back to storing scaled covers as JPG. PNG is taking too much space,
+ especially with retina displays.
+34. Read ArtistSort, AlbumArtistSort, and AlbumSort from MPD. If found, use
+ these to sort items.
+35. Add 'Full Refresh' action - cuases caches to be removed, and models to be
+ completely refreshed.
+36. Add actions to mark podcast as episode as listened or new.
+37. Add action to cancel podcast downloads.
+38. Download podcasts sequentially.
+39. Configurable limit to auto podcast downloading.
+40. When starting, remove any previous partial podcast downloads.
+41. Don't make media keys backend configurable, auto detect the best one.
+42. Remove Gtk combo popup size hack.
+43. Fix Qt5 translations.
+44. Add button to status bar to eanble/disable playback of MPD HTTP output
+ stream.
+45. Show notification when outputs changed.
+46. Connect MPRIS stopAfterCurrent signal to correct action.
+47. Add prev/play/pause/etc actions to Unity launcher, and to windows taskbar
+ entry.
+48. Fix current track highlight in grouped view under windows for header item.
+49. Use same selection drawing for all views.
+50. Fix size of collapsed window in windows builds.
+51. If run under Unity or OSX, then place close buttons on left.
+52. Fix auto-marking of played downloaded podcasts when connected via a local
+ socket.
+53. Fix playback of local files by inbuilt HTTP server.
+54. In catata-tags.exe set unhandled exception handler, to prevent windows
+ crash dialog appearing.
+55. If a command fails to be sent to MPD, and the socket is in an error state,
+ then reconnect and update status and playqueue.
+56. For windows builds, when window is not focused, draw sidebar selection as
+ a darkened background.
+57. If MPD supports https, then there is no need to convert SoundCould URLs.
+58. If playlist is loaded and replaces playqueue, then start playback of first
+ track.
+59. Custom/thin scrollbars for context view.
+60. If fail to read a Gtk setting from DConf then try GSettings.
+61. Send a message (default to 'status') at least once every 30 seconds to keep
+ command connection alive.
+62. Fix inconsistent default cover sizes.
+63. French translation - thanks to Jaussoin Timothée.
+64. Seek 5seconds when control (or command for Mac) and lef/right arrow keys
+ are pressed. (Seek setting may be changed via config file - refer to
+ README for more details.)
+
1.4.2
-----
1. When guessing song details from filename (due to missing tags), remove any
diff -Nru cantata-1.4.2.ds1/cmake/DeployQt5.cmake cantata-1.5.2.ds2/cmake/DeployQt5.cmake
--- cantata-1.4.2.ds1/cmake/DeployQt5.cmake 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/cmake/DeployQt5.cmake 2015-03-23 20:09:32.000000000 +0000
@@ -0,0 +1,350 @@
+# - Functions to help assemble a standalone Qt5 executable.
+# A collection of CMake utility functions useful for deploying
+# Qt5 executables.
+#
+# The following functions are provided by this module:
+# write_qt5_conf
+# resolve_qt5_paths
+# fixup_qt5_executable
+# install_qt5_plugin_path
+# install_qt5_plugin
+# install_qt5_executable
+# Requires CMake 2.6 or greater because it uses function and
+# PARENT_SCOPE. Also depends on BundleUtilities.cmake.
+#
+# WRITE_QT5_CONF( )
+# Writes a qt.conf file with the into .
+#
+# RESOLVE_QT5_PATHS( [])
+# Loop through list and if any don't exist resolve them
+# relative to the (if supplied) or the CMAKE_INSTALL_PREFIX.
+#
+# FIXUP_QT5_EXECUTABLE( [ ])
+# Copies Qt plugins, writes a Qt configuration file (if needed) and fixes up a
+# Qt5 executable using BundleUtilities so it is standalone and can be
+# drag-and-drop copied to another machine as long as all of the system
+# libraries are compatible.
+#
+# should point to the executable to be fixed-up.
+#
+# should contain a list of the names or paths of any Qt plugins
+# to be installed.
+#
+# will be passed to BundleUtilities and should be a list of any already
+# installed plugins, libraries or executables to also be fixed-up.
+#
+# will be passed to BundleUtilities and should contain and directories
+# to be searched to find library dependencies.
+#
+# allows an custom plugins directory to be used.
+#
+# will force a qt.conf file to be written even if not needed.
+#
+# INSTALL_QT5_PLUGIN_PATH(plugin executable copy installed_plugin_path_var )
+# Install (or copy) a resolved to the default plugins directory
+# (or ) relative to and store the result in
+# .
+#
+# If is set to TRUE then the plugins will be copied rather than
+# installed. This is to allow this module to be used at CMake time rather than
+# install time.
+#
+# If is set then anything installed will use this COMPONENT.
+#
+# INSTALL_QT5_PLUGIN(plugin executable copy installed_plugin_path_var )
+# Install (or copy) an unresolved to the default plugins directory
+# (or ) relative to and store the result in
+# . See documentation of INSTALL_QT5_PLUGIN_PATH.
+#
+# INSTALL_QT5_EXECUTABLE( [ ])
+# Installs Qt plugins, writes a Qt configuration file (if needed) and fixes up
+# a Qt5 executable using BundleUtilities so it is standalone and can be
+# drag-and-drop copied to another machine as long as all of the system
+# libraries are compatible. The executable will be fixed-up at install time.
+# is the COMPONENT used for bundle fixup and plugin installation.
+# See documentation of FIXUP_QT5_BUNDLE.
+
+#=============================================================================
+# Copyright 2011 Mike McQuaid
+# Copyright 2013 Mihai Moldovan
+# CMake - Cross Platform Makefile Generator
+# Copyright 2000-2011 Kitware, Inc., Insight Software Consortium
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the names of Kitware, Inc., the Insight Software Consortium,
+# nor the names of their contributors may be used to endorse or promote
+# products derived from this software without specific prior written
+# permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# The functions defined in this file depend on the fixup_bundle function
+# (and others) found in BundleUtilities.cmake
+
+cmake_policy(SET CMP0011 NEW)
+cmake_policy(SET CMP0009 NEW)
+
+include(BundleUtilities)
+set(DeployQt5_cmake_dir "${CMAKE_CURRENT_LIST_DIR}")
+set(DeployQt5_apple_plugins_dir "PlugIns")
+
+function(write_qt5_conf qt_conf_dir qt_conf_contents)
+ set(qt_conf_path "${qt_conf_dir}/qt.conf")
+ message(STATUS "Writing ${qt_conf_path}")
+ file(WRITE "${qt_conf_path}" "${qt_conf_contents}")
+endfunction()
+
+function(resolve_qt5_paths paths_var)
+ set(executable_path ${ARGV1})
+
+ set(paths_resolved)
+ foreach(path ${${paths_var}})
+ if(EXISTS "${path}")
+ list(APPEND paths_resolved "${path}")
+ else()
+ if(${executable_path})
+ list(APPEND paths_resolved "${executable_path}/${path}")
+ else()
+ list(APPEND paths_resolved "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${path}")
+ endif()
+ endif()
+ endforeach()
+ set(${paths_var} ${paths_resolved} PARENT_SCOPE)
+endfunction()
+
+function(fixup_qt5_executable executable)
+ set(qtplugins ${ARGV1})
+ set(libs ${ARGV2})
+ set(dirs ${ARGV3})
+ set(plugins_dir ${ARGV4})
+ set(request_qt_conf ${ARGV5})
+
+ message(STATUS "fixup_qt5_executable")
+ message(STATUS " executable='${executable}'")
+ message(STATUS " qtplugins='${qtplugins}'")
+ message(STATUS " libs='${libs}'")
+ message(STATUS " dirs='${dirs}'")
+ message(STATUS " plugins_dir='${plugins_dir}'")
+ message(STATUS " request_qt_conf='${request_qt_conf}'")
+
+ if(QT_LIBRARY_DIR)
+ list(APPEND dirs "${QT_LIBRARY_DIR}")
+ endif()
+ if(QT_BINARY_DIR)
+ list(APPEND dirs "${QT_BINARY_DIR}")
+ endif()
+
+ if(APPLE)
+ set(qt_conf_dir "${executable}/Contents/Resources")
+ set(executable_path "${executable}")
+ set(write_qt_conf TRUE)
+ if(NOT plugins_dir)
+ set(plugins_dir "${DeployQt5_apple_plugins_dir}")
+ endif()
+ else()
+ get_filename_component(executable_path "${executable}" PATH)
+ if(NOT executable_path)
+ set(executable_path ".")
+ endif()
+ set(qt_conf_dir "${executable_path}")
+ set(write_qt_conf ${request_qt_conf})
+ endif()
+
+ foreach(plugin ${qtplugins})
+ set(installed_plugin_path "")
+ install_qt5_plugin("${plugin}" "${executable}" 1 installed_plugin_path)
+ list(APPEND libs ${installed_plugin_path})
+ endforeach()
+
+ foreach(lib ${libs})
+ if(NOT EXISTS "${lib}")
+ message(FATAL_ERROR "Library does not exist: ${lib}")
+ endif()
+ endforeach()
+
+ resolve_qt5_paths(libs "${executable_path}")
+
+ if(write_qt_conf)
+ set(qt_conf_contents "[Paths]\nPlugins = ${plugins_dir}")
+ write_qt5_conf("${qt_conf_dir}" "${qt_conf_contents}")
+ endif()
+
+ fixup_bundle("${executable}" "${libs}" "${dirs}")
+endfunction()
+
+function(install_qt5_plugin_path plugin executable copy installed_plugin_path_var)
+ set(plugins_dir ${ARGV4})
+ set(component ${ARGV5})
+ set(configurations ${ARGV6})
+ if(EXISTS "${plugin}")
+ if(APPLE)
+ if(NOT plugins_dir)
+ set(plugins_dir "${DeployQt5_apple_plugins_dir}")
+ endif()
+ set(plugins_path "${executable}/Contents/${plugins_dir}")
+ else()
+ get_filename_component(plugins_path "${executable}" PATH)
+ if(NOT plugins_path)
+ set(plugins_path ".")
+ endif()
+ if(plugins_dir)
+ set(plugins_path "${plugins_path}/${plugins_dir}")
+ endif()
+ endif()
+
+ set(plugin_group "")
+
+ get_filename_component(plugin_path "${plugin}" PATH)
+ get_filename_component(plugin_parent_path "${plugin_path}" PATH)
+ get_filename_component(plugin_parent_dir_name "${plugin_parent_path}" NAME)
+ get_filename_component(plugin_name "${plugin}" NAME)
+ string(TOLOWER "${plugin_parent_dir_name}" plugin_parent_dir_name)
+
+ if("${plugin_parent_dir_name}" STREQUAL "plugins")
+ get_filename_component(plugin_group "${plugin_path}" NAME)
+ set(${plugin_group_var} "${plugin_group}")
+ endif()
+ set(plugins_path "${plugins_path}/${plugin_group}")
+
+ if(${copy})
+ file(MAKE_DIRECTORY "${plugins_path}")
+ file(COPY "${plugin}" DESTINATION "${plugins_path}")
+ else()
+ if(configurations AND (CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE))
+ set(configurations CONFIGURATIONS ${configurations})
+ else()
+ unset(configurations)
+ endif()
+ install(FILES "${plugin}" DESTINATION "${plugins_path}" ${configurations} ${component})
+ endif()
+ set(${installed_plugin_path_var} "${plugins_path}/${plugin_name}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(install_qt5_plugin plugin executable copy installed_plugin_path_var)
+ set(plugins_dir ${ARGV4})
+ set(component ${ARGV5})
+ if(EXISTS "${plugin}")
+ install_qt5_plugin_path("${plugin}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}")
+ else()
+ #string(TOUPPER "QT_${plugin}_PLUGIN" plugin_var)
+ set(plugin_release)
+ set(plugin_debug)
+ set(plugin_tmp_path)
+ set(plugin_find_path "${Qt5Core_DIR}/../../../plugins/")
+ get_filename_component(plugin_find_path "${plugin_find_path}" REALPATH)
+ set(plugin_find_release_filename "lib${plugin}.dylib")
+ set(plugin_find_debug_filename "lib${plugin}_debug.dylib")
+ file(GLOB_RECURSE pluginlist "${plugin_find_path}" FOLLOW_SYMLINKS "${plugin_find_path}/*/lib*.dylib")
+ foreach(found_plugin ${pluginlist})
+ get_filename_component(curname "${found_plugin}" NAME)
+ if("${curname}" STREQUAL "${plugin_find_release_filename}")
+ set(plugin_tmp_release_path "${found_plugin}")
+ endif()
+ if("${curname}" STREQUAL "${plugin_find_debug_filename}")
+ set(plugin_tmp_debug_path "${found_plugin}")
+ endif()
+ endforeach()
+
+ if((NOT DEFINED plugin_tmp_release_path OR NOT EXISTS "${plugin_tmp_release_path}") AND (NOT DEFINED plugin_tmp_debug_PATH OR NOT EXISTS "${plugin_tmp_debug_path}"))
+ message(WARNING "Qt plugin \"${plugin}\" not recognized or found.")
+ endif()
+
+ if(EXISTS "${plugin_tmp_release_path}")
+ set(plugin_release "${plugin_tmp_release_path}")
+ elseif(EXISTS "${plugin_tmp_debug_path}")
+ set(plugin_release "${plugin_tmp_debug_path}")
+ endif()
+
+ if(EXISTS "${plugin_tmp_debug_path}")
+ set(plugin_debug "${plugin_tmp_debug_path}")
+ elseif(EXISTS "${plugin_tmp_release_path}")
+ set(plugin_debug "${plugin_tmp_release_path}")
+ endif()
+
+ if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE)
+ install_qt5_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}_release" "${plugins_dir}" "${component}" "Release|RelWithDebInfo|MinSizeRel")
+ install_qt5_plugin_path("${plugin_debug}" "${executable}" "${copy}" "${installed_plugin_path_var}_debug" "${plugins_dir}" "${component}" "Debug")
+
+ if(CMAKE_BUILD_TYPE MATCHES "^Debug$")
+ set(${installed_plugin_path_var} ${${installed_plugin_path_var}_debug})
+ else()
+ set(${installed_plugin_path_var} ${${installed_plugin_path_var}_release})
+ endif()
+ else()
+ install_qt5_plugin_path("${plugin_release}" "${executable}" "${copy}" "${installed_plugin_path_var}" "${plugins_dir}" "${component}")
+ endif()
+ endif()
+ set(${installed_plugin_path_var} ${${installed_plugin_path_var}} PARENT_SCOPE)
+endfunction()
+
+function(install_qt5_executable executable)
+ set(qtplugins ${ARGV1})
+ set(libs ${ARGV2})
+ set(dirs ${ARGV3})
+ set(plugins_dir ${ARGV4})
+ set(request_qt_conf ${ARGV5})
+ set(component ${ARGV6})
+ if(QT_LIBRARY_DIR)
+ list(APPEND dirs "${QT_LIBRARY_DIR}")
+ endif()
+ if(QT_BINARY_DIR)
+ list(APPEND dirs "${QT_BINARY_DIR}")
+ endif()
+ if(component)
+ set(component COMPONENT ${component})
+ else()
+ unset(component)
+ endif()
+
+ get_filename_component(executable_absolute "${executable}" ABSOLUTE)
+ if(EXISTS "${QT_QTCORE_LIBRARY_RELEASE}")
+ gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_RELEASE}" qtcore_type)
+ elseif(EXISTS "${QT_QTCORE_LIBRARY_DEBUG}")
+ gp_file_type("${executable_absolute}" "${QT_QTCORE_LIBRARY_DEBUG}" qtcore_type)
+ endif()
+ if(qtcore_type STREQUAL "system")
+ set(qt_plugins_dir "")
+ endif()
+
+ if(QT_IS_STATIC)
+ message(WARNING "Qt built statically: not installing plugins.")
+ else()
+ foreach(plugin ${qtplugins})
+ message(STATUS "trying to install plugin ${plugin}")
+ set(installed_plugin_paths "")
+ install_qt5_plugin("${plugin}" "${executable}" 0 installed_plugin_paths "${plugins_dir}" "${component}")
+ list(APPEND libs ${installed_plugin_paths})
+ endforeach()
+ endif()
+
+ resolve_qt5_paths(libs "")
+
+ install(CODE
+ "include(\"${DeployQt5_cmake_dir}/DeployQt5.cmake\")
+ set(BU_CHMOD_BUNDLE_ITEMS TRUE)
+ FIXUP_QT5_EXECUTABLE(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${executable}\" \"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")"
+ ${component}
+ )
+endfunction()
diff -Nru cantata-1.4.2.ds1/cmake/FindFoundation.cmake cantata-1.5.2.ds2/cmake/FindFoundation.cmake
--- cantata-1.4.2.ds1/cmake/FindFoundation.cmake 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/cmake/FindFoundation.cmake 2015-03-23 20:09:32.000000000 +0000
@@ -0,0 +1,22 @@
+# - Find Foundation on Mac
+#
+# FOUNDATION_LIBRARY - the library to use Foundation
+# FOUNDATION_FOUND - true if Foundation has been found
+
+# Copyright (c) 2009, Harald Fernengel
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+include(CMakeFindFrameworks)
+
+cmake_find_frameworks(Foundation)
+
+if (Foundation_FRAMEWORKS)
+ set(FOUNDATION_LIBRARY "-framework Foundation" CACHE FILEPATH "Foundation framework" FORCE)
+ set(FOUNDATION_FOUND 1)
+endif (Foundation_FRAMEWORKS)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Foundation DEFAULT_MSG FOUNDATION_LIBRARY)
+
diff -Nru cantata-1.4.2.ds1/cmake/FindIOKit.cmake cantata-1.5.2.ds2/cmake/FindIOKit.cmake
--- cantata-1.4.2.ds1/cmake/FindIOKit.cmake 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/cmake/FindIOKit.cmake 2015-03-23 20:09:32.000000000 +0000
@@ -0,0 +1,23 @@
+# - Find IOKit on Mac
+#
+# IOKIT_LIBRARY - the library to use IOKit
+# IOKIT_FOUND - true if IOKit has been found
+
+# Copyright (c) 2009, Harald Fernengel
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+include(CMakeFindFrameworks)
+
+cmake_find_frameworks(IOKit)
+cmake_find_frameworks(CoreFoundation)
+
+if (IOKit_FRAMEWORKS)
+ set(IOKIT_LIBRARY "-framework IOKit -framework CoreFoundation" CACHE FILEPATH "IOKit framework" FORCE)
+ set(IOKIT_FOUND 1)
+endif (IOKit_FRAMEWORKS)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(IOKit DEFAULT_MSG IOKIT_LIBRARY)
+
diff -Nru cantata-1.4.2.ds1/CMakeLists.txt cantata-1.5.2.ds2/CMakeLists.txt
--- cantata-1.4.2.ds1/CMakeLists.txt 2014-09-28 16:30:10.000000000 +0000
+++ cantata-1.5.2.ds2/CMakeLists.txt 2015-03-23 20:09:38.000000000 +0000
@@ -1,5 +1,20 @@
PROJECT(cantata)
+# NOTE: If PROJECT_URL, or PROJECT_REV_URL, are changed, then cantata-dynamic, and README will need updating.
+# dbus/com.googlecode.cantata.xml and devices/mounter/com.googlecode.cantata.mounter.xml
+# will also need renaming/updating.
+set(PROJECT_URL "cantata.googlecode.com")
+set(PROJECT_REV_URL "com.googlecode.cantata")
+
+if (WIN32)
+ # For some reason I chose mpd as the organization name for Windows builds. So, for config compatability, this is
+ # left as mpd for now...
+ set(ORGANIZATION_NAME "mpd")
+else (WIN32)
+ # Otherwise its set to the same as the project name. Not sure what else to set it to!!!
+ set(ORGANIZATION_NAME ${CMAKE_PROJECT_NAME})
+endif (WIN32)
+
cmake_minimum_required(VERSION 2.6)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
@@ -10,14 +25,15 @@
set(DEBIAN_PACKAGE_SECTION "kde4")
set(CPACK_SOURCE_GENERATOR "TBZ2")
set(CPACK_PACKAGE_VERSION_MAJOR "1")
-set(CPACK_PACKAGE_VERSION_MINOR "4")
+set(CPACK_PACKAGE_VERSION_MINOR "5")
set(CPACK_PACKAGE_VERSION_PATCH "2")
-set(CPACK_PACKAGE_VERSION_SPIN "")
+set(CPACK_PACKAGE_VERSION_SPIN "") # Use ".$number" - e.g. ".1"
set(CPACK_PACKAGE_CONTACT "Craig Drummond ")
set(CANTATA_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}")
set(CANTATA_VERSION_FULL "${CANTATA_VERSION}.${CPACK_PACKAGE_VERSION_PATCH}")
-set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CANTATA_VERSION_FULL}${CPACK_PACKAGE_VERSION_SPIN}")
-set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CANTATA_VERSION_FULL}${CPACK_PACKAGE_VERSION_SPIN}")
+set(CANTATA_VERSION_WITH_SPIN "${CANTATA_VERSION_FULL}${CPACK_PACKAGE_VERSION_SPIN}")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CANTATA_VERSION_WITH_SPIN}")
+set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CANTATA_VERSION_WITH_SPIN}")
set(CPACK_SOURCE_IGNORE_FILES "/.svn/;CMakeLists.txt.user")
include(CPack)
include(MacroLogFeature)
@@ -30,6 +46,7 @@
option(ENABLE_KWALLET "Use KWallet in KDE builds" ON)
option(ENABLE_QT5 "Build against Qt5" OFF)
option(ENABLE_UBUNTU "Build for the Ubuntu SDK" OFF)
+option(ENABLE_UBUNTU_COMMAND_LINE "Build for the Ubuntu SDK from the command line" OFF)
option(ENABLE_FFMPEG "Enable ffmpeg/libav libraries (required for replaygain calculation)" ON)
option(ENABLE_MPG123 "Enable mpg123 libraries (required for replaygain calculation)" ON)
option(ENABLE_PROXY_CONFIG "Enable proxy config in settings dialog" OFF)
@@ -39,12 +56,15 @@
option(ENABLE_STREAMS "Enable support for streams tab (to save favourite streams, and search for others)" ON)
option(ENABLE_ONLINE_SERVICES "Enable support for online services (Jamendo, Magnatune, SoundCloud, and Podcasts)" ON)
if (WIN32 OR APPLE)
- set(USE_SYSTEM_MENU_ICON OFF)
option(ENABLE_DEVICES_SUPPORT "Enable suport for external devices" OFF)
else (WIN32 OR APPLE)
- option(USE_SYSTEM_MENU_ICON "Use system menu icon" ON)
option(ENABLE_DEVICES_SUPPORT "Enable suport for external devices" ON)
endif (WIN32 OR APPLE)
+if (WIN32)
+ set(USE_SYSTEM_MENU_ICON OFF)
+else (WIN32)
+ option(USE_SYSTEM_MENU_ICON "Use system menu icon" ON)
+endif (WIN32)
option(ENABLE_CDPARANOIA "Enable CDParanoia libraries (required for AudioCD support)" ON)
option(ENABLE_CDDB "Enable CDDB libraries (either this or MusicBrianz required for AudioCD support)" ON)
option(ENABLE_MUSICBRAINZ "Enable MusicBrianz libraries (either this or CDDB required for AudioCD support)" ON)
@@ -56,17 +76,29 @@
if (WIN32)
set(CANTATA_ICON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/icons/oxygen)
elseif (APPLE)
+ set(ENABLE_QT5 ON)
set(MACOSX_BUNDLE_BUNDLE_NAME Cantata)
- set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${CANATA_VERSION})
- set(MACOSX_BUNDLE_VERSION ${CANATA_VERSION})
- set(MACOSX_BUNDLE_LONG_VERSION_STRING ${CANTATA_VERSION_FULL})
- set(MACOSX_BUNDLE_ICON_FILE "cantata.icns")
- set(MACOSX_BUNDLE_RESOURCES "${CMAKE_INSTALL_PREFIX}/cantata.app/Contents/Resources")
+ set(MACOSX_BUNDLE_EXECUTABLE cantata)
+ set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${CANTATA_VERSION})
+ set(MACOSX_BUNDLE_VERSION ${CANTATA_VERSION})
+ set(MACOSX_BUNDLE_LONG_VERSION_STRING ${CANTATA_VERSION_WITH_SPIN})
+ set(MACOSX_BUNDLE_ICON_FILE cantata.icns)
+ set(CANTATA_APP_CONTENTS_DIR ${CMAKE_INSTALL_PREFIX}/Cantata.app/Contents)
+ set(MACOSX_BUNDLE_RESOURCES ${CANTATA_APP_CONTENTS_DIR}/Resources)
+ set(MACOSX_BUNDLE_APP_DIR ${CANTATA_APP_CONTENTS_DIR}/MacOS)
set(CANTATA_ICON_INSTALL_PREFIX ${MACOSX_BUNDLE_RESOURCES}/icons/oxygen)
-else (WIN32)
+elseif (NOT ENABLE_UBUNTU)
set(CANTATA_ICON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor)
endif (WIN32)
+if (ENABLE_UBUNTU_COMMAND_LINE)
+ set(ENABLE_UBUNTU ON)
+endif (ENABLE_UBUNTU_COMMAND_LINE)
+
+if (NOT APPLE AND NOT WIN32 AND NOT ENABLE_UBUNTU AND NOT ENABLE_KDE_SUPPORT)
+ set(UNITY_MENU_HACK ON)
+endif (NOT APPLE AND NOT WIN32 AND NOT ENABLE_UBUNTU AND NOT ENABLE_KDE_SUPPORT)
+
if (ENABLE_UBUNTU)
set(ENABLE_QT5 ON)
set(ENABLE_DYNAMIC OFF)
@@ -106,8 +138,20 @@
message("-- Set build type to ${CMAKE_BUILD_TYPE}")
endif (NOT CMAKE_BUILD_TYPE)
+if (NOT APPLE AND NOT WIN32)
+ if (CANTATA_HELPERS_LIB_DIR AND NOT ENABLE_KDE AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(LINUX_LIB_DIR ${CANTATA_HELPERS_LIB_DIR})
+ else (CANTATA_HELPERS_LIB_DIR AND NOT ENABLE_KDE AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(LINUX_LIB_DIR lib)
+ endif (CANTATA_HELPERS_LIB_DIR AND NOT ENABLE_KDE AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+endif (NOT APPLE AND NOT WIN32)
+
if (ENABLE_UBUNTU)
- set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/click")
+ if (ENABLE_UBUNTU_COMMAND_LINE)
+ set(CMAKE_INSTALL_PREFIX click)
+ else (ENABLE_UBUNTU_COMMAND_LINE)
+ set(CMAKE_INSTALL_PREFIX /)
+ endif (ENABLE_UBUNTU_COMMAND_LINE)
elseif (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
if (ENABLE_KDE)
find_program(KDE4_KDECONFIG_EXECUTABLE NAMES kde4-config
@@ -194,7 +238,7 @@
if (ENABLE_FFMPEG)
find_package(FFMPEG)
- macro_log_feature(FFMPEG_FOUND "libavcodec" "ReplayGain calculation." "http://ffmpeg.org")
+ macro_log_feature(FFMPEG_FOUND "libavcodec/libavutil/libavformat" "ReplayGain calculation." "http://ffmpeg.org")
endif (ENABLE_FFMPEG)
if (ENABLE_MPG123)
find_package(MPG123)
@@ -218,15 +262,16 @@
find_package(Qt5Xml REQUIRED)
find_package(Qt5Network REQUIRED)
find_package(Qt5Concurrent REQUIRED)
- find_package(Qt5Svg REQUIRED) # Only actually required for SVG icons...
+ find_package(Qt5Svg REQUIRED)
set(QTCORELIBS ${Qt5Core_LIBRARIES})
set(QTNETWORKLIBS ${Qt5Network_LIBRARIES})
set(QTGUILIBS ${Qt5Gui_LIBRARIES})
- set(QTLIBS ${QTCORELIBS} ${Qt5Widgets_LIBRARIES} ${QTNETWORKLIBS} ${QTGUILIBS} ${Qt5Xml_LIBRARIES} ${Qt5Concurrent_LIBRARIES})
- set(QTINCLUDES ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${Qt5Concurrent_INCLUDE_DIRS})
- add_definitions(${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5Xml_DEFINITIONS} ${Qt5Concurrent_DEFINITIONS})
+ set(QTLIBS ${QTCORELIBS} ${Qt5Widgets_LIBRARIES} ${QTNETWORKLIBS} ${QTGUILIBS} ${Qt5Xml_LIBRARIES} ${Qt5Concurrent_LIBRARIES} ${Qt5Svg_LIBRARIES})
+ set(QTINCLUDES ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${Qt5Concurrent_INCLUDE_DIRS}
+ ${Qt5Svg_INCLUDE_DIRS})
+ add_definitions(${Qt5Widgets_DEFINITIONS} ${Qt5Network_DEFINITIONS} ${Qt5Xml_DEFINITIONS} ${Qt5Concurrent_DEFINITIONS} ${Qt5Svg_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
- if (NOT ENABLE_UBUNTU)
+ if (NOT ENABLE_UBUNTU AND NOT APPLE AND NOT WIN32)
# Does Ubuntu/Touch version need DBus?
find_package(Qt5DBus)
macro_log_feature(Qt5DBus_FOUND "Qt5DBus" "DBus support." "http://qtproject.org")
@@ -236,17 +281,21 @@
set(QTINCLUDES ${QTINCLUDES} ${Qt5DBus_INCLUDE_DIRS})
add_definitions(${Qt5DBus_DEFINITIONS})
endif (Qt5DBus_FOUND)
- endif (NOT ENABLE_UBUNTU)
+ endif (NOT ENABLE_UBUNTU AND NOT APPLE AND NOT WIN32)
if (ENABLE_UBUNTU)
find_package(Qt5Quick REQUIRED)
find_package(Qt5Qml REQUIRED)
endif (ENABLE_UBUNTU)
+ if (APPLE OR WIN32)
+ get_target_property(QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
+ exec_program(${QT_QMAKE_EXECUTABLE} ARGS -query QT_INSTALL_TRANSLATIONS OUTPUT_VARIABLE QT_TRANSLATIONS_DIR)
+ endif (APPLE OR WIN32)
else (ENABLE_QT5)
- find_package(Qt4 REQUIRED QtCore QtGui QtXml QtNetwork QtSvg) # SVG only actually required for SVG icons...
+ find_package(Qt4 REQUIRED QtCore QtGui QtXml QtNetwork QtSvg)
set(QTCORELIBS ${QT_QTCORE_LIBRARY})
set(QTNETWORKLIBS ${QT_QTNETWORK_LIBRARY})
set(QTGUILIBS ${QT_QTGUI_LIBRARY})
- set(QTLIBS ${QT_QTXML_LIBRARY} ${QTCORELIBS} ${QTGUILIBS} ${QTNETWORKLIBS})
+ set(QTLIBS ${QT_QTXML_LIBRARY} ${QTCORELIBS} ${QTGUILIBS} ${QTNETWORKLIBS} ${QT_QTSVG_LIBRARY})
if (QT_QTDBUS_FOUND)
set(QTLIBS ${QTLIBS} ${QT_QTDBUS_LIBRARY})
endif (QT_QTDBUS_FOUND)
@@ -257,14 +306,14 @@
if (ENABLE_HTTP_STREAM_PLAYBACK)
if (ENABLE_LIBVLC)
find_package(LIBVLC REQUIRED)
- macro_log_feature(Qt5Multimedia "libVLC" "MPD HTTP stream playback." "http://videolan.org")
+ macro_log_feature(LIBVLC_FOUND "libVLC" "MPD HTTP stream playback." "http://videolan.org")
add_definitions(-DLIBVLC_FOUND)
include_directories(${LIBVLC_INCLUDE_DIR})
set(CANTATA_LIBS ${CANTATA_LIBS} ${LIBVLC_LIBRARY})
elseif (ENABLE_QT5)
find_package(Qt5Multimedia REQUIRED)
- macro_log_feature(Qt5Multimedia "Qt5Multimedia" "MPD HTTP stream playback." "http://qtproject.org")
- include_directories(${Qt5Multimedia_INCLUDES})
+ macro_log_feature(Qt5Multimedia_FOUND "Qt5Multimedia" "MPD HTTP stream playback." "http://qtproject.org")
+ include_directories(${Qt5Multimedia_INCLUDE_DIRS})
add_definitions(${Qt5Multimedia_DEFINITIONS})
set(CANTATA_LIBS ${CANTATA_LIBS} ${Qt5Multimedia_LIBRARIES})
else (ENABLE_LIBVLC)
@@ -285,6 +334,30 @@
find_package(ZLIB REQUIRED)
+if (APPLE)
+ set(CANTATA_SRCS ${CANTATA_SRCS} mac/dockmenu.cpp mac/macnotify.mm)
+ find_package(IOKit)
+ if (IOKIT_FOUND)
+ set(CANTATA_LIBS ${CANTATA_LIBS} ${IOKIT_LIBRARY})
+ set(CANTATA_SRCS ${CANTATA_SRCS} mac/powermanagement.cpp)
+ set(CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} mac/powermanagement.h)
+ endif (IOKIT_FOUND)
+ find_package(Foundation REQUIRED)
+ set(CANTATA_LIBS ${CANTATA_LIBS} ${FOUNDATION_LIBRARY})
+ find_package(Qt5MacExtras)
+ if (Qt5MacExtras_FOUND)
+ set(QTINCLUDES ${QTINCLUDES} ${Qt5MacExtras_INCLUDE_DIRS})
+ set(QTLIBS ${QTLIBS} ${Qt5MacExtras_LIBRARIES})
+ add_definitions(${Qt5MacExtras_DEFINITIONS})
+ set(QT_MAC_EXTRAS_FOUND 1)
+ endif (Qt5MacExtras_FOUND)
+elseif (WIN32 AND ENABLE_QT5)
+ find_package(Qt5WinExtras REQUIRED)
+ set(QTINCLUDES ${QTINCLUDES} ${Qt5WinExtras_INCLUDE_DIRS})
+ set(QTLIBS ${QTLIBS} ${Qt5WinExtras_LIBRARIES})
+ add_definitions(${Qt5WinExtras_DEFINITIONS})
+ set(CANTATA_SRCS ${CANTATA_SRCS} windows/thumbnailtoolbar.cpp)
+endif (APPLE)
# For Qt5, we use Qt's own QJSonDocument class, so no need to find libqjson
if (NOT ENABLE_QT5 AND NOT WIN32 AND NOT APPLE)
find_package(QJSON)
@@ -339,7 +412,8 @@
models/multimusicmodel.h models/searchmodel.h
mpd/mpdconnection.h mpd/mpdstats.h mpd/mpdstatus.h
network/networkaccessmanager.h
- streams/streamfetcher.h)
+ streams/streamfetcher.h
+ widgets/notelabel.h)
set(CANTATA_SRCS ${CANTATA_CORE_SRCS} ${CANTATA_SRCS}
gui/settings.cpp gui/application.cpp gui/initialsettingswizard.cpp gui/mainwindow.cpp gui/preferencesdialog.cpp
@@ -352,7 +426,8 @@
widgets/volumeslider.cpp widgets/genrecombo.cpp widgets/menubutton.cpp widgets/icons.cpp widgets/toolbutton.cpp widgets/wizardpage.cpp
widgets/statuslabel.cpp widgets/searchwidget.cpp widgets/messageoverlay.cpp widgets/basicitemdelegate.cpp widgets/sizegrip.cpp
widgets/sizewidget.cpp widgets/servicestatuslabel.cpp widgets/spacerwidget.cpp widgets/songdialog.cpp widgets/stretchheaderview.cpp
- widgets/tableview.cpp widgets/thinsplitterhandle.cpp widgets/coverwidget.cpp
+ widgets/tableview.cpp widgets/thinsplitterhandle.cpp widgets/coverwidget.cpp widgets/ratingwidget.cpp widgets/notelabel.cpp
+ widgets/selectorlabel.cpp
context/lyricsettings.cpp context/ultimatelyricsprovider.cpp context/ultimatelyrics.cpp context/lyricsdialog.cpp
context/contextwidget.cpp context/view.cpp context/artistview.cpp context/albumview.cpp context/songview.cpp context/contextengine.cpp
context/wikipediaengine.cpp context/wikipediasettings.cpp context/othersettings.cpp context/contextsettings.cpp context/togglelist.cpp
@@ -360,13 +435,13 @@
scrobbling/scrobbler.cpp scrobbling/pausabletimer.cpp scrobbling/scrobblingsettings.cpp scrobbling/scrobblingstatus.cpp
scrobbling/scrobblinglove.cpp)
set(CANTATA_MOC_HDRS ${CANTATA_CORE_MOC_HDRS} ${CANTATA_MOC_HDRS}
- gui/settings.h gui/initialsettingswizard.h gui/mainwindow.h gui/folderpage.h gui/librarypage.h gui/albumspage.h gui/playlistspage.h
+ gui/initialsettingswizard.h gui/mainwindow.h gui/folderpage.h gui/librarypage.h gui/albumspage.h gui/playlistspage.h
gui/playbacksettings.h gui/serversettings.h gui/preferencesdialog.h gui/interfacesettings.h gui/cachesettings.h gui/trayitem.h
gui/coverdialog.h gui/searchpage.h
widgets/treeview.h widgets/listview.h widgets/itemview.h widgets/autohidingsplitter.h widgets/nowplayingwidget.h widgets/actionlabel.h
widgets/playqueueview.h widgets/groupedview.h widgets/actionitemdelegate.h widgets/volumeslider.h widgets/genrecombo.h
widgets/searchwidget.h widgets/messageoverlay.h widgets/servicestatuslabel.h widgets/stretchheaderview.h widgets/tableview.h
- widgets/coverwidget.h
+ widgets/coverwidget.h widgets/ratingwidget.h widgets/selectorlabel.h
context/togglelist.h context/ultimatelyrics.h context/ultimatelyricsprovider.h context/lyricsdialog.h
context/contextwidget.h context/artistview.h context/albumview.h context/songview.h context/view.h context/contextengine.h
context/wikipediaengine.h context/wikipediasettings.h context/othersettings.h context/lastfmengine.h context/metaengine.h
@@ -398,7 +473,7 @@
# Not installed for windows - script uses sym-links...
elseif (APPLE)
install(PROGRAMS dynamic/cantata-dynamic DESTINATION ${MACOSX_BUNDLE_RESOURCES}/scripts/)
- else (WIN32)
+ elseif (NOT ENABLE_UBUNTU)
install(PROGRAMS dynamic/cantata-dynamic DESTINATION ${CMAKE_INSTALL_PREFIX}/share/${CMAKE_PROJECT_NAME}/scripts)
endif (WIN32)
endif (ENABLE_DYNAMIC)
@@ -454,9 +529,10 @@
if (ENABLE_QT5)
qt5_add_dbus_adaptor(CANTATA_SRCS dbus/org.mpris.MediaPlayer2.Player.xml dbus/mpris.h Mpris)
qt5_add_dbus_adaptor(CANTATA_SRCS dbus/org.mpris.MediaPlayer2.root.xml dbus/mpris.h Mpris)
- qt5_add_dbus_adaptor(CANTATA_SRCS dbus/com.googlecode.cantata.xml gui/mainwindow.h MainWindow)
+ qt5_add_dbus_adaptor(CANTATA_SRCS dbus/${PROJECT_REV_URL}.xml gui/mainwindow.h MainWindow)
qt5_add_dbus_interfaces(CANTATA_SRCS dbus/org.freedesktop.Notifications.xml)
qt5_add_dbus_interfaces(CANTATA_SRCS dbus/org.freedesktop.UPower.xml)
+ qt5_add_dbus_interfaces(CANTATA_SRCS dbus/org.freedesktop.login1.xml)
qt5_add_dbus_interfaces(CANTATA_SRCS dbus/org.gnome.SettingsDaemon.xml)
qt5_add_dbus_interfaces(CANTATA_SRCS dbus/org.gnome.SettingsDaemon.MediaKeys.xml)
qt5_add_dbus_interfaces(CANTATA_SRCS dbus/org.kde.Solid.PowerManagement.PolicyAgent.xml)
@@ -470,10 +546,11 @@
qt4_add_dbus_interfaces(CANTATA_SRCS dbus/org.freedesktop.Notifications.xml)
endif (USE_OLD_DBUS_TYPEDEF OR ((QT_VERSION_MINOR LESS 8) OR (QT_VERSION_MINOR EQUAL 8 AND QT_VERSION_PATCH LESS 2) ))
qt4_add_dbus_adaptor(CANTATA_SRCS dbus/org.mpris.MediaPlayer2.root.xml dbus/mpris.h Mpris)
- qt4_add_dbus_adaptor(CANTATA_SRCS dbus/com.googlecode.cantata.xml gui/mainwindow.h MainWindow)
+ qt4_add_dbus_adaptor(CANTATA_SRCS dbus/${PROJECT_REV_URL}.xml gui/mainwindow.h MainWindow)
if (NOT ENABLE_KDE)
qt4_add_dbus_interfaces(CANTATA_SRCS dbus/org.freedesktop.UPower.xml)
+ qt4_add_dbus_interfaces(CANTATA_SRCS dbus/org.freedesktop.login1.xml)
qt4_add_dbus_interfaces(CANTATA_SRCS dbus/org.gnome.SettingsDaemon.xml)
qt4_add_dbus_interfaces(CANTATA_SRCS dbus/org.gnome.SettingsDaemon.MediaKeys.xml)
endif (NOT ENABLE_KDE)
@@ -488,12 +565,12 @@
endif (NOT WIN32 AND NOT APPLE)
set(CANTATA_RCS cantata.qrc)
-if (NOT WIN32 AND NOT APPLE)
+if (NOT WIN32)
set(CANTATA_RCS ${CANTATA_RCS} cantata_media.qrc)
- if (USE_SYSTEM_MENU_ICON)
- set(CANTATA_RCS ${CANTATA_RCS} cantata_menu.qrc)
- endif (USE_SYSTEM_MENU_ICON)
-endif (NOT WIN32 AND NOT APPLE)
+endif (NOT WIN32)
+if (USE_SYSTEM_MENU_ICON AND NOT WIN32)
+ set(CANTATA_RCS ${CANTATA_RCS} cantata_menu.qrc)
+endif (USE_SYSTEM_MENU_ICON AND NOT WIN32)
if (TAGLIB_FOUND)
set(CANTATA_SRCS ${CANTATA_SRCS} tags/tageditor.cpp tags/trackorganiser.cpp devices/filenameschemedialog.cpp widgets/tagspinbox.cpp)
@@ -503,6 +580,10 @@
# Cantata still links to taglib, even if external tag reader/writer is used, because JamendoService uses taglib for ID3 genres.
set(CANTATA_LIBS ${CANTATA_LIBS} ${TAGLIB_LIBRARIES})
include_directories(${TAGLIB_INCLUDES})
+ if (APPLE)
+ # for some reason under osx we get full path ino include/taglib?
+ include_directories(${TAGLIB_INCLUDES}/..)
+ endif (APPLE)
if (NOT ENABLE_EXTERNAL_TAGS AND TAGLIB-EXTRAS_FOUND)
set(CANTATA_LIBS ${CANTATA_LIBS} ${TAGLIB-EXTRAS_LIBRARIES})
include_directories(${TAGLIB-EXTRAS_INCLUDES})
@@ -585,9 +666,9 @@
devices/remotedevicepropertieswidget.h)
set(CANTATA_UIS ${CANTATA_UIS} devices/remotedevicepropertieswidget.ui)
if (ENABLE_QT5)
- qt5_add_dbus_interfaces(CANTATA_SRCS devices/mounter/com.googlecode.cantata.mounter.xml)
+ qt5_add_dbus_interfaces(CANTATA_SRCS devices/mounter/${PROJECT_REV_URL}.mounter.xml)
else (ENABLE_QT5)
- qt4_add_dbus_interfaces(CANTATA_SRCS devices/mounter/com.googlecode.cantata.mounter.xml)
+ qt4_add_dbus_interfaces(CANTATA_SRCS devices/mounter/${PROJECT_REV_URL}.mounter.xml)
endif (ENABLE_QT5)
add_subdirectory(devices/mounter)
add_subdirectory(devices/avahi)
@@ -657,7 +738,7 @@
endif (WIN32)
set(CANTATA_SRCS ${CANTATA_SRCS} gui/shortcutssettingspage.cpp gui/mediakeys.cpp)
- set(CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} gui/shortcutssettingspage.h gui/multimediakeysinterface.h)
+ set(CANTATA_MOC_HDRS ${CANTATA_MOC_HDRS} gui/multimediakeysinterface.h)
if (ENABLE_QT5)
QT5_ADD_RESOURCES(CANTATA_RC_SRCS ${CANTATA_RCS})
@@ -683,14 +764,21 @@
elseif (APPLE)
ADD_EXECUTABLE(cantata MACOSX_BUNDLE ${CANTATA_SRCS} ${CANTATA_MOC_SRCS} ${CANTATA_RC_SRCS} ${CANTATA_UI_HDRS} ${CANTATA_PO})
add_subdirectory(mac)
- include(DeployQt4)
- INSTALL_QT4_EXECUTABLE("cantata.app" "qjpeg;qsvg;qsvgicon")
- else (WIN32)
+ include(DeployQt5)
+ install(PROGRAMS ${CMAKE_BINARY_DIR}/cantata.app/Contents/MacOS/cantata DESTINATION ${MACOSX_BUNDLE_APP_DIR})
+ # Create our own plist file to enable HighDPI support
+ configure_file(mac/Info.plist.cmake ${CMAKE_CURRENT_BINARY_DIR}/mac/Info.plist)
+ configure_file(mac/dmg/create-dmg.sh.in ${CMAKE_CURRENT_BINARY_DIR}/mac/create-dmg.sh)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mac/Info.plist DESTINATION ${CANTATA_APP_CONTENTS_DIR})
+ install_qt5_executable(cantata.app "qjpeg;qsvg;qsvgicon;qcocoa")
+ elseif (NOT ENABLE_UBUNTU)
ADD_EXECUTABLE(cantata ${CANTATA_SRCS} ${CANTATA_MOC_SRCS} ${CANTATA_RC_SRCS} ${CANTATA_UI_HDRS})
install(TARGETS cantata RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
endif (WIN32)
- set(XDG_APPS_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/applications")
+ if (NOT ENABLE_UBUNTU)
+ set(XDG_APPS_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/applications")
+ endif (NOT ENABLE_UBUNTU)
if (WIN32 OR APPLE)
add_subdirectory(3rdparty/qtsingleapplication)
target_link_libraries(cantata qtsingleapplication)
@@ -712,7 +800,10 @@
install(FILES mpd/mpd.conf.template DESTINATION ${CMAKE_INSTALL_PREFIX}/share/${CMAKE_PROJECT_NAME}/mpd)
endif (WIN32)
-add_subdirectory(po)
+if (NOT ENABLE_UBUNTU)
+ add_subdirectory(po)
+endif (NOT ENABLE_UBUNTU)
+
add_subdirectory(support)
add_subdirectory(3rdparty/qtiocompressor)
target_link_libraries(cantata support-core qtiocompressor ${CANTATA_LIBS} ${QTLIBS} ${ZLIB_LIBRARIES})
@@ -722,7 +813,10 @@
if (UNIX AND NOT APPLE)
if (NOT ENABLE_UBUNTU)
- install(FILES cantata.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
+ configure_file(cantata-remote.cmake ${CMAKE_BINARY_DIR}/cantata-remote)
+ configure_file(cantata.desktop.cmake ${CMAKE_BINARY_DIR}/cantata.desktop)
+ install(PROGRAMS ${CMAKE_BINARY_DIR}/cantata-remote DESTINATION ${CMAKE_INSTALL_PREFIX}/share/${CMAKE_PROJECT_NAME}/scripts)
+ install(FILES ${CMAKE_BINARY_DIR}/cantata.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
endif (NOT ENABLE_UBUNTU)
target_link_libraries(cantata -lpthread)
endif (UNIX AND NOT APPLE)
@@ -742,6 +836,8 @@
macro_display_feature_log()
if (ENABLE_UBUNTU)
+ set(UBUNTU_PROJECT_TYPE "ClickApp" CACHE INTERNAL "Tells QtCreator this is a Click application project")
+
add_custom_target(components_QmlFiles ALL SOURCES
ubuntu/qml/cantata/main.qml ubuntu/qml/cantata/AboutPage.qml ubuntu/qml/cantata/ListViewPage.qml
ubuntu/qml/cantata/SubListViewPage.qml ubuntu/qml/cantata/CurrentlyPlayingPage.qml
@@ -752,18 +848,19 @@
ubuntu/qml/cantata/components/ControlButtonsRow.qml ubuntu/qml/cantata/components/ListItemDelegate.qml
ubuntu/qml/cantata/components/PlayQueueListItemDelegate.qml ubuntu/qml/cantata/components/LabelVisual.qml
ubuntu/qml/cantata/components/Notification.qml ubuntu/qml/cantata/backend/SettingsBackend.qml
+ ubuntu/qml/cantata/components/PageWithBottomEdge.qml ubuntu/qml/cantata/CurrentlyPlayingContent.qml
+ )
+ add_custom_target(click_files ALL SOURCES
+ ubuntu/manifest.json
+ ubuntu/cantata-ubuntu.json
+ ubuntu/cantata-ubuntu.desktop
+ )
+ add_custom_target(images ALL SOURCES #TODO: Add other icons
+ ubuntu/icons/desktop/cantata.png
)
- # click package...
- set(UBUNTU_CLICK_FOLDER ${CMAKE_BINARY_DIR}/click/)
- file(MAKE_DIRECTORY ${UBUNTU_CLICK_FOLDER})
- # Hard link target into click folder
- add_custom_command(TARGET cantata COMMAND ln ARGS -f ${CMAKE_BINARY_DIR}/cantata ${UBUNTU_CLICK_FOLDER})
- # Hard link other files required for package
- set(UBUNTU_EXTRA ubuntu/manifest.json ubuntu/cantata-ubuntu.json ubuntu/cantata-ubuntu.desktop /ubuntu/icons/desktop/cantata.png)
- foreach (extraFile ${UBUNTU_EXTRA})
- add_custom_command(TARGET cantata COMMAND ln ARGS -f ${CMAKE_SOURCE_DIR}/${extraFile} ${UBUNTU_CLICK_FOLDER})
- endforeach (extraFile ${UBUNTU_EXTRA})
+ install(TARGETS cantata RUNTIME DESTINATION .)
+ install(FILES ubuntu/manifest.json ubuntu/cantata-ubuntu.json ubuntu/cantata-ubuntu.desktop ubuntu/icons/desktop/cantata.png DESTINATION .)
else (ENABLE_UBUNTU)
if (NOT ENABLE_STREAMS OR NOT ENABLE_DYNAMIC OR NOT ENABLE_ONLINE_SERVICES OR (NOT ENABLE_DEVICES_SUPPORT AND NOT WIN32 AND NOT APPLE))
diff -Nru cantata-1.4.2.ds1/config.h.cmake cantata-1.5.2.ds2/config.h.cmake
--- cantata-1.4.2.ds1/config.h.cmake 2014-09-28 16:30:21.000000000 +0000
+++ cantata-1.5.2.ds2/config.h.cmake 2015-03-23 20:09:47.000000000 +0000
@@ -5,15 +5,11 @@
#include "support/utils.h"
#define CANTATA_MAKE_VERSION(a, b, c) (((a) << 16) | ((b) << 8) | (c))
-/*
- NOTE: If CANTATA_REV_URL, or CANTATA_URL, are changed, then cantata-dynamac,
- CMakeLists.txt, README, and cantata.desktop will need updating.
- dbus/com.googlecode.cantata.xml will also need renaming/updating.
-*/
#define PACKAGE_NAME "@PROJECT_NAME@"
+#define ORGANIZATION_NAME "@ORGANIZATION_NAME@"
#define PACKAGE_VERSION CANTATA_MAKE_VERSION(@CPACK_PACKAGE_VERSION_MAJOR@, @CPACK_PACKAGE_VERSION_MINOR@, @CPACK_PACKAGE_VERSION_PATCH@)
#define PACKAGE_STRING PACKAGE_NAME" @CANTATA_VERSION_FULL@"
-#define PACKAGE_VERSION_STRING "@CANTATA_VERSION_FULL@"
+#define PACKAGE_VERSION_STRING "@CANTATA_VERSION_WITH_SPIN@"
#define INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
#cmakedefine ENABLE_DEVICES_SUPPORT 1
@@ -44,13 +40,16 @@
#cmakedefine ENABLE_MODEL_TEST 1
#cmakedefine USE_SYSTEM_MENU_ICON 1
#cmakedefine ENABLE_UBUNTU 1
+#cmakedefine IOKIT_FOUND 1
+#cmakedefine QT_MAC_EXTRAS_FOUND 1
+#cmakedefine UNITY_MENU_HACK 1
#ifdef ENABLE_UBUNTU
-#define CANTATA_REV_URL "com.ubuntu.developer.nikwen.cantata-touch" //Sadly, it requires the com.ubuntu.developer.nikwen prefix to be published to the click store
+#define CANTATA_REV_URL "com.ubuntu.developer.nikwen.cantata-touch-reboot" //Sadly, it requires the com.ubuntu.developer.nikwen prefix to be published to the click store
#else
-#define CANTATA_REV_URL "com.googlecode.cantata"
+#define CANTATA_REV_URL "@PROJECT_REV_URL@"
#endif
-#define CANTATA_URL "cantata.googlecode.com"
+#define CANTATA_URL "@PROJECT_URL@"
#define CANTATA_SYS_CONFIG_DIR Utils::systemDir(QLatin1String("config"))
#define CANTATA_SYS_ICONS_DIR Utils::systemDir(QLatin1String("icons"))
@@ -58,4 +57,16 @@
#define CANTATA_SYS_TRANS_DIR Utils::systemDir(QLatin1String("translations"))
#define CANTATA_SYS_SCRIPTS_DIR Utils::systemDir(QLatin1String("scripts"))
+#ifdef UNITY_MENU_HACK
+#define HIDE_MENU_ICON(A) menuIcons ? A : Icon()
+#define HIDE_MENU_ICON_NAME(A) menuIcons ? A : 0
+#define UNITY_MENU_ICON_CHECK bool menuIcons=Utils::Unity!=Utils::currentDe() && !QCoreApplication::testAttribute(Qt::AA_DontShowIconsInMenus);
+#else
+#define HIDE_MENU_ICON(A) A
+#define HIDE_MENU_ICON_NAME(A) A
+#define UNITY_MENU_ICON_CHECK
+#endif
+
+#define LINUX_LIB_DIR "@LINUX_LIB_DIR@"
+
#endif
diff -Nru cantata-1.4.2.ds1/context/contextwidget.cpp cantata-1.5.2.ds2/context/contextwidget.cpp
--- cantata-1.4.2.ds1/context/contextwidget.cpp 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/context/contextwidget.cpp 2015-03-23 20:09:41.000000000 +0000
@@ -209,7 +209,7 @@
setChildrenCollapsible(true);
setOrientation(Qt::Horizontal);
resetAct=new QAction(i18n("Reset Spacing"), this);
- connect(resetAct, SIGNAL(triggered(bool)), this, SLOT(reset()));
+ connect(resetAct, SIGNAL(triggered()), this, SLOT(reset()));
setHandleWidth(0);
}
diff -Nru cantata-1.4.2.ds1/context/onlineview.cpp cantata-1.5.2.ds2/context/onlineview.cpp
--- cantata-1.4.2.ds1/context/onlineview.cpp 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/context/onlineview.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -22,7 +22,7 @@
*/
#include "onlineview.h"
-#include "models/onlineservicesmodel.h"
+#include "gui/covers.h"
#include "support/localize.h"
OnlineView::OnlineView(QWidget *p)
@@ -42,7 +42,7 @@
return;
}
setHeader(song.describe(true));
- Covers::Image cImg=OnlineServicesModel::self()->readImage(song);
+ Covers::Image cImg=Covers::self()->requestImage(song, true);
if (!cImg.img.isNull()) {
setHtml(createPicTag(cImg.img, cImg.fileName));
} else {
diff -Nru cantata-1.4.2.ds1/context/othersettings.cpp cantata-1.5.2.ds2/context/othersettings.cpp
--- cantata-1.4.2.ds1/context/othersettings.cpp 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/context/othersettings.cpp 2015-03-23 20:09:41.000000000 +0000
@@ -66,7 +66,7 @@
contextBackdrop_custom->setChecked(bgnd==contextBackdrop_custom->property(constValueProperty).toInt());
contextBackdropOpacity->setValue(Settings::self()->contextBackdropOpacity());
contextBackdropBlur->setValue(Settings::self()->contextBackdropBlur());
- contextBackdropFile->setText(Settings::self()->contextBackdropFile());
+ contextBackdropFile->setText(Utils::convertPathForDisplay(Settings::self()->contextBackdropFile(), false));
contextSwitchTime->setValue(Settings::self()->contextSwitchTime());
toggleWikiNote();
@@ -90,7 +90,7 @@
}
Settings::self()->saveContextBackdropOpacity(contextBackdropOpacity->value());
Settings::self()->saveContextBackdropBlur(contextBackdropBlur->value());
- Settings::self()->saveContextBackdropFile(contextBackdropFile->text().trimmed());
+ Settings::self()->saveContextBackdropFile(Utils::convertPathFromDisplay(contextBackdropFile->text(), false));
Settings::self()->saveContextSwitchTime(contextSwitchTime->value());
}
diff -Nru cantata-1.4.2.ds1/context/othersettings.ui cantata-1.5.2.ds2/context/othersettings.ui
--- cantata-1.4.2.ds1/context/othersettings.ui 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/context/othersettings.ui 2015-03-23 20:09:41.000000000 +0000
@@ -203,7 +203,7 @@
Always collapse into a single pane
- Only show 'Artist', 'Album', or 'Lyrics' even if sufficient width to show all three.
+ Only show 'Artist', 'Album', or 'Track' even if sufficient width to show all three.
@@ -214,45 +214,14 @@
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 8
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
+ -
+
- <i><b>NOTE:</b> Cantata does not show the full wikipedia pages (with images, links, etc), instead it shows a trimmed down version. This trimming is not always 100% accurate, hence by default Cantata will only show the basic introduction to each article. If you elect to show the full article, then there may be parsing errors. You will also need to remove any currently cached articles (using the 'Cache' page).</i>
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- true
-
-
- Qt::NoTextInteraction
+ Cantata only shows a trimmed down version of wikipedia pages (no images, links, etc). This trimming is not always 100% accurate, which is why Cantata defaults to only showing the introduction. If you elect to show the full article, then there may be parsing errors. You will also need to remove any currently cached articles (using the 'Cache' page).
- -
+
-
Qt::Vertical
@@ -277,9 +246,9 @@
- StateLabel
+ NoteLabel
QLabel
-
+
PathRequester
diff -Nru cantata-1.4.2.ds1/context/songview.cpp cantata-1.5.2.ds2/context/songview.cpp
--- cantata-1.4.2.ds1/context/songview.cpp 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/context/songview.cpp 2015-03-23 20:09:41.000000000 +0000
@@ -121,7 +121,7 @@
}
SongView::SongView(QWidget *p)
- : View(p, QStringList() << i18n("Lyrics") << i18n("Information") << i18n("Tags"))
+ : View(p, QStringList() << i18n("Lyrics") << i18n("Information") << i18n("Metadata"))
, scrollTimer(0)
, songPos(0)
, currentProvider(-1)
@@ -131,7 +131,7 @@
, currentProv(0)
, lyricsNeedsUpdating(true)
, infoNeedsUpdating(true)
- , tagsNeedsUpdating(true)
+ , metadataNeedsUpdating(true)
{
scrollAction = ActionCollection::get()->createAction("scrolllyrics", i18n("Scroll Lyrics"), "go-down");
refreshAction = ActionCollection::get()->createAction("refreshlyrics", i18n("Refresh Lyrics"), "view-refresh");
@@ -361,10 +361,10 @@
return;
}
switch (currentView()) {
- case Page_Lyrics: loadLyrics(); break;
- case Page_Information: loadInfo(); break;
- case Page_Tags: loadTags(); break;
- default: break;
+ case Page_Lyrics: loadLyrics(); break;
+ case Page_Information: loadInfo(); break;
+ case Page_Metadata: loadMetadata(); break;
+ default: break;
}
}
@@ -450,9 +450,14 @@
searchForInfo();
}
+static inline QString fixNewLine(QString s)
+{
+ return s.replace(QLatin1String("\n"), QLatin1String(" "));
+}
+
static QString createRow(const QString &key, const QString &value)
{
- return value.isEmpty() ? QString() : QString("%1: %2 ").arg(key).arg(value);
+ return value.isEmpty() ? QString() : QString("%1: %2 ").arg(key).arg(fixNewLine(value));
}
struct MapEntry {
@@ -461,6 +466,7 @@
QString str;
};
+#ifdef TAGLIB_FOUND
static QString clean(QString v)
{
if (v.length()>1) {
@@ -469,13 +475,14 @@
}
return v;
}
+#endif
-void SongView::loadTags()
+void SongView::loadMetadata()
{
- if (!tagsNeedsUpdating) {
+ if (!metadataNeedsUpdating) {
return;
}
- tagsNeedsUpdating=false;
+ metadataNeedsUpdating=false;
QMultiMap tags;
QMultiMap audioProperties;
@@ -553,6 +560,22 @@
}
#endif
+ int audioPos=1024;
+ if (audioProperties.isEmpty()) {
+ if (MPDStatus::self()->bitrate()>0) {
+ audioProperties.insert(audioPos++, createRow(i18n("Bitrate"), i18n("%1 kb/s", MPDStatus::self()->bitrate())));
+ }
+ if (MPDStatus::self()->samplerate()>0) {
+ audioProperties.insert(audioPos++, createRow(i18n("Sample rate"), i18n("%1 Hz", MPDStatus::self()->samplerate())));
+ }
+ if (MPDStatus::self()->channels()>0) {
+ audioProperties.insert(audioPos++, createRow(i18n("Channels"), QString::number(MPDStatus::self()->channels())));
+ }
+ }
+ if (MPDStatus::self()->bits()>0) {
+ audioProperties.insert(audioPos++, createRow(i18n("Bits"), QString::number(MPDStatus::self()->bits())));
+ }
+
if (tags.isEmpty()) {
int pos=0;
tags.insert(pos++, createRow(i18n("Artist"), currentSong.artist));
@@ -564,7 +587,7 @@
tags.insert(pos++, createRow(i18n("Disc number"), 0==currentSong.disc ? QString() : QString::number(currentSong.disc)));
tags.insert(pos++, createRow(i18n("Genre"), currentSong.genres().join(", ")));
tags.insert(pos++, createRow(i18n("Year"), 0==currentSong.track ? QString() : QString::number(currentSong.year)));
- tags.insert(pos++, createRow(i18n("Comment"), currentSong.comment()));
+ tags.insert(pos++, createRow(i18n("Comment"), fixNewLine(currentSong.comment())));
}
QString tagInfo;
@@ -593,11 +616,21 @@
}
}
}
- if (!tagInfo.isEmpty()) {
- tagInfo+=QLatin1String("");
+ if (tagInfo.isEmpty()) {
+ tagInfo=QLatin1String("");
+ } else {
+ tagInfo+=QLatin1String(" ");
+ }
+ if (MPDConnection::self()->getDetails().dirReadable) {
+ QString path=Utils::getDir(MPDConnection::self()->getDetails().dir+currentSong.filePath());
+ tagInfo+=createRow(i18n("Filename"), QLatin1String("")+
+ currentSong.filePath()+QLatin1String(" "));
+ } else {
+ tagInfo+=createRow(i18n("Filename"), currentSong.filePath());
}
+ tagInfo+=QLatin1String("
");
- setHtml(tagInfo, Page_Tags);
+ setHtml(tagInfo, Page_Metadata);
}
void SongView::refreshInfo()
@@ -684,7 +717,7 @@
{
if (s.isEmpty() || s.title.isEmpty() || s.artist.isEmpty()) {
currentSong=s;
- infoNeedsUpdating=tagsNeedsUpdating=lyricsNeedsUpdating=false;
+ infoNeedsUpdating=metadataNeedsUpdating=lyricsNeedsUpdating=false;
clear();
abort();
return;
@@ -722,7 +755,7 @@
currentProvider=-1;
}
- infoNeedsUpdating=tagsNeedsUpdating=lyricsNeedsUpdating=true;
+ infoNeedsUpdating=metadataNeedsUpdating=lyricsNeedsUpdating=true;
setHeader(song.title);
curentViewChanged();
}
diff -Nru cantata-1.4.2.ds1/context/songview.h cantata-1.5.2.ds2/context/songview.h
--- cantata-1.4.2.ds1/context/songview.h 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/context/songview.h 2015-03-23 20:09:41.000000000 +0000
@@ -47,7 +47,7 @@
enum Pages {
Page_Lyrics,
Page_Information,
- Page_Tags
+ Page_Metadata
};
public:
@@ -88,7 +88,7 @@
private:
void loadLyrics();
void loadInfo();
- void loadTags();
+ void loadMetadata();
void searchForInfo();
void hideSpinner();
void abort();
@@ -128,7 +128,7 @@
bool lyricsNeedsUpdating;
bool infoNeedsUpdating;
- bool tagsNeedsUpdating;
+ bool metadataNeedsUpdating;
Action *refreshInfoAction;
Action *cancelInfoJobAction;
ContextEngine *engine;
diff -Nru cantata-1.4.2.ds1/context/togglelist.ui cantata-1.5.2.ds2/context/togglelist.ui
--- cantata-1.4.2.ds1/context/togglelist.ui 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/context/togglelist.ui 2015-03-23 20:09:42.000000000 +0000
@@ -66,18 +66,10 @@
-
-
-
- true
-
-
+
-
-
-
- true
-
-
+
-
@@ -112,18 +104,10 @@
-
-
-
- true
-
-
+
-
-
-
- true
-
-
+
-
@@ -173,4 +157,11 @@
+
+
+ FlatToolButton
+ QToolButton
+
+
+
diff -Nru cantata-1.4.2.ds1/context/view.cpp cantata-1.5.2.ds2/context/view.cpp
--- cantata-1.4.2.ds1/context/view.cpp 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/context/view.cpp 2015-03-23 20:09:41.000000000 +0000
@@ -31,10 +31,11 @@
#include "support/action.h"
#include "widgets/icons.h"
#include "support/localize.h"
+#include "support/touchproxystyle.h"
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -44,6 +45,7 @@
#include
#include
#include
+#include
// Uncomment this #define to have header labels an images centered. Thsi is disabled, as the image
// centering only works if there is some text larger than 1 line to be displayed underneath :-(
@@ -87,85 +89,6 @@
return text;
}
-ViewTextSelector::ViewTextSelector(QWidget *p)
- : QLabel(p)
- , current(0)
-{
- setAttribute(Qt::WA_Hover, true);
- menu=new QMenu(this);
- setStyleSheet(QLatin1String("QLabel:hover {color:palette(highlight);}"));
- setMargin(Utils::scaleForDpi(2));
-}
-
-static QString viewText(const QString &s)
-{
- // 0x25BE is unicode for small down arrow...
- return QLatin1String("")+s+QLatin1String(" ")+QChar(0x25BE)+QLatin1String(" ");
-}
-
-void ViewTextSelector::addItem(const QString &t)
-{
- menu->addAction(t, this, SLOT(itemSelected()))->setData(items.count());
- if (text().isEmpty()) {
- setText(viewText(t));
- current=items.count();
- }
- items.append(t);
-}
-
-void ViewTextSelector::itemSelected()
-{
- QAction *act=qobject_cast(sender());
- if (act) {
- setCurrentIndex(act->data().toInt());
- }
-}
-
-bool ViewTextSelector::event(QEvent *e)
-{
- switch (e->type()) {
- case QEvent::MouseButtonPress:
- if (Qt::NoModifier==static_cast(e)->modifiers() && Qt::LeftButton==static_cast(e)->button()) {
- menu->exec(mapToGlobal(static_cast(e)->pos()));
- }
- case QEvent::Wheel: {
- int numDegrees = static_cast(e)->delta() / 8;
- int numSteps = numDegrees / 15;
- int newIndex = current;
- if (numSteps > 0) {
- for (int i = 0; i < numSteps; ++i) {
- newIndex++;
- if (newIndex>=items.count()) {
- newIndex=0;
- }
- }
- } else {
- for (int i = 0; i > numSteps; --i) {
- newIndex--;
- if (newIndex<0) {
- newIndex=items.count()-1;
- }
- }
- }
- setCurrentIndex(newIndex);
- break;
- }
- default:
- break;
- }
- return QLabel::event(e);
-}
-
-void ViewTextSelector::setCurrentIndex(int v)
-{
- if (v<0 || v>=items.count() || v==current) {
- return;
- }
- current=v;
- setText(viewText(items.at(current)));
- emit activated(current);
-}
-
View::View(QWidget *parent, const QStringList &views)
: QWidget(parent)
, needToUpdate(false)
@@ -173,7 +96,7 @@
, selector(0)
, stack(0)
{
- QGridLayout *layout=new QGridLayout(this);
+ QVBoxLayout *layout=new QVBoxLayout(this);
header=new QLabel(this);
if (views.isEmpty()) {
@@ -181,10 +104,11 @@
texts.append(t);
} else {
stack=new QStackedWidget(this);
- selector=new ViewTextSelector(this);
+ selector=new SelectorLabel(this);
+ selector->setUseArrow(true);
foreach (const QString &v, views) {
TextBrowser *t=createView(stack);
- selector->addItem(v);
+ selector->addItem(v, v);
stack->addWidget(t);
texts.append(t);
}
@@ -192,21 +116,19 @@
connect(selector, SIGNAL(activated(int)), this, SIGNAL(viewChanged()));
}
- layout->setMargin(0);
header->setWordWrap(true);
header->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
- int row=0;
- layout->addItem(new QSpacerItem(1, layout->spacing(), QSizePolicy::Fixed, QSizePolicy::Fixed), row++, 0);
- layout->addWidget(header, row++, 0, 1, 2);
+ layout->setMargin(2);
+ layout->addWidget(header);
if (views.isEmpty()) {
- layout->addWidget(texts.at(0), row++, 0, 1, 2);
+ layout->addWidget(texts.at(0));
} else {
- layout->addWidget(selector, row, 0);
- layout->addItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed), row++, 1);
- layout->addWidget(stack, row++, 0, 1, 2);
+ layout->addWidget(selector);
+ layout->addItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed));
+ layout->addWidget(stack);
}
- layout->addItem(new QSpacerItem(1, fontMetrics().height()/4, QSizePolicy::Fixed, QSizePolicy::Fixed), row++, 0);
+ layout->addItem(new QSpacerItem(1, fontMetrics().height()/4, QSizePolicy::Fixed, QSizePolicy::Fixed));
if (headerTag.isEmpty()) {
initHeaderTags();
}
@@ -215,6 +137,10 @@
cancelJobAction->setEnabled(false);
connect(cancelJobAction, SIGNAL(triggered()), SLOT(abort()));
text=texts.at(0);
+
+ if (!Utils::touchFriendly()) {
+ QTimer::singleShot(0, this, SLOT(initStyle()));
+ }
}
View::~View()
@@ -367,3 +293,16 @@
void View::abort()
{
}
+
+void View::initStyle()
+{
+ if (GtkStyle::isActive() && GtkStyle::thinScrollbars()) {
+ // Already have thin style scrollbars...
+ return;
+ }
+ static TouchProxyStyle *scrollbarStyle=new TouchProxyStyle(0, false, true);
+ foreach (TextBrowser *t, texts) {
+ t->verticalScrollBar()->setStyle(scrollbarStyle);
+ t->horizontalScrollBar()->setStyle(scrollbarStyle);
+ }
+}
diff -Nru cantata-1.4.2.ds1/context/view.h cantata-1.5.2.ds2/context/view.h
--- cantata-1.4.2.ds1/context/view.h 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/context/view.h 2015-03-23 20:09:42.000000000 +0000
@@ -28,6 +28,7 @@
#include
#include
#include "mpd/song.h"
+#include "widgets/selectorlabel.h"
class QImage;
class Spinner;
@@ -38,28 +39,6 @@
class QStackedWidget;
class QMenu;
-class ViewTextSelector : public QLabel
-{
- Q_OBJECT
-public:
- ViewTextSelector(QWidget *p);
- void addItem(const QString &t);
- bool event(QEvent *e);
- int currentIndex() const { return current; }
- void setCurrentIndex(int v);
-
-Q_SIGNALS:
- void activated(int);
-
-private Q_SLOTS:
- void itemSelected();
-
-private:
- int current;
- QStringList items;
- QMenu *menu;
-};
-
class View : public QWidget
{
Q_OBJECT
@@ -98,6 +77,9 @@
protected Q_SLOTS:
virtual void abort();
+private Q_SLOTS:
+ void initStyle();
+
protected:
Song currentSong;
QString stdHeader;
@@ -106,7 +88,7 @@
Spinner *spinner;
Action *cancelJobAction;
- ViewTextSelector *selector;
+ SelectorLabel *selector;
QStackedWidget *stack;
TextBrowser *text; // short-cut to first text item...
QList texts;
diff -Nru cantata-1.4.2.ds1/context/wikipediasettings.cpp cantata-1.5.2.ds2/context/wikipediasettings.cpp
--- cantata-1.4.2.ds1/context/wikipediasettings.cpp 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/context/wikipediasettings.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -92,7 +92,7 @@
{
label->setText(i18n("Choose the wikipedia languages you want to use when searching for artist and album information."));
reload=new Action(i18n("Reload"), this);
- connect(reload, SIGNAL(triggered(bool)), this, SLOT(getLangs()));
+ connect(reload, SIGNAL(triggered()), this, SLOT(getLangs()));
available->addAction(reload);
available->setContextMenuPolicy(Qt::ActionsContextMenu);
}
diff -Nru cantata-1.4.2.ds1/dbus/gnomemediakeys.cpp cantata-1.5.2.ds2/dbus/gnomemediakeys.cpp
--- cantata-1.4.2.ds1/dbus/gnomemediakeys.cpp 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/dbus/gnomemediakeys.cpp 2015-03-23 20:09:35.000000000 +0000
@@ -43,13 +43,21 @@
{
}
-void GnomeMediaKeys::activate(bool a)
+bool GnomeMediaKeys::activate()
{
- if (a && !mk) {
- if (daemonIsRunning()) {
- grabKeys();
- }
- } else if (!a && mk) {
+ if (mk) {
+ return true;
+ }
+ if (daemonIsRunning()) {
+ grabKeys();
+ return true;
+ }
+ return false;
+}
+
+void GnomeMediaKeys::deactivate()
+{
+ if (mk) {
releaseKeys();
disconnectDaemon();
if (watcher) {
diff -Nru cantata-1.4.2.ds1/dbus/gnomemediakeys.h cantata-1.5.2.ds2/dbus/gnomemediakeys.h
--- cantata-1.4.2.ds1/dbus/gnomemediakeys.h 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/dbus/gnomemediakeys.h 2015-03-23 20:09:35.000000000 +0000
@@ -38,7 +38,8 @@
public:
GnomeMediaKeys(QObject *p);
- void activate(bool a);
+ bool activate();
+ void deactivate();
private:
bool daemonIsRunning();
diff -Nru cantata-1.4.2.ds1/dbus/mpris.h cantata-1.5.2.ds2/dbus/mpris.h
--- cantata-1.4.2.ds1/dbus/mpris.h 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/dbus/mpris.h 2015-03-23 20:09:35.000000000 +0000
@@ -79,7 +79,7 @@
void PlayPause() { StdActions::self()->playPauseTrackAction->trigger(); }
void Stop() { StdActions::self()->stopPlaybackAction->trigger(); }
- void StopAfterCurrent() { StdActions::self()->stopAfterTrackAction->trigger(); }
+ void StopAfterCurrent() { StdActions::self()->stopAfterCurrentTrackAction->trigger(); }
void Play() {
MPDStatus * const status = MPDStatus::self();
diff -Nru cantata-1.4.2.ds1/dbus/notify.cpp cantata-1.5.2.ds2/dbus/notify.cpp
--- cantata-1.4.2.ds1/dbus/notify.cpp 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/dbus/notify.cpp 2015-03-23 20:09:35.000000000 +0000
@@ -75,7 +75,7 @@
{
// This is needed to link but shouldn't be called.
Q_ASSERT(0);
- Q_UNUSED(image);
+ Q_UNUSED(image)
return arg;
}
diff -Nru cantata-1.4.2.ds1/dbus/org.freedesktop.login1.xml cantata-1.5.2.ds2/dbus/org.freedesktop.login1.xml
--- cantata-1.4.2.ds1/dbus/org.freedesktop.login1.xml 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/dbus/org.freedesktop.login1.xml 2015-03-23 20:09:35.000000000 +0000
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -Nru cantata-1.4.2.ds1/dbus/powermanagement.cpp cantata-1.5.2.ds2/dbus/powermanagement.cpp
--- cantata-1.4.2.ds1/dbus/powermanagement.cpp 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/dbus/powermanagement.cpp 2015-03-23 20:09:35.000000000 +0000
@@ -30,6 +30,7 @@
#include "inhibitinterface.h"
#include "policyagentinterface.h"
#include "upowerinterface.h"
+#include "login1interface.h"
#endif
#include "support/localize.h"
#include "mpd/mpdstatus.h"
@@ -53,7 +54,10 @@
QDBusConnection::sessionBus(), this);
upower = new OrgFreedesktopUPowerInterface(OrgFreedesktopUPowerInterface::staticInterfaceName(),
QLatin1String("/org/freedesktop/UPower"), QDBusConnection::systemBus(), this);
+ login1 = new OrgFreedesktopLogin1ManagerInterface("org.freedesktop.login1",
+ QLatin1String("/org/freedesktop/login1"), QDBusConnection::systemBus(), this);
connect(upower, SIGNAL(Resuming()), this, SIGNAL(resuming()));
+ connect(login1, SIGNAL(PrepareForSleep(bool)), this, SLOT(prepareForSleep(bool)));
#endif
}
@@ -124,3 +128,14 @@
}
}
}
+
+void PowerManagement::prepareForSleep(bool s)
+{
+ #ifdef ENABLE_KDE_SUPPORT
+ Q_UNUSED(s)
+ #else
+ if (!s) {
+ emit resuming();
+ }
+ #endif
+}
diff -Nru cantata-1.4.2.ds1/dbus/powermanagement.h cantata-1.5.2.ds2/dbus/powermanagement.h
--- cantata-1.4.2.ds1/dbus/powermanagement.h 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/dbus/powermanagement.h 2015-03-23 20:09:35.000000000 +0000
@@ -31,6 +31,7 @@
class OrgKdeSolidPowerManagementPolicyAgentInterface;
class OrgFreedesktopPowerManagementInhibitInterface;
class OrgFreedesktopUPowerInterface;
+class OrgFreedesktopLogin1ManagerInterface;
#endif
class PowerManagement : public QObject
@@ -50,6 +51,7 @@
private Q_SLOTS:
void mpdStatusUpdated();
+ void prepareForSleep(bool s);
private:
bool inhibitSuspendWhilstPlaying;
@@ -58,6 +60,7 @@
OrgKdeSolidPowerManagementPolicyAgentInterface *policy;
OrgFreedesktopPowerManagementInhibitInterface *inhibit;
OrgFreedesktopUPowerInterface *upower;
+ OrgFreedesktopLogin1ManagerInterface *login1;
#endif
};
diff -Nru cantata-1.4.2.ds1/debian/changelog cantata-1.5.2.ds2/debian/changelog
--- cantata-1.4.2.ds1/debian/changelog 2015-08-14 18:38:08.000000000 +0000
+++ cantata-1.5.2.ds2/debian/changelog 2015-08-14 20:56:44.000000000 +0000
@@ -1,20 +1,23 @@
-cantata (1.4.2.ds1-1ubuntu2) wily; urgency=medium
+cantata (1.5.2.ds2-2ubuntu1) wily; urgency=medium
- * No-change rebuild against libmusicbrainz5-2
+ * Merge with Debian; remaining changes:
+ - Remove install dep on kde-style-oxygen which no longer exists.
- -- Steve Langasek Fri, 14 Aug 2015 18:38:08 +0000
+ -- Matthias Klose Fri, 14 Aug 2015 22:55:17 +0200
-cantata (1.4.2.ds1-1ubuntu1) vivid; urgency=medium
+cantata (1.5.2.ds2-2) unstable; urgency=medium
- * Remove install dep on kde-style-oxygen which no longer exists
+ * Team upload.
+ * Look for libmusicbrainz5cc instead of libmusicbrainz5 (Closes: #791880).
- -- Jonathan Riddell Thu, 18 Dec 2014 14:34:02 +0100
+ -- Sebastian Ramacher Thu, 09 Jul 2015 12:38:44 +0200
-cantata (1.4.2.ds1-1build1) vivid; urgency=medium
+cantata (1.5.2.ds2-1) unstable; urgency=medium
- * Rebuild against libmusicbrainz5-1.
+ * New upstream release.
+ * Bump standards version (no changes required).
- -- Colin Watson Thu, 04 Dec 2014 11:57:11 +0000
+ -- Stuart Prescott Mon, 27 Apr 2015 00:36:16 +1000
cantata (1.4.2.ds1-1) unstable; urgency=medium
@@ -22,6 +25,18 @@
-- Stuart Prescott Mon, 29 Sep 2014 20:54:08 +1000
+cantata (1.4.2.ds1-1ubuntu1) vivid; urgency=medium
+
+ * Remove install dep on kde-style-oxygen which no longer exists
+
+ -- Jonathan Riddell Thu, 18 Dec 2014 14:34:02 +0100
+
+cantata (1.4.2.ds1-1build1) vivid; urgency=medium
+
+ * Rebuild against libmusicbrainz5-1.
+
+ -- Colin Watson Thu, 04 Dec 2014 11:57:11 +0000
+
cantata (1.4.1.ds1-1) unstable; urgency=medium
* New upstream release
diff -Nru cantata-1.4.2.ds1/debian/control cantata-1.5.2.ds2/debian/control
--- cantata-1.4.2.ds1/debian/control 2014-12-18 13:34:42.000000000 +0000
+++ cantata-1.5.2.ds2/debian/control 2015-08-14 20:56:53.000000000 +0000
@@ -1,8 +1,7 @@
Source: cantata
Section: sound
Priority: optional
-Maintainer: Kubuntu Developers
-XSBC-Original-Maintainer: Debian Multimedia Maintainers
+Maintainer: Debian Multimedia Maintainers
Uploaders: Stuart Prescott
Build-Depends: cmake,
debhelper (>= 9),
@@ -13,7 +12,7 @@
libavutil-dev,
libcdparanoia-dev,
libebur128-dev,
- libmusicbrainz5-dev,
+ libmusicbrainz5-dev (>= 5.1.0+git20150707),
libmpg123-dev,
libmtp-dev (>= 1.0.0),
libphonon-dev,
@@ -28,7 +27,7 @@
libx11-dev,
pkg-config,
pkg-kde-tools
-Standards-Version: 3.9.5
+Standards-Version: 3.9.6
Homepage: https://code.google.com/p/cantata/
Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-multimedia/cantata.git
Vcs-Git: git://anonscm.debian.org/pkg-multimedia/cantata.git
diff -Nru cantata-1.4.2.ds1/debian/copyright cantata-1.5.2.ds2/debian/copyright
--- cantata-1.4.2.ds1/debian/copyright 2014-09-29 10:54:23.000000000 +0000
+++ cantata-1.5.2.ds2/debian/copyright 2015-07-09 10:35:23.000000000 +0000
@@ -7,6 +7,7 @@
3rdparty/qtsingleapplication
3rdparty/qxt
3rdparty/solid-lite
+ windows/icu
Comment: Unneeded 3rd party source code removed
License: GPL-3+
diff -Nru cantata-1.4.2.ds1/debian/patches/ebur128-location.patch cantata-1.5.2.ds2/debian/patches/ebur128-location.patch
--- cantata-1.4.2.ds1/debian/patches/ebur128-location.patch 2014-09-29 10:54:23.000000000 +0000
+++ cantata-1.5.2.ds2/debian/patches/ebur128-location.patch 2015-07-09 10:35:23.000000000 +0000
@@ -9,7 +9,7 @@
Forwarded: not sure -- check interaction with cmake rules
--- a/replaygain/ffmpeginput.cpp
+++ b/replaygain/ffmpeginput.cpp
-@@ -32,7 +32,7 @@
+@@ -31,7 +31,7 @@
#include
#include
#include
@@ -20,7 +20,7 @@
static QMutex mutex;
--- a/replaygain/mpg123input.cpp
+++ b/replaygain/mpg123input.cpp
-@@ -19,7 +19,7 @@
+@@ -18,7 +18,7 @@
#include
#include
#include
diff -Nru cantata-1.4.2.ds1/debian/patches/libmusicbrainz5cc.patch cantata-1.5.2.ds2/debian/patches/libmusicbrainz5cc.patch
--- cantata-1.4.2.ds1/debian/patches/libmusicbrainz5cc.patch 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/debian/patches/libmusicbrainz5cc.patch 2015-07-09 10:35:39.000000000 +0000
@@ -0,0 +1,19 @@
+Description: Look for libmusicbrainz5cc instead of libmusicbrainz5.
+Author: Sebastian Ramacher
+Last-Update: 2015-07-09
+
+--- cantata-1.5.2.ds2.orig/cmake/FindMusicBrainz5.cmake
++++ cantata-1.5.2.ds2/cmake/FindMusicBrainz5.cmake
+@@ -16,10 +16,10 @@ endif(MUSICBRAINZ5_INCLUDE_DIRS AND MUSI
+
+ IF (NOT WIN32)
+ find_package(PkgConfig)
+- PKG_SEARCH_MODULE( MUSICBRAINZ5 libmusicbrainz5 )
++ PKG_SEARCH_MODULE( MUSICBRAINZ5 libmusicbrainz5cc )
+ ELSE (NOT WIN32)
+ FIND_PATH( MUSICBRAINZ5_INCLUDE_DIRS musicbrainz5/Disc.h )
+- FIND_LIBRARY( MUSICBRAINZ5_LIBRARIES NAMES musicbrainz5 )
++ FIND_LIBRARY( MUSICBRAINZ5_LIBRARIES NAMES musicbrainz5cc )
+ ENDIF (NOT WIN32)
+
+ include(FindPackageHandleStandardArgs)
diff -Nru cantata-1.4.2.ds1/debian/patches/series cantata-1.5.2.ds2/debian/patches/series
--- cantata-1.4.2.ds1/debian/patches/series 2014-09-29 10:54:23.000000000 +0000
+++ cantata-1.5.2.ds2/debian/patches/series 2015-07-09 10:35:39.000000000 +0000
@@ -1,3 +1,4 @@
# only needed for Qt in wheezy
#playeradaptor.patch
ebur128-location.patch
+libmusicbrainz5cc.patch
diff -Nru cantata-1.4.2.ds1/devices/actiondialog.cpp cantata-1.5.2.ds2/devices/actiondialog.cpp
--- cantata-1.4.2.ds1/devices/actiondialog.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/actiondialog.cpp 2015-03-23 20:09:33.000000000 +0000
@@ -85,8 +85,6 @@
MusicLibraryModel *model=new MusicLibraryModel(this, false);
MusicLibraryProxyModel *proxy=new MusicLibraryProxyModel(this);
proxy->setSourceModel(model);
- model->setUseAlbumImages(false);
- model->setUseArtistImages(false);
model->setSupportsAlbumArtistTag(true);
TreeView *view=new TreeView(this);
view->setPageDefaults();
@@ -322,14 +320,14 @@
}
show();
if (!enoughSpace) {
- MessageBox::information(this, i18n("There is insufficient space left on the destination device.\n"
+ MessageBox::information(this, i18n("There is insufficient space left on the destination device.\n\n"
"The selected songs consume %1, but there is only %2 left.\n"
"The songs will need to be transcoded to a smaller filesize in order to be successfully copied.",
Utils::formatByteSize(spaceRequired),
Utils::formatByteSize(spaceAvailable)));
}
} else {
- MessageBox::error(parentWidget(), i18n("There is insufficient space left on the destination.\n"
+ MessageBox::error(parentWidget(), i18n("There is insufficient space left on the destination.\n\n"
"The selected songs consume %1, but there is only %2 left.",
Utils::formatByteSize(spaceRequired),
Utils::formatByteSize(spaceAvailable)));
@@ -415,12 +413,12 @@
case Ok:
if (haveVariousArtists &&
((configureDestLabel->isVisible() && sourceUdi.isEmpty() && // Only warn if copying FROM library
- MessageBox::No==MessageBox::warningYesNo(this, i18n("You have not configured the destination device. "
- "Continue with the default settings?
"), i18n("Not Configured"),
+ MessageBox::No==MessageBox::warningYesNo(this, i18n("You have not configured the destination device.\n\n"
+ "Continue with the default settings?"), i18n("Not Configured"),
GuiItem(i18n("Use Defaults")), StdGuiItem::cancel())) ||
(configureSourceLabel->isVisible() && !sourceUdi.isEmpty() && // Only warn if copying TO library
- MessageBox::No==MessageBox::warningYesNo(this, i18n("You have not configured the source device. "
- "Continue with the default settings?
"), i18n("Not Configured"),
+ MessageBox::No==MessageBox::warningYesNo(this, i18n("You have not configured the source device.\n\n"
+ "Continue with the default settings?"), i18n("Not Configured"),
GuiItem(i18n("Use Defaults")), StdGuiItem::cancel())) ) ) {
return;
}
@@ -614,7 +612,7 @@
#ifdef ENABLE_REPLAYGAIN_SUPPORT
if (Copy==mode && !albumsWithoutRgTags.isEmpty() && sourceIsAudioCd) {
QWidget *pw=parentWidget();
- if (MessageBox::Yes==MessageBox::questionYesNo(pw, i18n("Calculate ReplayGain for ripped tracks?"), i18n("ReplyGain"),
+ if (MessageBox::Yes==MessageBox::questionYesNo(pw, i18n("Calculate ReplayGain for ripped tracks?"), i18n("ReplayGain"),
GuiItem(i18n("Calculate")), StdGuiItem::no())) {
RgDialog *dlg=new RgDialog(pw);
QList songs;
diff -Nru cantata-1.4.2.ds1/devices/actiondialog.ui cantata-1.5.2.ds2/devices/actiondialog.ui
--- cantata-1.4.2.ds1/devices/actiondialog.ui 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/actiondialog.ui 2015-03-23 20:09:33.000000000 +0000
@@ -200,12 +200,9 @@
-
-
+
- <i><b>NOTE:</b> Connected to a Mopidy server (manual update required).</i>
-
-
- Qt::NoTextInteraction
+ Connected to a Mopidy server (manual update required).
@@ -410,6 +407,11 @@
+ UrlNoteLabel
+ QLabel
+
+
+
SplitLabelWidget
QLabel
devices/splitlabelwidget.h
diff -Nru cantata-1.4.2.ds1/devices/albumdetailsdialog.cpp cantata-1.5.2.ds2/devices/albumdetailsdialog.cpp
--- cantata-1.4.2.ds1/devices/albumdetailsdialog.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/albumdetailsdialog.cpp 2015-03-23 20:09:33.000000000 +0000
@@ -51,7 +51,7 @@
EditorDelegate(QObject *parent=0) : BasicItemDelegate(parent) { }
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
- Q_UNUSED(option);
+ Q_UNUSED(option)
if (COL_TRACK==index.column()) {
QSpinBox *editor = new QSpinBox(parent);
editor->setMinimum(0);
@@ -83,7 +83,7 @@
}
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const {
- Q_UNUSED(index);
+ Q_UNUSED(index)
editor->setGeometry(option.rect);
}
};
@@ -230,10 +230,10 @@
void AlbumDetailsDialog::applyVa()
{
if (MessageBox::No==MessageBox::questionYesNo(this, i18n("Apply \"Various Artists\" workaround?")+
- QLatin1String(" ")+
- i18n("This will set 'Album artist' and 'Artist' to "
+ QLatin1String("\n\n")+
+ i18n("This will set 'Album artist' and 'Artist' to "
"\"Various Artists\", and set 'Title' to "
- "\"TrackArtist - TrackTitle\" "), i18n("Apply \"Various Artists\" Workaround"),
+ "\"TrackArtist - TrackTitle\""), i18n("Apply \"Various Artists\" Workaround"),
StdGuiItem::apply(), StdGuiItem::cancel())) {
return;
}
@@ -250,14 +250,14 @@
void AlbumDetailsDialog::revertVa()
{
- if (MessageBox::No==MessageBox::questionYesNo(this, i18n("Revert \"Various Artists\" workaround")+
- QLatin1String(" ")+
- i18n("Where the 'Album artist' is the same as 'Artist' "
+ if (MessageBox::No==MessageBox::questionYesNo(this, i18n("Revert \"Various Artists\" workaround?")+
+ QLatin1String("\n\n")+
+ i18n("Where the 'Album artist' is the same as 'Artist' "
"and the 'Title' is of the format \"TrackArtist - TrackTitle\", "
"'Artist' will be taken from 'Title' and 'Title' itself will be "
- "set to just the title. e.g. "
+ "set to just the title. e.g. \n"
"If 'Title' is \"Wibble - Wobble\", then 'Artist' will be set to "
- "\"Wibble\" and 'Title' will be set to \"Wobble\" "), i18n("Revert \"Various Artists\" Workaround"),
+ "\"Wibble\" and 'Title' will be set to \"Wobble\""), i18n("Revert \"Various Artists\" Workaround"),
GuiItem(i18n("Revert")), StdGuiItem::cancel())) {
return;
}
@@ -274,7 +274,7 @@
void AlbumDetailsDialog::capitalise()
{
- if (MessageBox::No==MessageBox::questionYesNo(this, i18n("Capitalize the first letter of 'Title', 'Artist', 'Album artist', and 'Album'"),
+ if (MessageBox::No==MessageBox::questionYesNo(this, i18n("Capitalize the first letter of 'Title', 'Artist', 'Album artist', and 'Album'?"),
i18n("Capitalize"), GuiItem(i18n("Capitalize")), StdGuiItem::cancel())) {
return;
}
diff -Nru cantata-1.4.2.ds1/devices/audiocddevice.cpp cantata-1.5.2.ds2/devices/audiocddevice.cpp
--- cantata-1.4.2.ds1/devices/audiocddevice.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/audiocddevice.cpp 2015-03-23 20:09:33.000000000 +0000
@@ -182,7 +182,7 @@
mb=0;
}
#else
- Q_UNUSED(useCddb);
+ Q_UNUSED(useCddb)
#endif
#ifdef CDDB_FOUND
diff -Nru cantata-1.4.2.ds1/devices/cdparanoia.cpp cantata-1.5.2.ds2/devices/cdparanoia.cpp
--- cantata-1.4.2.ds1/devices/cdparanoia.cpp 2014-09-28 16:30:06.000000000 +0000
+++ cantata-1.5.2.ds2/devices/cdparanoia.cpp 2015-03-23 20:09:32.000000000 +0000
@@ -37,8 +37,6 @@
, neverSkip(noSkip)
, maxRetries(20)
{
- paranoia = 0;
- drive = 0;
QMutexLocker locker(&mutex);
if (!lockedDevices.contains(device)) {
dev = device;
@@ -125,11 +123,6 @@
// return paranoia ? cdda_disc_lastsector(drive) : -1;
//}
-void CdParanoia::reset()
-{
- init();
-}
-
bool CdParanoia::init()
{
free();
@@ -148,7 +141,8 @@
return true;
}
-void CdParanoia::free() {
+void CdParanoia::free()
+{
if (paranoia) {
paranoia_free(paranoia);
paranoia = 0;
diff -Nru cantata-1.4.2.ds1/devices/cdparanoia.h cantata-1.5.2.ds2/devices/cdparanoia.h
--- cantata-1.4.2.ds1/devices/cdparanoia.h 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/cdparanoia.h 2015-03-23 20:09:33.000000000 +0000
@@ -58,7 +58,7 @@
double sizeOfTrack(int n); //in MiB
int frameOffsetOfTrack(int n);
bool isAudioTrack(int n);
- void reset();
+ void reset() { init(); }
private:
bool init();
diff -Nru cantata-1.4.2.ds1/devices/device.h cantata-1.5.2.ds2/devices/device.h
--- cantata-1.4.2.ds1/devices/device.h 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/device.h 2015-03-23 20:09:33.000000000 +0000
@@ -26,6 +26,7 @@
#include "models/musiclibraryitemroot.h"
#include "mpd/song.h"
+#include "gui/covers.h"
#include "config.h"
#ifdef ENABLE_DEVICES_SUPPORT
#include "deviceoptions.h"
@@ -100,9 +101,6 @@
, needToFixVa(false)
, jobAbortRequested(false)
, transcoding(false) {
- setUseArtistImages(false);
- setUseAlbumImages(true);
- setLargeImages(false);
Q_UNUSED(m)
Q_UNUSED(id)
}
@@ -117,9 +115,6 @@
, jobAbortRequested(false)
, transcoding(false) {
m_model=m;
- setUseArtistImages(false);
- setUseAlbumImages(true);
- setLargeImages(false);
icn=Icon(solidDev.isValid() ? solidDev.icon() : QLatin1String("inode-directory"));
}
Device(MusicModel *m, const QString &name, const QString &id)
@@ -131,8 +126,6 @@
, jobAbortRequested(false)
, transcoding(false) {
m_model=m;
- setUseArtistImages(false);
- setUseAlbumImages(true);
icn=Icon(solidDev.isValid() ? solidDev.icon() : QLatin1String("inode-directory"));
}
#endif
@@ -155,7 +148,7 @@
virtual void copySongTo(const Song &s, const QString &musicPath, bool overwrite, bool copyCover)=0;
virtual void removeSong(const Song &s)=0;
virtual void cleanDirs(const QSet &dirs)=0;
- virtual void requestCover(const Song &) { }
+ virtual Covers::Image requestCover(const Song &) { return Covers::Image(); }
virtual double usedCapacity()=0;
virtual QString capacityString()=0;
virtual qint64 freeSpace()=0;
diff -Nru cantata-1.4.2.ds1/devices/devicepropertieswidget.cpp cantata-1.5.2.ds2/devices/devicepropertieswidget.cpp
--- cantata-1.4.2.ds1/devices/devicepropertieswidget.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/devicepropertieswidget.cpp 2015-03-23 20:09:33.000000000 +0000
@@ -29,7 +29,6 @@
#include "support/utils.h"
#include
#include
-#include
class CoverNameValidator : public QValidator
{
@@ -149,7 +148,7 @@
origOpts=opts;
if (props&Prop_Folder) {
- musicFolder->setText(Utils::convertDirForDisplay(path));
+ musicFolder->setText(Utils::convertPathForDisplay(path));
connect(musicFolder, SIGNAL(textChanged(const QString &)), this, SLOT(checkSaveable()));
if (disabledProps&Prop_Folder) {
musicFolder->setDisabled(true);
@@ -321,17 +320,7 @@
}
}
- QWidget *win=window();
- if (win) {
- QSize was=win->size();
- QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
- win->setMinimumSize(QSize(0, 0));
- win->adjustSize();
- QSize now=win->size();
- win->setMinimumSize(now);
- win->resize(qMax(was.width(), now.width()), now.height());
- }
-
+ Utils::resizeWindow(this, true, false);
checkSaveable();
}
diff -Nru cantata-1.4.2.ds1/devices/devicepropertieswidget.h cantata-1.5.2.ds2/devices/devicepropertieswidget.h
--- cantata-1.4.2.ds1/devices/devicepropertieswidget.h 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/devicepropertieswidget.h 2015-03-23 20:09:33.000000000 +0000
@@ -57,7 +57,7 @@
DeviceOptions settings();
bool isModified() const { return modified; }
bool isSaveable() const { return saveable; }
- QString music() const { return musicFolder && musicFolder->isEnabled() ? Utils::convertDirFromDisplay(musicFolder->text()) : origMusicFolder; }
+ QString music() const { return musicFolder && musicFolder->isEnabled() ? Utils::convertPathFromDisplay(musicFolder->text()) : origMusicFolder; }
QString cover() const;
void showRemoteConnectionNote(bool v) { remoteDeviceNote->setVisible(v); }
diff -Nru cantata-1.4.2.ds1/devices/devicepropertieswidget.ui cantata-1.5.2.ds2/devices/devicepropertieswidget.ui
--- cantata-1.4.2.ds1/devices/devicepropertieswidget.ui 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/devicepropertieswidget.ui 2015-03-23 20:09:33.000000000 +0000
@@ -15,15 +15,9 @@
0
-
-
+
- <i><b>NOTE:</b> These settings are only valid, and editable, when the device is connected.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ These settings are only valid, and editable, when the device is connected.
@@ -195,7 +189,7 @@
-
- Ignore 'The' in artist names
+ Append 'The' to artist names
@@ -261,6 +255,11 @@
QSlider
+
+ PlainNoteLabel
+ QLabel
+
+
musicFolder
diff -Nru cantata-1.4.2.ds1/devices/devicespage.cpp cantata-1.5.2.ds2/devices/devicespage.cpp
--- cantata-1.4.2.ds1/devices/devicespage.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/devicespage.cpp 2015-03-23 20:09:34.000000000 +0000
@@ -79,14 +79,10 @@
view->addAction(StdActions::self()->replaygainAction);
#endif
#ifdef ENABLE_REMOTE_DEVICES
- QAction *sepA=new QAction(this);
- sepA->setSeparator(true);
- view->addAction(sepA);
+ view->addSeparator();
view->addAction(forgetDeviceAction);
#endif
- QAction *sep=new QAction(this);
- sep->setSeparator(true);
- view->addAction(sep);
+ view->addSeparator();
view->addAction(StdActions::self()->deleteSongsAction);
connect(this, SIGNAL(add(const QStringList &, bool, quint8)), MPDConnection::self(), SLOT(add(const QStringList &, bool, quint8)));
connect(this, SIGNAL(addSongsToPlaylist(const QString &, const QStringList &)), MPDConnection::self(), SLOT(addToPlaylist(const QString &, const QStringList &)));
@@ -230,11 +226,9 @@
return DevicesModel::self()->songs(proxy.mapToSource(selected, proxy.enabled() && Settings::self()->filteredOnly()));
}
-void DevicesPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty, bool randomAlbums)
+void DevicesPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty)
{
- Q_UNUSED(randomAlbums)
QStringList files=playableUrls();
-
if (!files.isEmpty()) {
if (name.isEmpty()) {
emit add(files, replace, priorty);
@@ -445,9 +439,11 @@
dev=DevicesModel::self()->device(udi);
} else {
if (dev->childCount() && Device::Mtp!=dev->devType()) {
- switch (MessageBox::questionYesNoCancel(this, i18n("Which type of refresh do you wish to perform?
"
- "Partial - Only new songs are scanned (quick) "
- "Full - All songs are rescanned (slow)
"),
+ static const QChar constBullet(0x2022);
+
+ switch (MessageBox::questionYesNoCancel(this, i18n("Which type of refresh do you wish to perform?")+QLatin1String("\n\n")+
+ constBullet+QLatin1Char(' ')+i18n("Partial - Only new songs are scanned (quick)")+QLatin1Char('\n')+
+ constBullet+QLatin1Char(' ')+i18n("Full - All songs are rescanned (slow)"),
i18n("Refresh"), GuiItem(i18n("Partial")), GuiItem(i18n("Full")))) {
case MessageBox::Yes:
full=false;
@@ -495,7 +491,7 @@
QList songs=DevicesModel::self()->songs(mapped);
if (!songs.isEmpty()) {
- if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to delete the selected songs?\nThis cannot be undone."),
+ if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to delete the selected songs?\n\nThis cannot be undone."),
i18n("Delete Songs"), StdGuiItem::del(), StdGuiItem::cancel())) {
emit deleteSongs(udi, songs);
}
@@ -522,7 +518,7 @@
}
QString udi=dev->id();
QString devName=dev->data();
- if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to forget %1 ?", devName))) {
+ if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to forget '%1'?", devName))) {
DevicesModel::self()->removeRemoteDevice(udi);
}
#endif
@@ -541,9 +537,9 @@
Device *dev=static_cast(item);
if (dev->isConnected() &&
(Device::AudioCd==dev->devType()
- ? MessageBox::No==MessageBox::warningYesNo(this, i18n("Are you sure you wish to eject Audio CD %1 - %2 ?", dev->data(), dev->subText()),
+ ? MessageBox::No==MessageBox::warningYesNo(this, i18n("Are you sure you wish to eject Audio CD '%1 - %2'?", dev->data(), dev->subText()),
i18n("Eject"), GuiItem(i18n("Eject")), StdGuiItem::cancel())
- : MessageBox::No==MessageBox::warningYesNo(this, i18n("Are you sure you wish to disconnect %1 ?", dev->data()),
+ : MessageBox::No==MessageBox::warningYesNo(this, i18n("Are you sure you wish to disconnect '%1'?", dev->data()),
i18n("Disconnect"), GuiItem(i18n("Disconnect")), StdGuiItem::cancel()))) {
return;
}
diff -Nru cantata-1.4.2.ds1/devices/devicespage.h cantata-1.5.2.ds2/devices/devicespage.h
--- cantata-1.4.2.ds1/devices/devicespage.h 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/devicespage.h 2015-03-23 20:09:33.000000000 +0000
@@ -47,11 +47,12 @@
QString activeFsDeviceUdi() const;
QStringList playableUrls() const;
QList selectedSongs(bool allowPlaylists=false) const;
- void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0, bool randomAlbums=false);
+ void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0);
void setView(int v) { view->setMode((ItemView::Mode)v); }
void focusSearch() { view->focusSearch(); }
void refresh();
void showEvent(QShowEvent *e);
+ void resort() { proxy.sort(); }
public Q_SLOTS:
void itemDoubleClicked(const QModelIndex &);
diff -Nru cantata-1.4.2.ds1/devices/encoders.cpp cantata-1.5.2.ds2/devices/encoders.cpp
--- cantata-1.4.2.ds1/devices/encoders.cpp 2014-09-28 16:30:06.000000000 +0000
+++ cantata-1.5.2.ds2/devices/encoders.cpp 2015-03-23 20:09:32.000000000 +0000
@@ -46,7 +46,7 @@
enc.outputParam=outputParam;
if (-1!=index) {
Encoder orig=installedEncoders.takeAt(index);
- orig.name+=QLatin1String(" (ffmpeg)");
+ orig.name+=usingAvconv ? QLatin1String(" (avconv)") : QLatin1String(" (ffmpeg)");
installedEncoders.insert(index, orig);
enc.name+=QLatin1String(" (")+cmd+QChar(')');
installedEncoders.insert(index+1, enc);
diff -Nru cantata-1.4.2.ds1/devices/filenameschemedialog.cpp cantata-1.5.2.ds2/devices/filenameschemedialog.cpp
--- cantata-1.4.2.ds1/devices/filenameschemedialog.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/filenameschemedialog.cpp 2015-03-23 20:09:34.000000000 +0000
@@ -118,13 +118,21 @@
void FilenameSchemeDialog::showHelp()
{
MessageBox::information(this,
- i18n("The following variables will be replaced with their corresponding meaning for each track name.
")+
- QLatin1String("
")+
+ i18n("The following variables will be replaced with their corresponding meaning for each track name.")+
+ QLatin1String(" ")+
+ #ifdef Q_OS_MAC
+ QLatin1String("")+
+ #endif
+ QLatin1String("")+
i18n("Variable Button Description ")+
tableEntry(albumArtist)+tableEntry(albumTitle)+tableEntry(composer)+tableEntry(trackArtist)+
tableEntry(trackTitle)+tableEntry(trackArtistAndTitle)+tableEntry(trackNo)+tableEntry(cdNo)+
tableEntry(year)+tableEntry(genre)+
- QLatin1String("
"));
+ QLatin1String("
")
+ #ifdef Q_OS_MAC
+ +QLatin1String("")
+ #endif
+ );
}
void FilenameSchemeDialog::enableOkButton()
diff -Nru cantata-1.4.2.ds1/devices/fsdevice.cpp cantata-1.5.2.ds2/devices/fsdevice.cpp
--- cantata-1.4.2.ds1/devices/fsdevice.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/fsdevice.cpp 2015-03-23 20:09:33.000000000 +0000
@@ -422,7 +422,8 @@
transcoding=true;
TranscodingJob *job=new TranscodingJob(encoder, opts.transcoderValue, s.file, currentDestFile, copyCover ? opts : DeviceOptions(Device::constNoCover),
(needToFixVa ? CopyJob::OptsApplyVaFix : CopyJob::OptsNone)|
- (Device::RemoteFs==devType() ? CopyJob::OptsFixLocal : CopyJob::OptsNone));
+ (Device::RemoteFs==devType() ? CopyJob::OptsFixLocal : CopyJob::OptsNone),
+ currentSong);
connect(job, SIGNAL(result(int)), SLOT(addSongResult(int)));
connect(job, SIGNAL(percent(int)), SLOT(percent(int)));
job->start();
@@ -507,8 +508,9 @@
job->start();
}
-void FsDevice::requestCover(const Song &s)
+Covers::Image FsDevice::requestCover(const Song &s)
{
+ Covers::Image i;
QString songFile=audioFolder+s.file;
QString dirName=Utils::getDir(songFile);
@@ -516,7 +518,7 @@
QImage img(dirName+opts.coverName);
if (!img.isNull()) {
emit cover(s, img);
- return;
+ return Covers::Image(img, dirName+opts.coverName);
}
}
@@ -526,9 +528,10 @@
if (!img.isNull()) {
emit cover(s, img);
- return;
+ return Covers::Image(img, dirName+fileName);
}
}
+ return Covers::Image();
}
void FsDevice::percent(int pc)
diff -Nru cantata-1.4.2.ds1/devices/fsdevice.h cantata-1.5.2.ds2/devices/fsdevice.h
--- cantata-1.4.2.ds1/devices/fsdevice.h 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/fsdevice.h 2015-03-23 20:09:33.000000000 +0000
@@ -123,7 +123,7 @@
void copySongTo(const Song &s, const QString &musicPath, bool overwrite, bool copyCover);
void removeSong(const Song &s);
void cleanDirs(const QSet &dirs);
- void requestCover(const Song &s);
+ Covers::Image requestCover(const Song &s);
QString cacheFileName() const;
virtual void setAudioFolder() const { }
void saveCache();
diff -Nru cantata-1.4.2.ds1/devices/mtpdevice.cpp cantata-1.5.2.ds2/devices/mtpdevice.cpp
--- cantata-1.4.2.ds1/devices/mtpdevice.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/mtpdevice.cpp 2015-03-23 20:09:33.000000000 +0000
@@ -55,9 +55,11 @@
#include
//#define TIME_MTP_OPERATIONS
#ifdef TIME_MTP_OPERATIONS
-#include
#include
#endif
+#include
+
+#define DBUG(CLASS) if (Covers::debugEnabled()) qWarning() << CLASS << __FUNCTION__
// Enable the following #define to have Cantata attempt to ascertain the AlbumArtist tag by
// looking at the file path
@@ -1208,11 +1210,14 @@
{
File c=getCoverDetils(song);
+ DBUG("MtpConnection") << c.name << c.id;
+
if (0!=c.id) {
QByteArray data;
if (0==LIBMTP_Get_File_To_Handler(device, c.id, fileReceiver, &data, 0, 0)) {
QImage img;
if (img.loadFromData(data)) {
+ DBUG("MtpConnection") << "loaded cover";
emit cover(song, img);
}
}
@@ -1555,12 +1560,15 @@
emit cleanMusicDirs(dirs);
}
-void MtpDevice::requestCover(const Song &song)
+Covers::Image MtpDevice::requestCover(const Song &song)
{
+ DBUG("MtpDevice") << song.file;
requestAbort(false);
if (isConnected()) {
+ DBUG("MtpDevice") << "Get cover from connection";
emit getCover(song);
}
+ return Covers::Image();
}
void MtpDevice::putSongStatus(int status, const QString &file, bool fixedVa, bool copiedCover)
diff -Nru cantata-1.4.2.ds1/devices/mtpdevice.h cantata-1.5.2.ds2/devices/mtpdevice.h
--- cantata-1.4.2.ds1/devices/mtpdevice.h 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/mtpdevice.h 2015-03-23 20:09:33.000000000 +0000
@@ -171,7 +171,7 @@
void copySongTo(const Song &s, const QString &musicPath, bool overwrite, bool copyCover);
void removeSong(const Song &s);
void cleanDirs(const QSet &dirs);
- void requestCover(const Song &song);
+ Covers::Image requestCover(const Song &song);
double usedCapacity();
QString capacityString();
qint64 freeSpace();
diff -Nru cantata-1.4.2.ds1/devices/musicbrainz.cpp cantata-1.5.2.ds2/devices/musicbrainz.cpp
--- cantata-1.4.2.ds1/devices/musicbrainz.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/musicbrainz.cpp 2015-03-23 20:09:33.000000000 +0000
@@ -77,6 +77,10 @@
static QString calculateDiscId(const QList &tracks)
{
+ if (tracks.isEmpty()) {
+ return QString();
+ }
+
// Code based on libmusicbrainz/lib/diskid.cpp
int numTracks = tracks.count()-1;
QCryptographicHash sha(QCryptographicHash::Sha1);
@@ -369,23 +373,17 @@
}
}
}
- }
- catch (MusicBrainz5::CConnectionError &e) {
+ } catch (MusicBrainz5::CConnectionError &e) {
DBUG << "MusicBrainz error" << e.what();
- }
- catch (MusicBrainz5::CTimeoutError &e) {
+ } catch (MusicBrainz5::CTimeoutError &e) {
DBUG << "MusicBrainz error - %1" << e.what();
- }
- catch (MusicBrainz5::CAuthenticationError &e) {
+ } catch (MusicBrainz5::CAuthenticationError &e) {
DBUG << "MusicBrainz error - %1" << e.what();
- }
- catch (MusicBrainz5::CFetchError &e) {
+ } catch (MusicBrainz5::CFetchError &e) {
DBUG << "MusicBrainz error - %1" << e.what();
- }
- catch (MusicBrainz5::CRequestError &e) {
+ } catch (MusicBrainz5::CRequestError &e) {
DBUG << "MusicBrainz error - %1" << e.what();
- }
- catch (MusicBrainz5::CResourceNotFoundError &e) {
+ } catch (MusicBrainz5::CResourceNotFoundError &e) {
DBUG << "MusicBrainz error - %1" << e.what();
}
diff -Nru cantata-1.4.2.ds1/devices/remotedevicepropertiesdialog.cpp cantata-1.5.2.ds2/devices/remotedevicepropertiesdialog.cpp
--- cantata-1.4.2.ds1/devices/remotedevicepropertiesdialog.cpp 2014-09-28 16:30:06.000000000 +0000
+++ cantata-1.5.2.ds2/devices/remotedevicepropertiesdialog.cpp 2015-03-23 20:09:32.000000000 +0000
@@ -88,7 +88,7 @@
case Ok: {
RemoteFsDevice::Details d=remoteProp->details();
if (d.name!=remoteProp->origDetails().name && DevicesModel::self()->device(RemoteFsDevice::createUdi(d.name))) {
- MessageBox::error(this, i18n("A remote device named \"%1\" already exists!\nPlease choose a different name", d.name));
+ MessageBox::error(this, i18n("A remote device named '%1' already exists!\n\nPlease choose a different name.", d.name));
} else {
emit updatedSettings(devProp->settings(), remoteProp->details());
accept();
diff -Nru cantata-1.4.2.ds1/devices/remotedevicepropertieswidget.ui cantata-1.5.2.ds2/devices/remotedevicepropertieswidget.ui
--- cantata-1.4.2.ds1/devices/remotedevicepropertieswidget.ui 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/remotedevicepropertieswidget.ui 2015-03-23 20:09:33.000000000 +0000
@@ -12,15 +12,9 @@
-
-
+
- <i><b>NOTE:</b> These settings are only editable when the device is not connected.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ These settings are only editable when the device is not connected.
@@ -161,15 +155,9 @@
-
-
+
- <i><b>NOTE:</b> If you enter a password here, it will be stored <b>unencrypted</b> in Cantata's config file. To have Cantata prompt for the password before accessing the share, set the password to '-'</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ If you enter a password here, it will be stored <b>unencrypted</b> in Cantata's config file. To have Cantata prompt for the password before accessing the share, set the password to '-'
@@ -264,9 +252,9 @@
-
-
+
- <i><b>NOTE:</b> If you enter a password here, it will be stored <b>unencrypted</b> in Cantata's config file. To have Cantata prompt for the password before accessing the share, set the password to '-'</i>
+ If you enter a password here, it will be stored <b>unencrypted</b> in Cantata's config file. To have Cantata prompt for the password before accessing the share, set the password to '-'
true
@@ -367,9 +355,9 @@
-
-
+
- <i><b>NOTE:</b> Due to the way sshfs works, a suitable ssh-askpass application (ksshaskpass, ssh-askpass-gnome, etc.) will be required to enter the password.</i>
+ Due to the way sshfs works, a suitable ssh-askpass application (ksshaskpass, ssh-askpass-gnome, etc.) will be required to enter the password.
true
@@ -417,24 +405,9 @@
-
-
-
-
- 0
- 0
-
-
+
- <i><b>NOTE:</b> This dialog is only used to add remote devices (e.g. via Samba), or to access locally mounted folders. For normal media players, attached via USB, Cantata will automatically display the device when it is attached.</i>
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- true
-
-
- Qt::NoTextInteraction
+ This dialog is only used to add remote devices (e.g. via Samba), or to access locally mounted folders. For normal media players, attached via USB, Cantata will automatically display the device when it is attached.
@@ -456,6 +429,11 @@
QLabel
+
+ PlainNoteLabel
+ QLabel
+
+
type
diff -Nru cantata-1.4.2.ds1/devices/synccollectionwidget.cpp cantata-1.5.2.ds2/devices/synccollectionwidget.cpp
--- cantata-1.4.2.ds1/devices/synccollectionwidget.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/synccollectionwidget.cpp 2015-03-23 20:09:33.000000000 +0000
@@ -33,7 +33,7 @@
#include
#include
-SyncCollectionWidget::SyncCollectionWidget(QWidget *parent, const QString &title, const QString &action, bool showCovers)
+SyncCollectionWidget::SyncCollectionWidget(QWidget *parent, const QString &title, const QString &action)
: QWidget(parent)
, performedSearch(false)
, searchTimer(0)
@@ -45,7 +45,6 @@
model=new MusicLibraryModel(this, false, true);
proxy=new MusicLibraryProxyModel(this);
- model->setUseAlbumImages(showCovers);
proxy->setSourceModel(model);
tree->setModel(proxy);
tree->setPageDefaults();
@@ -59,11 +58,11 @@
connect(search, SIGNAL(textChanged(const QString)), this, SLOT(delaySearchItems()));
copyAction=new Action(action, this);
- connect(copyAction, SIGNAL(triggered(bool)), SLOT(copySongs()));
+ connect(copyAction, SIGNAL(triggered()), SLOT(copySongs()));
checkAction=new Action(i18n("Check Items"), this);
- connect(checkAction, SIGNAL(triggered(bool)), SLOT(checkItems()));
+ connect(checkAction, SIGNAL(triggered()), SLOT(checkItems()));
unCheckAction=new Action(i18n("Uncheck Items"), this);
- connect(unCheckAction, SIGNAL(triggered(bool)), SLOT(unCheckItems()));
+ connect(unCheckAction, SIGNAL(triggered()), SLOT(unCheckItems()));
tree->addAction(copyAction);
QAction *sep=new QAction(this);
sep->setSeparator(true);
@@ -82,8 +81,8 @@
tree->addAction(collapse);
addAction(expand);
addAction(collapse);
- connect(expand, SIGNAL(triggered(bool)), this, SLOT(expandAll()));
- connect(collapse, SIGNAL(triggered(bool)), this, SLOT(collapseAll()));
+ connect(expand, SIGNAL(triggered()), this, SLOT(expandAll()));
+ connect(collapse, SIGNAL(triggered()), this, SLOT(collapseAll()));
}
connect(tree, SIGNAL(itemsSelected(bool)), checkAction, SLOT(setEnabled(bool)));
diff -Nru cantata-1.4.2.ds1/devices/synccollectionwidget.h cantata-1.5.2.ds2/devices/synccollectionwidget.h
--- cantata-1.4.2.ds1/devices/synccollectionwidget.h 2014-09-28 16:30:06.000000000 +0000
+++ cantata-1.5.2.ds2/devices/synccollectionwidget.h 2015-03-23 20:09:32.000000000 +0000
@@ -39,7 +39,7 @@
Q_OBJECT
public:
- SyncCollectionWidget(QWidget *parent, const QString &title, const QString &action, bool showCovers=true);
+ SyncCollectionWidget(QWidget *parent, const QString &title, const QString &action);
virtual ~SyncCollectionWidget();
void update(const QSet &songs) { model->update(songs); }
diff -Nru cantata-1.4.2.ds1/devices/syncdialog.cpp cantata-1.5.2.ds2/devices/syncdialog.cpp
--- cantata-1.4.2.ds1/devices/syncdialog.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/syncdialog.cpp 2015-03-23 20:09:33.000000000 +0000
@@ -99,8 +99,8 @@
iCount++;
QSplitter *splitter=new QSplitter(this);
- libWidget=new SyncCollectionWidget(splitter, i18n("Songs Only In Library:"), i18n("Copy To Device"), false);
- devWidget=new SyncCollectionWidget(splitter, i18n("Songs Only On Device:"), i18n("Copy To Library"), false);
+ libWidget=new SyncCollectionWidget(splitter, i18n("Songs Only In Library:"), i18n("Copy To Device"));
+ devWidget=new SyncCollectionWidget(splitter, i18n("Songs Only On Device:"), i18n("Copy To Library"));
setMainWidget(splitter);
setButtons(Close);
setAttribute(Qt::WA_DeleteOnClose);
diff -Nru cantata-1.4.2.ds1/devices/transcodingjob.cpp cantata-1.5.2.ds2/devices/transcodingjob.cpp
--- cantata-1.4.2.ds1/devices/transcodingjob.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/devices/transcodingjob.cpp 2015-03-23 20:09:33.000000000 +0000
@@ -71,7 +71,7 @@
void TranscodingJob::finished(int exitCode, QProcess::ExitStatus exitStatus)
{
- Q_UNUSED(exitStatus);
+ Q_UNUSED(exitStatus)
if (!process) {
return;
}
diff -Nru cantata-1.4.2.ds1/dynamic/cantata-dynamic cantata-1.5.2.ds2/dynamic/cantata-dynamic
--- cantata-1.4.2.ds1/dynamic/cantata-dynamic 2014-09-28 16:30:08.000000000 +0000
+++ cantata-1.5.2.ds2/dynamic/cantata-dynamic 2015-03-23 20:09:34.000000000 +0000
@@ -198,6 +198,12 @@
}
sub baseDir() {
+ if ($^O eq "darwin") {
+ # MacOSX
+ return "$ENV{'HOME'}/Library/Caches/cantata/cantata/dynamic";
+ }
+
+ # Linux
my $cacheDir=$ENV{'XDG_CACHE_HOME'};
if (!$cacheDir) {
$cacheDir="$ENV{'HOME'}/.cache";
@@ -249,12 +255,24 @@
$lastExcludeRules;
$initialRead=1;
$rulesTimestamp=0;
+$numMpdSongs=0;
+
+$ratingFrom=0;
+$ratingTo=0;
+# If we have no include rules, then song list is taken from tracks with ratings
+# Therefore, there is no need to subsequently filter - and ratingFilter woudl be
+# set to 0
+$ratingFilter=1;
+$lastRatingFrom=0;
+$lastRatingTo=0;
# Determine if rules file has been updated
sub checkRulesChanged() {
if ($initialRead==1) { # Always changed on first run...
$rulesChanged=1;
$initialRead=0;
+ } elsif ($lastRatingFrom!=$ratingFrom || $lastRatingTo!=$ratingTo) {
+ $rulesChanged=1;
} elsif ( scalar(@lastIncludeRules)!=scalar(@includeRules) ||
scalar(@lastExcludeRules)!=scalar(@excludeRules)) { # Different number of rules
$rulesChanged=1;
@@ -339,6 +357,7 @@
#
# File format:
#
+# Rating:
# Rule
# :
# :
@@ -346,6 +365,7 @@
#
# e.g.
#
+# Rating:1-5
# Rule
# AlbumArtist:Various Artists
# Genre:Dance
@@ -390,6 +410,8 @@
my $currentRule="";
@includeRules=();
@excludeRules=();
+ $ratingFrom=0;
+ $ratingTo=0;
close($fileHandle);
foreach my $line (@lines) {
if (! ($line=~ m/^(#)/)) {
@@ -411,12 +433,23 @@
@dates=();
@similarArtists=();
@genres=();
+ } elsif ($key=~ m/^(Rating)/) {
+ my @vals = split("-", $val);
+ if (scalar(@vals)==2) {
+ $ratingFrom=int($vals[0]);
+ $ratingTo=int($vals[1]);
+ if ($ratingFrom > $ratingTo) {
+ my $tmp=$ratingFrom;
+ $ratingFrom=$ratingTo;
+ $ratingTo=$tmp;
+ }
+ }
} else {
if ($key eq "Date") {
my @dateVals = split("-", $val);
if (scalar(@dateVals)==2) {
- my $fromDate=scalar($dateVals[0]);
- my $toDate=scalar($dateVals[1]);
+ my $fromDate=int($dateVals[0]);
+ my $toDate=int($dateVals[1]);
if ($fromDate > $toDate) { # Fix dates if from>to!!!
my $tmp=$fromDate;
$fromDate=$toDate;
@@ -461,7 +494,7 @@
@mpdArtists=uniq(@mpdArtists);
- # Now chec which last.fm artists MPD actually has...
+ # Now check which last.fm artists MPD actually has...
my $pos=0;
foreach my $artist (@artistSearchResults) {
my @match = grep(/^$artist/i, @mpdArtists);
@@ -494,7 +527,8 @@
foreach my $rule (@excludeRules) {
print "${rule}\n";
}
- print "---------------------\n"
+ print "---------------------\n";
+ print "RATING: ${ratingFrom} -> ${ratingTo}\n";
}
&checkRulesChanged();
@@ -515,10 +549,16 @@
my $method=shift;
my $argument=shift;
if (0==$isServerMode) {
- system("qdbus com.googlecode.cantata /cantata ${method} ${argument}");
- if ( $? == -1 ) {
- # Maybe qdbus is not installed? Try dbus-send...
- system("dbus-send --type=method_call --session --dest=com.googlecode.cantata /cantata com.googlecode.cantata.${method} string:${argument}");
+ if ($^O eq "darwin") {
+ # MacOSX
+ # TODO: How to send a dbus (or other) message to Cantata application????
+ } else {
+ # Linux
+ system("qdbus com.googlecode.cantata /cantata ${method} ${argument}");
+ if ( $? == -1 ) {
+ # Maybe qdbus is not installed? Try dbus-send...
+ system("dbus-send --type=method_call --session --dest=com.googlecode.cantata /cantata com.googlecode.cantata.${method} string:${argument}");
+ }
}
} else {
my $clientId=shift;
@@ -533,10 +573,81 @@
}
}
+# Parse sticker value, and check that its in range.
+sub songRatingInRange() {
+ my $stickerEntry=shift;
+ my @parts = split("=", $stickerEntry);
+ if (2==scalar(@parts)) {
+ my $rating=scalar($parts[1]);
+ if ($rating >= $ratingFrom && $rating <= $ratingTo) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+# Get all songs with a rating between ratingFrom & ratingTo
+sub getRatedSongs() {
+ my @entries = ();
+ my $data=&sendCommand("sticker find song / rating");
+ if (defined($data)) {
+ my @lines=split('\n', $data);
+ my $file="";
+ foreach my $line (@lines) {
+ if ($line=~ m/^(file\:)/) {
+ my $sep = index($line, ':');
+ if ($sep>0) {
+ $file=substr($line, $sep+2, length($line)-($sep+1));
+ }
+ } elsif ($line=~ m/^(sticker\:)/) {
+ my $sep = index($line, ':');
+ if ($sep>0) {
+ my $entry=substr($line, $sep+2, length($line)-($sep+1));
+ if (1==&songRatingInRange($entry)) {
+ push (@entries, $file);
+ }
+ }
+ }
+ }
+ }
+ return @entries;
+}
+
+# Is a file with rating from .. rating to?
+sub checkSongRatingInRange() {
+ if ($ratingFilter = 0) {
+ # Rating filter disabled - i,e. had no include rule, so song list is
+ # taken from those with a rating...
+ return 1;
+ }
+ if ($ratingFrom<=0 && $ratingTo<=0) { # No filter, so must be in range!
+ return 1;
+ }
+ if ($numMpdSongs<1) { # No songs!
+ return 0;
+ }
+ my $file=shift;
+ my @entries = &getEntries("sticker get song \"${file}\" rating", 'sticker');
+ foreach my $entry (@entries) {
+ if (1==&songRatingInRange($entry)) {
+ return 1;
+ }
+ }
+ # Song is not within range, so 'blank' its name out of list
+ my $pos=shift;
+ if (1==$testMode) {
+ print "$file is NOT in rating range - remove:${pos} total:${numMpdSongs}!\n";
+ }
+ splice @mpdSongs, $pos, 1;
+ $numMpdSongs--;
+ return 0;
+}
+
# Use rules to obtain a list of songs from MPD...
sub getSongs() {
# If we have no current songs, or rules have changed, or MPD has been updated - then we need to run the rules against MPD to get song list...
if (scalar(@mpdSongs)<1 || $rulesChanged==1 || $mpdDbUpdated==1) {
+ $numMpdSongs=0;
my @excludeSongs=();
if (scalar(@excludeRules)>0) {
# Get list of songs that should be removed from the song list...
@@ -566,6 +677,15 @@
}
@mpdSongs=uniq(@mpdSongs);
}
+ } elsif ($ratingTo>=1 && $ratingFrom>=0) {
+ if (1==$testMode) { print "No include rules, so get all songs in rating range ${ratingFrom}..${ratingTo}...\n"; }
+ my @songs = &getRatedSongs();
+ foreach my $song (@songs) {
+ if (! $excludeSongSet{$song}) {
+ $mpdSongs[$mpdSong]=$song;
+ $mpdSong++;
+ }
+ }
} else {
if (1==$testMode) { print "No include rules, so get all songs...\n"; }
# No 'include' rules => get all songs! Do this by getting all Artists, and then all songs by each...
@@ -601,6 +721,7 @@
}
print "---------------------\n"
}
+ $numMpdSongs=scalar(@mpdSongs);
}
}
@@ -738,33 +859,48 @@
&readRules();
&getSongs();
- my $numMpdSongs=scalar(@mpdSongs);
if ($numMpdSongs>0) {
# fill up playlist to 10 random tunes
my $failues=0;
my $added=0;
- while ($playQueueLength < $PLAY_QUEUE_DESIRED_LENGTH) {
+ while ($playQueueLength < $PLAY_QUEUE_DESIRED_LENGTH && $numMpdSongs>0) {
my $pos=int(rand($numMpdSongs));
- if ($failues > 100 || &canAdd(${mpdSongs[$pos]}, $numMpdSongs)) {
- my $file=${mpdSongs[$pos]};
- $file =~ s/\\/\\\\/g;
- $file =~ s/\"/\\\"/g;
- if (&sendCommand("add \"${file}\"") ne '') {
- &storeSong(${mpdSongs[$pos]});
- $playQueueLength++;
- $failues=0;
- $added++;
+ my $origFile=${mpdSongs[$pos]};
+ my $file=$origFile;
+ $file =~ s/\\/\\\\/g;
+ $file =~ s/\"/\\\"/g;
+
+ if (&checkSongRatingInRange($file, $pos)) {
+ if ($failues > 100 || &canAdd($origFile, $numMpdSongs)) {
+ if (&sendCommand("add \"${file}\"") ne '') {
+ &storeSong($origFile);
+ $playQueueLength++;
+ $failues=0;
+ $added++;
+ }
+ } else { # Song is already in playqueue history...
+ $failues++;
}
- } else { # Song is already in playqueue history...
- $failues++;
}
}
# If we are not currently playing and we filled playqueue - then play first!
- if ($isPlaying==0 && $added==$PLAY_QUEUE_DESIRED_LENGTH) {
+ if ($numMpdSongs>0 && $isPlaying==0 && $added==$PLAY_QUEUE_DESIRED_LENGTH) {
&sendCommand("play 0")
}
}
- &waitForEvent();
+
+ if ($numMpdSongs>0) {
+ &waitForEvent();
+ } else {
+ if (1==$isServerMode) {
+ $currentStatus="NO_SONGS";
+ $dynamicIsActive=0;
+ &sendStatus();
+ } else {
+ &sendMessage("showError", "NO_SONGS");
+ exit(0);
+ }
+ }
} elsif (0==$isServerMode) {
sleep 2;
}
diff -Nru cantata-1.4.2.ds1/dynamic/dynamic.cpp cantata-1.5.2.ds2/dynamic/dynamic.cpp
--- cantata-1.4.2.ds1/dynamic/dynamic.cpp 2014-09-28 16:30:08.000000000 +0000
+++ cantata-1.5.2.ds2/dynamic/dynamic.cpp 2015-03-23 20:09:34.000000000 +0000
@@ -141,9 +141,12 @@
const QString Dynamic::constTitleKey=QLatin1String("Title");
const QString Dynamic::constGenreKey=QLatin1String("Genre");
const QString Dynamic::constDateKey=QLatin1String("Date");
+const QString Dynamic::constRatingKey=QLatin1String("Rating");
const QString Dynamic::constExactKey=QLatin1String("Exact");
const QString Dynamic::constExcludeKey=QLatin1String("Exclude");
+const QChar Dynamic::constRangeSep=QLatin1Char('-');
+const QChar constKeyValSep=QLatin1Char(':');
const QString constOk=QLatin1String("0");
const QString constFilename=QLatin1String("FILENAME:");
@@ -206,13 +209,17 @@
}
switch (role) {
- case Qt::DisplayRole:
case Qt::ToolTipRole:
+ if (!Settings::self()->infoTooltips()) {
+ return QVariant();
+ }
+ case Qt::DisplayRole:
return entryList.at(index.row()).name;
case Qt::DecorationRole:
return IS_ACTIVE(entryList.at(index.row()).name) ? QIcon::fromTheme("media-playback-start") : Icons::self()->dynamicRuleIcon;
case Cantata::Role_SubText: {
- return Plurals::rules(entryList.at(index.row()).rules.count());
+ const Entry &e=entryList.at(index.row());
+ return Plurals::rules(e.rules.count())+(e.haveRating() ? i18n(" - Rating: %1..%2", (double)e.ratingFrom/Song::Rating_Step, (double)e.ratingTo/Song::Rating_Step) : QString());
}
case Cantata::Role_Actions: {
QVariant v;
@@ -252,13 +259,16 @@
QString string;
QTextStream str(&string);
+ if (e.ratingFrom!=0 || e.ratingTo!=0) {
+ str << constRatingKey << constKeyValSep << e.ratingFrom << constRangeSep << e.ratingTo<< '\n';
+ }
foreach (const Rule &rule, e.rules) {
if (!rule.isEmpty()) {
str << constRuleKey << '\n';
Rule::ConstIterator it(rule.constBegin());
Rule::ConstIterator end(rule.constEnd());
for (; it!=end; ++it) {
- str << it.key() << ':' << it.value() << '\n';
+ str << it.key() << constKeyValSep << it.value() << '\n';
}
}
}
@@ -529,8 +539,8 @@
foreach (const QString &rf, rulesFiles) {
QFile f(dirName+rf);
if (f.open(QIODevice::ReadOnly|QIODevice::Text)) {
- QStringList keys=QStringList() << constArtistKey << constSimilarArtistsKey << constAlbumArtistKey << constDateKey << constExactKey
- << constAlbumKey << constTitleKey << constGenreKey << constExcludeKey;
+ QStringList keys=QStringList() << constArtistKey << constSimilarArtistsKey << constAlbumArtistKey << constDateKey
+ << constExactKey << constAlbumKey << constTitleKey << constGenreKey << constExcludeKey;
Entry e;
e.name=rf.left(rf.length()-constExtension.length());
@@ -550,9 +560,15 @@
e.rules.append(r);
r.clear();
}
+ } else if (str.startsWith(constRatingKey+constKeyValSep)) {
+ QStringList vals=str.mid(constRatingKey.length()+1).split(constRangeSep);
+ if (2==vals.count()) {
+ e.ratingFrom=vals.at(0).toUInt();
+ e.ratingTo=vals.at(1).toUInt();
+ }
} else {
foreach (const QString &k, keys) {
- if (str.startsWith(k+':')) {
+ if (str.startsWith(k+constKeyValSep)) {
r.insert(k, str.mid(k.length()+1));
}
}
@@ -575,8 +591,8 @@
beginResetModel();
entryList.clear();
currentEntry=QString();
- QStringList keys=QStringList() << constArtistKey << constSimilarArtistsKey << constAlbumArtistKey << constDateKey << constExactKey
- << constAlbumKey << constTitleKey << constGenreKey << constExcludeKey;
+ QStringList keys=QStringList() << constArtistKey << constSimilarArtistsKey << constAlbumArtistKey << constDateKey
+ << constExactKey << constAlbumKey << constTitleKey << constGenreKey << constExcludeKey;
Entry e;
Rule r;
@@ -595,6 +611,7 @@
entryList.append(e);
}
e.name=str.mid(9, str.length()-15); // Remove extension...
+ e.ratingFrom=e.ratingTo=0;
e.rules.clear();
r.clear();
} else if (str==constRuleKey) {
@@ -602,9 +619,15 @@
e.rules.append(r);
r.clear();
}
+ } else if (str.startsWith(constRatingKey+constKeyValSep)) {
+ QStringList vals=str.mid(constRatingKey.length()+1).split(constRangeSep);
+ if (2==vals.count()) {
+ e.ratingFrom=vals.at(0).toUInt();
+ e.ratingTo=vals.at(1).toUInt();
+ }
} else {
foreach (const QString &k, keys) {
- if (str.startsWith(k+':')) {
+ if (str.startsWith(k+constKeyValSep)) {
r.insert(k, str.mid(k.length()+1));
}
}
diff -Nru cantata-1.4.2.ds1/dynamic/dynamic.h cantata-1.5.2.ds2/dynamic/dynamic.h
--- cantata-1.4.2.ds1/dynamic/dynamic.h 2014-09-28 16:30:08.000000000 +0000
+++ cantata-1.5.2.ds2/dynamic/dynamic.h 2015-03-23 20:09:34.000000000 +0000
@@ -56,10 +56,13 @@
typedef QMap Rule;
struct Entry {
- Entry(const QString &n=QString()) : name(n) { }
+ Entry(const QString &n=QString()) : name(n), ratingFrom(0), ratingTo(0) { }
bool operator==(const Entry &o) const { return name==o.name; }
+ bool haveRating() const { return ratingFrom>=0 && ratingTo>0; }
QString name;
QList rules;
+ int ratingFrom;
+ int ratingTo;
};
static Dynamic * self();
@@ -74,8 +77,10 @@
static const QString constTitleKey;
static const QString constGenreKey;
static const QString constDateKey;
+ static const QString constRatingKey;
static const QString constExactKey;
static const QString constExcludeKey;
+ static const QChar constRangeSep;
Dynamic();
virtual ~Dynamic() { }
diff -Nru cantata-1.4.2.ds1/dynamic/dynamicpage.cpp cantata-1.5.2.ds2/dynamic/dynamicpage.cpp
--- cantata-1.4.2.ds1/dynamic/dynamicpage.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/dynamic/dynamicpage.cpp 2015-03-23 20:09:34.000000000 +0000
@@ -136,7 +136,7 @@
QModelIndexList selected=view->selectedIndexes();
if (selected.isEmpty() ||
- MessageBox::No==MessageBox::warningYesNo(this, i18n("Are you sure you wish to remove the selected rules?\nThis cannot be undone."),
+ MessageBox::No==MessageBox::warningYesNo(this, i18n("Are you sure you wish to remove the selected rules?\n\nThis cannot be undone."),
i18n("Remove Dynamic Rules"), StdGuiItem::remove(), StdGuiItem::cancel())) {
return;
}
diff -Nru cantata-1.4.2.ds1/dynamic/dynamicruledialog.cpp cantata-1.5.2.ds2/dynamic/dynamicruledialog.cpp
--- cantata-1.4.2.ds1/dynamic/dynamicruledialog.cpp 2014-09-28 16:30:08.000000000 +0000
+++ cantata-1.5.2.ds2/dynamic/dynamicruledialog.cpp 2015-03-23 20:09:34.000000000 +0000
@@ -27,7 +27,6 @@
static const int constMinDate=1800;
static const int constMaxDate=2100;
-static const QChar constDateSep('-');
DynamicRuleDialog::DynamicRuleDialog(QWidget *parent)
: Dialog(parent)
@@ -125,7 +124,7 @@
int dateFrom=0;
int dateTo=0;
if (!date.isEmpty()) {
- int idx=date.indexOf(constDateSep);
+ int idx=date.indexOf(Dynamic::constRangeSep);
if (-1==idx) {
dateFrom=date.toInt();
} else {
@@ -184,7 +183,7 @@
bool haveTo=dateTo>=constMinDate && dateTo<=constMaxDate && dateTo!=dateFrom;
if (haveFrom && haveTo) {
- r.insert(Dynamic::constDateKey, QString::number(dateFrom)+constDateSep+QString::number(dateTo));
+ r.insert(Dynamic::constDateKey, QString::number(dateFrom)+Dynamic::constRangeSep+QString::number(dateTo));
} else if (haveFrom) {
r.insert(Dynamic::constDateKey, QString::number(dateFrom));
} else if (haveTo) {
diff -Nru cantata-1.4.2.ds1/dynamic/dynamicrulesdialog.cpp cantata-1.5.2.ds2/dynamic/dynamicrulesdialog.cpp
--- cantata-1.4.2.ds1/dynamic/dynamicrulesdialog.cpp 2014-09-28 16:30:07.000000000 +0000
+++ cantata-1.5.2.ds2/dynamic/dynamicrulesdialog.cpp 2015-03-23 20:09:34.000000000 +0000
@@ -188,6 +188,8 @@
model->setItem(model->rowCount(), 0, item);
}
origName=name;
+ ratingFrom->setValue(e.ratingFrom);
+ ratingTo->setValue(e.ratingTo);
show();
}
@@ -289,16 +291,20 @@
void DynamicRulesDialog::showAbout()
{
MessageBox::information(this,
+ #ifdef Q_OS_MAC
+ i18n("About dynamic rules")+QLatin1String(" ")+
+ #endif
i18n("Cantata will query your library using all of the rules listed. "
"The list of Include rules will be used to build a set of songs that can be used. "
"The list of Exclude rules will be used to build a set of songs that cannot be used. "
- "If there are no Include rules, Cantata will assume that all songs (bar those from Exclude ) can be used. "
- "e.g. to have Cantata look for 'Rock songs by Wibble OR songs by Various Artists', you would need the following: "
+ "If there are no Include rules, Cantata will assume that all songs (bar those from Exclude ) can be used.
"
+ "e.g. to have Cantata look for 'Rock songs by Wibble OR songs by Various Artists', you would need the following: "
"
Include AlbumArtist=Wibble Genre=Rock Include AlbumArtist=Various Artists "
"To have Cantata look for 'Songs by Wibble but not from album Abc', you would need the following: "
- "Include AlbumArtist=Wibble Exclude Album=Abc "
+ "Include AlbumArtist=Wibble Exclude AlbumArtist=Wibble Album=Abc "
"After the set of usable songs has been created, Cantata will randomly select songs to "
- "keep the play queue filled with 10 entries.")
+ "keep the play queue filled with 10 entries. If a range of ratings has been specified, then "
+ "only songs with a rating within this range will be used.")
);
}
@@ -326,13 +332,18 @@
}
if (name!=origName && Dynamic::self()->exists(name) &&
- MessageBox::No==MessageBox::warningYesNo(this, i18n("A set of rules named \'%1\' already exists!\nOverwrite?", name),
+ MessageBox::No==MessageBox::warningYesNo(this, i18n("A set of rules named '%1' already exists!\n\nOverwrite?", name),
i18n("Overwrite Rules"), StdGuiItem::overwrite(), StdGuiItem::cancel())) {
return false;
}
Dynamic::Entry entry;
entry.name=name;
+ int from=ratingFrom->value();
+ int to=ratingTo->value();
+ entry.ratingFrom=qMin(from, to);
+ entry.ratingTo=qMax(from, to);
+
for (int i=0; irowCount(); ++i) {
QStandardItem *itm=model->item(i);
if (itm) {
@@ -347,7 +358,6 @@
}
}
-
bool saved=Dynamic::self()->save(entry);
if (Dynamic::self()->isRemote()) {
diff -Nru cantata-1.4.2.ds1/dynamic/dynamicrules.ui cantata-1.5.2.ds2/dynamic/dynamicrules.ui
--- cantata-1.4.2.ds1/dynamic/dynamicrules.ui 2014-09-28 16:30:08.000000000 +0000
+++ cantata-1.5.2.ds2/dynamic/dynamicrules.ui 2015-03-23 20:09:34.000000000 +0000
@@ -81,7 +81,44 @@
- -
+
-
+
+ -
+
+
+ Song with ratings between:
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 2
+ 2
+
+
+
+
+
+
+ -
@@ -94,7 +131,7 @@
- -
+
-
Qt::Horizontal
@@ -134,6 +171,11 @@
1
+
+ RatingWidget
+ QWidget
+
+
diff -Nru cantata-1.4.2.ds1/dynamic/dynamicrule.ui cantata-1.5.2.ds2/dynamic/dynamicrule.ui
--- cantata-1.4.2.ds1/dynamic/dynamicrule.ui 2014-09-28 16:30:08.000000000 +0000
+++ cantata-1.5.2.ds2/dynamic/dynamicrule.ui 2015-03-23 20:09:34.000000000 +0000
@@ -223,66 +223,16 @@
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 4
-
-
-
-
- -
-
+
- <i><b>NOTE</b> Only enter values for the tags you wish to be search on. </i>
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- true
-
-
- Qt::NoTextInteraction
+ Only enter values for the tags you wish to be search on.
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 4
-
-
-
-
- -
-
+
- <i><b>NOTE</b> For genre, end string with an asterisk to match various genres. e.g 'rock*' matches 'Hard Rock' and 'Rock and Roll'. </i>
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- true
-
-
- Qt::NoTextInteraction
+ For genre, end string with an asterisk to match various genres. e.g 'rock*' matches 'Hard Rock' and 'Rock and Roll'.
@@ -311,6 +261,11 @@
+ NoteLabel
+ QLabel
+
+
+
LineEdit
QLineEdit
diff -Nru cantata-1.4.2.ds1/dynamic/init/cantata-dynamic.systemd cantata-1.5.2.ds2/dynamic/init/cantata-dynamic.systemd
--- cantata-1.4.2.ds1/dynamic/init/cantata-dynamic.systemd 2014-09-28 16:30:08.000000000 +0000
+++ cantata-1.5.2.ds2/dynamic/init/cantata-dynamic.systemd 2015-03-23 20:09:34.000000000 +0000
@@ -1,12 +1,16 @@
[Unit]
Description=Cantata Dynamic Server
+Wants=mpd.service
+After=mpd.service
[Service]
-User=root
+User=mpd
+Group=audio
Type=forking
ExecStart=/usr/share/cantata/scripts/cantata-dynamic server /etc/cantata-dynamic.conf
ExecStop=/usr/share/cantata/scripts/cantata-dynamic stopserver /etc/cantata-dynamic.conf
-PIDFile=/var/run/cantata-dynamic/pid
+RuntimeDirectory=cantata-dynamic
+PIDFile=/run/cantata-dynamic/pid
[Install]
WantedBy=multi-user.target
diff -Nru cantata-1.4.2.ds1/gui/albumspage.cpp cantata-1.5.2.ds2/gui/albumspage.cpp
--- cantata-1.4.2.ds1/gui/albumspage.cpp 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/albumspage.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -41,7 +41,6 @@
replacePlayQueue->setDefaultAction(StdActions::self()->replacePlayQueueAction);
view->addAction(StdActions::self()->addToPlayQueueAction);
- view->addAction(StdActions::self()->addRandomToPlayQueueAction);
view->addAction(StdActions::self()->replacePlayQueueAction);
view->addAction(StdActions::self()->addWithPriorityAction);
view->addAction(StdActions::self()->addToStoredPlaylistAction);
@@ -56,9 +55,7 @@
#endif
view->addAction(StdActions::self()->setCoverAction);
#ifdef ENABLE_DEVICES_SUPPORT
- QAction *sep=new QAction(this);
- sep->setSeparator(true);
- view->addAction(sep);
+ view->addSeparator();
view->addAction(StdActions::self()->deleteSongsAction);
#endif
#endif // TAGLIB_FOUND
@@ -74,10 +71,10 @@
connect(view, SIGNAL(itemsSelected(bool)), this, SLOT(controlActions()));
connect(view, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(itemDoubleClicked(const QModelIndex &)));
connect(view, SIGNAL(rootIndexSet(QModelIndex)), this, SLOT(updateGenres(QModelIndex)));
- connect(MPDConnection::self(), SIGNAL(updatingLibrary()), this, SLOT(showSpinner()));
- connect(MPDConnection::self(), SIGNAL(updatedLibrary()), this, SLOT(hideSpinner()));
- connect(MPDConnection::self(), SIGNAL(updatingDatabase()), this, SLOT(showSpinner()));
- connect(MPDConnection::self(), SIGNAL(updatedDatabase()), this, SLOT(hideSpinner()));
+ connect(MPDConnection::self(), SIGNAL(updatingLibrary()), view, SLOT(updating()));
+ connect(MPDConnection::self(), SIGNAL(updatedLibrary()), view, SLOT(updated()));
+ connect(MPDConnection::self(), SIGNAL(updatingDatabase()), view, SLOT(updating()));
+ connect(MPDConnection::self(), SIGNAL(updatedDatabase()), view, SLOT(updated()));
view->load(metaObject()->className());
}
@@ -86,13 +83,6 @@
view->save(metaObject()->className());
}
-void AlbumsPage::setView(int v)
-{
- setItemSize(v);
- view->setMode((ItemView::Mode)v);
- AlbumsModel::self()->setIconMode(ItemView::Mode_IconTop==v);
-}
-
void AlbumsPage::showEvent(QShowEvent *e)
{
view->focusView();
@@ -105,70 +95,13 @@
view->update();
}
-void AlbumsPage::setItemSize(int v)
-{
- if (ItemView::Mode_IconTop!=v) {
- AlbumsModel::setItemSize(QSize(0, 0));
- } else {
- QFontMetrics fm(font());
-
- int size=AlbumsModel::iconSize();
- QSize grid(size+8, size+(fm.height()*2.5));
- view->setGridSize(grid);
- AlbumsModel::setItemSize(grid-QSize(4, 4));
- }
-}
-
-QStringList AlbumsPage::selectedFiles(bool allowPlaylists, bool randomAlbums) const
+QStringList AlbumsPage::selectedFiles(bool allowPlaylists) const
{
QModelIndexList selected = view->selectedIndexes();
if (selected.isEmpty()) {
return QStringList();
}
- bool filteredOnly=proxy.enabled() && Settings::self()->filteredOnly();
- QModelIndexList mapped=proxy.mapToSource(selected, filteredOnly);
- if (randomAlbums) {
- if (filteredOnly) {
- QMap albums;
- foreach (const QModelIndex &idx, mapped) {
- if (idx.parent().isValid()) {
- albums[idx.parent().row()].append(idx);
- }
- }
- QList keys=albums.keys();
- if (keys.isEmpty()) {
- return QStringList();
- } else if (1==keys.count()) {
- mapped=albums.begin().value();
- } else {
- mapped.clear();
- while (!keys.isEmpty()) {
- mapped.append(albums[keys.takeAt(Utils::random(keys.count()))]);
- }
- }
- } else {
- QModelIndexList albumIndexes;
- foreach (const QModelIndex &idx, mapped) {
- if (static_cast(idx.internalPointer())->isAlbum()) {
- albumIndexes.append(idx);
- }
- }
-
- if (albumIndexes.isEmpty()) {
- return QStringList();
- }
-
- if (1==albumIndexes.count()) {
- mapped=albumIndexes;
- } else {
- mapped.clear();
- while (!albumIndexes.isEmpty()) {
- mapped.append(albumIndexes.takeAt(Utils::random(albumIndexes.count())));
- }
- }
- }
- }
- return AlbumsModel::self()->filenames(mapped, allowPlaylists);
+ return AlbumsModel::self()->filenames(proxy.mapToSource(selected, proxy.enabled() && Settings::self()->filteredOnly()), allowPlaylists);
}
QList AlbumsPage::selectedSongs(bool allowPlaylists) const
@@ -193,9 +126,9 @@
return Song();
}
-void AlbumsPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty, bool randomAlbums)
+void AlbumsPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty)
{
- QStringList files=selectedFiles(name.isEmpty(), randomAlbums);
+ QStringList files=selectedFiles(name.isEmpty());
if (!files.isEmpty()) {
if (name.isEmpty()) {
@@ -223,7 +156,7 @@
QList songs=selectedSongs();
if (!songs.isEmpty()) {
- if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to delete the selected songs?\nThis cannot be undone."),
+ if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to delete the selected songs?\n\nThis cannot be undone."),
i18n("Delete Songs"), StdGuiItem::del(), StdGuiItem::cancel())) {
emit deleteSongs(QString(), songs);
}
@@ -281,27 +214,4 @@
#endif
#endif // TAGLIB_FOUND
StdActions::self()->setCoverAction->setEnabled(1==selected.count() && static_cast(proxy.mapToSource(selected.at(0)).internalPointer())->isAlbum());
-
- bool allowRandomAlbum=!selected.isEmpty();
- if (allowRandomAlbum) {
- foreach (const QModelIndex &idx, selected) {
- if (!static_cast(proxy.mapToSource(idx).internalPointer())->isAlbum()) {
- allowRandomAlbum=false;
- break;
- }
- }
- }
- StdActions::self()->addRandomToPlayQueueAction->setEnabled(allowRandomAlbum);
-}
-
-void AlbumsPage::showSpinner()
-{
- view->showSpinner();
- view->showMessage(i18n("Updating..."), -1);
-}
-
-void AlbumsPage::hideSpinner()
-{
- view->hideSpinner();
- view->showMessage(QString(), 0);
}
diff -Nru cantata-1.4.2.ds1/gui/albumspage.h cantata-1.5.2.ds2/gui/albumspage.h
--- cantata-1.4.2.ds1/gui/albumspage.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/albumspage.h 2015-03-23 20:09:42.000000000 +0000
@@ -40,19 +40,20 @@
virtual ~AlbumsPage();
void clear();
- QStringList selectedFiles(bool allowPlaylists=false, bool randomAlbums=false) const;
+ QStringList selectedFiles(bool allowPlaylists=false) const;
QList selectedSongs(bool allowPlaylists=false) const;
Song coverRequest() const;
- void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0, bool randomAlbums=false);
+ void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0);
#ifdef ENABLE_DEVICES_SUPPORT
void addSelectionToDevice(const QString &udi);
void deleteSongs();
#endif
- void setView(int v);
+ void setView(int v) { view->setMode((ItemView::Mode)v); }
ItemView::Mode viewMode() const { return view->viewMode(); }
void focusSearch() { view->focusSearch(); }
void goTop() { view->goToTop(); }
void showEvent(QShowEvent *e);
+ void resort() { proxy.resort(); }
private:
void setItemSize(int v);
@@ -70,8 +71,6 @@
void controlActions();
void searchItems();
void updateGenres(const QModelIndex &);
- void showSpinner();
- void hideSpinner();
private:
AlbumsProxyModel proxy;
diff -Nru cantata-1.4.2.ds1/gui/application.cpp cantata-1.5.2.ds2/gui/application.cpp
--- cantata-1.4.2.ds1/gui/application.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/application.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -35,7 +35,6 @@
#include "widgets/itemview.h"
#include "widgets/groupedview.h"
#include "widgets/actionitemdelegate.h"
-#include "models/musiclibraryitemalbum.h"
void Application::initObjects()
{
@@ -57,5 +56,4 @@
FancyTabWidget::setup();
GroupedView::setup();
ActionItemDelegate::setup();
- MusicLibraryItemAlbum::setup();
}
diff -Nru cantata-1.4.2.ds1/gui/application_kde.cpp cantata-1.5.2.ds2/gui/application_kde.cpp
--- cantata-1.4.2.ds1/gui/application_kde.cpp 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/application_kde.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -33,6 +33,11 @@
: KUniqueApplication(display, visual, colormap)
, w(0)
{
+ #if QT_VERSION >= 0x050400
+ if (Settings::self()->retinaSupport()) {
+ setAttribute(Qt::AA_UseHighDpiPixmaps);
+ }
+ #endif
}
#endif
@@ -40,6 +45,11 @@
: KUniqueApplication()
, w(0)
{
+ #if QT_VERSION >= 0x050400
+ if (Settings::self()->retinaSupport()) {
+ setAttribute(Qt::AA_UseHighDpiPixmaps);
+ }
+ #endif
}
Application::~Application() {
diff -Nru cantata-1.4.2.ds1/gui/application_mac.cpp cantata-1.5.2.ds2/gui/application_mac.cpp
--- cantata-1.4.2.ds1/gui/application_mac.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/application_mac.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -22,13 +22,19 @@
*/
#include "application_mac.h"
+#include "settings.h"
#include "support/utils.h"
#include
Application::Application(int &argc, char **argv)
: SingleApplication(argc, argv)
{
- QCoreApplication::setAttribute(Qt::AA_DontShowIconsInMenus, true);
+ setAttribute(Qt::AA_DontShowIconsInMenus, true);
+ #if QT_VERSION >= 0x050100
+ if (Settings::self()->retinaSupport()) {
+ setAttribute(Qt::AA_UseHighDpiPixmaps);
+ }
+ #endif
// Setup icon path...
QStringList paths=QIcon::themeSearchPaths();
@@ -39,4 +45,3 @@
QIcon::setThemeName(QLatin1String("oxygen"));
}
-
diff -Nru cantata-1.4.2.ds1/gui/application_qt.cpp cantata-1.5.2.ds2/gui/application_qt.cpp
--- cantata-1.4.2.ds1/gui/application_qt.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/application_qt.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -58,6 +58,11 @@
Application::Application(int &argc, char **argv)
: QApplication(argc, argv)
{
+ #if QT_VERSION >= 0x050400
+ if (Settings::self()->retinaSupport()) {
+ setAttribute(Qt::AA_UseHighDpiPixmaps);
+ }
+ #endif
}
bool Application::start()
diff -Nru cantata-1.4.2.ds1/gui/application_win.cpp cantata-1.5.2.ds2/gui/application_win.cpp
--- cantata-1.4.2.ds1/gui/application_win.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/application_win.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -22,6 +22,7 @@
*/
#include "application_win.h"
+#include "settings.h"
#include
#include
@@ -32,6 +33,11 @@
installNativeEventFilter(this);
#endif
QIcon::setThemeName(QLatin1String("oxygen"));
+ #if QT_VERSION >= 0x050400
+ if (Settings::self()->retinaSupport()) {
+ setAttribute(Qt::AA_UseHighDpiPixmaps);
+ }
+ #endif
}
#if QT_VERSION >= 0x050000
diff -Nru cantata-1.4.2.ds1/gui/cachesettings.cpp cantata-1.5.2.ds2/gui/cachesettings.cpp
--- cantata-1.4.2.ds1/gui/cachesettings.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/cachesettings.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -337,12 +337,14 @@
toDelete.first()->clean();
}
} else if (toDelete.count()>1) {
+ static const QChar constBullet(0x2022);
+
QString items;
foreach (CacheItem *i, toDelete) {
- items+=""+i->name()+" ";
+ items+=constBullet+QLatin1Char(' ')+i->name()+QLatin1Char('\n');
}
- if (MessageBox::No==MessageBox::warningYesNo(this, i18n("Delete all from the following?
", items),
+ if (MessageBox::No==MessageBox::warningYesNo(this, i18n("Delete items from all selected categories?")+QLatin1String("\n\n")+items,
i18n("Delete Cache Items"), StdGuiItem::del(), StdGuiItem::cancel())) {
return;
}
diff -Nru cantata-1.4.2.ds1/gui/coverdialog.cpp cantata-1.5.2.ds2/gui/coverdialog.cpp
--- cantata-1.4.2.ds1/gui/coverdialog.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/coverdialog.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -356,7 +356,7 @@
, showAction(0)
, removeAction(0)
{
- Configuration cfg("CoverDialog");
+ Configuration cfg(objectName());
enabledProviders=cfg.get("enabledProviders", (int)Prov_All);
iCount++;
@@ -395,7 +395,7 @@
list->setSpacing(spacing);
list->setViewMode(QListView::IconMode);
list->setResizeMode(QListView::Adjust);
- list->setMinimumSize((list->gridSize().width()*4)+(spacing*5), list->gridSize().height()*3);
+ list->setMinimumSize((list->gridSize().width()*3)+style()->pixelMetric(QStyle::PM_ScrollBarExtent)+spacing, list->gridSize().height()*2);
list->setSortingEnabled(false);
addFileButton->setIcon(Icon("document-open"));
@@ -419,7 +419,7 @@
CoverDialog::~CoverDialog()
{
- Configuration cfg("CoverDialog");
+ Configuration cfg(objectName());
cfg.set("enabledProviders", enabledProviders);
iCount--;
@@ -433,7 +433,7 @@
isArtist=song.isArtistImageRequest();
Covers::Image img=current.img.isNull() ? Covers::locateImage(song) : current;
- if (!img.fileName.isEmpty() && !QFileInfo(img.fileName).isWritable()) {
+ if (img.validFileName() && !QFileInfo(img.fileName).isWritable()) {
MessageBox::error(parentWidget(),
(isArtist
? i18n("An image already exists for this artist, and the file is not writeable.")
@@ -452,7 +452,6 @@
list->addItem(existing);
}
query->setText(isArtist ? song.albumArtist() : QString(song.albumArtist()+QLatin1String(" ")+song.album));
- adjustSize();
Dialog::show();
sendQuery();
}
@@ -574,7 +573,7 @@
previewDialog()->showImage(cropImage(img, isArtist), reply->property(constLargeProperty).toString());
} else if (DL_LargeSave==dlType) {
if (!temp) {
- MessageBox::error(this, i18n("Failed to set cover!\nCould not download to temporary file!"));
+ MessageBox::error(this, i18n("Failed to set cover!\n\nCould not download to temporary file!"));
} else if (saveCover(temp->fileName(), img)) {
accept();
}
@@ -886,8 +885,8 @@
menu=new QMenu(list);
showAction=menu->addAction(Icon("zoom-original"), i18n("Display"));
removeAction=menu->addAction(Icon("list-remove"), i18n("Remove"));
- connect(showAction, SIGNAL(triggered(bool)), SLOT(showImage()));
- connect(removeAction, SIGNAL(triggered(bool)), SLOT(removeImages()));
+ connect(showAction, SIGNAL(triggered()), SLOT(showImage()));
+ connect(removeAction, SIGNAL(triggered()), SLOT(removeImages()));
}
QList items=list->selectedItems();
@@ -1348,16 +1347,16 @@
return true;
}
}
- MessageBox::error(this, i18n("Failed to set cover!\nCould not make copy!"));
+ MessageBox::error(this, i18n("Failed to set cover!\n\nCould not make copy!"));
return false;
}
QString existingBackup;
- if (existing && !existing->url().isEmpty()) {
+ if (existing && !existing->url().isEmpty() && !existing->url().startsWith(Covers::constCoverInTagPrefix)) {
static const QLatin1String constBakExt(".bak");
existingBackup=existing->url()+constBakExt;
if (!QFile::rename(existing->url(), existingBackup)) {
- MessageBox::error(this, i18n("Failed to set cover!\nCould not backup original!"));
+ MessageBox::error(this, i18n("Failed to set cover!\n\nCould not backup original!"));
return false;
}
}
@@ -1398,13 +1397,13 @@
if (!existingBackup.isEmpty() && QFile::exists(existingBackup)) {
QFile::remove(existingBackup);
}
- Covers::self()->emitCoverUpdated(song, img, destName);
+ Covers::self()->updateCover(song, img, destName);
return true;
} else {
if (existing && !existingBackup.isEmpty()) {
QFile::rename(existingBackup, existing->url());
}
- MessageBox::error(this, i18n("Failed to set cover!\nCould not copy file to '%1'!", destName));
+ MessageBox::error(this, i18n("Failed to set cover!\n\nCould not copy file to '%1'!", destName));
return false;
}
}
diff -Nru cantata-1.4.2.ds1/gui/coverdialog.ui cantata-1.5.2.ds2/gui/coverdialog.ui
--- cantata-1.4.2.ds1/gui/coverdialog.ui 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/coverdialog.ui 2015-03-23 20:09:42.000000000 +0000
@@ -25,14 +25,14 @@
-
-
+
Add a local file
-
-
+
Configure
@@ -45,6 +45,11 @@
+ FlatToolButton
+ QToolButton
+
+
+
LineEdit
QLineEdit
diff -Nru cantata-1.4.2.ds1/gui/covers.cpp cantata-1.5.2.ds2/gui/covers.cpp
--- cantata-1.4.2.ds1/gui/covers.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/covers.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -33,12 +33,18 @@
#ifdef ENABLE_ONLINE_SERVICES
#include "online/soundcloudservice.h"
#include "online/podcastservice.h"
+#include "online/jamendoservice.h"
#include "models/onlineservicesmodel.h"
#endif
+#ifdef ENABLE_DEVICES_SUPPORT
+#include "devices/device.h"
+#include "models/devicesmodel.h"
+#endif
#ifdef TAGLIB_FOUND
#include "tags/tags.h"
#endif
#include "support/globalstatic.h"
+#include "widgets/icons.h"
#include
#include
#include
@@ -54,10 +60,9 @@
#include
#include
#include
-#include
+#include
#ifdef ENABLE_KDE_SUPPORT
#include
-#include
#endif
GLOBAL_STATIC(Covers, instance)
@@ -82,11 +87,18 @@
const QLatin1String Covers::constCddaCoverDir("cdda/");
const QLatin1String Covers::constFileName("cover");
const QLatin1String Covers::constArtistImage("artist");
+const QString Covers::constCoverInTagPrefix=QLatin1String("{tag}");
static const char * constExtensions[]={".jpg", ".png", 0};
static bool saveInMpdDir=true;
static bool fetchCovers=true;
-static QString constCoverInTagPrefix=QLatin1String("{tag}");
+static QString constNoCover=QLatin1String("{nocover}");
+
+#if QT_VERSION >= 0x050100
+static double devicePixelRatio=1.0;
+// Only scale images to device pixel ratio if un-scaled size is less then 300pixels.
+static const int constRetinaScaleMaxSize=300;
+#endif
static QImage scale(const Song &song, const QImage &img, int size)
{
@@ -168,6 +180,7 @@
return img;
}
+
static inline bool isOnlineServiceImage(const Song &s)
{
#ifdef ENABLE_ONLINE_SERVICES
@@ -199,6 +212,12 @@
static inline QString albumKey(const Song &s)
{
+ if (Song::SingleTracks==s.type) {
+ return QLatin1String("-single-tracks-");
+ }
+ if (s.isStandardStream()) {
+ return QLatin1String("-stream-");
+ }
#ifdef ENABLE_ONLINE_SERVICES
if (isOnlineServiceImage(s)) {
return s.onlineService();
@@ -214,10 +233,23 @@
static inline QString cacheKey(const Song &song, int size)
{
+ if (song.isArtistImageRequest() && song.isVariousArtists()) {
+ return QLatin1String("va")+QString::number(size);
+ } else if (Song::SingleTracks==song.type) {
+ return QLatin1String("single")+QString::number(size);
+ } else if (song.isStandardStream()) {
+ return QLatin1String("str")+QString::number(size);
+ }
+ #ifdef ENABLE_ONLINE_SERVICES
+ else if (isOnlineServiceImage(song)) {
+ return song.onlineService()+QString::number(size);
+ }
+ #endif
+
return (song.isArtistImageRequest() ? artistKey(song) : albumKey(song))+QString::number(size);
}
-static const QLatin1String constScaledFormat(".png");
+static const QLatin1String constScaledFormat(".jpg");
static bool cacheScaledCovers=true;
static QString getScaledCoverName(const Song &song, int size, bool createDir)
@@ -244,6 +276,7 @@
return;
}
+ DBUG_CLASS("Covers") << song.file << song.artist << song.albumartist << song.album;
QStringList sizeDirNames=d.entryList(QStringList() << "*", QDir::Dirs|QDir::NoDotAndDotDot);
if (artistImage) {
@@ -275,13 +308,13 @@
QString fileName=getScaledCoverName(song, size, false);
if (!fileName.isEmpty()) {
if (QFile::exists(fileName)) {
- QImage img(fileName, "PNG");
+ QImage img(fileName, "JPG");
if (!img.isNull() && (img.width()==size || img.height()==size)) {
DBUG_CLASS("Covers") << song.albumArtist() << song.albumId() << size << "scaled cover found" << fileName;
return img;
}
- } else { // Remove any previous JPG scaled cover...
- fileName=Utils::changeExtension(fileName, ".jpg");
+ } else { // Remove any previous PNG scaled cover...
+ fileName=Utils::changeExtension(fileName, ".png");
if (QFile::exists(fileName)) {
QFile::remove(fileName);
}
@@ -307,21 +340,34 @@
QString Covers::encodeName(QString name)
{
- name.replace("/", "_");
+ name.replace(QLatin1Char('/'), QLatin1Char('_'));
+ #if defined Q_OS_WIN
+ name.replace(QLatin1Char('?'), QLatin1Char('_'));
+ name.replace(QLatin1Char(':'), QLatin1Char('_'));
+ name.replace(QLatin1Char('<'), QLatin1Char('_'));
+ name.replace(QLatin1Char('>'), QLatin1Char('_'));
+ name.replace(QLatin1Char('\\'), QLatin1Char('_'));
+ name.replace(QLatin1Char('*'), QLatin1Char('_'));
+ name.replace(QLatin1Char('|'), QLatin1Char('_'));
+ name.replace(QLatin1Char('\"'), QLatin1Char('_'));
+ #elif defined Q_OS_MAC
+ name.replace(QLatin1Char(':'), QLatin1Char('_'));
+ if (name.startsWith(QLatin1Char('.'))) {
+ name[0]=QLatin1Char('_');
+ }
+ if (name.length()>255) {
+ name=name.left(255);
+ }
+ #else // Linux
#ifdef ENABLE_UBUNTU
// qrc:/ does not seem to like ?
- name.replace("?", "_");
- name.replace(":", "_");
- name.replace("%", "_");
- #elif defined Q_OS_WIN
- name.replace("?", "_");
- name.replace(":", "_");
- name.replace("<", "_");
- name.replace(">", "_");
- name.replace("\\", "_");
- name.replace("*", "_");
- name.replace("|", "_");
- name.replace("\"", "_");
+ name.replace(QLatin1Char('?'), QLatin1Char('_'));
+ name.replace(QLatin1Char(':'), QLatin1Char('_'));
+ name.replace(QLatin1Char('%'), QLatin1Char('_'));
+ #endif // ENABLE_UBUNTU
+ if (name.startsWith(QLatin1Char('.'))) {
+ name[0]=QLatin1Char('_');
+ }
#endif
return name;
}
@@ -333,11 +379,11 @@
coverName=Covers::constFileName;
}
#ifndef ENABLE_UBUNTU
- else if (coverName.contains("%")) {
+ else if (coverName.contains(QLatin1Char('%'))) {
coverName.replace(DeviceOptions::constAlbumArtist, encodeName(song.albumArtist()));
coverName.replace(DeviceOptions::constTrackArtist, encodeName(song.albumArtist()));
coverName.replace(DeviceOptions::constAlbumTitle, encodeName(song.album));
- coverName.replace("%", "");
+ coverName.replace(QLatin1String("%"), QLatin1String(""));
}
#endif
return coverName;
@@ -346,7 +392,7 @@
QString Covers::artistFileName(const Song &song)
{
QString coverName=MPDConnection::self()->getDetails().coverName;
- if (coverName.contains("%")){
+ if (coverName.contains(QLatin1Char('%'))) {
return encodeName(song.albumArtist());
}
return constArtistImage;
@@ -515,6 +561,29 @@
void CoverDownloader::download(const Song &song)
{
DBUG << song.file << song.artist << song.albumartist << song.album;
+ #ifdef ENABLE_ONLINE_SERVICES
+ if (song.isFromOnlineService()) {
+ QString serviceName=song.onlineService();
+ QString imageUrl=song.extraField(Song::OnlineImageUrl);
+ // Jamendo image URL is just the album ID!
+ if (!imageUrl.isEmpty() && !imageUrl.startsWith("http:/") && imageUrl.length()<15 && serviceName==JamendoService::constName) {
+ imageUrl=JamendoService::imageUrl(imageUrl);
+ }
+
+ Job job(song, QString(), false);
+ job.type=JobHttpJpg;
+ DBUG << "Online image url" << imageUrl;
+ if (!imageUrl.isEmpty()) {
+ NetworkJob *j=network()->get(imageUrl);
+ jobs.insert(j, job);
+ connect(j, SIGNAL(finished()), this, SLOT(onlineJobFinished()));
+ } else {
+ failed(job);
+ }
+ return;
+ }
+ #endif
+
bool isArtistImage=song.isArtistImageRequest();
if (jobs.end()!=findJob(Job(song, QString(), isArtistImage))) {
@@ -728,13 +797,62 @@
reply->deleteLater();
}
+void CoverDownloader::onlineJobFinished()
+{
+ #ifdef ENABLE_ONLINE_SERVICES
+ NetworkJob *reply=qobject_cast(sender());
+
+ if (!reply) {
+ return;
+ }
+ reply->deleteLater();
+
+ DBUG << "status" << reply->error() << reply->errorString();
+
+ QHash::Iterator it(jobs.find(reply));
+ QHash::Iterator end(jobs.end());
+
+ if (it!=end) {
+ QByteArray data=QNetworkReply::NoError==reply->error() ? reply->readAll() : QByteArray();
+ if (data.isEmpty()) {
+ DBUG << reply->url().toString() << "empty!";
+ return;
+ }
+
+ Job job=it.value();
+ const Song &song=job.song;
+ QString id=song.onlineService();
+ QString fileName;
+ QImage img=data.isEmpty() ? QImage() : QImage::fromData(data, Covers::imageFormat(data));
+
+ bool png=Covers::isPng(data);
+ DBUG << "Got image" << id << song.artist << song.album << png;
+ if (!img.isNull()) {
+ if (img.size().width()>Covers::constMaxSize.width() || img.size().height()>Covers::constMaxSize.height()) {
+ img=img.scaled(Covers::constMaxSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
+ QString cacheName=song.extraField(Song::OnlineImageCacheName);
+ fileName=cacheName.isEmpty()
+ ? Utils::cacheDir(id.toLower(), true)+Covers::encodeName(song.album.isEmpty() ? song.artist : (song.artist+" - "+song.album))+(png ? ".png" : ".jpg")
+ : cacheName;
+ QFile f(fileName);
+ if (f.open(QIODevice::WriteOnly)) {
+ DBUG << "Saved image to" << fileName;
+ f.write(data);
+ }
+ }
+ emit cover(job.song, img, fileName);
+ }
+ #endif
+}
+
void CoverDownloader::failed(const Job &job)
{
if (job.isArtist) {
- DBUG << "failed to download artist image";
+ DBUG << "artist image" << job.song.artist;
emit artistImage(job.song, QImage(), QString());
} else {
- DBUG << "Failed to download cover image";
+ DBUG << "cover image" << job.song.artist << job.song.album;
emit cover(job.song, QImage(), QString());
}
}
@@ -926,7 +1044,13 @@
QList covers;
foreach (const LoadedCover &s, toDo) {
DBUG << s.song.artist << s.song.albumId() << s.song.size;
- covers.append(LoadedCover(s.song, loadScaledCover(s.song, s.song.size)));
+ int size=s.song.size;
+ #if QT_VERSION >= 0x050100
+ if (size= 0x050100
+ if (Settings::self()->retinaSupport()) {
+ devicePixelRatio=qApp->devicePixelRatio();
+ }
+ #endif
#ifdef ENABLE_UBUNTU
cache.setMaxCost(20*1024*1024); // Not used?
cacheScaledCovers=false;
@@ -1037,7 +1166,7 @@
if (cacheScaledCovers && !isOnlineServiceImage(song)) {
QString fileName=getScaledCoverName(song, size, true);
- bool status=img.save(fileName, "PNG");
+ bool status=img.save(fileName, "JPG");
DBUG_CLASS("Covers") << song.albumArtist() << song.album << song.mbAlbumId() << size << fileName << status;
}
QPixmap *pix=new QPixmap(QPixmap::fromImage(img));
@@ -1046,47 +1175,151 @@
return pix;
}
-QPixmap * Covers::get(const Song &song, int size)
+QPixmap * Covers::defaultPix(const Song &song, int size, int origSize)
{
- if (song.isUnknown()) {
- return 0;
+ #if QT_VERSION < 0x050100
+ Q_UNUSED(origSize)
+ #endif
+ #ifdef ENABLE_ONLINE_SERVICES
+ bool podcast=!song.isArtistImageRequest() && song.isFromOnlineService() && PodcastService::constName==song.onlineService();
+ QString key=song.isArtistImageRequest()
+ ? QLatin1String("artist-")
+ : podcast
+ ? QLatin1String("podcast-")
+ : QLatin1String("album-");
+ #else
+ bool podcast=false;
+ QString key=song.isArtistImageRequest() ? QLatin1String("artist-") : QLatin1String("album-");
+ #endif
+ key+=QString::number(size);
+ QPixmap *pix=cache.object(key);
+ #ifndef ENABLE_UBUNTU
+ if (!pix) {
+ Icon &icn=song.isArtistImageRequest()
+ ? Icons::self()->artistIcon
+ : podcast
+ ? Icons::self()->podcastIcon
+ : Icons::self()->albumIcon;
+ pix=new QPixmap(icn.pixmap(size, size).scaled(QSize(size, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ #if QT_VERSION >= 0x050100
+ if (size!=origSize) {
+ pix->setDevicePixelRatio(devicePixelRatio);
+ DBUG << "Set pixel ratio of dummy pixmap" << devicePixelRatio;
+ }
+ #endif
+ cache.insert(key, pix, 1);
+ cacheSizes.insert(size);
}
+ #endif
+ return pix;
+}
- QString key=cacheKey(song, size);
- QPixmap *pix(cache.object(key));
+QPixmap * Covers::get(const Song &song, int size, bool urgent)
+{
+ // DBUG_CLASS("Covers") << song.albumArtist() << song.album << song.mbAlbumId() << size << urgent;
+ QString key;
+ QPixmap *pix=0;
+ if (0==size) {
+ size=22;
+ }
- if (!pix) {
- #ifdef ENABLE_ONLINE_SERVICES
- if (isOnlineServiceImage(song)) {
- Covers::Image img=serviceImage(song);
- if (!img.img.isNull()) {
- pix=new QPixmap(QPixmap::fromImage(img.img.scaled(QSize(size, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)));
- cache.insert(key, pix);
+ int origSize=size;
+ #if QT_VERSION >= 0x050100
+ if (sizevariousArtistsIcon.pixmap(size, size).scaled(QSize(size, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ } else if (Song::SingleTracks==song.type) {
+ pix=new QPixmap(Icons::self()->albumIcon.pixmap(size, size).scaled(QSize(size, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ } else if (song.isStandardStream()) {
+ pix=new QPixmap(Icons::self()->streamIcon.pixmap(size, size).scaled(QSize(size, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ }
+ #ifdef ENABLE_ONLINE_SERVICES
+ else if (isOnlineServiceImage(song)) {
+ Covers::Image img=serviceImage(song);
+ if (!img.img.isNull()) {
+ pix=new QPixmap(QPixmap::fromImage(img.img.scaled(QSize(size, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)));
+ }
+ }
+ #endif
+ if (pix) {
+ #if QT_VERSION >= 0x050100
+ if (size!=origSize) {
+ pix->setDevicePixelRatio(devicePixelRatio);
+ DBUG << "Set pixel ratio of cover" << devicePixelRatio;
+ }
+ #endif
+ cache.insert(key, pix, 1);
cacheSizes.insert(size);
}
}
#endif
+ if (!pix) {
+ if (urgent) {
+ QImage cached=loadScaledCover(song, size);
+ if (cached.isNull()) {
+ Image img=findImage(song, false);
+ if (!img.img.isNull()) {
+ pix=saveScaledCover(scale(song, img.img, size), song, size);
+ #if QT_VERSION >= 0x050100
+ if (size!=origSize) {
+ pix->setDevicePixelRatio(devicePixelRatio);
+ DBUG << "Set pixel ratio of saved scaled cover" << devicePixelRatio;
+ }
+ #endif
+ return pix;
+ } else if (constNoCover==img.fileName) {
+ return defaultPix(song, size, origSize);
+ }
+ } else {
+ pix=new QPixmap(QPixmap::fromImage(cached));
+ #if QT_VERSION >= 0x050100
+ if (size!=origSize) {
+ pix->setDevicePixelRatio(devicePixelRatio);
+ DBUG << "Set pixel ratio of loaded scaled cover" << devicePixelRatio;
+ }
+ #endif
+ cache.insert(key, pix);
+ cacheSizes.insert(size);
+ return pix;
+ }
+ }
+ if (cacheScaledCovers) {
+ tryToLoad(setSizeRequest(song, origSize));
+ } else {
+ tryToLocate(setSizeRequest(song, origSize));
+ }
- if (cacheScaledCovers) {
- tryToLoad(setSizeRequest(song, size));
- } else {
- tryToLocate(setSizeRequest(song, size));
+ // Create a dummy image so that we dont keep on locating/loading/downloading files that do not exist!
+ pix=new QPixmap(1, 1);
+ #if QT_VERSION >= 0x050100
+ if (size!=origSize) {
+ pix->setDevicePixelRatio(devicePixelRatio);
+ DBUG << "Set pixel ratio of dummy cover" << devicePixelRatio;
+ }
+ #endif
+ cache.insert(key, pix, 1);
+ cacheSizes.insert(size);
}
- // Create a dummy image so that we dont keep on locating/loading/downloading files that do not exist!
- pix=new QPixmap(1, 1);
- cache.insert(key, pix, 1);
- cacheSizes.insert(size);
+ if (pix && pix->width()>1) {
+ return pix;
+ }
}
-
- return pix && pix->width()>1 ? pix : 0;
+ return defaultPix(song, size, origSize);
}
void Covers::coverDownloaded(const Song &song, const QImage &img, const QString &file)
{
- if (!img.isNull()) {
- updateCache(song, img, true);
- }
gotAlbumCover(song, img, file);
}
@@ -1095,7 +1328,7 @@
gotArtistImage(song, img, file);
}
-void Covers::updateCache(const Song &song, const QImage &img, bool dummyEntriesOnly)
+bool Covers::updateCache(const Song &song, const QImage &img, bool dummyEntriesOnly)
{
// Only remove all scaled entries from disk if the cover has been set by the CoverDialog
// This is the only case where dummyEntriesOnly==false
@@ -1103,19 +1336,45 @@
if (!dummyEntriesOnly) {
clearScaledCache(song);
}
+ #ifdef ENABLE_DEVICES_SUPPORT
+ bool emitLoaded=!song.isFromDevice();
+ #else
+ bool emitLoaded=true;
+ #endif
+ bool updated=false;
+
foreach (int s, cacheSizes) {
QString key=cacheKey(song, s);
QPixmap *pix(cache.object(key));
if (pix && (!dummyEntriesOnly || pix->width()<2)) {
+ #if QT_VERSION >= 0x050100
+ double pixRatio=pix->devicePixelRatio();
+ #endif
cache.remove(key);
if (!img.isNull()) {
- if (saveScaledCover(scale(song, img, s), song, s)) {
+ DBUG_CLASS("Covers");
+ QPixmap *p=saveScaledCover(scale(song, img, s), song, s);
+ #if QT_VERSION >= 0x050100
+ if (p) {
+ p->setDevicePixelRatio(pixRatio);
+ DBUG << "Set pixel ratio of updated cached pixmap" << devicePixelRatio;
+ }
+ #endif
+ if (p && emitLoaded) {
+ #if QT_VERSION >= 0x050100
+ if (pixRatio>1.00001) {
+ s/=pixRatio;
+ }
+ #endif
emit loaded(song, s);
+ updated=true;
}
}
}
}
+
+ return updated;
}
void Covers::tryToLocate(const Song &song)
@@ -1132,6 +1391,11 @@
void Covers::tryToDownload(const Song &song)
{
+ #ifdef ENABLE_DEVICES_SUPPORT
+ if (song.isFromDevice()) {
+ return;
+ }
+ #endif
if (!downloader) {
downloader=new CoverDownloader();
connect(this, SIGNAL(download(Song)), downloader, SLOT(download(Song)), Qt::QueuedConnection);
@@ -1170,19 +1434,57 @@
{
DBUG_CLASS("Covers") << song.file << song.artist << song.albumartist << song.album << song.type;
#ifdef ENABLE_ONLINE_SERVICES
- if (isOnlineServiceImage(song)) {
- Covers::Image img=serviceImage(song);
- if (!img.img.isNull()) {
- return img;
+ if (song.isFromOnlineService()) {
+ QString id=song.onlineService();
+ Covers::Image img;
+
+ if (isOnlineServiceImage(song)) {
+ img=serviceImage(song);
+ if (!img.img.isNull()) {
+ DBUG_CLASS("Covers") << "Got cover online image" << QString(img.fileName) << "for" << id;
+ return img;
+ }
+ }
+
+ img.fileName=song.extraField(Song::OnlineImageCacheName);
+ if (img.fileName.isEmpty()) {
+ img.fileName=Utils::cacheDir(id.toLower(), true)+Covers::encodeName(song.album.isEmpty() ? song.artist : (song.artist+" - "+song.album))+".jpg";
+ if (!QFile::exists(img.fileName)) {
+ img.fileName=Utils::changeExtension(img.fileName, ".png");
+ }
+ }
+ if (!img.fileName.isEmpty()) {
+ img.img=loadImage(img.fileName);
+ if (!img.img.isNull()) {
+ DBUG_CLASS("Covers") << "Got cover online image" << QString(img.fileName) << "for" << id;
+ return img;
+ }
}
+ DBUG_CLASS("Covers") << "Failed to locate online image for" << id;
+ return Image();
}
- if (Song::OnlineSvrTrack==song.type) {
- return OnlineServicesModel::self()->readImage(song);
+ #endif
+ #ifdef ENABLE_DEVICES_SUPPORT
+ if (song.isFromDevice()) {
+ Device *dev=DevicesModel::self()->device(song.deviceId());
+ Image img;
+ if (dev) {
+ img=dev->requestCover(song);
+ }
+ if (img.img.isNull()) {
+ DBUG_CLASS("Covers") << "Failed to locate device image for" << song.deviceId();
+ }
+ return img;
}
#endif
+
bool isArtistImage=song.isArtistImageRequest();
QString prevFileName=Covers::self()->getFilename(song, isArtistImage);
if (!prevFileName.isEmpty()) {
+ if (constNoCover==prevFileName) {
+ DBUG_CLASS("Covers") << "No cover";
+ return Image(QImage(), constNoCover);
+ }
#ifdef TAGLIB_FOUND
QImage img;
if (prevFileName.startsWith(constCoverInTagPrefix)) {
@@ -1386,13 +1688,18 @@
}
DBUG_CLASS("Covers") << "Failed to locate image";
- return Image(QImage(), QString());
+ return Image();
}
// Dont return song files as cover files!
static Covers::Image fix(const Covers::Image &img)
{
- return Covers::Image(img.img, img.fileName.startsWith(constCoverInTagPrefix) ? QString() : img.fileName);
+ return Covers::Image(img.img, img.validFileName() ? img.fileName : QString());
+}
+
+bool Covers::Image::validFileName() const
+{
+ return !fileName.isEmpty() && !fileName.startsWith(constCoverInTagPrefix) && constNoCover!=fileName;
}
Covers::Image Covers::requestImage(const Song &song, bool urgent)
@@ -1407,20 +1714,29 @@
}
}
#endif
+ #ifdef ENABLE_DEVICES_SUPPORT
+ if (song.isFromDevice()) {
+ Device *dev=DevicesModel::self()->device(song.deviceId());
+ if (dev) {
+ return dev->requestCover(song);
+ }
+ return Image();
+ }
+ #endif
QString key=song.isArtistImageRequest() ? artistKey(song) : albumKey(song);
if (currentImageRequests.contains(key)) {
- return Covers::Image();
+ return Image();
}
if (!urgent) {
currentImageRequests.insert(key);
tryToLocate(song);
- return Covers::Image();
+ return Image();
}
Image img=findImage(song, false);
- if (img.img.isNull() && Song::OnlineSvrTrack!=song.type) {
+ if (img.img.isNull() && Song::OnlineSvrTrack!=song.type && constNoCover!=img.fileName) {
DBUG << song.file << song.artist << song.albumartist << song.album << "Need to download";
currentImageRequests.insert(key);
tryToDownload(song);
@@ -1448,8 +1764,22 @@
{
foreach (const LoadedCover &cvr, covers) {
if (!cvr.img.isNull()) {
- cache.insert(cacheKey(cvr.song, cvr.song.size), new QPixmap(QPixmap::fromImage(cvr.img)));
- cacheSizes.insert(cvr.song.size);
+ int size=cvr.song.size;
+ #if QT_VERSION >= 0x050100
+ int origSize=size;
+ if (size= 0x050100
+ if (size!=origSize) {
+ pix->setDevicePixelRatio(devicePixelRatio);
+ DBUG << "Set pixel ratio of loaded pixmap" << devicePixelRatio;
+ }
+ #endif
+ cache.insert(cacheKey(cvr.song, size), pix);
+ cacheSizes.insert(size);
emit loaded(cvr.song, cvr.song.size);
} else { // Failed to load a scaled cover, try locating non-scaled cover...
tryToLocate(cvr.song);
@@ -1457,10 +1787,15 @@
}
}
-void Covers::emitCoverUpdated(const Song &song, const QImage &img, const QString &file)
+void Covers::updateCover(const Song &song, const QImage &img, const QString &file)
{
updateCache(song, img, false);
- filenames[song.isArtistImageRequest() ? artistKey(song) : albumKey(song)]=file;
+ if (!file.isEmpty()) {
+ filenames[song.isArtistImageRequest() ? artistKey(song) : albumKey(song)]=file;
+ }
+ #ifdef ENABLE_DEVICES_SUPPORT
+ if (!song.isFromDevice())
+ #endif
emit coverUpdated(song, img, file);
}
@@ -1487,18 +1822,17 @@
{
QString key=albumKey(song);
currentImageRequests.remove(key);
- if (!img.isNull() && !fileName.isEmpty() && !fileName.startsWith("http:/")) {
+// if (!img.isNull() && !fileName.isEmpty() && !fileName.startsWith("http:/")) {
mutex.lock();
- filenames.insert(key, fileName);
+ filenames.insert(key, fileName.isEmpty() ? constNoCover : fileName);
mutex.unlock();
- }
+// }
if (emitResult) {
- if (song.isSpecificSizeRequest()) {
- if (!img.isNull() && saveScaledCover(scale(song, img, song.size), song, song.size)) {
- DBUG << "loaded cover" << song.file << song.artist << song.albumartist << song.album << song.mbAlbumId() << img.width() << img.height() << fileName << song.size;
- emit loaded(song, song.size);
- }
- } else {
+ bool updatedCover=false;
+ if (!img.isNull()) {
+ updatedCover=updateCache(song, img, true);
+ }
+ if (updatedCover || !song.isSpecificSizeRequest()) {
DBUG << "emit cover" << song.file << song.artist << song.albumartist << song.album << song.mbAlbumId() << img.width() << img.height() << fileName;
emit cover(song, img, fileName.startsWith(constCoverInTagPrefix) ? QString() : fileName);
}
@@ -1509,18 +1843,16 @@
{
QString key=artistKey(song);
currentImageRequests.remove(key);
- if (!img.isNull() && !fileName.isEmpty() && !fileName.startsWith("http:/")) {
+// if (!img.isNull() && !fileName.isEmpty() && !fileName.startsWith("http:/")) {
mutex.lock();
- filenames.insert(key, fileName);
+ filenames.insert(key, fileName.isEmpty() ? constNoCover : fileName);
mutex.unlock();
- }
+// }
if (emitResult) {
- if (song.isSpecificSizeRequest()) {
- if (!img.isNull() && saveScaledCover(scale(song, img, song.size), song, song.size)) {
- DBUG << "loaded artistImage" << song.file << song.artist << song.albumartist << song.album << img.width() << img.height() << fileName << song.size;
- emit loaded(song, song.size);
- }
- } else {
+ if (!img.isNull()) {
+ updateCache(song, img, true);
+ }
+ if (!song.isSpecificSizeRequest()) {
DBUG << "emit artistImage" << song.file << song.artist << song.albumartist << song.album << img.width() << img.height() << fileName;
emit artistImage(song, img, fileName.startsWith(constCoverInTagPrefix) ? QString() : fileName);
}
diff -Nru cantata-1.4.2.ds1/gui/covers.h cantata-1.5.2.ds2/gui/covers.h
--- cantata-1.4.2.ds1/gui/covers.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/covers.h 2015-03-23 20:09:42.000000000 +0000
@@ -87,6 +87,7 @@
private Q_SLOTS:
void lastFmCallFinished();
void jobFinished();
+ void onlineJobFinished();
private:
void failed(const Job &job);
@@ -180,7 +181,7 @@
: img(i)
, fileName(f) {
}
-
+ bool validFileName() const;
QImage img;
QString fileName;
};
@@ -195,6 +196,7 @@
static const QLatin1String constFileName;
static const QLatin1String constCddaCoverDir;
static const QLatin1String constArtistImage;
+ static const QString constCoverInTagPrefix;
static Covers * self();
// static bool isCoverFile(const QString &file);
@@ -223,7 +225,7 @@
QPixmap * saveScaledCover(const QImage &img, const Song &song, int size);
// Get cover image of specified size. If this is not found 0 will be returned, and the cover
// will be downloaded.
- QPixmap * get(const Song &song, int size);
+ QPixmap * get(const Song &song, int size, bool urgent=false);
// Get QImage and filename associated with Song request. If this is not found, then the cover
// will NOT be downloaded. 'emitResult' controls whether 'cover()/artistImage()' is emitted if
// a cover is found.
@@ -232,7 +234,7 @@
// will be downloaded. If more than 5 covers have been requested in an event-loop iteration, then
// the cover requests are placed on a queue.
Image requestImage(const Song &song, bool urgent=false);
- void emitCoverUpdated(const Song &song, const QImage &img, const QString &file);
+ void updateCover(const Song &song, const QImage &img, const QString &file);
#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND
void cleanCdda();
@@ -257,11 +259,12 @@
void artistImageDownloaded(const Song &song, const QImage &img, const QString &file);
private:
+ QPixmap * defaultPix(const Song &song, int size, int origSize);
void tryToLocate(const Song &song);
void tryToDownload(const Song &song);
void tryToLoad(const Song &song);
Image findImage(const Song &song, bool emitResult);
- void updateCache(const Song &song, const QImage &img, bool dummyEntriesOnly);
+ bool updateCache(const Song &song, const QImage &img, bool dummyEntriesOnly);
void gotAlbumCover(const Song &song, const QImage &img, const QString &fileName, bool emitResult=true);
void gotArtistImage(const Song &song, const QImage &img, const QString &fileName, bool emitResult=true);
QString getFilename(const Song &s, bool isArtist);
diff -Nru cantata-1.4.2.ds1/gui/currentcover.cpp cantata-1.5.2.ds2/gui/currentcover.cpp
--- cantata-1.4.2.ds1/gui/currentcover.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/currentcover.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -216,14 +216,15 @@
}
}
-void CurrentCover::coverRetrieved(const Song &s, const QImage &img, const QString &file)
+void CurrentCover::coverRetrieved(const Song &s, const QImage &newImage, const QString &file)
{
if (!s.isArtistImageRequest() && s.albumArtist()==current.albumArtist() && s.album==current.album) {
- valid=!img.isNull();
+ valid=!newImage.isNull();
if (valid) {
coverFileName=file;
+ img=newImage;
emit coverFile(file);
- emit coverImage(img);
+ emit coverImage(newImage);
} else {
coverFileName=current.isStandardStream() ? noStreamCoverFileName : noCoverFileName;
emit coverFile(coverFileName);
diff -Nru cantata-1.4.2.ds1/gui/filesettings.cpp cantata-1.5.2.ds2/gui/filesettings.cpp
--- cantata-1.4.2.ds1/gui/filesettings.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/filesettings.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -28,6 +28,10 @@
: QWidget(p)
{
setupUi(this);
+
+ #ifdef Q_OS_MAC
+ expandingSpacer->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
+ #endif
}
void FileSettings::load()
diff -Nru cantata-1.4.2.ds1/gui/filesettings.ui cantata-1.5.2.ds2/gui/filesettings.ui
--- cantata-1.4.2.ds1/gui/filesettings.ui 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/filesettings.ui 2015-03-23 20:09:42.000000000 +0000
@@ -45,74 +45,21 @@
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 8
-
-
-
-
- -
-
-
-
- 0
- 0
-
-
+
- <i><b>NOTE:</b> If you elect to have Cantata store covers, lyrics, or backdrops, within the music folder, and you do not have write access to this folder, then Cantata will revert to saving the files in your personal cache folder.</i>
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- true
-
-
- Qt::NoTextInteraction
+ If you elect to have Cantata store covers, lyrics, or backdrops, within the music folder, and you do not have write access to this folder, then Cantata will revert to saving the files in your personal cache folder.
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 8
-
-
-
-
- -
-
+
- <i><b>NOTE:</b> Cantata can only save backdrops and artist images within the music folder hierarchy if this is 2 levels deep. (i.e. 'Artist/Album/Tracks')</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ Cantata can only save backdrops and artist images within the music folder hierarchy if this is 2 levels deep. (i.e. 'Artist/Album/Tracks')
-
-
+
Qt::Vertical
@@ -122,13 +69,20 @@
20
- 8
+ 0
+
+
+ NoteLabel
+ QLabel
+
+
+
diff -Nru cantata-1.4.2.ds1/gui/folderpage.cpp cantata-1.5.2.ds2/gui/folderpage.cpp
--- cantata-1.4.2.ds1/gui/folderpage.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/folderpage.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -58,9 +58,7 @@
#endif
view->addAction(browseAction);
#ifdef ENABLE_DEVICES_SUPPORT
- QAction *sep=new QAction(this);
- sep->setSeparator(true);
- view->addAction(sep);
+ view->addSeparator();
view->addAction(StdActions::self()->deleteSongsAction);
#endif
@@ -72,11 +70,11 @@
connect(view, SIGNAL(searchItems()), this, SLOT(searchItems()));
connect(view, SIGNAL(itemsSelected(bool)), this, SLOT(controlActions()));
connect(view, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(itemDoubleClicked(const QModelIndex &)));
- connect(browseAction, SIGNAL(triggered(bool)), this, SLOT(openFileManager()));
- connect(MPDConnection::self(), SIGNAL(updatingFileList()), this, SLOT(showSpinner()));
- connect(MPDConnection::self(), SIGNAL(updatedFileList()), this, SLOT(hideSpinner()));
- connect(MPDConnection::self(), SIGNAL(updatingDatabase()), this, SLOT(showSpinner()));
- connect(MPDConnection::self(), SIGNAL(updatedDatabase()), this, SLOT(hideSpinner()));
+ connect(browseAction, SIGNAL(triggered()), this, SLOT(openFileManager()));
+ connect(MPDConnection::self(), SIGNAL(updatingFileList()), view, SLOT(updating()));
+ connect(MPDConnection::self(), SIGNAL(updatedFileList()), view, SLOT(updated()));
+ connect(MPDConnection::self(), SIGNAL(updatingDatabase()), view, SLOT(updating()));
+ connect(MPDConnection::self(), SIGNAL(updatedDatabase()), view, SLOT(updated()));
view->load(metaObject()->className());
}
@@ -222,9 +220,8 @@
return DirViewModel::self()->filenames(proxy.mapToSource(selected, proxy.enabled() && Settings::self()->filteredOnly()), allowPlaylists);
}
-void FolderPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty, bool randomAlbums)
+void FolderPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty)
{
- Q_UNUSED(randomAlbums)
QStringList files=selectedFiles(name.isEmpty());
if (!files.isEmpty()) {
@@ -253,7 +250,7 @@
QList songs=selectedSongs(ES_GuessTags);
if (!songs.isEmpty()) {
- if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to delete the selected songs?\nThis cannot be undone."),
+ if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to delete the selected songs?\n\nThis cannot be undone."),
i18n("Delete Songs"), StdGuiItem::del(), StdGuiItem::cancel())) {
emit deleteSongs(QString(), songs);
}
@@ -284,15 +281,3 @@
}
return files;
}
-
-void FolderPage::showSpinner()
-{
- view->showSpinner();
- view->showMessage(i18n("Updating..."), -1);
-}
-
-void FolderPage::hideSpinner()
-{
- view->hideSpinner();
- view->showMessage(QString(), 0);
-}
diff -Nru cantata-1.4.2.ds1/gui/folderpage.h cantata-1.5.2.ds2/gui/folderpage.h
--- cantata-1.4.2.ds1/gui/folderpage.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/folderpage.h 2015-03-23 20:09:42.000000000 +0000
@@ -53,7 +53,7 @@
QStringList selectedFiles(bool allowPlaylists=false) const;
QList selectedSongs(EmptySongMod esMod, bool allowPlaylists=false) const;
QList selectedSongs(bool allowPlaylists=false) const { return selectedSongs(ES_None, allowPlaylists); }
- void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0, bool randomAlbums=false);
+ void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0);
#ifdef ENABLE_DEVICES_SUPPORT
void addSelectionToDevice(const QString &udi);
void deleteSongs();
@@ -76,8 +76,6 @@
void controlActions();
void itemDoubleClicked(const QModelIndex &);
void openFileManager();
- void showSpinner();
- void hideSpinner();
private:
QStringList walk(QModelIndex rootItem);
diff -Nru cantata-1.4.2.ds1/gui/initialsettingswizard.cpp cantata-1.5.2.ds2/gui/initialsettingswizard.cpp
--- cantata-1.4.2.ds1/gui/initialsettingswizard.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/initialsettingswizard.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -222,7 +222,7 @@
} else {
MPDUser::self()->cleanup();
}
- Settings::self()->save(true);
+ Settings::self()->save();
QDialog::accept();
}
@@ -232,4 +232,3 @@
Settings::self()->clearVersion();
QDialog::reject();
}
-
diff -Nru cantata-1.4.2.ds1/gui/initialsettingswizard.ui cantata-1.5.2.ds2/gui/initialsettingswizard.ui
--- cantata-1.4.2.ds1/gui/initialsettingswizard.ui 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/initialsettingswizard.ui 2015-03-23 20:09:42.000000000 +0000
@@ -66,7 +66,7 @@
-
- <html><head/><body><p>Cantata is a feature-rich and user friendly client for Music Player Daemon (MPD). MPD is a background application that can be used to play music.</p><p>For more information on MPD itself, please refer to the MPD website <a href="http://www.musicpd.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.musicpd.org</span></a></p><p>This 'wizard' will guide you through the basic settings required for Cantata to function correctly.</p></body></html>
+ <html><head/><body><p>Cantata is a feature-rich and user friendly client for Music Player Daemon (MPD). MPD is a flexible, powerful, server-side application for playing music.</p><p>For more information on MPD itself, please refer to the MPD website <a href="http://www.musicpd.org"><span style=" text-decoration: underline; color:#0000ff;">http://www.musicpd.org</span></a></p><p>This 'wizard' will guide you through the basic settings required for Cantata to function correctly.</p></body></html>
Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
@@ -131,7 +131,7 @@
-
- <html><head/><body><p>Cantata is a feature-rich and user friendly client for Music Player Daemon (MPD). MPD is a background application that can be used to play music. MPD may be started either system-wide, or on a per-user basis. Please select how you would like to have Cantata initially connect to (or startup) MPD:</p></body></html>
+ <html><head/><body><p>Cantata is a feature-rich and user friendly client for Music Player Daemon (MPD). MPD is a flexible, powerful, server-side application for playing music. MPD may be started either system-wide, or on a per-user basis. Please select how you would like to have Cantata initially connect to (or startup) MPD:</p></body></html>
Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
@@ -378,6 +378,9 @@
-
+
+ QFormLayout::ExpandingFieldsGrow
+
-
@@ -485,60 +488,16 @@
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 13
-
-
-
-
- -
-
+
- <i><b>NOTE:</b> The 'Music folder' setting is used to lookup cover-art, lyrics, etc. If you're MPD instance is on a remote host, you may set this to a HTTP URL.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ The 'Music folder' setting is used to lookup cover-art, lyrics, etc. If your MPD instance is on a remote host, you may set this to a HTTP URL.
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 13
-
-
-
-
- -
-
+
- <i><b>NOTE:</b> When using a local socket the full absolute path to the socket needs to be set. (Port number is not required.)</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ When using a local socket the full absolute path to the socket needs to be set. (Port number is not required.)
@@ -751,89 +710,23 @@
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 8
-
-
-
-
- -
-
+
- <i><b>NOTE:</b> If you elect to have Cantata store covers, lyrics, or backdrops, within the music folder, and you do not have write access to this folder, then Cantata will revert to saving the files in your personal cache folder.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ If you elect to have Cantata store covers, lyrics, or backdrops, within the music folder, and you do not have write access to this folder, then Cantata will revert to saving the files in your personal cache folder.
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 8
-
-
-
-
- -
-
+
- <i><b>NOTE:</b> Cantata can only save backdrops and artist images within the music folder hierarchy if this is 2 levels deep. i.e. 'Artist/Album/Tracks'.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ Cantata can only save backdrops and artist images within the music folder hierarchy if this is 2 levels deep. i.e. 'Artist/Album/Tracks'.
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 8
-
-
-
-
- -
-
+
- <i><b>NOTE:</b> The 'Music folder' is set to a HTTP address, and Cantata currently cannot upload files to external HTTP servers. Therefore, the above settings should be left un-checked.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ The 'Music folder' is set to a HTTP address, and Cantata currently cannot upload files to external HTTP servers. Therefore, the above settings should be left un-checked.
@@ -915,10 +808,33 @@
- -
+
-
+
+
+ Cantata will groups tracks into albums by using the 'AlbumArtist' tag if it is set, otherwise it will fallback to the 'Artist' tag. If you have albums with multiple artists, you <b>must</b> set the 'AlbumArtist' tag for the grouping to function correctly. It is suggested to use 'Various Artists' in this scenario.
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 32
+
+
+
+
+ -
- -
+
-
@@ -937,7 +853,7 @@
- -
+
-
Qt::Vertical
@@ -977,9 +893,9 @@
1
- StateLabel
+ NoteLabel
QLabel
-
+
diff -Nru cantata-1.4.2.ds1/gui/interfacesettings.cpp cantata-1.5.2.ds2/gui/interfacesettings.cpp
--- cantata-1.4.2.ds1/gui/interfacesettings.cpp 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/interfacesettings.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -23,14 +23,15 @@
#include "interfacesettings.h"
#include "settings.h"
-#include "widgets/itemview.h"
-#include "support/localize.h"
#include "models/musiclibraryitemalbum.h"
#include "models/albumsmodel.h"
+#include "support/localize.h"
+#include "support/utils.h"
#include "support/fancytabwidget.h"
+#include "support/pathrequester.h"
#include "widgets/basicitemdelegate.h"
#include "widgets/playqueueview.h"
-#include "support/pathrequester.h"
+#include "widgets/itemview.h"
#include
#ifndef ENABLE_KDE_SUPPORT
#include
@@ -45,6 +46,7 @@
#ifndef ENABLE_KDE_SUPPORT
#include
#endif
+#include
#define REMOVE(w) \
w->setVisible(false); \
@@ -61,15 +63,6 @@
box->addItem(i18n("Year, Artist, Album"), AlbumsModel::Sort_YearArtist);
}
-static void addImageSizes(QComboBox *box)
-{
- box->addItem(i18n("None"), MusicLibraryItemAlbum::CoverNone);
- box->addItem(i18n("Small"), MusicLibraryItemAlbum::CoverSmall);
- box->addItem(i18n("Medium"), MusicLibraryItemAlbum::CoverMedium);
- box->addItem(i18n("Large"), MusicLibraryItemAlbum::CoverLarge);
- box->addItem(i18n("Extra Large"), MusicLibraryItemAlbum::CoverExtraLarge);
-}
-
static QString viewTypeString(ItemView::Mode mode)
{
switch (mode) {
@@ -79,7 +72,7 @@
case ItemView::Mode_DetailedTree: return i18n("Detailed Tree");
case ItemView::Mode_GroupedTree: return i18n("Grouped Albums");
case ItemView::Mode_List: return i18n("List");
- case ItemView::Mode_IconTop: return i18n("Icon/List");
+ case ItemView::Mode_IconTop: return i18n("Grid");
case ItemView::Mode_Table: return i18n("Table");
}
}
@@ -100,7 +93,6 @@
}
}
}
-bool enableNotifications(true);
static inline int getValue(QComboBox *box)
{
@@ -115,12 +107,17 @@
, loadedLangs(false)
#endif
{
+ #ifdef Q_OS_MAC
+ // OSX always displays an entry in the taskbar - and the tray seems to confuse things.
+ bool enableTrayItem=false;
+ bool enableNotifications=QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8;
+ #else
#ifdef QT_QTDBUS_FOUND
// We have dbus, check that org.freedesktop.Notifications exists
bool enableNotifications=QDBusConnection::sessionBus().interface()->isServiceRegistered("org.freedesktop.Notifications");
- #else
+ #else // QT_QTDBUS_FOUND
bool enableNotifications=true;
- #endif
+ #endif // QT_QTDBUS_FOUND
bool enableTrayItem=true;
#ifndef ENABLE_KDE_SUPPORT
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
@@ -129,10 +126,10 @@
enableNotifications=false;
#endif
}
- #endif
+ #endif // !ENABLE_KDE_SUPPORT
+ #endif // Q_MAC_OS
setupUi(this);
- addImageSizes(libraryCoverSize);
QList standardViews=QList() << ItemView::Mode_BasicTree << ItemView::Mode_SimpleTree
<< ItemView::Mode_DetailedTree << ItemView::Mode_List;
addViewTypes(libraryView, QList() << standardViews << ItemView::Mode_IconTop);
@@ -142,7 +139,6 @@
addViewTypes(searchView, QList() << ItemView::Mode_List << ItemView::Mode_Table);
addViewTypes(playQueueView, QList() << ItemView::Mode_GroupedTree << ItemView::Mode_Table);
- addImageSizes(albumsCoverSize);
addAlbumSorts(albumSort);
addView(i18n("Play Queue"), QLatin1String("PlayQueuePage"));
@@ -179,9 +175,6 @@
addView(i18n("Info - Current song information (artist, album, and lyrics)"), QLatin1String("ContextPage"));
connect(libraryView, SIGNAL(currentIndexChanged(int)), SLOT(libraryViewChanged()));
- connect(libraryCoverSize, SIGNAL(currentIndexChanged(int)), SLOT(libraryCoverSizeChanged()));
- connect(albumsView, SIGNAL(currentIndexChanged(int)), SLOT(albumsViewChanged()));
- connect(albumsCoverSize, SIGNAL(currentIndexChanged(int)), SLOT(albumsCoverSizeChanged()));
connect(playlistsView, SIGNAL(currentIndexChanged(int)), SLOT(playlistsViewChanged()));
connect(playQueueView, SIGNAL(currentIndexChanged(int)), SLOT(playQueueViewChanged()));
connect(forceSingleClick, SIGNAL(toggled(bool)), SLOT(forceSingleClickChanged()));
@@ -234,7 +227,9 @@
}
if (!enableNotifications && !enableTrayItem) {
- tabWidget->removeTab(6);
+ tabWidget->removeTab(4);
+ } else if (!enableTrayItem && enableNotifications) {
+ tabWidget->setTabText(4, i18n("Notifications"));
}
#if defined Q_OS_WIN || defined Q_OS_MAC || !defined QT_QTDBUS_FOUND
if (systemTrayPopup && systemTrayCheckBox) {
@@ -242,16 +237,38 @@
connect(systemTrayPopup, SIGNAL(toggled(bool)), SLOT(systemTrayPopupToggled()));
}
#endif
+ #if QT_VERSION >= 0x050400 || (defined Q_OS_MAC && QT_VERSION >= 0x050100)
+ connect(retinaSupport, SIGNAL(toggled(bool)), SLOT(retinaSupportChanged()));
+ #else
+ REMOVE(retinaSupport)
+ REMOVE(retinaSupportNoteLabel)
+ #endif
+
+ // If we are on a display less than 800 pixels tall (e.g. a netbook), then re-arrange
+ // the view settings to allow dialog to shrink more...
+ if (Utils::limitedHeight(this)) {
+ viewsLayout->removeWidget(otherViewGroupBox);
+ viewsLayout->addWidget(otherViewGroupBox, 0, 1, 3, 1);
+ viewsLayout->addItem(new QSpacerItem(0, 2, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2, 1, 1);
+ styleLayout->removeWidget(sbIconsOnly);
+ styleLayout->removeWidget(sbMonoIcons);
+ styleLayout->removeWidget(sbAutoHide);
+ QVBoxLayout *sbOther = new QVBoxLayout();
+ sbOther->addWidget(sbIconsOnly);
+ sbOther->addWidget(sbMonoIcons);
+ sbOther->addWidget(sbAutoHide);
+ sbLayout->addItem(new QSpacerItem(Utils::layoutSpacing(this)*8, 2, QSizePolicy::Fixed, QSizePolicy::Fixed));
+ sbLayout->addLayout(sbOther);
+ sbLayout->addItem(new QSpacerItem(0, 2, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ }
}
void InterfaceSettings::load()
{
libraryArtistImage->setChecked(Settings::self()->libraryArtistImage());
selectEntry(libraryView, Settings::self()->libraryView());
- libraryCoverSize->setCurrentIndex(Settings::self()->libraryCoverSize());
libraryYear->setChecked(Settings::self()->libraryYear());
selectEntry(albumsView, Settings::self()->albumsView());
- albumsCoverSize->setCurrentIndex(Settings::self()->albumsCoverSize());
selectEntry(albumSort, Settings::self()->albumSort());
selectEntry(folderView, Settings::self()->folderView());
selectEntry(playlistsView, Settings::self()->playlistsView());
@@ -282,17 +299,21 @@
playQueueBackground_custom->setChecked(pqBgnd==playQueueBackground_custom->property(constValueProperty).toInt());
playQueueBackgroundOpacity->setValue(Settings::self()->playQueueBackgroundOpacity());
playQueueBackgroundBlur->setValue(Settings::self()->playQueueBackgroundBlur());
- playQueueBackgroundFile->setText(Settings::self()->playQueueBackgroundFile());
+ playQueueBackgroundFile->setText(Utils::convertPathForDisplay(Settings::self()->playQueueBackgroundFile(), false));
playQueueConfirmClear->setChecked(Settings::self()->playQueueConfirmClear());
- albumsViewChanged();
- albumsCoverSizeChanged();
+ playQueueSearch->setChecked(Settings::self()->playQueueSearch());
playlistsViewChanged();
playQueueViewChanged();
forceSingleClick->setChecked(Settings::self()->forceSingleClick());
+ infoTooltips->setChecked(Settings::self()->infoTooltips());
+ if (retinaSupport) {
+ retinaSupport->setChecked(Settings::self()->retinaSupport());
+ }
touchFriendly->setChecked(Settings::self()->touchFriendly());
showStopButton->setChecked(Settings::self()->showStopButton());
showCoverWidget->setChecked(Settings::self()->showCoverWidget());
+ showRatingWidget->setChecked(Settings::self()->showRatingWidget());
if (systemTrayCheckBox) {
systemTrayCheckBox->setChecked(Settings::self()->useSystemTray());
if (minimiseOnClose) {
@@ -312,8 +333,6 @@
if (systemTrayPopup) {
systemTrayPopup->setChecked(Settings::self()->showPopups());
}
-
- cacheScaledCovers->setChecked(Settings::self()->cacheScaledCovers());
fetchCovers->setChecked(Settings::self()->fetchCovers());
QStringList hiddenPages=Settings::self()->hiddenPages();
@@ -339,10 +358,8 @@
{
Settings::self()->saveLibraryArtistImage(libraryArtistImage->isChecked());
Settings::self()->saveLibraryView(getValue(libraryView));
- Settings::self()->saveLibraryCoverSize(libraryCoverSize->currentIndex());
Settings::self()->saveLibraryYear(libraryYear->isChecked());
Settings::self()->saveAlbumsView(getValue(albumsView));
- Settings::self()->saveAlbumsCoverSize(albumsCoverSize->currentIndex());
Settings::self()->saveAlbumSort(getValue(albumSort));
Settings::self()->saveFolderView(getValue(folderView));
Settings::self()->savePlaylistsView(getValue(playlistsView));
@@ -375,13 +392,19 @@
}
Settings::self()->savePlayQueueBackgroundOpacity(playQueueBackgroundOpacity->value());
Settings::self()->savePlayQueueBackgroundBlur(playQueueBackgroundBlur->value());
- Settings::self()->savePlayQueueBackgroundFile(playQueueBackgroundFile->text().trimmed());
+ Settings::self()->savePlayQueueBackgroundFile(Utils::convertPathFromDisplay(playQueueBackgroundFile->text(), false));
Settings::self()->savePlayQueueConfirmClear(playQueueConfirmClear->isChecked());
+ Settings::self()->savePlayQueueSearch(playQueueSearch->isChecked());
Settings::self()->saveForceSingleClick(forceSingleClick->isChecked());
+ Settings::self()->saveInfoTooltips(infoTooltips->isChecked());
+ if (retinaSupport) {
+ Settings::self()->saveRetinaSupport(retinaSupport->isChecked());
+ }
Settings::self()->saveTouchFriendly(touchFriendly->isChecked());
Settings::self()->saveShowStopButton(showStopButton->isChecked());
Settings::self()->saveShowCoverWidget(showCoverWidget->isChecked());
+ Settings::self()->saveShowRatingWidget(showRatingWidget->isChecked());
Settings::self()->saveUseSystemTray(systemTrayCheckBox && systemTrayCheckBox->isChecked());
Settings::self()->saveShowPopups(systemTrayPopup && systemTrayPopup->isChecked());
Settings::self()->saveMinimiseOnClose(minimiseOnClose && minimiseOnClose->isChecked());
@@ -392,7 +415,6 @@
} else if (startupStateRestore->isChecked()) {
Settings::self()->saveStartupState(Settings::SS_Previous);
}
- Settings::self()->saveCacheScaledCovers(cacheScaledCovers->isChecked());
Settings::self()->saveFetchCovers(fetchCovers->isChecked());
#ifndef ENABLE_KDE_SUPPORT
if (loadedLangs && lang) {
@@ -505,10 +527,6 @@
void InterfaceSettings::libraryViewChanged()
{
int vt=getValue(libraryView);
- if (ItemView::Mode_IconTop==vt && 0==libraryCoverSize->currentIndex()) {
- libraryCoverSize->setCurrentIndex(2);
- }
-
bool isIcon=ItemView::Mode_IconTop==vt;
bool isSimpleTree=ItemView::Mode_SimpleTree==vt || ItemView::Mode_BasicTree==vt;
libraryArtistImage->setEnabled(!isIcon && !isSimpleTree);
@@ -519,30 +537,6 @@
}
}
-void InterfaceSettings::libraryCoverSizeChanged()
-{
- if (ItemView::Mode_IconTop==getValue(libraryView) && 0==libraryCoverSize->currentIndex()) {
- libraryView->setCurrentIndex(1);
- }
- if (0==libraryCoverSize->currentIndex()) {
- libraryArtistImage->setChecked(false);
- }
-}
-
-void InterfaceSettings::albumsViewChanged()
-{
- if (ItemView::Mode_IconTop==getValue(albumsView) && 0==albumsCoverSize->currentIndex()) {
- albumsCoverSize->setCurrentIndex(2);
- }
-}
-
-void InterfaceSettings::albumsCoverSizeChanged()
-{
- if (ItemView::Mode_IconTop==getValue(albumsView) && 0==albumsCoverSize->currentIndex()) {
- albumsView->setCurrentIndex(1);
- }
-}
-
void InterfaceSettings::playQueueViewChanged()
{
bool grouped=ItemView::Mode_GroupedTree==getValue(playQueueView);
@@ -566,6 +560,11 @@
touchFriendlyNoteLabel->setOn(touchFriendly->isChecked()!=Settings::self()->touchFriendly());
}
+void InterfaceSettings::retinaSupportChanged()
+{
+ retinaSupportNoteLabel->setOn(retinaSupport->isChecked()!=Settings::self()->retinaSupport());
+}
+
void InterfaceSettings::enableStartupState()
{
if (systemTrayCheckBox && minimiseOnClose && startupState) {
diff -Nru cantata-1.4.2.ds1/gui/interfacesettings.h cantata-1.5.2.ds2/gui/interfacesettings.h
--- cantata-1.4.2.ds1/gui/interfacesettings.h 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/interfacesettings.h 2015-03-23 20:09:42.000000000 +0000
@@ -49,13 +49,11 @@
private Q_SLOTS:
void libraryViewChanged();
- void libraryCoverSizeChanged();
- void albumsViewChanged();
- void albumsCoverSizeChanged();
void playlistsViewChanged();
void playQueueViewChanged();
void forceSingleClickChanged();
void touchFriendlyChanged();
+ void retinaSupportChanged();
void enableStartupState();
void langChanged();
void viewItemChanged(QListWidgetItem *changedItem);
diff -Nru cantata-1.4.2.ds1/gui/interfacesettings.ui cantata-1.5.2.ds2/gui/interfacesettings.ui
--- cantata-1.4.2.ds1/gui/interfacesettings.ui 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/interfacesettings.ui 2015-03-23 20:09:42.000000000 +0000
@@ -56,375 +56,293 @@
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 4
-
+
+
+ By default, the play queue appears to the side of the other views, and the Info view is accessible by pressing its icon in the main toolbar. Checking the appropriate option above will cause the view to be merged into the sidebar as per other views.
-
+
+
+
+
+ -
+
+
+ Options
+
+
-
-
-
- <i><b>NOTE:</b> By default, the play queue appears to the side of the other views. If you enable the option above, then it will be merged into the sidebar as per other views.</i>
+
+
+ QFormLayout::ExpandingFieldsGrow
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+ -
+
+
+ Style:
+
+
+ sbStyle
+
+
+
+ -
+
+
+ -
+
+
+ Position:
+
+
+ sbPosition
+
+
+
+ -
+
+
+ -
+
+
+ Only show icons, no text
+
+
+
+ -
+
+
+ Use monochrome icons
+
+
+
+ -
+
+
+ Auto-hide
+
+
+
+
+
+
+
+
+
+
+
+
+ Views
+
+
+ -
+
+
+ Artists
+
+
+
+ QFormLayout::ExpandingFieldsGrow
+
+
+ Qt::AlignJustify|Qt::AlignTop
+
+ -
+
+
+ Style:
-
- true
+
+ libraryView
-
- Qt::NoTextInteraction
+
+
+ -
+
+
+ -
+
+
+ Sort albums by year
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 4
-
+ -
+
+
+ Show artist images
-
+
- -
-
+
+
+
+ -
+
+
+ Albums
+
+
+
+ QFormLayout::ExpandingFieldsGrow
+
+
+ Qt::AlignJustify|Qt::AlignTop
+
+ -
+
- <i><b>NOTE:</b> By default, the 'Info' (current song information) view is accessible by pressing its icon in the main toolbar. If you enable the option above, then it will be merged into the sidebar as per other views.</i>
+ Style:
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+ albumsView
-
- true
+
+
+ -
+
+
+ -
+
+
+ Sort:
-
- Qt::NoTextInteraction
+
+ albumSort
+ -
+
+
- -
-
+ -
+
- Options
+ Playlists
-
+
QFormLayout::ExpandingFieldsGrow
+
+ Qt::AlignJustify|Qt::AlignTop
+
-
-
+
Style:
- sbStyle
+ playlistsView
-
-
+
+
+ -
+
+
+ Initially collapse albums
+
+
+
+
+
+ removeWidget
+ -
+
+
+ Other Views
+
+
+
+ QFormLayout::ExpandingFieldsGrow
+
+
+ Qt::AlignJustify|Qt::AlignTop
+
+ -
+
+
+ Folders:
+
+
+ folderView
+
+
+
+ -
+
-
-
+
- Position:
+ Streams:
- sbPosition
+ streamsView
-
-
+
- -
-
+ -
+
- Only show icons, no text
+ Online:
+
+
+ onlineView
- -
-
+ -
+
+
+ -
+
- Use monochrome icons
+ Devices:
+
+
+ devicesView
- -
-
+ -
+
+
+ -
+
- Auto-hide
+ Search:
+ -
+
+
-
-
-
-
- Artists
-
-
- -
-
-
- QFormLayout::ExpandingFieldsGrow
-
- -
-
-
- Style:
-
-
- libraryView
-
-
-
- -
-
-
- -
-
-
- Covers:
-
-
- libraryCoverSize
-
-
-
- -
-
-
- -
-
-
- Show artist images
-
-
-
- -
-
-
- Sort albums by year
-
-
-
-
-
- -
-
+ -
+
Qt::Vertical
-
- QSizePolicy::Fixed
-
- 20
- 4
+ 2
+ 0
- -
-
-
-
- 0
- 0
-
-
-
- <i><b>NOTE:</b> When looking for artist images, Cantata will look for either artist.jpg, artist.png, 'Artist'.jpg, or 'Artist'.png,
-within the folder of the current track, or within its parent folder. If no image is found, Cantata will attempt to download one.</i>
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- true
-
-
- Qt::NoTextInteraction
-
-
-
-
-
-
-
- Albums
-
-
-
- QFormLayout::ExpandingFieldsGrow
-
- -
-
-
- Style:
-
-
- albumsView
-
-
-
- -
-
-
- -
-
-
- Covers:
-
-
- albumsCoverSize
-
-
-
- -
-
-
- -
-
-
- Sort albums:
-
-
- albumSort
-
-
-
- -
-
-
-
-
-
-
- Playlists
-
-
-
- QFormLayout::ExpandingFieldsGrow
-
- -
-
-
- Style:
-
-
- playlistsView
-
-
-
- -
-
-
- -
-
-
- Initially collapse albums
-
-
-
-
-
-
-
- Other Views
-
-
-
- QFormLayout::ExpandingFieldsGrow
-
- -
-
-
- Folder view style:
-
-
- folderView
-
-
-
- -
-
-
- -
-
-
- Streams view style:
-
-
- streamsView
-
-
-
- -
-
-
- -
-
-
- Online view style:
-
-
- onlineView
-
-
-
- -
-
-
- -
-
-
- Devices view style:
-
-
- devicesView
-
-
-
- -
-
-
- -
-
-
- Search view style:
-
-
-
- -
-
-
@@ -477,6 +395,29 @@
-
+
+
+ Separate action (and shortcut) for play queue search
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 2
+ 1
+
+
+
+
+ -
@@ -643,6 +584,37 @@
+
+
+ Toolbar
+
+
+
+ QFormLayout::ExpandingFieldsGrow
+
+ -
+
+
+ Show stop button
+
+
+
+ -
+
+
+ Show cover of current track
+
+
+
+ -
+
+
+ Show track rating
+
+
+
+
+
External
@@ -712,8 +684,8 @@
- 20
- 90
+ 2
+ 2
@@ -768,52 +740,45 @@
-
-
-
- Cache scaled covers
-
-
-
- -
Show delete action in context menus
- -
+
-
Enforce single-click activation of items
- -
+
-
<p>This will change Cantata's interface as detailed:
-<ul><li>Playback, and control, buttons will be 33% wider</li><li>Views will be 'flickable'</li><li>To drag items, you will need to 'touch' the top-left corner</li><li>Scrollbars will only be a few pixels wide</li><li>Actions (e.g. 'Add To Play Queue') will always be visible (not just when item is under mouse)</li><li>Spin buttons with have + and - buttons at the side of the text field</li></ul></p>
+<ul><li>Playback, and control, buttons will be 33% wider</li><li>Views will be 'flickable'</li><li>To drag items, you will need to 'touch' the top-left corner</li><li>Scrollbars will only be a few pixels wide</li><li>Actions (e.g. 'Add To Play Queue') will always be visible (not just when item is under mouse)</li><li>Spin buttons will have + and - buttons at the side of the text field</li></ul></p>
Make interface more touch friendly
- -
-
+ -
+
- Show stop button in toolbar
+ Show song information tooltips
- -
-
+ -
+
- Show cover of current track in toolbar
+ Support retina displays
- -
+
-
Language:
@@ -823,104 +788,36 @@
- -
+
-
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 4
-
-
-
-
- -
-
+
- <i><b>NOTE:</b> Changing the 'Enforce single-click activation of items' setting will require a re-start of Cantata.</i>
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- true
-
-
- Qt::NoTextInteraction
+ Changing the 'Enforce single-click activation of items' setting will require a re-start of Cantata.
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 4
-
-
-
-
- -
-
+
- <i><b>NOTE:</b> Changing the language setting will require a re-start of Cantata.</i>
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- true
-
-
- Qt::NoTextInteraction
+ Changing the language setting will require a re-start of Cantata.
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 4
-
+
+
+ Changing the 'touch friendly' setting will require a re-start of Cantata.
-
+
-
-
+
- <i><b>NOTE:</b> Changing the 'touch friendly' setting will require a re-start of Cantata.</i>
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- true
-
-
- Qt::NoTextInteraction
+ Enabling support for retina displays will produce sharper icons on the retina display, but may produce less sharp icons on non-retina displays. Changing this setting will require a re-start of Cantata.
@@ -950,9 +847,9 @@
- StateLabel
+ NoteLabel
QLabel
-
+
PathRequester
diff -Nru cantata-1.4.2.ds1/gui/librarypage.cpp cantata-1.5.2.ds2/gui/librarypage.cpp
--- cantata-1.4.2.ds1/gui/librarypage.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/librarypage.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -43,7 +43,6 @@
replacePlayQueue->setDefaultAction(StdActions::self()->replacePlayQueueAction);
view->addAction(StdActions::self()->addToPlayQueueAction);
- view->addAction(StdActions::self()->addRandomToPlayQueueAction);
view->addAction(StdActions::self()->replacePlayQueueAction);
view->addAction(StdActions::self()->addWithPriorityAction);
view->addAction(StdActions::self()->addToStoredPlaylistAction);
@@ -58,9 +57,7 @@
#endif
view->addAction(StdActions::self()->setCoverAction);
#ifdef ENABLE_DEVICES_SUPPORT
- QAction *sep=new QAction(this);
- sep->setSeparator(true);
- view->addAction(sep);
+ view->addSeparator();
view->addAction(StdActions::self()->deleteSongsAction);
#endif
#endif // TAGLIB_FOUND
@@ -68,10 +65,10 @@
connect(this, SIGNAL(add(const QStringList &, bool, quint8)), MPDConnection::self(), SLOT(add(const QStringList &, bool, quint8)));
connect(this, SIGNAL(addSongsToPlaylist(const QString &, const QStringList &)), MPDConnection::self(), SLOT(addToPlaylist(const QString &, const QStringList &)));
connect(genreCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(searchItems()));
- connect(MPDConnection::self(), SIGNAL(updatingLibrary()), this, SLOT(showSpinner()));
- connect(MPDConnection::self(), SIGNAL(updatedLibrary()), this, SLOT(hideSpinner()));
- connect(MPDConnection::self(), SIGNAL(updatingDatabase()), this, SLOT(showSpinner()));
- connect(MPDConnection::self(), SIGNAL(updatedDatabase()), this, SLOT(hideSpinner()));
+ connect(MPDConnection::self(), SIGNAL(updatingLibrary()), view, SLOT(updating()));
+ connect(MPDConnection::self(), SIGNAL(updatedLibrary()), view, SLOT(updated()));
+ connect(MPDConnection::self(), SIGNAL(updatingDatabase()), view, SLOT(updating()));
+ connect(MPDConnection::self(), SIGNAL(updatedDatabase()), view, SLOT(updated()));
connect(MusicLibraryModel::self(), SIGNAL(updateGenres(const QSet &)), genreCombo, SLOT(update(const QSet &)));
connect(this, SIGNAL(loadLibrary()), MPDConnection::self(), SLOT(loadLibrary()));
connect(view, SIGNAL(itemsSelected(bool)), this, SLOT(controlActions()));
@@ -88,37 +85,15 @@
view->save(metaObject()->className());
}
-void LibraryPage::setView(int v)
-{
- setItemSize(v);
- view->setMode((ItemView::Mode)v);
- MusicLibraryModel::self()->setLargeImages(ItemView::Mode_IconTop==v);
-}
-
void LibraryPage::showEvent(QShowEvent *e)
{
view->focusView();
QWidget::showEvent(e);
}
-void LibraryPage::setItemSize(int v)
-{
- if (ItemView::Mode_IconTop!=v) {
- MusicLibraryItemAlbum::setItemSize(QSize(0, 0));
- } else {
- QFontMetrics fm(font());
-
- int size=MusicLibraryItemAlbum::iconSize(true);
- QSize grid(size+8, size+(fm.height()*2.5));
- view->setGridSize(grid);
- MusicLibraryItemAlbum::setItemSize(grid-QSize(4, 4));
- }
-}
-
void LibraryPage::refresh()
{
view->goToTop();
-
if (!MusicLibraryModel::self()->fromXML()) {
emit loadLibrary();
}
@@ -135,73 +110,13 @@
return '{'+artist+"}{"+album+'}';
}
-QStringList LibraryPage::selectedFiles(bool allowPlaylists, bool randomAlbums) const
+QStringList LibraryPage::selectedFiles(bool allowPlaylists) const
{
QModelIndexList selected = view->selectedIndexes();
if (selected.isEmpty()) {
return QStringList();
}
-
- bool filteredOnly=proxy.enabled() && Settings::self()->filteredOnly();
- QModelIndexList mapped=proxy.mapToSource(selected, filteredOnly);
- if (randomAlbums) {
- if (filteredOnly) {
- QMap albums;
- foreach (const QModelIndex &idx, mapped) {
- if (idx.parent().isValid() && idx.parent().parent().isValid()) {
- albums[(idx.parent().parent().row()<<16)+idx.parent().row()].append(idx);
- }
- }
- QList keys=albums.keys();
- if (keys.isEmpty()) {
- return QStringList();
- } else if (1==keys.count()) {
- mapped=albums.begin().value();
- } else {
- mapped.clear();
- while (!keys.isEmpty()) {
- mapped.append(albums[keys.takeAt(Utils::random(keys.count()))]);
- }
- }
- } else {
- QModelIndexList albumIndexes;
- QSet albumNames;
- foreach (const QModelIndex &idx, mapped) {
- MusicLibraryItem *item=static_cast(idx.internalPointer());
- if (MusicLibraryItem::Type_Album==item->itemType()) {
- QString name=nameKey(item->parentItem()->data(), item->data());
- if (!albumNames.contains(name)) {
- albumNames.insert(name);
- albumIndexes.append(idx);
- }
- } else if (MusicLibraryItem::Type_Artist==item->itemType()) {
- for (int row=0; row(item)->childCount(); ++row) {
- MusicLibraryItem *album=static_cast(item)->childItem(row);
- QString name=nameKey(item->data(), album->data());
- if (!albumNames.contains(name)) {
- albumNames.insert(name);
- albumIndexes.append(MusicLibraryModel::self()->index(row, 0, idx));
- }
- }
- }
- }
-
- if (albumIndexes.isEmpty()) {
- return QStringList();
- }
-
- if (1==albumIndexes.count()) {
- mapped=albumIndexes;
- } else {
- mapped.clear();
- while (!albumIndexes.isEmpty()) {
- mapped.append(albumIndexes.takeAt(Utils::random(albumIndexes.count())));
- }
- }
- }
- }
-
- return MusicLibraryModel::self()->filenames(mapped, allowPlaylists);
+ return MusicLibraryModel::self()->filenames(proxy.mapToSource(selected, proxy.enabled() && Settings::self()->filteredOnly()), allowPlaylists);
}
QList LibraryPage::selectedSongs(bool allowPlaylists) const
@@ -232,9 +147,9 @@
return Song();
}
-void LibraryPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty, bool randomAlbums)
+void LibraryPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty)
{
- QStringList files=selectedFiles(name.isEmpty(), randomAlbums);
+ QStringList files=selectedFiles(name.isEmpty());
if (!files.isEmpty()) {
if (name.isEmpty()) {
@@ -262,7 +177,7 @@
QList songs=selectedSongs();
if (!songs.isEmpty()) {
- if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to delete the selected songs?\nThis cannot be undone."),
+ if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to delete the selected songs?\n\nThis cannot be undone."),
i18n("Delete Songs"), StdGuiItem::del(), StdGuiItem::cancel())) {
emit deleteSongs(QString(), songs);
}
@@ -337,7 +252,6 @@
}
}
-
void LibraryPage::itemDoubleClicked(const QModelIndex &)
{
const QModelIndexList selected = view->selectedIndexes(false); // Dont need sorted selection here...
@@ -414,17 +328,4 @@
}
}
}
- StdActions::self()->addRandomToPlayQueueAction->setEnabled(allowRandomAlbum);
-}
-
-void LibraryPage::showSpinner()
-{
- view->showSpinner();
- view->showMessage(i18n("Updating..."), -1);
-}
-
-void LibraryPage::hideSpinner()
-{
- view->hideSpinner();
- view->showMessage(QString(), 0);
}
diff -Nru cantata-1.4.2.ds1/gui/librarypage.h cantata-1.5.2.ds2/gui/librarypage.h
--- cantata-1.4.2.ds1/gui/librarypage.h 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/librarypage.h 2015-03-23 20:09:42.000000000 +0000
@@ -40,21 +40,22 @@
void refresh();
void clear();
- QStringList selectedFiles(bool allowPlaylists=false, bool randomAlbums=false) const;
+ QStringList selectedFiles(bool allowPlaylists=false) const;
QList selectedSongs(bool allowPlaylists=false) const;
Song coverRequest() const;
- void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0, bool randomAlbums=false);
+ void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0);
#ifdef ENABLE_DEVICES_SUPPORT
void addSelectionToDevice(const QString &udi);
void deleteSongs();
#endif
- void setView(int v);
+ void setView(int v) { view->setMode((ItemView::Mode)v); }
ItemView::Mode viewMode() const { return view->viewMode(); }
void showSongs(const QList &songs);
void showArtist(const QString &artist);
void showAlbum(const QString &artist, const QString &album);
void focusSearch() { view->focusSearch(); }
void showEvent(QShowEvent *e);
+ void resort() { proxy.resort(); }
private:
void setItemSize(int v);
@@ -73,8 +74,6 @@
void searchItems();
void controlActions();
void updateGenres(const QModelIndex &);
- void showSpinner();
- void hideSpinner();
private:
MusicLibraryProxyModel proxy;
diff -Nru cantata-1.4.2.ds1/gui/main.cpp cantata-1.5.2.ds2/gui/main.cpp
--- cantata-1.4.2.ds1/gui/main.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/main.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -53,6 +53,9 @@
#ifdef ENABLE_DYNAMIC
#include "dynamic/dynamic.h"
#endif
+#ifdef ENABLE_DEVICES_SUPPORT
+#include "models/devicesmodel.h"
+#endif
#include "streams/streamfetcher.h"
#include "http/httpserver.h"
#include "widgets/songdialog.h"
@@ -63,6 +66,9 @@
#endif
#include "context/contextwidget.h"
#include "scrobbling/scrobbler.h"
+#ifndef ENABLE_KDE_SUPPORT
+#include "gui/mediakeys.h"
+#endif
#include
#include
@@ -98,11 +104,19 @@
class PoTranslator : public QTranslator
{
public:
+ #if QT_VERSION < 0x050000
QString translate(const char *context, const char *sourceText, const char *disambiguation = 0) const
{
QString ret = QTranslator::translate(context, sourceText, disambiguation);
return !ret.isEmpty() ? ret : QTranslator::translate(NULL, sourceText, disambiguation);
}
+ #else
+ QString translate(const char *context, const char *sourceText, const char *disambiguation = 0, int n=-1) const
+ {
+ QString ret = QTranslator::translate(context, sourceText, disambiguation, n);
+ return !ret.isEmpty() ? ret : QTranslator::translate(NULL, sourceText, disambiguation, n);
+ }
+ #endif
};
static void loadTranslation(const QString &prefix, const QString &path, const QString &overrideLanguage = QString())
@@ -119,7 +133,6 @@
QString language = overrideLanguage.isEmpty() ? QLocale::system().name() : overrideLanguage;
QTranslator *t = new PoTranslator;
-
if (t->load(prefix+"_"+language, path)) {
QCoreApplication::installTranslator(t);
} else {
@@ -150,9 +163,11 @@
Dbg_Threads = 0x00004000,
Dbg_Tags = 0x00008000,
Dbg_Scrobbling = 0x00010000,
+ Dbg_Devices = 0x00020000,
+ DBG_Other = 0x00040000,
// NOTE: MUST UPDATE Dbg_All IF ADD NEW ITEMS!!!
- Dbg_All = 0x0001FFFF
+ Dbg_All = 0x0007FFFF
};
static void installDebugMessageHandler()
@@ -224,6 +239,16 @@
if (dbg&Dbg_Scrobbling) {
Scrobbler::enableDebug();
}
+ #ifdef ENABLE_DEVICES_SUPPORT
+ if (dbg&Dbg_Devices) {
+ DevicesModel::enableDebug();
+ }
+ #endif
+ #ifndef ENABLE_KDE_SUPPORT
+ if (dbg&DBG_Other) {
+ MediaKeys::enableDebug();
+ }
+ #endif
if (dbg&Dbg_All && logToFile) {
#if QT_VERSION < 0x050000
qInstallMsgHandler(cantataQtMsgHandler);
@@ -272,11 +297,7 @@
#else // ENABLE_KDE_SUPPORT
QCoreApplication::setApplicationName(PACKAGE_NAME);
- #ifdef Q_OS_WIN
- QCoreApplication::setOrganizationName("mpd");
- #else
- QCoreApplication::setOrganizationName(PACKAGE_NAME);
- #endif
+ QCoreApplication::setOrganizationName(ORGANIZATION_NAME);
Application app(argc, argv);
if (!app.start()) {
@@ -302,13 +323,11 @@
installDebugMessageHandler();
// Translations
- QString lang=qgetenv("CANTATA_LANG");
- if (lang.isEmpty()) {
- lang=Settings::self()->lang();
- }
- loadTranslation("qt", QLibraryInfo::location(QLibraryInfo::TranslationsPath), lang);
- #ifdef Q_OS_WIN
+ QString lang=Settings::self()->lang();
+ #if defined Q_OS_WIN || defined Q_OS_MAC
loadTranslation("qt", CANTATA_SYS_TRANS_DIR, lang);
+ #else
+ loadTranslation("qt", QLibraryInfo::location(QLibraryInfo::TranslationsPath), lang);
#endif
loadTranslation("cantata", CANTATA_SYS_TRANS_DIR, lang);
diff -Nru cantata-1.4.2.ds1/gui/mainwindow.cpp cantata-1.5.2.ds2/gui/mainwindow.cpp
--- cantata-1.4.2.ds1/gui/mainwindow.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/mainwindow.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -84,11 +84,21 @@
#ifdef QT_QTDBUS_FOUND
#include "dbus/mpris.h"
#include "cantataadaptor.h"
+#ifdef Q_OS_LINUX
#include "dbus/powermanagement.h"
#endif
+#endif
#if !defined Q_OS_WIN && !defined Q_OS_MAC
#include "devices/mountpoints.h"
#endif
+#ifdef Q_OS_MAC
+#include "support/windowmanager.h"
+#include "support/osxstyle.h"
+#include "mac/dockmenu.h"
+#ifdef IOKIT_FOUND
+#include "mac/powermanagement.h"
+#endif
+#endif
#ifdef ENABLE_DYNAMIC
#include "dynamic/dynamicpage.h"
#include "dynamic/dynamic.h"
@@ -104,29 +114,25 @@
#ifdef ENABLE_HTTP_STREAM_PLAYBACK
#include "mpd/httpstream.h"
#endif
-#ifdef Q_OS_WIN
-static void raiseWindow(QWidget *w);
-#endif
#include
#include
#include
#include
-#if defined Q_OS_MAC && QT_VERSION >= 0x050000
-// QMacNativeToolBar requres Qt Mac Extras to be installed on Qt 5.0 and 5.1.
-#include
-#endif
#if QT_VERSION >= 0x050000
#include
+#ifdef Q_OS_WIN
+#include "windows/thumbnailtoolbar.h"
+#endif
#endif
#include
#include
+#include
#ifdef ENABLE_KDE_SUPPORT
#include
#include
#include
#include
#include
-#include
#include
#else
#include
@@ -145,6 +151,8 @@
return k;
}
+static const char *constRatingKey="rating";
+
MainWindow::MainWindow(QWidget *parent)
: MAIN_WINDOW_BASE_CLASS(parent)
, prevPage(-1)
@@ -168,15 +176,14 @@
, contextSwitchTime(0)
, connectedState(CS_Init)
, stopAfterCurrent(false)
+ #if defined Q_OS_WIN && QT_VERSION >= 0x050000
+ , thumbnailTooolbar(0)
+ #endif
{
QPoint p=pos();
ActionCollection::setMainWidget(this);
trayItem=new TrayItem(this);
- #ifdef ENABLE_KDE_SUPPORT
- bool menuIcons=true;
- #else
- bool menuIcons=!QCoreApplication::testAttribute(Qt::AA_DontShowIconsInMenus);
- #endif
+ UNITY_MENU_ICON_CHECK
#ifdef QT_QTDBUS_FOUND
new CantataAdaptor(this);
QDBusConnection::sessionBus().registerObject("/cantata", this);
@@ -191,17 +198,21 @@
MPDParseUtils::setGroupSingle(Settings::self()->groupSingle());
Song::setUseComposer(Settings::self()->useComposer());
+ int hSpace=Utils::layoutSpacing(this);
+ int vSpace=fontMetrics().height()<14 ? hSpace/2 : 0;
+ toolbarLayout->setContentsMargins(hSpace, vSpace, hSpace, vSpace);
#ifdef Q_OS_WIN
GtkStyle::applyTheme(this); // Despite its name, it *might* also apply touch style to spinboxes...
+ toolbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
#else
- #if defined Q_OS_MAC && QT_VERSION>=0x050000
- QMacNativeToolBar *topToolBar = new QMacNativeToolBar(this);
- topToolBar->showInWindowForWidget(this);
- #else // defined Q_OS_MAC && QT_VERSION>=0x050000
setUnifiedTitleAndToolBarOnMac(true);
QToolBar *topToolBar = addToolBar("ToolBar");
- #endif // defined Q_OS_MAC && QT_VERSION>=0x050000
- toolbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ #ifdef Q_OS_MAC
+ WindowManager *wm=new WindowManager(topToolBar);
+ wm->initialize(WindowManager::WM_DRAG_MENU_AND_TOOLBAR);
+ wm->registerWidgetAndChildren(topToolBar);
+ #endif
+ toolbar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
topToolBar->setObjectName("MainToolBar");
topToolBar->addWidget(toolbar);
topToolBar->setMovable(false);
@@ -230,13 +241,13 @@
setWindowIcon(Icons::self()->appIcon);
prefAction=ActionCollection::get()->createAction("configure", Utils::KDE==Utils::currentDe() ? i18n("Configure Cantata...") : i18n("Preferences"),
- menuIcons ? Icons::self()->configureIcon : Icon());
- connect(prefAction, SIGNAL(triggered(bool)),this, SLOT(showPreferencesDialog()));
- quitAction = ActionCollection::get()->createAction("quit", i18n("Quit"), menuIcons ? "application-exit" : "");
- connect(quitAction, SIGNAL(triggered(bool)), this, SLOT(quit()));
+ HIDE_MENU_ICON(Icons::self()->configureIcon));
+ connect(prefAction, SIGNAL(triggered()),this, SLOT(showPreferencesDialog()));
+ quitAction = ActionCollection::get()->createAction("quit", i18n("Quit"), HIDE_MENU_ICON_NAME("application-exit"));
+ connect(quitAction, SIGNAL(triggered()), this, SLOT(quit()));
quitAction->setShortcut(QKeySequence::Quit);
- Action *aboutAction=ActionCollection::get()->createAction("about", i18nc("Qt-only", "About Cantata..."), menuIcons ? Icons::self()->appIcon : Icon());
- connect(aboutAction, SIGNAL(triggered(bool)),this, SLOT(showAboutDialog()));
+ Action *aboutAction=ActionCollection::get()->createAction("about", i18nc("Qt-only", "About Cantata..."), HIDE_MENU_ICON(Icons::self()->appIcon));
+ connect(aboutAction, SIGNAL(triggered()),this, SLOT(showAboutDialog()));
#ifdef Q_OS_MAC
prefAction->setMenuRole(QAction::PreferencesRole);
quitAction->setMenuRole(QAction::QuitRole);
@@ -244,59 +255,77 @@
#endif
#endif // ENABLE_KDE_SUPPORT
restoreAction = ActionCollection::get()->createAction("showwindow", i18n("Show Window"));
- connect(restoreAction, SIGNAL(triggered(bool)), this, SLOT(restoreWindow()));
+ connect(restoreAction, SIGNAL(triggered()), this, SLOT(restoreWindow()));
- serverInfoAction=ActionCollection::get()->createAction("mpdinfo", i18n("Server information..."), menuIcons ? "network-server" : "");
- connect(serverInfoAction, SIGNAL(triggered(bool)),this, SLOT(showServerInfo()));
+ serverInfoAction=ActionCollection::get()->createAction("mpdinfo", i18n("Server information..."), HIDE_MENU_ICON_NAME("network-server"));
+ connect(serverInfoAction, SIGNAL(triggered()),this, SLOT(showServerInfo()));
serverInfoAction->setEnabled(Settings::self()->firstRun());
- refreshDbAction = ActionCollection::get()->createAction("refresh", i18n("Refresh Database"), menuIcons ? "view-refresh" : "");
+ refreshDbAction = ActionCollection::get()->createAction("refresh", i18n("Refresh Database"), HIDE_MENU_ICON_NAME("view-refresh"));
doDbRefreshAction = new Action(refreshDbAction->icon(), i18n("Refresh"), this);
+ dbFullRefreshAction= new Action(refreshDbAction->icon(), i18n("Full Refresh"), this);
refreshDbAction->setEnabled(false);
connectAction = ActionCollection::get()->createAction("connect", i18n("Connect"), Icons::self()->connectIcon);
- connectionsAction = ActionCollection::get()->createAction("connections", i18n("Collection"), menuIcons ? "network-server" : "");
- outputsAction = ActionCollection::get()->createAction("outputs", i18n("Outputs"), menuIcons ? Icons::self()->speakerIcon : Icon());
+ connectionsAction = new Action(HIDE_MENU_ICON(Icon("network-server")), i18n("Collection"), this);
+ outputsAction = new Action(HIDE_MENU_ICON(Icons::self()->speakerIcon), i18n("Outputs"), this);
stopAfterTrackAction = ActionCollection::get()->createAction("stopaftertrack", i18n("Stop After Track"), Icons::self()->toolbarStopIcon);
- addPlayQueueToStoredPlaylistAction = ActionCollection::get()->createAction("addpqtostoredplaylist", i18n("Add To Stored Playlist"), Icons::self()->playlistIcon);
+ fwdAction = new Action(this);
+ revAction = new Action(this);
+ fwdAction->setShortcut((Qt::RightToLeft==layoutDirection() ? Qt::Key_Left : Qt::Key_Right)+Qt::ControlModifier);
+ revAction->setShortcut((Qt::RightToLeft==layoutDirection() ? Qt::Key_Right : Qt::Key_Left)+Qt::ControlModifier);
+ connect(fwdAction, SIGNAL(triggered()), MPDConnection::self(), SLOT(forward()));
+ connect(revAction, SIGNAL(triggered()), MPDConnection::self(), SLOT(reverse()));
+ addAction(fwdAction);
+ addAction(revAction);
+
+ addPlayQueueToStoredPlaylistAction = new Action(HIDE_MENU_ICON(Icons::self()->playlistIcon), i18n("Add To Stored Playlist"), this);
cropPlayQueueAction = ActionCollection::get()->createAction("cropplaylist", i18n("Crop"));
- addStreamToPlayQueueAction = ActionCollection::get()->createAction("addstreamtoplayqueue", i18n("Add Stream URL"), menuIcons ? Icons::self()->addRadioStreamIcon : Icon());
- promptClearPlayQueueAction = ActionCollection::get()->createAction("clearplaylist", i18n("Clear"), Icons::self()->clearListIcon);
+ addStreamToPlayQueueAction = ActionCollection::get()->createAction("addstreamtoplayqueue", i18n("Add Stream URL"), HIDE_MENU_ICON(Icons::self()->addRadioStreamIcon));
+ promptClearPlayQueueAction = ActionCollection::get()->createAction("clearplaylist", i18n("Clear"), HIDE_MENU_ICON(Icons::self()->clearListIcon));
centerPlayQueueAction = ActionCollection::get()->createAction("centerplaylist", i18n("Center On Current Track"), isRightToLeft() ? "go-previous" : "go-next");
- expandInterfaceAction = ActionCollection::get()->createAction("expandinterface", i18n("Expanded Interface"), menuIcons ? "view-media-playlist" : "");
+ expandInterfaceAction = ActionCollection::get()->createAction("expandinterface", i18n("Expanded Interface"), HIDE_MENU_ICON_NAME("view-media-playlist"));
expandInterfaceAction->setCheckable(true);
songInfoAction = ActionCollection::get()->createAction("showsonginfo", i18n("Show Current Song Information"), Icons::self()->infoIcon);
songInfoAction->setShortcut(Qt::Key_F12);
songInfoAction->setCheckable(true);
- fullScreenAction = ActionCollection::get()->createAction("fullScreen", i18n("Full Screen"), menuIcons ? "view-fullscreen" : "");
+ fullScreenAction = ActionCollection::get()->createAction("fullScreen", i18n("Full Screen"), HIDE_MENU_ICON_NAME("view-fullscreen"));
+ #ifndef Q_OS_MAC
fullScreenAction->setShortcut(Qt::Key_F11);
+ #endif
randomPlayQueueAction = ActionCollection::get()->createAction("randomplaylist", i18n("Random"), Icons::self()->shuffleIcon);
repeatPlayQueueAction = ActionCollection::get()->createAction("repeatplaylist", i18n("Repeat"), Icons::self()->repeatIcon);
singlePlayQueueAction = ActionCollection::get()->createAction("singleplaylist", i18n("Single"), Icons::self()->singleIcon, i18n("When 'Single' is activated, playback is stopped after current song, or song is repeated if 'Repeat' is enabled."));
consumePlayQueueAction = ActionCollection::get()->createAction("consumeplaylist", i18n("Consume"), Icons::self()->consumeIcon, i18n("When consume is activated, a song is removed from the play queue after it has been played."));
- setPriorityAction = ActionCollection::get()->createAction("setprio", i18n("Set Priority"), Icon("favorites"));
+ searchPlayQueueAction = ActionCollection::get()->createAction("searchplaylist", i18n("Find in Play Queue"), HIDE_MENU_ICON(Icons::self()->searchIcon));
+ addAction(searchPlayQueueAction);
+ searchPlayQueueAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+Qt::Key_F);
+ setPriorityAction = new Action(Icon("favorites"), i18n("Set Priority"), this);
#ifdef ENABLE_HTTP_STREAM_PLAYBACK
- streamPlayAction = ActionCollection::get()->createAction("streamplay", i18n("Play Stream"));
+ streamPlayAction = ActionCollection::get()->createAction("streamplay", i18n("Play Stream"), HIDE_MENU_ICON(Icons::self()->radioStreamIcon));
streamPlayAction->setCheckable(true);
streamPlayAction->setChecked(false);
streamPlayAction->setVisible(false);
+ streamPlayButton->setDefaultAction(streamPlayAction);
#endif
+ streamPlayButton->setVisible(false);
+
locateTrackAction = ActionCollection::get()->createAction("locatetrack", i18n("Locate In Library"), "edit-find");
#ifdef TAGLIB_FOUND
- editPlayQueueTagsAction = ActionCollection::get()->createAction("editpqtags", i18n("Edit Song Tags"), "document-edit");
+ editPlayQueueTagsAction = ActionCollection::get()->createAction("editpqtags", StdActions::self()->editTagsAction->text(), StdActions::self()->editTagsAction->icon());
#endif
addAction(expandAllAction = ActionCollection::get()->createAction("expandall", i18n("Expand All")));
expandAllAction->setShortcut(Qt::ControlModifier+Qt::Key_Plus);
addAction(collapseAllAction = ActionCollection::get()->createAction("collapseall", i18n("Collapse All")));
collapseAllAction->setShortcut(Qt::ControlModifier+Qt::Key_Minus);
- clearPlayQueueAction = ActionCollection::get()->createAction("confimclearplaylist", i18n("Remove All Songs"), Icons::self()->clearListIcon);
+ clearPlayQueueAction = ActionCollection::get()->createAction("confimclearplaylist", i18n("Remove All Songs"), HIDE_MENU_ICON(Icons::self()->clearListIcon));
clearPlayQueueAction->setShortcut(Qt::AltModifier+Qt::Key_Return);
cancelAction = ActionCollection::get()->createAction("cancel", i18n("Cancel"), Icons::self()->cancelIcon);
cancelAction->setShortcut(Qt::AltModifier+Qt::Key_Escape);
- connect(cancelAction, SIGNAL(triggered(bool)), messageWidget, SLOT(animatedHide()));
- connect(clearPlayQueueAction, SIGNAL(triggered(bool)), messageWidget, SLOT(animatedHide()));
- connect(clearPlayQueueAction, SIGNAL(triggered(bool)), this, SLOT(clearPlayQueue()));
+ connect(cancelAction, SIGNAL(triggered()), messageWidget, SLOT(animatedHide()));
+ connect(clearPlayQueueAction, SIGNAL(triggered()), messageWidget, SLOT(animatedHide()));
+ connect(clearPlayQueueAction, SIGNAL(triggered()), this, SLOT(clearPlayQueue()));
clearNewStateAction = ActionCollection::get()->createAction("clearnewstate", i18n("Clear 'New' State Of Artists and Albums"));
- connect(clearNewStateAction, SIGNAL(triggered(bool)), MusicLibraryModel::self(), SLOT(clearNewState()));
- connect(clearNewStateAction, SIGNAL(triggered(bool)), AlbumsModel::self(), SLOT(clearNewState()));
+ connect(clearNewStateAction, SIGNAL(triggered()), MusicLibraryModel::self(), SLOT(clearNewState()));
+ connect(clearNewStateAction, SIGNAL(triggered()), AlbumsModel::self(), SLOT(clearNewState()));
connect(MusicLibraryModel::self(), SIGNAL(haveNewItems(bool)), clearNewStateAction, SLOT(setEnabled(bool)));
clearNewStateAction->setEnabled(false);
@@ -342,13 +371,7 @@
QBoxLayout *layout=new QBoxLayout(QBoxLayout::TopToBottom, playQueuePage);
layout->setContentsMargins(0, 0, 0, 0);
bool playQueueInSidebar=!hiddenPages.contains(playQueuePage->metaObject()->className());
- if (playQueueInSidebar && (Settings::self()->firstRun() || Settings::self()->version()metaObject()->className());
- if (contextInSidebar && (Settings::self()->firstRun() || Settings::self()->version()setContentsMargins(0, 0, 0, 0);
@@ -358,36 +381,36 @@
addAction(showPlayQueueAction = ActionCollection::get()->createAction("showplayqueue", i18n("Play Queue"), Icons::self()->playqueueIcon));
showPlayQueueAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+Qt::Key_Q);
tabWidget->addTab(playQueuePage, TAB_ACTION(showPlayQueueAction), playQueueInSidebar);
- connect(showPlayQueueAction, SIGNAL(triggered(bool)), this, SLOT(showPlayQueue()));
+ connect(showPlayQueueAction, SIGNAL(triggered()), this, SLOT(showPlayQueue()));
libraryPage = new LibraryPage(this);
addAction(libraryTabAction = ActionCollection::get()->createAction("showlibrarytab", i18n("Artists"), Icons::self()->artistsIcon));
libraryTabAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+nextKey(sidebarPageShortcutKey));
tabWidget->addTab(libraryPage, TAB_ACTION(libraryTabAction), !hiddenPages.contains(libraryPage->metaObject()->className()));
- connect(libraryTabAction, SIGNAL(triggered(bool)), this, SLOT(showLibraryTab()));
+ connect(libraryTabAction, SIGNAL(triggered()), this, SLOT(showLibraryTab()));
albumsPage = new AlbumsPage(this);
addAction(albumsTabAction = ActionCollection::get()->createAction("showalbumstab", i18n("Albums"), Icons::self()->albumsIcon));
albumsTabAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+nextKey(sidebarPageShortcutKey));
tabWidget->addTab(albumsPage, TAB_ACTION(albumsTabAction), !hiddenPages.contains(albumsPage->metaObject()->className()));
- connect(albumsTabAction, SIGNAL(triggered(bool)), this, SLOT(showAlbumsTab()));
+ connect(albumsTabAction, SIGNAL(triggered()), this, SLOT(showAlbumsTab()));
AlbumsModel::self()->setEnabled(!hiddenPages.contains(albumsPage->metaObject()->className()));
folderPage = new FolderPage(this);
addAction(foldersTabAction = ActionCollection::get()->createAction("showfolderstab", i18n("Folders"), Icons::self()->foldersIcon));
foldersTabAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+nextKey(sidebarPageShortcutKey));
tabWidget->addTab(folderPage, TAB_ACTION(foldersTabAction), !hiddenPages.contains(folderPage->metaObject()->className()));
- connect(foldersTabAction, SIGNAL(triggered(bool)), this, SLOT(showFoldersTab()));
+ connect(foldersTabAction, SIGNAL(triggered()), this, SLOT(showFoldersTab()));
folderPage->setEnabled(!hiddenPages.contains(folderPage->metaObject()->className()));
playlistsPage = new PlaylistsPage(this);
addAction(playlistsTabAction = ActionCollection::get()->createAction("showplayliststab", i18n("Playlists"), Icons::self()->playlistsIcon));
playlistsTabAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+nextKey(sidebarPageShortcutKey));
tabWidget->addTab(playlistsPage, TAB_ACTION(playlistsTabAction), !hiddenPages.contains(playlistsPage->metaObject()->className()));
- connect(playlistsTabAction, SIGNAL(triggered(bool)), this, SLOT(showPlaylistsTab()));
+ connect(playlistsTabAction, SIGNAL(triggered()), this, SLOT(showPlaylistsTab()));
setPlaylistsEnabled(!hiddenPages.contains(playlistsPage->metaObject()->className()));
#ifdef ENABLE_DYNAMIC
dynamicPage = new DynamicPage(this);
addAction(dynamicTabAction = ActionCollection::get()->createAction("showdynamictab", i18n("Dynamic"), Icons::self()->dynamicIcon));
dynamicTabAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+nextKey(sidebarPageShortcutKey));
tabWidget->addTab(dynamicPage, TAB_ACTION(dynamicTabAction), !hiddenPages.contains(dynamicPage->metaObject()->className()));
- connect(dynamicTabAction, SIGNAL(triggered(bool)), this, SLOT(showDynamicTab()));
+ connect(dynamicTabAction, SIGNAL(triggered()), this, SLOT(showDynamicTab()));
connect(Dynamic::self(), SIGNAL(error(const QString &)), SLOT(showError(const QString &)));
connect(Dynamic::self(), SIGNAL(running(bool)), dynamicLabel, SLOT(setVisible(bool)));
connect(Dynamic::self(), SIGNAL(running(bool)), this, SLOT(controlDynamicButton()));
@@ -398,7 +421,7 @@
addAction(streamsTabAction = ActionCollection::get()->createAction("showstreamstab", i18n("Streams"), Icons::self()->streamsIcon));
streamsTabAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+nextKey(sidebarPageShortcutKey));
tabWidget->addTab(streamsPage, TAB_ACTION(streamsTabAction), !hiddenPages.contains(streamsPage->metaObject()->className()));
- connect(streamsTabAction, SIGNAL(triggered(bool)), this, SLOT(showStreamsTab()));
+ connect(streamsTabAction, SIGNAL(triggered()), this, SLOT(showStreamsTab()));
connect(streamsPage, SIGNAL(add(const QStringList &, bool, quint8)), &playQueueModel, SLOT(addItems(const QStringList &, bool, quint8)));
connect(streamsPage, SIGNAL(error(QString)), this, SLOT(showError(QString)));
connect(streamsPage, SIGNAL(showPreferencesPage(QString)), this, SLOT(showPreferencesDialog(QString)));
@@ -409,7 +432,7 @@
onlineTabAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+nextKey(sidebarPageShortcutKey));
tabWidget->addTab(onlinePage, TAB_ACTION(onlineTabAction), !hiddenPages.contains(onlinePage->metaObject()->className()));
onlinePage->setEnabled(!hiddenPages.contains(onlinePage->metaObject()->className()));
- connect(onlineTabAction, SIGNAL(triggered(bool)), this, SLOT(showOnlineTab()));
+ connect(onlineTabAction, SIGNAL(triggered()), this, SLOT(showOnlineTab()));
connect(onlinePage, SIGNAL(showPreferencesPage(QString)), this, SLOT(showPreferencesDialog(QString)));
connect(onlinePage, SIGNAL(addToDevice(const QString &, const QString &, const QList &)), SLOT(copyToDevice(const QString &, const QString &, const QList &)));
connect(OnlineServicesModel::self(), SIGNAL(error(const QString &)), this, SLOT(showError(const QString &)));
@@ -420,12 +443,12 @@
devicesTabAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+nextKey(sidebarPageShortcutKey));
tabWidget->addTab(devicesPage, TAB_ACTION(devicesTabAction), !hiddenPages.contains(devicesPage->metaObject()->className()));
DevicesModel::self()->setEnabled(!hiddenPages.contains(devicesPage->metaObject()->className()));
- connect(devicesTabAction, SIGNAL(triggered(bool)), this, SLOT(showDevicesTab()));
+ connect(devicesTabAction, SIGNAL(triggered()), this, SLOT(showDevicesTab()));
#endif
searchPage = new SearchPage(this);
addAction(searchTabAction = ActionCollection::get()->createAction("showsearchtab", i18n("Search"), Icons::self()->searchTabIcon));
searchTabAction->setShortcut(Qt::ControlModifier+Qt::ShiftModifier+nextKey(sidebarPageShortcutKey));
- connect(searchTabAction, SIGNAL(triggered(bool)), this, SLOT(showSearchTab()));
+ connect(searchTabAction, SIGNAL(triggered()), this, SLOT(showSearchTab()));
connect(searchPage, SIGNAL(locate(QList)), this, SLOT(locateTracks(QList)));
tabWidget->addTab(searchPage, TAB_ACTION(searchTabAction), !hiddenPages.contains(searchPage->metaObject()->className()));
tabWidget->addTab(contextPage, Icons::self()->infoSidebarIcon, i18n("Info"), songInfoAction->text(),
@@ -457,6 +480,7 @@
songInfoButton->setDefaultAction(songInfoAction);
fullScreenLabel->setVisible(false);
connect(fullScreenLabel, SIGNAL(leftClickedUrl()), fullScreenAction, SIGNAL(triggered()));
+ connect(playQueueSearchWidget, SIGNAL(active(bool)), playQueue, SLOT(searchActive(bool)));
if (Configuration(playQueuePage->metaObject()->className()).get(ItemView::constSearchActiveKey, false)) {
playQueueSearchWidget->activate();
} else {
@@ -521,9 +545,19 @@
singlePlayQueueAction->setChecked(false);
consumePlayQueueAction->setChecked(false);
- MusicLibraryItemAlbum::setCoverSize((MusicLibraryItemAlbum::CoverSize)Settings::self()->libraryCoverSize());
+ #ifdef UNITY_MENU_HACK
+ if (!menuIcons) {
+ // These buttons have actions that are in the menubar, as wall as in the main window.
+ // Under unity we dont want any icons in menus - so the actions themselves have no icons.
+ // But the toolbuttuns need icons!
+ #ifdef ENABLE_HTTP_STREAM_PLAYBACK
+ streamPlayButton->setIcon(Icons::self()->radioStreamIcon);
+ #endif
+ savePlayQueueButton->setIcon(Icon("document-save-as"));
+ clearPlayQueueButton->setIcon(Icons::self()->clearListIcon);
+ }
+ #endif
MusicLibraryItemAlbum::setSortByDate(Settings::self()->libraryYear());
- AlbumsModel::setCoverSize((MusicLibraryItemAlbum::CoverSize)Settings::self()->albumsCoverSize());
expandedSize=Settings::self()->mainWindowSize();
collapsedSize=Settings::self()->mainWindowCollapsedSize();
@@ -597,6 +631,7 @@
mainMenu->addAction(shortcutsAction);
mainMenu->addSeparator();
mainMenu->addAction(StdActions::self()->searchAction);
+ mainMenu->addAction(searchPlayQueueAction);
mainMenu->addSeparator();
mainMenu->addAction(serverInfoAction);
mainMenu->addMenu(helpMenu());
@@ -606,6 +641,7 @@
mainMenu->addAction(clearNewStateAction);
mainMenu->addSeparator();
mainMenu->addAction(StdActions::self()->searchAction);
+ mainMenu->addAction(searchPlayQueueAction);
mainMenu->addSeparator();
mainMenu->addAction(serverInfoAction);
mainMenu->addAction(aboutAction);
@@ -638,6 +674,7 @@
addMenuAction(menu, clearNewStateAction);
menu->addSeparator();
addMenuAction(menu, StdActions::self()->searchAction);
+ addMenuAction(menu, searchPlayQueueAction);
#ifndef ENABLE_KDE_SUPPORT
if (Utils::KDE!=Utils::currentDe()) {
menu->addSeparator();
@@ -660,9 +697,8 @@
}
#endif
menu=new QMenu(i18n("&Queue"), this);
-// addMenuAction(menu, promptClearPlayQueueAction);
-// addMenuAction(menu, StdActions::self()->savePlayQueueAction);
-// menu->addSeparator();
+ addMenuAction(menu, promptClearPlayQueueAction);
+ addMenuAction(menu, StdActions::self()->savePlayQueueAction);
addMenuAction(menu, addStreamToPlayQueueAction);
menu->addSeparator();
addMenuAction(menu, playQueueModel.shuffleAct());
@@ -686,6 +722,9 @@
addMenuAction(menu, prefAction);
menuBar()->addMenu(menu);
}
+ #ifdef Q_OS_MAC
+ OSXStyle::self()->initWindowMenu(this);
+ #endif
menu=new QMenu(i18n("&Help"), this);
addMenuAction(menu, serverInfoAction);
#ifdef ENABLE_KDE_SUPPORT
@@ -714,25 +753,42 @@
playQueueProxyModel.setSourceModel(&playQueueModel);
playQueue->setModel(&playQueueProxyModel);
playQueue->addAction(playQueue->removeFromAct());
+ ratingAction=new Action(i18n("Set Rating"), this);
+ ratingAction->setMenu(new QMenu(0));
+ for (int i=0; i<((Song::Rating_Max/Song::Rating_Step)+1); ++i) {
+ QString text;
+ if (0==i) {
+ text=i18n("No Rating");
+ } else {
+ for (int s=0; ssetProperty(constRatingKey, i*Song::Rating_Step);
+ ratingAction->menu()->addAction(action);
+ connect(action, SIGNAL(triggered()), SLOT(setRating()));
+ }
+ playQueue->addAction(ratingAction);
+ playQueue->addAction(setPriorityAction);
+ playQueue->addAction(stopAfterTrackAction);
+ playQueue->addAction(locateTrackAction);
+ #ifdef TAGLIB_FOUND
+ playQueue->addAction(editPlayQueueTagsAction);
+ #endif
+ Action *sep=new Action(this);
+ sep->setSeparator(true);
+ playQueue->addAction(sep);
+ playQueue->addAction(playQueueModel.removeDuplicatesAct());
playQueue->addAction(promptClearPlayQueueAction);
+ playQueue->addAction(cropPlayQueueAction);
playQueue->addAction(StdActions::self()->savePlayQueueAction);
playQueue->addAction(addStreamToPlayQueueAction);
playQueue->addAction(addPlayQueueToStoredPlaylistAction);
- playQueue->addAction(cropPlayQueueAction);
playQueue->addAction(playQueueModel.shuffleAct());
playQueue->addAction(playQueueModel.sortAct());
playQueue->addAction(playQueueModel.undoAct());
playQueue->addAction(playQueueModel.redoAct());
- Action *sep=new Action(this);
- sep->setSeparator(true);
- playQueue->addAction(sep);
- playQueue->addAction(stopAfterTrackAction);
- playQueue->addAction(setPriorityAction);
- playQueue->addAction(locateTrackAction);
- #ifdef TAGLIB_FOUND
- playQueue->addAction(editPlayQueueTagsAction);
- #endif
- playQueue->addAction(playQueueModel.removeDuplicatesAct());
playQueue->readConfig();
playlistsPage->setStartClosed(Settings::self()->playListsStartClosed());
@@ -745,18 +801,18 @@
connect(playlistsPage, SIGNAL(addToDevice(const QString &, const QString &, const QList &)), SLOT(copyToDevice(const QString &, const QString &, const QList &)));
connect(devicesPage, SIGNAL(addToDevice(const QString &, const QString &, const QList &)), SLOT(copyToDevice(const QString &, const QString &, const QList &)));
connect(searchPage, SIGNAL(addToDevice(const QString &, const QString &, const QList &)), SLOT(copyToDevice(const QString &, const QString &, const QList &)));
- connect(StdActions::self()->deleteSongsAction, SIGNAL(triggered(bool)), SLOT(deleteSongs()));
+ connect(StdActions::self()->deleteSongsAction, SIGNAL(triggered()), SLOT(deleteSongs()));
connect(devicesPage, SIGNAL(deleteSongs(const QString &, const QList &)), SLOT(deleteSongs(const QString &, const QList &)));
connect(libraryPage, SIGNAL(deleteSongs(const QString &, const QList &)), SLOT(deleteSongs(const QString &, const QList &)));
connect(albumsPage, SIGNAL(deleteSongs(const QString &, const QList &)), SLOT(deleteSongs(const QString &, const QList &)));
connect(folderPage, SIGNAL(deleteSongs(const QString &, const QList &)), SLOT(deleteSongs(const QString &, const QList &)));
#endif
- connect(StdActions::self()->addPrioHighestAction, SIGNAL(triggered(bool)), this, SLOT(addWithPriority()));
- connect(StdActions::self()->addPrioHighAction, SIGNAL(triggered(bool)), this, SLOT(addWithPriority()));
- connect(StdActions::self()->addPrioMediumAction, SIGNAL(triggered(bool)), this, SLOT(addWithPriority()));
- connect(StdActions::self()->addPrioLowAction, SIGNAL(triggered(bool)), this, SLOT(addWithPriority()));
- connect(StdActions::self()->addPrioDefaultAction, SIGNAL(triggered(bool)), this, SLOT(addWithPriority()));
- connect(StdActions::self()->addPrioCustomAction, SIGNAL(triggered(bool)), this, SLOT(addWithPriority()));
+ connect(StdActions::self()->addPrioHighestAction, SIGNAL(triggered()), this, SLOT(addWithPriority()));
+ connect(StdActions::self()->addPrioHighAction, SIGNAL(triggered()), this, SLOT(addWithPriority()));
+ connect(StdActions::self()->addPrioMediumAction, SIGNAL(triggered()), this, SLOT(addWithPriority()));
+ connect(StdActions::self()->addPrioLowAction, SIGNAL(triggered()), this, SLOT(addWithPriority()));
+ connect(StdActions::self()->addPrioDefaultAction, SIGNAL(triggered()), this, SLOT(addWithPriority()));
+ connect(StdActions::self()->addPrioCustomAction, SIGNAL(triggered()), this, SLOT(addWithPriority()));
connect(MPDConnection::self(), SIGNAL(outputsUpdated(const QList &)), this, SLOT(outputsUpdated(const QList &)));
connect(this, SIGNAL(enableOutput(int, bool)), MPDConnection::self(), SLOT(enableOutput(int, bool)));
connect(this, SIGNAL(outputs()), MPDConnection::self(), SLOT(outputs()));
@@ -781,23 +837,27 @@
connect(MPDStats::self(), SIGNAL(updated()), this, SLOT(updateStats()));
connect(MPDStatus::self(), SIGNAL(updated()), this, SLOT(updateStatus()));
connect(MPDConnection::self(), SIGNAL(playlistUpdated(const QList &)), this, SLOT(updatePlayQueue(const QList &)));
- connect(MPDConnection::self(), SIGNAL(currentSongUpdated(const Song &)), this, SLOT(updateCurrentSong(const Song &)));
+ connect(MPDConnection::self(), SIGNAL(currentSongUpdated(Song)), this, SLOT(updateCurrentSong(Song)));
connect(MPDConnection::self(), SIGNAL(stateChanged(bool)), SLOT(mpdConnectionStateChanged(bool)));
connect(MPDConnection::self(), SIGNAL(error(const QString &, bool)), SLOT(showError(const QString &, bool)));
connect(MPDConnection::self(), SIGNAL(info(const QString &)), SLOT(showInformation(const QString &)));
connect(MPDConnection::self(), SIGNAL(dirChanged()), SLOT(checkMpdDir()));
- connect(refreshDbAction, SIGNAL(triggered(bool)), this, SLOT(refreshDbPromp()));
- connect(doDbRefreshAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(update()));
- connect(doDbRefreshAction, SIGNAL(triggered(bool)), messageWidget, SLOT(animatedHide()));
- connect(connectAction, SIGNAL(triggered(bool)), this, SLOT(connectToMpd()));
- connect(StdActions::self()->prevTrackAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(goToPrevious()));
- connect(StdActions::self()->nextTrackAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(goToNext()));
- connect(StdActions::self()->playPauseTrackAction, SIGNAL(triggered(bool)), this, SLOT(playPauseTrack()));
- connect(StdActions::self()->stopPlaybackAction, SIGNAL(triggered(bool)), this, SLOT(stopPlayback()));
- connect(StdActions::self()->stopAfterCurrentTrackAction, SIGNAL(triggered(bool)), this, SLOT(stopAfterCurrentTrack()));
- connect(stopAfterTrackAction, SIGNAL(triggered(bool)), this, SLOT(stopAfterTrack()));
+ connect(refreshDbAction, SIGNAL(triggered()), this, SLOT(refreshDbPromp()));
+ connect(doDbRefreshAction, SIGNAL(triggered()), MPDConnection::self(), SLOT(update()));
+ connect(doDbRefreshAction, SIGNAL(triggered()), messageWidget, SLOT(animatedHide()));
+ connect(dbFullRefreshAction, SIGNAL(triggered()), this, SLOT(fullDbRefresh()));
+ connect(dbFullRefreshAction, SIGNAL(triggered()), MPDConnection::self(), SLOT(update()));
+ connect(dbFullRefreshAction, SIGNAL(triggered()), messageWidget, SLOT(animatedHide()));
+ connect(connectAction, SIGNAL(triggered()), this, SLOT(connectToMpd()));
+ connect(StdActions::self()->prevTrackAction, SIGNAL(triggered()), MPDConnection::self(), SLOT(goToPrevious()));
+ connect(StdActions::self()->nextTrackAction, SIGNAL(triggered()), MPDConnection::self(), SLOT(goToNext()));
+ connect(StdActions::self()->playPauseTrackAction, SIGNAL(triggered()), this, SLOT(playPauseTrack()));
+ connect(StdActions::self()->stopPlaybackAction, SIGNAL(triggered()), this, SLOT(stopPlayback()));
+ connect(StdActions::self()->stopAfterCurrentTrackAction, SIGNAL(triggered()), this, SLOT(stopAfterCurrentTrack()));
+ connect(stopAfterTrackAction, SIGNAL(triggered()), this, SLOT(stopAfterTrack()));
connect(this, SIGNAL(setVolume(int)), MPDConnection::self(), SLOT(setVolume(int)));
connect(nowPlaying, SIGNAL(sliderReleased()), this, SLOT(setPosition()));
+ connect(&playQueueModel, SIGNAL(currentSongRating(QString,quint8)), nowPlaying, SLOT(rating(QString,quint8)));
connect(randomPlayQueueAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(setRandom(bool)));
connect(repeatPlayQueueAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(setRepeat(bool)));
connect(singlePlayQueueAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(setSingle(bool)));
@@ -810,35 +870,35 @@
connect(playQueueSearchWidget, SIGNAL(textChanged(const QString)), this, SLOT(searchPlayQueue()));
connect(playQueueSearchWidget, SIGNAL(active(bool)), this, SLOT(playQueueSearchActivated(bool)));
connect(playQueue, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(playQueueItemActivated(const QModelIndex &)));
- connect(StdActions::self()->removeAction, SIGNAL(triggered(bool)), this, SLOT(removeItems()));
- connect(StdActions::self()->addToPlayQueueAction, SIGNAL(triggered(bool)), this, SLOT(addToPlayQueue()));
- connect(StdActions::self()->addRandomToPlayQueueAction, SIGNAL(triggered(bool)), this, SLOT(addRandomToPlayQueue()));
- connect(StdActions::self()->replacePlayQueueAction, SIGNAL(triggered(bool)), this, SLOT(replacePlayQueue()));
- connect(playQueue->removeFromAct(), SIGNAL(triggered(bool)), this, SLOT(removeFromPlayQueue()));
- connect(promptClearPlayQueueAction, SIGNAL(triggered(bool)), playQueueSearchWidget, SLOT(clear()));
- connect(promptClearPlayQueueAction, SIGNAL(triggered(bool)), this, SLOT(promptClearPlayQueue()));
- connect(centerPlayQueueAction, SIGNAL(triggered(bool)), this, SLOT(centerPlayQueue()));
- connect(cropPlayQueueAction, SIGNAL(triggered(bool)), this, SLOT(cropPlayQueue()));
- connect(songInfoAction, SIGNAL(triggered(bool)), this, SLOT(showSongInfo()));
- connect(expandInterfaceAction, SIGNAL(triggered(bool)), this, SLOT(expandOrCollapse()));
- connect(fullScreenAction, SIGNAL(triggered(bool)), this, SLOT(fullScreen()));
+ connect(StdActions::self()->removeAction, SIGNAL(triggered()), this, SLOT(removeItems()));
+ connect(StdActions::self()->addToPlayQueueAction, SIGNAL(triggered()), this, SLOT(addToPlayQueue()));
+ connect(StdActions::self()->replacePlayQueueAction, SIGNAL(triggered()), this, SLOT(replacePlayQueue()));
+ connect(playQueue->removeFromAct(), SIGNAL(triggered()), this, SLOT(removeFromPlayQueue()));
+ connect(promptClearPlayQueueAction, SIGNAL(triggered()), playQueueSearchWidget, SLOT(clear()));
+ connect(promptClearPlayQueueAction, SIGNAL(triggered()), this, SLOT(promptClearPlayQueue()));
+ connect(centerPlayQueueAction, SIGNAL(triggered()), this, SLOT(centerPlayQueue()));
+ connect(cropPlayQueueAction, SIGNAL(triggered()), this, SLOT(cropPlayQueue()));
+ connect(songInfoAction, SIGNAL(triggered()), this, SLOT(showSongInfo()));
+ connect(expandInterfaceAction, SIGNAL(triggered()), this, SLOT(expandOrCollapse()));
+ connect(fullScreenAction, SIGNAL(triggered()), this, SLOT(fullScreen()));
#ifdef TAGLIB_FOUND
- connect(StdActions::self()->editTagsAction, SIGNAL(triggered(bool)), this, SLOT(editTags()));
- connect(editPlayQueueTagsAction, SIGNAL(triggered(bool)), this, SLOT(editPlayQueueTags()));
- connect(StdActions::self()->organiseFilesAction, SIGNAL(triggered(bool)), SLOT(organiseFiles()));
+ connect(StdActions::self()->editTagsAction, SIGNAL(triggered()), this, SLOT(editTags()));
+ connect(editPlayQueueTagsAction, SIGNAL(triggered()), this, SLOT(editTags()));
+ connect(StdActions::self()->organiseFilesAction, SIGNAL(triggered()), SLOT(organiseFiles()));
#endif
connect(context, SIGNAL(findArtist(QString)), this, SLOT(locateArtist(QString)));
connect(context, SIGNAL(findAlbum(QString,QString)), this, SLOT(locateAlbum(QString,QString)));
connect(context, SIGNAL(playSong(QString)), &playQueueModel, SLOT(playSong(QString)));
- connect(locateTrackAction, SIGNAL(triggered(bool)), this, SLOT(locateTrack()));
- connect(StdActions::self()->searchAction, SIGNAL(triggered(bool)), SLOT(showSearch()));
+ connect(locateTrackAction, SIGNAL(triggered()), this, SLOT(locateTrack()));
+ connect(StdActions::self()->searchAction, SIGNAL(triggered()), SLOT(showSearch()));
+ connect(searchPlayQueueAction, SIGNAL(triggered()), this, SLOT(showPlayQueueSearch()));
connect(playQueue, SIGNAL(focusSearch(QString)), playQueueSearchWidget, SLOT(activate(QString)));
- connect(expandAllAction, SIGNAL(triggered(bool)), this, SLOT(expandAll()));
- connect(collapseAllAction, SIGNAL(triggered(bool)), this, SLOT(collapseAll()));
- connect(addStreamToPlayQueueAction, SIGNAL(triggered(bool)), this, SLOT(addStreamToPlayQueue()));
- connect(StdActions::self()->setCoverAction, SIGNAL(triggered(bool)), SLOT(setCover()));
+ connect(expandAllAction, SIGNAL(triggered()), this, SLOT(expandAll()));
+ connect(collapseAllAction, SIGNAL(triggered()), this, SLOT(collapseAll()));
+ connect(addStreamToPlayQueueAction, SIGNAL(triggered()), this, SLOT(addStreamToPlayQueue()));
+ connect(StdActions::self()->setCoverAction, SIGNAL(triggered()), SLOT(setCover()));
#ifdef ENABLE_REPLAYGAIN_SUPPORT
- connect(StdActions::self()->replaygainAction, SIGNAL(triggered(bool)), SLOT(replayGain()));
+ connect(StdActions::self()->replaygainAction, SIGNAL(triggered()), SLOT(replayGain()));
#endif
connect(PlaylistsModel::self(), SIGNAL(addToNew()), this, SLOT(addToNewStoredPlaylist()));
connect(PlaylistsModel::self(), SIGNAL(addToExisting(const QString &)), this, SLOT(addToExistingStoredPlaylist(const QString &)));
@@ -887,7 +947,10 @@
updateStats();
}
#ifndef ENABLE_KDE_SUPPORT
- MediaKeys::self()->load();
+ MediaKeys::self()->start();
+ #endif
+ #ifdef Q_OS_MAC
+ dockMenu=new DockMenu(this);
#endif
updateActionToolTips();
}
@@ -928,7 +991,7 @@
Settings::StartupState startupState=Settings::self()->startupState();
Settings::self()->saveStartHidden(trayItem->isActive() && Settings::self()->minimiseOnClose() &&
((isHidden() && Settings::SS_ShowMainWindow!=startupState) || (Settings::SS_HideMainWindow==startupState)));
- Settings::self()->save(true);
+ Settings::self()->save();
disconnect(MPDConnection::self(), 0, 0, 0);
#ifdef ENABLE_DYNAMIC
if (Settings::self()->stopOnExit()) {
@@ -1031,6 +1094,16 @@
}
}
+#if defined Q_OS_WIN && QT_VERSION >= 0x050000
+void MainWindow::showEvent(QShowEvent *event)
+{
+ if (!thumbnailTooolbar) {
+ thumbnailTooolbar=new ThumbnailToolBar(this);
+ }
+ MAIN_WINDOW_BASE_CLASS::showEvent(event);
+}
+#endif
+
void MainWindow::closeEvent(QCloseEvent *event)
{
if (trayItem->isActive() && Settings::self()->minimiseOnClose()) {
@@ -1058,6 +1131,7 @@
#endif
addPlayQueueToStoredPlaylistAction->setEnabled(haveItems);
stopAfterTrackAction->setEnabled(singleSelection);
+ ratingAction->setEnabled(s && haveItems);
}
void MainWindow::connectToMpd(const MPDConnectionDetails &details)
@@ -1093,6 +1167,7 @@
#ifdef ENABLE_HTTP_STREAM_PLAYBACK
streamPlayAction->setVisible(!u.isEmpty());
streamPlayAction->setChecked(streamPlayAction->isVisible() && Settings::self()->playStream());
+ streamPlayButton->setVisible(!u.isEmpty());
httpStream->setEnabled(streamPlayAction->isChecked());
#else
Q_UNUSED(u)
@@ -1101,15 +1176,22 @@
void MainWindow::refreshDbPromp()
{
- if (QDialogButtonBox::GnomeLayout==style()->styleHint(QStyle::SH_DialogButtonLayout)) {
- messageWidget->setActions(QList() << cancelAction << doDbRefreshAction);
+ int btnLayout=style()->styleHint(QStyle::SH_DialogButtonLayout);
+ if (QDialogButtonBox::GnomeLayout==btnLayout || QDialogButtonBox::MacLayout==btnLayout) {
+ messageWidget->setActions(QList() << cancelAction << doDbRefreshAction << dbFullRefreshAction);
} else {
- messageWidget->setActions(QList() << doDbRefreshAction << cancelAction);
+ messageWidget->setActions(QList() << doDbRefreshAction << dbFullRefreshAction << cancelAction);
}
messageWidget->setWarning(i18n("Refresh MPD Database?"), false);
expand();
}
+void MainWindow::fullDbRefresh()
+{
+ MusicLibraryModel::self()->removeCache();
+ DirViewModel::self()->removeCache();
+}
+
#ifdef ENABLE_KDE_SUPPORT
void MainWindow::configureShortcuts()
{
@@ -1137,6 +1219,19 @@
}
#endif
+bool MainWindow::canClose()
+{
+ #ifdef ENABLE_ONLINE_SERVICES
+ if (OnlineServicesModel::self()->isDownloading() &&
+ MessageBox::No==MessageBox::warningYesNo(this, i18n("A Podcast is currently being downloaded\n\nQuiting now will abort the download."),
+ QString(), GuiItem(i18n("Abort download and quit")), GuiItem("Do not quit just yet"))) {
+ return false;
+ }
+ OnlineServicesModel::self()->cancelAll();
+ #endif
+ return true;
+}
+
void MainWindow::expand()
{
if (!expandInterfaceAction->isChecked()) {
@@ -1177,10 +1272,10 @@
connect(pref, SIGNAL(settingsSaved()), this, SLOT(updateSettings()));
connect(pref, SIGNAL(destroyed()), SLOT(controlConnectionsMenu()));
connect(this, SIGNAL(showPreferencesPage(QString)), pref, SLOT(showPage(QString)));
- pref->show();
if (!page.isEmpty()) {
pref->showPage(page);
}
+ pref->show();
}
void MainWindow::quit()
@@ -1188,7 +1283,6 @@
if (!canClose()) {
return;
}
-
#ifdef ENABLE_REPLAYGAIN_SUPPORT
if (RgDialog::instanceCount()) {
return;
@@ -1221,8 +1315,8 @@
#endif
#ifdef TAGLIB_FOUND
- if (editPlayQueueTagsAction->isEnabled()) {
- editPlayQueueTagsAction->setEnabled(MPDConnection::self()->getDetails().dirReadable);
+ if (StdActions::self()->editTagsAction->isEnabled()) {
+ StdActions::self()->editTagsAction->setEnabled(MPDConnection::self()->getDetails().dirReadable);
}
#endif
if (currentPage) {
@@ -1232,44 +1326,75 @@
void MainWindow::outputsUpdated(const QList &outputs)
{
- if (outputs.count()<2) {
- outputsAction->setVisible(false);
+ const char *constMpdConName="mpd-name";
+ const char *constMpdEnabledOuptuts="mpd-outputs";
+ QString lastConn=property(constMpdConName).toString();
+ QString newConn=MPDConnection::self()->getDetails().name;
+ setProperty(constMpdConName, newConn);
+ outputsAction->setVisible(true);
+ QSet enabledMpd;
+ QSet lastEnabledMpd=QSet::fromList(property(constMpdEnabledOuptuts).toStringList());
+ QSet mpd;
+ QSet menuItems;
+ QMenu *menu=outputsAction->menu();
+ foreach (const Output &o, outputs) {
+ if (o.enabled) {
+ enabledMpd.insert(o.name);
+ }
+ mpd.insert(o.name);
+ }
+
+ foreach (QAction *act, menu->actions()) {
+ menuItems.insert(act->data().toString());
+ }
+
+ if (menuItems!=mpd) {
+ menu->clear();
+ QList out=outputs;
+ qSort(out);
+ int i=Qt::Key_1;
+ foreach (const Output &o, out) {
+ QAction *act=menu->addAction(o.name, this, SLOT(toggleOutput()));
+ act->setData(o.id);
+ act->setCheckable(true);
+ act->setChecked(o.enabled);
+ act->setShortcut(Qt::ControlModifier+Qt::AltModifier+nextKey(i));
+ }
} else {
- outputsAction->setVisible(true);
- QSet mpd;
- QSet menuItems;
- QMenu *menu=outputsAction->menu();
foreach (const Output &o, outputs) {
- mpd.insert(o.name);
- }
-
- foreach (QAction *act, menu->actions()) {
- menuItems.insert(act->data().toString());
- }
-
- if (menuItems!=mpd) {
- menu->clear();
- QList out=outputs;
- qSort(out);
- int i=Qt::Key_1;
- foreach (const Output &o, out) {
- QAction *act=menu->addAction(o.name, this, SLOT(toggleOutput()));
- act->setData(o.id);
- act->setCheckable(true);
- act->setChecked(o.enabled);
- act->setShortcut(Qt::MetaModifier+nextKey(i));
- }
- } else {
- foreach (const Output &o, outputs) {
- foreach (QAction *act, menu->actions()) {
- if (Utils::strippedText(act->text())==o.name) {
- act->setChecked(o.enabled);
- break;
- }
+ foreach (QAction *act, menu->actions()) {
+ if (Utils::strippedText(act->text())==o.name) {
+ act->setChecked(o.enabled);
+ break;
}
}
}
}
+
+ if (newConn==lastConn && enabledMpd!=lastEnabledMpd && !menuItems.isEmpty()) {
+ QSet switchedOn=enabledMpd-lastEnabledMpd;
+ QSet switchedOff=lastEnabledMpd-enabledMpd;
+
+ if (!switchedOn.isEmpty() && switchedOff.isEmpty()) {
+ QStringList names=switchedOn.toList();
+ qSort(names);
+ trayItem->showMessage(i18n("Outputs"), i18n("Enabled: %1", names.join(QLatin1String(", "))), Icons::self()->speakerIcon.pixmap(64, 64).toImage());
+ } else if (!switchedOff.isEmpty() && switchedOn.isEmpty()) {
+ QStringList names=switchedOff.toList();
+ qSort(names);
+ trayItem->showMessage(i18n("Outputs"), i18n("Disabled: %1", names.join(QLatin1String(", "))), Icons::self()->speakerIcon.pixmap(64, 64).toImage());
+ } else if (!switchedOn.isEmpty() && !switchedOff.isEmpty()) {
+ QStringList on=switchedOn.toList();
+ qSort(on);
+ QStringList off=switchedOff.toList();
+ qSort(off);
+ trayItem->showMessage(i18n("Outputs"),
+ i18n("Enabled: %1", on.join(QLatin1String(", ")))+QLatin1Char('\n')+
+ i18n("Disabled: %1", off.join(QLatin1String(", "))), Icons::self()->speakerIcon.pixmap(64, 64).toImage());
+ }
+ }
+ setProperty(constMpdEnabledOuptuts, QStringList() << enabledMpd.toList());
+ outputsAction->setVisible(outputs.count()>1);
}
void MainWindow::updateConnectionsMenu()
@@ -1326,6 +1451,14 @@
#endif
}
+void MainWindow::setRating()
+{
+ Action *act=qobject_cast(sender());
+ if (act) {
+ playQueueModel.setRating(playQueueProxyModel.mapToSourceRows(playQueue->selectedIndexes()), act->property(constRatingKey).toUInt());
+ }
+}
+
void MainWindow::readSettings()
{
#ifndef QT_QTDBUS_FOUND
@@ -1341,8 +1474,9 @@
Song::setUseComposer(Settings::self()->useComposer());
albumsPage->setView(Settings::self()->albumsView());
AlbumsModel::self()->setAlbumSort(Settings::self()->albumSort());
+ MusicLibraryItemAlbum::setSortByDate(Settings::self()->libraryYear());
+ MusicLibraryModel::self()->readConfig();
libraryPage->setView(Settings::self()->libraryView());
- MusicLibraryModel::self()->setUseArtistImages(Settings::self()->libraryArtistImage());
playlistsPage->setView(Settings::self()->playlistsView());
#ifdef ENABLE_STREAMS
streamsPage->setView(Settings::self()->streamsView());
@@ -1359,17 +1493,22 @@
autoScrollPlayQueue=Settings::self()->playQueueScroll();
updateWindowTitle();
TreeView::setForceSingleClick(Settings::self()->forceSingleClick());
- #ifdef QT_QTDBUS_FOUND
+ #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND)
PowerManagement::self()->setInhibitSuspend(Settings::self()->inhibitSuspend());
#endif
- #ifndef ENABLE_KDE_SUPPORT
- MediaKeys::self()->load();
- #endif
context->readConfig();
tabWidget->setHiddenPages(Settings::self()->hiddenPages());
tabWidget->setStyle(Settings::self()->sidebar());
coverWidget->setEnabled(Settings::self()->showCoverWidget());
stopTrackButton->setVisible(Settings::self()->showStopButton());
+ #if defined Q_OS_WIN && QT_VERSION >= 0x050000
+ if (thumbnailTooolbar) {
+ thumbnailTooolbar->readSettings();
+ }
+ #endif
+ searchPlayQueueAction->setEnabled(Settings::self()->playQueueSearch());
+ searchPlayQueueAction->setVisible(Settings::self()->playQueueSearch());
+ nowPlaying->readConfig();
setCollapsedSize();
toggleMonoIcons();
toggleSplitterAutoHide();
@@ -1384,72 +1523,39 @@
MPDConnection::self()->setVolumeFadeDuration(Settings::self()->stopFadeDuration());
}
-static inline bool diffCoverSize(int a, int b)
-{
- return (a==ItemView::Mode_IconTop && b!=ItemView::Mode_IconTop) || (a!=ItemView::Mode_IconTop && b==ItemView::Mode_IconTop);
-}
-
void MainWindow::updateSettings()
{
connectToMpd();
Settings::self()->save();
- bool diffLibCovers=((int)MusicLibraryItemAlbum::currentCoverSize())!=Settings::self()->libraryCoverSize() ||
- diffCoverSize(Settings::self()->libraryView(), libraryPage->viewMode());
- bool diffLibArtistImages=diffLibCovers ||
- (libraryPage->viewMode()==ItemView::Mode_IconTop && Settings::self()->libraryView()!=ItemView::Mode_IconTop) ||
- (libraryPage->viewMode()!=ItemView::Mode_IconTop && Settings::self()->libraryView()==ItemView::Mode_IconTop) ||
- Settings::self()->libraryArtistImage()!=MusicLibraryModel::self()->useArtistImages();
- bool diffAlCovers=((int)AlbumsModel::currentCoverSize())!=Settings::self()->albumsCoverSize() ||
- albumsPage->viewMode()!=Settings::self()->albumsView() ||
- diffCoverSize(Settings::self()->albumsView(), albumsPage->viewMode());
+ bool diffAlbumSort=AlbumsModel::self()->albumSort()!=Settings::self()->albumSort();
bool diffLibYear=MusicLibraryItemAlbum::sortByDate()!=Settings::self()->libraryYear();
bool diffGrouping=MPDParseUtils::groupSingle()!=Settings::self()->groupSingle() ||
Song::useComposer()!=Settings::self()->useComposer();
readSettings();
- if (diffLibArtistImages) {
- MusicLibraryItemArtist::clearDefaultCover();
- }
- if (diffLibCovers) {
- MusicLibraryItemAlbum::setCoverSize((MusicLibraryItemAlbum::CoverSize)Settings::self()->libraryCoverSize());
- }
- if (diffLibYear) {
- MusicLibraryItemAlbum::setSortByDate(Settings::self()->libraryYear());
- }
- if (diffLibArtistImages || diffLibCovers) {
- libraryPage->setView(libraryPage->viewMode());
- }
- if (diffAlCovers) {
- AlbumsModel::setCoverSize((MusicLibraryItemAlbum::CoverSize)Settings::self()->albumsCoverSize());
- }
- if (diffAlCovers || diffGrouping) {
- albumsPage->setView(albumsPage->viewMode());
- albumsPage->clear();
- }
-
if (diffGrouping) {
MusicLibraryModel::self()->toggleGrouping();
#ifdef ENABLE_DEVICES_SUPPORT
DevicesModel::self()->toggleGrouping();
#endif
+ #ifdef ENABLE_ONLINE_SERVICES
+ OnlineServicesModel::self()->toggleGrouping();
+ #endif
}
- if (diffLibCovers || diffLibYear || diffLibArtistImages || diffAlCovers) {
- libraryPage->clear();
- albumsPage->goTop();
- libraryPage->refresh();
+ if (diffAlbumSort) {
+ albumsPage->resort();
}
- #if defined ENABLE_ONLINE_SERVICES || defined ENABLE_DEVICES_SUPPORT
- if (diffLibCovers || diffLibYear || Settings::self()->libraryArtistImage()!=MusicLibraryModel::self()->useArtistImages()) {
+ if (diffLibYear) {
+ libraryPage->resort();
#ifdef ENABLE_ONLINE_SERVICES
- onlinePage->refresh();
+ onlinePage->resort();
#endif
#ifdef ENABLE_DEVICES_SUPPORT
- devicesPage->refresh();
+ devicesPage->resort();
#endif
}
- #endif
bool wasAutoExpand=playQueue->isAutoExpand();
bool wasStartClosed=playQueue->isStartClosed();
@@ -1494,7 +1600,11 @@
qSort(handlers);
qSort(tags);
long version=MPDConnection::self()->version();
- MessageBox::information(this, QLatin1String("
")+
+ MessageBox::information(this,
+ #ifdef Q_OS_MAC
+ i18n("Server Information")+QLatin1String(" ")+
+ #endif
+ QLatin1String("
")+
i18n("Server "
"Protocol: %1.%2.%3 "
"Uptime: %4 "
@@ -1635,7 +1745,7 @@
bool scroll=autoScrollPlayQueue && playQueueProxyModel.isEmpty() && (wasEmpty || MPDState_Playing==MPDStatus::self()->state());
playQueue->updateRows(idx.row(), current.key, scroll, wasEmpty);
if (!scroll && topRow>0 && topRowscrollTo(playQueueProxyModel.mapFromSource(playQueueModel.index(topRow, 0)), QAbstractItemView::PositionAtTop);
+ playQueue->scrollTo(playQueueProxyModel.mapFromSource(playQueueModel.index(topRow, PlayQueueModel::COL_TITLE)), QAbstractItemView::PositionAtTop);
}
if (songs.isEmpty()) {
@@ -1643,7 +1753,7 @@
} else if (wasEmpty || current.isStandardStream()) {
// Check to see if it has been updated...
Song pqSong=playQueueModel.getSongByRow(playQueueModel.currentSongRow());
- if (wasEmpty || pqSong.artist!=current.artist || pqSong.album!=current.album || pqSong.title!=current.title || pqSong.year!=current.year || pqSong.name()!=current.name() ) {
+ if (wasEmpty || pqSong.isDifferent(current) ) {
updateCurrentSong(pqSong, wasEmpty);
}
}
@@ -1657,27 +1767,29 @@
setWindowTitle(multipleConnections ? i18n("Cantata (%1)", connection) : "Cantata");
}
-void MainWindow::updateCurrentSong(const Song &song, bool wasEmpty)
+void MainWindow::updateCurrentSong(Song song, bool wasEmpty)
{
- current=song;
- if (current.isCdda()) {
+ if (song.isCdda()) {
emit getStatus();
- if (current.isUnknown()) {
+ if (song.isUnknown()) {
Song pqSong=playQueueModel.getSongById(current.id);
if (!pqSong.isEmpty()) {
- current=pqSong;
+ song=pqSong;
}
}
}
- if (current.isCantataStream()) {
- Song mod=HttpServer::self()->decodeUrl(current.file);
+ if (song.isCantataStream()) {
+ Song mod=HttpServer::self()->decodeUrl(song.file);
if (!mod.title.isEmpty()) {
- current=mod;
- current.id=song.id;
+ song=mod;
+ song.id=song.id;
}
}
+ bool diffSong=song.isDifferent(current);
+ current=song;
+
CurrentCover::self()->update(current);
#ifdef QT_QTDBUS_FOUND
mpris->updateCurrentSong(current);
@@ -1692,8 +1804,10 @@
QModelIndex idx=playQueueProxyModel.mapFromSource(playQueueModel.index(playQueueModel.currentSongRow(), 0));
playQueue->updateRows(idx.row(), current.key, autoScrollPlayQueue && playQueueProxyModel.isEmpty() && isPlaying, wasEmpty);
scrollPlayQueue(wasEmpty);
- context->update(current);
- trayItem->songChanged(song, isPlaying);
+ if (diffSong) {
+ context->update(current);
+ trayItem->songChanged(song, isPlaying);
+ }
centerPlayQueueAction->setEnabled(!song.isEmpty());
}
@@ -1780,10 +1894,10 @@
}
playQueueModel.setState(status->state());
+ StdActions::self()->playPauseTrackAction->setEnabled(status->playlistLength()>0);
switch (status->state()) {
case MPDState_Playing:
StdActions::self()->playPauseTrackAction->setIcon(Icons::self()->toolbarPauseIcon);
- StdActions::self()->playPauseTrackAction->setEnabled(0!=status->playlistLength());
enableStopActions(true);
StdActions::self()->nextTrackAction->setEnabled(status->playlistLength()>1);
StdActions::self()->prevTrackAction->setEnabled(status->playlistLength()>1);
@@ -1792,7 +1906,6 @@
case MPDState_Inactive:
case MPDState_Stopped:
StdActions::self()->playPauseTrackAction->setIcon(Icons::self()->toolbarPlayIcon);
- StdActions::self()->playPauseTrackAction->setEnabled(0!=status->playlistLength());
enableStopActions(false);
StdActions::self()->nextTrackAction->setEnabled(false);
StdActions::self()->prevTrackAction->setEnabled(false);
@@ -1807,7 +1920,6 @@
break;
case MPDState_Paused:
StdActions::self()->playPauseTrackAction->setIcon(Icons::self()->toolbarPlayIcon);
- StdActions::self()->playPauseTrackAction->setEnabled(0!=status->playlistLength());
enableStopActions(0!=status->playlistLength());
StdActions::self()->nextTrackAction->setEnabled(status->playlistLength()>1);
StdActions::self()->prevTrackAction->setEnabled(status->playlistLength()>1);
@@ -1828,6 +1940,14 @@
// Update status info
lastState = status->state();
lastSongId = status->songId();
+ #if defined Q_OS_WIN && QT_VERSION>=0x050000
+ if (thumbnailTooolbar) {
+ thumbnailTooolbar->update(status);
+ }
+ #endif
+ #ifdef Q_OS_MAC
+ dockMenu->update(status);
+ #endif
}
void MainWindow::playQueueItemActivated(const QModelIndex &index)
@@ -1838,7 +1958,8 @@
void MainWindow::promptClearPlayQueue()
{
if (Settings::self()->playQueueConfirmClear()) {
- if (QDialogButtonBox::GnomeLayout==style()->styleHint(QStyle::SH_DialogButtonLayout)) {
+ int btnLayout=style()->styleHint(QStyle::SH_DialogButtonLayout);
+ if (QDialogButtonBox::GnomeLayout==btnLayout || QDialogButtonBox::MacLayout==btnLayout) {
messageWidget->setActions(QList() << cancelAction << clearPlayQueueAction);
} else {
messageWidget->setActions(QList() << clearPlayQueueAction << cancelAction);
@@ -1863,7 +1984,8 @@
void MainWindow::centerPlayQueue()
{
- QModelIndex idx=playQueueProxyModel.mapFromSource(playQueueModel.index(playQueueModel.currentSongRow(), 0));
+ QModelIndex idx=playQueueProxyModel.mapFromSource(playQueueModel.index(playQueueModel.currentSongRow(),
+ playQueue->isGrouped() ? 0 : PlayQueueModel::COL_TITLE));
if (idx.isValid()) {
if (playQueue->isGrouped()) {
playQueue->updateRows(idx.row(), current.key, true, true);
@@ -1873,11 +1995,11 @@
}
}
-void MainWindow::addToPlayQueue(bool replace, quint8 priority, bool randomAlbums)
+void MainWindow::addToPlayQueue(bool replace, quint8 priority)
{
playQueueSearchWidget->clear();
if (currentPage) {
- currentPage->addSelectionToPlaylist(QString(), replace, priority, randomAlbums);
+ currentPage->addSelectionToPlaylist(QString(), replace, priority);
}
}
@@ -1928,11 +2050,11 @@
QString name = InputDialog::getText(i18n("Playlist Name"), i18n("Enter a name for the playlist:"), QString(), 0, this);
if (name==StreamsModel::constPlayListName) {
- MessageBox::error(this, i18n("%1 is used to store favorite streams, please choose another name.", name));
+ MessageBox::error(this, i18n("'%1' is used to store favorite streams, please choose another name.", name));
continue;
}
if (PlaylistsModel::self()->exists(name)) {
- switch(MessageBox::warningYesNoCancel(this, i18n("A playlist named %1 already exists! Add to that playlist?", name),
+ switch(MessageBox::warningYesNoCancel(this, i18n("A playlist named '%1' already exists!\n\nAdd to that playlist?", name),
i18n("Existing Playlist"))) {
case MessageBox::Cancel: return;
case MessageBox::Yes: break;
@@ -2037,7 +2159,9 @@
void MainWindow::fullScreen()
{
if (expandInterfaceAction->isChecked()) {
+ #ifndef Q_OS_MAC
fullScreenLabel->setVisible(!isFullScreen());
+ #endif
expandInterfaceAction->setEnabled(isFullScreen());
if (isFullScreen()) {
showNormal();
@@ -2203,11 +2327,6 @@
}
}
-void MainWindow::locateTrack()
-{
- locateTracks(playQueue->selectedSongs());
-}
-
void MainWindow::locateArtist(const QString &artist)
{
if (songInfoAction->isCheckable()) {
@@ -2237,32 +2356,24 @@
#endif
}
+void MainWindow::showPlayQueueSearch()
+{
+ playQueueSearchWidget->activate();
+}
+
void MainWindow::showSearch()
{
- if (playQueue->hasFocus()) {
+ if (!searchPlayQueueAction->isEnabled() && playQueue->hasFocus()) {
playQueueSearchWidget->activate();
} else if (context->isVisible()) {
context->search();
} else if (currentPage && splitter->sizes().at(0)>0) {
currentPage->focusSearch();
- } else if (playQueuePage->isVisible() || playQueue->isVisible()) {
+ } else if (!searchPlayQueueAction->isEnabled() && (playQueuePage->isVisible() || playQueue->isVisible())) {
playQueueSearchWidget->activate();
}
}
-bool MainWindow::canClose()
-{
- #ifdef ENABLE_ONLINE_SERVICES
- if (OnlineServicesModel::self()->isDownloading() &&
- MessageBox::No==MessageBox::warningYesNo(this, i18n("Podcasts are currently being downloaded\n\nQuiting now will abort all downloads."),
- QString(), GuiItem(i18n("Abort downloads and quit")), GuiItem("Do not quit just yet"))) {
- return false;
- }
- OnlineServicesModel::self()->cancelAll();
- #endif
- return true;
-}
-
void MainWindow::expandAll()
{
QWidget *f=QApplication::focusWidget();
@@ -2282,30 +2393,19 @@
void MainWindow::editTags()
{
#ifdef TAGLIB_FOUND
+ if (TagEditor::instanceCount() || !canShowDialog()) {
+ return;
+ }
QList songs;
- if (currentPage==folderPage) {
+ bool isPlayQueue=playQueue->hasFocus();
+ if (isPlayQueue) {
+ songs=playQueue->selectedSongs();
+ } else if (currentPage==folderPage) {
songs=folderPage->selectedSongs(FolderPage::ES_FillEmpty);
} else if (currentPage) {
songs=currentPage->selectedSongs();
}
- editTags(songs, false);
- #endif
-}
-
-void MainWindow::editPlayQueueTags()
-{
- #ifdef TAGLIB_FOUND
- editTags(playQueue->selectedSongs(), true);
- #endif
-}
-
-#ifdef TAGLIB_FOUND
-void MainWindow::editTags(const QList &songs, bool isPlayQueue)
-{
- if (songs.isEmpty() && isPlayQueue) {
- MessageBox::error(this, i18n("Can only edit tags of songs within MPD's music collection."));
- }
- if (songs.isEmpty() || TagEditor::instanceCount() || !canShowDialog()) {
+ if (songs.isEmpty()) {
return;
}
QSet artists, albumArtists, composers, albums, genres;
@@ -2317,15 +2417,13 @@
if (udi.isEmpty()) {
return;
}
- } else
- #else
- Q_UNUSED(isPlayQueue)
+ }
#endif
MusicLibraryModel::self()->getDetails(artists, albumArtists, composers, albums, genres);
TagEditor *dlg=new TagEditor(this, songs, artists, albumArtists, composers, albums, genres, udi);
dlg->show();
+ #endif
}
-#endif
void MainWindow::organiseFiles()
{
@@ -2529,19 +2627,16 @@
int MainWindow::calcMinHeight()
{
- if (tabWidget->style()&FancyTabWidget::Side && tabWidget->style()&FancyTabWidget::Large) {
- return toolbar->height()+(tabWidget->visibleCount()*tabWidget->tabSize().height());
- } else {
- return Utils::scaleForDpi(256);
- }
+ return tabWidget->style()&FancyTabWidget::Side && tabWidget->style()&FancyTabWidget::Large
+ ? toolbar->height()+(tabWidget->visibleCount()*tabWidget->tabSize().height())
+ : Utils::scaleForDpi(256);
}
int MainWindow::calcCollapsedSize()
{
- if (showMenuAction && menuButton && showMenuAction->isChecked()) {
- return toolbar->height()+menuBar()->height();
- }
- return toolbar->height();
+ return showMenuAction && menuButton && showMenuAction->isChecked()
+ ? toolbar->height()+menuBar()->height()
+ : toolbar->height();
}
void MainWindow::setCollapsedSize()
@@ -2638,11 +2733,6 @@
}
}
-#if !defined Q_OS_WIN && !defined Q_OS_MAC && QT_VERSION < 0x050000
-#include
-#include
-#endif
-
void MainWindow::hideWindow()
{
lastPos=pos();
@@ -2652,52 +2742,8 @@
void MainWindow::restoreWindow()
{
bool wasHidden=isHidden();
- #ifdef Q_OS_WIN // FIXME - need on mac?
- raiseWindow(this);
- #endif
- raise();
- showNormal();
- activateWindow();
- #if !defined Q_OS_WIN && !defined Q_OS_MAC
- // This section seems to be required for compiz, so that MPRIS.Raise actually shows the window, and not just highlight launcher.
- #if QT_VERSION < 0x050000
- static const Atom constNetActive=XInternAtom(QX11Info::display(), "_NET_ACTIVE_WINDOW", False);
- QX11Info info;
- XEvent xev;
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.message_type = constNetActive;
- xev.xclient.display = QX11Info::display();
- xev.xclient.window = effectiveWinId();
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = 2;
- xev.xclient.data.l[1] = xev.xclient.data.l[2] = xev.xclient.data.l[3] = xev.xclient.data.l[4] = 0;
- XSendEvent(QX11Info::display(), QX11Info::appRootWindow(info.screen()), False, SubstructureRedirectMask|SubstructureNotifyMask, &xev);
- #else // QT_VERSION < 0x050000
- QString wmctrl=Utils::findExe(QLatin1String("wmctrl"));
- if (!wmctrl.isEmpty()) {
- if (wasHidden) {
- QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
- }
- QProcess::execute(wmctrl, QStringList() << QLatin1String("-i") << QLatin1String("-a") << QString::number(effectiveWinId()));
- }
- #endif // QT_VERSION < 0x050000
- #endif // !defined Q_OS_WIN && !defined Q_OS_MAC
+ Utils::raiseWindow(this);
if (wasHidden && !lastPos.isNull()) {
move(lastPos);
}
- #ifdef ENABLE_KDE_SUPPORT
- KWindowSystem::forceActiveWindow(effectiveWinId());
- #endif
}
-
-#ifdef Q_OS_WIN
-// This is down here, because windows.h includes ALL windows stuff - and we get conflicts with MessageBox :-(
-#include
-static void raiseWindow(QWidget *w)
-{
- ::SetWindowPos(reinterpret_cast(w->effectiveWinId()), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
- ::SetWindowPos(reinterpret_cast(w->effectiveWinId()), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
-}
-#endif
diff -Nru cantata-1.4.2.ds1/gui/mainwindow.h cantata-1.5.2.ds2/gui/mainwindow.h
--- cantata-1.4.2.ds1/gui/mainwindow.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/mainwindow.h 2015-03-23 20:09:42.000000000 +0000
@@ -79,6 +79,12 @@
class MPDStatus;
struct MPDConnectionDetails;
struct Output;
+#if defined Q_OS_WIN && QT_VERSION>=0x050000
+class ThumbnailToolBar;
+#endif
+#ifdef Q_OS_MAC
+class DockMenu;
+#endif
// Dummy classes so that when class name is saved to the config file, we get a more meaningful name than QWidget!!!
class PlayQueuePage : public QWidget
@@ -129,11 +135,13 @@
protected:
void keyPressEvent(QKeyEvent *event);
+ #if defined Q_OS_WIN && QT_VERSION >= 0x050000
+ void showEvent(QShowEvent *event);
+ #endif
void closeEvent(QCloseEvent *event);
private:
void addMenuAction(QMenu *menu, QAction *action);
- void initSizes();
void setupTrayIcon();
Q_SIGNALS:
@@ -179,6 +187,7 @@
void connectToMpd(const MPDConnectionDetails &details);
void streamUrl(const QString &u);
void refreshDbPromp();
+ void fullDbRefresh();
void showServerInfo();
void stopPlayback();
void stopAfterCurrentTrack();
@@ -189,7 +198,7 @@
void realSearchPlayQueue();
void playQueueSearchActivated(bool a);
void updatePlayQueue(const QList &songs);
- void updateCurrentSong(const Song &song, bool wasEmpty=false);
+ void updateCurrentSong(Song song, bool wasEmpty=false);
void scrollPlayQueue(bool wasEmpty=false);
void updateStats();
void updateStatus();
@@ -200,7 +209,6 @@
void removeFromPlayQueue() { playQueueModel.remove(playQueueProxyModel.mapToSourceRows(playQueue->selectedIndexes())); }
void replacePlayQueue() { addToPlayQueue(true); }
void addToPlayQueue() { addToPlayQueue(false); }
- void addRandomToPlayQueue() { addToPlayQueue(false, 0, true); }
void addWithPriority();
void addToNewStoredPlaylist();
void addToExistingStoredPlaylist(const QString &name) { addToExistingStoredPlaylist(name, playQueue->hasFocus()); }
@@ -246,11 +254,10 @@
void toggleSplitterAutoHide();
void toggleMonoIcons();
void locateTracks(const QList &songs);
- void locateTrack();
+ void locateTrack() { locateTracks(playQueue->selectedSongs()); }
void locateArtist(const QString &artist);
void locateAlbum(const QString &artist, const QString &album);
void editTags();
- void editPlayQueueTags();
void organiseFiles();
void addToDevice(const QString &udi);
void deleteSongs();
@@ -258,6 +265,7 @@
void deleteSongs(const QString &from, const QList &songs);
void replayGain();
void setCover();
+ void showPlayQueueSearch();
void showSearch();
void expandAll();
void collapseAll();
@@ -266,6 +274,7 @@
void updateConnectionsMenu();
void controlConnectionsMenu(bool enable=true);
void controlDynamicButton();
+ void setRating();
private:
bool canClose();
@@ -274,10 +283,7 @@
void enableStopActions(bool enable);
void updateStatus(MPDStatus * const status);
void readSettings();
- void addToPlayQueue(bool replace, quint8 priority=0, bool randomAlbums=false);
- #ifdef TAGLIB_FOUND
- void editTags(const QList &songs, bool isPlayQueue);
- #endif
+ void addToPlayQueue(bool replace, quint8 priority=0);
bool currentIsStream() const { return playQueueModel.rowCount() && -1!=current.id && current.isStream(); }
void updateWindowTitle();
void showTab(int page) { tabWidget->setCurrentIndex(page); }
@@ -310,6 +316,7 @@
Action *prefAction;
Action *refreshDbAction;
Action *doDbRefreshAction;
+ Action *dbFullRefreshAction;
Action *connectAction;
Action *connectionsAction;
Action *outputsAction;
@@ -346,6 +353,9 @@
Action *clearPlayQueueAction;
Action *cancelAction;
Action *clearNewStateAction;
+ Action *ratingAction;
+ Action *fwdAction;
+ Action *revAction;
TrayItem *trayItem;
QPoint lastPos;
QSize expandedSize;
@@ -392,6 +402,12 @@
int contextSwitchTime;
enum { CS_Init, CS_Connected, CS_Disconnected } connectedState;
bool stopAfterCurrent;
+ #if defined Q_OS_WIN && QT_VERSION>=0x050000
+ ThumbnailToolBar *thumbnailTooolbar;
+ #endif
+ #ifdef Q_OS_MAC
+ DockMenu *dockMenu;
+ #endif
friend class TrayItem;
};
diff -Nru cantata-1.4.2.ds1/gui/mainwindow.ui cantata-1.5.2.ds2/gui/mainwindow.ui
--- cantata-1.4.2.ds1/gui/mainwindow.ui 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/mainwindow.ui 2015-03-23 20:09:42.000000000 +0000
@@ -193,7 +193,7 @@
6
- 21
+ 2
@@ -212,6 +212,16 @@
-
+
+
+ true
+
+
+ false
+
+
+
+ -
true
diff -Nru cantata-1.4.2.ds1/gui/mediakeys.cpp cantata-1.5.2.ds2/gui/mediakeys.cpp
--- cantata-1.4.2.ds1/gui/mediakeys.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/mediakeys.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -30,47 +30,16 @@
#endif
#include "multimediakeysinterface.h"
#include "stdactions.h"
-#include "settings.h"
#include "support/globalstatic.h"
-
-GLOBAL_STATIC(MediaKeys, instance)
-
-QString MediaKeys::toString(InterfaceType i)
+#include
+static bool debugIsEnabled=false;
+#define DBUG if (debugIsEnabled) qWarning() << "MediaKeys" << __FUNCTION__
+void MediaKeys::enableDebug()
{
- switch (i) {
- case NoInterface:
- default:
- return QString();
- case GnomeInteface:
- return "gnome";
- case QxtInterface:
- return "qxt";
- }
+ debugIsEnabled=true;
}
-MediaKeys::InterfaceType MediaKeys::toIface(const QString &i)
-{
- #if defined Q_OS_MAC
- return NoInterface;
- #endif
-
- if (i==toString(GnomeInteface)) {
- #ifdef QT_QTDBUS_FOUND
- return GnomeInteface;
- #else
- return NoInterface;
- #endif
- }
-
- if (i==toString(QxtInterface)) {
- #if QT_VERSION < 0x050000
- return QxtInterface;
- #else
- return NoInterface;
- #endif
- }
- return NoInterface;
-}
+GLOBAL_STATIC(MediaKeys, instance)
MediaKeys::MediaKeys()
{
@@ -97,66 +66,37 @@
#endif
}
-void MediaKeys::load()
+void MediaKeys::start()
{
- InterfaceType current=NoInterface;
- InterfaceType configured=toIface(Settings::self()->mediaKeysIface());
#ifdef QT_QTDBUS_FOUND
- if (gnome && gnome->isEnabled()) {
- current=GnomeInteface;
- }
- #endif
-
- #ifdef CANTATA_USE_QXT_MEDIAKEYS
- if (qxt && qxt->isEnabled()) {
- current=QxtInterface;
- }
- #endif
-
- if (current==configured) {
+ gnome=new GnomeMediaKeys(0);
+ if (activate(gnome)) {
+ DBUG << "Using Gnome";
return;
}
-
- #ifdef QT_QTDBUS_FOUND
- if (gnome && GnomeInteface==current) {
- disable(gnome);
- gnome->deleteLater();
- gnome=0;
- }
- #endif
-
- #ifdef CANTATA_USE_QXT_MEDIAKEYS
- if (qxt && QxtInterface==current) {
- disable(qxt);
- qxt->deleteLater();
- qxt=0;
- }
- #endif
-
- #ifdef QT_QTDBUS_FOUND
- if (GnomeInteface==configured) {
- if (!gnome) {
- gnome=new GnomeMediaKeys(0);
- }
- enable(gnome);
- }
+ DBUG << "Gnome failed";
+ gnome->deleteLater();
+ gnome=0;
#endif
#ifdef CANTATA_USE_QXT_MEDIAKEYS
- if (QxtInterface==configured) {
- if (!qxt) {
- qxt=new QxtMediaKeys(0);
- }
- enable(qxt);
+ qxt=new QxtMediaKeys(0);
+ if (activate(qxt)) {
+ DBUG << "Using Qxt";
+ return;
}
+ DBUG << "Qxt failed";
+ qxt->deleteLater();
+ qxt=0;
#endif
+ DBUG << "None";
}
void MediaKeys::stop()
{
#ifdef QT_QTDBUS_FOUND
if (gnome) {
- disable(gnome);
+ deactivate(gnome);
gnome->deleteLater();
gnome=0;
}
@@ -164,34 +104,36 @@
#ifdef CANTATA_USE_QXT_MEDIAKEYS
if (qxt) {
- disable(qxt);
+ deactivate(qxt);
qxt->deleteLater();
qxt=0;
}
#endif
}
-void MediaKeys::enable(MultiMediaKeysInterface *iface)
+bool MediaKeys::activate(MultiMediaKeysInterface *iface)
{
- if (!iface || iface->isEnabled()) {
- return;
+ if (!iface) {
+ return false;
}
- QObject::connect(iface, SIGNAL(playPause()), StdActions::self()->playPauseTrackAction, SIGNAL(triggered()));
- QObject::connect(iface, SIGNAL(stop()), StdActions::self()->stopPlaybackAction, SIGNAL(triggered()));
- QObject::connect(iface, SIGNAL(next()), StdActions::self()->nextTrackAction, SIGNAL(triggered()));
- QObject::connect(iface, SIGNAL(previous()), StdActions::self()->prevTrackAction, SIGNAL(triggered()));
- iface->setEnabled(true);
+ if (iface->activate()) {
+ QObject::connect(iface, SIGNAL(playPause()), StdActions::self()->playPauseTrackAction, SIGNAL(triggered()));
+ QObject::connect(iface, SIGNAL(stop()), StdActions::self()->stopPlaybackAction, SIGNAL(triggered()));
+ QObject::connect(iface, SIGNAL(next()), StdActions::self()->nextTrackAction, SIGNAL(triggered()));
+ QObject::connect(iface, SIGNAL(previous()), StdActions::self()->prevTrackAction, SIGNAL(triggered()));
+ return true;
+ }
+ return false;
}
-void MediaKeys::disable(MultiMediaKeysInterface *iface)
+void MediaKeys::deactivate(MultiMediaKeysInterface *iface)
{
- if (!iface || !iface->isEnabled()) {
+ if (!iface) {
return;
}
QObject::disconnect(iface, SIGNAL(playPause()), StdActions::self()->playPauseTrackAction, SIGNAL(triggered()));
QObject::disconnect(iface, SIGNAL(stop()), StdActions::self()->stopPlaybackAction, SIGNAL(triggered()));
QObject::disconnect(iface, SIGNAL(next()), StdActions::self()->nextTrackAction, SIGNAL(triggered()));
QObject::disconnect(iface, SIGNAL(previous()), StdActions::self()->prevTrackAction, SIGNAL(triggered()));
- iface->setEnabled(false);
+ iface->deactivate();
}
-
diff -Nru cantata-1.4.2.ds1/gui/mediakeys.h cantata-1.5.2.ds2/gui/mediakeys.h
--- cantata-1.4.2.ds1/gui/mediakeys.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/mediakeys.h 2015-03-23 20:09:42.000000000 +0000
@@ -38,25 +38,18 @@
class MediaKeys
{
public:
- enum InterfaceType {
- NoInterface,
- GnomeInteface,
- QxtInterface
- };
-
+ static void enableDebug();
static MediaKeys * self();
- static QString toString(InterfaceType i);
- static InterfaceType toIface(const QString &i);
MediaKeys();
~MediaKeys();
- void load();
+ void start();
void stop();
private:
- void enable(MultiMediaKeysInterface *iface);
- void disable(MultiMediaKeysInterface *iface);
+ bool activate(MultiMediaKeysInterface *iface);
+ void deactivate(MultiMediaKeysInterface *iface);
private:
#ifdef QT_QTDBUS_FOUND
diff -Nru cantata-1.4.2.ds1/gui/multimediakeysinterface.h cantata-1.5.2.ds2/gui/multimediakeysinterface.h
--- cantata-1.4.2.ds1/gui/multimediakeysinterface.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/multimediakeysinterface.h 2015-03-23 20:09:42.000000000 +0000
@@ -30,23 +30,17 @@
{
Q_OBJECT
public:
- MultiMediaKeysInterface(QObject *p) : QObject(p), enabled(false) { }
+ MultiMediaKeysInterface(QObject *p) : QObject(p) { }
~MultiMediaKeysInterface() { }
- void setEnabled(bool e) { activate(e); enabled=e; }
- bool isEnabled() const { return enabled; }
-
-private:
- virtual void activate(bool a)=0;
+ virtual bool activate()=0;
+ virtual void deactivate()=0;
Q_SIGNALS:
void playPause();
void stop();
void next();
void previous();
-
-protected:
- bool enabled;
};
#endif
diff -Nru cantata-1.4.2.ds1/gui/page.h cantata-1.5.2.ds2/gui/page.h
--- cantata-1.4.2.ds1/gui/page.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/page.h 2015-03-23 20:09:42.000000000 +0000
@@ -33,8 +33,8 @@
virtual ~Page() { }
virtual Song coverRequest() const { return Song(); }
virtual QList selectedSongs(bool allowPlaylists=false) const { Q_UNUSED(allowPlaylists) return QList(); }
- virtual void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0, bool randomAlbums=false) {
- Q_UNUSED(name) Q_UNUSED(replace) Q_UNUSED(priorty) Q_UNUSED(randomAlbums)
+ virtual void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0) {
+ Q_UNUSED(name) Q_UNUSED(replace) Q_UNUSED(priorty)
}
#ifdef ENABLE_DEVICES_SUPPORT
virtual void addSelectionToDevice(const QString &udi) { Q_UNUSED(udi) }
diff -Nru cantata-1.4.2.ds1/gui/playbacksettings.cpp cantata-1.5.2.ds2/gui/playbacksettings.cpp
--- cantata-1.4.2.ds1/gui/playbacksettings.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/playbacksettings.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -24,6 +24,7 @@
#include "playbacksettings.h"
#include "settings.h"
#include "support/localize.h"
+#include "support/utils.h"
#include "mpd/mpdconnection.h"
#include "support/icon.h"
#include "widgets/basicitemdelegate.h"
@@ -56,22 +57,26 @@
connect(this, SIGNAL(setCrossFade(int)), MPDConnection::self(), SLOT(setCrossFade(int)));
connect(this, SIGNAL(getReplayGain()), MPDConnection::self(), SLOT(getReplayGain()));
connect(aboutReplayGain, SIGNAL(leftClickedUrl()), SLOT(showAboutReplayGain()));
- int iconSize=Icon::dlgIconSize();
+ int iconSize=Utils::limitedHeight(this) ? 32 : Icon::dlgIconSize();
messageIcon->setMinimumSize(iconSize, iconSize);
messageIcon->setMaximumSize(iconSize, iconSize);
mpdConnectionStateChanged(MPDConnection::self()->isConnected());
- #if defined Q_OS_WIN || defined Q_OS_MAC
+ #if defined Q_OS_WIN || (defined Q_OS_MAC && !defined IOKIT_FOUND)
REMOVE(inhibitSuspend)
#endif
outputsView->setVisible(outputsView->count()>1);
outputsViewLabel->setVisible(outputsView->count()>1);
+
+ #ifdef Q_OS_MAC
+ expandingSpacer->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
+ #endif
}
void PlaybackSettings::load()
{
stopOnExit->setChecked(Settings::self()->stopOnExit());
stopFadeDuration->setValue(Settings::self()->stopFadeDuration());
- #if !defined Q_OS_WIN && !defined Q_OS_MAC
+ #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND)
inhibitSuspend->setChecked(Settings::self()->inhibitSuspend());
#endif
@@ -85,8 +90,7 @@
void PlaybackSettings::save()
{
Settings::self()->saveStopOnExit(stopOnExit->isChecked());
- Settings::self()->saveStopFadeDuration(stopFadeDuration->value());
- #if !defined Q_OS_WIN && !defined Q_OS_MAC
+ #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND)
Settings::self()->saveInhibitSuspend(inhibitSuspend->isChecked());
#endif
@@ -167,13 +171,13 @@
void PlaybackSettings::showAboutReplayGain()
{
- MessageBox::information(this, i18n("Replay Gain is a proposed standard published in 2001 to normalize the perceived loudness of computer "
+ MessageBox::information(this, i18n("Replay Gain is a proposed standard published in 2001 to normalize the perceived loudness of computer "
"audio formats such as MP3 and Ogg Vorbis. It works on a track/album basis, and is now supported in a "
- "growing number of players.
"
- "The following ReplayGain settings may be used:
"
+ "growing number of players."
+ " The following ReplayGain settings may be used:"
"None - No ReplayGain is applied. "
"Track - Volume will be adjusted using the track's ReplayGain tags. "
"Album - Volume will be adjusted using the albums's ReplayGain tags. "
"Auto - Volume will be adjusted using the track's ReplayGain tags if random play is activated, otherwise the album's tags will be used. "
- " "));
+ " "));
}
diff -Nru cantata-1.4.2.ds1/gui/playbacksettings.ui cantata-1.5.2.ds2/gui/playbacksettings.ui
--- cantata-1.4.2.ds1/gui/playbacksettings.ui 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/playbacksettings.ui 2015-03-23 20:09:42.000000000 +0000
@@ -66,32 +66,10 @@
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 13
-
-
-
-
- -
-
+ -
+
- <i><b>NOTE:</b> If you press and hold the stop button, then a menu will be shown allowing you to choose whether to stop playback now, or after the current track.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ If you press and hold the stop button, then a menu will be shown allowing you to choose whether to stop playback now, or after the current track. (The stop button can be enabled in the Interface/Toolbar section)
@@ -229,14 +207,14 @@
-
-
+
Qt::Vertical
20
- 2
+ 0
@@ -250,6 +228,11 @@
+ NoteLabel
+ QLabel
+
+
+
UrlLabel
QWidget
diff -Nru cantata-1.4.2.ds1/gui/playlistspage.cpp cantata-1.5.2.ds2/gui/playlistspage.cpp
--- cantata-1.4.2.ds1/gui/playlistspage.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/playlistspage.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -95,9 +95,9 @@
connect(this, SIGNAL(savePlaylist(const QString &)), MPDConnection::self(), SLOT(savePlaylist(const QString &)));
connect(this, SIGNAL(renamePlaylist(const QString &, const QString &)), MPDConnection::self(), SLOT(renamePlaylist(const QString &, const QString &)));
connect(this, SIGNAL(removeFromPlaylist(const QString &, const QList &)), MPDConnection::self(), SLOT(removeFromPlaylist(const QString &, const QList &)));
- connect(StdActions::self()->savePlayQueueAction, SIGNAL(triggered(bool)), this, SLOT(savePlaylist()));
- connect(renamePlaylistAction, SIGNAL(triggered(bool)), this, SLOT(renamePlaylist()));
- connect(removeDuplicatesAction, SIGNAL(triggered(bool)), this, SLOT(removeDuplicates()));
+ connect(StdActions::self()->savePlayQueueAction, SIGNAL(triggered()), this, SLOT(savePlaylist()));
+ connect(renamePlaylistAction, SIGNAL(triggered()), this, SLOT(renamePlaylist()));
+ connect(removeDuplicatesAction, SIGNAL(triggered()), this, SLOT(removeDuplicates()));
connect(PlaylistsModel::self(), SIGNAL(updated(const QModelIndex &)), this, SLOT(updated(const QModelIndex &)));
connect(PlaylistsModel::self(), SIGNAL(playlistRemoved(quint32)), view, SLOT(collectionRemoved(quint32)));
QMenu *menu=new QMenu(this);
@@ -169,9 +169,8 @@
// return PlaylistsModel::self()->filenames(mapped, true);
//}
-void PlaylistsPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty, bool randomAlbums)
+void PlaylistsPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty)
{
- Q_UNUSED(randomAlbums)
addItemsToPlayList(view->selectedIndexes(), name, replace, priorty);
}
@@ -222,7 +221,7 @@
}
if (remPlaylists.count() &&
- MessageBox::No==MessageBox::warningYesNo(this, i18n("Are you sure you wish to remove the selected playlists?\nThis cannot be undone."),
+ MessageBox::No==MessageBox::warningYesNo(this, i18n("Are you sure you wish to remove the selected playlists?\n\nThis cannot be undone."),
i18n("Remove Playlists"), StdGuiItem::remove(), StdGuiItem::cancel())) {
return;
}
@@ -243,7 +242,7 @@
if (!name.isEmpty()) {
if (PlaylistsModel::self()->exists(name)) {
- if (MessageBox::No==MessageBox::warningYesNo(this, i18n("A playlist named %1 already exists! Overwrite?", name),
+ if (MessageBox::No==MessageBox::warningYesNo(this, i18n("A playlist named '%1' already exists!\n\nOverwrite?", name),
i18n("Overwrite Playlist"), StdGuiItem::overwrite(), StdGuiItem::cancel())) {
return;
}
@@ -270,7 +269,7 @@
if (!newName.isEmpty() && name!=newName) {
if (PlaylistsModel::self()->exists(newName)) {
- if (MessageBox::No==MessageBox::warningYesNo(this, i18n("A playlist named %1 already exists! Overwrite?", newName),
+ if (MessageBox::No==MessageBox::warningYesNo(this, i18n("A playlist named '%1' already exists!\n\nOverwrite?", newName),
i18n("Overwrite Playlist"), StdGuiItem::overwrite(), StdGuiItem::cancel())) {
return;
}
diff -Nru cantata-1.4.2.ds1/gui/playlistspage.h cantata-1.5.2.ds2/gui/playlistspage.h
--- cantata-1.4.2.ds1/gui/playlistspage.h 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/playlistspage.h 2015-03-23 20:09:42.000000000 +0000
@@ -44,7 +44,7 @@
void refresh();
void clear();
//QStringList selectedFiles() const;
- void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0, bool randomAlbums=false);
+ void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0);
void setView(int mode);
void focusSearch() { view->focusSearch(); }
#ifdef ENABLE_DEVICES_SUPPORT
diff -Nru cantata-1.4.2.ds1/gui/preferencesdialog.cpp cantata-1.5.2.ds2/gui/preferencesdialog.cpp
--- cantata-1.4.2.ds1/gui/preferencesdialog.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/preferencesdialog.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -54,6 +54,8 @@
#include "shortcutssettingspage.h"
#endif
#include "scrobbling/scrobblingsettings.h"
+#include
+#include
static int iCount=0;
@@ -63,12 +65,9 @@
}
PreferencesDialog::PreferencesDialog(QWidget *parent)
- : Dialog(parent, "PreferencesDialog")
+ : ConfigDialog(parent, "PreferencesDialog")
{
iCount++;
- setButtons(Ok|Apply|Cancel);
-
- pageWidget = new PageWidget(this);
server = new ServerSettings(0);
playback = new PlaybackSettings(0);
files = new FileSettings(0);
@@ -82,22 +81,22 @@
interface->load();
context->load();
scrobbling->load();
- pages.insert(QLatin1String("collection"), pageWidget->addPage(server, i18n("Collection"), Icons::self()->audioFileIcon, i18n("Collection Settings")));
- pageWidget->addPage(playback, i18n("Playback"), Icon("media-playback-start"), i18n("Playback Settings"));
- pageWidget->addPage(files, i18n("Files"), Icons::self()->filesIcon, i18n("File Settings"));
- pages.insert(QLatin1String("interface"), pageWidget->addPage(interface, i18n("Interface"), Icon("preferences-other"), i18n("Interface Settings")));
+ addPage(QLatin1String("collection"), server, i18n("Collection"), Icons::self()->audioFileIcon, i18n("Collection Settings"));
+ addPage(QLatin1String("playback"), playback, i18n("Playback"), Icon("media-playback-start"), i18n("Playback Settings"));
+ addPage(QLatin1String("files"), files, i18n("Files"), Icons::self()->filesIcon, i18n("File Settings"));
+ addPage(QLatin1String("interface"), interface, i18n("Interface"), Icon("preferences-other"), i18n("Interface Settings"));
#ifdef ENABLE_STREAMS
streams = new StreamsSettings(0);
- pages.insert(QLatin1String("streams"), pageWidget->addPage(streams, i18n("Streams"), Icons::self()->radioStreamIcon, i18n("Streams Settings")));
+ addPage(QLatin1String("streams"), streams, i18n("Streams"), Icons::self()->radioStreamIcon, i18n("Streams Settings"));
streams->load();
#endif
#ifdef ENABLE_ONLINE_SERVICES
online = new OnlineSettings(0);
- pages.insert(QLatin1String("online"), pageWidget->addPage(online, i18n("Online"), Icon("applications-internet"), i18n("Online Providers")));
+ addPage(QLatin1String("online"), online, i18n("Online"), Icon("applications-internet"), i18n("Online Providers"));
online->load();
#endif
- pageWidget->addPage(context, i18n("Context"), Icons::self()->contextIcon, i18n("Context View Settings"));
- pages.insert(QLatin1String("scrobbling"), pageWidget->addPage(scrobbling, i18n("Scrobbling"), Icons::self()->lastFmIcon, i18n("Scrobbling Settings")));
+ addPage(QLatin1String("context"), context, i18n("Context"), Icons::self()->contextIcon, i18n("Context View Settings"));
+ addPage(QLatin1String("scrobbling"), scrobbling, i18n("Scrobbling"), Icons::self()->lastFmIcon, i18n("Scrobbling Settings"));
#ifdef ENABLE_HTTP_SERVER
http = new HttpServerSettings(0);
if (http->haveMultipleInterfaces()) {
@@ -106,7 +105,7 @@
if (icon.isNull()) {
icon=Icons::self()->streamIcon;
}
- pageWidget->addPage(http, i18n("HTTP Server"), icon, i18n("HTTP Server Settings"));
+ addPage(QLatin1String("http"), http, i18n("HTTP Server"), icon, i18n("HTTP Server Settings"));
} else {
http->deleteLater();
http=0;
@@ -115,26 +114,27 @@
#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND
audiocd = new AudioCdSettings(0);
audiocd->load();
- pageWidget->addPage(audiocd, i18n("Audio CD"), Icon("media-optical"), i18n("Audio CD Settings"));
+ addPage(QLatin1String("cd"), audiocd, i18n("Audio CD"), Icon("media-optical"), i18n("Audio CD Settings"));
#endif
#ifdef ENABLE_PROXY_CONFIG
proxy = new ProxySettings(0);
proxy->load();
- pageWidget->addPage(proxy, i18n("Proxy"), Icon("preferences-system-network"), i18nc("Qt-only", "Proxy Settings"));
+ addPage(QLatin1String("proxy"), proxy, i18n("Proxy"), Icon("preferences-system-network"), i18nc("Qt-only", "Proxy Settings"));
#endif
#ifndef ENABLE_KDE_SUPPORT
- shortcuts = new ShortcutsSettingsPage(pageWidget);
- pageWidget->addPage(shortcuts, i18nc("Qt-only", "Shortcuts"), Icons::self()->shortcutsIcon, i18nc("Qt-only", "Keyboard Shortcut Settings"));
+ shortcuts = new ShortcutsSettingsPage(0);
+ addPage(QLatin1String("shortcuts"), shortcuts, i18nc("Qt-only", "Shortcuts"), Icons::self()->shortcutsIcon, i18nc("Qt-only", "Keyboard Shortcut Settings"));
shortcuts->load();
#endif
- pageWidget->addPage(cache, i18n("Cache"), Icons::self()->folderIcon, i18n("Cached Items"));
+ addPage(QLatin1String("cache"), cache, i18n("Cache"), Icons::self()->folderIcon, i18n("Cached Items"));
+ #ifdef Q_OS_MAC
+ setCaption(i18n("Cantata Preferences"));
+ #else
setCaption(i18n("Configure"));
- setMainWidget(pageWidget);
+ #endif
setAttribute(Qt::WA_DeleteOnClose);
- int h=sizeHint().height();
- setMinimumHeight(h);
- setMinimumWidth(h*1.1);
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ setCurrentPage(QLatin1String("collection"));
}
PreferencesDialog::~PreferencesDialog()
@@ -145,12 +145,15 @@
void PreferencesDialog::showPage(const QString &page)
{
QStringList parts=page.split(QLatin1Char(':'));
- if (pages.contains(parts.at(0))) {
- pageWidget->setCurrentPage(pages[parts.at(0)]);
- if (parts.count()>1 && qobject_cast(pages[parts.at(0)]->widget())) {
- static_cast(pages[parts.at(0)]->widget())->showPage(parts.at(1));
+ if (setCurrentPage(parts.at(0))) {
+ if (parts.count()>1) {
+ QWidget *cur=getPage(parts.at(0));
+ if (qobject_cast(cur)) {
+ static_cast(cur)->showPage(parts.at(1));
+ }
}
}
+ Utils::raiseWindow(this);
}
void PreferencesDialog::writeSettings()
@@ -186,26 +189,12 @@
emit settingsSaved();
}
-void PreferencesDialog::slotButtonClicked(int button)
+void PreferencesDialog::save()
{
- switch (button) {
- case Ok:
- case Apply:
- writeSettings();
- break;
- case Cancel:
- server->cancel();
- reject();
- // Need to call this - if not, when dialog is closed by window X control, it is not deleted!!!!
- Dialog::slotButtonClicked(button);
- break;
- default:
- break;
- }
-
- if (Ok==button) {
- accept();
- }
+ writeSettings();
+}
- Dialog::slotButtonClicked(button);
+void PreferencesDialog::cancel()
+{
+ server->cancel();
}
diff -Nru cantata-1.4.2.ds1/gui/preferencesdialog.h cantata-1.5.2.ds2/gui/preferencesdialog.h
--- cantata-1.4.2.ds1/gui/preferencesdialog.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/preferencesdialog.h 2015-03-23 20:09:42.000000000 +0000
@@ -25,8 +25,7 @@
#define PREFERENCES_DIALOG_H
#include "config.h"
-#include "support/dialog.h"
-#include "support/pagewidget.h"
+#include "support/configdialog.h"
#ifndef ENABLE_KDE_SUPPORT
class ProxySettings;
@@ -56,7 +55,7 @@
#endif
class ScrobblingSettings;
-class PreferencesDialog : public Dialog
+class PreferencesDialog : public ConfigDialog
{
Q_OBJECT
@@ -67,7 +66,8 @@
virtual ~PreferencesDialog();
private:
- void slotButtonClicked(int button);
+ void save();
+ void cancel();
public Q_SLOTS:
void showPage(const QString &page);
@@ -79,7 +79,6 @@
void settingsSaved();
private:
- PageWidget *pageWidget;
ServerSettings *server;
PlaybackSettings *playback;
FileSettings *files;
@@ -105,7 +104,6 @@
AudioCdSettings *audiocd;
#endif
ScrobblingSettings *scrobbling;
- QMap pages;
};
#endif
diff -Nru cantata-1.4.2.ds1/gui/qxtmediakeys.cpp cantata-1.5.2.ds2/gui/qxtmediakeys.cpp
--- cantata-1.4.2.ds1/gui/qxtmediakeys.cpp 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/qxtmediakeys.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -29,13 +29,15 @@
{
}
-void QxtMediaKeys::activate(bool a)
+bool QxtMediaKeys::activate()
{
- if (a) {
- createShortcuts();
- } else {
- clear();
- }
+ createShortcuts();
+ return true; // Hmm... How to detect if this failed?
+}
+
+void QxtMediaKeys::deactivate()
+{
+ clear();
}
void QxtMediaKeys::createShortcuts()
@@ -64,3 +66,4 @@
shortcuts.clear();
}
}
+
diff -Nru cantata-1.4.2.ds1/gui/qxtmediakeys.h cantata-1.5.2.ds2/gui/qxtmediakeys.h
--- cantata-1.4.2.ds1/gui/qxtmediakeys.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/qxtmediakeys.h 2015-03-23 20:09:42.000000000 +0000
@@ -35,7 +35,8 @@
QxtMediaKeys(QObject *p);
virtual ~QxtMediaKeys() { clear(); }
- void activate(bool a);
+ bool activate();
+ void deactivate();
private:
void createShortcuts();
diff -Nru cantata-1.4.2.ds1/gui/searchpage.cpp cantata-1.5.2.ds2/gui/searchpage.cpp
--- cantata-1.4.2.ds1/gui/searchpage.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/searchpage.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -75,7 +75,7 @@
connect(view, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(itemDoubleClicked(const QModelIndex &)));
connect(view, SIGNAL(searchItems()), this, SLOT(searchItems()));
connect(MPDConnection::self(), SIGNAL(stateChanged(bool)), this, SLOT(setSearchCategories()));
- connect(locateAction, SIGNAL(triggered(bool)), SLOT(locateSongs()));
+ connect(locateAction, SIGNAL(triggered()), SLOT(locateSongs()));
proxy.setSourceModel(&model);
view->setModel(&proxy);
view->setMode(ItemView::Mode_List);
@@ -150,9 +150,8 @@
return model.songs(mapped, allowPlaylists);
}
-void SearchPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty, bool randomAlbums)
+void SearchPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty)
{
- Q_UNUSED(randomAlbums)
QStringList files=selectedFiles(true);
if (!files.isEmpty()) {
@@ -206,7 +205,6 @@
StdActions::self()->addWithPriorityAction->setEnabled(enable);
StdActions::self()->replacePlayQueueAction->setEnabled(enable);
StdActions::self()->addToStoredPlaylistAction->setEnabled(enable);
- StdActions::self()->addRandomToPlayQueueAction->setEnabled(false);
locateAction->setEnabled(enable);
}
@@ -214,7 +212,8 @@
{
int newState=(MPDConnection::self()->composerTagSupported() ? State_ComposerSupported : 0)|
(MPDConnection::self()->commentTagSupported() ? State_CommmentSupported : 0)|
- (MPDConnection::self()->performerTagSupported() ? State_PerformerSupported : 0);;
+ (MPDConnection::self()->performerTagSupported() ? State_PerformerSupported : 0)|
+ (MPDConnection::self()->modifiedFindSupported() ? State_ModifiedSupported : 0);
if (state==newState) {
// No changes to be made!
@@ -238,8 +237,11 @@
if (state&State_CommmentSupported) {
categories << QPair(i18n("Comment:"), QLatin1String("comment"));
}
- categories << QPair(i18n("Date:"), QLatin1String("date"))
- << QPair(i18n("File:"), QLatin1String("file"))
+ categories << QPair(i18n("Date:"), QLatin1String("date"));
+ if (state&State_ModifiedSupported) {
+ categories << QPair(i18n("Modified:"), MPDConnection::constModifiedSince);
+ }
+ categories << QPair(i18n("File:"), QLatin1String("file"))
<< QPair(i18n("Any:"), QLatin1String("any"));
view->setSearchCategories(categories);
}
diff -Nru cantata-1.4.2.ds1/gui/searchpage.h cantata-1.5.2.ds2/gui/searchpage.h
--- cantata-1.4.2.ds1/gui/searchpage.h 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/searchpage.h 2015-03-23 20:09:42.000000000 +0000
@@ -45,7 +45,7 @@
void setView(int mode);
QStringList selectedFiles(bool allowPlaylists=false) const;
QList selectedSongs(bool allowPlaylists=false) const;
- void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0, bool randomAlbums=false);
+ void addSelectionToPlaylist(const QString &name=QString(), bool replace=false, quint8 priorty=0);
#ifdef ENABLE_DEVICES_SUPPORT
void addSelectionToDevice(const QString &udi);
#endif
@@ -70,9 +70,10 @@
private:
enum State
{
- State_ComposerSupported=0x01,
- State_CommmentSupported=0x02,
- State_PerformerSupported=0x04
+ State_ComposerSupported = 0x01,
+ State_CommmentSupported = 0x02,
+ State_PerformerSupported = 0x04,
+ State_ModifiedSupported = 0x08
};
int state;
diff -Nru cantata-1.4.2.ds1/gui/searchpage.ui cantata-1.5.2.ds2/gui/searchpage.ui
--- cantata-1.4.2.ds1/gui/searchpage.ui 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/searchpage.ui 2015-03-23 20:09:42.000000000 +0000
@@ -29,6 +29,22 @@
0
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 2
+ 2
+
+
+
+
+ -
-
diff -Nru cantata-1.4.2.ds1/gui/serversettings.cpp cantata-1.5.2.ds2/gui/serversettings.cpp
--- cantata-1.4.2.ds1/gui/serversettings.cpp 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/serversettings.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -83,9 +83,8 @@
{
setupUi(this);
#if defined ENABLE_DEVICES_SUPPORT
- musicFolderNoteLabel->setText(musicFolderNoteLabel->text()+
- i18n("
This folder will also be used to locate music files "
- "for transferring to (and from) devices. "));
+ musicFolderNoteLabel->appendText(i18n(" This folder will also be used to locate music files "
+ "for transferring to (and from) devices. "));
#endif
connect(combo, SIGNAL(activated(int)), SLOT(showDetails(int)));
connect(removeButton, SIGNAL(clicked(bool)), SLOT(remove()));
@@ -112,6 +111,10 @@
REMOVE(streamUrl)
REMOVE(streamUrlNoteLabel)
#endif
+
+ #ifdef Q_OS_MAC
+ expandingSpacer->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
+ #endif
}
void ServerSettings::load()
@@ -230,10 +233,12 @@
bool addStandard=true;
if (!haveBasicCollection && MPDUser::self()->isSupported()) {
+ static const QChar constBullet(0x2022);
+
switch (MessageBox::questionYesNoCancel(this,
- i18n("Which type of collection do you wish to connect to?"
- "Standard - music collection may be shared, is on another machine, or is already setup "
- "Basic - music collection is not shared with others, and Cantata will configure and control the MPD instance "),
+ i18n("Which type of collection do you wish to connect to?")+QLatin1String("\n\n")+
+ constBullet+QLatin1Char(' ')+i18n("Standard - music collection may be shared, is on another machine, or is already setup")+QLatin1Char('\n')+
+ constBullet+QLatin1Char(' ')+i18n("Basic - music collection is not shared with others, and Cantata will configure and control the MPD instance"),
i18n("Add Collection"), GuiItem(i18n("Standard")), GuiItem(i18n("Basic")))) {
case MessageBox::Yes: addStandard=true; break;
case MessageBox::No: addStandard=false; break;
@@ -275,7 +280,7 @@
{
int index=combo->currentIndex();
QString cName=1==stackedWidget->currentIndex() ? MPDUser::translatedName() : name->text();
- if (combo->count()>1 && MessageBox::Yes==MessageBox::questionYesNo(this, i18n("Delete %1 ?", cName),
+ if (combo->count()>1 && MessageBox::Yes==MessageBox::questionYesNo(this, i18n("Delete '%1'?", cName),
i18n("Delete"), StdGuiItem::del(), StdGuiItem::cancel())) {
bool isLast=index==(combo->count()-1);
combo->removeItem(index);
@@ -326,7 +331,7 @@
void ServerSettings::setDetails(const MPDConnectionDetails &details)
{
if (details.name==MPDUser::constName) {
- basicDir->setText(Utils::convertDirForDisplay(details.dir));
+ basicDir->setText(Utils::convertPathForDisplay(details.dir));
basicCoverName->setText(details.coverName);
stackedWidget->setCurrentIndex(1);
} else {
@@ -334,7 +339,7 @@
host->setText(details.hostname);
port->setValue(details.port);
password->setText(details.password);
- dir->setText(Utils::convertDirForDisplay(details.dir));
+ dir->setText(Utils::convertPathForDisplay(details.dir));
coverName->setText(details.coverName);
#ifdef ENABLE_HTTP_STREAM_PLAYBACK
streamUrl->setText(details.streamUrl);
@@ -354,14 +359,14 @@
details.hostname=host->text().trimmed();
details.port=port->value();
details.password=password->text();
- details.dir=Utils::convertDirFromDisplay(dir->text());
+ details.dir=Utils::convertPathFromDisplay(dir->text());
details.coverName=coverName->text().trimmed();
#ifdef ENABLE_HTTP_STREAM_PLAYBACK
details.streamUrl=streamUrl->text().trimmed();
#endif
} else {
details=MPDUser::self()->details(true);
- details.dir=Utils::convertDirFromDisplay(basicDir->text());
+ details.dir=Utils::convertPathFromDisplay(basicDir->text());
details.coverName=basicCoverName->text().trimmed();
MPDUser::self()->setMusicFolder(details.dir);
}
diff -Nru cantata-1.4.2.ds1/gui/serversettings.ui cantata-1.5.2.ds2/gui/serversettings.ui
--- cantata-1.4.2.ds1/gui/serversettings.ui 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/serversettings.ui 2015-03-23 20:09:42.000000000 +0000
@@ -40,10 +40,10 @@
-
-
+
-
-
+
-
@@ -168,110 +168,28 @@
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 13
-
-
-
-
- -
-
+ -
+
- <i><b>NOTE:</b> The 'Music folder' setting is used to lookup cover-art (either the value specified above, or <code>cover.jpg / cover.png</code> if not set). If you also have write permissions to this folder (and it's sub-folders), then Cantata will save any downloaded covers into the respective album folder.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ The 'Music folder' setting is used to lookup cover-art (either the value specified above, or <code>cover.jpg / cover.png</code> if not set). If you also have write permissions to this folder (and it's sub-folders), then Cantata will save any downloaded covers into the respective album folder.
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 13
-
-
-
-
- -
-
+ -
+
- <i><b>NOTE:</b> When using a local socket the full absolute path to the socket needs to be set. (Port number is not required.)</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ When using a local socket the full absolute path to the socket needs to be set. (Port number is not required.)
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 13
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 13
-
-
-
-
- -
-
+ -
+
- <i><b>NOTE:</b> 'HTTP Stream URL' is only of use if you have MPD configured to output to a HTTP stream, and you wish Cantata to be able to play that stream.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ 'HTTP Stream URL' is only of use if you have MPD configured to output to a HTTP stream, and you wish Cantata to be able to play that stream.
- -
+
-
Qt::Vertical
@@ -338,59 +256,28 @@
-
-
+
- <i><b>NOTE:</b> If you change the 'Music folder' setting, then you will need to manually update the music database. This can be performed by pressing the 'Refresh Database' button in the 'Artists' or 'Albums' views.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ If you change the 'Music folder' setting, then you will need to manually update the music database. This can be performed by pressing the 'Refresh Database' button in the 'Artists' or 'Albums' views.
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 13
-
-
-
-
- -
-
+ -
+
- <i><b>NOTE:</b> If no setting is specified for 'Cover filename, then Cantata will use a default of <code>cover</code> </i>
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
- true
-
-
- Qt::NoTextInteraction
+ If no setting is specified for 'Cover filename, then Cantata will use a default of <code>cover</code>
- -
-
+ -
+
Qt::Vertical
20
- 363
+ 0
@@ -408,9 +295,9 @@
- StateLabel
+ NoteLabel
QLabel
-
+
LineEdit
@@ -423,6 +310,11 @@
1
+
+ FlatToolButton
+ QToolButton
+
+
combo
diff -Nru cantata-1.4.2.ds1/gui/settings.cpp cantata-1.5.2.ds2/gui/settings.cpp
--- cantata-1.4.2.ds1/gui/settings.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/settings.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -32,9 +32,6 @@
#if defined ENABLE_KDE_SUPPORT && defined ENABLE_KWALLET
#include
#endif
-#ifndef ENABLE_KDE_SUPPORT
-#include "mediakeys.h"
-#endif
#include
#include
#include
@@ -137,22 +134,22 @@
Settings::Settings()
: state(AP_Configured)
- , timer(0)
, ver(-1)
#if defined ENABLE_KDE_SUPPORT && defined ENABLE_KWALLET
, wallet(0)
#endif
{
+ // Call 'version' so that it initialises 'ver' and 'state'
+ version();
// Only need to read system defaults if we have not previously been configured...
- if (version()readPassword("mpd", details.password);
+ if (KWallet::Wallet::isEnabled()) {
+ if (grp.get("passwd", false)) {
+ if (openWallet()) {
+ wallet->readPassword(name.isEmpty() ? "mpd" : name, details.password);
+ }
+ } else if (name.isEmpty()) {
+ details.password=mpdDefaults.passwd;
}
- } else if (name.isEmpty()) {
- details.password=mpdDefaults.passwd;
- }
- #else
- details.password=cfg.get("connectionPasswd", name.isEmpty() ? mpdDefaults.passwd : QString());
- #endif
- details.port=cfg.get("connectionPort", name.isEmpty() ? mpdDefaults.port : 6600);
- #ifdef Q_OS_WIN
- details.dir=Utils::fixPath(QDir::fromNativeSeparators(cfg.get("mpdDir", mpdDefaults.dir)));
- #else
- details.dir=Utils::fixPath(cfg.get("mpdDir", mpdDefaults.dir));
+ } else
+ #endif // ENABLE_KWALLET
+ details.password=grp.get("passwd", name.isEmpty() ? mpdDefaults.passwd : QString());
+ details.coverName=grp.get("coverName", QString());
+ #ifdef ENABLE_HTTP_STREAM_PLAYBACK
+ details.streamUrl=grp.get("streamUrl", QString());
#endif
} else {
- QString n=MPDConnectionDetails::configGroupName(name);
- details.name=name;
- if (!cfg.hasGroup(n)) {
- details.name=QString();
- n=MPDConnectionDetails::configGroupName(details.name);
- }
- if (cfg.hasGroup(n)) {
- cfg.beginGroup(n);
- details.hostname=cfg.get("host", name.isEmpty() ? mpdDefaults.host : QString());
- details.port=cfg.get("port", name.isEmpty() ? mpdDefaults.port : 6600);
- #ifdef Q_OS_WIN
- details.dir=Utils::fixPath(QDir::fromNativeSeparators(cfg.get("dir", name.isEmpty() ? mpdDefaults.dir : "/var/lib/mpd/music")));
- #else
- details.dir=Utils::fixPath(cfg.get("dir", name.isEmpty() ? mpdDefaults.dir : "/var/lib/mpd/music"));
- #endif
- #if defined ENABLE_KDE_SUPPORT && defined ENABLE_KWALLET
- if (KWallet::Wallet::isEnabled()) {
- if (cfg.get("passwd", false)) {
- if (openWallet()) {
- wallet->readPassword(name.isEmpty() ? "mpd" : name, details.password);
- }
- } else if (name.isEmpty()) {
- details.password=mpdDefaults.passwd;
- }
- } else
- #endif // ENABLE_KWALLET
- details.password=cfg.get("passwd", name.isEmpty() ? mpdDefaults.passwd : QString());
- details.coverName=cfg.get("coverName", QString());
- #ifdef ENABLE_HTTP_STREAM_PLAYBACK
- details.streamUrl=cfg.get("streamUrl", QString());
- #endif
- cfg.endGroup();
- } else {
- details.hostname=mpdDefaults.host;
- details.port=mpdDefaults.port;
- details.dir=mpdDefaults.dir;
- details.password=mpdDefaults.passwd;
- details.coverName=QString();
- #ifdef ENABLE_HTTP_STREAM_PLAYBACK
- details.streamUrl=QString();
- #endif
- }
+ details.hostname=mpdDefaults.host;
+ details.port=mpdDefaults.port;
+ details.dir=mpdDefaults.dir;
+ details.password=mpdDefaults.passwd;
+ details.coverName=QString();
+ #ifdef ENABLE_HTTP_STREAM_PLAYBACK
+ details.streamUrl=QString();
+ #endif
}
details.setDirReadable();
return details;
@@ -367,9 +338,7 @@
#ifndef ENABLE_UBUNTU
int Settings::libraryView()
{
- int v=version();
- QString def=ItemView::modeStr(vMusicLibraryItemAlbum::CoverExtraLarge || size<0 ? MusicLibraryItemAlbum::CoverMedium : size;
-}
-
-int Settings::albumsCoverSize()
-{
- int size=cfg.get("albumsCoverSize", (int)(MusicLibraryItemAlbum::CoverMedium));
- return size>MusicLibraryItemAlbum::CoverExtraLarge || size<0 ? MusicLibraryItemAlbum::CoverMedium : size;
+ return cfg.get("libraryArtistImage", false);
}
int Settings::albumSort()
@@ -446,27 +387,7 @@
int Settings::sidebar()
{
if (version()stop();
- }
- } else {
- if (!timer) {
- timer=new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(actualSave()));
+ cfg.set("showRatingWidget", v);
+}
+
+void Settings::saveInfoTooltips(bool v)
+{
+ cfg.set("infoTooltips", v);
+}
+
+void Settings::saveRetinaSupport(bool v)
+{
+ cfg.set("retinaSupport", v);
+}
+
+void Settings::save()
+{
+ if (AP_NotConfigured!=state) {
+ if (version()!=PACKAGE_VERSION || AP_FirstRun==state) {
+ cfg.set("version", PACKAGE_VERSION_STRING);
+ ver=PACKAGE_VERSION;
}
- timer->start(30*1000);
}
+ cfg.sync();
}
void Settings::clearVersion()
@@ -1519,11 +1422,6 @@
state=AP_NotConfigured;
}
-void Settings::actualSave()
-{
- save(true);
-}
-
int Settings::getBoolAsInt(const QString &key, int def)
{
// Old config, sometimes bool was used - which has now been converted
@@ -1537,4 +1435,3 @@
}
return v.toInt();
}
-
diff -Nru cantata-1.4.2.ds1/gui/settings.h cantata-1.5.2.ds2/gui/settings.h
--- cantata-1.4.2.ds1/gui/settings.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/settings.h 2015-03-23 20:09:42.000000000 +0000
@@ -33,12 +33,8 @@
}
#endif
-class QTimer;
-
-class Settings : public QObject
+class Settings
{
- Q_OBJECT
-
public:
enum StartupState
{
@@ -85,8 +81,6 @@
int onlineView();
#endif
bool libraryArtistImage();
- int libraryCoverSize();
- int albumsCoverSize();
int albumSort();
int sidebar();
bool libraryYear();
@@ -109,9 +103,6 @@
int contextTrackView();
QString page();
QStringList hiddenPages();
- #if !defined ENABLE_KDE_SUPPORT && !defined ENABLE_UBUNTU
- QString mediaKeysIface();
- #endif
#ifdef ENABLE_DEVICES_SUPPORT
bool overwriteSongs();
bool showDeleteAction();
@@ -134,6 +125,7 @@
int playQueueBackgroundBlur();
QString playQueueBackgroundFile();
bool playQueueConfirmClear();
+ bool playQueueSearch();
bool playListsStartClosed();
#ifdef ENABLE_HTTP_STREAM_PLAYBACK
bool playStream();
@@ -157,13 +149,13 @@
bool showTimeRemaining();
QStringList hiddenStreamCategories();
QStringList hiddenOnlineProviders();
- #if !defined Q_OS_WIN && !defined Q_OS_MAC
+ #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND)
bool inhibitSuspend();
#endif
int rssUpdate();
QDateTime lastRssUpdate();
QString podcastDownloadPath();
- bool podcastAutoDownload();
+ int podcastAutoDownloadLimit();
int maxCoverUpdatePerIteration();
int coverCacheSize();
QStringList cueFileCodecs();
@@ -186,6 +178,10 @@
bool filteredOnly();
bool showCoverWidget();
bool showStopButton();
+ bool showRatingWidget();
+ bool infoTooltips();
+ bool retinaSupport();
+ int seekStep();
void removeConnectionDetails(const QString &v);
void saveConnectionDetails(const MPDConnectionDetails &v);
@@ -213,8 +209,6 @@
void saveOnlineView(int v);
#endif
void saveLibraryArtistImage(bool v);
- void saveLibraryCoverSize(int v);
- void saveAlbumsCoverSize(int v);
void saveAlbumSort(int v);
void saveSidebar(int v);
void saveLibraryYear(bool v);
@@ -237,9 +231,6 @@
void saveContextTrackView(int v);
void savePage(const QString &v);
void saveHiddenPages(const QStringList &v);
- #if !defined ENABLE_KDE_SUPPORT && !defined ENABLE_UBUNTU
- void saveMediaKeysIface(const QString &v);
- #endif
#ifdef ENABLE_DEVICES_SUPPORT
void saveOverwriteSongs(bool v);
void saveShowDeleteAction(bool v);
@@ -260,6 +251,7 @@
void savePlayQueueBackgroundBlur(int v);
void savePlayQueueBackgroundFile(const QString &v);
void savePlayQueueConfirmClear(bool v);
+ void savePlayQueueSearch(bool v);
void savePlayListsStartClosed(bool v);
#ifdef ENABLE_HTTP_STREAM_PLAYBACK
void savePlayStream(bool v);
@@ -282,16 +274,15 @@
void saveShowTimeRemaining(bool v);
void saveHiddenStreamCategories(const QStringList &v);
void saveHiddenOnlineProviders(const QStringList &v);
- #if !defined Q_OS_WIN && !defined Q_OS_MAC
+ #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND)
void saveInhibitSuspend(bool v);
#endif
void saveRssUpdate(int v);
void saveLastRssUpdate(const QDateTime &v);
void savePodcastDownloadPath(const QString &v);
- void savePodcastAutoDownload(bool v);
+ void savePodcastAutoDownloadLimit(int v);
void saveStartupState(int v);
void saveSearchCategory(const QString &v);
- void saveCacheScaledCovers(bool v);
void saveFetchCovers(bool v);
#ifndef ENABLE_KDE_SUPPORT
void saveLang(const QString &v);
@@ -301,7 +292,10 @@
void saveFilteredOnly(bool v);
void saveShowCoverWidget(bool v);
void saveShowStopButton(bool v);
- void save(bool force=false);
+ void saveShowRatingWidget(bool v);
+ void saveInfoTooltips(bool v);
+ void saveRetinaSupport(bool v);
+ void save();
void clearVersion();
#if defined ENABLE_KDE_SUPPORT && defined ENABLE_KWALLET
bool openWallet();
@@ -311,9 +305,6 @@
bool firstRun() const { return AP_Configured!=state; }
-private Q_SLOTS:
- void actualSave();
-
private:
int getBoolAsInt(const QString &key, int def);
@@ -325,7 +316,6 @@
};
AppState state;
- QTimer *timer;
int ver;
#if defined ENABLE_KDE_SUPPORT && defined ENABLE_KWALLET
KWallet::Wallet *wallet;
diff -Nru cantata-1.4.2.ds1/gui/shortcutssettingspage.cpp cantata-1.5.2.ds2/gui/shortcutssettingspage.cpp
--- cantata-1.4.2.ds1/gui/shortcutssettingspage.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/shortcutssettingspage.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -39,13 +39,8 @@
#include
#include
-static const char * constMkEnabledVal="mk-enabled-val";
-
ShortcutsSettingsPage::ShortcutsSettingsPage(QWidget *p)
: QWidget(p)
- , mediaKeysIfaceCombo(0)
- , settingsButton(0)
- , mediaKeysEnabled(0)
{
QBoxLayout *lay=new QBoxLayout(QBoxLayout::TopToBottom, this);
lay->setMargin(0);
@@ -56,121 +51,13 @@
shortcuts->view()->setAlternatingRowColors(false);
shortcuts->view()->setItemDelegate(new BasicItemDelegate(shortcuts->view()));
lay->addWidget(shortcuts);
-
- #if !defined Q_OS_WIN && !defined Q_OS_MAC
- Utils::Desktop de=Utils::currentDe();
- bool useDesktop=true;
- bool isGnome=Utils::Unity==de || Utils::Gnome==de;
- #else
- bool useDesktop=false;
- bool isGnome=false;
- #endif
-
- #ifdef CANTATA_USE_QXT_MEDIAKEYS
- bool useQxt=true;
- #else
- bool useQxt=false;
- #endif
-
- if (useDesktop || useQxt) {
- QGroupBox *box=new QGroupBox(i18n("Multi-Media Keys"));
-
- if (useDesktop && useQxt) {
- QBoxLayout *boxLay=new QBoxLayout(QBoxLayout::LeftToRight, box);
- mediaKeysIfaceCombo=new QComboBox(box);
- boxLay->addWidget(mediaKeysIfaceCombo);
- mediaKeysIfaceCombo->addItem(i18n("Do not use media keys to control Cantata"), (unsigned int)MediaKeys::NoInterface);
- mediaKeysIfaceCombo->addItem(i18n("Use media keys to control Cantata"), (unsigned int)MediaKeys::QxtInterface);
-
- mediaKeysIfaceCombo->addItem(isGnome
- ? i18n("Use media keys, as configured in desktop settings, to control Cantata")
- : i18n("Use media keys, as configured in GNOME/Unity settings, to control Cantata"), (unsigned int)MediaKeys::GnomeInteface);
-
- settingsButton=new ToolButton(box);
- settingsButton->setToolTip(i18n("Configure..."));
- settingsButton->setIcon(Icons::self()->configureIcon);
- boxLay->addWidget(settingsButton);
- boxLay->addItem(new QSpacerItem(0, 1, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed));
- connect(settingsButton, SIGNAL(clicked(bool)), SLOT(showGnomeSettings()));
- connect(mediaKeysIfaceCombo, SIGNAL(currentIndexChanged(int)), SLOT(mediaKeysIfaceChanged()));
- } else if (useQxt) {
- QBoxLayout *boxLay=new QBoxLayout(QBoxLayout::LeftToRight, box);
- mediaKeysEnabled = new QCheckBox(i18n("Use media keys to control Cantata"), box);
- boxLay->addWidget(mediaKeysEnabled);
- boxLay->addItem(new QSpacerItem(0, 1, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed));
- mediaKeysEnabled->setProperty(constMkEnabledVal, (unsigned int)MediaKeys::QxtInterface);
- } else if (useDesktop) {
- QBoxLayout *boxLay=new QBoxLayout(QBoxLayout::LeftToRight, box);
- QWidget *controlWidget = new QWidget(box);
- mediaKeysEnabled = new QCheckBox(isGnome
- ? i18n("Use media keys, as configured in desktop settings, to control Cantata")
- : i18n("Use media keys, as configured in GNOME/Unity settings, to control Cantata"), controlWidget);
- settingsButton=new ToolButton(controlWidget);
- settingsButton->setToolTip(i18n("Configure..."));
- settingsButton->setIcon(Icons::self()->configureIcon);
- boxLay->addWidget(mediaKeysEnabled);
- boxLay->addWidget(settingsButton);
- boxLay->addItem(new QSpacerItem(0, 1, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed));
- mediaKeysEnabled->setProperty(constMkEnabledVal, (unsigned int)MediaKeys::GnomeInteface);
- connect(mediaKeysEnabled, SIGNAL(toggled(bool)), settingsButton, SLOT(setEnabled(bool)));
- connect(settingsButton, SIGNAL(clicked(bool)), SLOT(showGnomeSettings()));
- }
- lay->addWidget(box);
- }
}
void ShortcutsSettingsPage::load()
{
- if (settingsButton) {
- settingsButton->setEnabled(false);
- }
- if (mediaKeysIfaceCombo) {
- unsigned int iface=(unsigned int)MediaKeys::toIface(Settings::self()->mediaKeysIface());
- for (int i=0; icount(); ++i) {
- if (mediaKeysIfaceCombo->itemData(i).toUInt()==iface) {
- mediaKeysIfaceCombo->setCurrentIndex(i);
- if (settingsButton) {
- settingsButton->setEnabled(iface==MediaKeys::GnomeInteface);
- }
- break;
- }
- }
- } else if (mediaKeysEnabled) {
- mediaKeysEnabled->setChecked(MediaKeys::NoInterface!=MediaKeys::toIface(Settings::self()->mediaKeysIface()));
- if (settingsButton) {
- settingsButton->setEnabled(mediaKeysEnabled->isChecked());
- }
- }
}
void ShortcutsSettingsPage::save()
{
shortcuts->save();
- if (mediaKeysIfaceCombo) {
- Settings::self()->saveMediaKeysIface(MediaKeys::toString((MediaKeys::InterfaceType)mediaKeysIfaceCombo->itemData(mediaKeysIfaceCombo->currentIndex()).toUInt()));
- } else if (mediaKeysEnabled) {
- Settings::self()->saveMediaKeysIface(MediaKeys::toString(
- mediaKeysEnabled->isChecked()
- ? (MediaKeys::InterfaceType)mediaKeysEnabled->property(constMkEnabledVal).toUInt()
- : MediaKeys::NoInterface));
- }
-}
-
-void ShortcutsSettingsPage::mediaKeysIfaceChanged()
-{
- if (!settingsButton) {
- return;
- }
- settingsButton->setEnabled(MediaKeys::GnomeInteface==mediaKeysIfaceCombo->itemData(mediaKeysIfaceCombo->currentIndex()).toUInt());
-}
-
-void ShortcutsSettingsPage::showGnomeSettings()
-{
- #if !defined Q_OS_WIN && !defined Q_OS_MAC
- if (Utils::Unity==Utils::currentDe() && !Utils::findExe("unity-control-center").isEmpty()) {
- QProcess::startDetached("unity-control-center", QStringList() << "keyboard");
- return;
- }
- #endif
- QProcess::startDetached("gnome-control-center", QStringList() << "keyboard");
}
diff -Nru cantata-1.4.2.ds1/gui/shortcutssettingspage.h cantata-1.5.2.ds2/gui/shortcutssettingspage.h
--- cantata-1.4.2.ds1/gui/shortcutssettingspage.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/shortcutssettingspage.h 2015-03-23 20:09:42.000000000 +0000
@@ -33,23 +33,13 @@
class ShortcutsSettingsPage : public QWidget
{
- Q_OBJECT
-
public:
ShortcutsSettingsPage(QWidget *p);
void load();
void save();
-
-private Q_SLOTS:
- void mediaKeysIfaceChanged();
- void showGnomeSettings();
-
private:
ShortcutsSettingsWidget *shortcuts;
- QComboBox *mediaKeysIfaceCombo;
- ToolButton *settingsButton;
- QCheckBox *mediaKeysEnabled;
};
#endif
diff -Nru cantata-1.4.2.ds1/gui/stdactions.cpp cantata-1.5.2.ds2/gui/stdactions.cpp
--- cantata-1.4.2.ds1/gui/stdactions.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/stdactions.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -39,11 +39,7 @@
StdActions::StdActions()
{
- #ifdef ENABLE_KDE_SUPPORT
- bool menuIcons=true;
- #else
- bool menuIcons=!QCoreApplication::testAttribute(Qt::AA_DontShowIconsInMenus);
- #endif
+ UNITY_MENU_ICON_CHECK
prevTrackAction = ActionCollection::get()->createAction("prevtrack", i18n("Previous Track"), Icons::self()->toolbarPrevIcon);
nextTrackAction = ActionCollection::get()->createAction("nexttrack", i18n("Next Track"), Icons::self()->toolbarNextIcon);
playPauseTrackAction = ActionCollection::get()->createAction("playpausetrack", i18n("Play/Pause"), Icons::self()->toolbarPlayIcon);
@@ -52,33 +48,32 @@
stopAfterTrackAction = ActionCollection::get()->createAction("stopaftertrack", i18n("Stop After Track"), Icons::self()->toolbarStopIcon);
increaseVolumeAction = ActionCollection::get()->createAction("increasevolume", i18n("Increase Volume"));
decreaseVolumeAction = ActionCollection::get()->createAction("decreasevolume", i18n("Decrease Volume"));
- savePlayQueueAction = ActionCollection::get()->createAction("saveplaylist", i18n("Save As"), "document-save-as");
+ savePlayQueueAction = ActionCollection::get()->createAction("saveplaylist", i18n("Save As"), HIDE_MENU_ICON_NAME("document-save-as"));
addToPlayQueueAction = ActionCollection::get()->createAction("addtoplaylist", i18n("Add To Play Queue"), "list-add");
- addRandomToPlayQueueAction = ActionCollection::get()->createAction("addrandomalbumstoplaylist", i18n("Add Albums In Random Order"), Icons::self()->shuffleIcon);
replacePlayQueueAction = ActionCollection::get()->createAction("replaceplaylist", i18n("Replace Play Queue"), "media-playback-start");
- addWithPriorityAction = ActionCollection::get()->createAction("addwithprio", i18n("Add With Priority"), Icon("favorites"));
+ addWithPriorityAction = new Action(Icon("favorites"), i18n("Add With Priority"), 0);
addPrioHighestAction = new Action(i18n("Highest Priority (255)"), 0);
addPrioHighAction = new Action(i18n("High Priority (200)"), 0);
addPrioMediumAction = new Action(i18n("Medium Priority (125)"), 0);
addPrioLowAction = new Action(i18n("Low Priority (50)"), 0);
addPrioDefaultAction = new Action(i18n("Default Priority (0)"), 0);
addPrioCustomAction = new Action(i18n("Custom Priority..."), 0);
- addToStoredPlaylistAction = ActionCollection::get()->createAction("addtostoredplaylist", i18n("Add To Playlist"), Icons::self()->playlistIcon);
+ addToStoredPlaylistAction = new Action(Icons::self()->playlistIcon, i18n("Add To Playlist"), 0);
#ifdef TAGLIB_FOUND
organiseFilesAction = ActionCollection::get()->createAction("organizefiles", i18n("Organize Files"), "inode-directory");
- editTagsAction = ActionCollection::get()->createAction("edittags", i18n("Edit Tags"), "document-edit");
+ editTagsAction = ActionCollection::get()->createAction("edittags", i18n("Edit Track Information"), "document-edit");
#endif
#ifdef ENABLE_REPLAYGAIN_SUPPORT
replaygainAction = ActionCollection::get()->createAction("replaygain", i18n("ReplayGain"), Icons::self()->audioFileIcon);
#endif
#ifdef ENABLE_DEVICES_SUPPORT
- copyToDeviceAction = ActionCollection::get()->createAction("copytodevice", i18n("Copy Songs To Device"), "multimedia-player");
+ copyToDeviceAction = new Action(HIDE_MENU_ICON(Icon("multimedia-player")), i18n("Copy Songs To Device"), 0);
copyToDeviceAction->setMenu(DevicesModel::self()->menu());
deleteSongsAction = ActionCollection::get()->createAction("deletesongs", i18n("Delete Songs"), "edit-delete");
#endif
setCoverAction = ActionCollection::get()->createAction("setcover", i18n("Set Image"));
removeAction = ActionCollection::get()->createAction("removeitems", i18n("Remove"), "list-remove");
- searchAction = ActionCollection::get()->createAction("search", i18n("Find"), menuIcons ? "edit-find" : "");
+ searchAction = ActionCollection::get()->createAction("search", i18n("Find"), HIDE_MENU_ICON_NAME("edit-find"));
searchAction->setShortcut(Qt::ControlModifier+Qt::Key_F);
addToStoredPlaylistAction->setMenu(PlaylistsModel::self()->menu());
diff -Nru cantata-1.4.2.ds1/gui/stdactions.h cantata-1.5.2.ds2/gui/stdactions.h
--- cantata-1.4.2.ds1/gui/stdactions.h 2014-09-28 16:30:14.000000000 +0000
+++ cantata-1.5.2.ds2/gui/stdactions.h 2015-03-23 20:09:42.000000000 +0000
@@ -44,7 +44,6 @@
Action *decreaseVolumeAction;
Action *savePlayQueueAction;
Action *addToPlayQueueAction;
- Action *addRandomToPlayQueueAction;
Action *replacePlayQueueAction;
Action *addWithPriorityAction;
Action *addToStoredPlaylistAction;
diff -Nru cantata-1.4.2.ds1/gui/trayitem.cpp cantata-1.5.2.ds2/gui/trayitem.cpp
--- cantata-1.4.2.ds1/gui/trayitem.cpp 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/trayitem.cpp 2015-03-23 20:09:42.000000000 +0000
@@ -40,7 +40,11 @@
#endif
#include
#include
+#ifdef Q_OS_MAC
+#include "mac/macnotify.h"
+#endif
+#ifndef Q_OS_MAC
class VolumeSliderEventHandler : public QObject
{
public:
@@ -66,20 +70,41 @@
return QObject::eventFilter(obj, event);
}
};
+#endif
TrayItem::TrayItem(MainWindow *p)
: QObject(p)
+ #ifndef Q_OS_MAC
, mw(p)
, trayItem(0)
, trayItemMenu(0)
#ifdef QT_QTDBUS_FOUND
, notification(0)
#endif
+ #endif
{
}
+void TrayItem::showMessage(const QString &title, const QString &text, const QImage &img)
+{
+ #ifdef Q_OS_MAC
+ MacNotify::showMessage(title, text, img);
+ #elif defined QT_QTDBUS_FOUND
+ if (!notification) {
+ notification=new Notify(this);
+ }
+ notification->show(title, text, img);
+ #else
+ Q_UNUSED(img)
+ if (trayItem) {
+ trayItem->showMessage(title, text, QSystemTrayIcon::Information, 5000);
+ }
+ #endif
+}
+
void TrayItem::setup()
{
+ #ifndef Q_OS_MAC
if (!Settings::self()->useSystemTray()) {
if (trayItem) {
#ifndef ENABLE_KDE_SUPPORT
@@ -103,6 +128,7 @@
trayItem->setTitle(i18n("Cantata"));
trayItem->setIconByName(QIcon::hasThemeIcon("cantata-panel") ? QLatin1String("cantata-panel") : QLatin1String("cantata"));
trayItem->setToolTip("cantata", i18n("Cantata"), QString());
+ trayItem->setStandardActionsEnabled(false);
trayItemMenu = new KMenu(0);
trayItemMenu->addAction(StdActions::self()->prevTrackAction);
@@ -114,6 +140,9 @@
trayItem->setStatus(KStatusNotifierItem::Active);
trayItemMenu->addSeparator();
trayItemMenu->addAction(mw->restoreAction);
+ trayItemMenu->addSeparator();
+ trayItemMenu->addAction(mw->quitAction);
+
connect(trayItem, SIGNAL(scrollRequested(int, Qt::Orientation)), this, SLOT(trayItemScrollRequested(int, Qt::Orientation)));
connect(trayItem, SIGNAL(secondaryActivateRequested(const QPoint &)), mw, SLOT(playPauseTrack()));
connect(trayItem, SIGNAL(activateRequested(bool, const QPoint &)), this, SLOT(clicked()));
@@ -141,6 +170,7 @@
trayItem->show();
connect(trayItem, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayItemClicked(QSystemTrayIcon::ActivationReason)));
#endif
+ #endif
}
#ifdef ENABLE_KDE_SUPPORT
@@ -166,6 +196,9 @@
#else
void TrayItem::trayItemClicked(QSystemTrayIcon::ActivationReason reason)
{
+ #ifdef Q_OS_MAC
+ Q_UNUSED(reason)
+ #else
switch (reason) {
case QSystemTrayIcon::Trigger:
if (mw->isHidden()) {
@@ -180,11 +213,26 @@
default:
break;
}
+ #endif
}
#endif
void TrayItem::songChanged(const Song &song, bool isPlaying)
{
+ #ifdef Q_OS_MAC
+ if (Settings::self()->showPopups()) {
+ bool useable=song.isStandardStream()
+ ? !song.title.isEmpty() && !song.name().isEmpty()
+ : !song.title.isEmpty() && !song.artist.isEmpty() && !song.album.isEmpty();
+ if (useable) {
+ QString text=song.describe(false);
+ if (song.time>0) {
+ text+=QLatin1String(" - ")+Utils::formatTime(song.time);
+ }
+ MacNotify::showMessage(i18n("Now playing"), text, CurrentCover::self()->image());
+ }
+ }
+ #else
if (Settings::self()->showPopups() || trayItem) {
bool useable=song.isStandardStream()
? !song.title.isEmpty() && !song.name().isEmpty()
@@ -207,7 +255,7 @@
trayItem->setToolTip(i18n("Cantata")+"\n\n"+text);
// The pure Qt implementation needs both the tray icon and the setting checked.
if (Settings::self()->showPopups() && isPlaying) {
- trayItem->showMessage(i18n("Cantata"), text, QSystemTrayIcon::Information, 5000);
+ trayItem->showMessage(i18n("Now playing"), text, QSystemTrayIcon::Information, 5000);
}
#else
trayItem->setToolTip(i18n("Cantata")+"\n\n"+text);
@@ -229,4 +277,5 @@
#endif
}
}
+ #endif
}
diff -Nru cantata-1.4.2.ds1/gui/trayitem.h cantata-1.5.2.ds2/gui/trayitem.h
--- cantata-1.4.2.ds1/gui/trayitem.h 2014-09-28 16:30:13.000000000 +0000
+++ cantata-1.5.2.ds2/gui/trayitem.h 2015-03-23 20:09:42.000000000 +0000
@@ -39,6 +39,7 @@
class Notify;
#endif
class MainWindow;
+class QImage;
struct Song;
class TrayItem : public QObject
@@ -48,7 +49,13 @@
TrayItem(MainWindow *p);
virtual ~TrayItem() { }
+ void showMessage(const QString &title, const QString &text, const QImage &img);
void setup();
+ #ifdef Q_OS_MAC
+ bool isActive() const { return false; }
+ void setIcon(const QIcon &) { }
+ void setToolTip(const QString &, const QString &, const QString &) { }
+ #else
bool isActive() const { return 0!=trayItem; }
#ifdef ENABLE_KDE_SUPPORT
void setIconByName(const QString &name) {
@@ -74,6 +81,7 @@
#endif
}
}
+ #endif
void songChanged(const Song &song, bool isPlaying);
private Q_SLOTS:
@@ -85,6 +93,8 @@
#endif
private:
+ #ifndef Q_OS_MAC
+
MainWindow *mw;
#ifdef ENABLE_KDE_SUPPORT
KStatusNotifierItem *trayItem;
@@ -96,6 +106,8 @@
#ifdef QT_QTDBUS_FOUND
Notify *notification;
#endif
+
+ #endif
};
#endif
diff -Nru cantata-1.4.2.ds1/http/httpserver.cpp cantata-1.5.2.ds2/http/httpserver.cpp
--- cantata-1.4.2.ds1/http/httpserver.cpp 2014-09-28 16:30:05.000000000 +0000
+++ cantata-1.5.2.ds2/http/httpserver.cpp 2015-03-23 20:09:31.000000000 +0000
@@ -67,7 +67,6 @@
, closeTimer(0)
{
force=Settings::self()->alwaysUseHttp();
- connect(MPDConnection::self(), SIGNAL(socketAddress(QString)), this, SLOT(mpdAddress(QString)));
connect(MPDConnection::self(), SIGNAL(cantataStreams(QList,bool)), this, SLOT(cantataStreams(QList,bool)));
connect(MPDConnection::self(), SIGNAL(cantataStreams(QStringList)), this, SLOT(cantataStreams(QStringList)));
connect(MPDConnection::self(), SIGNAL(removedIds(QSet)), this, SLOT(removedIds(QSet)));
@@ -92,7 +91,7 @@
thread=new Thread("HttpServer");
}
socket=new HttpSocket(Settings::self()->httpInterface(), prevPort);
- socket->mpdAddress(mpdAddr);
+ socket->mpdAddress(MPDConnection::self()->ipAddress());
connect(this, SIGNAL(terminateSocket()), socket, SLOT(terminate()), Qt::QueuedConnection);
if (socket->serverPort()!=prevPort) {
Settings::self()->saveHttpAllocatedPort(socket->serverPort());
@@ -131,8 +130,7 @@
QString HttpServer::address() const
{
- return socket ? QLatin1String("http://")+socket->address()+QChar(':')+QString::number(socket->serverPort())
- : QLatin1String("http://127.0.0.1:*");
+ return socket ? socket->urlAddress() : QLatin1String("http://127.0.0.1:*");
}
bool HttpServer::isOurs(const QString &url) const
@@ -316,11 +314,6 @@
closeTimer->start(1000);
}
-void HttpServer::mpdAddress(const QString &a)
-{
- mpdAddr=a;
-}
-
void HttpServer::cantataStreams(const QStringList &files)
{
DBUG << files;
diff -Nru cantata-1.4.2.ds1/http/httpserver.h cantata-1.5.2.ds2/http/httpserver.h
--- cantata-1.4.2.ds1/http/httpserver.h 2014-09-28 16:30:05.000000000 +0000
+++ cantata-1.5.2.ds2/http/httpserver.h 2015-03-23 20:09:31.000000000 +0000
@@ -80,7 +80,6 @@
private Q_SLOTS:
void stop();
void startCloseTimer();
- void mpdAddress(const QString &a);
void cantataStreams(const QStringList &files);
void cantataStreams(const QList &songs, bool isUpdate);
void removedIds(const QSet &ids);
@@ -93,7 +92,6 @@
Thread *thread;
HttpSocket *socket;
- QString mpdAddr;
QSet streamIds; // Currently playing MPD stream IDs
QTimer *closeTimer;
#endif
diff -Nru cantata-1.4.2.ds1/http/httpserversettings.cpp cantata-1.5.2.ds2/http/httpserversettings.cpp
--- cantata-1.4.2.ds1/http/httpserversettings.cpp 2014-09-28 16:30:05.000000000 +0000
+++ cantata-1.5.2.ds2/http/httpserversettings.cpp 2015-03-23 20:09:31.000000000 +0000
@@ -36,15 +36,38 @@
static QString details(const QNetworkInterface &iface)
{
QString d=iface.humanReadableName();
- if (!iface.addressEntries().isEmpty()) {
- d+=QLatin1String(" - ")+iface.addressEntries().first().ip().toString();
+ QList addresses=iface.addressEntries();
+ if (!addresses.isEmpty()) {
+ QString ipV4, ipV6;
+ foreach (const QNetworkAddressEntry &addr, addresses) {
+ QString ip=addr.ip().toString();
+ if (ip.isEmpty()) {
+ continue;
+ }
+ if (ip.endsWith(QLatin1Char('%')+d)) {
+ ip=ip.left(ip.length()-(d.length()+1));
+ }
+ if (QAbstractSocket::IPv4Protocol==addr.ip().protocol()) {
+ ipV4=ip;
+ } else if (QAbstractSocket::IPv6Protocol==addr.ip().protocol()) {
+ ipV6=ip;
+ }
+ }
+
+ QString ipAddr;
+ if (!ipV4.isEmpty()) {
+ ipAddr=ipV4;
+ } else if (!ipV6.isEmpty()) {
+ ipAddr=ipV6;
+ }
+ d+=QLatin1String(" - ")+ipAddr;
}
return d;
}
static QString displayName(const QNetworkInterface &iface)
{
- if (iface.name()=="lo") {
+ if (iface.name()==QLatin1String("lo") || isIfaceType(iface , "lo")) {
return i18n("Local loopback (%1)", details(iface));
}
if (isIfaceType(iface, "eth")) {
@@ -72,6 +95,10 @@
{
setupUi(this);
initInterfaces(httpInterface);
+
+ #ifdef Q_OS_MAC
+ expandingSpacer->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
+ #endif
}
void HttpServerSettings::load()
diff -Nru cantata-1.4.2.ds1/http/httpserversettings.ui cantata-1.5.2.ds2/http/httpserversettings.ui
--- cantata-1.4.2.ds1/http/httpserversettings.ui 2014-09-28 16:30:05.000000000 +0000
+++ cantata-1.5.2.ds2/http/httpserversettings.ui 2015-03-23 20:09:31.000000000 +0000
@@ -35,44 +35,28 @@
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Fixed
-
-
-
- 20
- 16
-
+
+
+ MPD usually only plays songs that are stored within its folders. Cantata contains a minimal HTTP server that can be used to serve other files to MPD. This, however, will only work whilst Cantata is running.
-
+
-
-
+
- <i><b>NOTE:</b> MPD usually only plays songs that are stored within its folders. Cantata contains a minimal HTTP server that can be used to serve other files to MPD. This, however, will only work whilst Cantata is running.<br/><br/>
-<b>NOTE:</b> If you choose 'Local loopback' for 'Network interface', then MPD <b>must</b> also be on this computer.</i>
-
-
- true
-
-
- Qt::NoTextInteraction
+ If you choose 'Local loopback' for 'Network interface', then MPD <b>must</b> also be on this computer.
-
-
+
Qt::Vertical
20
- 13
+ 0
@@ -85,6 +69,11 @@
QLabel
+
+ NoteLabel
+ QLabel
+
+
diff -Nru cantata-1.4.2.ds1/http/httpsocket.cpp cantata-1.5.2.ds2/http/httpsocket.cpp
--- cantata-1.4.2.ds1/http/httpsocket.cpp 2014-09-28 16:30:05.000000000 +0000
+++ cantata-1.5.2.ds2/http/httpsocket.cpp 2015-03-23 20:09:31.000000000 +0000
@@ -258,13 +258,15 @@
if (isListening() && ifaceAddress.isEmpty()) {
ifaceAddress=QLatin1String("127.0.0.1");
}
+ setUrlAddress();
- DBUG << isListening() << ifaceAddress << serverPort();
+ DBUG << isListening() << urlAddr;
connect(MPDConnection::self(), SIGNAL(socketAddress(QString)), this, SLOT(mpdAddress(QString)));
connect(MPDConnection::self(), SIGNAL(cantataStreams(QList,bool)), this, SLOT(cantataStreams(QList,bool)));
connect(MPDConnection::self(), SIGNAL(cantataStreams(QStringList)), this, SLOT(cantataStreams(QStringList)));
connect(MPDConnection::self(), SIGNAL(removedIds(QSet)), this, SLOT(removedIds(QSet)));
+ connect(this, SIGNAL(newConnection()), SLOT(handleNewConnection()));
}
bool HttpSocket::openPort(const QHostAddress &a, quint16 p)
@@ -304,12 +306,14 @@
deleteLater();
}
-void HttpSocket::incomingConnection(int socket)
+void HttpSocket::handleNewConnection()
{
- QTcpSocket *s = new QTcpSocket(this);
- connect(s, SIGNAL(readyRead()), this, SLOT(readClient()));
- connect(s, SIGNAL(disconnected()), this, SLOT(discardClient()));
- s->setSocketDescriptor(socket);
+ DBUG;
+ while (hasPendingConnections()) {
+ QTcpSocket *s = nextPendingConnection();
+ connect(s, SIGNAL(readyRead()), this, SLOT(readClient()));
+ connect(s, SIGNAL(disconnected()), this, SLOT(discardClient()));
+ }
}
void HttpSocket::readClient()
@@ -565,3 +569,16 @@
}
return true;
}
+
+void HttpSocket::setUrlAddress()
+{
+ if (ifaceAddress.isEmpty()) {
+ ifaceAddress=QString();
+ } else {
+ QUrl url;
+ url.setScheme("http");
+ url.setHost(ifaceAddress);
+ url.setPort(serverPort());
+ urlAddr=url.toString();
+ }
+}
diff -Nru cantata-1.4.2.ds1/http/httpsocket.h cantata-1.5.2.ds2/http/httpsocket.h
--- cantata-1.4.2.ds1/http/httpsocket.h 2014-09-28 16:30:05.000000000 +0000
+++ cantata-1.5.2.ds2/http/httpsocket.h 2015-03-23 20:09:31.000000000 +0000
@@ -41,9 +41,9 @@
HttpSocket(const QString &iface, quint16 port);
virtual ~HttpSocket() { }
- void incomingConnection(int socket);
QString address() const { return ifaceAddress; }
QString configuredInterface() { return cfgInterface; }
+ QString urlAddress() const { return urlAddr; }
public Q_SLOTS:
void terminate();
@@ -55,6 +55,7 @@
void sendErrorResponse(QTcpSocket *socket, int code);
private Q_SLOTS:
+ void handleNewConnection();
void readClient();
void discardClient();
void cantataStreams(const QStringList &files);
@@ -63,12 +64,14 @@
private:
bool write(QTcpSocket *socket, char *buffer, qint32 bytesRead, bool &stop);
+ void setUrlAddress();
private:
QSet newlyAddedFiles; // Holds cantata strema filenames as added to MPD via "add"
QMap streamIds; // Maps MPD playqueue song ID to fileName
QString cfgInterface;
QString ifaceAddress;
+ QString urlAddr;
QString mpdAddr;
bool terminated;
};
diff -Nru cantata-1.4.2.ds1/icons/CMakeLists.txt cantata-1.5.2.ds2/icons/CMakeLists.txt
--- cantata-1.4.2.ds1/icons/CMakeLists.txt 2014-09-28 16:30:21.000000000 +0000
+++ cantata-1.5.2.ds2/icons/CMakeLists.txt 2015-03-23 20:09:47.000000000 +0000
@@ -46,3 +46,6 @@
endif (NOT WIN32 AND NOT APPLE)
+#if (APPLE)
+# install(FILES trayicon-mono-dark.svg DESTINATION ${CANTATA_ICON_INSTALL_PREFIX}/scalable/apps RENAME cantata-panel.svg)
+#endif (APPLE)
diff -Nru cantata-1.4.2.ds1/icons/media-next-rtl-dark.svg cantata-1.5.2.ds2/icons/media-next-rtl-dark.svg
--- cantata-1.4.2.ds1/icons/media-next-rtl-dark.svg 2014-09-28 16:30:21.000000000 +0000
+++ cantata-1.5.2.ds2/icons/media-next-rtl-dark.svg 1970-01-01 00:00:00.000000000 +0000
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff -Nru cantata-1.4.2.ds1/icons/media-next-rtl-light.svg cantata-1.5.2.ds2/icons/media-next-rtl-light.svg
--- cantata-1.4.2.ds1/icons/media-next-rtl-light.svg 2014-09-28 16:30:21.000000000 +0000
+++ cantata-1.5.2.ds2/icons/media-next-rtl-light.svg 1970-01-01 00:00:00.000000000 +0000
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff -Nru cantata-1.4.2.ds1/icons/media-prev-rtl-dark.svg cantata-1.5.2.ds2/icons/media-prev-rtl-dark.svg
--- cantata-1.4.2.ds1/icons/media-prev-rtl-dark.svg 2014-09-28 16:30:21.000000000 +0000
+++ cantata-1.5.2.ds2/icons/media-prev-rtl-dark.svg 1970-01-01 00:00:00.000000000 +0000
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff -Nru cantata-1.4.2.ds1/icons/media-prev-rtl-light.svg cantata-1.5.2.ds2/icons/media-prev-rtl-light.svg
--- cantata-1.4.2.ds1/icons/media-prev-rtl-light.svg 2014-09-28 16:30:21.000000000 +0000
+++ cantata-1.5.2.ds2/icons/media-prev-rtl-light.svg 1970-01-01 00:00:00.000000000 +0000
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff -Nru cantata-1.4.2.ds1/icons/stars.svg cantata-1.5.2.ds2/icons/stars.svg
--- cantata-1.4.2.ds1/icons/stars.svg 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/icons/stars.svg 2015-03-23 20:09:47.000000000 +0000
@@ -0,0 +1,4 @@
+
+
+
+
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist128.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist128.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist16.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist16.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist22.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist22.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist32.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist32.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist48.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist48.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist64.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist64.png differ
diff -Nru cantata-1.4.2.ds1/icons/view-media-artist.svg cantata-1.5.2.ds2/icons/view-media-artist.svg
--- cantata-1.4.2.ds1/icons/view-media-artist.svg 2014-09-28 16:30:21.000000000 +0000
+++ cantata-1.5.2.ds2/icons/view-media-artist.svg 2015-03-23 20:09:47.000000000 +0000
@@ -1,42 +1,24 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist-various128.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist-various128.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist-various16.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist-various16.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist-various22.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist-various22.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist-various32.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist-various32.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist-various48.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist-various48.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-artist-various64.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-artist-various64.png differ
diff -Nru cantata-1.4.2.ds1/icons/view-media-artist-various.svg cantata-1.5.2.ds2/icons/view-media-artist-various.svg
--- cantata-1.4.2.ds1/icons/view-media-artist-various.svg 2014-09-28 16:30:21.000000000 +0000
+++ cantata-1.5.2.ds2/icons/view-media-artist-various.svg 2015-03-23 20:09:47.000000000 +0000
@@ -1,71 +1,32 @@
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-repeat16.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-repeat16.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-repeat22.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-repeat22.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-repeat24.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-repeat24.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-repeat32.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-repeat32.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-repeat48.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-repeat48.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-repeat64.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-repeat64.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-shuffle16.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-shuffle16.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-shuffle22.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-shuffle22.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-shuffle24.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-shuffle24.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-shuffle32.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-shuffle32.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-shuffle48.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-shuffle48.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/icons/view-media-shuffle64.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/icons/view-media-shuffle64.png differ
diff -Nru cantata-1.4.2.ds1/INSTALL cantata-1.5.2.ds2/INSTALL
--- cantata-1.4.2.ds1/INSTALL 2014-09-28 16:30:10.000000000 +0000
+++ cantata-1.5.2.ds2/INSTALL 2015-03-23 20:09:38.000000000 +0000
@@ -29,7 +29,7 @@
------
1. mkdir build
2. cd build
-3. cmake .. -DENABLE_UBUNTU=ON
+3. cmake .. -DENABLE_UBUNTU_COMMAND_LINE=ON
4. make
5. make install
6. click build click
@@ -49,7 +49,7 @@
-DCANTATA_TRANSLATIONS=
Builds and installs the selected translations. Supported values are
- cs, de, en_GB, es, hu, pl, ru, ko, zh_CN, and all. Entries should be
+ cs, de, en_GB, es, fr, hu, pl, ru, ko, zh_CN, and all. Entries should be
separated with a semicolon (";") e.g. -DCANTATA_TRANSLATIONS="es;pl"
Default: all
@@ -146,6 +146,13 @@
-DINSTALL_UBUNTU_ICONS=
Install monochrome system tray icons for Ubuntu.
+ -DCANTATA_HELPERS_LIB_DIR=
+ For non-KDE 64 bit builds, this may be used to control the lib sub-dir
+ where Cantata helper apps will be placed. e.g. setting this to lib64
+ will cause the helper apps (cantata-tags, cantata-replaygain) to be
+ install into /usr/lib64/cantata instead of /usr/lib/cantata
+ Default:
+
Windows specific:
@@ -153,15 +160,31 @@
Path where Inno Setpup Compiler should place the catata setup exe.
Default: z:\
- -DCANTATA_MINGW_LIBS=\mingwm10.dll;libgcc_s_dw2-1.dll
+ -DCANTATA_MINGW_LIBS=/mingwm10.dll;/libgcc_s_dw2-1.dll
Extra MinGW libraries required for install stage.
+ Qt4 builds only - not required for Qt5.
Default:
-
+
+ -DCANTATA_SSL_LIBS=/libeay32.dll;/ssleay32.dll
+ SSL libraries
+ Default:
+
-DCANTATA_OXYGEN_DIR=
Path to Oxygen icons, required for install stage.
Default:
+ Ubuntu specific:
+
+ -DENABLE_UBUNTU=ON
+ Build for Ubuntu Touch.
+ Default: OFF
+
+ -DENABLE_UBUNTU_COMMAND_LINE=ON
+ Build for the Ubuntu SDK from the command line.
+ Default: OFF
+
+
Testing ONLY options:
-DENABLE_MODEL_TEST=ON
diff -Nru cantata-1.4.2.ds1/mac/CMakeLists.txt cantata-1.5.2.ds2/mac/CMakeLists.txt
--- cantata-1.4.2.ds1/mac/CMakeLists.txt 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/mac/CMakeLists.txt 2015-03-23 20:09:36.000000000 +0000
@@ -1,5 +1,15 @@
install(FILES ${MACOSX_BUNDLE_ICON_FILE} DESTINATION ${MACOSX_BUNDLE_RESOURCES})
+# Qt translation files...
+file(GLOB qt_trans ${QT_TRANSLATIONS_DIR}/qt_*.qm)
+foreach(qm ${qt_trans})
+ if (NOT ${qm} MATCHES "(${QT_TRANSLATIONS_DIR}/qt_help*)")
+ list(APPEND qt_translations "${qm}")
+ endif (NOT ${qm} MATCHES "(${QT_TRANSLATIONS_DIR}/qt_help*)")
+endforeach(qm ${qt_trans})
+install(FILES ${qt_translations} DESTINATION ${MACOSX_BUNDLE_RESOURCES}/translations/)
+
if (CANTATA_OXYGEN_DIR)
add_subdirectory(icons)
endif (CANTATA_OXYGEN_DIR)
+
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/mac/dmg/background.png and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/mac/dmg/background.png differ
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/mac/dmg/background.xcf and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/mac/dmg/background.xcf differ
diff -Nru cantata-1.4.2.ds1/mac/dmg/create-dmg.sh.in cantata-1.5.2.ds2/mac/dmg/create-dmg.sh.in
--- cantata-1.4.2.ds1/mac/dmg/create-dmg.sh.in 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/mac/dmg/create-dmg.sh.in 2015-03-23 20:09:36.000000000 +0000
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# This script has been copied, and modified from the orignal create-dmg.sh
+# in Clemtine 1.2.3 - which in turn was taken from Tomahawk.
+#
+# author: max@last.fm, muesli@tomahawk-player.org
+# brief: Produces a compressed DMG from a bundle directory
+
+tempFolder="dmg/@MACOSX_BUNDLE_BUNDLE_NAME@"
+tempFile=dmg/temp.dmg
+dmgFileName="@MACOSX_BUNDLE_BUNDLE_NAME@-@CANTATA_VERSION_WITH_SPIN@.dmg"
+
+rm -rf "$tempFolder"
+rm -f "$dmgFileName" "$tempFile"
+
+# Create folder structure for disk image
+mkdir -p "$tempFolder/.background"
+cp @CMAKE_CURRENT_SOURCE_DIR@/mac/dmg/background.png "$tempFolder/.background/background.png"
+cp @CMAKE_CURRENT_SOURCE_DIR@/mac/dmg/DS_Store.in "$tempFolder/.DS_Store"
+chmod go-rwx "$tempFolder/.DS_Store"
+ln -s /Applications "$tempFolder/Applications"
+cp -R "@CMAKE_INSTALL_PREFIX@/@MACOSX_BUNDLE_BUNDLE_NAME@.app" "$tempFolder"
+
+# Create DMG file
+hdiutil makehybrid -hfs -hfs-volume-name @MACOSX_BUNDLE_BUNDLE_NAME@ -hfs-openfolder "$tempFolder" "$tempFolder" -o "$tempFile"
+hdiutil convert -format UDZO -imagekey zlib-level=9 "$tempFile" -o "$dmgFileName"
+
+# Remove temporary files
+rm -rf "$tempFolder"
+rm -f "$tempFile"
Binary files /tmp/6MegnvV89W/cantata-1.4.2.ds1/mac/dmg/DS_Store.in and /tmp/BCSka7CcRi/cantata-1.5.2.ds2/mac/dmg/DS_Store.in differ
diff -Nru cantata-1.4.2.ds1/mac/dockmenu.cpp cantata-1.5.2.ds2/mac/dockmenu.cpp
--- cantata-1.4.2.ds1/mac/dockmenu.cpp 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/mac/dockmenu.cpp 2015-03-23 20:09:36.000000000 +0000
@@ -0,0 +1,45 @@
+/*
+ * Cantata
+ *
+ * Copyright (c) 2011-2014 Craig Drummond
+ *
+ * ----
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "dockmenu.h"
+#include "gui/stdactions.h"
+#include "mpd/mpdstatus.h"
+#include "support/localize.h"
+
+DockMenu::DockMenu(QWidget *p)
+ : QMenu(p)
+{
+ setAsDockMenu();
+ addAction(StdActions::self()->prevTrackAction);
+ playPauseAction=addAction(i18n("Play"));
+ addAction(StdActions::self()->stopPlaybackAction);
+ addAction(StdActions::self()->stopAfterCurrentTrackAction);
+ addAction(StdActions::self()->nextTrackAction);
+ connect(playPauseAction, SIGNAL(triggered()), StdActions::self()->playPauseTrackAction, SIGNAL(triggered()));
+}
+
+void DockMenu::update(MPDStatus * const status)
+{
+ playPauseAction->setEnabled(status->playlistLength()>0);
+ playPauseAction->setText(MPDState_Playing==status->state() ? i18n("Pause") : i18n("Play"));
+}
diff -Nru cantata-1.4.2.ds1/mac/dockmenu.h cantata-1.5.2.ds2/mac/dockmenu.h
--- cantata-1.4.2.ds1/mac/dockmenu.h 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/mac/dockmenu.h 2015-03-23 20:09:36.000000000 +0000
@@ -0,0 +1,44 @@
+/*
+ * Cantata
+ *
+ * Copyright (c) 2011-2014 Craig Drummond
+ *
+ * ----
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef DOCKMENU_H
+#define DOCKMENU_H
+
+#include
+
+class QAction;
+class MPDStatus;
+
+class DockMenu : public QMenu
+{
+public:
+ DockMenu(QWidget *w);
+ virtual ~DockMenu() { }
+
+ void update(MPDStatus * const status);
+
+private:
+ QAction *playPauseAction;
+};
+
+#endif
diff -Nru cantata-1.4.2.ds1/mac/icons/CMakeLists.txt cantata-1.5.2.ds2/mac/icons/CMakeLists.txt
--- cantata-1.4.2.ds1/mac/icons/CMakeLists.txt 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/mac/icons/CMakeLists.txt 2015-03-23 20:09:36.000000000 +0000
@@ -197,9 +197,23 @@
32x32/actions/go-up.png
22x22/actions/go-up.png
16x16/actions/go-up.png
+64x64/actions/go-down.png
+48x48/actions/go-down.png
32x32/actions/go-down.png
22x22/actions/go-down.png
16x16/actions/go-down.png
+22x22/apps/clock.png
+48x48/apps/clock.png
+32x32/apps/clock.png
+64x64/apps/clock.png
+16x16/apps/clock.png
+48x48/actions/document-save-as.png
+48x48/mimetypes/inode-directory.png
+64x64/mimetypes/inode-directory.png
+48x48/mimetypes/audio-x-generic.png
+64x64/mimetypes/audio-x-generic.png
+48x48/places/document-multiple.png
+64x64/places/document-multiple.png
)
foreach(ICON ${OXYGEN_ICONS})
diff -Nru cantata-1.4.2.ds1/mac/icons/index.theme cantata-1.5.2.ds2/mac/icons/index.theme
--- cantata-1.4.2.ds1/mac/icons/index.theme 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/mac/icons/index.theme 2015-03-23 20:09:36.000000000 +0000
@@ -17,7 +17,7 @@
DialogDefault=32
DialogSizes=16,22,32,48,64,128,256
-Directories=16x16/actions,16x16/apps,16x16/categories,16x16/devices,16x16/mimetypes,16x16/places,16x16/status,22x22/actions,22x22/animations,22x22/apps,22x22/categories,22x22/devices,22x22/mimetypes,22x22/places,22x22/status,32x32/actions,32x32/apps,32x32/categories,32x32/devices,32x32/mimetypes,32x32/places,32x32/status,48x48/actions,48x48/apps,48x48/categories,48x48/devices,48x48/status,64x64/apps,64x64/categories,64x64/devices,64x64/status,128x128/categories,128x128/devices,256x256/categories,256x256/devices,scalable/apps
+Directories=16x16/actions,16x16/apps,16x16/categories,16x16/devices,16x16/mimetypes,16x16/places,16x16/status,22x22/actions,22x22/animations,22x22/apps,22x22/categories,22x22/devices,22x22/mimetypes,22x22/places,22x22/status,32x32/actions,32x32/apps,32x32/categories,32x32/devices,32x32/mimetypes,32x32/places,32x32/status,48x48/actions,48x48/apps,48x48/categories,48x48/devices,48x48/mimetypes,48x48/places,48x48/status,64x64/apps,64x64/categories,64x64/devices,64x64/mimetypes,64x64/places,64x64/status,128x128/categories,128x128/devices,256x256/categories,256x256/devices,scalable/apps
[16x16/actions]
Size=16
@@ -149,6 +149,16 @@
Context=Devices
Type=Threshold
+[48x48/mimetypes]
+Size=48
+Context=MimeTypes
+Type=Threshold
+
+[48x48/places]
+Size=48
+Context=Places
+Type=Threshold
+
[48x48/status]
Size=48
Context=Status
@@ -169,6 +179,16 @@
Context=Devices
Type=Threshold
+[64x64/mimetypes]
+Size=64
+Context=MimeTypes
+Type=Threshold
+
+[64x64/places]
+Size=64
+Context=Places
+Type=Threshold
+
[64x64/status]
Size=64
Context=Status
diff -Nru cantata-1.4.2.ds1/mac/icons/README cantata-1.5.2.ds2/mac/icons/README
--- cantata-1.4.2.ds1/mac/icons/README 2014-09-28 16:30:09.000000000 +0000
+++ cantata-1.5.2.ds2/mac/icons/README 2015-03-23 20:09:36.000000000 +0000
@@ -1,6 +1,7 @@
-The icons included here are (apart from the cantata icon) are taken from the
-Oxygen icon project (http://www.oxygen-icons.org/). Only the minimum set of
+The icons included here are (apart from the cantata icon) are taken from the
+Oxygen icon project (http://www.oxygen-icons.org/). Only the minimum set of
icons needed for Cantata are included.
-Oxygen icon theme is dual licensed. To facilitate this, a copy of each license
+Oxygen icon theme is dual licensed. To facilitate this, a copy of each license
is included.
+
diff -Nru cantata-1.4.2.ds1/mac/Info.plist.cmake cantata-1.5.2.ds2/mac/Info.plist.cmake
--- cantata-1.4.2.ds1/mac/Info.plist.cmake 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/mac/Info.plist.cmake 2015-03-23 20:09:36.000000000 +0000
@@ -0,0 +1,40 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleExecutable
+ @MACOSX_BUNDLE_EXECUTABLE@
+ CFBundleGetInfoString
+
+ CFBundleIconFile
+ @MACOSX_BUNDLE_ICON_FILE@
+ CFBundleIdentifier
+ @PROJECT_REV_URL@
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleLongVersionString
+ @MACOSX_BUNDLE_LONG_VERSION_STRING@
+ CFBundleName
+ @MACOSX_BUNDLE_BUNDLE_NAME@
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ @MACOSX_BUNDLE_SHORT_VERSION_STRING@
+ CFBundleSignature
+ ????
+ CFBundleVersion
+
+ CSResourcesFileMapped
+
+ LSRequiresCarbon
+
+ NSHumanReadableCopyright
+
+ NSPrincipalClass
+ NSApplication
+ NSHighResolutionCapable
+ True
+
+
diff -Nru cantata-1.4.2.ds1/mac/macnotify.h cantata-1.5.2.ds2/mac/macnotify.h
--- cantata-1.4.2.ds1/mac/macnotify.h 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/mac/macnotify.h 2015-03-23 20:09:36.000000000 +0000
@@ -0,0 +1,35 @@
+/*
+ * Cantata
+ *
+ * Copyright (c) 2011-2014 Craig Drummond
+ *
+ * ----
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef MACNOTIFY_H
+#define MACNOTIFY_H
+
+class QString;
+class QImage;
+
+namespace MacNotify
+{
+ extern void showMessage(const QString &title, const QString &text, const QImage &img);
+}
+
+#endif
diff -Nru cantata-1.4.2.ds1/mac/macnotify.mm cantata-1.5.2.ds2/mac/macnotify.mm
--- cantata-1.4.2.ds1/mac/macnotify.mm 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/mac/macnotify.mm 2015-03-23 20:09:36.000000000 +0000
@@ -0,0 +1,84 @@
+/*
+ * Cantata
+ *
+ * Copyright (c) 2011-2014 Craig Drummond
+ *
+ * ----
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "macnotify.h"
+#include "config.h"
+#include
+#include
+#ifdef QT_MAC_EXTRAS_FOUND
+#include
+#include
+#include
+#endif
+#include
+
+@interface UserNotificationItem : NSObject { }
+
+- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification;
+@end
+
+@implementation UserNotificationItem
+- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification {
+ Q_UNUSED(center);
+ Q_UNUSED(notification);
+ return YES;
+}
+@end
+
+class UserNotificationItemClass
+{
+public:
+ UserNotificationItemClass() {
+ item = [UserNotificationItem alloc];
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:item];
+ }
+ }
+ ~UserNotificationItemClass() {
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil];
+ }
+ [item release];
+ }
+ UserNotificationItem *item;
+};
+
+void MacNotify::showMessage(const QString &title, const QString &text, const QImage &img)
+{
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
+ static UserNotificationItemClass *n=0;
+ if (!n) {
+ n=new UserNotificationItemClass();
+ }
+
+ NSUserNotification *userNotification = [[[NSUserNotification alloc] init] autorelease];
+ userNotification.title = title.toNSString();
+ userNotification.informativeText = text.toNSString();
+ #ifdef QT_MAC_EXTRAS_FOUND
+ userNotification.contentImage = QtMac::toNSImage(QPixmap::fromImage(img));
+ #else
+ Q_UNUSED(img)
+ #endif
+ [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];
+ }
+}
diff -Nru cantata-1.4.2.ds1/mac/powermanagement.cpp cantata-1.5.2.ds2/mac/powermanagement.cpp
--- cantata-1.4.2.ds1/mac/powermanagement.cpp 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/mac/powermanagement.cpp 2015-03-23 20:09:36.000000000 +0000
@@ -0,0 +1,70 @@
+/*
+ * Cantata
+ *
+ * Copyright (c) 2011-2014 Craig Drummond
+ *
+ * ----
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "powermanagement.h"
+#include "support/globalstatic.h"
+#include "mpd/mpdstatus.h"
+#include
+#include
+#include
+
+GLOBAL_STATIC(PowerManagement, instance)
+
+static void powerEventCallback(void *rootPort, io_service_t, natural_t msg, void *arg)
+{
+ switch (msg) {
+ case kIOMessageSystemWillSleep:
+ IOAllowPowerChange(*(io_connect_t *) rootPort, (long)arg);
+ break;
+ case kIOMessageSystemHasPoweredOn:
+ PowerManagement::self()->emitResuming();
+ break;
+ case kIOMessageCanSystemSleep:
+ if (PowerManagement::self()->inhibitSuspend() && MPDState_Playing==MPDStatus::self()->state()) {
+ IOCancelPowerChange(*(io_connect_t *) rootPort, (long)arg);
+ } else {
+ IOAllowPowerChange(*(io_connect_t *) rootPort, (long)arg);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+PowerManagement::PowerManagement()
+ : inhibitSuspendWhilstPlaying(false)
+{
+ static io_connect_t rootPort;
+ IONotificationPortRef notificationPort;
+ io_object_t notifier;
+
+ rootPort = IORegisterForSystemPower(&rootPort, ¬ificationPort, powerEventCallback, ¬ifier);
+ if (rootPort) {
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(notificationPort), kCFRunLoopDefaultMode);
+ }
+}
+
+void PowerManagement::emitResuming()
+{
+ emit resuming();
+}
diff -Nru cantata-1.4.2.ds1/mac/powermanagement.h cantata-1.5.2.ds2/mac/powermanagement.h
--- cantata-1.4.2.ds1/mac/powermanagement.h 1970-01-01 00:00:00.000000000 +0000
+++ cantata-1.5.2.ds2/mac/powermanagement.h 2015-03-23 20:09:36.000000000 +0000
@@ -0,0 +1,48 @@
+/*
+ * Cantata
+ *
+ * Copyright (c) 2011-2014 Craig Drummond
+ *
+ * ----
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef POWERMANAGEMENT_H
+#define POWERMANAGEMENT_H
+
+#include
+
+class PowerManagement : public QObject
+{
+ Q_OBJECT
+
+public:
+ static PowerManagement * self();
+ PowerManagement();
+
+ void setInhibitSuspend(bool i) { inhibitSuspendWhilstPlaying=i; }
+ bool inhibitSuspend() const { return inhibitSuspendWhilstPlaying; }
+ void emitResuming();
+
+Q_SIGNALS:
+ void resuming();
+
+private:
+ bool inhibitSuspendWhilstPlaying;
+};
+
+#endif
diff -Nru cantata-1.4.2.ds1/models/albumsmodel.cpp cantata-1.5.2.ds2/models/albumsmodel.cpp
--- cantata-1.4.2.ds1/models/albumsmodel.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/albumsmodel.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -54,53 +54,6 @@
GLOBAL_STATIC(AlbumsModel, instance)
-#ifndef ENABLE_UBUNTU
-static MusicLibraryItemAlbum::CoverSize coverSize=MusicLibraryItemAlbum::CoverMedium;
-static QPixmap *theDefaultIcon=0;
-static QSize itemSize;
-static bool iconMode=true;
-
-int AlbumsModel::iconSize()
-{
- return MusicLibraryItemAlbum::iconSize(coverSize, iconMode);
-}
-
-static int stdIconSize()
-{
- return iconMode ? 128 : MusicLibraryItemAlbum::iconSize(coverSize);
-}
-
-void AlbumsModel::setIconMode(bool u)
-{
- if (iconMode!=u && theDefaultIcon) {
- delete theDefaultIcon;
- theDefaultIcon=0;
- }
- iconMode=u;
-}
-
-MusicLibraryItemAlbum::CoverSize AlbumsModel::currentCoverSize()
-{
- return coverSize;
-}
-
-void AlbumsModel::setItemSize(const QSize &sz)
-{
- itemSize=sz;
-}
-
-void AlbumsModel::setCoverSize(MusicLibraryItemAlbum::CoverSize size)
-{
- if (size!=coverSize) {
- if (theDefaultIcon) {
- delete theDefaultIcon;
- theDefaultIcon=0;
- }
- coverSize=size;
- }
-}
-#endif
-
AlbumsModel::Sort AlbumsModel::toSort(const QString &str)
{
for (int i=0; i<=Sort_YearArtist; ++i) {
@@ -225,32 +178,17 @@
QString cover=al->cover();
return cover.isEmpty() ? constDefaultCover : cover;
}
- #else
- case Cantata::Role_Image:
- case Qt::DecorationRole: {
- int iSize=iconSize();
- if (iSize) {
- QPixmap *pix=al->cover();
- if (pix) {
- return *pix;
- }
- } else if (Qt::DecorationRole==role) {
- return Icons::self()->albumIcon;
- }
-
- if (!theDefaultIcon) {
- int cSize=iSize;
- int stdSize=stdIconSize();
- if (0==cSize) {
- cSize=stdSize=22;
- }
- theDefaultIcon = new QPixmap(Icons::self()->albumIcon.pixmap(stdSize, stdSize)
- .scaled(QSize(cSize, cSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
- }
- return *theDefaultIcon;
- }
+ #endif
+ case Cantata::Role_ListImage:
+ return true;
+ #ifndef ENABLE_UBUNTU
+ case Qt::DecorationRole:
+ return Icons::self()->albumIcon;
#endif
case Qt::ToolTipRole:
+ if (!Settings::self()->infoTooltips()) {
+ return QVariant();
+ }
return 0==al->songs.count()
? QString()
: (al->artist+QLatin1Char('\n')+al->albumDisplay()+QLatin1Char('\n')+
@@ -268,19 +206,15 @@
return al->albumDisplay();
case Cantata::Role_BriefMainText:
return al->album;
- #ifndef ENABLE_UBUNTU
- case Cantata::Role_ImageSize:
- return iconSize();
- case Qt::SizeHintRole:
- if (!itemSize.isNull()) {
- return itemSize;
- }
- break;
- #endif
case Cantata::Role_SubText:
return al->artist;
case Cantata::Role_TitleText:
return i18nc("Album by Artist", "%1 by %2", al->album, al->artist);
+ case Cantata::Role_CoverSong: {
+ QVariant v;
+ v.setValue(al->coverSong());
+ return v;
+ }
}
} else {
SongItem *si=static_cast(item);
@@ -291,11 +225,17 @@
#ifdef ENABLE_UBUNTU
case Cantata::Role_Image:
return QString();
- #else
+ #endif
+ case Cantata::Role_ListImage:
+ return false;
+ #ifndef ENABLE_UBUNTU
case Qt::DecorationRole:
return Song::Playlist==si->type ? Icons::self()->playlistIcon : Icons::self()->audioFileIcon;
#endif
case Qt::ToolTipRole:
+ if (!Settings::self()->infoTooltips()) {
+ return QVariant();
+ }
return si->toolTip();
case Cantata::Role_MainText:
case Qt::DisplayRole:
@@ -383,14 +323,19 @@
}
#endif
-void AlbumsModel::update(const MusicLibraryItemRoot *root)
+void AlbumsModel::update(const MusicLibraryItemRoot *root, bool incremental)
{
if (!enabled) {
return;
}
bool changesMade=false;
- bool resettingModel=items.isEmpty() || 0==root->childCount();
+ bool resettingModel=!incremental || items.isEmpty() || 0==root->childCount();
+
+ if (!incremental) {
+ clear();
+ }
+
if (resettingModel) {
beginResetModel();
}
@@ -446,7 +391,10 @@
if (!found) {
changesMade=true;
- AlbumItem *a=new AlbumItem(artist, albumItem->data(), albumId, albumItem->year());
+ AlbumItem *a=new AlbumItem(artist, albumItem->data(), albumId,
+ artistItem->hasSort() ? artistItem->sortString() : QString(),
+ albumItem->hasSort() ? albumItem->sortString() : QString(),
+ albumItem->year());
a->setSongs(albumItem);
a->genres=albumItem->genres();
a->updated=true;
@@ -486,9 +434,10 @@
void AlbumsModel::setCover(const Song &song, const QImage &img, const QString &file)
{
#ifdef ENABLE_UBUNTU
- if (img.isNull() || file.isEmpty()) {
- return;
+ if (img.isNull()) {
+ if (!file.isEmpty()) return; //If empty, we need to execute the stuff below to set m_coverRequested to false
}
+
QList::Iterator it=items.begin();
QList::Iterator end=items.end();
QString artist=MusicLibraryItemRoot::artistName(song);
@@ -497,10 +446,12 @@
for (int row=0; it!=end; ++it, ++row) {
if ((*it)->artist==artist && (*it)->albumId()==albumId) {
if ((*it)->coverRequested) {
- (*it)->coverFile="file://"+file;
(*it)->coverRequested=false;
- QModelIndex idx=index(row, 0, QModelIndex());
- emit dataChanged(idx, idx);
+ if (!file.isEmpty()) {
+ (*it)->coverFile="file://"+file;
+ QModelIndex idx=index(row, 0, QModelIndex());
+ emit dataChanged(idx, idx);
+ }
}
return;
}
@@ -514,11 +465,11 @@
void AlbumsModel::coverLoaded(const Song &song, int s)
{
+ Q_UNUSED(s)
#ifdef ENABLE_UBUNTU
Q_UNUSED(song)
- Q_UNUSED(s)
#else
- if (s==iconSize() && !song.isArtistImageRequest()) {
+ if (!song.isArtistImageRequest()) {
QList::Iterator it=items.begin();
QList::Iterator end=items.end();
const QString &albumArtist=song.albumArtist();
@@ -572,7 +523,7 @@
#else
connect(Covers::self(), SIGNAL(loaded(Song,int)), this, SLOT(coverLoaded(Song,int)));
#endif
- update(MusicLibraryModel::self()->root());
+ update(MusicLibraryModel::self()->root(), false);
} else {
clear();
#ifdef ENABLE_UBUNTU
@@ -598,9 +549,10 @@
}
}
-AlbumsModel::AlbumItem::AlbumItem(const QString &ar, const QString &al, const QString &i, quint16 y)
+AlbumsModel::AlbumItem::AlbumItem(const QString &ar, const QString &al, const QString &i, const QString &arSort, const QString &alSort, quint16 y)
: artist(ar)
, album(al)
+ , albumSortString(alSort)
, id(i)
, year(y)
, updated(false)
@@ -611,8 +563,10 @@
, coverRequested(false)
#endif
{
- if (artist.startsWith(QLatin1String("The "))) {
- nonTheArtist=artist.mid(4);
+ if (!arSort.isEmpty()) {
+ artistSortString=arSort;
+ } else if (artist.startsWith(QLatin1String("The "))) {
+ artistSortString=artist.mid(4);
}
}
@@ -625,8 +579,8 @@
{
switch (sortAlbums) {
default:
- case Sort_AlbumArtist: {
- int compare=album.localeAwareCompare(o.album);
+ case Sort_AlbumArtist: {
+ int compare=sortAlbum().localeAwareCompare(o.sortAlbum());
if (0!=compare) {
return compare<0;
}
@@ -637,7 +591,7 @@
return year==o.year ? id.compare(o.id)<0 : yearget(coverSong(), iconSize());
- }
- return 0;
-}
#endif
const Song & AlbumsModel::AlbumItem::coverSong()
diff -Nru cantata-1.4.2.ds1/models/albumsmodel.h cantata-1.5.2.ds2/models/albumsmodel.h
--- cantata-1.4.2.ds1/models/albumsmodel.h 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/albumsmodel.h 2015-03-23 20:09:40.000000000 +0000
@@ -40,14 +40,6 @@
Q_OBJECT
public:
- #ifndef ENABLE_UBUNTU
- static MusicLibraryItemAlbum::CoverSize currentCoverSize();
- static void setCoverSize(MusicLibraryItemAlbum::CoverSize size);
- static int iconSize();
- static void setItemSize(const QSize &sz);
- static void setIconMode(bool u);
- #endif
-
enum Sort
{
Sort_AlbumArtist,
@@ -84,7 +76,7 @@
struct AlbumItem : public Item
{
- AlbumItem(const QString &ar, const QString &al, const QString &i, quint16 y);
+ AlbumItem(const QString &ar, const QString &al, const QString &i, const QString &arSort, const QString &alSort, quint16 y);
virtual ~AlbumItem();
bool operator<(const AlbumItem &o) const;
bool isAlbum() { return true; }
@@ -95,18 +87,18 @@
void updateStats();
#ifdef ENABLE_UBUNTU
QString cover();
- #else
- QPixmap *cover();
#endif
bool isSingleTracks() const { return Song::SingleTracks==type; }
const SongItem *getCueFile() const;
QString albumDisplay() const { return Song::displayAlbum(album, year); }
- const QString & sortArtist() const { return nonTheArtist.isEmpty() ? artist : nonTheArtist; }
+ const QString & sortArtist() const { return artistSortString.isEmpty() ? artist : artistSortString; }
+ const QString & sortAlbum() const { return albumSortString.isEmpty() ? album : albumSortString; }
const QString & albumId() const { return id.isEmpty() ? album : id; }
const Song & coverSong();
QString artist;
- QString nonTheArtist;
+ QString artistSortString;
QString album;
+ QString albumSortString;
QString id;
quint16 year;
QList songs;
@@ -154,7 +146,7 @@
void coverLoaded(const Song &song, int s);
// Touch version...
void setCover(const Song &song, const QImage &img, const QString &file);
- void update(const MusicLibraryItemRoot *root);
+ void update(const MusicLibraryItemRoot *root, bool incremental=true);
private:
bool enabled;
diff -Nru cantata-1.4.2.ds1/models/devicesmodel.cpp cantata-1.5.2.ds2/models/devicesmodel.cpp
--- cantata-1.4.2.ds1/models/devicesmodel.cpp 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/models/devicesmodel.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -71,8 +71,14 @@
#include "modeltest.h"
#endif
+
#include
-#define DBUG qDebug()
+static bool debugIsEnabled=false;
+#define DBUG if (debugIsEnabled) qWarning() << metaObject()->className() << __FUNCTION__
+void DevicesModel::enableDebug()
+{
+ debugIsEnabled=true;
+}
QString DevicesModel::fixDevicePath(const QString &path)
{
@@ -180,6 +186,8 @@
}
return v;
}
+ case Cantata::Role_ListImage:
+ return MusicLibraryItem::Type_Album==item->itemType();
default:
break;
}
@@ -272,11 +280,14 @@
void DevicesModel::setCover(const Song &song, const QImage &img, const QString &file)
{
#if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND
+ DBUG << "Set CDDA cover" << song.file << img.isNull() << file << song.isCdda();
if (song.isCdda()) {
int idx=indexOf(song.title);
if (idx>=0) {
Device *dev=static_cast(collections.at(idx));
if (Device::AudioCd==dev->devType()) {
+ DBUG << "Set cover of CD";
+ Covers::self()->updateCover(song, img, file);
static_cast(dev)->setCover(song, img, file);
}
}
@@ -290,10 +301,7 @@
void DevicesModel::setCover(const Song &song, const QImage &img)
{
- if (MusicLibraryItemAlbum::CoverNone==MusicLibraryItemAlbum::currentCoverSize()) {
- return;
- }
-
+ DBUG << "Set album cover" << song.file << img.isNull();
if (img.isNull()) {
return;
}
@@ -309,7 +317,9 @@
MusicLibraryItemArtist *artistItem = dev->artist(song, false);
if (artistItem) {
MusicLibraryItemAlbum *albumItem = artistItem->album(song, false);
- if (albumItem && albumItem->saveToCache(img)) {
+ if (albumItem) {
+ DBUG << "Set cover of album";
+ Covers::self()->updateCover(song, img, QString());
QModelIndex idx=index(albumItem->row(), 0, index(artistItem->row(), 0, index(i, 0, QModelIndex())));
emit dataChanged(idx, idx);
}
diff -Nru cantata-1.4.2.ds1/models/devicesmodel.h cantata-1.5.2.ds2/models/devicesmodel.h
--- cantata-1.4.2.ds1/models/devicesmodel.h 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/devicesmodel.h 2015-03-23 20:09:40.000000000 +0000
@@ -42,6 +42,7 @@
public:
static DevicesModel * self();
+ static void enableDebug();
static QString fixDevicePath(const QString &path);
DevicesModel(QObject *parent = 0);
diff -Nru cantata-1.4.2.ds1/models/digitallyimported.cpp cantata-1.5.2.ds2/models/digitallyimported.cpp
--- cantata-1.4.2.ds1/models/digitallyimported.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/digitallyimported.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -125,6 +125,22 @@
emit updated();
}
+bool DigitallyImported::isDiUrl(const QString &u) const
+{
+ if (!u.startsWith(QLatin1String("http://"))) {
+ return false;
+ }
+ QUrl url(u);
+ if (!url.host().startsWith(QLatin1String("listen."))) {
+ return false;
+ }
+ QStringList pathParts=url.path().split(QLatin1Char('/'), QString::SkipEmptyParts);
+ if (2!=pathParts.count()) {
+ return false;
+ }
+ return pathParts.at(0)==constPublicValue;
+}
+
QString DigitallyImported::modifyUrl(const QString &u) const
{
if (listenHash.isEmpty()) {
diff -Nru cantata-1.4.2.ds1/models/digitallyimported.h cantata-1.5.2.ds2/models/digitallyimported.h
--- cantata-1.4.2.ds1/models/digitallyimported.h 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/digitallyimported.h 2015-03-23 20:09:40.000000000 +0000
@@ -60,6 +60,7 @@
const QString & statusString() const { return status; }
+ bool isDiUrl(const QString &u) const;
QString modifyUrl(const QString &u) const;
public Q_SLOTS:
diff -Nru cantata-1.4.2.ds1/models/dirviewmodel.cpp cantata-1.5.2.ds2/models/dirviewmodel.cpp
--- cantata-1.4.2.ds1/models/dirviewmodel.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/dirviewmodel.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -204,6 +204,9 @@
case Qt::DisplayRole:
return item->data();
case Qt::ToolTipRole:
+ if (!Settings::self()->infoTooltips()) {
+ return QVariant();
+ }
return 0==item->childCount()
? item->data()
: item->data()+"\n"+Plurals::entries(item->childCount());
diff -Nru cantata-1.4.2.ds1/models/modeltest.cpp cantata-1.5.2.ds2/models/modeltest.cpp
--- cantata-1.4.2.ds1/models/modeltest.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/modeltest.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -472,7 +472,7 @@
*/
void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, int end )
{
-// Q_UNUSED(end);
+// Q_UNUSED(end)
// qDebug() << "rowsAboutToBeInserted" << "start=" << start << "end=" << end << "parent=" << model->data ( parent ).toString()
// << "current count of parent=" << model->rowCount ( parent ); // << "display of last=" << model->data( model->index(start-1, 0, parent) );
// qDebug() << model->index(start-1, 0, parent) << model->data( model->index(start-1, 0, parent) );
diff -Nru cantata-1.4.2.ds1/models/musiclibraryitemalbum.cpp cantata-1.5.2.ds2/models/musiclibraryitemalbum.cpp
--- cantata-1.4.2.ds1/models/musiclibraryitemalbum.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibraryitemalbum.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -42,92 +42,11 @@
#include
#include
-static MusicLibraryItemAlbum::CoverSize coverSize=MusicLibraryItemAlbum::CoverNone;
#ifdef ENABLE_UBUNTU
static const QString constDefaultCover=QLatin1String("qrc:/album.svg");
-#else
-static QPixmap *theDefaultIcon=0;
#endif
static bool dateSort=false;
-#ifndef ENABLE_UBUNTU
-static QSize iconItemSize;
-
-static inline int adjust(int v)
-{
- if (v>48) {
- static const int constStep=4;
- return (((int)(v/constStep))*constStep)+((v%constStep) ? constStep : 0);
- } else {
- return Icon::stdSize(v);
- }
-}
-
-static int fontHeight=16;
-
-void MusicLibraryItemAlbum::setup()
-{
- fontHeight=QApplication::fontMetrics().height();
-}
-
-int MusicLibraryItemAlbum::iconSize(MusicLibraryItemAlbum::CoverSize sz, bool iconMode)
-{
- if (CoverNone==sz) {
- return 0;
- }
-
- if (iconMode) {
- switch (sz) {
- case CoverSmall: return qMax(76, adjust((4.75*fontHeight)+0.5));
- default:
- case CoverMedium: return qMax(100, adjust((6.25*fontHeight)+0.5));
- case CoverLarge: return qMax(128, adjust(8*fontHeight));
- case CoverExtraLarge: return qMax(160, adjust(10*fontHeight));
- }
- } else {
- switch (sz) {
- case CoverSmall: return qMax(22, adjust((1.375*fontHeight)+0.5));
- default:
- case CoverMedium: return qMax(32, adjust(2*fontHeight));
- case CoverLarge: return qMax(48, adjust(3*fontHeight));
- case CoverExtraLarge: return qMax(64, adjust(4*fontHeight));
- }
- }
-}
-
-int MusicLibraryItemAlbum::iconSize(bool iconMode)
-{
- return MusicLibraryItemAlbum::iconSize(coverSize, iconMode);
-}
-
-void MusicLibraryItemAlbum::setItemSize(const QSize &sz)
-{
- iconItemSize=sz;
-}
-
-QSize MusicLibraryItemAlbum::itemSize()
-{
- return iconItemSize;
-}
-
-MusicLibraryItemAlbum::CoverSize MusicLibraryItemAlbum::currentCoverSize()
-{
- return coverSize;
-}
-
-void MusicLibraryItemAlbum::setCoverSize(MusicLibraryItemAlbum::CoverSize size)
-{
- if (size!=coverSize) {
- if (theDefaultIcon) {
- delete theDefaultIcon;
- theDefaultIcon=0;
- }
- MusicLibraryItemArtist::clearDefaultCover();
- coverSize=size;
- }
-}
-#endif
-
void MusicLibraryItemAlbum::setSortByDate(bool sd)
{
dateSort=sd;
@@ -148,13 +67,13 @@
}
if (!MusicLibraryItemAlbum::sortByDate() || aa->year()==ab->year()) {
- int compare=aa->data().localeAwareCompare(ab->data());
+ int compare=aa->sortString().localeAwareCompare(ab->sortString());
return compare==0 ? aa->id().compare(ab->id())<0 : compare<0;
}
return aa->year()year();
}
-MusicLibraryItemAlbum::MusicLibraryItemAlbum(const QString &data, const QString &original, const QString &mbId, quint32 year, MusicLibraryItemContainer *parent)
+MusicLibraryItemAlbum::MusicLibraryItemAlbum(const QString &data, const QString &original, const QString &mbId, quint32 year, const QString &sort, MusicLibraryItemContainer *parent)
: MusicLibraryItemContainer(data, parent)
, m_year(year)
, m_yearOfTrack(0xFFFF)
@@ -162,8 +81,11 @@
, m_totalTime(0)
, m_numTracks(0)
, m_originalName(original!=data ? original : QString())
+ , m_sortString(sort)
, m_id(mbId)
+ #ifdef ENABLE_UBUNTU
, m_coverRequested(false)
+ #endif
, m_type(Song::Standard)
{
}
@@ -181,94 +103,13 @@
const QString & MusicLibraryItemAlbum::cover() const
{
if (Song::SingleTracks!=m_type && m_coverName.isEmpty() && !m_coverRequested && childCount()) {
- MusicLibraryItemSong *firstSong=static_cast(childItem(0));
- Song song;
- song.artist=firstSong->song().artist;
- song.albumartist=Song::useComposer() && !firstSong->song().composer().isEmpty() ? firstSong->song().albumArtist() : parentItem()->data();
- song.album=Song::useComposer() ? firstSong->song().album : m_itemData;
- song.year=m_year;
- song.file=firstSong->file();
- song.type=m_type;
- song.setComposer(firstSong->song().composer());
- song.setMbAlbumId(firstSong->song().mbAlbumId());
- m_coverName=Covers::self()->requestImage(song).fileName;
+ m_coverName=Covers::self()->requestImage(coverSong()).fileName;
if (!m_coverName.isEmpty()) {
m_coverRequested=false;
}
}
-
return m_coverName.isEmpty() ? constDefaultCover : m_coverName;
}
-#else
-QPixmap *MusicLibraryItemAlbum::saveToCache(const QImage &img) const
-{
- int size=MusicLibraryItemAlbum::iconSize(largeImages());
- return Covers::self()->saveScaledCover(img.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation), coverSong(), size);
-}
-
-const QPixmap & MusicLibraryItemAlbum::cover() const
-{
- int iSize=iconSize(largeImages());
- if (Song::SingleTracks!=m_type && parentItem() && iSize && childCount()) {
- Song song=coverSong();
-
- QPixmap *pix=Covers::self()->getScaledCover(song, iSize);
- if (pix) {
- return *pix;
- }
-
- if (!m_coverRequested) {
- MusicLibraryItemSong *firstSong=static_cast(childItem(0));
- song.year=m_year;
- song.file=firstSong->file();
- song.type=m_type;
- song.setComposer(firstSong->song().composer());
- song.setMbAlbumId(firstSong->song().mbAlbumId());
- Covers::Image img;
- MusicLibraryItemRoot *root=parentItem() && parentItem()->parentItem() && MusicLibraryItem::Type_Root==parentItem()->parentItem()->itemType()
- ? static_cast(parentItem()->parentItem()) : 0;
- m_coverRequested=true;
- if (root && !root->useAlbumImages()) {
- // Not showing album images in this model, so dont request any!
- }
- #ifdef ENABLE_DEVICES_SUPPORT
- else if (root && root->isDevice()) {
- song.id=firstSong->song().id;
- static_cast(parentItem()->parentItem())->requestCover(song);
- }
- #endif
- #ifdef ENABLE_ONLINE_SERVICES
- else if (root && root->isOnlineService()) {
- img.img=OnlineServicesModel::self()->requestImage(static_cast(root)->id(), parentItem()->data(), data(), m_imageUrl);
- }
- #endif
- else {
- img=Covers::self()->requestImage(song);
- }
-
- if (!img.img.isNull()) {
- pix=saveToCache(img.img);
- if (pix) {
- return *pix;
- }
- }
- }
- }
-
- int cSize=iSize;
- if (0==cSize) {
- cSize=22;
- }
-
- if (!theDefaultIcon || theDefaultIcon->width()!=cSize) {
- if (theDefaultIcon) {
- delete theDefaultIcon;
- }
- theDefaultIcon = new QPixmap(Icons::self()->albumIcon.pixmap(cSize, cSize)
- .scaled(QSize(cSize, cSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
- }
- return *theDefaultIcon;
-}
#endif
quint32 MusicLibraryItemAlbum::totalTime()
@@ -429,12 +270,35 @@
Song MusicLibraryItemAlbum::coverSong() const
{
- MusicLibraryItemSong *firstSong=static_cast(childItem(0));
Song song;
- song.artist=firstSong->song().artist;
- song.albumartist=Song::useComposer() && !firstSong->song().composer().isEmpty() ? firstSong->song().albumArtist() : parentItem()->data();
- song.album=Song::useComposer() ? firstSong->song().album : m_itemData;
- song.setMbAlbumId(firstSong->song().mbAlbumId());
+ if (childCount()) {
+ MusicLibraryItemSong *firstSong=static_cast(childItem(0));
+ song.artist=firstSong->song().artist;
+ song.albumartist=Song::useComposer() && !firstSong->song().composer().isEmpty() ? firstSong->song().albumArtist() : parentItem()->data();
+ song.album=Song::useComposer() ? firstSong->song().album : m_itemData;
+ song.setMbAlbumId(firstSong->song().mbAlbumId());
+ song.setComposer(firstSong->song().composer());
+ song.year=m_year;
+ song.file=firstSong->file();
+ song.type=m_type;
+ #if defined ENABLE_ONLINE_SERVICES || defined ENABLE_DEVICES_SUPPORT
+ MusicLibraryItemRoot *root=parentItem() && parentItem()->parentItem() && MusicLibraryItem::Type_Root==parentItem()->parentItem()->itemType()
+ ? static_cast(parentItem()->parentItem()) : 0;
+ if (root) {
+ #ifdef ENABLE_ONLINE_SERVICES
+ if (root->isOnlineService()) {
+ song.setIsFromOnlineService(static_cast(root)->id());
+ song.setExtraField(Song::OnlineImageUrl, m_imageUrl);
+ }
+ #endif
+ #ifdef ENABLE_DEVICES_SUPPORT
+ if (root->isDevice()) {
+ song.setIsFromDevice(static_cast(root)->id());
+ }
+ #endif
+ }
+ #endif
+ }
return song;
}
@@ -449,9 +313,3 @@
Song::storeAlbumYear(song->song());
}
}
-
-bool MusicLibraryItemAlbum::largeImages() const
-{
- return m_parentItem && m_parentItem->parentItem() && Type_Root==m_parentItem->parentItem()->itemType() &&
- static_cast(m_parentItem->parentItem())->useLargeImages();
-}
diff -Nru cantata-1.4.2.ds1/models/musiclibraryitemalbum.h cantata-1.5.2.ds2/models/musiclibraryitemalbum.h
--- cantata-1.4.2.ds1/models/musiclibraryitemalbum.h 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibraryitemalbum.h 2015-03-23 20:09:40.000000000 +0000
@@ -40,38 +40,17 @@
class MusicLibraryItemAlbum : public MusicLibraryItemContainer
{
public:
- enum CoverSize
- {
- CoverNone = 0,
- CoverSmall = 1,
- CoverMedium = 2,
- CoverLarge = 3,
- CoverExtraLarge = 4
- };
-
- #ifndef ENABLE_UBUNTU
- static void setup();
- static CoverSize currentCoverSize();
- static void setCoverSize(CoverSize size);
- static int iconSize(MusicLibraryItemAlbum::CoverSize sz, bool iconMode=false);
- static int iconSize(bool iconMode=false);
- static void setItemSize(const QSize &sz);
- static QSize itemSize();
- #endif
static void setSortByDate(bool sd);
static bool sortByDate();
static bool lessThan(const MusicLibraryItem *a, const MusicLibraryItem *b);
- MusicLibraryItemAlbum(const QString &data, const QString &original, const QString &mbId, quint32 year, MusicLibraryItemContainer *parent);
+ MusicLibraryItemAlbum(const QString &data, const QString &original, const QString &mbId, quint32 year, const QString &sort, MusicLibraryItemContainer *parent);
virtual ~MusicLibraryItemAlbum();
QString displayData(bool full=false) const;
#ifdef ENABLE_UBUNTU
const QString & cover() const;
- #else
- QPixmap * saveToCache(const QImage &img) const;
- const QPixmap & cover() const;
#endif
quint32 year() const { return m_year; }
quint32 totalTime();
@@ -95,16 +74,17 @@
// Return orignal album name. If we are grouping by composer, then album will appear as "Album (Artist)"
const QString & originalName() const { return m_originalName; }
const QString & id() const { return m_id; }
- const QString & albumId() const { return m_id.isEmpty() ? m_id : m_originalName; }
+ const QString & albumId() const { return m_id.isEmpty() ? m_itemData : m_id; }
+ const QString & sortString() const { return m_sortString.isEmpty() ? m_itemData : m_sortString; }
+ bool hasSort() const { return !m_sortString.isEmpty(); }
#ifdef ENABLE_UBUNTU
void setCover(const QString &c) { m_coverName="file://"+c; m_coverRequested=false; }
const QString & coverName() { return m_coverName; }
#endif
-
-private:
Song coverSong() const;
+
+private:
void setYear(const MusicLibraryItemSong *song);
- bool largeImages() const;
void updateStats();
private:
@@ -114,10 +94,11 @@
quint32 m_totalTime;
quint32 m_numTracks;
QString m_originalName;
+ QString m_sortString;
QString m_id;
- mutable bool m_coverRequested;
mutable Song m_coverSong;
#ifdef ENABLE_UBUNTU
+ mutable bool m_coverRequested;
mutable QString m_coverName;
#endif
Song::Type m_type;
diff -Nru cantata-1.4.2.ds1/models/musiclibraryitemartist.cpp cantata-1.5.2.ds2/models/musiclibraryitemartist.cpp
--- cantata-1.4.2.ds1/models/musiclibraryitemartist.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibraryitemartist.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -50,42 +50,31 @@
if (aa->isVarious() != ab->isVarious()) {
return aa->isVarious() > ab->isVarious();
}
- return aa->baseArtist().localeAwareCompare(ab->baseArtist())<0;
+ return aa->sortString().localeAwareCompare(ab->sortString())<0;
}
#ifdef ENABLE_UBUNTU
static const QString constDefaultCover=QLatin1String("qrc:/artist.svg");
static const QString constDefaultVariousCover=QLatin1String("qrc:/variousartists.svg");
-#else
-static QPixmap *theDefaultIcon=0;
-static QPixmap *theVariousArtistsIcon=0;
#endif
-void MusicLibraryItemArtist::clearDefaultCover()
-{
- #ifndef ENABLE_UBUNTU
- if (theDefaultIcon) {
- delete theDefaultIcon;
- theDefaultIcon=0;
- }
- if (theVariousArtistsIcon) {
- delete theVariousArtistsIcon;
- theVariousArtistsIcon=0;
- }
- #endif
-}
-
-MusicLibraryItemArtist::MusicLibraryItemArtist(const QString &data, const QString &artistName, MusicLibraryItemContainer *parent)
+MusicLibraryItemArtist::MusicLibraryItemArtist(const QString &data, const QString &artistName, const QString &artistSort, MusicLibraryItemContainer *parent)
: MusicLibraryItemContainer(data, parent)
#ifdef ENABLE_UBUNTU
, m_coverRequested(false)
#endif
, m_various(false)
+ , m_haveSort(false)
, m_actualArtist(artistName==data ? QString() : artistName)
{
- if (m_itemData.startsWith(QLatin1String("The "))) {
- m_nonTheArtist=m_itemData.mid(4);
- } else if (Song::isVariousArtists(m_itemData)) {
+ if (!artistSort.isEmpty()) {
+ m_sortString=artistSort;
+ m_haveSort=true;
+ } else if (m_itemData.startsWith(QLatin1String("The "))) {
+ m_sortString=m_itemData.mid(4);
+ }
+
+ if (Song::isVariousArtists(m_itemData)) {
m_various=true;
}
}
@@ -98,21 +87,8 @@
}
if (m_coverName.isEmpty() && !m_coverRequested && childCount()) {
- Song coverSong;
- coverSong.albumartist=coverSong.title=m_itemData; // If title is empty, then Song::isUnknown() will be true!!!
-
- MusicLibraryItemAlbum *firstAlbum=static_cast(childItem(0));
- MusicLibraryItemSong *firstSong=firstAlbum ? static_cast(firstAlbum->childItem(0)) : 0;
-
- if (firstSong) {
- coverSong.file=firstSong->file();
- if (Song::useComposer() && !firstSong->song().composer().isEmpty()) {
- coverSong.albumartist=firstSong->song().albumArtist();
- }
- }
- coverSong.setArtistImageRequest();
m_coverRequested=true;
- m_coverName=Covers::self()->requestImage(coverSong).fileName;
+ m_coverName=Covers::self()->requestImage(coverSong()).fileName;
if (!m_coverName.isEmpty()) {
m_coverRequested=false;
}
@@ -120,64 +96,20 @@
return m_coverName.isEmpty() ? constDefaultCover : m_coverName;
}
-#else
-const QPixmap & MusicLibraryItemArtist::cover() const
-{
- int iSize=MusicLibraryItemAlbum::iconSize(largeImages());
- int cSize=iSize;
- if (0==cSize) {
- cSize=22;
- }
- if (m_various) {
- if (!theVariousArtistsIcon || theVariousArtistsIcon->width()!=cSize) {
- if (theVariousArtistsIcon) {
- delete theVariousArtistsIcon;
- }
- theVariousArtistsIcon = new QPixmap(Icons::self()->variousArtistsIcon.pixmap(cSize, cSize)
- .scaled(QSize(cSize, cSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
- }
- return *theVariousArtistsIcon;
- }
-
- if (m_coverSong.isEmpty()) {
- m_coverSong.albumartist=m_coverSong.title=m_itemData; // If title is empty, then Song::isUnknown() will be true!!!
-
- MusicLibraryItemAlbum *firstAlbum=static_cast(childItem(0));
- MusicLibraryItemSong *firstSong=firstAlbum ? static_cast(firstAlbum->childItem(0)) : 0;
-
- if (firstSong) {
- m_coverSong.file=firstSong->file();
- if (Song::useComposer() && !firstSong->song().composer().isEmpty()) {
- m_coverSong.albumartist=firstSong->song().albumArtist();
- }
- }
- m_coverSong.setArtistImageRequest();
- }
-
- QPixmap *pix=Covers::self()->get(m_coverSong, iSize);
- if (pix) {
- return *pix;
- }
- if (!theDefaultIcon || theDefaultIcon->width()!=cSize) {
- if (theDefaultIcon) {
- delete theDefaultIcon;
- }
- theDefaultIcon = new QPixmap(Icons::self()->artistIcon.pixmap(cSize, cSize)
- .scaled(QSize(cSize, cSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+void MusicLibraryItemArtist::setCover(const QString &c)
+{
+ if (!c.isEmpty()) {
+ m_coverName="file://"+c;
}
- return *theDefaultIcon;
+ m_coverRequested=false;
}
#endif
MusicLibraryItemAlbum * MusicLibraryItemArtist::album(const Song &s, bool create)
{
- QHash::ConstIterator it=m_indexes.find(s.albumId());
-
- if (m_indexes.end()==it) {
- return create ? createAlbum(s) : 0;
- }
- return static_cast(m_childItems.at(*it));
+ MusicLibraryItemAlbum *albumItem=getAlbum(s.albumId());
+ return albumItem ? albumItem : (create ? createAlbum(s) : 0);
}
MusicLibraryItemAlbum * MusicLibraryItemArtist::createAlbum(const Song &s)
@@ -186,17 +118,12 @@
// So, when creating an album entry we need to use the "Album (Artist)" value for display/sort, and still store just
// "Album" (for saving to cache, tag editing, etc.)
QString albumId=s.albumId();
- MusicLibraryItemAlbum *item=new MusicLibraryItemAlbum(s.albumName(), s.album, s.mbAlbumId(), s.year, this);
+ MusicLibraryItemAlbum *item=new MusicLibraryItemAlbum(s.albumName(), s.album, s.mbAlbumId(), s.year, s.albumSort(), this);
m_indexes.insert(albumId, m_childItems.count());
m_childItems.append(item);
return item;
}
-const QString & MusicLibraryItemArtist::baseArtist() const
-{
- return m_nonTheArtist.isEmpty() ? m_itemData : m_nonTheArtist;
-}
-
bool MusicLibraryItemArtist::allSingleTrack() const
{
foreach (MusicLibraryItem *a, m_childItems) {
@@ -223,12 +150,8 @@
return true;
}
- QHash::ConstIterator it=m_indexes.find(i18n("Single Tracks"));
-
- if (m_indexes.end()!=it) {
- return static_cast(m_childItems.at(*it))->isSingleTrackFile(s);
- }
- return false;
+ MusicLibraryItemAlbum *st=getAlbum(i18n("Single Tracks"));
+ return st && st->isSingleTrackFile(s);
}
void MusicLibraryItemArtist::remove(MusicLibraryItemAlbum *album)
@@ -247,23 +170,66 @@
(*it)--;
}
}
- m_indexes.remove(album->data());
+ m_indexes.remove(album->albumId());
delete m_childItems.takeAt(index);
resetRows();
}
-void MusicLibraryItemArtist::updateIndexes()
+Song MusicLibraryItemArtist::coverSong() const
{
- m_indexes.clear();
- QList::iterator it=m_childItems.begin();
- QList::iterator end=m_childItems.end();
- for (int i=0; it!=end; ++it, ++i) {
- m_indexes.insert((*it)->data(), i);
+ Song song;
+ song.albumartist=song.title=m_itemData; // If title is empty, then Song::isUnknown() will be true!!!
+
+ if (childCount()) {
+ MusicLibraryItemAlbum *firstAlbum=static_cast(childItem(0));
+ MusicLibraryItemSong *firstSong=firstAlbum ? static_cast(firstAlbum->childItem(0)) : 0;
+
+ if (firstSong) {
+ song.file=firstSong->file();
+ if (Song::useComposer() && !firstSong->song().composer().isEmpty()) {
+ song.albumartist=firstSong->song().albumArtist();
+ }
+ }
}
+ song.setArtistImageRequest();
+ return song;
}
-bool MusicLibraryItemArtist::largeImages() const
+MusicLibraryItemAlbum * MusicLibraryItemArtist::getAlbum(const QString &key) const
{
- return m_parentItem && Type_Root==m_parentItem->itemType() &&
- static_cast(m_parentItem)->useLargeImages();
+ if (m_indexes.count()==m_childItems.count()) {
+ if (m_childItems.isEmpty()) {
+ return 0;
+ }
+
+ QHash::ConstIterator idx=m_indexes.find(key);
+
+ if (m_indexes.end()==idx) {
+ return 0;
+ }
+
+ // Check index value is within range
+ if (*idx>=0 && *idx(m_childItems.at(*idx));
+ // Check id actually matches!
+ if (a->albumId()==key) {
+ return a;
+ }
+ }
+ }
+
+ // Something wrong with m_indexes??? So, refresh them...
+ MusicLibraryItemAlbum *al=0;
+ m_indexes.clear();
+ QList::ConstIterator it=m_childItems.constBegin();
+ QList::ConstIterator end=m_childItems.constEnd();
+ for (int i=0; it!=end; ++it, ++i) {
+ MusicLibraryItemAlbum *currenAlbum=static_cast(*it);
+ if (!al && currenAlbum->albumId()==key) {
+ al=currenAlbum;
+ }
+ m_indexes.insert(currenAlbum->albumId(), i);
+ }
+ return al;
}
+
diff -Nru cantata-1.4.2.ds1/models/musiclibraryitemartist.h cantata-1.5.2.ds2/models/musiclibraryitemartist.h
--- cantata-1.4.2.ds1/models/musiclibraryitemartist.h 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibraryitemartist.h 2015-03-23 20:09:40.000000000 +0000
@@ -42,46 +42,43 @@
public:
static bool lessThan(const MusicLibraryItem *a, const MusicLibraryItem *b);
- MusicLibraryItemArtist(const QString &data, const QString &artistName, MusicLibraryItemContainer *parent = 0);
+ MusicLibraryItemArtist(const QString &data, const QString &artistName, const QString &artistSort, MusicLibraryItemContainer *parent = 0);
virtual ~MusicLibraryItemArtist() { }
MusicLibraryItemAlbum * album(const Song &s, bool create=true);
MusicLibraryItemAlbum * createAlbum(const Song &s);
- const QString & baseArtist() const;
+ const QString & sortString() const { return m_sortString.isEmpty() ? m_itemData : m_sortString; }
+ bool hasSort() const { return m_haveSort && !m_sortString.isEmpty(); }
bool isVarious() const { return m_various; }
bool allSingleTrack() const;
void addToSingleTracks(MusicLibraryItemArtist *other);
bool isFromSingleTracks(const Song &s) const;
void remove(MusicLibraryItemAlbum *album);
- void updateIndexes();
Type itemType() const { return Type_Artist; }
- static void clearDefaultCover();
#ifdef ENABLE_UBUNTU
const QString & cover() const;
- #else
- const QPixmap & cover() const;
#endif
// 'data' could be 'Composer' if we are set to use that, but need to save real artist...
const QString & actualArtist() const { return m_actualArtist; }
#ifdef ENABLE_UBUNTU
- void setCover(const QString &c) { m_coverName="file://"+c; m_coverRequested=false; }
+ void setCover(const QString &c);
const QString & coverName() { return m_coverName; }
#endif
-
+ Song coverSong() const;
+
private:
- bool largeImages() const;
+ MusicLibraryItemAlbum * getAlbum(const QString &key) const;
private:
#ifdef ENABLE_UBUNTU
mutable QString m_coverName;
mutable bool m_coverRequested;
- #else
- mutable Song m_coverSong;
#endif
bool m_various;
- QString m_nonTheArtist;
+ bool m_haveSort;
+ QString m_sortString; // Do we have an actual artist-sort, or is m_sortString just "Artist, The" ??? - needed for cache saving
QString m_actualArtist;
- QHash m_indexes;
+ mutable QHash m_indexes;
};
#endif
diff -Nru cantata-1.4.2.ds1/models/musiclibraryitempodcast.cpp cantata-1.5.2.ds2/models/musiclibraryitempodcast.cpp
--- cantata-1.4.2.ds1/models/musiclibraryitempodcast.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibraryitempodcast.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -33,6 +33,7 @@
#include "support/utils.h"
#include "gui/covers.h"
#include "online/rssparser.h"
+#include "online/podcastservice.h"
#include
#include
#include
@@ -40,8 +41,6 @@
#include
#include
-static QPixmap *theDefaultIcon=0;
-
static QLatin1String constTopTag("podcast");
static QLatin1String constImageAttribute("img");
static QLatin1String constRssAttribute("rss");
@@ -76,8 +75,6 @@
MusicLibraryItemPodcast::MusicLibraryItemPodcast(const QString &fileName, MusicLibraryItemContainer *parent)
: MusicLibraryItemContainer(QString(), parent)
- , m_coverRequested(false)
- , m_cover(0)
, m_fileName(fileName)
, m_unplayedEpisodeCount(0)
{
@@ -229,58 +226,20 @@
return true;
}
-void MusicLibraryItemPodcast::setCoverImage(const QImage &img) const
-{
- if (m_cover) {
- delete m_cover;
- }
- int size=MusicLibraryItemAlbum::iconSize(largeImages());
- QImage scaled=img.scaled(QSize(size, size), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- m_cover = new QPixmap(QPixmap::fromImage(scaled));
- m_coverRequested=false;
-}
-
-bool MusicLibraryItemPodcast::setCover(const QImage &img, bool update) const
-{
- if ((update || m_coverRequested) && !img.isNull()) {
- setCoverImage(img);
- return true;
- }
-
- return false;
-}
-
-const QPixmap & MusicLibraryItemPodcast::cover() const
+Song MusicLibraryItemPodcast::coverSong() const
{
- if (m_cover) {
- return *m_cover;
- }
-
- int iSize=MusicLibraryItemAlbum::iconSize(largeImages());
- int cSize=iSize;
- if (0==cSize) {
- cSize=22;
- }
-
- if (!m_cover && !m_coverRequested) {
- m_coverRequested = true;
- QImage img=OnlineServicesModel::self()->requestImage(static_cast(parentItem())->id(), data(), QString(), m_imageUrl.toString(), // ??
- m_imageFile, 300);
-
- if (!img.isNull()) {
- setCoverImage(img);
- return *m_cover;
- }
+ Song song;
+ if (childCount()) {
+ song.artist=PodcastService::constName;
+ song.album=data();
+ song.title=data();
+ song.type=Song::OnlineSvrTrack;
+ song.setIsFromOnlineService(PodcastService::constName);
+ song.setExtraField(Song::OnlineImageUrl, m_imageUrl.toString());
+ song.setExtraField(Song::OnlineImageCacheName, m_imageFile);
+ song.file=m_rssUrl.toString();
}
-
- if (!theDefaultIcon || theDefaultIcon->width()!=cSize) {
- if (theDefaultIcon) {
- delete theDefaultIcon;
- }
- theDefaultIcon = new QPixmap(Icons::self()->podcastIcon.pixmap(cSize, cSize)
- .scaled(QSize(cSize, cSize), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
- }
- return *theDefaultIcon;
+ return song;
}
void MusicLibraryItemPodcast::remove(int row)
@@ -297,14 +256,6 @@
}
}
-void MusicLibraryItemPodcast::clearImage() const
-{
- if (m_cover) {
- delete m_cover;
- m_cover=0;
- }
-}
-
void MusicLibraryItemPodcast::removeFiles()
{
if (!m_fileName.isEmpty() && QFile::exists(m_fileName)) {
@@ -325,11 +276,15 @@
}
}
-void MusicLibraryItemPodcast::setPlayed(MusicLibraryItemSong *song)
+void MusicLibraryItemPodcast::setPlayed(MusicLibraryItemSong *song, bool played)
{
- if (!song->song().hasBeenPlayed()) {
- song->setPlayed(true);
- m_unplayedEpisodeCount--;
+ if (played!=song->song().hasBeenPlayed()) {
+ song->setPlayed(played);
+ if (played) {
+ m_unplayedEpisodeCount--;
+ } else {
+ m_unplayedEpisodeCount++;
+ }
}
}
@@ -351,12 +306,6 @@
return 0;
}
-bool MusicLibraryItemPodcast::largeImages() const
-{
- return m_parentItem && Type_Root==m_parentItem->itemType() &&
- static_cast(m_parentItem)->useLargeImages();
-}
-
const QString & MusicLibraryItemPodcastEpisode::published()
{
if (publishedDate.isEmpty()) {
diff -Nru cantata-1.4.2.ds1/models/musiclibraryitempodcast.h cantata-1.5.2.ds2/models/musiclibraryitempodcast.h
--- cantata-1.4.2.ds1/models/musiclibraryitempodcast.h 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibraryitempodcast.h 2015-03-23 20:09:40.000000000 +0000
@@ -58,30 +58,25 @@
bool load();
RssStatus loadRss(QNetworkReply *dev);
bool save();
- bool setCover(const QImage &img, bool update=false) const;
- const QPixmap & cover() const;
void remove(int row);
void remove(MusicLibraryItemSong *i);
Type itemType() const { return Type_Podcast; }
const QUrl & imageUrl() const { return m_imageUrl; }
void setImageUrl(const QString &u) { m_imageUrl=u; }
- void clearImage() const;
const QUrl & rssUrl() const { return m_rssUrl; }
void removeFiles();
void setUnplayedCount();
quint32 unplayedEpisodes() const { return m_unplayedEpisodeCount; }
- void setPlayed(MusicLibraryItemSong *song);
+ void setPlayed(MusicLibraryItemSong *song, bool played=true);
void addAll(const QList &others);
MusicLibraryItemPodcastEpisode * getEpisode(const QString &file) const;
+ Song coverSong() const;
private:
- void setCoverImage(const QImage &img) const;
- bool largeImages() const;
void updateStats();
private:
mutable bool m_coverRequested;
- mutable QPixmap *m_cover;
QUrl m_imageUrl;
QUrl m_rssUrl;
QString m_fileName;
@@ -92,8 +87,13 @@
class MusicLibraryItemPodcastEpisode : public MusicLibraryItemSong
{
public:
+ enum DownloadState {
+ NotDownloading = -1,
+ QueuedForDownload = -2
+ };
+
MusicLibraryItemPodcastEpisode(const Song &s, MusicLibraryItemContainer *parent)
- : MusicLibraryItemSong(s, parent), downloadProg(-1) { }
+ : MusicLibraryItemSong(s, parent), downloadProg(NotDownloading) { }
virtual ~MusicLibraryItemPodcastEpisode() { }
const QString & published();
diff -Nru cantata-1.4.2.ds1/models/musiclibraryitemroot.cpp cantata-1.5.2.ds2/models/musiclibraryitemroot.cpp
--- cantata-1.4.2.ds1/models/musiclibraryitemroot.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibraryitemroot.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -45,18 +45,14 @@
MusicLibraryItemArtist * MusicLibraryItemRoot::artist(const Song &s, bool create)
{
QString aa=songArtist(s);
- QHash::ConstIterator it=m_indexes.find(aa);
-
- if (m_indexes.end()==it) {
- return create ? createArtist(s) : 0;
- }
- return static_cast(m_childItems.at(*it));
+ MusicLibraryItemArtist *artistItem=getArtist(aa);
+ return artistItem ? artistItem : (create ? createArtist(s) : 0);
}
MusicLibraryItemArtist * MusicLibraryItemRoot::createArtist(const Song &s)
{
QString aa=songArtist(s);
- MusicLibraryItemArtist *item=new MusicLibraryItemArtist(aa, Song::Standard==s.type ? s.albumArtist() : QString(), this);
+ MusicLibraryItemArtist *item=new MusicLibraryItemArtist(aa, Song::Standard==s.type ? s.albumArtist() : QString(), s.artistSortString(), this);
m_indexes.insert(aa, m_childItems.count());
m_childItems.append(item);
return item;
@@ -75,12 +71,10 @@
for (; it!=m_childItems.end(); ) {
if (various!=(*it) && static_cast(*it)->allSingleTrack()) {
if (!various) {
- QHash::ConstIterator it=m_indexes.find(Song::variousArtists());
- if (m_indexes.end()==it) {
- various=new MusicLibraryItemArtist(Song::variousArtists(), QString(), this);
+ various=getArtist(Song::variousArtists());
+ if (!various) {
+ various=new MusicLibraryItemArtist(Song::variousArtists(), QString(), QString(), this);
created=true;
- } else {
- various=static_cast(m_childItems.at(*it));
}
}
various->addToSingleTracks(static_cast(*it));
@@ -92,26 +86,18 @@
}
if (various) {
- m_indexes.clear();
if (created) {
m_childItems.append(various);
}
- it=m_childItems.begin();
- QList::iterator end=m_childItems.end();
- for (int i=0; it!=end; ++it, ++i) {
- m_indexes.insert((*it)->data(), i);
- }
+ refreshIndexes();
}
}
bool MusicLibraryItemRoot::isFromSingleTracks(const Song &s) const
{
if (!isFlat && (supportsAlbumArtist && !s.file.isEmpty())) {
- QHash::ConstIterator it=m_indexes.find(Song::variousArtists());
-
- if (m_indexes.end()!=it) {
- return static_cast(m_childItems.at(*it))->isFromSingleTracks(s);
- }
+ MusicLibraryItemArtist *various=getArtist(Song::variousArtists());
+ return various && various->isFromSingleTracks(s);
}
return false;
}
@@ -265,6 +251,7 @@
static const QString constAlbumElement=QLatin1String("Album");
static const QString constTrackElement=QLatin1String("Track");
static const QString constNameAttribute=QLatin1String("name");
+static const QString constSortAttribute=QLatin1String("sort");
static const QString constArtistAttribute=QLatin1String("artist");
static const QString constAlbumArtistAttribute=QLatin1String("albumartist");
static const QString constComposerAttribute=QLatin1String("composer");
@@ -338,6 +325,9 @@
if (!artist->actualArtist().isEmpty()) {
writer.writeAttribute(constActualAttribute, artist->actualArtist());
}
+ if (artist->hasSort()) {
+ writer.writeAttribute(constSortAttribute, artist->sortString());
+ }
foreach (const MusicLibraryItem *al, artist->childItems()) {
if (prog && prog->wasStopped()) {
return;
@@ -359,6 +349,9 @@
if (!album->id().isEmpty()) {
writer.writeAttribute(constMbIdAttribute, album->id());
}
+ if (album->hasSort()) {
+ writer.writeAttribute(constSortAttribute, album->sortString());
+ }
QString artistName=artist->actualArtist().isEmpty() ? artist->data() : artist->actualArtist();
foreach (const MusicLibraryItem *t, album->childItems()) {
@@ -447,7 +440,7 @@
#endif
return rv;
}
-#include
+
quint32 MusicLibraryItemRoot::fromXML(QXmlStreamReader &reader, const QDateTime &date, bool *dateUnreliable, const QString &baseFolder, MusicLibraryProgressMonitor *prog)
{
if (isFlat) {
@@ -502,12 +495,14 @@
song.artist=song.albumartist=actual;
song.setComposer(attributes.value(constNameAttribute).toString());
}
+ song.setAlbumArtistSort(attributes.value(constSortAttribute).toString());
artistItem = createArtist(song);
} else if (constAlbumElement==element) {
song.album=attributes.value(constNameAttribute).toString();
song.year=attributes.value(constYearAttribute).toString().toUInt();
song.genre=attributes.value(constGenreAttribute).toString();
song.setMbAlbumId(attributes.value(constMbIdAttribute).toString());
+ song.setAlbumSort(attributes.value(constSortAttribute).toString());
if (!song.file.isEmpty()) {
song.file.append("dummy.mp3");
}
@@ -952,3 +947,41 @@
return artistName(s);
}
+
+MusicLibraryItemArtist * MusicLibraryItemRoot::getArtist(const QString &key) const
+{
+ if (m_indexes.count()==m_childItems.count()) {
+ if (m_childItems.isEmpty()) {
+ return 0;
+ }
+
+ QHash::ConstIterator idx=m_indexes.find(key);
+
+ if (m_indexes.end()==idx) {
+ return 0;
+ }
+
+ // Check index value is within range
+ if (*idx>=0 && *idx(m_childItems.at(*idx));
+ // Check id actually matches!
+ if (a->data()==key) {
+ return a;
+ }
+ }
+ }
+
+ // Something wrong with m_indexes??? So, refresh them...
+ MusicLibraryItemArtist *ar=0;
+ m_indexes.clear();
+ QList::ConstIterator it=m_childItems.constBegin();
+ QList::ConstIterator end=m_childItems.constEnd();
+ for (int i=0; it!=end; ++it, ++i) {
+ MusicLibraryItemArtist *currenArtist=static_cast(*it);
+ if (!ar && currenArtist->data()==key) {
+ ar=currenArtist;
+ }
+ m_indexes.insert(currenArtist->data(), i);
+ }
+ return ar;
+}
diff -Nru cantata-1.4.2.ds1/models/musiclibraryitemroot.h cantata-1.5.2.ds2/models/musiclibraryitemroot.h
--- cantata-1.4.2.ds1/models/musiclibraryitemroot.h 2014-09-28 16:30:12.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibraryitemroot.h 2015-03-23 20:09:41.000000000 +0000
@@ -59,9 +59,6 @@
MusicLibraryItemRoot(const QString &name=QString(), bool albumArtistSupport=true, bool flatHierarchy=false)
: MusicLibraryItemContainer(name, 0)
, supportsAlbumArtist(albumArtistSupport)
- , albumImages(true)
- , artistImages(false)
- , largeImages(false)
, isFlat(flatHierarchy)
, m_model(0) {
}
@@ -92,12 +89,6 @@
void add(const QSet &songs);
bool supportsAlbumArtistTag() const { return supportsAlbumArtist; }
void setSupportsAlbumArtistTag(bool s) { supportsAlbumArtist=s; }
- bool useAlbumImages() const { return albumImages; }
- void setUseAlbumImages(bool a) { albumImages=a; }
- bool useArtistImages() const { return artistImages; }
- void setUseArtistImages(bool a) { artistImages=a; }
- bool useLargeImages() const { return largeImages; }
- void setLargeImages(bool a) { largeImages=a; }
virtual void toggleGrouping();
void applyGrouping();
void clearItems();
@@ -115,14 +106,12 @@
protected:
QString songArtist(const Song &s) const;
+ MusicLibraryItemArtist * getArtist(const QString &key) const;
protected:
bool supportsAlbumArtist; // TODO: ALBUMARTIST: Remove when libMPT supports album artist!
- bool albumImages:1;
- bool artistImages:1;
- bool largeImages:1;
- bool isFlat:1;
- QHash m_indexes;
+ bool isFlat;
+ mutable QHash m_indexes;
MusicModel *m_model;
};
diff -Nru cantata-1.4.2.ds1/models/musiclibraryitemsong.cpp cantata-1.5.2.ds2/models/musiclibraryitemsong.cpp
--- cantata-1.4.2.ds1/models/musiclibraryitemsong.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibraryitemsong.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -56,12 +56,12 @@
{
// Reduce memory usage by only storing genres in a set if required...
if (0==m_genres) {
- QSet g=m_song.genre.split(QLatin1Char(';'), QString::SkipEmptyParts).toSet();
+ QStringList g=m_song.genres();
if (g.count()<2) {
m_genres=(QSet *)1;
} else {
m_genres=new QSet();
- *m_genres=g;
+ *m_genres=g.toSet();
}
}
}
diff -Nru cantata-1.4.2.ds1/models/musiclibrarymodel.cpp cantata-1.5.2.ds2/models/musiclibrarymodel.cpp
--- cantata-1.4.2.ds1/models/musiclibrarymodel.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibrarymodel.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -33,6 +33,7 @@
#include "playqueuemodel.h"
#include "dirviewmodel.h"
#include "config.h"
+#include "roles.h"
#include "gui/covers.h"
#include "mpd/mpdparseutils.h"
#include "mpd/mpdconnection.h"
@@ -133,6 +134,7 @@
: MusicModel(parent)
, mpdModel(isMpdModel)
, checkable(isCheckable)
+ , artistImages(false)
, rootItem(new MusicLibraryItemRoot)
, databaseTimeUnreliable(false)
{
@@ -160,6 +162,20 @@
delete rootItem;
}
+void MusicLibraryModel::readConfig()
+{
+ #ifndef ENABLE_UBUNTU
+ bool aa=Settings::self()->libraryArtistImage();
+ if (aa!=artistImages) {
+ artistImages=aa;
+ for (int r=0; rchildItem(r));
+ emit dataChanged(index, index);
+ }
+ }
+ #endif
+}
+
QModelIndex MusicLibraryModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent)) {
@@ -234,6 +250,12 @@
return f;
}
}
+
+ if (Cantata::Role_ListImage==role && artistImages) {
+ MusicLibraryItem *item = static_cast(index.internalPointer());
+ return MusicLibraryItem::Type_Album==item->itemType() || MusicLibraryItem::Type_Artist==item->itemType();
+ }
+
return MusicModel::data(index, role);
}
@@ -348,14 +370,11 @@
databaseTime = QDateTime();
rootItem = new MusicLibraryItemRoot;
rootItem->setModel(this);
- rootItem->setLargeImages(oldRoot->useLargeImages());
- rootItem->setUseAlbumImages(oldRoot->useAlbumImages());
- rootItem->setUseArtistImages(oldRoot->useArtistImages());
delete oldRoot;
endResetModel();
if (mpdModel) {
- AlbumsModel::self()->update(rootItem);
+ AlbumsModel::self()->update(rootItem, false);
}
}
@@ -465,8 +484,6 @@
return;
}
- newroot->setUseAlbumImages(rootItem->useAlbumImages());
- newroot->setUseArtistImages(rootItem->useArtistImages());
bool updatedSongs=false;
bool needToSave=!databaseTime.isValid() || (validCacheDate(dbUpdate) && dbUpdate>databaseTime);
bool incremental=rootItem->childCount() && newroot->childCount();
@@ -487,9 +504,6 @@
beginResetModel();
rootItem = newroot;
rootItem->setModel(this);
- rootItem->setLargeImages(oldRoot->useLargeImages());
- rootItem->setUseAlbumImages(oldRoot->useAlbumImages());
- rootItem->setUseArtistImages(oldRoot->useArtistImages());
delete oldRoot;
endResetModel();
updatedSongs=true;
@@ -512,7 +526,7 @@
rootItem->toXML(cacheFileName(), databaseTime, databaseTimeUnreliable);
}
- AlbumsModel::self()->update(rootItem);
+ AlbumsModel::self()->update(rootItem, incremental);
emit updateGenres(rootItem->genres());
#ifdef ENABLE_UBUNTU
if (updatedSongs) {
@@ -536,16 +550,19 @@
void MusicLibraryModel::setArtistImage(const Song &song, const QImage &img, const QString &file)
{
#ifdef ENABLE_UBUNTU
- if (!rootItem->useArtistImages() || img.isNull() || file.isEmpty() ||
- song.file.startsWith("http://") || song.name().startsWith("http://")) {
- return;
+
+ if (img.isNull() || song.file.startsWith("http://") || song.name().startsWith("http://")) {
+ if (!file.isEmpty()) return; //If empty, we need to execute the stuff below to set m_coverRequested to false
}
MusicLibraryItemArtist *artistItem = rootItem->artist(song, false);
+
if (artistItem && artistItem->coverName().isEmpty()) {
- artistItem->setCover(file);
- QModelIndex idx=index(artistItem->row(), 0, QModelIndex());
- emit dataChanged(idx, idx);
+ artistItem->setCover(file); //Always execute to set m_coverRequested to false
+ if (!file.isEmpty()) {
+ QModelIndex idx=index(artistItem->row(), 0, QModelIndex());
+ emit dataChanged(idx, idx);
+ }
}
#else
Q_UNUSED(song)
@@ -652,7 +669,7 @@
rootItem->toXML(cacheFileName(), databaseTime, databaseTimeUnreliable);
endResetModel();
if (mpdModel) {
- AlbumsModel::self()->update(rootItem);
+ AlbumsModel::self()->update(rootItem, false);
}
}
@@ -714,66 +731,61 @@
// Currently ONLY artist images are always loaded from non UI thread.
void MusicLibraryModel::coverLoaded(const Song &song, int size)
{
- if (
- #ifndef ENABLE_UBUNTU
- MusicLibraryItemAlbum::CoverNone==MusicLibraryItemAlbum::currentCoverSize() || size!=MusicLibraryItemAlbum::iconSize(rootItem->useLargeImages()) ||
- #endif
- //song.isCdda() || (song.isArtistImageRequest() && !rootItem->useArtistImages()) ||
- song.isCdda() || !song.isArtistImageRequest() || !rootItem->useArtistImages() ||
- song.file.startsWith("http://") || song.name().startsWith("http://")) {
+ Q_UNUSED(size)
+ #ifdef ENABLE_ONLINE_SERVICES
+ if (song.isFromOnlineService()) {
+ return;
+ }
+ #endif
+ if (song.isCdda() || song.file.startsWith("http://") || song.name().startsWith("http://")) {
return;
}
- //if (song.isArtistImageRequest()) {
+ if (song.isArtistImageRequest()) {
MusicLibraryItemArtist *artistItem = rootItem->artist(song, false);
if (artistItem) {
QModelIndex idx=index(artistItem->row(), 0, QModelIndex());
emit dataChanged(idx, idx);
}
-// } else {
-// MusicLibraryItemArtist *artistItem = rootItem->artist(song, false);
-// if (artistItem) {
-// MusicLibraryItemAlbum *albumItem = artistItem->album(song, false);
-// if (albumItem) {
-// QModelIndex idx=index(albumItem->row(), 0, index(artistItem->row(), 0, QModelIndex()));
-// emit dataChanged(idx, idx);
-// }
-// }
-// }
+ } else {
+ MusicLibraryItemArtist *artistItem = rootItem->artist(song, false);
+ if (artistItem) {
+ MusicLibraryItemAlbum *albumItem = artistItem->album(song, false);
+ if (albumItem) {
+ QModelIndex idx=index(albumItem->row(), 0, index(artistItem->row(), 0, QModelIndex()));
+ emit dataChanged(idx, idx);
+ }
+ }
+ }
}
void MusicLibraryModel::setCover(const Song &song, const QImage &img, const QString &file)
{
- #ifdef ENABLE_UBUNTU
- if (!rootItem->useAlbumImages() || img.isNull() || file.isEmpty() ||
+ if (img.isNull() || file.isEmpty() ||
song.isCdda() || song.file.startsWith("http:/") || song.name().startsWith("http:/")) {
return;
}
+ #ifdef ENABLE_ONLINE_SERVICES
+ if (song.isFromOnlineService()) {
+ return;
+ }
+ #endif
MusicLibraryItemArtist *artistItem = rootItem->artist(song, false);
if (artistItem) {
MusicLibraryItemAlbum *albumItem = artistItem->album(song, false);
+ #ifdef ENABLE_UBUNTU
if (albumItem && albumItem->coverName().isEmpty()) {
albumItem->setCover(file);
QModelIndex idx=index(albumItem->row(), 0, index(artistItem->row(), 0, QModelIndex()));
emit dataChanged(idx, idx);
}
- }
- #else
- Q_UNUSED(file)
- if (!rootItem->useAlbumImages() || img.isNull() || MusicLibraryItemAlbum::CoverNone==MusicLibraryItemAlbum::currentCoverSize() ||
- song.isCdda() || song.file.startsWith("http:/") || song.name().startsWith("http:/")) {
- return;
- }
-
- MusicLibraryItemArtist *artistItem = rootItem->artist(song, false);
- if (artistItem) {
- MusicLibraryItemAlbum *albumItem = artistItem->album(song, false);
- if (albumItem && albumItem->saveToCache(img)) {
+ #else
+ if (albumItem) {
QModelIndex idx=index(albumItem->row(), 0, index(artistItem->row(), 0, QModelIndex()));
emit dataChanged(idx, idx);
}
+ #endif
}
- #endif
}
/**
diff -Nru cantata-1.4.2.ds1/models/musiclibrarymodel.h cantata-1.5.2.ds2/models/musiclibrarymodel.h
--- cantata-1.4.2.ds1/models/musiclibrarymodel.h 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/musiclibrarymodel.h 2015-03-23 20:09:40.000000000 +0000
@@ -55,6 +55,7 @@
MusicLibraryModel(QObject *parent=0, bool isMpdModel=true, bool isCheckable=false);
~MusicLibraryModel();
+ void readConfig();
QModelIndex index(int, int, const QModelIndex & = QModelIndex()) const;
QModelIndex parent(const QModelIndex &) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
@@ -87,13 +88,7 @@
QSet getAlbumArtists();
bool update(const QSet &songs);
// void uncheckAll();
- bool useAlbumImages() const { return rootItem->useAlbumImages(); }
- void setUseAlbumImages(bool a) { rootItem->setUseAlbumImages(a); }
- bool useArtistImages() const { return rootItem->useArtistImages(); }
- void setUseArtistImages(bool a) { rootItem->setUseArtistImages(a); }
const QDateTime & lastUpdate() { return databaseTime; }
- bool useLargeImages() const { return rootItem->useLargeImages(); }
- void setLargeImages(bool a) { rootItem->setLargeImages(a); }
void setSupportsAlbumArtistTag(bool s) { rootItem->setSupportsAlbumArtistTag(s); }
void toggleGrouping();
const QSet & genres() const { return rootItem->genres(); }
@@ -127,6 +122,7 @@
private:
bool mpdModel;
bool checkable;
+ bool artistImages;
MusicLibraryItemRoot *rootItem;
QDateTime databaseTime;
bool databaseTimeUnreliable;
diff -Nru cantata-1.4.2.ds1/models/musicmodel.cpp cantata-1.5.2.ds2/models/musicmodel.cpp
--- cantata-1.4.2.ds1/models/musicmodel.cpp 2014-09-28 16:30:11.000000000 +0000
+++ cantata-1.5.2.ds2/models/musicmodel.cpp 2015-03-23 20:09:40.000000000 +0000
@@ -37,6 +37,7 @@
#include "roles.h"
#include "support/localize.h"
#include "gui/plurals.h"
+#include "gui/settings.h"
#include "widgets/icons.h"
#include "gui/covers.h"
#include
@@ -102,33 +103,20 @@
#ifndef ENABLE_UBUNTU
case Qt::DecorationRole:
switch (item->itemType()) {
- case MusicLibraryItem::Type_Root: {
- QImage img=static_cast(item)->image();
- if (!img.isNull()) {
- return img;
- }
+ case MusicLibraryItem::Type_Root:
return static_cast(item)->icon();
- }
- case MusicLibraryItem::Type_Artist: {
- MusicLibraryItemArtist *artist = static_cast(item);
- return artist->isVarious() ? Icons::self()->variousArtistsIcon : Icons::self()->artistIcon;
- }
+ case MusicLibraryItem::Type_Artist:
+ return static_cast(item)->isVarious() ? Icons::self()->variousArtistsIcon : Icons::self()->artistIcon;
#ifdef ENABLE_ONLINE_SERVICES
case MusicLibraryItem::Type_Podcast:
- if (MusicLibraryItemAlbum::CoverNone==MusicLibraryItemAlbum::currentCoverSize()) {
- return Icons::self()->podcastIcon;
- } else {
- return static_cast(item)->cover();
- }
+ return Icons::self()->podcastIcon;
#endif
case MusicLibraryItem::Type_Album:
- if (MusicLibraryItemAlbum::CoverNone==MusicLibraryItemAlbum::currentCoverSize() || !root(item)->useAlbumImages()) {
- return Icons::self()->albumIcon;
- } else {
- return static_cast(item)->cover();
- }
- case MusicLibraryItem::Type_Song: return Song::Playlist==static_cast(item)->song().type ? Icons::self()->playlistIcon : Icons::self()->audioFileIcon;
- default: return QVariant();
+ return Icons::self()->albumIcon;
+ case MusicLibraryItem::Type_Song:
+ return Song::Playlist==static_cast(item)->song().type ? Icons::self()->playlistIcon : Icons::self()->audioFileIcon;
+ default:
+ return QVariant();
}
#endif
case Cantata::Role_BriefMainText:
@@ -157,6 +145,9 @@
}
return item->displayData();
case Qt::ToolTipRole:
+ if (!Settings::self()->infoTooltips()) {
+ return QVariant();
+ }
if (MusicLibraryItem::Type_Song==item->itemType()) {
#ifdef ENABLE_ONLINE_SERVICES
if (MusicLibraryItem::Type_Podcast==item->parentItem()->itemType()) {
@@ -172,17 +163,6 @@
(0==item->childCount()
? item->displayData(true)
: (item->displayData(true)+" "+data(index, Cantata::Role_SubText).toString()));
- #ifndef ENABLE_UBUNTU
- case Cantata::Role_ImageSize: {
- const MusicLibraryItemRoot *r=root(item);
- if (MusicLibraryItem::Type_Song!=item->itemType() && !MusicLibraryItemAlbum::itemSize().isNull()) { // icon/list style view...
- return MusicLibraryItemAlbum::iconSize(r->useLargeImages());
- } else if ((r->useAlbumImages() && MusicLibraryItem::Type_Album==item->itemType()) || MusicLibraryItem::Type_Podcast==item->itemType() || (r->useArtistImages() && MusicLibraryItem::Type_Artist==item->itemType())) {
- return MusicLibraryItemAlbum::iconSize();
- }
- break;
- }
- #endif
case Cantata::Role_SubText:
switch (item->itemType()) {
case MusicLibraryItem::Type_Root: {
@@ -204,35 +184,43 @@
Utils::formatTime(static_cast(item)->totalTime()));
default: return QVariant();
}
- case Cantata::Role_Image: {
+ case Cantata::Role_ListImage:
+ switch (item->itemType()) {
+ case MusicLibraryItem::Type_Album:
+ return true;
+ #ifdef ENABLE_ONLINE_SERVICES
+ case MusicLibraryItem::Type_Podcast:
+ return true;
+ #endif
+ default:
+ return false;
+ }
+ #ifdef ENABLE_UBUNTU
+ case Cantata::Role_Image:
+ switch (item->itemType()) {
+ case MusicLibraryItem::Type_Album:
+ return static_cast