diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d6463805..34367c6bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,8 +104,8 @@ if(PHONON_FOUND) message(STATUS "Phonon found; ensure that phonon-vlc is at least 0.4") endif() -macro_optional_find_package(LibEchonest 2.0.0) -macro_log_feature(LIBECHONEST_FOUND "Echonest" "Qt library for communicating with The Echo Nest" "http://projects.kde.org/libechonest" TRUE "" "libechonest 2.0.0 is needed for dynamic playlists and the infosystem") +macro_optional_find_package(Echonest 2.0.0) +macro_log_feature(ECHONEST_FOUND "Echonest" "Qt library for communicating with The Echo Nest" "http://projects.kde.org/libechonest" TRUE "" "libechonest 2.0.0 is needed for dynamic playlists and the infosystem") macro_optional_find_package(CLucene 0.9.23) macro_log_feature(CLucene_FOUND "CLucene" "The open-source, C++ search engine" "http://clucene.sf.net" TRUE "" "CLucene is used for indexing the collection") @@ -122,7 +122,7 @@ macro_optional_find_package( Boost ) macro_log_feature(Boost_FOUND "Boost" "Provides free peer-reviewed portable C++ source libraries" "http://www.boost.org" TRUE "" "") #FIXME: give useful explaination macro_optional_find_package(QCA2) -macro_log_feature(QCA2_FOUND "QCA2" "Provides encryption and signing functions required for Grooveshark resolver" "http://delta.affinix.com/qca/" FALSE "" "") +macro_log_feature(QCA2_FOUND "QCA2" "Provides encryption and signing functions required for Grooveshark resolver" "http://delta.affinix.com/qca/" TRUE "" "") macro_optional_find_package(LibAttica 0.4.0) macro_log_feature(LIBATTICA_FOUND "libattica" "Provides support for automatic fetching and managing of resolvers from the tomahawk website" "https://projects.kde.org/projects/kdesupport/attica" TRUE "" "") diff --git a/CMakeModules/FindEchonest.cmake b/CMakeModules/FindEchonest.cmake new file mode 100644 index 000000000..768d0eb4c --- /dev/null +++ b/CMakeModules/FindEchonest.cmake @@ -0,0 +1,36 @@ +# - Find libechonest +# Find the libechonest includes and the libechonest libraries +# This module defines +# ECHONEST_INCLUDE_DIR, root echonest include dir. Include echonest includes with echonest/foo.h +# ECHONEST_LIBRARIES, the path to libechonest +# ECHONEST_FOUND, whether libechonest was found + +FIND_PACKAGE(PkgConfig QUIET) +PKG_CHECK_MODULES(PC_ECHONEST QUIET libechonest) + +FIND_PATH(ECHONEST_INCLUDE_DIR NAMES echonest/Track.h + HINTS + ${PC_ECHONEST_INCLUDEDIR} + ${PC_ECHONEST_INCLUDE_DIRS} + ${CMAKE_INSTALL_INCLUDEDIR} + ${KDE4_INCLUDE_DIR} +) + +FIND_LIBRARY(ECHONEST_LIBRARIES NAMES echonest + HINTS + ${PC_ECHONEST_LIBDIR} + ${PC_ECHONEST_LIBRARY_DIRS} + ${CMAKE_INSTALL_LIBDIR} + ${KDE4_LIB_DIR} +) + +IF(ECHONEST_LIBRARIES AND ECHONEST_INCLUDE_DIR AND NOT PC_ECHONEST_VERSION) + MESSAGE(WARNING "You don't have pkg-config and so the libechonest version check does not work!") +ENDIF() + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Echonest + REQUIRED_VARS ECHONEST_LIBRARIES ECHONEST_INCLUDE_DIR + VERSION_VAR PC_ECHONEST_VERSION) + +MARK_AS_ADVANCED(ECHONEST_INCLUDE_DIR ECHONEST_LIBRARIES) diff --git a/CMakeModules/FindLibEchonest.cmake b/CMakeModules/FindLibEchonest.cmake deleted file mode 100644 index 9c78462f4..000000000 --- a/CMakeModules/FindLibEchonest.cmake +++ /dev/null @@ -1,42 +0,0 @@ -# - Find libechonest -# Find the libechonest includes and the libechonest libraries -# This module defines -# LIBECHONEST_INCLUDE_DIR, root echonest include dir. Include echonest includes with echonest/foo.h -# LIBECHONEST_LIBRARY, the path to libechonest -# LIBECHONEST_FOUND, whether libechonest was found - - -find_path(LIBECHONEST_INCLUDE_DIR NAMES echonest_export.h - HINTS - ~/usr/include - /opt/local/include - /usr/include - /usr/local/include - /opt/kde4/include - ${KDE4_INCLUDE_DIR} - PATH_SUFFIXES echonest -) - -find_library( LIBECHONEST_LIBRARY NAMES echonest - PATHS - ~/usr/lib - /opt/local/lib - /usr/lib - /usr/lib64 - /usr/local/lib - /opt/kde4/lib - ${KDE4_LIB_DIR} -) - - -if(LIBECHONEST_INCLUDE_DIR AND LIBECHONEST_LIBRARY) - set(LIBECHONEST_FOUND TRUE) - message(STATUS "Found libechonest: ${LIBECHONEST_INCLUDE_DIR}, ${LIBECHONEST_LIBRARY}") -else(LIBECHONEST_INCLUDE_DIR AND LIBECHONEST_LIBRARY) - set(LIBECHONEST_FOUND FALSE) - if (LIBECHONEST_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find required package libechonest") - endif(LIBECHONEST_FIND_REQUIRED) -endif(LIBECHONEST_INCLUDE_DIR AND LIBECHONEST_LIBRARY) - -mark_as_advanced(LIBECHONEST_INCLUDE_DIR LIBECHONEST_LIBRARY) diff --git a/ChangeLog b/ChangeLog index d3df8fd69..85e9fd93a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,20 @@ Version 0.6.0: * Access Control queries now stay on the bottom of the job view, removing the tendency to jump away from the mouse. +Version 0.5.5: + * Changed the Spotify config dialog to indicate when the user + is logged in. + * Fixed bug where the wrong avatar could be shown for a user. + * Fixed shortcuts not working in the global search field on OS X. + * Fixed The Echo Nest stations. + * Code-signed executable on OS X for GateKeeper. + * Fixed logging in to Spotify when pressing return in the config dialog. + * Fixed queue not auto-collapsing when playing the last track. + * Fixed bug where album listings would fail to show up. + * Improved stability. + * Fixed bug where it was not possible to drop a mixture of resolved + and unresolved tracks onto a playlist. + Version 0.5.4: * Improved stability. * Added support for Spotify album lookups. diff --git a/data/images/playlist-subscribed.png b/data/images/playlist-subscribed.png new file mode 100755 index 000000000..09234c070 Binary files /dev/null and b/data/images/playlist-subscribed.png differ diff --git a/data/images/subscribe-off.png b/data/images/subscribe-off.png new file mode 100644 index 000000000..99565fd80 Binary files /dev/null and b/data/images/subscribe-off.png differ diff --git a/data/images/subscribe-on.png b/data/images/subscribe-on.png new file mode 100644 index 000000000..37f78f7cd Binary files /dev/null and b/data/images/subscribe-on.png differ diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts index 8d022ae17..3de9024d6 100644 --- a/lang/tomahawk_ar.ts +++ b/lang/tomahawk_ar.ts @@ -146,17 +146,17 @@ connect and stream from you? ألبومات أخرى للفنان - + Sorry, we could not find any other albums for this artist! نعتذر, لم نستطيع إيجاد ألبومات أخرى لهذا الفنان! - + Sorry, we could not find any tracks for this album! نعتذر، لم نستطيع إيجاد أغاني أخرى لهذا الألبوم! - + Other Albums by %1 ألبومات أخرى ل%1 @@ -304,17 +304,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 نعتذر، لم نستطيع إيجاد الأغنية '%1' ل%2 - + Sorry, Tomahawk couldn't find the artist '%1' نعتذر، لم نستطيع إيجاد الفنان '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 نعتذر، لم نستطيع إيجاد الألبوم '%1' ل%2 @@ -374,12 +374,12 @@ connect and stream from you? - + Show Footnotes أظهر الحاشية - + Hide Footnotes إخفي الحاشية @@ -551,6 +551,11 @@ connect and stream from you? Import Playback History استيراد تاريخ إعادة الإستماع + + + Synchronize Loved Tracks + + LastfmContext @@ -1224,47 +1229,67 @@ connect and stream from you? SettingsDialog - + Collection مجموعة - + Advanced متقدمة - + All الكل - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted بعض الإعدادات التي تم تغييرها لن تصبح نافذة المفعول حتى يتم إعادة تشغيل توماهوك - + Services خدمات - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file تثبيت محلل من ملف - + Delete all Access Control entries? حذف كافة بيانات التحكم بالوصول؟ - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. هل فعلا تريد حذف جميع بيانات التحكم بالوصول؟ سوف يطلب منك اتخاذ القرار مجددا لكل ند على اتصال به. - + Information معلومات @@ -1475,69 +1500,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &نسخ الرابط - + &Delete %1 &أحذف %1 - + Add to my Playlists أضف إلى لوائحي للأغاني - + Add to my Automatic Playlists أضف إلى لوائحي الأوتوماتيكية للأغاني - + Add to my Stations أضف إلى إذاعاتي - + &Export Playlist &تصدير قائمة الأغاني - + playlist قائمة الأغاني - + automatic playlist قائمة أغاني أوتوماتيكية - + station إذاعة - - Delete %1? - playlist/station/... - أحذف %1؟ - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? هل ترغب في حذف %1 <b>"%2"</b>؟ - + + Delete + + + + Save XSPF حفظ XSPF - + Playlists (*.xspf) قوائم أغاني (*.xspf) @@ -1671,14 +1695,9 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - أحذف في سبوتيفي (Spotify)؟ - - - - Would you like to delete the corresponding Spotify playlist as well? - هل ترغب في حذف قائمة التشغيل المطابقة على سبوتيفي (Spotify)؟ + + Delete associated Spotify playlist? + @@ -1689,17 +1708,12 @@ connect and stream from you? إعدادات توماهوك - - Local Music Information - معلومات الأغاني المحلية - - - + Path to scan for music files: ماسار لتفحص ملفات الموسيقى: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1709,107 +1723,97 @@ connect and stream from you? إنشاء قوائم أغاني أوتوماتيكيا و إذاعات حسب ذوقك الشخصي. - + Upload collection list to The Echo Nest to enable user radio تحميل قائمة المجموعة إلى "The Echo" لتمكين راديو المستخدم - + Watch for changes إنتبه للتغييرات - + Time between scans, in seconds: الوقت بين المسوحات، بالثواني: - - Advanced Settings - إعدادات متقدمة - - - + Remote Peer Connection Method طريقة الاتصال بالند البعيد - + None (outgoing connections only) لا شيء (الاتصالات الصادرة فقط) - + Use UPnP to establish port forward (recommended) استخدم عمل UPnP لإنشاء بوابة إعادة التوجيه (موصى به) - + Use static external IP address/host name and port استخدم عنوان/مضيف ايب (IP) و بوابة ثابتين - + Set this to your external IP address or host name. Make sure to forward the port to this host! عين هذا إلى عنوان الايب الخارجي (External IP) الخاص بك أو اسم المضيف. تأكد من إحالة البوابة إلى هذا المضيف! - + SOCKS Proxy سوكس الوكيل - + Use SOCKS Proxy استخدم سوكس الوكيل - + Clear All Access Control Entries حذف كافة بيانات التحكم بالوصول - - Internet Services - خدمات الانترنت - - - + Install from file... تثبيت من ملف... - + Filter by capability: ترشيح حسب القدرة: - + Static Host Name: اسم مضيف ثابت: - + Static Port: بوابة ثابتة: - + Proxy Settings... إعدادات الوسيط... - + Other Settings إعدادات أخرى - + Send reports after Tomahawk crashed أرسل تقارير بعد فشل توماهوك - + Allow web browsers to interact with Tomahawk (recommended) السماح لمحرك البحث بالتفاعل مع توماهوك (موصى به) @@ -1925,7 +1929,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play إبعث أغانيك الخاصة إلى last .fm و جد أغاني جديدة مجانا للاستماع إليها @@ -1933,52 +1937,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... اختبار... - + Test Login اختبار الدخول - + Importing %1 e.g. Importing 2012/01/01 استيراد %1 - + Importing History... نقل التاريخ... - + History Incomplete. Resume تاريخ ناقص. استأنف - + Playback History Imported تم استيراد تاريخ إعادة الإستماع - - + + Failed فشلت - + Success نجاح - + Could not contact server لم أستطيع الإتصال بالخادم + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2866,7 +2880,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums ألبومات @@ -2929,40 +2943,54 @@ Try tweaking the filters for a new set of songs to play. &استمع مع + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and و - + You أنت - + you أنت - + and و - + %n other(s) %n أخرين%n أخر%n أخرين%n أخرين%n أخرين%n أخرين - + %1 people %1 أشخاص - + loved this track أحببت هذه الأغنية @@ -3030,7 +3058,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! مشكلة في جلب معلومات "Spotify" من الشبكة! @@ -3259,7 +3287,7 @@ enter the displayed PIN number here: - + Play إستمع @@ -3279,172 +3307,172 @@ enter the displayed PIN number here: التالي - + Back إلى الوراء - + Go back one page العودة صفحة واحدة إلى الوراء - + Forward تقدم - + Go forward one page تقدم صفحة واحدة - + Global Search... بحث شامل... - - + + Check For Updates... التحقق من التحديثات... - - - + + + Connect To Peer ربط بالند - + Enter peer address: أدخل عنوان الند: - + Enter peer port: أدخل بوابة الند: - + Enter peer key: أدخل مفتاح الند: - + XSPF Error خطأ XSPF - + This is not a valid XSPF playlist. قائمة الأغاني XSPF هذه ليست صالحة. - + Failed to save tracks فشل في حفظ الأغاني - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. بعض الأغاني في قائمة الأغاني لا تحتوي على إسم الفنان أو إسم الأغنية. هذه الأغاني سوف تتجاهل. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. عذرا، هناك مشكلة في الوصول إلى جهاز الصوت أو الأغنية المطلوب، سوف يتم تخطي الأغنية الحالية. تأكد أن لديك خلفية فونون المناسبة والإضافات المطلوبة مثبتة. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. عذرا، هناك مشكلة في الوصول إلى جهاز الصوت أو الأغنية المطلوب، سوف يتم تخطي الأغنية الحالية. - + Station إذاعة - + Create New Station إنشاء قائمة أغاني جديدة - + Name: الاسم: - + Playlist قائمة الأغاني - + Automatic Playlist قائمة أغاني أوتوماتيكية - + Pause تعليق - + Go &offline أصبح &غير متصل - + Go &online اصبح &متصل - + Authentication Error خطأ في المصادقة - + Error connecting to SIP: Authentication failed! خطأ في الاتصال بسيب (SIP): فشلت المصادقة! - + %1 by %2 track, artist name %1 من قبل %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 حقوق الطبع والنشر ٢٠١٠ - ٢٠١٢ - + Thanks to: شكر لكل من: - + About Tomahawk عن توماهوك @@ -3495,32 +3523,32 @@ enter the displayed PIN number here: أغاني قريبة - + Sorry, but we could not find similar tracks for this song! نعتذر، لم نستطيع إيجاد أغاني قريبة من هذه الأغنية! - + You've listened to this track %n time(s). لقد استمعت إلى هذه الأغنية %n مرة.لقد استمعت إلى هذه الأغنية مرة %n.لقد استمعت إلى هذه الأغنية مرتين %n.لقد استمعت إلى هذه الأغنية %n مرات.لقد استمعت إلى هذه الأغنية %n مرات.لقد استمعت إلى هذه الأغنية %n مرات. - + You've never listened to this track before. لم تستمع لهذه الأغنية من قبل. - + You first listened to it on %1. استمعت إليها أولاً في %1. - + You've listened to %1 %n time(s). لقد استمعت إلى %1 %n مرة.لقد استمعت إلى %1 مرة %n.لقد استمعت إلى %1 مرتين %n.لقد استمعت إلى %1 %n مرات.لقد استمعت إلى %1 %n مرات.لقد استمعت إلى %1 %n مرات. - + You've never listened to %1 before. لم تستمع إلى %1 من قبل. @@ -3538,12 +3566,14 @@ enter the displayed PIN number here: from - من + streaming artist - track from friend + to - إلى + streaming artist - track to friend + @@ -3658,37 +3688,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. بعد إجراء مسح مجموعة أغانيك الخاصة ستجد أغانيك هنا. - + This collection is empty. هذه المجموعة فارغة. - + SuperCollection سوبر كولكشن - + Combined libraries of all your online friends مكتبات مجمعة لكل اصحابك المتصلين - + Recently Played Tracks الأغاني التي إستمعت إليها مؤخرا - + Recently played tracks from all your friends جميع الأغاني التي استمع إليها أصدقائك مؤخرا - + Sorry, we could not find any recent plays! @@ -3711,12 +3741,12 @@ You can re-send a sync message at any time simply by sending another tweet using الأغاني التي إستمعت إليها مؤخرا - + No recently created playlists in your network. لا قوائم أغاني جديدة أنشئت مؤخرا على شبكتك. - + Welcome to Tomahawk مرحبا بكم في توماهوك diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index 69c7fb575..e8e0fe9c4 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -145,17 +145,17 @@ connect and stream from you? Други албуми на този артист - + Sorry, we could not find any other albums for this artist! Съжалявам, но не откривам нито един албум от този артист! - + Sorry, we could not find any tracks for this album! Съжалявам, но не откривам нито една песен за този артист! - + Other Albums by %1 Други албуми от %1 @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Покажи подробности - + Hide Footnotes Скрий подробности @@ -553,6 +553,11 @@ Tomahaw създаде доклад относно това и изпращай Import Playback History Импортирай история на просвирените песни + + + Synchronize Loved Tracks + + LastfmContext @@ -1224,47 +1229,67 @@ Tomahaw създаде доклад относно това и изпращай SettingsDialog - + Collection Колекция - + Advanced Разширени - + All Всички - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Някои промени няма да имат ефект, докато програмата не бъде рестартирана. - + Services Услуги - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Инсталирай услиги за търсене от файл - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Информация @@ -1476,69 +1501,68 @@ Tomahaw създаде доклад относно това и изпращай SourceTreeView - + &Copy Link &Копирай адресът - + &Delete %1 &Изтрий %1 - + Add to my Playlists Добави към моите списъци - + Add to my Automatic Playlists Добави към моите автоматично-генерирани списъци - + Add to my Stations Добави към станциите ми - + &Export Playlist &Изнеси списък - + playlist списък - + automatic playlist автоматично-генериран списък - + station станция - - Delete %1? - playlist/station/... - Изтрий %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Наистина ли желаеш да изтриеш %1 <b>''%2" </b> - + + Delete + + + + Save XSPF Запази XSPF - + Playlists (*.xspf) Списъци (*.xspf) @@ -1673,14 +1697,9 @@ Tomahaw създаде доклад относно това и изпращай SpotifyPlaylistUpdater - - Delete in Spotify? - Изтривам и в Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? - Желаеш ли да изтриеш и съответните Spotify списъци? + + Delete associated Spotify playlist? + @@ -1691,17 +1710,12 @@ Tomahaw създаде доклад относно това и изпращай Настройки на Tomahawk - - Local Music Information - Информация за локалната музика - - - + Path to scan for music files: Път за сканиране за музика: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1712,107 +1726,97 @@ Tomahaw създаде доклад относно това и изпращай базирани на вашият персонален вкус. - + Upload collection list to The Echo Nest to enable user radio Качи списък на колекцията ти в The Echo Nest за да се създаде потребителско радио - + Watch for changes Наблюдавай за промени - + Time between scans, in seconds: Време между две сканирания, в секунди - - Advanced Settings - Разширени настройки - - - + Remote Peer Connection Method Начин за свързване - + None (outgoing connections only) Без. (само изходящи връзки) - + Use UPnP to establish port forward (recommended) Ползвай UPnP (препоръчително) - + Use static external IP address/host name and port Ползвай статичен IP адрес/име и порт - + Set this to your external IP address or host name. Make sure to forward the port to this host! Настрой тук, своят външен IP адрес или име. Моля увери се, че си настроил прехвърляне на избраният порт, към адресът ти от локалната мрежа. - + SOCKS Proxy SOCKS Proxy - + Use SOCKS Proxy Ползвай SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - Интернет услуги - - - + Install from file... Инсталирай от файл... - + Filter by capability: Филтрирай по възможности: - + Static Host Name: Статичен адрес: - + Static Port: Статичен порт: - + Proxy Settings... Настройка на Proxy: - + Other Settings Други настройки - + Send reports after Tomahawk crashed Изпрати сервизна информация след забиване. - + Allow web browsers to interact with Tomahawk (recommended) Позволи на браузърите да работят съвместно с Tomahawk (препоръчително) @@ -1931,7 +1935,7 @@ Tomahaw създаде доклад относно това и изпращай Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Качи информация за изпълнените песни в Last.fm и открий свободно разпространявани. @@ -1939,52 +1943,62 @@ Tomahaw създаде доклад относно това и изпращай Tomahawk::Accounts::LastFmConfig - + Testing... Тествам... - + Test Login Тествай връзката - + Importing %1 e.g. Importing 2012/01/01 Импортирам %1 - + Importing History... Импортирам... - + History Incomplete. Resume Непълна информация. Продължи. - + Playback History Imported Историята на просвирените песни е импортирана - - + + Failed Неуспешно - + Success Ура! - + Could not contact server Не мога да се свържа със сървъра + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2873,7 +2887,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Албуми @@ -2936,40 +2950,54 @@ Try tweaking the filters for a new set of songs to play. &Слушай заедно + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and и - + You Ти - + you ти - + and и - + %n other(s) %n друг%n други - + %1 people %1 хора - + loved this track хареса тази песен @@ -3037,7 +3065,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Грешка при извличане на информация от Spotify @@ -3266,7 +3294,7 @@ enter the displayed PIN number here: - + Play Изпълни @@ -3286,175 +3314,175 @@ enter the displayed PIN number here: Следваща - + Back - + Go back one page Една страница назад - + Forward Напред - + Go forward one page Една страница напред - + Global Search... Глобално търсене... - - + + Check For Updates... Провери за обновления... - - - + + + Connect To Peer Свържи се с друг потребител - + Enter peer address: Въведи адресът на отдалеченият потребител: - + Enter peer port: Въведи порт: - + Enter peer key: Въведи ключът за удостоверяване: - + XSPF Error XSPF Грешка - + This is not a valid XSPF playlist. Това не е валиден XSPF списък - + Failed to save tracks Не мога да запазя списъкът с песни - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Някои от песните в този списък нямат артист и заглавие. Те ще бъдат игнорирани. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Съжалявам. Има проблем с достъпа до твоето аудио-устройство или до избраната песен - тя ще бъде прескочена. Моля, увери се, че са инсталирани подходящ Phonon и приставки. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Съжалявам. Има проблем с достъпа до твоето аудио устройство или избраната песен. Тя ще бъде пропусната. - + Station Станция - + Create New Station Създай нова станция - + Name: Име: - + Playlist Списък - + Automatic Playlist Автоматично-генериран списък - + Pause Пауза - + Go &offline Излез &извън линия - + Go &online Свържи &се - + Authentication Error Грешка при удостоверяване - + Error connecting to SIP: Authentication failed! Грешка при свързване: Неуспешно удостоверяване! - + %1 by %2 track, artist name %1 от %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Всички права - запазени. 2010 - 2012 - + Thanks to: Благодарности на: - + About Tomahawk Относно Tomahawk @@ -3505,32 +3533,32 @@ enter the displayed PIN number here: Подобни песни - + Sorry, but we could not find similar tracks for this song! Съжалявам, но не откривам нито една подобна на тази песен! - + You've listened to this track %n time(s). Ти си слушал тази песен %n път(и)Ти си слушал тази песен %n път(и) - + You've never listened to this track before. Никога не си слушал тази песен преди - + You first listened to it on %1. Първоначално си я слушал на %1 - + You've listened to %1 %n time(s). Слушал си %1 път(и)Слушал си %1 %n път(и) - + You've never listened to %1 before. Никога не си слушал %1 преди @@ -3548,12 +3576,14 @@ enter the displayed PIN number here: from - от + streaming artist - track from friend + to - до + streaming artist - track to friend + @@ -3669,38 +3699,38 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. След като бъде сканирана колекцията ти, ще откриеш твоите песни точно тук. - + This collection is empty. Празна колекция. - + SuperCollection Супер колекция /Сборен излед от локалните и наличните в колекциите на приятелите ти/ - + Combined libraries of all your online friends Обща колекция с всичките ми приятели на линия - + Recently Played Tracks Наскоро изпълени песни - + Recently played tracks from all your friends Наскоро изпълнени песни от всичките ти приятели - + Sorry, we could not find any recent plays! @@ -3723,12 +3753,12 @@ You can re-send a sync message at any time simply by sending another tweet using Наскоро изпълнени - + No recently created playlists in your network. Не откривам наскоро създадени списъци в твоята мрежа - + Welcome to Tomahawk Здравей! diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts index 955a02cd4..2514f535d 100644 --- a/lang/tomahawk_ca.ts +++ b/lang/tomahawk_ca.ts @@ -145,17 +145,17 @@ connect and stream from you? Altres Àlbums de l'Artista - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Altres Àlbums de %1 @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Mostra les Notes al peu - + Hide Footnotes Amaga les Notes al peu @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History Importa l'historial de reproducció + + + Synchronize Loved Tracks + + LastfmContext @@ -1222,47 +1227,67 @@ connect and stream from you? SettingsDialog - + Collection Col·lecció - + Advanced Avançat - + All Tot - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Alguns paràmetres no tindran efecte fins que no reinicieu Tomahawk - + Services Serveis - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Instal·la un Resolver des d'un fitxer - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Informació @@ -1473,69 +1498,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Copia l'Enllaç - + &Delete %1 &Esborra %1 - + Add to my Playlists Afegeix a les meves Llistes - + Add to my Automatic Playlists Afegeix a les meves Llistes Automàtiques - + Add to my Stations Afegeix a les meves Emissores - + &Export Playlist E&xporta la Llista de Reproducció - + playlist llista - + automatic playlist llista automàtica - + station emissora - - Delete %1? - playlist/station/... - Voleu esborrar %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Voleu esborrar %1 <b>"%2"</b>? - + + Delete + + + + Save XSPF Desa com XSPF - + Playlists (*.xspf) Llistes de reproducció (*.xspf) @@ -1669,14 +1693,9 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - Voleu esborrar-ho de Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? - Voleu esborrar les llistes de Spotify, també? + + Delete associated Spotify playlist? + @@ -1687,17 +1706,12 @@ connect and stream from you? Paràmetres de Tomahawk - - Local Music Information - Informació de la Música Local - - - + Path to scan for music files: Camí als fitxers de música: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1708,107 +1722,97 @@ aquesta opció podreu crear llistes de reproducció automàtiques i emissores de ràdio basades en el vostre gust musical. - + Upload collection list to The Echo Nest to enable user radio Carrega la llista de la col·lecció a The Echo Nest per activar la radio d'usuari - + Watch for changes Monitoritza els canvis - + Time between scans, in seconds: Temps entre escanejos, en segons: - - Advanced Settings - Paràmetres Avançats - - - + Remote Peer Connection Method Mètode de connexió remota entre iguals - + None (outgoing connections only) Cap (només connexions cap a l'exterior) - + Use UPnP to establish port forward (recommended) Utiliza UPnP per establir el redireccionament de ports (recomanat) - + Use static external IP address/host name and port Utilitza l'adreça IP estàtica externa/nom de l'ordinador i el port - + Set this to your external IP address or host name. Make sure to forward the port to this host! Ajusteu aquest paràmetre amb la vostra adreça IP o el nom de l'ordinador. Assegure-vos que redireccioneu el port a aquest ordinador! - + SOCKS Proxy Proxys SOCKS - + Use SOCKS Proxy Utilitza un proxy SOCKS - + Clear All Access Control Entries - - Internet Services - Serveis d'Internet - - - + Install from file... Instal·la des d'un fitxer... - + Filter by capability: Filtra per capacitats: - + Static Host Name: Nom de l'ordinador estàtic: - + Static Port: Port estàtic: - + Proxy Settings... Paràmetres del proxy... - + Other Settings Altres Paràmetres - + Send reports after Tomahawk crashed Envia informació de les fallades de Tomahawk - + Allow web browsers to interact with Tomahawk (recommended) Permet que els navegadors web interactuin amb Tomahawk (recomanat) @@ -1924,7 +1928,7 @@ i emissores de ràdio basades en el vostre gust musical. Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Fes scrobbling de les cançons a last.fm, i cerca cançons descarregables gratuïtament per escoltar-les @@ -1932,52 +1936,62 @@ i emissores de ràdio basades en el vostre gust musical. Tomahawk::Accounts::LastFmConfig - + Testing... S'està comprovant... - + Test Login Comprova l'inici de sessió - + Importing %1 e.g. Importing 2012/01/01 S'està important %1 - + Importing History... S'està important l'historial... - + History Incomplete. Resume Historial incomplet... Reprèn - + Playback History Imported S'ha importat l'historial de reproducció - - + + Failed Error - + Success Èxit - + Could not contact server No s'ha pogut contactar amb el servidor + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2865,7 +2879,7 @@ Intenteu ajustar els filtres per reproduir noves cançons. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Àlbums @@ -2928,40 +2942,54 @@ Intenteu ajustar els filtres per reproduir noves cançons. &Escolta a la vegada + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and i - + You Jo - + you jo - + and i - + %n other(s) %n més%n més - + %1 people %1 persones - + loved this track els ha encantat aquesta cançó @@ -3029,7 +3057,7 @@ Intenteu ajustar els filtres per reproduir noves cançons. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Error en cercar la informació de Spotify a través de la xarxa! @@ -3258,7 +3286,7 @@ introduïu el PIN aquí: - + Play Reprodueix @@ -3278,172 +3306,172 @@ introduïu el PIN aquí: Següent - + Back Enrere - + Go back one page Retrocedeix una pàgina - + Forward Endavant - + Go forward one page Avança una pàgina - + Global Search... Cerca Global... - - + + Check For Updates... Comprova les actualitzacions... - - - + + + Connect To Peer Connexió Remota - + Enter peer address: Introduïu l'adreça remota: - + Enter peer port: Introduïu el port remot: - + Enter peer key: Introduïu la clau remota: - + XSPF Error Error XSPF - + This is not a valid XSPF playlist. No és una llista XSPF vàlida. - + Failed to save tracks Error en desar les cançons - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Algunes cançons de la llista no contenen ni artista ni titol i s'han ignorat. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Hi ha un problema per accedir al dispositiu de so o a la cançó. La cançó actual s'ha saltat. Assegureu-vos que teniu un back.end de Phonon adequant i els plugins necessaris instal·lats. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Hi ha un problema per accedir al dispositiu de so o a la cançó, la cançó actual s'ha saltat. - + Station Emissora - + Create New Station Crea una Nova Emissora - + Name: Nom: - + Playlist Llista - + Automatic Playlist Llista Automàtica - + Pause Pausa - + Go &offline &Desconnecta't - + Go &online &Connecta't - + Authentication Error Error d'autentificació - + Error connecting to SIP: Authentication failed! S'ha produït un error connectant-se a SIP: Ha fallat autentificant! - + %1 by %2 track, artist name %1 de %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Copyright 2010 - 2012 - + Thanks to: Gràcies a: - + About Tomahawk Quant a Tomahawk @@ -3494,32 +3522,32 @@ introduïu el PIN aquí: Cançons Semblants - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). Heu escoltat aquesta cançó %n cop.Heu escoltat aquesta cançó %n cops. - + You've never listened to this track before. No heu escoltat mai aquesta cançó abans. - + You first listened to it on %1. Vau escoltar aquesta cançó per primer cop el %1. - + You've listened to %1 %n time(s). Heu escoltat %1 %n cop.Heu escoltat %1 %n cops. - + You've never listened to %1 before. No heu escoltat mai %1 abans. @@ -3537,12 +3565,14 @@ introduïu el PIN aquí: from - de + streaming artist - track from friend + to - a + streaming artist - track to friend + @@ -3657,37 +3687,37 @@ Podeu reenviar un missatge de sincronisme en qualsevol moment simplement enviant ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection SuperCol·lecció - + Combined libraries of all your online friends Biblioteques combinades de tots els amis en línia - + Recently Played Tracks Cançons Escoltades Recentment - + Recently played tracks from all your friends Cançons escoltades recentment pels amics - + Sorry, we could not find any recent plays! @@ -3710,12 +3740,12 @@ Podeu reenviar un missatge de sincronisme en qualsevol moment simplement enviant Cançons Escoltades Recentment - + No recently created playlists in your network. No hi ha cançons escoltades recentment a la xarxa. - + Welcome to Tomahawk Us donem la benvinguda a Tomahawk diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index cc0a37f69..a1eb2dad4 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -146,17 +146,17 @@ erlauben sich mit dir zu verbinden? Andere Alben des Künstlers - + Sorry, we could not find any other albums for this artist! Sorry, wir konnten keine anderen Alben für diesen Künstler finden! - + Sorry, we could not find any tracks for this album! Sorry, wir konnten keine anderen Lieder für dieses Album finden! - + Other Albums by %1 Andere Alben von %1 @@ -304,17 +304,17 @@ erlauben sich mit dir zu verbinden? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 Sorry, Tomahawk konnte '%1' von %2 nicht finden - + Sorry, Tomahawk couldn't find the artist '%1' Sorry, Tomahawk konnte den Künstler '%1' nicht finden - + Sorry, Tomahawk couldn't find the album '%1' by %2 Sorry, Tomahawk konnte das Album '%1' von %2 nicht finden @@ -374,12 +374,12 @@ erlauben sich mit dir zu verbinden? - + Show Footnotes Footnotes einblenden - + Hide Footnotes Footnotes ausblenden @@ -551,6 +551,11 @@ erlauben sich mit dir zu verbinden? Import Playback History Lieder-Historie importieren + + + Synchronize Loved Tracks + + LastfmContext @@ -1223,47 +1228,67 @@ erlauben sich mit dir zu verbinden? SettingsDialog - + Collection Sammlung - + Advanced Erweitert - + All Alle - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Einige geänderte Einstellungen haben keinen Effekt bis zum nächsten Neustart - + Services Dienste - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Installiere Resolver Datei - + Delete all Access Control entries? Alle erteilten Zugriffsrechte löschen? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. Willst du wirklich alle Zugriffseinstellungen zurücksetzen? Du wirst für alle Verbindungen erneut nach Zugriffseinstellungen gefragt werden. - + Information Information @@ -1474,69 +1499,68 @@ erlauben sich mit dir zu verbinden? SourceTreeView - + &Copy Link &Kopiere Link - + &Delete %1 &Lösche %1 - + Add to my Playlists Zu meinen Playlisten hinzufügen - + Add to my Automatic Playlists Zu meinen Automatischen Playlisten hinzufügen - + Add to my Stations Zu meinen Stationen hinzufügen - + &Export Playlist Playlist &exportieren - + playlist Playlist - + automatic playlist Automatische Playlist - + station Station - - Delete %1? - playlist/station/... - %1 löschen? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Möchtest du die %1 <b>"%2"</b> löschen? - + + Delete + + + + Save XSPF XSPF speichern - + Playlists (*.xspf) Playlisten (*.xspf) @@ -1670,14 +1694,9 @@ erlauben sich mit dir zu verbinden? SpotifyPlaylistUpdater - - Delete in Spotify? - Auf Spotify löschen - - - - Would you like to delete the corresponding Spotify playlist as well? - Möchtest du die entsprechende Spotify Playlist auch löschen? + + Delete associated Spotify playlist? + @@ -1688,17 +1707,12 @@ erlauben sich mit dir zu verbinden? Tomahawk Einstellungen - - Local Music Information - Information über lokale Musik - - - + Path to scan for music files: Pfad zu den Musikdateien: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1706,107 +1720,97 @@ erlauben sich mit dir zu verbinden? - + Upload collection list to The Echo Nest to enable user radio Liste der aktuellen Sammlung an Echo Nest übermitteln, um User Radio zu aktivieren - + Watch for changes Automatisch aktualisieren - + Time between scans, in seconds: Zeitinterval (in Sekunden) zwischen zwei Scans: - - Advanced Settings - Erweiterte Einstellungen - - - + Remote Peer Connection Method Verbindung zu anderen Tomahawks - + None (outgoing connections only) Keine (nur ausgehende Verbindungen möglich) - + Use UPnP to establish port forward (recommended) UPnP für Port-Weiterleitung verwenden (empfohlen) - + Use static external IP address/host name and port Statische externe IP Adresse / Hostnamen und Port verwenden - + Set this to your external IP address or host name. Make sure to forward the port to this host! Stelle hier deine externe IP Adresse oder Hostnamen ein. Du musst den Port selbst an diesen Rechner weiterleiten! - + SOCKS Proxy SOCKS Proxy - + Use SOCKS Proxy SOCKS Proxy verwenden - + Clear All Access Control Entries Alle erteilten Zugriffsrechte löschen - - Internet Services - Internet Dienste - - - + Install from file... Installiere Datei... - + Filter by capability: Nach Fähigkeiten filtern: - + Static Host Name: Statischer Rechnername: - + Static Port: Statischer Port: - + Proxy Settings... Proxy-Einstellungen… - + Other Settings Andere Einstellungen - + Send reports after Tomahawk crashed Übermittlung von Fehlerberichten nach Tomahawk Absturz - + Allow web browsers to interact with Tomahawk (recommended) Erlaube Web Browser mit Tomahawk zu interagieren (empfohlen) @@ -1922,7 +1926,7 @@ erlauben sich mit dir zu verbinden? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Gehörte Stücke zu last.fm scrobbeln und frei-verfügbare Stücke anhören @@ -1930,52 +1934,62 @@ erlauben sich mit dir zu verbinden? Tomahawk::Accounts::LastFmConfig - + Testing... Teste... - + Test Login Login testen - + Importing %1 e.g. Importing 2012/01/01 Importiere %1 - + Importing History... Importiere Historie... - + History Incomplete. Resume Historie unvollständig. Fortfahren - + Playback History Imported Lieder-Historie importiert - - + + Failed Fehlgeschlagen - + Success Erfolgreich - + Could not contact server Konnte den Server nicht erreichen! + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2861,7 +2875,7 @@ Versuch die Filter anzupassen für neue Lieder. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Alben @@ -2924,40 +2938,54 @@ Versuch die Filter anzupassen für neue Lieder. &Mithören + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and und - + You Du - + you du - + and und - + %n other(s) %n anderer%n andere - + %1 people %1 Leute - + loved this track liebte dieses Lied @@ -3025,7 +3053,7 @@ Versuch die Filter anzupassen für neue Lieder. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Konnte Spotify-Daten nicht laden! @@ -3254,7 +3282,7 @@ Tomahawk auf Twitter's Website authentifiziert hast: - + Play Abspielen @@ -3274,172 +3302,172 @@ Tomahawk auf Twitter's Website authentifiziert hast: Weiter - + Back Zurück - + Go back one page Gehe eine Seite zurück - + Forward Vorwärts - + Go forward one page Gehe eine Seite vorwärts - + Global Search... Globale Suche... - - + + Check For Updates... Nach Updates suchen... - - - + + + Connect To Peer Mit anderem Tomahawk verbinden - + Enter peer address: Gib die Adresse der Gegenstelle ein: - + Enter peer port: Gib den Port der Gegenstelle ein: - + Enter peer key: Gib den Schlüssel der Gegenstelle ein: - + XSPF Error XSPF-Fehler - + This is not a valid XSPF playlist. Dies ist keine gültige XSPF-Playlist. - + Failed to save tracks Konnte Stücke nicht abspeichern - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Einige Stücke in der Playlist enthalten weder Künstler noch Titel. Diese werden ignoriert. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Es tut uns leid, Tomahawk kann auf dein Audio-Gerät oder das gewünschte Stück nicht zugreifen und überspringt es deshalb. Vergewisser dich, dass ein geignetes Phonon-Backend mitsamt benötigten Plugins installiert ist. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Es tut uns leid, Tomahawk kann auf dein Audio-Gerät oder das gewünschte Stück nicht zugreifen und überspringt es deshalb. - + Station Station - + Create New Station Neue Station erstellen - + Name: Name: - + Playlist Playlist - + Automatic Playlist Automatische Playlist - + Pause Pause - + Go &offline Verbindung &trennen - + Go &online &Verbindung herstellen - + Authentication Error Authentifizierungsfehler - + Error connecting to SIP: Authentication failed! Verbindungsfehler mit SIP: Authentifizierung fehlgeschlagen! - + %1 by %2 track, artist name %1 von %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Copright 2010 - 2012 - + Thanks to: Danke an: - + About Tomahawk Über Tomahawk @@ -3490,32 +3518,32 @@ Tomahawk auf Twitter's Website authentifiziert hast: Ähnliche Lieder - + Sorry, but we could not find similar tracks for this song! Sorry, wir konnten keine ähnlichen Lieder finden! - + You've listened to this track %n time(s). Du hast dieses Lied einmal gehört.Du hast dieses Lied %n mal gehört. - + You've never listened to this track before. Du hast dieses Lied noch nie angehört. - + You first listened to it on %1. Du hast dieses Lied zum ersten mal am %1 gehört. - + You've listened to %1 %n time(s). Du hast %1 einmal angehört.Du hast %1 %n mal angehört. - + You've never listened to %1 before. Du hast %1 vorher noch nie gehört. @@ -3533,12 +3561,14 @@ Tomahawk auf Twitter's Website authentifiziert hast: from - von + streaming artist - track from friend + to - an + streaming artist - track to friend + @@ -3648,37 +3678,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. Nachdem du deine Musik Sammlung gescannt hast, findest du all deine Lieder genau hier. - + This collection is empty. Diese Sammlung ist leer. - + SuperCollection SuperCollection - + Combined libraries of all your online friends Kombinierte Sammlung all deiner Freunde - + Recently Played Tracks Zuletzt gehörte Lieder - + Recently played tracks from all your friends Zuletzt gehörte Lieder all deiner Freunde - + Sorry, we could not find any recent plays! @@ -3701,12 +3731,12 @@ You can re-send a sync message at any time simply by sending another tweet using Kürzlich gehörte Lieder - + No recently created playlists in your network. Es gibt keine kürzlich erstellten Playlisten in deinem Netzwerk. - + Welcome to Tomahawk Willkommen bei Tomahawk diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index 893995482..614d5c974 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -146,17 +146,17 @@ connect and stream from you? Other Albums by Artist - + Sorry, we could not find any other albums for this artist! Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! Sorry, we could not find any tracks for this album! - + Other Albums by %1 Other Albums by %1 @@ -304,17 +304,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -374,12 +374,12 @@ connect and stream from you? - + Show Footnotes Show Footnotes - + Hide Footnotes Hide Footnotes @@ -551,6 +551,11 @@ connect and stream from you? Import Playback History Import Playback History + + + Synchronize Loved Tracks + Synchronize Loved Tracks + LastfmContext @@ -1223,47 +1228,67 @@ connect and stream from you? SettingsDialog - + Collection Collection - + Advanced Advanced - + All All - + + Tomahawk Settings + Tomahawk Settings + + + Some changed settings will not take effect until Tomahawk is restarted Some changed settings will not take effect until Tomahawk is restarted - + Services Services - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + Install resolver from file Install resolver from file - + Delete all Access Control entries? Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Information @@ -1474,69 +1499,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Copy Link - + &Delete %1 &Delete %1 - + Add to my Playlists Add to my Playlists - + Add to my Automatic Playlists Add to my Automatic Playlists - + Add to my Stations Add to my Stations - + &Export Playlist &Export Playlist - + playlist playlist - + automatic playlist automatic playlist - + station station - - Delete %1? - playlist/station/... - Delete %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Would you like to delete the %1 <b>"%2"</b>? - + + Delete + Delete + + + Save XSPF Save XSPF - + Playlists (*.xspf) Playlists (*.xspf) @@ -1670,14 +1694,9 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - Delete in Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? + Delete associated Spotify playlist? @@ -1688,17 +1707,12 @@ connect and stream from you? Tomahawk Settings - - Local Music Information - Local Music Information - - - + Path to scan for music files: Path to scan for music files: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1709,107 +1723,97 @@ connect and stream from you? and stations based on your personal taste profile. - + Upload collection list to The Echo Nest to enable user radio Upload collection list to The Echo Nest to enable user radio - + Watch for changes Watch for changes - + Time between scans, in seconds: Time between scans, in seconds: - - Advanced Settings - Advanced Settings - - - + Remote Peer Connection Method Remote Peer Connection Method - + None (outgoing connections only) None (outgoing connections only) - + Use UPnP to establish port forward (recommended) Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy SOCKS Proxy - + Use SOCKS Proxy Use SOCKS Proxy - + Clear All Access Control Entries Clear All Access Control Entries - - Internet Services - Internet Services - - - + Install from file... Install from file... - + Filter by capability: Filter by capability: - + Static Host Name: Static Host Name: - + Static Port: Static Port: - + Proxy Settings... Proxy Settings... - + Other Settings Other Settings - + Send reports after Tomahawk crashed Send reports after Tomahawk crashed - + Allow web browsers to interact with Tomahawk (recommended) Allow web browsers to interact with Tomahawk (recommended) @@ -1925,7 +1929,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1933,52 +1937,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... Testing... - + Test Login Test Login - + Importing %1 e.g. Importing 2012/01/01 Importing %1 - + Importing History... Importing History... - + History Incomplete. Resume History Incomplete. Resume - + Playback History Imported Playback History Imported - - + + Failed Failed - + Success Success - + Could not contact server Could not contact server + + + Synchronizing... + Synchronizing... + + + + Synchronization Finished + Synchronization Finished + Tomahawk::Accounts::SpotifyAccount @@ -2866,7 +2880,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Albums @@ -2929,40 +2943,54 @@ Try tweaking the filters for a new set of songs to play. &Listen Along + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + Would you like to delete the playlist <b>"%2"</b>? + + + + Delete + Delete + + Tomahawk::Query - + and and - + You You - + you you - + and and - + %n other(s) %n other%n others - + %1 people %1 people - + loved this track loved this track @@ -3030,7 +3058,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Error fetching Spotify information from the network! @@ -3259,7 +3287,7 @@ enter the displayed PIN number here: - + Play Play @@ -3279,172 +3307,172 @@ enter the displayed PIN number here: Next - + Back Back - + Go back one page Go back one page - + Forward Forward - + Go forward one page Go forward one page - + Global Search... Global Search... - - + + Check For Updates... Check For Updates... - - - + + + Connect To Peer Connect To Peer - + Enter peer address: Enter peer address: - + Enter peer port: Enter peer port: - + Enter peer key: Enter peer key: - + XSPF Error XSPF Error - + This is not a valid XSPF playlist. This is not a valid XSPF playlist. - + Failed to save tracks Failed to save tracks - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station Station - + Create New Station Create New Station - + Name: Name: - + Playlist Playlist - + Automatic Playlist Automatic Playlist - + Pause Pause - + Go &offline Go &offline - + Go &online Go &online - + Authentication Error Authentication Error - + Error connecting to SIP: Authentication failed! Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name %1 by %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Copyright 2010 - 2012 - + Thanks to: Thanks to: - + About Tomahawk About Tomahawk @@ -3495,32 +3523,32 @@ enter the displayed PIN number here: Similar Tracks - + Sorry, but we could not find similar tracks for this song! Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). You've listened to this track %n time.You've listened to this track %n times. - + You've never listened to this track before. You've never listened to this track before. - + You first listened to it on %1. You first listened to it on %1. - + You've listened to %1 %n time(s). You've listened to %1 %n time.You've listened to %1 %n times. - + You've never listened to %1 before. You've never listened to %1 before. @@ -3538,11 +3566,13 @@ enter the displayed PIN number here: from + streaming artist - track from friend from to + streaming artist - track to friend to @@ -3658,37 +3688,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. After you have scanned your music collection you will find your tracks right here. - + This collection is empty. This collection is empty. - + SuperCollection SuperCollection - + Combined libraries of all your online friends Combined libraries of all your online friends - + Recently Played Tracks Recently Played Tracks - + Recently played tracks from all your friends Recently played tracks from all your friends - + Sorry, we could not find any recent plays! Sorry, we could not find any recent plays! @@ -3711,12 +3741,12 @@ You can re-send a sync message at any time simply by sending another tweet using Recently Played Tracks - + No recently created playlists in your network. No recently created playlists in your network. - + Welcome to Tomahawk Welcome to Tomahawk diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index 5137dfcd0..fd9497c64 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -145,17 +145,17 @@ connect and stream from you? Otros álbumes por el artista - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Otros álbumes por %1 @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Mostrar información de contexto - + Hide Footnotes Ocultar información de contexto @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1221,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection Colección - + Advanced Avanzado - + All Todo - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Algunos cambios no tomarán efecto hasta reiniciar Tomahawk - + Services Servicios - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Instalar un Resolver desde un fichero - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Información @@ -1472,69 +1497,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Copiar enlace - + &Delete %1 &Eliminar %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist &Exportar lista de reproducción - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF Guardar XSPF - + Playlists (*.xspf) Listas de reproducción (*.xspf) @@ -1668,14 +1692,9 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - ¿Borrar en Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? - Quieres eliminar la lista de Spotify correspondiente, también? + + Delete associated Spotify playlist? + @@ -1686,17 +1705,12 @@ connect and stream from you? Preferencias de Tomahawk - - Local Music Information - Información de música local - - - + Path to scan for music files: Ruta para escanear archivos de música: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1707,107 +1721,97 @@ usted podrá (y sus amigos) crear listas de reproducción automáticas y estaciones basadas en sus gustos personales. - + Upload collection list to The Echo Nest to enable user radio Subir la lista de colección a Echo Nest para activar la radio del usuario - + Watch for changes Vigilar los cambios en las carpetas - + Time between scans, in seconds: Tiempo entre escaneo, en segundos: - - Advanced Settings - Ajustes avanzados - - - + Remote Peer Connection Method Método de conexión remota - + None (outgoing connections only) Ninguna (sólo conexiones salientes) - + Use UPnP to establish port forward (recommended) Usar UPnP para establecer la redirección de puertos (recomendado) - + Use static external IP address/host name and port Usar IP estática externa/nombre de host y puero - + Set this to your external IP address or host name. Make sure to forward the port to this host! Ajustar a la dirección IP externa o nombre de la máquina. Hay que redirigir los puertos a esta máquina! - + SOCKS Proxy Proxy SOCKS - + Use SOCKS Proxy Utilizar el Proxy SOCKS - + Clear All Access Control Entries - - Internet Services - Servicios de Internet - - - + Install from file... Instalar desde un fichero... - + Filter by capability: Filtrar por capacidad: - + Static Host Name: Nombre estático del host: - + Static Port: Puerto estático: - + Proxy Settings... Configuración del proxy... - + Other Settings Otros Ajustes - + Send reports after Tomahawk crashed Mandar reportes después de que Tomahawk falle - + Allow web browsers to interact with Tomahawk (recommended) Permitir a los navegadores web interactuar con Tomahawk (recomendado) @@ -1923,7 +1927,7 @@ y estaciones basadas en sus gustos personales. Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Hacer Scrobble de mis temas a last.fm y encontrar canciones gratuitas para reproducirlas @@ -1931,52 +1935,62 @@ y estaciones basadas en sus gustos personales. Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login Comprobar Inicio de Sesión - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed Fallo - + Success Éxito - + Could not contact server No se pudo contactar el servidor + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2864,7 +2878,7 @@ Intente ajustar los filtros para reproducir nuevas canciones. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Álbumes @@ -2927,40 +2941,54 @@ Intente ajustar los filtros para reproducir nuevas canciones. &Escuchar juntos + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and y - + You usted - + you usted - + and y - + %n other(s) %n más%n más - + %1 people %1 personas - + loved this track han añadido este tema a Favoritos @@ -3028,7 +3056,7 @@ Intente ajustar los filtros para reproducir nuevas canciones. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Error al buscar la información de Spotify en la red! @@ -3257,7 +3285,7 @@ introduzca su número PIN aquí: - + Play Reproducir @@ -3277,172 +3305,172 @@ introduzca su número PIN aquí: Siguiente - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... Búsqueda global... - - + + Check For Updates... Buscar actualizaciones... - - - + + + Connect To Peer Conectar a un par - + Enter peer address: Introducir dirección del par: - + Enter peer port: Introducir puerto del par: - + Enter peer key: Introducir contraseña del par: - + XSPF Error Error XSPF - + This is not a valid XSPF playlist. Esta no es una lista de reproducción XSPF válida. - + Failed to save tracks Fallo al guardar pistas - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Algunas pistas en la lista de reproducción no contienen artista ni título. Serán ignoradas. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Se ha producido un error al acceder al dispostivo de audio o al tema deseado y se va saltar. Asegúrese de que ha instalado un backend de Phonon adecuado y los plugins necesarios. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Se ha producido un error al acceder al dispostivo de audio o al tema deseado y se va saltar. - + Station - + Create New Station Crear nueva estación - + Name: Nombre: - + Playlist - + Automatic Playlist - + Pause Pausar - + Go &offline &Desconectarse - + Go &online &Conectarse - + Authentication Error Error de autenticación - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name %1 por %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk Acerca de Tomahawk @@ -3493,32 +3521,32 @@ introduzca su número PIN aquí: Temas Similares - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). Ha escuchado esta canción %n vez.Ha escuchado esta canción %n veces. - + You've never listened to this track before. Nunca ha escuchado este tema antes. - + You first listened to it on %1. Escuchó este tema pro primera vez en %1. - + You've listened to %1 %n time(s). Ha escuchado %1 %n vez.Ha escuchado %1 %n veces. - + You've never listened to %1 before. Nunca ha escuchado %1 antes. @@ -3536,12 +3564,14 @@ introduzca su número PIN aquí: from - de + streaming artist - track from friend + to - para + streaming artist - track to friend + @@ -3656,37 +3686,37 @@ Puede reenviar el mensaje de sincronización en cualquier momento simplemente en ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection SuperColección - + Combined libraries of all your online friends Bibliotecas combinadas de todos tus amigos conectados - + Recently Played Tracks Temas Escuchados Recientemente - + Recently played tracks from all your friends Temas escuchados recientemente por mis amigos - + Sorry, we could not find any recent plays! @@ -3709,12 +3739,12 @@ Puede reenviar el mensaje de sincronización en cualquier momento simplemente en Pistas reproducidas recientemente - + No recently created playlists in your network. No hay listas de reproducción recientemente creadas en su red. - + Welcome to Tomahawk Bienvenido a Tomahawk diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts index 62e675a3c..cdef43390 100644 --- a/lang/tomahawk_fr.ts +++ b/lang/tomahawk_fr.ts @@ -146,17 +146,17 @@ de se connecter et streamer de vous? Tous les albums par cet artiste - + Sorry, we could not find any other albums for this artist! Désolé, aucun autre album n'a pu être trouvé pour cet artiste ! - + Sorry, we could not find any tracks for this album! Désolé, on a pas pu trouver aucune pistes pour cet album! - + Other Albums by %1 Autres albums de %1 @@ -304,17 +304,17 @@ de se connecter et streamer de vous? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 Désolé, on a pas pu trouver la piste '%1' pour %2 - + Sorry, Tomahawk couldn't find the artist '%1' Désolé, on a pas pu trouver l'artiste '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 Désolé, on a pas pu trouver l'album '%1' pour %2 @@ -374,12 +374,12 @@ de se connecter et streamer de vous? - + Show Footnotes Afficher les notes - + Hide Footnotes Masquer les notes @@ -551,6 +551,11 @@ de se connecter et streamer de vous? Import Playback History Importer l'historique + + + Synchronize Loved Tracks + + LastfmContext @@ -1223,47 +1228,67 @@ de se connecter et streamer de vous? SettingsDialog - + Collection Collection - + Advanced Avancés - + All Tous - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Certaines modifications ne prendront effet qu'au prochain démarrage de Tomahawk - + Services Services - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Installer un script de résolution depuis un fichier - + Delete all Access Control entries? Supprimer toutes les entrées de Contrôle d'accès? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. Voulez-vous vraiment supprimer toutes les entrées de contrôle d'accès ? On vous demandera de nouveau votre autorisation pour toutes les nouvelles connexions. - + Information Information @@ -1474,69 +1499,68 @@ de se connecter et streamer de vous? SourceTreeView - + &Copy Link &Copier le lien - + &Delete %1 &Supprimer %1 - + Add to my Playlists Ajoute a mes listes de lecture - + Add to my Automatic Playlists Ajoute a mes listes de lecture automatique - + Add to my Stations Ajouter à mes stations - + &Export Playlist &Exporter la liste de lecture - + playlist liste de lecture - + automatic playlist liste de lecture automatique - + station station - - Delete %1? - playlist/station/... - Supprimer %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Voulez-vous supprimer la %1 <b>"%2"</b>? - + + Delete + + + + Save XSPF Enregistrer XSPF - + Playlists (*.xspf) Listes de lecture (*.xspf) @@ -1670,14 +1694,9 @@ de se connecter et streamer de vous? SpotifyPlaylistUpdater - - Delete in Spotify? - Supprimer dans Spotify ? - - - - Would you like to delete the corresponding Spotify playlist as well? - Voulez-vous aussi supprimer la liste de lecture correspondante dans Spotify ? + + Delete associated Spotify playlist? + @@ -1688,17 +1707,12 @@ de se connecter et streamer de vous? Paramètres de Tomahawk - - Local Music Information - Fichiers de musique locaux - - - + Path to scan for music files: Chemin à scanner pour des fichiers musicaux : - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1709,107 +1723,97 @@ vous (et vos amis) pourrez créer des listes de lecture automatiquement et des stations basées sur vos goûts. - + Upload collection list to The Echo Nest to enable user radio Envoyer la collection à The Echo Nest pour activer la radio utilisateur - + Watch for changes Surveiller les changements - + Time between scans, in seconds: Période de scan, en secondes : - - Advanced Settings - Paramètres avancés - - - + Remote Peer Connection Method Méthode de connexion distante à un pair - + None (outgoing connections only) Aucune (Connexions sortantes uniquement) - + Use UPnP to establish port forward (recommended) Utiliser UPnP pour la redirection des ports (recommandé) - + Use static external IP address/host name and port Utiliser une adresse IP externe statique/nom d'hôte et un port - + Set this to your external IP address or host name. Make sure to forward the port to this host! Indiquez votre adresse IP externe ou nom d'hôte. Vérifiez que le port est bien redirigé vers cet hôte ! - + SOCKS Proxy Proxy SOCKS - + Use SOCKS Proxy Utiliser un proxy SOCKS - + Clear All Access Control Entries Supprimer toutes les entrées de Contrôle d'accès - - Internet Services - Services Internet - - - + Install from file... Installer depuis un fichier... - + Filter by capability: Filtrer par fonctionnalité : - + Static Host Name: Nom d'hôte statique : - + Static Port: Port statique : - + Proxy Settings... Paramètres du proxy... - + Other Settings Autres paramètres - + Send reports after Tomahawk crashed Envoyer un rapport après un crash de Tomahawk - + Allow web browsers to interact with Tomahawk (recommended) Permettre aux navigateurs web d’interagir avec Tomahawk (recommandé) @@ -1925,7 +1929,7 @@ et des stations basées sur vos goûts. Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Scrobbler vos écoutes sur Last.fm et trouver des morceaux téléchargeables gratuitement @@ -1933,52 +1937,62 @@ et des stations basées sur vos goûts. Tomahawk::Accounts::LastFmConfig - + Testing... Test... - + Test Login Test de connexion - + Importing %1 e.g. Importing 2012/01/01 Importation %1 - + Importing History... Import de l'historique... - + History Incomplete. Resume Historique incomplet. Reprendre - + Playback History Imported Historique de lecture importé - - + + Failed Échec - + Success Succès - + Could not contact server Impossible de contacter le serveur + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2866,7 +2880,7 @@ Essayez de changer les filtres pour avoir de nouveaux morceaux à jouer. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Albums @@ -2929,40 +2943,54 @@ Essayez de changer les filtres pour avoir de nouveaux morceaux à jouer.&Ecouter avec + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and et - + You Vous - + you vous - + and et - + %n other(s) %n autre%n autres - + %1 people %1 personnes - + loved this track a enregistré cette piste dans ses favoris @@ -3030,7 +3058,7 @@ Essayez de changer les filtres pour avoir de nouveaux morceaux à jouer. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Échec du chargement des informations Spotify depuis le réseau! @@ -3259,7 +3287,7 @@ saisissez le numéro PIN ici : - + Play Lecture @@ -3279,172 +3307,172 @@ saisissez le numéro PIN ici : Suivant - + Back Retour - + Go back one page Reculer d'une page - + Forward Avancer - + Go forward one page Avancer d'une page - + Global Search... Recherche Globale... - - + + Check For Updates... Rechercher une mise à jour... - - - + + + Connect To Peer Connexion à un pair - + Enter peer address: Adresse du pair : - + Enter peer port: Port du pair : - + Enter peer key: Clé du pair : - + XSPF Error Erreur XSPF - + This is not a valid XSPF playlist. Ceci n'est pas une liste de lecture XSPF valide. - + Failed to save tracks Échec de la sauvegarde des pistes - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Certaines pistes dans la liste de lecture ne contiennent pas d'artiste ou de titre. Elles seront ignorées. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Désolé, il y a un problème d'accès à votre matériel audio ou la piste en cours va être sautée. Vérifiez que vous avez un backend Phonon et les plugins requis installés. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Désolé, il y a un problème d'accès à votre matériel audio ou la piste en cours va être sauter. - + Station Station - + Create New Station Créer une nouvelle station - + Name: Nom : - + Playlist Liste de lecture - + Automatic Playlist Liste de lecture automatique - + Pause Pause - + Go &offline Se &déconnecter - + Go &online Se c&onnecter - + Authentication Error Erreur d'authentification - + Error connecting to SIP: Authentication failed! Erreur de connexion SIP : échec de l'authentification ! - + %1 by %2 track, artist name %1 par %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Droit d'auteur 2010 - 2012 - + Thanks to: Merci a: - + About Tomahawk A propos de Tomahawk @@ -3495,32 +3523,32 @@ saisissez le numéro PIN ici : Piste similaire - + Sorry, but we could not find similar tracks for this song! Désolé, on a pas pu trouver aucune pistes pour cette chanson! - + You've listened to this track %n time(s). Vous avez écouté cette piste %n fois.Vous avez écouté cette piste %n fois. - + You've never listened to this track before. Vous n'avez encore jamais écouté cette piste. - + You first listened to it on %1. Vous l'avez écouté pour la première fois le %1. - + You've listened to %1 %n time(s). Vous avez écouté %1 %n fois.Vous avez écouté %1 %n fois. - + You've never listened to %1 before. Vous n'avez encore jamais écouté %1. @@ -3538,12 +3566,14 @@ saisissez le numéro PIN ici : from - de + streaming artist - track from friend + to - à + streaming artist - track to friend + @@ -3658,37 +3688,37 @@ Vous pouvez envoyer un message de synchronisation quand vous le souhaitez en env ViewManager - + After you have scanned your music collection you will find your tracks right here. Après avoir scanné votre collection musicale, vous trouverez tous vos titres ici. - + This collection is empty. La collection est vide. - + SuperCollection SuperCollection - + Combined libraries of all your online friends Collections regroupant toutes celles de vos amis en ligne - + Recently Played Tracks Derniers titres joués - + Recently played tracks from all your friends Derniers titres joués par vos amis - + Sorry, we could not find any recent plays! @@ -3711,12 +3741,12 @@ Vous pouvez envoyer un message de synchronisation quand vous le souhaitez en env Joués récemment - + No recently created playlists in your network. Pas de liste de lecture créée récemment sur votre réseau. - + Welcome to Tomahawk Bienvenue dans Tomahawk diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index 19c1685c7..dd9e9ca69 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -5,12 +5,12 @@ Allow %1 to connect and stream from you? - + %1からの接続、又はストリーミングを許可しますか? Allow Streaming - + ストリーミングを許可 @@ -23,7 +23,7 @@ connect and stream from you? Tomahawk needs you to decide whether %1 is allowed to connect. - + %1からの接続を許可することが必要です。 @@ -145,17 +145,17 @@ connect and stream from you? 他のアルバム - + Sorry, we could not find any other albums for this artist! このアーティストのアルバムは他に見つかりませんでした。 - + Sorry, we could not find any tracks for this album! このアルバムの曲は見つかりませんでした。 - + Other Albums by %1 %1の他のアルバム @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 Tomahawkは%2の%1を見つかりませんでした。 - + Sorry, Tomahawk couldn't find the artist '%1' Tomahawkは'%1'と言うアーティストを見つかりませんでした。 - + Sorry, Tomahawk couldn't find the album '%1' by %2 Tomahawkは%2の%1を見つかりませんでした。 @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes 脚注を表示 - + Hide Footnotes 脚注を隠す @@ -451,7 +451,7 @@ connect and stream from you? About - + 情報 @@ -551,6 +551,11 @@ connect and stream from you? Import Playback History 再生履歴をインポートする + + + Synchronize Loved Tracks + + LastfmContext @@ -1223,47 +1228,67 @@ connect and stream from you? SettingsDialog - + Collection コレクション - + Advanced 詳細 - + All すべて - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Tomahawkを再起動すると設定変更が反映されます - + Services サービス - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file ファイルからリゾルバをインストールする - + Delete all Access Control entries? 全てのアクセス制御のエントリーを削除しますか? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. 本当に全てのアクセス制御のエントリーを削除しますか?ピア接続に対して、改めて同意を求めます。 - + Information 情報 @@ -1474,69 +1499,68 @@ connect and stream from you? SourceTreeView - + &Copy Link リンクをコピー - + &Delete %1 %1を削除 - + Add to my Playlists プレイリストに追加する - + Add to my Automatic Playlists 自動プレイリストに追加する - + Add to my Stations ステーションに追加する - + &Export Playlist プレイリストを書き出し - + playlist プレイリスト - + automatic playlist 自動プレイリスト - + station ステーション - - Delete %1? - playlist/station/... - %1を削除しますか? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? <b>"%2"</b>と言う%1を削除しますか? - + + Delete + 削除 + + + Save XSPF XSPFを保存する - + Playlists (*.xspf) プレイリスト (*.xspf) @@ -1670,14 +1694,9 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - Spotifyにも削除しますか? - - - - Would you like to delete the corresponding Spotify playlist as well? - 同期のSpotifyのプレイリストも削除してもよろしいですか? + + Delete associated Spotify playlist? + 関連付けられたSpotifyのプレイリストも削除しますか? @@ -1688,127 +1707,115 @@ connect and stream from you? 設定 - - Local Music Information - - - - + Path to scan for music files: - + 音楽ファイルの検索パス: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists and stations based on your personal taste profile. - + The Echo Nestはカタログのメタデータを整理して、 +個人的なラジオを作成する機能があります。 +このオプションを有効にすると、あなたと友達の音楽の好みに +基づいた自動プレイリストやステーションを作れます。 - + Upload collection list to The Echo Nest to enable user radio - + The Echo Nestにコレクションのリストをアップロードして、ユーザーラジオを有効にする - + Watch for changes - + 変更を監視 - + Time between scans, in seconds: - + スキャン作業の時間間隔(秒数): - - Advanced Settings - - - - + Remote Peer Connection Method - + リモートピアとの接続方法 - + None (outgoing connections only) - + 無 (出接続のみ) - + Use UPnP to establish port forward (recommended) - + UPnPを使用して、ポートのフォワーディングを設ける (推奨) - + Use static external IP address/host name and port - + グローバル静的IP、又はホスト名とポートを使用する - + Set this to your external IP address or host name. Make sure to forward the port to this host! フォーム - + SOCKS Proxy - + SOCKSのプロクシ - + Use SOCKS Proxy - + SOCKSのプロクシを使用する - + Clear All Access Control Entries - + 全てのアクセス制御のエントリーを削除する - - Internet Services - - - - + Install from file... - + ファイルからインストール... - + Filter by capability: - + 機能別に分類: - + Static Host Name: - + 静的ホスト名: - + Static Port: - + 静的ポート: - + Proxy Settings... - + プロクシ設定 - + Other Settings - + 他の設定 - + Send reports after Tomahawk crashed - + Tomahawkがクラッシュしたら、レポートを送信 - + Allow web browsers to interact with Tomahawk (recommended) - + ウェブブラウザーとの対話を許可する(お勧め) @@ -1816,17 +1823,17 @@ connect and stream from you? Copy Artist Link - + アーティストリンクをコピー Copy Album Link - + アルバムリンクをコピー Copy Track Link - + トラックリンクをコピー @@ -1839,12 +1846,12 @@ connect and stream from you? Remove - + 削除 %1 downloads - + %1ダウンロード @@ -1854,7 +1861,7 @@ connect and stream from you? Connecting... - + 接続中... @@ -1867,12 +1874,12 @@ connect and stream from you? Manual Install Required - + 手動インストールが要求 Unfortunately, automatic installation of this resolver is not available or disabled for your platform.<br /><br />Please use "Install from file" above, by fetching it from your distribution or compiling it yourself. Further instructions can be found here:<br /><br />http://www.tomahawk-player.org/resolvers/%1 - + 残念ながら、このプラットフォームでは、リゾルバの自動インストールは設けてないか、無効にされました。<br /><br />以上の「ファイルからインストール」を使用して、又はディストリビューションから取得するか、自分でコンパイルして下さい。詳しくはこちらを参照:<br /><br />http://www.tomahawk-player.org/resolvers/%1 @@ -1880,22 +1887,22 @@ connect and stream from you? Configure this Google Account - + Googleのアカウントを設定 Google Address - + Googleのアドレス Enter your Google login to connect with your friends using Tomahawk! - + Googleのログイン情報を入力して、Tomahawkで友達に接続しましょう! username@gmail.com - + username@gmail.com @@ -1903,7 +1910,7 @@ connect and stream from you? Connect to Google Talk to find your friends - + Google Talkに接続して、友達を探す @@ -1911,69 +1918,79 @@ connect and stream from you? Add Friend - + 友達を追加 Enter Google Address: - + Googleのアドレスを入力: Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play - + Last.fmにトラックをscrobbleして、無料ダウンロードのトラックを探して再生する Tomahawk::Accounts::LastFmConfig - + Testing... - + 試験用接続... - + Test Login - + ログインを試用 - + Importing %1 e.g. Importing 2012/01/01 - + %1をインポート - + Importing History... - + 履歴をインポート中... - + History Incomplete. Resume - + 不完全履歴。回復 - + Playback History Imported - + 再生履歴インポート完了 - - + + Failed - + 失敗しました - + Success + 完成 + + + + Could not contact server + サーバーに接続できませんでした + + + + Synchronizing... - - Could not contact server + + Synchronization Finished @@ -1982,37 +1999,37 @@ connect and stream from you? Sync with Spotify - + Spotifyと同期する Re-enable syncing with Spotify - + Spotifyとの同期を再び有効にする Create local copy - + ローカルのコピーを作成 Subscribe to playlist changes - + プレイリストの変更フィードに登録する Re-enable playlist subscription - + 再びプレイリストのフィードに登録する Stop subscribing to changes - + 変更フィードの登録を解除 Stop syncing with Spotify - + Spotifyとの同期を解除 @@ -2025,17 +2042,17 @@ connect and stream from you? Failed: %1 - + 失敗しました: %1 Logged in as %1 - + %1としてログイン済み Log Out - + ログアウト @@ -2856,7 +2873,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums アルバム @@ -2919,40 +2936,54 @@ Try tweaking the filters for a new set of songs to play. + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -3020,7 +3051,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! @@ -3249,7 +3280,7 @@ Meta+Ctrl+Z - + Play 再生 @@ -3269,172 +3300,172 @@ Meta+Ctrl+Z 次へ - + Back プレイリスト - + Go back one page - + Forward - + Go forward one page - + Global Search... - - + + Check For Updates... - - - + + + Connect To Peer - + Enter peer address: - + Enter peer port: - + Enter peer key: - + XSPF Error - + This is not a valid XSPF playlist. - + Failed to save tracks - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station ステーション - + Create New Station 新規ステーションを作成 - + Name: 名前: - + Playlist プレイリスト - + Automatic Playlist - + Pause 一時停止 - + Go &offline - + Go &online - + Authentication Error - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name %1 by %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Copyright 2010 - 2012 - + Thanks to: Thanks to: - + About Tomahawk Tomahawkについて @@ -3485,32 +3516,32 @@ Meta+Ctrl+Z 似ているトラック - + Sorry, but we could not find similar tracks for this song! この曲に似ているトラックが見つかりませんでした。 - + You've listened to this track %n time(s). このトラックは%n回聴いています。 - + You've never listened to this track before. このトラックを一度も聴いていません。 - + You first listened to it on %1. 初めてこの曲を聴いたのは、%1です。 - + You've listened to %1 %n time(s). %1を%n回聴いています。 - + You've never listened to %1 before. %1を一度も聴いていません。 @@ -3528,12 +3559,14 @@ Meta+Ctrl+Z from - から + streaming artist - track from friend + to - まで + streaming artist - track to friend + @@ -3648,37 +3681,37 @@ Twitterを使っている友達にTomahawkを接続したいなら、ツイー ViewManager - + After you have scanned your music collection you will find your tracks right here. コレクションのスキャンが完了したら、トラックはここに表示されます。 - + This collection is empty. このコレクションには何も入っていません。 - + SuperCollection スーパーコレクション - + Combined libraries of all your online friends オンラインの友達全員のライブラリ - + Recently Played Tracks 最近再生したトラック - + Recently played tracks from all your friends 友達の最近再生したトラック - + Sorry, we could not find any recent plays! @@ -3701,12 +3734,12 @@ Twitterを使っている友達にTomahawkを接続したいなら、ツイー 最近再生したトラック - + No recently created playlists in your network. ネットワークに最近作成したプレイリストはありません。 - + Welcome to Tomahawk Tomahawkへようこそ diff --git a/lang/tomahawk_lt.ts b/lang/tomahawk_lt.ts new file mode 100644 index 000000000..7ec770c21 --- /dev/null +++ b/lang/tomahawk_lt.ts @@ -0,0 +1,4096 @@ + + + ACLJobDelegate + + + Allow %1 to +connect and stream from you? + + + + + Allow Streaming + Leisti transliavimą + + + + Deny Access + Drausti priėjimą + + + + ACLJobItem + + + Tomahawk needs you to decide whether %1 is allowed to connect. + + + + + AccountFactoryWrapper + + + Dialog + + + + + Description goes here + Apibūdinimo vieta čia + + + + Add Account + Pridėti paskyrą + + + + AccountFactoryWrapperDelegate + + + Online + Prisijungęs + + + + Connecting... + Jungiamasi... + + + + Offline + Atsijungęs + + + + ActionCollection + + + &Listen Along + K&lausytis kartu + + + + Stop &Listening Along + Stabdyti k&lausymąsi kartu + + + + &Follow in real-time + Se&kti realiu laiku + + + + + &Listen Privately + K&lausytis privačiai + + + + + &Listen Publicly + K&lausytis viešai + + + + &Load Playlist + Įke&lti grojaraštį + + + + &Rename Playlist + Per&vadinti grojaraštį + + + + &Copy Playlist Link + &Kopijuoti grojaraščio nuorodą + + + + &Play + &Groti + + + + &Stop + &Sustabdyti + + + + &Previous Track + Ankstesnis takelis + + + + &Next Track + Kitas takelis + + + + &Quit + &Baigti darbą + + + + AlbumInfoWidget + + + Form + Forma + + + + Other Albums by Artist + Kiti atlikėjo albumai + + + + Sorry, we could not find any other albums for this artist! + Atsiprašome, neradome jokių kitų šio atlikėjo albumų! + + + + Sorry, we could not find any tracks for this album! + Atsiprašome, neradome jokių takelių iš šio albumo! + + + + Other Albums by %1 + Kiti %1 albumai + + + + AlbumModel + + + + All albums from %1 + Visi %1 albumai + + + + All albums + Visi albumai + + + + ArtistInfoWidget + + + Form + Forma + + + + Top Hits + + + + + Related Artists + Susiję atlikėjai + + + + Artist + Atlikėjas + + + + Albums + Albumai + + + + Cover + Viršelis + + + + Sorry, we could not find any albums for this artist! + Atsiprašome, neradome jokių šio atlikėjo albumų! + + + + Sorry, we could not find any related artists! + Atsiprašome, neradome jokių susijusių atlikėjų! + + + + Sorry, we could not find any top hits for this artist! + + + + + AudioControls + + + Prev + Ankstesnis + + + + Play + Groti + + + + Pause + Pristabdyti + + + + Next + Kitas + + + + Artist + Atlikėjas + + + + Album + Albumas + + + + Owner + Savininkas + + + + social + + + + + love + + + + + Time + + + + + Time Left + + + + + Shuffle + Maišyti + + + + Repeat + Kartoti + + + + Low + + + + + High + + + + + AudioEngine + + + Sorry, Tomahawk couldn't find the track '%1' by %2 + Atsiprašome, Tomahawk nepavyko rasti takelio '%1', atliekamo %2 + + + + Sorry, Tomahawk couldn't find the artist '%1' + Atsiprašome, Tomahawk nepavyko rasti atlikėjo '%1' + + + + Sorry, Tomahawk couldn't find the album '%1' by %2 + Atsiprašome, Tomahawk nepavyko rasti %2 atliekamo albumo '%1' + + + + CategoryAddItem + + + Create new Playlist + Sukurti naują grojaraštį + + + + Create new Station + Sukurti naują stotį + + + + + New Station + Nauja stotis + + + + + %1 Station + + + + + CategoryItem + + + Playlists + Grojaraščiai + + + + Stations + Stotys + + + + ClearButton + + + Clear + Valyti + + + + ContextWidget + + + InfoBar + + + + + + Show Footnotes + Rodyti išnašas + + + + Hide Footnotes + Slėpti išnašas + + + + CrashReporter + + + Tomahawk Crash Reporter + Tomahawk strigties pranešyklė + + + + <html><head/><body><p><span style=" font-weight:600;">Sorry!</span> Tomahawk crashed. Please tell us about it! Tomahawk has created an error report for you that can help improve the stability in the future. You can now send this report directly to the Tomahawk developers.</p></body></html> + + + + + Send this report + Siųsti šią ataskaitą + + + + Don't send + Nesiųsti + + + + Abort + Nutraukti + + + + You can disable sending crash reports in the configuration dialog. + Galite išjungti strigčių ataskaitų siuntimą konfigūracijos dialogo lange. + + + + Uploaded %L1 of %L2 KB. + + + + + + Close + Užverti + + + + Sent! <b>Many thanks</b>. + Išsiųsta! <b>Labai ačiū</b>. + + + + Failed to send crash info. + Nepavyko nusiųsti strigties informacijos. + + + + DatabaseCommand_AllAlbums + + + Unknown + + + + + DelegateConfigWrapper + + + About + Apie + + + + Delete Account + Pašalinti paskyrą + + + + About this Account + Apie šią paskyrą + + + + DiagnosticsDialog + + + Tomahawk Diagnostics + Tomahawk diagnostika + + + + &Copy to Clipboard + &Kopijuoti į iškarpinę + + + + Open &Log-file + Atverti žurna&lą + + + + FlexibleHeader + + + Filter... + Filtruoti... + + + + GlobalSearchWidget + + + Form + Forma + + + + IndexingJobItem + + + Indexing database + + + + + InfoBar + + + InfoBar + + + + + Filter... + Filtruoti... + + + + LastFmConfig + + + Form + Forma + + + + Scrobble tracks to Last.fm + Pranešti grojamus takelius Last.fm + + + + Username: + Vartotojo vardas: + + + + Password: + Slaptažodis: + + + + Test Login + Išbandyti prisijungimą + + + + Import Playback History + Įkelti klausymosi istoriją + + + + Synchronize Loved Tracks + + + + + LastfmContext + + + Last.fm + Last.fm + + + + LatchedStatusItem + + + %1 is listening along with you! + %1 klausosi kartu su Jumis! + + + + LoadXSPF + + + Load XSPF + Įkelti XSPF + + + + Playlist URL + Grojaraščio URL + + + + Enter URL... + Įveskite URL... + + + + ... + ... + + + + Automatically update + Atnaujinti automatiškai + + + + LoadXSPFDialog + + + Load XSPF File + Įkelti XSPF failą + + + + XSPF Files (*.xspf) + XSPF failai (*.xspf) + + + + LocalCollection + + + Bookmarks + Žymelės + + + + Saved tracks + Išsaugoti takeliai + + + + LovedTracksItem + + + Top Loved Tracks + Populiariausios mylimos dainos + + + + Sorry, we could not find any loved tracks! + Deja, neradome jokių mylimų dainų! + + + + The most loved tracks from all your friends + Visų Jūsų draugų labiausiai mylimos dainos + + + + All of your loved tracks + Visos Jūsų mylimos dainos + + + + All of %1's loved tracks + Visos %1 mylimos dainos + + + + Loved Tracks + Mylimos dainos + + + + MetadataEditor + + + Form + Forma + + + + Tags + Žymės + + + + Title: + Pavadinimas: + + + + Title... + Pavadinimas... + + + + Artist: + Atlikėjas: + + + + Artist... + Atlikėjas... + + + + Album: + Albumas: + + + + Album... + Albumas... + + + + Disc Number: + Disko numeris: + + + + Duration: + Trukmė: + + + + 00.00 + 00.00 + + + + Year: + Metai: + + + + Bitrate: + Bitų dažnis: + + + + File + Failas + + + + File Name: + Failo vardas: + + + + File Name... + Failo vardas... + + + + File Size... + Failo dydis... + + + + File size... + Failo dydis... + + + + File Size: + Failo dydis: + + + + Back + Atgal + + + + Forward + Pirmyn + + + + - Properties + - Savybės + + + + NewPlaylistWidget + + + Enter a title for the new playlist: + Įveskite naujojo grojaraščio pavadinimą: + + + + Tomahawk offers a variety of ways to help you create playlists and find music you enjoy! + + + + + Just enter a genre or tag name and Tomahawk will suggest a few songs to get you started with your new playlist: + + + + + &Create Playlist + Su&kurti grojaraštį + + + + Create a new playlist + Sukurti naują grojaraštį + + + + NewReleasesWidget + + + New Releases + Nauji leidimai + + + + PlayableModel + + + Artist + Atlikėjas + + + + Title + Pavadinimas + + + + Composer + Kompozitorius + + + + Album + Albumas + + + + Track + Takelio numeris + + + + Duration + Trukmė + + + + Bitrate + Bitų dažnis + + + + Age + Amžius + + + + Year + Metai + + + + Size + Dydis + + + + Origin + Šaltinis + + + + Score + Įvertis + + + + + Name + Vardas + + + + PlaylistHeader + + + InfoBar + + + + + Caption + Pavadinimas + + + + Description + Apibūdinimas + + + + + + RadioButton + Akutė + + + + PlaylistItemDelegate + + + played %1 by you + + + + + played %1 by %2 + + + + + PlaylistLargeItemDelegate + + + played %1 by you + + + + + played %1 by %2 + + + + + added %1 + + + + + PlaylistModel + + + A playlist by %1, created %2 + + + + + you + + + + + All tracks by %1 on album %2 + Visi %1 takeliai iš albumo %2 + + + + All tracks by %1 + Visi %1 takeliai + + + + PlaylistTypeSelectorDlg + + + New Playlist + Naujas grojaraštis + + + + Just a regular old playlist... Give it a name, drag in some tracks, and go! + Tiesiog senas geras grojaraštis... Suteikite jam vardą, įtempkite keletą dainų ir pirmyn! + + + + Don't know exactly what you want? Give Tomahawk a few pointers and let it build a playlist for you! + Nežinote, ko tiksliai norite? Suteikite Tomahawk keletą nuorodų ir leiskite jam sukurti Jums grojaraštį! + + + + Name: + Vardas: + + + + New Playlist... + Naujas grojaraštis... + + + + Create Manual Playlist + Sukurti rankinį grojaraštį + + + + Create Automatic Playlist + Sukurti automatinį grojaraštį + + + + PlaylistView + + + This playlist is currently empty. + Šis grojaraštis kol kas tuščias. + + + + This playlist is currently empty. Add some tracks to it and enjoy the music! + Šis grojaraštis kol kas tuščias. Pridėkite takelių ir mėgaukitės muzika! + + + + ProxyDialog + + + Proxy Settings + Proxy nuostatos + + + + Hostname of proxy server + Proxy serverio vardas + + + + Host + Serveris + + + + Port + Prievadas + + + + Proxy login + Proxy prisijungimas + + + + User + Vartotojas + + + + Password + Slaptažodis + + + + Proxy password + Proxy slaptažodis + + + + No Proxy Hosts: +(Overrides system proxy) + + + + + localhost *.example.com (space separated) + + + + + Use proxy for DNS lookups? + + + + + QObject + + + %n year(s) ago + prieš %n metusprieš %n metusprieš %n metų + + + + %n year(s) + %n metai%n metai%n metų + + + + %n month(s) ago + prieš %n mėnesįprieš %n mėnesiusprieš %n mėnesių + + + + %n month(s) + %n mėnuo%n mėnesiai%n mėnesių + + + + %n week(s) ago + prieš %n savaitęprieš %n savaitesprieš %n savaičių + + + + %n week(s) + %n savaitė%n savaitės%n savaičių + + + + %n day(s) ago + prieš %n dienąprieš %n dienasprieš %n dienų + + + + %n day(s) + %n diena%n dienos%n dienų + + + + %n hour(s) ago + prieš %n valandąprieš %n valandasprieš %n valandų + + + + %n hour(s) + %n valanda%n valandos%n valandų + + + + %1 minutes ago + + + + + %1 minutes + + + + + just now + ką tik + + + + Friend Finders + Draugų ieškyklės + + + + Music Finders + Muzikos ieškyklės + + + + Status Updaters + + + + + QuaZipFilePrivate + + + ZIP/UNZIP API error %1 + ZIP/UNZIP API klaida %1 + + + + QueueView + + + InfoBar + + + + + + Open Queue + Atverti eilę + + + + Open Queue - %n item(s) + Atverti eilę - %n elementasAtverti eilę - %n elementaiAtverti eilę - %n elementų + + + + Close Queue + Užverti eilę + + + + RelatedArtistsContext + + + Related Artists + Susiję atlikėjai + + + + ResolverConfigDelegate + + + Not found: %1 + Nerasta: %1 + + + + Failed to load: %1 + Nepavyko įkelti: %1 + + + + SearchLineEdit + + + Search + + + + + SearchWidget + + + Search: %1 + + + + + Results for '%1' + + + + + SettingsDialog + + + Collection + Kolekcija + + + + Advanced + Išplėstinės + + + + All + Visi + + + + Tomahawk Settings + + + + + Some changed settings will not take effect until Tomahawk is restarted + + + + + Services + Paslaugos + + + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + + Install resolver from file + + + + + Delete all Access Control entries? + + + + + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. + + + + + Information + Informacija + + + + SocialPlaylistWidget + + + Popular New Albums From Your Friends + + + + + Most Played Playlists + Dažniausiai grojami grojaraščiai + + + + Most Played Tracks You Don't Have + Dažniausiai groti takeliai, kurių Jūs neturite + + + + SocialWidget + + + Form + Forma + + + + Facebook + Facebook + + + + Twitter + Twitter + + + + Cover + Viršelis + + + + TextLabel + Teksto etiketė + + + + Tweet + + + + + Listening to "%1" by %2. %3 + Klausosi "%1", atliekamą %2. %3 + + + + Listening to "%1" by %2 on "%3". %4 + Klausosi "%1", atliekamą %2 iš albumo "%3". %4 + + + + %1 characters left + Liko simbolių: %1 + + + + SourceDelegate + + + Track + Takelis + + + + Album + Albumas + + + + Artist + Atlikėjas + + + + Local + + + + + Top 10 + Top 10 + + + + All available tracks + Visi prieinami takeliai + + + + + Show + Rodyti + + + + + Hide + Slėpti + + + + SourceInfoWidget + + + Recent Albums + + + + + Latest Additions + Naujai pridėta + + + + Recently Played Tracks + Neseniai klausyti takeliai + + + + New Additions + Naujai pridėta + + + + My recent activity + Paskiausia mano veikla + + + + Recent activity from %1 + + + + + SourceItem + + + Collection + Kolekcija + + + + + Latest Additions + Neseniai pridėta + + + + Recently Played + Neseniai grota + + + + SuperCollection + Super Kolekcija + + + + Latest additions to your collection + Neseniai pridėta prie Jūsų kolekcijos + + + + Latest additions to %1's collection + Neseniai pridėta prie %1 kolekcijos + + + + Sorry, we could not find any recent additions! + Atsiprašome, neradome nieko, kas pridėta neseniai! + + + + Recently Played Tracks + Neseniai groti takeliai + + + + Your recently played tracks + Jūsų neseniai groti takeliai + + + + %1's recently played tracks + %1 neseniai groti takeliai + + + + Sorry, we could not find any recent plays! + Atsiprašome, neradome jokių neseniai grotų takelių! + + + + SourceTreeView + + + &Copy Link + &Kopijuoti nuorodą + + + + &Delete %1 + Paša&linti %1 + + + + Add to my Playlists + Pridėti prie mano grojaraščių + + + + Add to my Automatic Playlists + Pridėti prie mano automatinių grojaraščių + + + + Add to my Stations + Pridėti prie mano stočių + + + + &Export Playlist + + + + + playlist + grojaraštis + + + + automatic playlist + automatinis grojaraštis + + + + station + stotis + + + + Would you like to delete the %1 <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + Ar norite pašalinti %1 <b>"%2"</b>? + + + + Delete + Pašalinti + + + + Save XSPF + Išsaugoti XSPF + + + + Playlists (*.xspf) + Grojaraščiai (*.xspf) + + + + SourcesModel + + + Group + + + + + Collection + Kolekcija + + + + Playlist + Grojaraštis + + + + Automatic Playlist + Automatinis grojaraštis + + + + Station + Stotis + + + + Browse + Naršyti + + + + Search History + Paieškos istorija + + + + My Music + Mano muzika + + + + SuperCollection + Super Kolekcija + + + + Dashboard + Skydelis + + + + Recently Played + Neseniai klausyta + + + + Charts + + + + + New Releases + Nauji leidimai + + + + Friends + Draugai + + + + SpotifyConfig + + + Form + Forma + + + + Configure your Spotify account + Konfigūruoti Jūsų Spotify paskyrą + + + + Username or Facebook Email + Vartotojo vardas arba Facebook elektroninis paštas + + + + Log In + Prisijungti + + + + Right click on any Tomahawk playlist to sync it to Spotify. + Dešiniu pelės klavišu spustelėkite ant bet kurio Tomahawk grojaraščio, jei norite sinchronizuoti jį su Spotify. + + + + High Quality Streams + Aukštos kokybės srautai + + + + Spotify playlists to keep in sync: + Sinchronizuojami Spotify grojaraščiai: + + + + Delete Tomahawk playlist when removing synchronization + Ištrinti Tomahawk grojaraštį kai panaikinamas sinchronizavimas + + + + Username: + Vartotojo vardas: + + + + Password: + Slaptažodis: + + + + SpotifyPlaylistUpdater + + + Delete associated Spotify playlist? + Pašalinti susietą Spotify grojaraštį? + + + + StackedSettingsDialog + + + Tomahawk Settings + Tomahawk nuostatos + + + + Path to scan for music files: + + + + + The Echo Nest supports keeping track of your catalog metadata + and using it to craft personalized radios. Enabling this option + will allow you (and all your friends) to create automatic playlists + and stations based on your personal taste profile. + + + + + Upload collection list to The Echo Nest to enable user radio + + + + + Watch for changes + Sekti pokyčius + + + + Time between scans, in seconds: + + + + + Remote Peer Connection Method + + + + + None (outgoing connections only) + + + + + Use UPnP to establish port forward (recommended) + + + + + Use static external IP address/host name and port + + + + + Set this to your external IP address or host name. Make sure to forward the port to this host! + + + + + SOCKS Proxy + SOCKS Proxy + + + + Use SOCKS Proxy + Naudoti SOCKS Proxy + + + + Clear All Access Control Entries + + + + + Install from file... + Įdiegti iš failo... + + + + Filter by capability: + Filtruoti pagal gebėjimą: + + + + Static Host Name: + Statinis serverio vardas: + + + + Static Port: + Statinis prievadas: + + + + Proxy Settings... + Proxy nuostatos... + + + + Other Settings + Kitos nuostatos + + + + Send reports after Tomahawk crashed + Siųsti ataskaitas apie Tomahawk strigtis + + + + Allow web browsers to interact with Tomahawk (recommended) + Leisti žiniatinklio naršyklėms sąveikauti su Tomahawk (rekomenduojama) + + + + TemporaryPageItem + + + Copy Artist Link + Kopijuoti atlikėjo nuorodą + + + + Copy Album Link + Kopijuoti albumo nuorodą + + + + Copy Track Link + Kopijuoti takelio nuorodą + + + + Tomahawk::Accounts::AccountDelegate + + + Add Account + Pridėti paskyrą + + + + Remove + Pašalinti + + + + %1 downloads + %1 atsisiuntimų + + + + Online + Prisijungęs + + + + Connecting... + Jungiamasi... + + + + Offline + Atsijungęs + + + + Tomahawk::Accounts::AccountModel + + + Manual Install Required + Reikalingas rankinis įdiegimas + + + + Unfortunately, automatic installation of this resolver is not available or disabled for your platform.<br /><br />Please use "Install from file" above, by fetching it from your distribution or compiling it yourself. Further instructions can be found here:<br /><br />http://www.tomahawk-player.org/resolvers/%1 + + + + + Tomahawk::Accounts::GoogleWrapper + + + Configure this Google Account + Konfigūruoti šią Google paskyrą + + + + Google Address + Google adresas + + + + Enter your Google login to connect with your friends using Tomahawk! + + + + + username@gmail.com + + + + + Tomahawk::Accounts::GoogleWrapperFactory + + + Connect to Google Talk to find your friends + Prisijungti prie Google Talk tam, kad rasti draugų + + + + Tomahawk::Accounts::GoogleWrapperSip + + + Add Friend + Pridėti draugą + + + + Enter Google Address: + Įveskite Google adresą: + + + + Tomahawk::Accounts::LastFmAccountFactory + + + Scrobble your tracks to last.fm, and find freely downloadable tracks to play + + + + + Tomahawk::Accounts::LastFmConfig + + + Testing... + Bandoma... + + + + Test Login + Išbandyti prisijungimą + + + + Importing %1 + e.g. Importing 2012/01/01 + Įkeliama %1 + + + + Importing History... + Įkeliama istorija... + + + + History Incomplete. Resume + Istorija nepilna. Tęskite + + + + Playback History Imported + Klausymosi istorija įkelta + + + + + Failed + Nepavyko + + + + Success + + + + + Could not contact server + + + + + Synchronizing... + + + + + Synchronization Finished + + + + + Tomahawk::Accounts::SpotifyAccount + + + Sync with Spotify + Sinchronizuoti su Spotify + + + + Re-enable syncing with Spotify + Iš naujo įjungti sinchronizavimą su Spotify + + + + Create local copy + Sukurti vietinę kopiją + + + + Subscribe to playlist changes + Sekti grojaraščio pokyčius + + + + Re-enable playlist subscription + Sekti grojarašio atnaujinimus iš naujo + + + + Stop subscribing to changes + Nebesekti grojaraščio pokyčių + + + + Stop syncing with Spotify + Stabdyti sinchronizavimą su Spotify + + + + Tomahawk::Accounts::SpotifyAccountConfig + + + Logging in... + Prisijungiama... + + + + Failed: %1 + Nepavyko: %1 + + + + Logged in as %1 + Prisijungta kaip %1 + + + + Log Out + Atsijungti + + + + + Log In + Prisijungti + + + + Tomahawk::Accounts::SpotifyAccountFactory + + + Play music from and sync your playlists with Spotify Premium + + + + + Tomahawk::Accounts::TwitterAccountFactory + + + Connect to your Twitter followers. + + + + + Tomahawk::Accounts::TwitterConfigWidget + + + + + Tweet! + + + + + + Status: No saved credentials + Būsena: Nėra išsaugotų prisijungimo duomenų + + + + + + Authenticate + Nustatyti tapatybę + + + + + Status: Credentials saved for %1 + + + + + + De-authenticate + + + + + + + + + + + Tweetin' Error + + + + + The credentials could not be verified. +You may wish to try re-authenticating. + + + + + Status: Error validating credentials + Būsena: Klaida tikrinant prisijungimo duomenis + + + + Global Tweet + + + + + Direct Message + Tiesioginė žinutė + + + + Send Message! + Siųsti žinutę! + + + + @Mention + + + + + Send Mention! + + + + + You must enter a user name for this type of tweet. + + + + + Your saved credentials could not be loaded. +You may wish to try re-authenticating. + + + + + Your saved credentials could not be verified. +You may wish to try re-authenticating. + + + + + + There was an error posting your status -- sorry! + Įvyko klaida siunčiant Jūsų būseną -- atsiprašome! + + + + + Tweeted! + + + + + Your tweet has been posted! + + + + + There was an error posting your direct message -- sorry! + + + + + Your message has been posted! + Jūsų žinutė sėkmingai išsiųsta! + + + + Tomahawk::Accounts::XmppAccountFactory + + + Log on to your Jabber/XMPP account to connect to your friends + + + + + Tomahawk::Accounts::ZeroconfFactory + + + Automatically connect to Tomahawks on the local network + + + + + Tomahawk::ContextMenu + + + &Play + &Groti + + + + + + Add to &Queue + Pridėti į &eilę + + + + Continue Playback after this &Track + Tęsti grojimą po šio &takelio + + + + Stop Playback after this &Track + Sustabdyti grojimą po šio &takelio + + + + + &Love + My&liu + + + + &Copy Track Link + &Kopijuoti takelio nuorodą + + + + Copy Album &Link + Kopijuoti albumo &nuorodą + + + + Copy Artist &Link + Kopijuoti atlikėjo &nuorodą + + + + Un-&Love + Nemy&liu + + + + &Delete Items + Iš&trinti elementus + + + + &Show Track Page + &Rodyti takelio puslapį + + + + Properties... + Savybės... + + + + &Delete Item + Iš&trinti elementą + + + + &Show Album Page + &Rodyti albumo puslapį + + + + &Show Artist Page + &Rodyti atlikėjo puslapį + + + + Tomahawk::DropJobNotifier + + + playlist + grojaraštis + + + + artist + atlikėjas + + + + track + takelis + + + + album + albumas + + + + Fetching %1 from database + Gaunama %1 iš duomenų bazės + + + + Parsing %1 %2 + Nagrinėjama %1 %2 + + + + Tomahawk::DynamicControlList + + + Click to collapse + Spustelėkite, kad suskleisti + + + + Tomahawk::DynamicModel + + + + Could not find a playable track. + +Please change the filters or try again. + + + + + Failed to generate preview with the desired filters + + + + + Tomahawk::DynamicSetupWidget + + + Type: + Tipas: + + + + Generate + Kurti + + + + Tomahawk::DynamicView + + + Add some filters above to seed this station! + + + + + Press Generate to get started! + Spauskite "Kurti", kad pradėti! + + + + Add some filters above, and press Generate to get started! + + + + + Tomahawk::DynamicWidget + + + Station ran out of tracks! + +Try tweaking the filters for a new set of songs to play. + + + + + Tomahawk::EchonestControl + + + + + + + + is + yra + + + + from user + + + + + + No users with Echo Nest Catalogs enabled. Try enabling option in Collection settings + + + + + similar to + panašus į + + + + + + + + + + Less + Mažiau + + + + + + + + + + More + Daugiau + + + + 0 BPM + 0 taktų per minutę + + + + 500 BPM + 500 taktų per minutę + + + + 0 secs + 0 sekundžių + + + + 3600 secs + 3600 sekundžių + + + + -100 dB + -100 dB + + + + 100 dB + -100 dB + + + + Major + Mažorinis + + + + Minor + Minorinis + + + + C + + + + + C Sharp + + + + + D + + + + + E Flat + + + + + E + + + + + F + + + + + F Sharp + + + + + G + + + + + A Flat + + + + + A + + + + + B Flat + + + + + B + + + + + Ascending + Didėjančiai + + + + Descending + Mažėjančiai + + + + Tempo + Tempas + + + + Duration + Trukmė + + + + Loudness + Garsumas + + + + Artist Familiarity + + + + + Artist Hotttnesss + + + + + Song Hotttnesss + + + + + Latitude + Platuma + + + + Longitude + Ilguma + + + + Mode + + + + + Key + + + + + Energy + Energija + + + + Danceability + + + + + only by ~%1 + + + + + similar to ~%1 + + + + + with genre ~%1 + + + + + + from no one + + + + + My Collection + Mano kolekcija + + + + from %1 radio + + + + + with %1 %2 + + + + + about %1 BPM + + + + + about %n minute(s) long + apytikriai %n minutės ilgioapytikriai %n minučių ilgioapytikriai %n minučių ilgio + + + + about %1 dB + apie %1 dB + + + + at around %1%2 %3 + + + + + in %1 + + + + + in a %1 key + + + + + sorted in %1 %2 order + + + + + with a %1 mood + + + + + in a %1 style + + + + + Tomahawk::EchonestSteerer + + + Steer this station: + + + + + Much less + Žymiai mažiau + + + + Less + Mažiau + + + + A bit less + Šiek tiek mažiau + + + + Keep at current + + + + + A bit more + Šiek tiek daugiau + + + + More + Daugiau + + + + Much more + Žymiai daugiau + + + + Tempo + Tempas + + + + Loudness + Garsumas + + + + Danceability + + + + + Energy + Energija + + + + Song Hotttnesss + + + + + Artist Hotttnesss + + + + + Artist Familiarity + + + + + By Description + Pagal apibūdinimą + + + + Enter a description + Įveskite apibūdinimą + + + + Apply steering command + + + + + Reset all steering commands + + + + + Tomahawk::GroovesharkParser + + + Error fetching Grooveshark information from the network! + + + + + Tomahawk::InfoSystem::ChartsPlugin + + + Top Overall + + + + + Artists + Atlikėjai + + + + Albums + Albumai + + + + Tracks + Takeliai + + + + Tomahawk::InfoSystem::FdoNotifyPlugin + + + Tomahawk is playing "%1" by %2%3. + Tomahawk groja "%1" atliekamą %2%3. + + + + on "%1" + iš albumo "%1" + + + + Tomahawk::InfoSystem::LastFmInfoPlugin + + + Top Tracks + Populiariausi takeliai + + + + Loved Tracks + Mylimi takeliai + + + + Hyped Tracks + + + + + Top Artists + Populiariausi atlikėjai + + + + Hyped Artists + + + + + Tomahawk::InfoSystem::NewReleasesPlugin + + + Albums + Albumai + + + + Tomahawk::InfoSystem::TwitterInfoPlugin + + + Listening to "%1" by %2 and loving it! %3 + + + + + Tomahawk::ItunesParser + + + Error fetching iTunes information from the network! + + + + + Tomahawk::JSPFLoader + + + New Playlist + Naujas grojaraštis + + + + Failed to save tracks + Nepavyko išsaugoti dainų + + + + Some tracks in the playlist do not contain an artist and a title. They will be ignored. + + + + + XSPF Error + XSPF klaida + + + + This is not a valid XSPF playlist. + + + + + Tomahawk::LatchManager + + + &Catch Up + &Pasivyti + + + + + &Listen Along + K&lausytis kartu + + + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + Ar norite pašalinti grojaraštį <b>"%2"</b>? + + + + Delete + Pašalinti + + + + Tomahawk::Query + + + and + + + + + You + + + + + you + + + + + and + + + + + %n other(s) + + + + + %1 people + + + + + loved this track + + + + + Tomahawk::RdioParser + + + Error fetching Rdio information from the network! + + + + + Tomahawk::ShortenedLinkParser + + + Network error parsing shortened link! + + + + + Tomahawk::Source + + + + Scanning (%L1 tracks) + Peržvelgiama (%L1 takeliai) + + + + Scanning + Peržvelgiama + + + + Checking + Tikrinama + + + + Syncing + Sinchronizuojama + + + + Importing + Įkeliama + + + + Saving (%1%) + Išsaugoma (%1%) + + + + Online + Prisijungęs + + + + Offline + Atsijungęs + + + + Tomahawk::SpotifyParser + + + Error fetching Spotify information from the network! + + + + + Tomahawk::XspfUpdater + + + Automatically update from XSPF + Automatiškai atnaujinti iš XSPF + + + + TomahawkApp + + + My Collection + Mano kolekcija + + + + TomahawkOAuthTwitter + + + Twitter PIN + Twitter PIN + + + + After authenticating on Twitter's web site, +enter the displayed PIN number here: + + + + + TomahawkTrayIcon + + + &Stop Playback after current Track + Sta&bdyti grojimą po dabartinio takelio + + + + + Hide Tomahawk Window + Slėpti Tomahawk langą + + + + Show Tomahawk Window + Rodyti Tomahawk langą + + + + Currently not playing. + Šiuo metu negrojama. + + + + Play + Groti + + + + Pause + Pristabdyti + + + + &Love + &Myliu + + + + Un-&Love + &Nemyliu + + + + &Continue Playback after current Track + &Tęsti grojimą po dabartinio takelio + + + + TomahawkWindow + + + Tomahawk + Tomahawk + + + + &Settings + &Nuostatos + + + + &Controls + &Valdymas + + + + &Network + Ti&nklas + + + + &Window + &Langas + + + + &Help + Ž&inynas + + + + &Quit + &Baigti darbą + + + + Ctrl+Q + Ctrl+Q + + + + Go &Online + Prisi&jungti + + + + Add &Friend... + Pridėti &draugą... + + + + U&pdate Collection + At&naujinti kolekciją + + + + Update Collection + Atnaujinti kolekciją + + + + &Configure Tomahawk... + &Konfigūruoti Tomahawk... + + + + Load &XSPF... + Įkelti &XSPF... + + + + Create &New Playlist... + Sukurti naują &grojaraštį + + + + About &Tomahawk... + Apie &Tomahawk... + + + + Create New &Automatic Playlist + Sukurti naują &automatinį grojaraštį + + + + Create New &Station + Sukurti naują &stotį + + + + Show Offline Sources + + + + + Hide Offline Sources + + + + + Minimize + Sumažinti + + + + Ctrl+M + Ctrl+M + + + + Zoom + + + + + Meta+Ctrl+Z + + + + + &Legal Info... + &Teisinė informacija... + + + + Diagnostics... + Diagnostika... + + + + Fully &Rescan Collection + Pilnai pe&ržvelgti kolekciją + + + + Fully Rescan Collection + Pilnai peržvelgti kolekciją + + + + + Play + Groti + + + + Space + Tarpas + + + + Previous + Ankstesnis + + + + Next + Kitas + + + + Back + Atgal + + + + Go back one page + Grįžti vienu puslapiu atgal + + + + Forward + Pirmyn + + + + Go forward one page + Eiti vienu puslapiu pirmyn + + + + Global Search... + Globali paieška... + + + + + Check For Updates... + Tikrinti, ar yra atnaujinimų... + + + + + + Connect To Peer + + + + + Enter peer address: + + + + + Enter peer port: + + + + + Enter peer key: + + + + + XSPF Error + XSPF klaida + + + + This is not a valid XSPF playlist. + + + + + Failed to save tracks + Nepavyko išsaugoti takelių + + + + Some tracks in the playlist do not contain an artist and a title. They will be ignored. + + + + + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. + + + + + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. + + + + + Station + Stotis + + + + Create New Station + Sukurti naują stotį + + + + Name: + Pavadinimas: + + + + Playlist + Grojaraštis + + + + Automatic Playlist + Automatinis grojaraštis + + + + Pause + Pristabdyti + + + + Go &offline + &Atsijungti + + + + Go &online + &Prisijungti + + + + Authentication Error + + + + + Error connecting to SIP: Authentication failed! + + + + + %1 by %2 + track, artist name + + + + + %1 - %2 + current track, some window title + + + + + <h2><b>Tomahawk %1<br/>(%2)</h2> + <h2><b>Tomahawk %1<br/>(%2)</h2> + + + + <h2><b>Tomahawk %1</h2> + <h2><b>Tomahawk %1</h2> + + + + Copyright 2010 - 2012 + Autorinės teisės 2010 - 2012 + + + + Thanks to: + Dėkojame: + + + + About Tomahawk + Apie Tomahawk + + + + TopTracksContext + + + Top Hits + + + + + TrackInfoWidget + + + Form + Forma + + + + Cover + Viršelis + + + + Track + Takelis + + + + Artist + Atlikėjas + + + + Album + Albumas + + + + Statistics + Statistika + + + + Similar Tracks + Panašūs takeliai + + + + Sorry, but we could not find similar tracks for this song! + Atsiprašome, neradome jokių į šią dainą panašių takelių! + + + + You've listened to this track %n time(s). + Jūs klausėtės šio takelio %n kartą.Jūs klausėtės šio takelio %n kartus.Jūs klausėtės šio takelio %n kartų. + + + + You've never listened to this track before. + Jūs niekad anksčiau nesiklausėte šio takelio. + + + + You first listened to it on %1. + Pirmąkart klausėtės jo %1. + + + + You've listened to %1 %n time(s). + Jūs klausėtės %1 %n kartą.Jūs klausėtės %1 %n kartus.Jūs klausėtės %1 %n kartų. + + + + You've never listened to %1 before. + Jūs niekada anksčiau nesiklausėte %1. + + + + TrackView + + + Sorry, your filter '%1' did not match any results. + + + + + TransferStatusItem + + + from + streaming artist - track from friend + + + + + to + streaming artist - track to friend + + + + + TreeItemDelegate + + + Unknown + + + + + TreeModel + + + All Artists + Visi atlikėjai + + + + + My Collection + Mano kolekcija + + + + + Collection of %1 + + + + + TreeView + + + Sorry, your filter '%1' did not match any results. + Atsiprašome, Jūsų užklausa '%1' neatitiko jokių rezultatų. + + + + TwitterConfigWidget + + + Configure this Twitter account + Konfigūruoti šią Twitter paskyrą + + + + The Twitter plugin allows you to discover and play music from your Twitter friends running Tomahawk and post messages to your account. + + + + + Status: No saved credentials + Būsena: Nėra išsaugotų prisijungimo duomenų + + + + Authenticate with Twitter + + + + + Twitter Connections + + + + + +If you only want to post tweets, you're done. + +If you want to connect Tomahawk to your friends using Twitter, select the type of tweet and press the button below to send a sync message. You must both be following each other as Direct Messages are used. Then be (very) patient -- it can take several minutes! + +You can re-send a sync message at any time simply by sending another tweet using the button. + + + + + Select the kind of tweet you would like, then press the button to post it: + + + + + Global Tweet + + + + + @Mention + + + + + Direct Message + Tiesioginė žinutė + + + + e.g. @tomahawk + pvz. @tomahawk + + + + Send Message + + + + + ViewManager + + + After you have scanned your music collection you will find your tracks right here. + Peržvelgus Jūsų muzikos kolekciją, savo takelius galėsite rasti čia akimirksniu. + + + + This collection is empty. + Ši kolekcija yra tuščia. + + + + SuperCollection + Super kolekcija + + + + Combined libraries of all your online friends + Jungtinė visų Jūsų prisijungusių draugų kolekcija + + + + Recently Played Tracks + Neseniai groti takeliai + + + + Recently played tracks from all your friends + Visų Jūsų draugų neseniai groti takeliai + + + + Sorry, we could not find any recent plays! + + + + + WelcomeWidget + + + Recent Additions + Neseniai pridėta + + + + Newest Stations & Playlists + Naujausios stotys ir grojaraščiai + + + + Recently Played Tracks + Neseniai groti takeliai + + + + No recently created playlists in your network. + Jūsų tinkle nėra neseniai sukurtų grojaraščių. + + + + Welcome to Tomahawk + + + + + WhatsHotWidget + + + Charts + + + + + WikipediaContext + + + Wikipedia + Vikipedija + + + + XMPPBot + + + +Terms for %1: + + + + + + No terms found, sorry. + + + + + +Hotttness for %1: %2 + + + + + + +Familiarity for %1: %2 + + + + + + +Lyrics for "%1" by %2: + +%3 + + + + + + XSPFLoader + + + Failed to parse contents of XSPF playlist + + + + + Some playlist entries were found without artist and track name, they will be omitted + + + + + Failed to fetch the desired playlist from the network, or the desired file does not exist + + + + + New Playlist + Naujas grojaraštis + + + + XmlConsole + + + Xml stream console + Xml srauto pultas + + + + + Filter + + + + + Save log + Išsaugoti žurnalą + + + + Disabled + Išjungta + + + + By JID + Pagal JID + + + + By namespace uri + Pagal vardų erdvės uri + + + + By all attributes + Pagal visus požymius + + + + Visible stanzas + + + + + Information query + + + + + Message + + + + + Presence + + + + + Custom + + + + + Close + Užverti + + + + Save XMPP log to file + Išsaugoti XMPP žurnalą į failą + + + + OpenDocument Format (*.odf);;HTML file (*.html);;Plain text (*.txt) + OpenDocument formatas (*.odf);;HTML failas (*.html);;Paprastas tekstas (*.txt) + + + + XmppConfigWidget + + + Xmpp Configuration + Xmpp konfigūracija + + + + Configure this Xmpp account + Konfigūruoti šią Xmpp paskyrą + + + + Enter your Xmpp login to connect with your friends using Tomahawk! + Įveskite savo Xmpp prisijungimo duomenis, jei norite prisijungti prie savo draugų, besinaudojančių Tomahawk! + + + + Login Information + Prisijungimo informacija + + + + Xmpp ID: + Xmpp ID: + + + + e.g. user@example.com + pvz. user@example.com + + + + Password: + Slaptažodis: + + + + An account with this name already exists! + Paskyra šiuo vardu jau yra! + + + + Advanced Xmpp Settings + Išplėstinės Xmpp nuostatos + + + + Server: + Serveris: + + + + Port: + Prievadas: + + + + Lots of servers don't support this (e.g. GTalk, jabber.org) + Daugybė serverių to nepalaiko (pvz. GTalk, jabber.org) + + + + Publish currently playing track + Viešinti šiuo metu grojamą takelį + + + + Enforce secure connection + Priverstinai naudoti saugų prisijungimą + + + + XmppSipPlugin + + + User Interaction + Vartotojo sąveika + + + + Host is unknown + Serveris nežinomas + + + + Item not found + Elementas nerastas + + + + Authorization Error + Tapatybės patvirtinimo klaida + + + + Remote Stream Error + Nuotolinio srauto klaida + + + + Remote Connection failed + Nuotolinis prisijungimas nepavyko + + + + Internal Server Error + Vidinė serverio klaida + + + + System shutdown + + + + + Conflict + Konfliktas + + + + Unknown + + + + + Do you want to add <b>%1</b> to your friend list? + Ar norite pridėti <b>%1</b> prie savo draugų sąrašo? + + + + No Compression Support + Nėra glaudinimo palaikymo + + + + No Encryption Support + Nėra užšifravimo palaikymo + + + + No Authorization Support + + + + + No Supported Feature + + + + + Add Friend + Pridėti draugą + + + + Enter Xmpp ID: + Įveskite Xmpp ID: + + + + Add Friend... + Pridėti draugą... + + + + XML Console... + XML pultas... + + + + I'm sorry -- I'm just an automatic presence used by Tomahawk Player (http://gettomahawk.com). If you are getting this message, the person you are trying to reach is probably not signed on, so please try again later! + + + + + Authorize User + + + + + ZeroconfConfig + + + Form + Forma + + + + Local Network configuration + Vietinio tinklo konfigūracija + + + + This plugin will automatically find other users running Tomahawk on your local network + + + + + Connect automatically when Tomahawk starts + Prisijungti automatiškai kai Tomahawk paleidžiamas + + + \ No newline at end of file diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index 4b7d2cfd6..b551391b3 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -145,17 +145,17 @@ connect and stream from you? Inne albumy artysty - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Inne albumy %1 @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Pokaż przypisy - + Hide Footnotes Schowaj przypisy @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1221,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection Kolekcje - + Advanced Zaawansowane - + All Wszystkie - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services Usługi - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Informacja @@ -1472,69 +1497,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Kopiuj Link - + &Delete %1 &Usuń %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist &Eksportuj Listę - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF Zapisz XSPF - + Playlists (*.xspf) Listy (*.xspf) @@ -1668,13 +1692,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -1686,17 +1705,12 @@ connect and stream from you? Ustawienia Tomahawk - - Local Music Information - Informacje o Lokalnej Muzyce - - - + Path to scan for music files: Ścieżka poszukiwania plików muzycznych: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1708,107 +1722,97 @@ tworzenie automatycznych list i stacji na podstawie twojego indywidualnego profilu gustu. - + Upload collection list to The Echo Nest to enable user radio Wyślij informacje o kolekcji do The Echo Nest, aby włączyć radio użytkownika - + Watch for changes Obserwuj zmiany - + Time between scans, in seconds: Czas pomiędzy skanami, w sekundach: - - Advanced Settings - - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy - + Use SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - Usługi internetowe - - - + Install from file... Zainstaluj z pliku... - + Filter by capability: - + Static Host Name: Nazwa statycznego hosta: - + Static Port: Statyczny Port: - + Proxy Settings... Ustawienia Proxy... - + Other Settings - + Send reports after Tomahawk crashed Wysyłaj zgłoszenia po awarii Tomahawka - + Allow web browsers to interact with Tomahawk (recommended) @@ -1924,7 +1928,7 @@ indywidualnego profilu gustu. Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1932,52 +1936,62 @@ indywidualnego profilu gustu. Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed - + Success - + Could not contact server + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2860,7 +2874,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Albumy @@ -2923,40 +2937,54 @@ Try tweaking the filters for a new set of songs to play. &Słuchaj razem + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and i - + You Ty - + you ty - + and i - + %n other(s) %n inny%n inne%n innych - + %1 people - + loved this track @@ -3024,7 +3052,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! @@ -3253,7 +3281,7 @@ wprowadź pokazany numer PIN tutaj: - + Play Odtwarzaj @@ -3273,172 +3301,172 @@ wprowadź pokazany numer PIN tutaj: Następny - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... Globalne Wyszukiwanie... - - + + Check For Updates... Sprawdź uaktualnienia... - - - + + + Connect To Peer - + Enter peer address: - + Enter peer port: - + Enter peer key: - + XSPF Error Błąd XSPF - + This is not a valid XSPF playlist. To nie jest poprawna lista XSPF. - + Failed to save tracks Nie udało się zapisać utworów - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Niektóre utwory na liście nie zawierają artysty i tytułu. Zostaną one zignorowane. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station - + Create New Station Utwórz Nową Stację - + Name: Nazwa: - + Playlist - + Automatic Playlist - + Pause Pauza - + Go &offline Przejdź do trybu &offline - + Go &online Przejdź do trybu &online - + Authentication Error Błąd uwierzytelniania - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name %1 wykonawcy %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk @@ -3489,32 +3517,32 @@ wprowadź pokazany numer PIN tutaj: - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). - + You've never listened to this track before. - + You first listened to it on %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. @@ -3532,12 +3560,14 @@ wprowadź pokazany numer PIN tutaj: from - od + streaming artist - track from friend + to - do + streaming artist - track to friend + @@ -3652,37 +3682,37 @@ Zawsze możesz ponownie wysłać wiadomość synchronizacyjną - po prostu wyśl ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection SuperKolekcja - + Combined libraries of all your online friends Połączone biblioteki wszystkich twoich znajomych online - + Recently Played Tracks - + Recently played tracks from all your friends - + Sorry, we could not find any recent plays! @@ -3705,12 +3735,12 @@ Zawsze możesz ponownie wysłać wiadomość synchronizacyjną - po prostu wyśl Ostatnio Odtworzone Utwory - + No recently created playlists in your network. Brak ostatnio utworzonych list w twojej sieci. - + Welcome to Tomahawk Witaj w Tomahawk diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index d33e59fa4..313c85204 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -146,17 +146,17 @@ se conecte e faça o stream de você? Outros álbuns do artista - + Sorry, we could not find any other albums for this artist! Desculpe, mas não conseguimos encontrar outro álbum para este artista! - + Sorry, we could not find any tracks for this album! Desculpe, mas não conseguimos encontrar outras faixas para este álbum! - + Other Albums by %1 Outros álbuns de %1 @@ -304,17 +304,17 @@ se conecte e faça o stream de você? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 Desculpe, o Tomahawk não encontrou a faixa '%1' de %2 - + Sorry, Tomahawk couldn't find the artist '%1' Desculpe, o Tomahawk não encontrou o artista '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 Desculpe, o Tomahawk não encontrou o álbum '%1' de %2 @@ -374,12 +374,12 @@ se conecte e faça o stream de você? - + Show Footnotes Mostrar Notas de Rodapé - + Hide Footnotes Ocultar Notas de Rodapé @@ -551,6 +551,11 @@ se conecte e faça o stream de você? Import Playback History Importar Histórico de Reprodução + + + Synchronize Loved Tracks + + LastfmContext @@ -1223,47 +1228,67 @@ se conecte e faça o stream de você? SettingsDialog - + Collection Coleção - + Advanced Avançado - + All Todos - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted Algumas configurações não terão efeito até que o Tomahawk seja reiniciado - + Services Serviços - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Instalar resolvedor via arquivo - + Delete all Access Control entries? Excluir todas as entradas de controle de acesso? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. Você realmente quer apagar todas as entradas de controle de acesso? Você será solicitado a tomar uma decisão para cada ponto a que você se conectar. - + Information Informação @@ -1474,69 +1499,68 @@ se conecte e faça o stream de você? SourceTreeView - + &Copy Link &Copiar link - + &Delete %1 &Excluir %1 - + Add to my Playlists Adicionar às minhas Playlists - + Add to my Automatic Playlists Adicionar às minhas Playlists Automáticas - + Add to my Stations Adicionar às minhas Estações - + &Export Playlist &Exportar Playlist - + playlist playlist - + automatic playlist playlist automática - + station estação - - Delete %1? - playlist/station/... - Deletar %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? Gostaria de deletar a %1 <b>"%2"</b>? - + + Delete + + + + Save XSPF Salvar XSPF - + Playlists (*.xspf) Playlists (*.xspf) @@ -1670,14 +1694,9 @@ se conecte e faça o stream de você? SpotifyPlaylistUpdater - - Delete in Spotify? - Deletar no Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? - Você também gostaria de deletar a playlist correspondente no Spotify? + + Delete associated Spotify playlist? + @@ -1688,17 +1707,12 @@ se conecte e faça o stream de você? Configurações do Tomahawk - - Local Music Information - Informação de Músicas Locais - - - + Path to scan for music files: Caminho para os arquivos de música: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1709,107 +1723,97 @@ irá permitir a você (e seus amigos) criar playlists e estações automáticas baseadas no seu gosto pessoal. - + Upload collection list to The Echo Nest to enable user radio Carregar coleção ao Echo Nest para habilitar a rádio do usuário - + Watch for changes Acompanhar alterações - + Time between scans, in seconds: Tempo entre escaneamentos, em segundos: - - Advanced Settings - Configurações Avançadas - - - + Remote Peer Connection Method Método de Conexão Remota por Peer - + None (outgoing connections only) Nenhum (somente conexões de saída) - + Use UPnP to establish port forward (recommended) Use UPnP para estabelecer o encaminhamento de porta (recomendado) - + Use static external IP address/host name and port Use endereço IP, nome de servidor e porta estáticos externos. - + Set this to your external IP address or host name. Make sure to forward the port to this host! Defina esta opção para o seu endereço de IP externo ou servidor. Certifique-se de encaminhar a porta para este servidor! - + SOCKS Proxy Proxy SOCKS - + Use SOCKS Proxy Utilizar Proxy SOCKS - + Clear All Access Control Entries Limpar todas as entradas de controle de acesso - - Internet Services - Serviços de Internet - - - + Install from file... Instalar via arquivo... - + Filter by capability: Filtrar por capacidade: - + Static Host Name: Nome do Servidor Estático: - + Static Port: Porta Estática: - + Proxy Settings... Configurações de Proxy... - + Other Settings Outras configurações - + Send reports after Tomahawk crashed Enviar informações caso o Tomahawk trave - + Allow web browsers to interact with Tomahawk (recommended) Permitir que navegadores web interajam com o Tomahawk (recomendado) @@ -1925,7 +1929,7 @@ automáticas baseadas no seu gosto pessoal. Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play Faça o scrobble para o last.fm e encontre faixas gratuitas para reproduzir @@ -1933,52 +1937,62 @@ automáticas baseadas no seu gosto pessoal. Tomahawk::Accounts::LastFmConfig - + Testing... Testando... - + Test Login Testar Login - + Importing %1 e.g. Importing 2012/01/01 Importando %1 - + Importing History... Importando Histórico... - + History Incomplete. Resume Histórico Incompleto. Retomar - + Playback History Imported Reproduzir Histórico Importado - - + + Failed Falhou - + Success Sucesso - + Could not contact server Não foi possível contatar o servidor + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2866,7 +2880,7 @@ Tente ajustar os filtros para ouvir um novo conjunto de músicas. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Álbuns @@ -2929,40 +2943,54 @@ Tente ajustar os filtros para ouvir um novo conjunto de músicas. &Ouvir Junto + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and e - + You Você - + you você - + and e - + %n other(s) %n outro%n outros - + %1 people %1 pessoas - + loved this track favoritou essa faixa @@ -3030,7 +3058,7 @@ Tente ajustar os filtros para ouvir um novo conjunto de músicas. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Erro ao obter informações do Spotify pela rede! @@ -3259,7 +3287,7 @@ colocar o número PIN mostrado aqui: - + Play Reporduzir @@ -3279,172 +3307,172 @@ colocar o número PIN mostrado aqui: Próximo - + Back Voltar - + Go back one page Voltar uma página - + Forward Avançar - + Go forward one page Avançar uma página - + Global Search... Busca global... - - + + Check For Updates... Buscar atualizações... - - - + + + Connect To Peer Conectar-se ao par - + Enter peer address: Coloque o endereço do par: - + Enter peer port: Coloque a porta do par: - + Enter peer key: Coloque a chave do par: - + XSPF Error Erro de XSPF - + This is not a valid XSPF playlist. Esta não é uma lista de reprodução XSPF válida. - + Failed to save tracks Falha ao salvar faixas - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Algumas faixas da lista de reprodução não contem artista e título. Estas serão ignoradas. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. Desculpe, há um problema ao acessar sua placa de áudio ou a faixa desejada, a faixa atual será ignorada. Certifique-se de ter um backend do Phonon adequado e os plugins necessários instalados. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Desculpe, há um problema ao acessar sua placa de áudio ou a faixa desejada, a faixa atual será ignorada. - + Station Estação - + Create New Station Criar uma nova estação - + Name: Nome: - + Playlist Playlist - + Automatic Playlist Playlist Automática - + Pause PIN do Twitter - + Go &offline Desc&onectar - + Go &online C&onectar - + Authentication Error Erro de autenticação - + Error connecting to SIP: Authentication failed! Erro ao conectar ao SIP: Falha de autenticação! - + %1 by %2 track, artist name %1 de %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Copyright 2010 - 2012 - + Thanks to: Agradecimentos: - + About Tomahawk Sobre o Tomahawk @@ -3495,32 +3523,32 @@ colocar o número PIN mostrado aqui: Faixas Similares - + Sorry, but we could not find similar tracks for this song! Desculpe, mas não conseguimos encontrar faixas similares para esta música! - + You've listened to this track %n time(s). Você ouviu esta faixa %n vez.Você ouviu esta faixa %n vezes. - + You've never listened to this track before. Você nunca ouviu esta faixa antes. - + You first listened to it on %1. Você ouviu pela primeira vez em %1. - + You've listened to %1 %n time(s). Você ouviu %1 %n vez.Você ouviu %1 %n vezes. - + You've never listened to %1 before. Você nunca ouviu %1 antes. @@ -3538,12 +3566,14 @@ colocar o número PIN mostrado aqui: from - de + streaming artist - track from friend + to - para + streaming artist - track to friend + @@ -3658,37 +3688,37 @@ Você pode enviar uma outra mensagem de sincronia a qualquer momento simplesment ViewManager - + After you have scanned your music collection you will find your tracks right here. Depois de escanear sua biblioteca de músicas as faixas irão aparecer aqui. - + This collection is empty. Esta coleção esta vazia. - + SuperCollection SuperColeção - + Combined libraries of all your online friends Bibliotecas combinadas de todos os seus amigos online - + Recently Played Tracks Faixas Reproduzidas Recentemente - + Recently played tracks from all your friends Faixas reproduzidas recentemente por todos os seus amigos - + Sorry, we could not find any recent plays! @@ -3711,12 +3741,12 @@ Você pode enviar uma outra mensagem de sincronia a qualquer momento simplesment Faixas reproduzidas recentemente - + No recently created playlists in your network. Nenhuma lista de reprodução criada recentemente na sua rede. - + Welcome to Tomahawk Bem-vindo ao Tomahawk diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts index 7d42754ce..26e921da8 100644 --- a/lang/tomahawk_ru.ts +++ b/lang/tomahawk_ru.ts @@ -5,17 +5,18 @@ Allow %1 to connect and stream from you? - + Разрешить %1 ⏎ +подключиться и слушать ваш поток? Allow Streaming - + Разрешить Поток Deny Access - + Запретить доступ @@ -145,17 +146,17 @@ connect and stream from you? Другие альбомы артиста - + Sorry, we could not find any other albums for this artist! - + К сожалению, мы не смогли найти другие альбомы этого исполнителя! - + Sorry, we could not find any tracks for this album! - + К сожалению, мы не смогли найти никаких треков для этого альбома! - + Other Albums by %1 Другие альбомы %1 @@ -204,22 +205,22 @@ connect and stream from you? Cover - + Обложка Sorry, we could not find any albums for this artist! - + К сожалению, мы не смогли найти никаких альбомов этого исполнителя! Sorry, we could not find any related artists! - + К сожалению, мы не смогли найти никаких исполнители! Sorry, we could not find any top hits for this artist! - + К сожалению, мы не смогли найти никаких хитов этого исполнителя! @@ -303,19 +304,19 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + К сожалению, Tomahawk не мог найти песню '%1' %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + К сожалению, Tomahawk не мог найти исполнителя '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 - + К сожалению, Tomahawk не мог найти альбом '%1' %2 @@ -373,12 +374,12 @@ connect and stream from you? - + Show Footnotes Показать Информацию об Исполнителе - + Hide Footnotes Спрятать Информацию об Исполнителе @@ -486,7 +487,7 @@ connect and stream from you? Filter... - + Фильтр... @@ -548,6 +549,11 @@ connect and stream from you? Import Playback History + Импортировать Историю Воспроизведений + + + + Synchronize Loved Tracks @@ -626,32 +632,32 @@ connect and stream from you? Top Loved Tracks - + Топ Любимых Песен Sorry, we could not find any loved tracks! - + К сожалению, мы не смогли найти никаких любимых песен! The most loved tracks from all your friends - + Любимые песни ваших друзей All of your loved tracks - + Все ваши любимые песни All of %1's loved tracks - + Все из %1 любимые песни Loved Tracks - + Любимые Песни @@ -659,107 +665,107 @@ connect and stream from you? Form - + Форма Tags - + Теги Title: - + Название: Title... - + Название... Artist: - + Исполнитель: Artist... - + Исполнитель...Алб Album: - + Альбом: Album... - + Альбом... Disc Number: - + Номер диска: Duration: - + Продолжительность: 00.00 - + 00.00 Year: - + Год: Bitrate: - + Битрей: File - + Файл File Name: - + Имя файла: File Name... - + Имя файла... File Size... - + Размер Файла... File size... - + Размер файла... File Size: - + Размер Файла: Back - + Назад Forward - + Вперед @@ -843,7 +849,7 @@ connect and stream from you? Age - + Возраст @@ -858,7 +864,7 @@ connect and stream from you? Origin - + Расположение @@ -877,12 +883,12 @@ connect and stream from you? InfoBar - + InfoBar Caption - + Заголовок @@ -894,7 +900,7 @@ connect and stream from you? RadioButton - + RadioButton @@ -1222,47 +1228,67 @@ connect and stream from you? SettingsDialog - + Collection Коллекция - + Advanced Дополнительны - + All Все - - Some changed settings will not take effect until Tomahawk is restarted + + Tomahawk Settings - + + Some changed settings will not take effect until Tomahawk is restarted + Некоторые измененные настройки не вступят в силу до перезапуска Tomahawk + + + Services Сервисы - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Установить resolver из файла - + Delete all Access Control entries? Удаление всех записей контроля доступа? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Инофрмация @@ -1320,12 +1346,12 @@ connect and stream from you? Listening to "%1" by %2. %3 - + Прослушивание "%1" %2. %3 Listening to "%1" by %2 on "%3". %4 - + Прослушивание "%1" by %2 on "%3". %4 @@ -1442,12 +1468,12 @@ connect and stream from you? Latest additions to %1's collection - + Новые поступления в коллекции %1 Sorry, we could not find any recent additions! - + К сожалению, мы не смогли найти никаких последних добавлений! @@ -1462,80 +1488,79 @@ connect and stream from you? %1's recently played tracks - + %1 последние проиграные треки Sorry, we could not find any recent plays! - + К сожалению, мы не смогли найти никаких воспроизвидений треков! SourceTreeView - + &Copy Link &Скопировать Cсылку - + &Delete %1 &Удалить %1 - + Add to my Playlists Добавить к моим Плейлистам - + Add to my Automatic Playlists Добавить к моим Автоматическим Плейлистам - + Add to my Stations Добавить к моим Станциям - + &Export Playlist &Экспорт Плейлиста - + playlist плейлист - + automatic playlist автоматический плейлист - + station станция - - Delete %1? - playlist/station/... - Удалить %1? - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? + Вы хотите удалить %1 <b>"%2"</b>? + + + + Delete - + Save XSPF Сохранить XSPF - + Playlists (*.xspf) Плейлисты (*.xspf) @@ -1638,7 +1663,7 @@ connect and stream from you? Right click on any Tomahawk playlist to sync it to Spotify. - + Щелкните правой кнопкой мыши по любому плейлисту Tomahawk для синхронизации его с Spotify. @@ -1653,7 +1678,7 @@ connect and stream from you? Delete Tomahawk playlist when removing synchronization - + Удалить плейлист Tomahawk, при удалении синхронизации. @@ -1669,13 +1694,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - Удалить в Spotify? - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -1687,17 +1707,12 @@ connect and stream from you? Настройки - - Local Music Information - Информация о локальной коллекции - - - + Path to scan for music files: Путь по которому сканировать музыку: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1705,107 +1720,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio Заргузить список на The Echo Nest, чтобы включить пользовательское радио - + Watch for changes Следить за изменением коллекции - + Time between scans, in seconds: Время между сканированием, в секундах: - - Advanced Settings - Дополнительные Настройки - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Использование UPnP для проброса портов (рекомендуется) - + Use static external IP address/host name and port - + Использовать статический IP-адрес / имя хоста и порт - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy SOCKS Прокси - + Use SOCKS Proxy Использовать SOCKS Прокси - + Clear All Access Control Entries - - Internet Services - Сервисы интернета - - - + Install from file... Установить из файла - + Filter by capability: Фильтр по возможности: - + Static Host Name: Статическое имя хоста: - + Static Port: Статический порт: - + Proxy Settings... Настройки прокси... - + Other Settings Другие Настройки - + Send reports after Tomahawk crashed Отправить отчет после падения Tomahawk - + Allow web browsers to interact with Tomahawk (recommended) @@ -1838,7 +1843,7 @@ connect and stream from you? Remove - + Удалить @@ -1921,7 +1926,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1929,52 +1934,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... Тестирую... - + Test Login - + Проверить Вход - + Importing %1 e.g. Importing 2012/01/01 Импортирование %1 - + Importing History... Импортирование истории... - + History Incomplete. Resume - + Playback History Imported - + История воспроизведений импортирована. - - + + Failed Неудача - + Success Успех - + Could not contact server Не удается связаться с сервером + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -1991,7 +2006,7 @@ connect and stream from you? Create local copy - + Создать локальную копию @@ -2029,7 +2044,7 @@ connect and stream from you? Logged in as %1 - + Вошли как %1 @@ -2048,7 +2063,7 @@ connect and stream from you? Play music from and sync your playlists with Spotify Premium - + Слушать музыку и синхронизировать плейлисты с Spotify Премиум @@ -2193,7 +2208,7 @@ You may wish to try re-authenticating. Log on to your Jabber/XMPP account to connect to your friends - + Войдите в ваш Jabber/XMPP аккаунт чтобы соединится с вашими друзьями. @@ -2221,12 +2236,12 @@ You may wish to try re-authenticating. Continue Playback after this &Track - + Продолжить воспроизведение после этого &Песни Stop Playback after this &Track - + Остановить воспроизведение после этого &Песни @@ -2242,12 +2257,12 @@ You may wish to try re-authenticating. Copy Album &Link - + Копировать &Ссылку Альбома Copy Artist &Link - + Копировать &Ссылку Исполнителя @@ -2395,7 +2410,7 @@ Try tweaking the filters for a new set of songs to play. is - + is @@ -2433,7 +2448,7 @@ Try tweaking the filters for a new set of songs to play. More - + Более @@ -2473,122 +2488,122 @@ Try tweaking the filters for a new set of songs to play. Minor - + Minor C - + C C Sharp - + C Sharp D - + D E Flat - + E Flat E - + E F - + F F Sharp - + F Sharp G - + G A Flat - + A Flat A - + A B Flat - + B Flat B - + B Ascending - + Ascending Descending - + Descending Tempo - + Tempo Duration - + Продолжительность Loudness - + Loudness Artist Familiarity - + Artist Familiarity Artist Hotttnesss - + Artist Hotttnesss Song Hotttnesss - + Song Hotttnesss Latitude - + Latitude Longitude - + Longitude Mode - + Mode @@ -2603,12 +2618,12 @@ Try tweaking the filters for a new set of songs to play. Danceability - + Danceability only by ~%1 - + только ~ %1 @@ -2618,7 +2633,7 @@ Try tweaking the filters for a new set of songs to play. with genre ~%1 - + с жанром ~%1 @@ -2644,7 +2659,7 @@ Try tweaking the filters for a new set of songs to play. about %1 BPM - + около %1 BPM @@ -2659,7 +2674,7 @@ Try tweaking the filters for a new set of songs to play. at around %1%2 %3 - + около %1%2 %3 @@ -2669,22 +2684,22 @@ Try tweaking the filters for a new set of songs to play. in a %1 key - + в %1 ключ sorted in %1 %2 order - + отсортированы в %1 %2 порядке with a %1 mood - + настроение %1 in a %1 style - + в стиле %1 @@ -2737,12 +2752,12 @@ Try tweaking the filters for a new set of songs to play. Loudness - + Loudness Danceability - + Danceability @@ -2752,17 +2767,17 @@ Try tweaking the filters for a new set of songs to play. Song Hotttnesss - + Song Hotttnesss Artist Hotttnesss - + Artist Hotttnesss Artist Familiarity - + Artist Familiarity @@ -2860,7 +2875,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums Альбом @@ -2923,40 +2938,54 @@ Try tweaking the filters for a new set of songs to play. &Слушать Его + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and и - + You Ты - + you ты - + and и - + %n other(s) - + %1 people %1 человек - + loved this track любимый @@ -2998,7 +3027,7 @@ Try tweaking the filters for a new set of songs to play. Syncing - + Синхронизация @@ -3018,13 +3047,13 @@ Try tweaking the filters for a new set of songs to play. Offline - + Не в сети Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! Возникла ошибка при получении информации из Spotify! @@ -3252,7 +3281,7 @@ enter the displayed PIN number here: - + Play Играть @@ -3272,172 +3301,172 @@ enter the displayed PIN number here: Следующая - + Back Назад - + Go back one page Перейти на предыдущую страницу - + Forward Вперед - + Go forward one page - + Перейдите на следующую страницу - + Global Search... Глобальный поиск - - + + Check For Updates... Проверить обновления... - - - + + + Connect To Peer Связаться с Peer - + Enter peer address: Введите адрес узла: - + Enter peer port: Введите адрес порта: - + Enter peer key: Введите адрес ключа: - + XSPF Error Ошибка XSPF - + This is not a valid XSPF playlist. Это не является допустимым XSPF плейлистом. - + Failed to save tracks Не удалось сохранить песни - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Некоторые треки в плейлисте не содержат исполнителя и название. Они будут проигнорированы. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station Станция - + Create New Station Создать новую станцию - + Name: Имя: - + Playlist Плейлист - + Automatic Playlist Автоматический Плейлист - + Pause Пауза - + Go &offline Отключиться - + Go &online Подлючиться - + Authentication Error Ошибка авторизации - + Error connecting to SIP: Authentication failed! Ошибка соединения с SIP: Ошибка авторизации! - + %1 by %2 track, artist name - + %1 %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 Авторское право 2010 - 2012 - + Thanks to: Благодарность - + About Tomahawk О Tomahawk @@ -3488,34 +3517,34 @@ enter the displayed PIN number here: Похожие Песни - + Sorry, but we could not find similar tracks for this song! - + Извините, но мы не смогли найти похожие треки на эту песню! - + You've listened to this track %n time(s). - + You've never listened to this track before. Вы никогда не слушали этот трек раньше. - + You first listened to it on %1. - + Первое прослушивание этой песни %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. - + Вы никогда не слушали %1 до этого. @@ -3531,11 +3560,13 @@ enter the displayed PIN number here: from + streaming artist - track from friend из to + streaming artist - track to friend к @@ -3572,7 +3603,7 @@ enter the displayed PIN number here: Sorry, your filter '%1' did not match any results. - + К сожалению, '%1' фильтр не найдено ни одного результата. @@ -3650,39 +3681,39 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. - + После сканирования вашей музыкальной коллекции вы найдете треки прямо здесь. - + This collection is empty. Коллекция пуста - + SuperCollection Общая коллекция - + Combined libraries of all your online friends Комбинированные библиотек всех ваших друзей онлайн - - - Recently Played Tracks - - - Recently played tracks from all your friends - + Recently Played Tracks + Последние Воспроизводимые Песни - + + Recently played tracks from all your friends + Последние воспроизводимые песни все ваших друзей + + + Sorry, we could not find any recent plays! - + К сожалению, мы не смогли найти никаких воспроизвидений песен! @@ -3703,12 +3734,12 @@ You can re-send a sync message at any time simply by sending another tweet using Последние Воспроизводимые Песни - + No recently created playlists in your network. Нет списков, созданных в последнее время в вашей сети. - + Welcome to Tomahawk Добро пожаловать в Tomahawk @@ -3778,7 +3809,7 @@ Lyrics for "%1" by %2: Failed to parse contents of XSPF playlist - + Невозможно разобрать содержимое XSPF плейлиста @@ -4003,7 +4034,7 @@ Lyrics for "%1" by %2: Do you want to add <b>%1</b> to your friend list? - + Вы хотите добавить <b>%1</b> в списке ваших друзей? diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 7babac319..80681eff9 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -145,17 +145,17 @@ connect and stream from you? Andra album av artisten - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Andra album av %1 @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Visa fotnot - + Hide Footnotes Dölj fotnot @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1222,47 +1227,67 @@ connect and stream from you? SettingsDialog - + Collection Samling - + Advanced Avancerat - + All Alla - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services Tjänster - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file Installera resolver från fil - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information Information @@ -1473,69 +1498,68 @@ connect and stream from you? SourceTreeView - + &Copy Link &Kopiera länk - + &Delete %1 &Ta bort %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist &Exportera spellista - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF Spara XSPF - + Playlists (*.xspf) Spellistor (*.xspf) @@ -1669,13 +1693,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -1687,17 +1706,12 @@ connect and stream from you? Inställningar för Tomahawk - - Local Music Information - - - - + Path to scan for music files: Sökväg att leta efter musik i - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1705,107 +1719,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio - + Watch for changes Bevaka förändringar - + Time between scans, in seconds: Intervall mellan letande, i sekunder - - Advanced Settings - - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy - + Use SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - Internet-tjänster - - - + Install from file... Installera från fil… - + Filter by capability: Filtrera efter funktion: - + Static Host Name: - + Static Port: Statisk port: - + Proxy Settings... Proxyinställningar... - + Other Settings - + Send reports after Tomahawk crashed Skicka en felrapport om Tomahawk kraschar - + Allow web browsers to interact with Tomahawk (recommended) @@ -1921,7 +1925,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1929,52 +1933,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed Misslyckades - + Success - + Could not contact server + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2855,7 +2869,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums @@ -2918,40 +2932,54 @@ Try tweaking the filters for a new set of songs to play. + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -3019,7 +3047,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! @@ -3247,7 +3275,7 @@ enter the displayed PIN number here: - + Play Spela upp @@ -3267,172 +3295,172 @@ enter the displayed PIN number here: Nästa - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... Global sökning... - - + + Check For Updates... Leta efter uppdateringar... - - - + + + Connect To Peer Anslut till klient - + Enter peer address: Ange klientadress: - + Enter peer port: Ange klientport: - + Enter peer key: Ange klientnyckel: - + XSPF Error XSPF-fel - + This is not a valid XSPF playlist. Detta är inte en giltig XSPF-spellista. - + Failed to save tracks Misslyckades med att spara spår - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. Några spår i spellistan innehåller inte någon artist och titel. De kommer att ignoreras. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station - + Create New Station Skapa ny station - + Name: Namn: - + Playlist - + Automatic Playlist - + Pause Paus - + Go &offline Koppla &från - + Go &online A&nslut - + Authentication Error Autentiseringsfel - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name %1 av %2 - + %1 - %2 current track, some window title %1 - %2 - + <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk @@ -3483,32 +3511,32 @@ enter the displayed PIN number here: - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). - + You've never listened to this track before. - + You first listened to it on %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. @@ -3526,12 +3554,14 @@ enter the displayed PIN number here: from - från + streaming artist - track from friend + to - till + streaming artist - track to friend + @@ -3641,37 +3671,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection - + Combined libraries of all your online friends - + Recently Played Tracks - + Recently played tracks from all your friends - + Sorry, we could not find any recent plays! @@ -3694,12 +3724,12 @@ You can re-send a sync message at any time simply by sending another tweet using Senaste spelade spår - + No recently created playlists in your network. Inga skapade spellistor i ditt nätverk på sistone. - + Welcome to Tomahawk Välkommen till Tomahawk diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts index e167967a9..eab967dcc 100644 --- a/lang/tomahawk_tr.ts +++ b/lang/tomahawk_tr.ts @@ -145,17 +145,17 @@ connect and stream from you? Sanatçının Diğer Albümleri - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 Diğer %1 Albümleri @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes Dipnotları Göster - + Hide Footnotes Dipnotları Gizle @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1221,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection - + Advanced - + All - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information @@ -1472,69 +1497,68 @@ connect and stream from you? SourceTreeView - + &Copy Link - + &Delete %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF - + Playlists (*.xspf) @@ -1668,13 +1692,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -1686,17 +1705,12 @@ connect and stream from you? - - Local Music Information - - - - + Path to scan for music files: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1704,107 +1718,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio - + Watch for changes - + Time between scans, in seconds: - - Advanced Settings - - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy - + Use SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - - - - + Install from file... - + Filter by capability: - + Static Host Name: - + Static Port: - + Proxy Settings... - + Other Settings - + Send reports after Tomahawk crashed - + Allow web browsers to interact with Tomahawk (recommended) @@ -1920,7 +1924,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1928,52 +1932,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed - + Success - + Could not contact server + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2854,7 +2868,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums @@ -2917,40 +2931,54 @@ Try tweaking the filters for a new set of songs to play. + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -3018,7 +3046,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! @@ -3246,7 +3274,7 @@ enter the displayed PIN number here: - + Play @@ -3266,172 +3294,172 @@ enter the displayed PIN number here: - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... - - + + Check For Updates... - - - + + + Connect To Peer - + Enter peer address: - + Enter peer port: - + Enter peer key: - + XSPF Error - + This is not a valid XSPF playlist. - + Failed to save tracks - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station - + Create New Station - + Name: - + Playlist - + Automatic Playlist - + Pause - + Go &offline - + Go &online - + Authentication Error - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name - + %1 - %2 current track, some window title - + <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk @@ -3482,32 +3510,32 @@ enter the displayed PIN number here: - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). - + You've never listened to this track before. - + You first listened to it on %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. @@ -3525,11 +3553,13 @@ enter the displayed PIN number here: from + streaming artist - track from friend to + streaming artist - track to friend @@ -3640,37 +3670,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection - + Combined libraries of all your online friends - + Recently Played Tracks - + Recently played tracks from all your friends - + Sorry, we could not find any recent plays! @@ -3693,12 +3723,12 @@ You can re-send a sync message at any time simply by sending another tweet using - + No recently created playlists in your network. - + Welcome to Tomahawk diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts index 010057964..5804711f1 100644 --- a/lang/tomahawk_zh_CN.ts +++ b/lang/tomahawk_zh_CN.ts @@ -145,17 +145,17 @@ connect and stream from you? 艺人的其他专辑 - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 %1 的其他专辑 @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes 显示脚注 - + Hide Footnotes 隐藏脚注 @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1221,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection - + Advanced - + All - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information @@ -1472,69 +1497,68 @@ connect and stream from you? SourceTreeView - + &Copy Link - + &Delete %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF - + Playlists (*.xspf) @@ -1668,13 +1692,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -1686,17 +1705,12 @@ connect and stream from you? - - Local Music Information - - - - + Path to scan for music files: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1704,107 +1718,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio - + Watch for changes - + Time between scans, in seconds: - - Advanced Settings - - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy - + Use SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - - - - + Install from file... - + Filter by capability: - + Static Host Name: - + Static Port: - + Proxy Settings... - + Other Settings - + Send reports after Tomahawk crashed - + Allow web browsers to interact with Tomahawk (recommended) 允许浏览器与 Tomahawk 之间的交互 (推荐) @@ -1920,7 +1924,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1928,52 +1932,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed - + Success - + Could not contact server + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2854,7 +2868,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums @@ -2917,40 +2931,54 @@ Try tweaking the filters for a new set of songs to play. + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -3018,7 +3046,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! @@ -3246,7 +3274,7 @@ enter the displayed PIN number here: - + Play @@ -3266,172 +3294,172 @@ enter the displayed PIN number here: - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... - - + + Check For Updates... - - - + + + Connect To Peer - + Enter peer address: - + Enter peer port: - + Enter peer key: - + XSPF Error - + This is not a valid XSPF playlist. - + Failed to save tracks - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station - + Create New Station - + Name: - + Playlist - + Automatic Playlist - + Pause - + Go &offline - + Go &online - + Authentication Error - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name - + %1 - %2 current track, some window title - + <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk @@ -3482,32 +3510,32 @@ enter the displayed PIN number here: - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). - + You've never listened to this track before. - + You first listened to it on %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. @@ -3525,11 +3553,13 @@ enter the displayed PIN number here: from + streaming artist - track from friend to + streaming artist - track to friend @@ -3640,37 +3670,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection - + Combined libraries of all your online friends - + Recently Played Tracks 最近播放曲目 - + Recently played tracks from all your friends 所有朋友最近播放的曲目 - + Sorry, we could not find any recent plays! @@ -3693,12 +3723,12 @@ You can re-send a sync message at any time simply by sending another tweet using 最近播放曲目 - + No recently created playlists in your network. - + Welcome to Tomahawk diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts index 3f38ca231..dc1c4c22b 100644 --- a/lang/tomahawk_zh_TW.ts +++ b/lang/tomahawk_zh_TW.ts @@ -145,17 +145,17 @@ connect and stream from you? 列出演出者的其他專輯 - + Sorry, we could not find any other albums for this artist! - + Sorry, we could not find any tracks for this album! - + Other Albums by %1 列出所有其他專輯,依 %1 @@ -303,17 +303,17 @@ connect and stream from you? AudioEngine - + Sorry, Tomahawk couldn't find the track '%1' by %2 - + Sorry, Tomahawk couldn't find the artist '%1' - + Sorry, Tomahawk couldn't find the album '%1' by %2 @@ -373,12 +373,12 @@ connect and stream from you? - + Show Footnotes 顯示註腳 - + Hide Footnotes 隱藏註腳 @@ -550,6 +550,11 @@ connect and stream from you? Import Playback History + + + Synchronize Loved Tracks + + LastfmContext @@ -1221,47 +1226,67 @@ connect and stream from you? SettingsDialog - + Collection 收藏 - + Advanced 進階 - + All 所有 - + + Tomahawk Settings + + + + Some changed settings will not take effect until Tomahawk is restarted - + Services 服務 - + + <b>Services</b><br>Configure the accounts and services used by Tomahawk to search and retrieve music, find your friends and update your status. + + + + + <b>Collection</b><br>Manage how Tomahawk finds music on your computer. + + + + + <b>Advanced</b><br>Configure Tomahawk's advanced settings, including network connectivity settings, browser interaction and more. + + + + Install resolver from file 從檔案安裝解析器 - + Delete all Access Control entries? - + Do you really want to delete all Access Control entries? You will be asked for a decision again for each peer that you connect to. - + Information 資訊 @@ -1472,69 +1497,68 @@ connect and stream from you? SourceTreeView - + &Copy Link 複製鏈接 - + &Delete %1 - + Add to my Playlists - + Add to my Automatic Playlists - + Add to my Stations - + &Export Playlist 匯出播放清單 - + playlist - + automatic playlist - + station - - Delete %1? - playlist/station/... - - - - + Would you like to delete the %1 <b>"%2"</b>? e.g. Would you like to delete the playlist named Foobar? - + + Delete + + + + Save XSPF 儲存 XSPF - + Playlists (*.xspf) 播放清單(*.xspf) @@ -1668,13 +1692,8 @@ connect and stream from you? SpotifyPlaylistUpdater - - Delete in Spotify? - - - - - Would you like to delete the corresponding Spotify playlist as well? + + Delete associated Spotify playlist? @@ -1686,17 +1705,12 @@ connect and stream from you? Tomahawk 設定 - - Local Music Information - 本地音樂資訊 - - - + Path to scan for music files: 掃描音樂檔的路徑: - + The Echo Nest supports keeping track of your catalog metadata and using it to craft personalized radios. Enabling this option will allow you (and all your friends) to create automatic playlists @@ -1704,107 +1718,97 @@ connect and stream from you? - + Upload collection list to The Echo Nest to enable user radio - + Watch for changes 觀看變化 - + Time between scans, in seconds: - - Advanced Settings - - - - + Remote Peer Connection Method - + None (outgoing connections only) - + Use UPnP to establish port forward (recommended) - + Use static external IP address/host name and port - + Set this to your external IP address or host name. Make sure to forward the port to this host! - + SOCKS Proxy - + Use SOCKS Proxy - + Clear All Access Control Entries - - Internet Services - 上網服務 - - - + Install from file... 從安裝檔案... - + Filter by capability: 按能力篩選: - + Static Host Name: 靜態主機名稱: - + Static Port: 靜態通訊埠: - + Proxy Settings... 代理服務器設定... - + Other Settings - + Send reports after Tomahawk crashed - + Allow web browsers to interact with Tomahawk (recommended) 允許 Web 瀏覽器與 Tomahawk 互動 (推薦) @@ -1920,7 +1924,7 @@ connect and stream from you? Tomahawk::Accounts::LastFmAccountFactory - + Scrobble your tracks to last.fm, and find freely downloadable tracks to play @@ -1928,52 +1932,62 @@ connect and stream from you? Tomahawk::Accounts::LastFmConfig - + Testing... - + Test Login - + Importing %1 e.g. Importing 2012/01/01 - + Importing History... - + History Incomplete. Resume - + Playback History Imported - - + + Failed 失敗 - + Success 成功 - + Could not contact server 無法聯繫服務器 + + + Synchronizing... + + + + + Synchronization Finished + + Tomahawk::Accounts::SpotifyAccount @@ -2854,7 +2868,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::NewReleasesPlugin - + Albums 專輯 @@ -2917,40 +2931,54 @@ Try tweaking the filters for a new set of songs to play. + + Tomahawk::Playlist + + + Would you like to delete the playlist <b>"%2"</b>? + e.g. Would you like to delete the playlist named Foobar? + + + + + Delete + + + Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -3018,7 +3046,7 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::SpotifyParser - + Error fetching Spotify information from the network! @@ -3246,7 +3274,7 @@ enter the displayed PIN number here: - + Play 播放 @@ -3266,172 +3294,172 @@ enter the displayed PIN number here: 下一首 - + Back - + Go back one page - + Forward - + Go forward one page - + Global Search... 全域搜尋... - - + + Check For Updates... 檢查更新... - - - + + + Connect To Peer 連接點對點 - + Enter peer address: 輸入對等地址: - + Enter peer port: 輸入對等連接埠: - + Enter peer key: 輸入對等密鑰: - + XSPF Error XSPF 錯誤 - + This is not a valid XSPF playlist. - + Failed to save tracks 無法儲存曲目 - + Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. Make sure you have a suitable Phonon backend and required plugins installed. - + Sorry, there is a problem accessing your audio device or the desired track, current track will be skipped. - + Station - + Create New Station - + Name: 名稱: - + Playlist - + Automatic Playlist - + Pause 暫停 - + Go &offline 離線 - + Go &online 上網 - + Authentication Error 驗證錯誤 - + Error connecting to SIP: Authentication failed! - + %1 by %2 track, artist name - + %1 - %2 current track, some window title - + <h2><b>Tomahawk %1<br/>(%2)</h2> <h2><b>Tomahawk %1<br/>(%2)</h2> - + <h2><b>Tomahawk %1</h2> <h2><b>Tomahawk %1</h2> - + Copyright 2010 - 2012 - + Thanks to: - + About Tomahawk @@ -3482,32 +3510,32 @@ enter the displayed PIN number here: - + Sorry, but we could not find similar tracks for this song! - + You've listened to this track %n time(s). - + You've never listened to this track before. - + You first listened to it on %1. - + You've listened to %1 %n time(s). - + You've never listened to %1 before. @@ -3525,11 +3553,13 @@ enter the displayed PIN number here: from + streaming artist - track from friend to + streaming artist - track to friend @@ -3640,37 +3670,37 @@ You can re-send a sync message at any time simply by sending another tweet using ViewManager - + After you have scanned your music collection you will find your tracks right here. - + This collection is empty. - + SuperCollection 超級收藏 - + Combined libraries of all your online friends 聯合您所有線上朋友的音樂庫 - + Recently Played Tracks - + Recently played tracks from all your friends - + Sorry, we could not find any recent plays! @@ -3693,12 +3723,12 @@ You can re-send a sync message at any time simply by sending another tweet using 最近播放的曲目 - + No recently created playlists in your network. 沒有最近建立的播放清單在您的網路。 - + Welcome to Tomahawk 歡迎到 Tomahawk diff --git a/resources.qrc b/resources.qrc index f4e960b76..2416c012e 100644 --- a/resources.qrc +++ b/resources.qrc @@ -148,6 +148,8 @@ data/images/jump-link.png data/images/scrollbar-vertical-handle.png data/images/scrollbar-horizontal-handle.png + data/images/subscribe-on.png + data/images/subscribe-off.png data/qml/ArtistInfoScene.qml data/qml/StationScene.qml data/qml/CoverImage.qml diff --git a/src/AudioControls.cpp b/src/AudioControls.cpp index e4b57075b..e081ddea6 100644 --- a/src/AudioControls.cpp +++ b/src/AudioControls.cpp @@ -37,6 +37,8 @@ #include "ViewManager.h" #include "Source.h" +const static int ALLOWED_MAX_DIVERSION = 300; + using namespace Tomahawk; @@ -205,22 +207,20 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result ) ui->seekSlider->setValue( 0 ); ui->seekSlider->setEnabled( AudioEngine::instance()->canSeek() ); - m_phononTickCheckTimer.stop(); - m_sliderTimeLine.stop(); m_sliderTimeLine.setDuration( duration ); m_sliderTimeLine.setFrameRange( 0, duration ); m_sliderTimeLine.setCurveShape( QTimeLine::LinearCurve ); m_sliderTimeLine.setCurrentTime( 0 ); - m_seekMsecs = -1; + m_seeked = false; ui->seekSlider->setVisible( true ); int updateRate = (double)1000 / ( (double)ui->seekSlider->contentsRect().width() / (double)( duration / 1000 ) ); m_sliderTimeLine.setUpdateInterval( qBound( 40, updateRate, 500 ) ); - m_noTimeChange = false; m_lastSliderCheck = 0; + m_phononTickCheckTimer.start( 500 ); } @@ -326,18 +326,15 @@ AudioControls::onPlaybackResumed() { tDebug( LOGEXTRA ) << Q_FUNC_INFO; ui->stackedLayout->setCurrentWidget( ui->pauseButton ); - m_sliderTimeLine.resume(); } void AudioControls::onPlaybackSeeked( qint64 msec ) { - tDebug( LOGEXTRA ) << Q_FUNC_INFO << " setting current timer to " << msec; - m_sliderTimeLine.setPaused( true ); - m_sliderTimeLine.setCurrentTime( msec ); - m_lastSliderCheck = msec; - m_seekMsecs = msec; + tDebug( LOGEXTRA ) << Q_FUNC_INFO; + m_seeked = true; + onPlaybackTimer( msec ); } @@ -356,7 +353,8 @@ AudioControls::onPlaybackStopped() ui->seekSlider->setVisible( false ); m_sliderTimeLine.stop(); m_sliderTimeLine.setCurrentTime( 0 ); - + m_phononTickCheckTimer.stop(); + ui->stackedLayout->setCurrentWidget( ui->playPauseButton ); ui->loveButton->setEnabled( false ); ui->loveButton->setVisible( false ); @@ -368,65 +366,90 @@ AudioControls::onPlaybackStopped() void AudioControls::onPlaybackTimer( qint64 msElapsed ) { + //tDebug() << Q_FUNC_INFO; + + m_phononTickCheckTimer.stop(); + + if ( m_currentTrack.isNull() ) + { + m_sliderTimeLine.stop(); + return; + } + const int seconds = msElapsed / 1000; - if ( seconds != m_lastTextSecondShown && !m_currentTrack.isNull() ) + if ( seconds != m_lastTextSecondShown ) { ui->timeLabel->setText( TomahawkUtils::timeToString( seconds ) ); ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( m_currentTrack->duration() - seconds ) ); m_lastTextSecondShown = seconds; } - //tDebug( LOGEXTRA ) << Q_FUNC_INFO << "msElapsed =" << msElapsed << "and timer current time =" << m_sliderTimeLine.currentTime() << "and m_seekMsecs =" << m_seekMsecs; - if ( msElapsed > 0 && msElapsed != m_lastSliderCheck && m_seekMsecs == -1 && msElapsed - 500 < m_lastSliderCheck ) + m_phononTickCheckTimer.start( 500 ); + + if ( msElapsed == 0 ) return; - m_lastSliderCheck = msElapsed; - - if ( m_currentTrack.isNull() ) - { - m_sliderTimeLine.stop(); - return; - } - - ui->seekSlider->blockSignals( true ); - - if ( sender() != &m_phononTickCheckTimer ) - m_phononTickCheckTimer.start( 1000 ); int currentTime = m_sliderTimeLine.currentTime(); - if ( m_noTimeChange ) + //tDebug( LOGEXTRA ) << Q_FUNC_INFO << "msElapsed =" << msElapsed << "and timer current time =" << m_sliderTimeLine.currentTime(); + + // First condition checks for the common case where + // 1) the track has been started + // 2) we haven't seeked, + // 3) the timeline is pretty close to the actual time elapsed, within ALLOWED_MAX_DIVERSIONmsec, so no adustment needed, and + // 4) The audio engine is actually currently running + if ( msElapsed > 0 + && !m_seeked + && qAbs( msElapsed - currentTime ) <= ALLOWED_MAX_DIVERSION + && AudioEngine::instance()->state() == AudioEngine::Playing ) { - if ( currentTime != msElapsed ) + if ( m_sliderTimeLine.state() != QTimeLine::Running ) + m_sliderTimeLine.resume(); + m_lastSliderCheck = msElapsed; + return; + } + else + { + //tDebug() << Q_FUNC_INFO << "Fallthrough"; + // If we're in here we're offset, so we need to do some munging around + ui->seekSlider->blockSignals( true ); + + // First handle seeks + if ( m_seeked ) { + //tDebug() << Q_FUNC_INFO << "Seeked"; m_sliderTimeLine.setPaused( true ); - m_noTimeChange = false; m_sliderTimeLine.setCurrentTime( msElapsed ); - m_seekMsecs = -1; - m_sliderTimeLine.resume(); + m_seeked = false; + if ( AudioEngine::instance()->state() == AudioEngine::Playing ) + m_sliderTimeLine.resume(); } + // Next handle falling behind by too much, or getting ahead by too much (greater than allowed amount, which would have been sorted above) + // However, a Phonon bug means that after a seek we'll actually have AudioEngine's state be Playing, when it ain't, so have to detect that + else if ( AudioEngine::instance()->state() == AudioEngine::Playing ) + { + //tDebug() << Q_FUNC_INFO << "AudioEngine playing"; + m_sliderTimeLine.setPaused( true ); + m_sliderTimeLine.setCurrentTime( msElapsed ); + if ( msElapsed != m_lastSliderCheck ) + m_sliderTimeLine.resume(); + } + // Finally, the case where the audioengine isn't playing; if the timeline is still running, pause it and catch up + else if ( AudioEngine::instance()->state() != AudioEngine::Playing ) + { + //tDebug() << Q_FUNC_INFO << "AudioEngine not playing"; + if ( msElapsed != currentTime || m_sliderTimeLine.state() == QTimeLine::Running) + { + m_sliderTimeLine.setPaused( true ); + m_sliderTimeLine.setCurrentTime( msElapsed ); + } + } + else + { + tDebug() << Q_FUNC_INFO << "What to do? How could we even get here?"; + } + m_lastSliderCheck = msElapsed; + ui->seekSlider->blockSignals( false ); } - else if ( currentTime >= msElapsed || m_seekMsecs != -1 ) - { - m_sliderTimeLine.setPaused( true ); - - m_noTimeChange = false; - if ( currentTime == msElapsed ) - m_noTimeChange = true; - - m_sliderTimeLine.setCurrentTime( msElapsed ); - m_seekMsecs = -1; - if ( AudioEngine::instance()->state() != AudioEngine::Paused && sender() != &m_phononTickCheckTimer ) - m_sliderTimeLine.resume(); - } - else if ( m_sliderTimeLine.duration() > msElapsed && m_sliderTimeLine.state() == QTimeLine::NotRunning && AudioEngine::instance()->state() == AudioEngine::Playing ) - { - m_sliderTimeLine.start(); - } - else if ( m_sliderTimeLine.state() == QTimeLine::Paused && AudioEngine::instance()->state() != AudioEngine::Paused ) - { - m_sliderTimeLine.resume(); - } - - ui->seekSlider->blockSignals( false ); } diff --git a/src/AudioControls.h b/src/AudioControls.h index aad7af1b9..3e5b0e7c5 100644 --- a/src/AudioControls.h +++ b/src/AudioControls.h @@ -101,9 +101,8 @@ private: QTimer m_phononTickCheckTimer; QTimeLine m_sliderTimeLine; - qint64 m_seekMsecs; + bool m_seeked; qint64 m_lastSliderCheck; - bool m_noTimeChange; qint64 m_lastTextSecondShown; QWidget* m_parent; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 863aa797f..26a4b8342 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,7 +70,6 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} AudioControls.cpp SettingsDialog.cpp DiagnosticsDialog.cpp - SettingsListDelegate.cpp TomahawkWindow.cpp LoadXSPFDialog.cpp SocialWidget.cpp @@ -113,8 +112,7 @@ INCLUDE_DIRECTORIES( ${PHONON_INCLUDES} ${QJSON_INCLUDE_DIR} ${LIBATTICA_INCLUDE_DIR} - ${LIBECHONEST_INCLUDE_DIR} - ${LIBECHONEST_INCLUDE_DIR}/.. + ${ECHONEST_INCLUDE_DIR} ${LIBLASTFM_INCLUDE_DIRS} ${LIBLASTFM_INCLUDE_DIRS}/.. ) @@ -200,7 +198,7 @@ TARGET_LINK_LIBRARIES( tomahawk ${OS_SPECIFIC_LINK_LIBRARIES} ${QT_LIBRARIES} ${MAC_EXTRA_LIBS} - ${LIBECHONEST_LIBRARY} + ${ECHONEST_LIBRARIES} ${QXTWEB_LIBRARIES} ${QJSON_LIBRARIES} ${TAGLIB_LIBRARIES} diff --git a/src/SettingsDialog.cpp b/src/SettingsDialog.cpp index 213373ea0..7c5a8f964 100644 --- a/src/SettingsDialog.cpp +++ b/src/SettingsDialog.cpp @@ -3,6 +3,7 @@ * Copyright 2010-2011, Christian Muehlhaeuser * Copyright 2010-2011, Leo Franchi * Copyright 2010-2012, Jeff Mitchell + * Copyright 2012, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +29,7 @@ #include #include #include +#include #include "AtticaManager.h" #include "AclRegistry.h" @@ -39,7 +41,6 @@ #include "ExternalResolverGui.h" #include "utils/TomahawkUtilsGui.h" #include "utils/GuiHelpers.h" -#include "SettingsListDelegate.h" #include "accounts/AccountDelegate.h" #include "database/Database.h" #include "network/Servent.h" @@ -72,11 +73,23 @@ SettingsDialog::SettingsDialog( QWidget *parent ) TomahawkSettings* s = TomahawkSettings::instance(); TomahawkUtils::unmarginLayout( layout() ); - ui->stackedWidget->setContentsMargins( 4, 4, 4, 0 ); +#ifdef Q_WS_X11 + ui->stackedWidget->setContentsMargins( 4, 4, 4, 4 ); +#else + ui->stackedWidget->setContentsMargins( 4, 4, 4, 0 ); +#endif ui->checkBoxReporter->setChecked( s->crashReporterEnabled() ); ui->checkBoxHttp->setChecked( s->httpEnabled() ); + QFrame *sepLine = new QFrame( this ); + sepLine->setFrameShape( QFrame::HLine ); + sepLine->setFrameShadow( QFrame::Sunken ); + ui->horizontalLayout->insertWidget( 0, sepLine ); + + m_toolBar = new QToolBar( tr( "Tomahawk Settings" ), this ); + ui->horizontalLayout->insertWidget( 0, m_toolBar ); + m_toolBar->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); //Network settings TomahawkSettings::ExternalAddressMode mode = TomahawkSettings::instance()->externalAddressMode(); @@ -102,29 +115,16 @@ SettingsDialog::SettingsDialog( QWidget *parent ) createIcons(); #ifdef Q_WS_X11 - ui->listWidget->setFrameShape( QFrame::StyledPanel ); - ui->listWidget->setFrameShadow( QFrame::Sunken ); setContentsMargins( 4, 4, 4, 4 ); #else setContentsMargins( 0, 4, 4, 4 ); #endif -#ifdef Q_WS_MAC - ui->listWidget->setFixedWidth( 83 ); -#endif - #ifdef Q_WS_MAC // Avoid resize handles on sheets on osx m_proxySettings.setSizeGripEnabled( true ); QSizeGrip* p = m_proxySettings.findChild< QSizeGrip* >(); p->setFixedSize( 0, 0 ); - - ui->groupBoxNetworkAdvanced->layout()->removeItem( ui->verticalSpacer ); - ui->groupBoxNetworkAdvanced->layout()->removeItem( ui->verticalSpacer_2 ); - ui->groupBoxNetworkAdvanced->layout()->removeItem( ui->verticalSpacer_4 ); - delete ui->verticalSpacer; - delete ui->verticalSpacer_2; - delete ui->verticalSpacer_4; #endif // Accounts @@ -193,6 +193,13 @@ SettingsDialog::SettingsDialog( QWidget *parent ) { ui->dirTree->checkPath( dir, Qt::Checked ); } + ui->advancedPage->setMinimumSize( ui->advancedPage->sizeHint() ); + + int buttonsWidth = qMax( ui->proxyButton->sizeHint().width(), + ui->aclEntryClearButton->sizeHint().width() ); + ui->proxyButton->setFixedWidth( buttonsWidth ); + ui->aclEntryClearButton->setFixedWidth( buttonsWidth ); + // NOW PLAYING // #ifdef Q_WS_MAC @@ -210,9 +217,6 @@ SettingsDialog::SettingsDialog( QWidget *parent ) connect( ui->upnpRadioButton, SIGNAL( toggled(bool) ), SLOT( toggleRemoteMode() ) ); connect( ui->enableProxyCheckBox, SIGNAL( toggled(bool) ), SLOT( toggleProxyEnabled() ) ); connect( this, SIGNAL( rejected() ), SLOT( onRejected() ) ); - - ui->listWidget->setCurrentRow( 0 ); - ui->listWidget->setItemDelegate(new SettingsListDelegate()); } @@ -280,56 +284,67 @@ SettingsDialog::serventReady() void SettingsDialog::createIcons() { - /// Not fun but QListWidget sucks. Do our max-width calculation manually - /// so the icons arre lined up. - // Resolvers is the longest string... in english. fml. - ensurePolished(); - int maxlen = 0; - QFontMetrics fm( font() ); - QListWidgetItem *accountsButton = new QListWidgetItem( ui->listWidget ); - accountsButton->setIcon( QIcon( RESPATH "images/account-settings.png" ) ); - accountsButton->setText( tr( "Services" ) ); - accountsButton->setTextAlignment( Qt::AlignHCenter ); - accountsButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - maxlen = fm.width( accountsButton->text() ); + m_settingsGroup = new QActionGroup( m_toolBar ); - QListWidgetItem *musicButton = new QListWidgetItem( ui->listWidget ); - musicButton->setIcon( QIcon( RESPATH "images/music-settings.png" ) ); - musicButton->setText( tr( "Collection" ) ); - musicButton->setTextAlignment( Qt::AlignHCenter ); - musicButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - maxlen = qMax( fm.width( musicButton->text() ), maxlen ); + QWidget *leftSpacer = new QWidget( m_toolBar ); + leftSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); + m_toolBar->addWidget( leftSpacer ); - QListWidgetItem *advancedButton = new QListWidgetItem( ui->listWidget ); - advancedButton->setIcon( QIcon( RESPATH "images/advanced-settings.png" ) ); - advancedButton->setText( tr( "Advanced" ) ); - advancedButton->setTextAlignment( Qt::AlignHCenter ); - advancedButton->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); - maxlen = qMax( fm.width( advancedButton->text() ), maxlen ); + QAction *accountsAction = new QAction( QIcon( RESPATH "images/account-settings.png" ), + tr( "Services" ), + m_toolBar ); + accountsAction->setCheckable( true ); + accountsAction->setToolTip( tr( "Services
" + "Configure the accounts and services used by Tomahawk " + "to search and retrieve music, find your friends and " + "update your status." ) ); + m_settingsGroup->addAction( accountsAction ); - maxlen += 15; // padding - accountsButton->setSizeHint( QSize( maxlen, 60 ) ); - musicButton->setSizeHint( QSize( maxlen, 60 ) ); - advancedButton->setSizeHint( QSize( maxlen, 60 ) ); + QAction *musicAction = new QAction( QIcon( RESPATH "images/music-settings.png" ), + tr( "Collection" ), + m_toolBar ); + musicAction->setCheckable( true ); + musicAction->setToolTip( tr( "Collection
" + "Manage how Tomahawk finds music on your computer." ) ); + m_settingsGroup->addAction( musicAction ); -#ifndef Q_WS_MAC - // doesn't listen to sizehint... - ui->listWidget->setFixedWidth( maxlen + 8 ); -#endif - connect( ui->listWidget, SIGNAL( currentItemChanged( QListWidgetItem*, QListWidgetItem* ) ), SLOT( changePage( QListWidgetItem*, QListWidgetItem* ) ) ); + QAction *advancedAction = new QAction( QIcon( RESPATH "images/advanced-settings.png" ), + tr( "Advanced" ), + m_toolBar ); + advancedAction->setCheckable( true ); + advancedAction->setToolTip( tr( "Advanced
" + "Configure Tomahawk's advanced settings, including " + "network connectivity settings, browser interaction " + "and more." ) ); + m_settingsGroup->addAction( advancedAction ); + + m_settingsGroup->setExclusive( true ); + + m_toolBar->addActions( m_settingsGroup->actions() ); + + QWidget *rightSpacer = new QWidget( m_toolBar ); + rightSpacer->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); + m_toolBar->addWidget( rightSpacer ); + + connect( m_settingsGroup, SIGNAL( triggered( QAction * ) ), + this, SLOT( changePage( QAction * ) ) ); + + accountsAction->setChecked( true ); + changePage( accountsAction ); } void -SettingsDialog::changePage( QListWidgetItem* current, QListWidgetItem* previous ) +SettingsDialog::changePage( QAction *action ) { - if ( !current ) - current = previous; - - ui->stackedWidget->setCurrentIndex( ui->listWidget->row(current) ); + int index = m_settingsGroup->actions().indexOf( action ); + if( ui->stackedWidget->currentIndex() != index ) + { + ui->stackedWidget->setCurrentIndex( index ); + } } diff --git a/src/SettingsDialog.h b/src/SettingsDialog.h index 487f6e4ae..88cb934a0 100644 --- a/src/SettingsDialog.h +++ b/src/SettingsDialog.h @@ -3,6 +3,7 @@ * Copyright 2010-2011, Christian Muehlhaeuser * Copyright 2010-2011, Leo Franchi * Copyright 2010-2012, Jeff Mitchell + * Copyright 2012, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +24,8 @@ #include #include +#include +#include #include "config.h" @@ -94,7 +97,7 @@ private slots: void updateScanOptionsView(); - void changePage( QListWidgetItem*, QListWidgetItem* ); + void changePage( QAction *action ); void serventReady(); void aclEntryClearButtonClicked(); @@ -106,6 +109,9 @@ private: Ui_StackedSettingsDialog* ui; + QToolBar *m_toolBar; + QActionGroup *m_settingsGroup; + ProxyDialog m_proxySettings; bool m_rejected; bool m_restartRequired; diff --git a/src/SettingsListDelegate.cpp b/src/SettingsListDelegate.cpp deleted file mode 100644 index 3756c5314..000000000 --- a/src/SettingsListDelegate.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* === This file is part of Tomahawk Player - === - * - * Copyright 2011, Michael Zanetti - * Copyright 2011, Leo Franchi - * - * Tomahawk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tomahawk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tomahawk. If not, see . - */ - -#include "SettingsListDelegate.h" -#include "utils/Logger.h" - -#include -#include -#include - -SettingsListDelegate::SettingsListDelegate(QObject *parent) : - QStyledItemDelegate(parent) -{ -} - - -void SettingsListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - painter->save(); - - QStyleOptionViewItemV4 opt = option; - initStyleOption( &opt, QModelIndex() ); - qApp->style()->drawControl( QStyle::CE_ItemViewItem, &opt, painter ); - -#if defined(Q_WS_MAC) || defined(Q_WS_WIN) - // On mac draw our own selection rect as we don't get one from osx (around the whole icon or around just text) - if ( opt.state & QStyle::State_Selected ) - { - painter->setRenderHint( QPainter::Antialiasing ); - - QPainterPath p; - p.addRoundedRect( opt.rect.adjusted( 2, 1, -1, -1 ), 5, 5 ); - - QColor fill( 214, 214, 214 ); - QColor border( 107, 107, 107 ); - painter->setPen( border ); - painter->drawPath( p ); - painter->fillPath( p, fill ); - } -#else - if ( ( option.state & QStyle::State_Selected ) == QStyle::State_Selected ) - { - painter->setPen( option.palette.color( QPalette::HighlightedText ) ); - } -#endif - - int horizontalOffset = ( option.rect.width() - option.decorationSize.width() ) /2; - QRect iconRect = option.rect.adjusted( horizontalOffset, 6, -horizontalOffset, -option.rect.height() + 6 + option.decorationSize.height() ); - QPixmap avatar = index.data( Qt::DecorationRole ).value().pixmap( iconRect.size() ); - painter->drawPixmap( iconRect, avatar ); - - QRect textRect = option.rect.adjusted( 6, iconRect.height() + 8, -6, 0 ); - QString text = painter->fontMetrics().elidedText( index.data( Qt::DisplayRole ).toString(), Qt::ElideRight, textRect.width() ); - QTextOption to( Qt::AlignHCenter ); - painter->drawText( textRect, text, to ); - - painter->restore(); -} diff --git a/src/StackedSettingsDialog.ui b/src/StackedSettingsDialog.ui index 08dcdf48b..af3cfe49d 100644 --- a/src/StackedSettingsDialog.ui +++ b/src/StackedSettingsDialog.ui @@ -18,74 +18,11 @@ 0 - - - - - - - Qt::NoFocus - - - QFrame::StyledPanel - - - QFrame::Sunken - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - true - - - - 32 - 32 - - - - QListView::Static - - - QListView::Adjust - - - QListView::Batched - - - 1 - - - QListView::IconMode - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 1 - 4 - - - - - - + - 2 + 0 @@ -93,9 +30,12 @@ 0 - - - Internet Services + + + QFrame::NoFrame + + + QFrame::Plain @@ -153,11 +93,17 @@ 0 - - - Local Music Information + + + QFrame::NoFrame + + + QFrame::Plain + + 2 + @@ -234,17 +180,23 @@ 0 - + 0 0 - - Advanced Settings + + QFrame::NoFrame + + + QFrame::Plain + + -1 + 2 @@ -342,10 +294,13 @@ Qt::Vertical + + QSizePolicy::Fixed + 20 - 40 + 10 @@ -363,8 +318,30 @@ + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + 0 + 0 + + Proxy Settings... @@ -378,10 +355,13 @@ Qt::Vertical + + QSizePolicy::Fixed + 20 - 40 + 10 @@ -395,7 +375,7 @@ - Qt::RightToLeft + Qt::LeftToRight Allow web browsers to interact with Tomahawk (recommended) @@ -408,7 +388,7 @@ - Qt::RightToLeft + Qt::LeftToRight Send reports after Tomahawk crashed @@ -425,6 +405,9 @@ Qt::Horizontal + + QSizePolicy::Expanding + 40 diff --git a/src/TomahawkWindow.cpp b/src/TomahawkWindow.cpp index 5cc182325..7949baa62 100644 --- a/src/TomahawkWindow.cpp +++ b/src/TomahawkWindow.cpp @@ -104,7 +104,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) connect( APP, SIGNAL( tomahawkLoaded() ), vm, SLOT( setTomahawkLoaded() ) ); // Pass loaded signal into libtomahawk so components in there can connect to ViewManager #ifdef Q_OS_WIN - connect(AudioEngine::instance(),SIGNAL(stateChanged(AudioState,AudioState)),this,SLOT(audioStateChanged(AudioState,AudioState))); + connect( AudioEngine::instance(), SIGNAL( stateChanged( AudioState, AudioState) ), SLOT( audioStateChanged( AudioState, AudioState) ) ); #endif ui->setupUi( this ); @@ -202,11 +202,7 @@ TomahawkWindow::saveSettings() void TomahawkWindow::applyPlatformTweaks() { - // HACK QtCurve causes an infinite loop on startup. This is because setStyle calls setPalette, which calls ensureBaseStyle, - // which loads QtCurve. QtCurve calls setPalette, which creates an infinite loop. The UI will look like CRAP with QtCurve, but - // the user is asking for it explicitly... so he's gonna be stuck with an ugly UI. - if ( !QString( qApp->style()->metaObject()->className() ).toLower().contains( "qtcurve" ) ) - qApp->setStyle( new ProxyStyle() ); + qApp->setStyle( new ProxyStyle() ); #ifdef Q_OS_MAC setUnifiedTitleAndToolBarOnMac( true ); @@ -412,6 +408,7 @@ TomahawkWindow::setupSignals() connect( AudioEngine::instance(), SIGNAL( error( AudioEngine::AudioErrorCode ) ), SLOT( onAudioEngineError( AudioEngine::AudioErrorCode ) ) ); connect( AudioEngine::instance(), SIGNAL( loading( const Tomahawk::result_ptr& ) ), SLOT( onPlaybackLoading( const Tomahawk::result_ptr& ) ) ); connect( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), SLOT( audioStarted() ) ); + connect( AudioEngine::instance(), SIGNAL( finished(Tomahawk::result_ptr) ), SLOT( audioFinished() ) ); connect( AudioEngine::instance(), SIGNAL( resumed()), SLOT( audioStarted() ) ); connect( AudioEngine::instance(), SIGNAL( paused() ), SLOT( audioPaused() ) ); connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( audioStopped() ) ); @@ -600,20 +597,7 @@ TomahawkWindow::winEvent( MSG* msg, long* result ) if ( !AudioEngine::instance()->currentTrack().isNull() ) { AudioEngine::instance()->currentTrack()->toQuery()->setLoved( !AudioEngine::instance()->currentTrack()->toQuery()->loved() ); - if ( AudioEngine::instance()->currentTrack()->toQuery()->loved()) - { - QPixmap loved( RESPATH "images/loved.png" ); - m_thumbButtons[TP_LOVE].hIcon = loved.toWinHICON(); - m_thumbButtons[TP_LOVE].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; - - } - else - { - QPixmap not_loved( RESPATH "images/not-loved.png" ); - m_thumbButtons[TP_LOVE].hIcon = not_loved.toWinHICON(); - m_thumbButtons[TP_LOVE].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; - } - m_taskbarList->ThumbBarUpdateButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); + updateWindowsLoveButton(); } break; } @@ -642,20 +626,8 @@ TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState ) QPixmap pause( RESPATH "images/pause-rest.png" ); m_thumbButtons[TP_PLAY_PAUSE].hIcon = pause.toWinHICON(); m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Pause" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; + updateWindowsLoveButton(); - if ( !AudioEngine::instance()->currentTrack().isNull() && AudioEngine::instance()->currentTrack()->toQuery()->loved() ) - { - QPixmap loved( RESPATH "images/loved.png" ); - m_thumbButtons[TP_LOVE].hIcon = loved.toWinHICON(); - m_thumbButtons[TP_LOVE].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; - } - else - { - QPixmap not_loved( RESPATH "images/not-loved.png" ); - m_thumbButtons[TP_LOVE].hIcon = not_loved.toWinHICON(); - m_thumbButtons[TP_LOVE].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; - } - m_thumbButtons[TP_LOVE].dwFlags = THBF_ENABLED; } break; @@ -669,6 +641,10 @@ TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState ) case AudioEngine::Stopped: { + if ( !AudioEngine::instance()->currentTrack().isNull() ) + { + disconnect(AudioEngine::instance()->currentTrack()->toQuery().data(),SIGNAL(socialActionsLoaded()),this,SLOT(updateWindowsLoveButton())); + } QPixmap play( RESPATH "images/play-rest.png" ); m_thumbButtons[TP_PLAY_PAUSE].hIcon = play.toWinHICON(); m_thumbButtons[TP_PLAY_PAUSE].szTip[ tr( "Play" ).toWCharArray( m_thumbButtons[TP_PLAY_PAUSE].szTip ) ] = 0; @@ -685,6 +661,26 @@ TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState ) m_taskbarList->ThumbBarUpdateButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); } + +void +TomahawkWindow::updateWindowsLoveButton() +{ + if ( !AudioEngine::instance()->currentTrack().isNull() && AudioEngine::instance()->currentTrack()->toQuery()->loved() ) + { + QPixmap loved( RESPATH "images/loved.png" ); + m_thumbButtons[TP_LOVE].hIcon = loved.toWinHICON(); + m_thumbButtons[TP_LOVE].szTip[ tr( "Unlove" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; + } + else + { + QPixmap not_loved( RESPATH "images/not-loved.png" ); + m_thumbButtons[TP_LOVE].hIcon = not_loved.toWinHICON(); + m_thumbButtons[TP_LOVE].szTip[ tr( "Love" ).toWCharArray( m_thumbButtons[TP_LOVE].szTip ) ] = 0; + } + m_thumbButtons[TP_LOVE].dwFlags = THBF_ENABLED; + m_taskbarList->ThumbBarUpdateButtons( winId(), ARRAYSIZE( m_thumbButtons ), m_thumbButtons ); +} + #endif @@ -1034,6 +1030,18 @@ TomahawkWindow::audioStarted() ui->actionPlay->setText( tr( "Pause" ) ); ActionCollection::instance()->getAction( "stop" )->setEnabled( true ); + +#ifdef Q_OS_WIN + connect( AudioEngine::instance()->currentTrack()->toQuery().data(), SIGNAL( socialActionsLoaded() ), SLOT( updateWindowsLoveButton() ) ); +#endif +} + +void +TomahawkWindow::audioFinished() +{ +#ifdef Q_OS_WIN + disconnect( AudioEngine::instance()->currentTrack()->toQuery().data(), SIGNAL( socialActionsLoaded() ), this, SLOT( updateWindowsLoveButton() ) ); +#endif } diff --git a/src/TomahawkWindow.h b/src/TomahawkWindow.h index c0220039b..7ee64cc5d 100644 --- a/src/TomahawkWindow.h +++ b/src/TomahawkWindow.h @@ -121,6 +121,7 @@ private slots: void onPlaybackLoading( const Tomahawk::result_ptr& result ); void audioStarted(); + void audioFinished(); void audioPaused(); void audioStopped(); @@ -144,6 +145,7 @@ private slots: #ifdef Q_OS_WIN void audioStateChanged( AudioState newState, AudioState oldState ); + void updateWindowsLoveButton(); #endif private: diff --git a/src/accounts/xmpp/sip/AvatarManager.cpp b/src/accounts/xmpp/sip/AvatarManager.cpp index 9ff1d26bf..68abbf819 100644 --- a/src/accounts/xmpp/sip/AvatarManager.cpp +++ b/src/accounts/xmpp/sip/AvatarManager.cpp @@ -73,6 +73,11 @@ AvatarManager::fetchVCard( const QString& jid ) void AvatarManager::onNewPresence( const Jreen::Presence& presence ) { + if ( presence.error() ) + { + return; + } + Jreen::VCardUpdate::Ptr update = presence.payload(); if ( update ) { diff --git a/src/infoplugins/generic/CMakeLists.txt b/src/infoplugins/generic/CMakeLists.txt index c077e1e77..60e981687 100644 --- a/src/infoplugins/generic/CMakeLists.txt +++ b/src/infoplugins/generic/CMakeLists.txt @@ -1,4 +1,4 @@ -include_directories(${LIBECHONEST_INCLUDE_DIR}) +include_directories(${ECHONEST_INCLUDE_DIR}) list(APPEND simple_plugins Echonest diff --git a/src/infoplugins/generic/newreleases/NewReleasesPlugin.cpp b/src/infoplugins/generic/newreleases/NewReleasesPlugin.cpp index b5b2ae1a2..9f0bf12f5 100644 --- a/src/infoplugins/generic/newreleases/NewReleasesPlugin.cpp +++ b/src/infoplugins/generic/newreleases/NewReleasesPlugin.cpp @@ -42,7 +42,7 @@ NewReleasesPlugin::NewReleasesPlugin() : InfoPlugin() , m_nrFetchJobs ( 0 ) { - m_nrVersion = "0"; + m_nrVersion = "0.1"; m_supportedGetTypes << InfoNewReleaseCapabilities << InfoNewRelease; } @@ -54,8 +54,10 @@ NewReleasesPlugin::~NewReleasesPlugin() void NewReleasesPlugin::init() { + QVariantList source_qvarlist = TomahawkUtils::Cache::instance()->getData( "NewReleasesPlugin", "nr_sources" ).toList(); - foreach( const QVariant & source, source_qvarlist ) { + foreach( const QVariant & source, source_qvarlist ) + { m_nrSources.append( source.toString() ); tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "fetched source from cache" << source.toString(); @@ -79,21 +81,28 @@ void NewReleasesPlugin::getInfo ( InfoRequestData requestData ) InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >(); bool foundSource = false; - switch ( requestData.type ) { + switch ( requestData.type ) + { case InfoNewRelease: /// We need something to check if the request is actually ment to go to this plugin - if ( !hash.contains ( "nr_source" ) ) { + if ( !hash.contains ( "nr_source" ) ) + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain required param!"; dataError ( requestData ); break; - } else { - foreach ( QString resource, m_nrSources ) { - if ( resource == hash["nr_source"] ) { + } + else + { + foreach ( QString resource, m_nrSources ) + { + if ( resource == hash["nr_source"] ) + { foundSource = true; } } - if ( !foundSource ) { + if ( !foundSource ) + { dataError ( requestData ); break; } @@ -112,7 +121,8 @@ void NewReleasesPlugin::getInfo ( InfoRequestData requestData ) void NewReleasesPlugin::fetchNRFromCache ( InfoRequestData requestData ) { - if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) { + if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + { dataError ( requestData ); return; } @@ -121,7 +131,8 @@ void NewReleasesPlugin::fetchNRFromCache ( InfoRequestData requestData ) Tomahawk::InfoSystem::InfoStringHash criteria; /// Each request needs to contain both a id and source - if ( !hash.contains ( "nr_id" ) && !hash.contains ( "nr_source" ) ) { + if ( !hash.contains ( "nr_id" ) && !hash.contains ( "nr_source" ) ) + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain required params!"; dataError ( requestData ); return; @@ -136,7 +147,8 @@ void NewReleasesPlugin::fetchNRFromCache ( InfoRequestData requestData ) void NewReleasesPlugin::fetchNRCapabilitiesFromCache ( InfoRequestData requestData ) { - if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) { + if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Could not convert requestData to InfoStringHash!"; dataError ( requestData ); return; @@ -150,15 +162,18 @@ void NewReleasesPlugin::fetchNRCapabilitiesFromCache ( InfoRequestData requestDa void NewReleasesPlugin::notInCacheSlot ( InfoStringHash criteria, InfoRequestData requestData ) { - switch ( requestData.type ) { - case InfoNewRelease: { + switch ( requestData.type ) + { + case InfoNewRelease: + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "InfoNewRelease not in cache! Fetching..."; fetchNR ( requestData, criteria["nr_source"], criteria["nr_id"] ); return; } - case InfoNewReleaseCapabilities: { + case InfoNewReleaseCapabilities: + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "InfoChartCapabilities not in cache! Fetching..."; fetchNRSourcesList( false ); m_cachedRequests.append ( requestData ); @@ -166,7 +181,8 @@ void NewReleasesPlugin::notInCacheSlot ( InfoStringHash criteria, InfoRequestDat return; } - default: { + default: + { tLog() << Q_FUNC_INFO << "Couldn't figure out what to do with this type of request after cache miss"; emit info ( requestData, QVariant() ); return; @@ -191,19 +207,22 @@ void NewReleasesPlugin::nrSourcesList() tDebug ( LOGVERBOSE ) << "Got newreleases sources list"; QNetworkReply* reply = qobject_cast ( sender() ); - if ( reply->error() == QNetworkReply::NoError ) { + if ( reply->error() == QNetworkReply::NoError ) + { QJson::Parser p; bool ok; const QVariantMap res = p.parse ( reply, &ok ).toMap(); const QVariantList sources = res.value ( "sources" ).toList(); - if ( !ok ) { + if ( !ok ) + { tLog() << "Failed to parse sources" << p.errorString() << "On line" << p.errorLine(); return; } m_nrSources.clear(); - foreach ( const QVariant &source, sources ) { + foreach ( const QVariant &source, sources ) + { m_nrSources << source.toString(); } TomahawkUtils::Cache::instance()->putData( "NewReleasesPlugin", 172800000 /* 2 days */, "nr_sources", m_nrSources ); @@ -214,9 +233,11 @@ void NewReleasesPlugin::nrSourcesList() void NewReleasesPlugin::fetchAllNRSources() { - if ( !m_nrSources.isEmpty() && m_allNRsMap.isEmpty() ) { + if ( !m_nrSources.isEmpty() && m_allNRsMap.isEmpty() ) + { tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "InfoNewRelease fetching source data"; - foreach ( QString source, m_nrSources ) { + foreach ( QString source, m_nrSources ) + { QUrl url = QUrl ( QString ( CHART_URL "newreleases/%1" ).arg ( source ) ); QNetworkReply* reply = TomahawkUtils::nam()->get ( QNetworkRequest ( url ) ); reply->setProperty ( "nr_source", source ); @@ -246,12 +267,14 @@ void NewReleasesPlugin::nrList() tDebug ( LOGVERBOSE ) << "Got newreleases list result"; QNetworkReply* reply = qobject_cast ( sender() ); - if ( reply->error() == QNetworkReply::NoError ) { + if ( reply->error() == QNetworkReply::NoError ) + { QJson::Parser p; bool ok; const QVariantMap res = p.parse ( reply, &ok ).toMap(); - if ( !ok ) { + if ( !ok ) + { tLog() << "Failed to parse resources" << p.errorString() << "On line" << p.errorLine(); return; @@ -267,31 +290,53 @@ void NewReleasesPlugin::nrList() // Building: // [Source] - New Release QList< InfoStringHash > albumNRs; - - foreach ( const QVariant &nrObj, res.values() ) { - if ( !nrObj.toMap().isEmpty() ) { + QHash< QString, QVariantMap > extraType; + foreach ( const QVariant &nrObj, res.values() ) + { + if ( !nrObj.toMap().isEmpty() ) + { const QVariantMap nrMap = nrObj.toMap(); const QString type = nrMap.value ( "type" ).toString(); + const QString extra = nrMap.value( "extra" ).toString(); InfoStringHash nr; nr["id"] = nrMap.value ( "id" ).toString(); nr["label"] = nrMap.value ( "name" ).toString(); nr["date"] = nrMap.value ( "date" ).toString(); - if ( type == "Album" ) { + if ( type == "Album" ) + { nr[ "type" ] = "album"; - albumNRs.append ( nr ); - } else { + + if( !extra.isEmpty() ) + { + qDebug() << "FOUND EXTRA!! " << extra; + QList< Tomahawk::InfoSystem::InfoStringHash > extraTypeData = extraType[ extra ][ type ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >(); + extraTypeData.append( nr ); + extraType[ extra ][ type ] = QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > >( extraTypeData ); + } + else + albumNRs.append ( nr ); + } + else + { tLog() << "Unknown newrelease type " << type; continue; } } + + foreach( const QString& c, extraType.keys() ) + { + newreleases[ c ] = extraType[ c ]; + tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "extraType has types:" << c; + } } if ( !albumNRs.isEmpty() ) newreleases.insert ( tr ( "Albums" ), QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > > ( albumNRs ) ); + /// @note For displaying purposes, upper the first letter /// @note Remeber to lower it when fetching this! nrName = source; @@ -306,8 +351,10 @@ void NewReleasesPlugin::nrList() } m_nrFetchJobs--; - if ( !m_cachedRequests.isEmpty() && m_nrFetchJobs == 0 ) { - foreach ( InfoRequestData request, m_cachedRequests ) { + if ( !m_cachedRequests.isEmpty() && m_nrFetchJobs == 0 ) + { + foreach ( InfoRequestData request, m_cachedRequests ) + { emit info ( request, m_allNRsMap ); // update cache Tomahawk::InfoSystem::InfoStringHash criteria; @@ -325,12 +372,14 @@ void NewReleasesPlugin::nrReturned() QNetworkReply* reply = qobject_cast ( sender() ); QVariantMap returnedData; - if ( reply->error() == QNetworkReply::NoError ) { + if ( reply->error() == QNetworkReply::NoError ) + { QJson::Parser p; bool ok; QVariantMap res = p.parse ( reply, &ok ).toMap(); - if ( !ok ) { + if ( !ok ) + { tLog() << "Failed to parse json from chart lookup:" << p.errorString() << "On line" << p.errorLine(); return; } @@ -339,9 +388,11 @@ void NewReleasesPlugin::nrReturned() QVariantList albumList = res.value ( "list" ).toList(); QList< Tomahawk::InfoSystem::InfoStringHash > newreleases; - foreach( const QVariant & albumObj, albumList ) { + foreach( const QVariant & albumObj, albumList ) + { QVariantMap albumMap = albumObj.toMap(); - if(!albumMap.isEmpty()) { + if( !albumMap.isEmpty() ) + { const QString album = albumMap.value("album").toString(); const QString artist = albumMap.value("artist").toString(); const QString date = albumMap.value("date").toString(); diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 371b4db42..c278b94d7 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -74,6 +74,7 @@ set( libGuiSources playlist/PlaylistLargeItemDelegate.cpp playlist/PlaylistChartItemDelegate.cpp playlist/PlayableItem.cpp + playlist/SingleTrackPlaylistInterface.h playlist/dynamic/DynamicPlaylist.cpp playlist/dynamic/DynamicView.cpp @@ -142,6 +143,7 @@ set( libGuiSources widgets/FadingPixmap.cpp widgets/SocialPlaylistWidget.cpp widgets/DeclarativeCoverArtProvider.cpp + widgets/SourceTreePopupDialog.cpp widgets/infowidgets/SourceInfoWidget.cpp widgets/infowidgets/ArtistInfoWidget.cpp widgets/infowidgets/AlbumInfoWidget.cpp @@ -336,8 +338,7 @@ include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/. ${CMAKE_CURRENT_SOURCE_DIR} ${QT_INCLUDE_DIR} ${QJSON_INCLUDE_DIR} - ${LIBECHONEST_INCLUDE_DIR} - ${LIBECHONEST_INCLUDE_DIR}/.. + ${ECHONEST_INCLUDE_DIR} ${LIBLASTFM_INCLUDE_DIRS} ${LIBLASTFM_INCLUDE_DIRS}/.. ${CLUCENE_INCLUDE_DIRS} @@ -394,7 +395,8 @@ IF( APPLE ) SET( libSources ${libSources} utils/TomahawkUtils_Mac.mm mac/FileHelpers.mm - thirdparty/Qocoa/qsearchfield_mac.mm ) + thirdparty/Qocoa/qsearchfield_mac.mm + widgets/SourceTreePopupDialog_mac.mm ) SET_SOURCE_FILES_PROPERTIES(utils/TomahawkUtils_Mac.mm PROPERTIES COMPILE_FLAGS "-fvisibility=default") @@ -449,7 +451,7 @@ TARGET_LINK_LIBRARIES( tomahawklib ${PHONON_LIBS} ${TAGLIB_LIBRARIES} ${CLUCENE_LIBRARIES} - ${LIBECHONEST_LIBRARY} + ${ECHONEST_LIBRARIES} ${QT_QTSQL_LIBRARY} ${QT_QTUITOOLS_LIBRARY} ${QT_QTGUI_LIBRARY} diff --git a/src/libtomahawk/Playlist.cpp b/src/libtomahawk/Playlist.cpp index 1762b7b26..8966f8484 100644 --- a/src/libtomahawk/Playlist.cpp +++ b/src/libtomahawk/Playlist.cpp @@ -37,7 +37,9 @@ #include "PlaylistPlaylistInterface.h" #include "utils/Logger.h" +#include "utils/Closure.h" #include "PlaylistUpdaterInterface.h" +#include "widgets/SourceTreePopupDialog.h" using namespace Tomahawk; @@ -179,16 +181,14 @@ Playlist::create( const source_ptr& author, p->setGuid( uuid() ); p->setDuration( query->duration() ); p->setLastmodified( 0 ); - QString annotation = ""; - if ( !query->property( "annotation" ).toString().isEmpty() ) - annotation = query->property( "annotation" ).toString(); - p->setAnnotation( annotation ); + p->setAnnotation( query->property( "annotation" ).toString() ); p->setQuery( query ); entries << p; } playlist_ptr playlist( new Playlist( author, guid, title, info, creator, shared, entries ), &QObject::deleteLater ); + playlist->setWeakSelf( playlist.toWeakRef() ); // save to DB in the background // Watch for the created() signal if you need to be sure it's written. @@ -310,6 +310,83 @@ Playlist::removeUpdater( PlaylistUpdaterInterface* updater ) } +bool +Playlist::hasCustomDeleter() const +{ + foreach ( PlaylistUpdaterInterface* updater, m_updaters ) + { + if ( updater->hasCustomDeleter() ) + return true; + } + + return false; +} + + +void +Playlist::customDelete( const QPoint& leftCenter ) +{ + if ( !hasCustomDeleter() ) + return; + + Tomahawk::PlaylistDeleteQuestions questions; + foreach ( PlaylistUpdaterInterface* updater, m_updaters ) + { + if ( updater->deleteQuestions().isEmpty() ) + continue; + + questions.append( updater->deleteQuestions() ); + } + + SourceTreePopupDialog* dialog = new SourceTreePopupDialog; + NewClosure( dialog, SIGNAL( result( bool ) ), this, SLOT( onDeleteResult( SourceTreePopupDialog* ) ), dialog ); + + dialog->setMainText( tr( "Would you like to delete the playlist \"%2\"?", "e.g. Would you like to delete the playlist named Foobar?" ) + .arg( title() ) ); + dialog->setOkButtonText( tr( "Delete" ) ); + dialog->setExtraQuestions( questions ); + + dialog->move( leftCenter.x() - dialog->offset(), leftCenter.y() - dialog->sizeHint().height() / 2. ); + dialog->show(); +} + + +void +Playlist::onDeleteResult( SourceTreePopupDialog* dialog ) +{ + dialog->deleteLater(); + + const bool ret = dialog->resultValue(); + + if ( !ret ) + return; + + playlist_ptr p = m_weakSelf.toStrongRef(); + if ( p.isNull() ) + { + qWarning() << "Got null m_weakSelf weak ref in Playlsit::onDeleteResult!!"; + Q_ASSERT( false ); + return; + } + + const QMap< int, bool > questionResults = dialog->questionResults(); + foreach ( PlaylistUpdaterInterface* updater, m_updaters ) + { + updater->setQuestionResults( questionResults ); + } + + dynplaylist_ptr dynpl = p.dynamicCast< DynamicPlaylist >(); + if ( !dynpl.isNull() ) + { + DynamicPlaylist::remove( dynpl ); + } + else + { + remove( p ); + } +} + + void Playlist::loadRevision( const QString& rev ) { @@ -508,7 +585,7 @@ Playlist::setNewRevision( const QString& rev, tDebug() << "m_entries" << m_entries; tLog() << "Playlist error for playlist with guid" << guid() << "from source" << author()->friendlyName(); - Q_ASSERT( false ); // XXX +// Q_ASSERT( false ); // XXX } } @@ -710,6 +787,13 @@ Playlist::checkRevisionQueue() } +void +Playlist::setWeakSelf( QWeakPointer< Playlist > self ) +{ + m_weakSelf = self; +} + + Tomahawk::playlistinterface_ptr Playlist::playlistInterface() { diff --git a/src/libtomahawk/Playlist.h b/src/libtomahawk/Playlist.h index c3ac6c45b..697b0114d 100644 --- a/src/libtomahawk/Playlist.h +++ b/src/libtomahawk/Playlist.h @@ -35,6 +35,7 @@ #include "DllMacro.h" +class SourceTreePopupDialog; class DatabaseCommand_LoadAllPlaylists; class DatabaseCommand_LoadAllSortedPlaylists; class DatabaseCommand_SetPlaylistRevision; @@ -194,6 +195,18 @@ public: void removeUpdater( PlaylistUpdaterInterface* updater ); QList updaters() const { return m_updaters; } + /** + * Some updaters might have custom deleters in order to perform more actions that require + * user prompting on delete. + */ + bool hasCustomDeleter() const; + /** + * If this playlist has a custom deleter, let it do the deleting itself. + * + * If it needs user prompting, use the \param customDeleter as the right-most center point. + */ + void customDelete( const QPoint& rightCenter ); + Tomahawk::playlistinterface_ptr playlistInterface(); signals: @@ -249,6 +262,7 @@ public slots: void resolve(); + void setWeakSelf( QWeakPointer< Playlist > self ); protected: // called from loadAllPlaylists DB cmd: explicit Playlist( const source_ptr& src, @@ -282,6 +296,7 @@ private slots: void onResultsFound( const QList& results ); void onResolvingFinished(); + void onDeleteResult( SourceTreePopupDialog* ); private: Playlist(); void init(); @@ -289,6 +304,7 @@ private: void setBusy( bool b ); void checkRevisionQueue(); + QWeakPointer< Playlist > m_weakSelf; source_ptr m_source; QString m_currentrevision; QString m_guid, m_title, m_info, m_creator; diff --git a/src/libtomahawk/Query.cpp b/src/libtomahawk/Query.cpp index 8cf519a9d..cbe748beb 100644 --- a/src/libtomahawk/Query.cpp +++ b/src/libtomahawk/Query.cpp @@ -479,14 +479,19 @@ Query::checkResults() bool -Query::equals( const Tomahawk::query_ptr& other ) const +Query::equals( const Tomahawk::query_ptr& other, bool ignoreCase ) const { if ( other.isNull() ) return false; - return ( artist() == other->artist() && - album() == other->album() && - track() == other->track() ); + if ( ignoreCase ) + return ( artist().toLower() == other->artist().toLower() && + album().toLower() == other->album().toLower() && + track().toLower() == other->track().toLower() ); + else + return ( artist() == other->artist() && + album() == other->album() && + track() == other->track() ); } diff --git a/src/libtomahawk/Query.h b/src/libtomahawk/Query.h index 4d6f5c3b9..7ad147074 100644 --- a/src/libtomahawk/Query.h +++ b/src/libtomahawk/Query.h @@ -123,7 +123,7 @@ public: void setAlbumPos( unsigned int albumpos ) { m_albumpos = albumpos; } void setDiscNumber( unsigned int discnumber ) { m_discnumber = discnumber; } - bool equals( const Tomahawk::query_ptr& other ) const; + bool equals( const Tomahawk::query_ptr& other, bool ignoreCase = false ) const; QVariant toVariant() const; QString toString() const; diff --git a/src/libtomahawk/Typedefs.h b/src/libtomahawk/Typedefs.h index 730799e9a..aad92ff9d 100644 --- a/src/libtomahawk/Typedefs.h +++ b/src/libtomahawk/Typedefs.h @@ -98,6 +98,9 @@ namespace Tomahawk typedef QMultiHash< QString, SerializedUpdater > SerializedUpdaters; typedef QList< SerializedUpdater > SerializedUpdaterList; + // Yes/no questions with an associated enum value + typedef QPair< QString, int > PlaylistDeleteQuestion; + typedef QList< PlaylistDeleteQuestion > PlaylistDeleteQuestions; namespace InfoSystem { diff --git a/src/libtomahawk/ViewManager.cpp b/src/libtomahawk/ViewManager.cpp index d247e932b..573d91fb4 100644 --- a/src/libtomahawk/ViewManager.cpp +++ b/src/libtomahawk/ViewManager.cpp @@ -2,6 +2,7 @@ * * Copyright 2010-2011, Christian Muehlhaeuser * Copyright 2010-2011, Jeff Mitchell + * Copyright 2010-2012, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 41a1963c1..01b2687f6 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -38,8 +38,9 @@ using namespace Accounts; AccountModel::AccountModel( QObject* parent ) : QAbstractListModel( parent ) + , m_waitingForAtticaLoaded( true ) { - connect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( loadData() ) ); + connect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( atticaLoaded() ) ); connect( AtticaManager::instance(), SIGNAL( startedInstalling( QString ) ), this, SLOT( onStartedInstalling( QString ) ) ); connect( AtticaManager::instance(), SIGNAL( resolverInstalled( QString ) ), this, SLOT( onFinishedInstalling( QString ) ) ); connect( AtticaManager::instance(), SIGNAL( resolverInstallationFailed( QString ) ), this, SLOT( resolverInstallFailed( QString ) ) ); @@ -51,6 +52,15 @@ AccountModel::AccountModel( QObject* parent ) loadData(); } + +void +AccountModel::atticaLoaded() +{ + m_waitingForAtticaLoaded = false; + loadData(); +} + + void AccountModel::loadData() { @@ -644,7 +654,8 @@ AccountModel::accountAdded( Account* account ) if ( ResolverAccount* resolver = qobject_cast< ResolverAccount* >( account ) ) { qDebug() << "Plain old manual resolver added, appending at end"; - Q_ASSERT( qobject_cast< AtticaResolverAccount* >( account ) == 0 ); // should NOT get attica accounts here, should be caught above + if ( !m_waitingForAtticaLoaded ) + Q_ASSERT( qobject_cast< AtticaResolverAccount* >( account ) == 0 ); // should NOT get attica accounts here, should be caught above const int count = m_accounts.size(); beginInsertRows( QModelIndex(), count, count ); m_accounts << new AccountModelNode( resolver ); diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index 13de779f1..09be15187 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -100,6 +100,7 @@ signals: void errorInstalling( const QPersistentModelIndex& idx ); private slots: + void atticaLoaded(); void loadData(); void accountAdded( Tomahawk::Accounts::Account* ); @@ -112,6 +113,7 @@ private slots: private: QModelIndex indexForAtticaId( const QString& resolverId ) const; + bool m_waitingForAtticaLoaded; QList< AccountModelNode* > m_accounts; QSet< QString > m_waitingForAtticaInstall; }; diff --git a/src/libtomahawk/accounts/lastfm/LastFmAccount.h b/src/libtomahawk/accounts/lastfm/LastFmAccount.h index f1b7ffc0c..ef4bbea3b 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmAccount.h +++ b/src/libtomahawk/accounts/lastfm/LastFmAccount.h @@ -26,6 +26,7 @@ #include #include +#include namespace Tomahawk { class ExternalResolverGui; diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp index aceea6bff..6a8c98b63 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.cpp @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Leo Franchi + * Copyright 2010-2012, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,11 +22,16 @@ #include "LastFmAccount.h" #include "database/Database.h" #include "database/DatabaseCommand_LogPlayback.h" +#include +#include #include "utils/TomahawkUtils.h" #include "utils/Logger.h" -#include "lastfm/ws.h" -#include "lastfm/User.h" -#include "lastfm/XmlQuery.h" +#include "utils/Closure.h" + +#include +#include +#include +#include using namespace Tomahawk::Accounts; @@ -36,6 +41,9 @@ LastFmConfig::LastFmConfig( LastFmAccount* account ) , m_account( account ) , m_page( 1 ) , m_lastTimeStamp( 0 ) + , m_totalLovedPages( -1 ) + , m_doneFetchingLoved( false ) + , m_doneFetchingLocal( false ) { m_ui = new Ui_LastFmConfig; m_ui->setupUi( this ); @@ -48,6 +56,7 @@ LastFmConfig::LastFmConfig( LastFmAccount* account ) connect( m_ui->testLogin, SIGNAL( clicked( bool ) ), SLOT( testLogin() ) ); connect( m_ui->importHistory, SIGNAL( clicked( bool ) ), SLOT( loadHistory() ) ); + connect( m_ui->syncLovedTracks, SIGNAL( clicked( bool ) ), SLOT( syncLovedTracks() ) ); connect( m_ui->username, SIGNAL( textChanged( QString ) ), SLOT( enableButton() ) ); connect( m_ui->password, SIGNAL( textChanged( QString ) ), SLOT( enableButton() ) ); @@ -141,7 +150,7 @@ LastFmConfig::onHistoryLoaded() foreach ( lastfm::XmlQuery e, lfm.children( "track" ) ) { // tDebug() << "Found:" << e.children( "artist" ).first()["name"].text() << e["name"].text() << e["date"].attribute( "uts" ).toUInt(); - Tomahawk::query_ptr query = Query::get( e.children( "artist" ).first()["name"].text(), e["name"].text(), QString(), QString(), false ); + Tomahawk::query_ptr query = Tomahawk::Query::get( e.children( "artist" ).first()["name"].text(), e["name"].text(), QString(), QString(), false ); if ( query.isNull() ) continue; @@ -217,6 +226,7 @@ LastFmConfig::onLastFmFinished() { m_ui->testLogin->setText( tr( "Success" ) ); m_ui->testLogin->setEnabled( false ); + m_ui->syncLovedTracks->setEnabled( true ); } } else @@ -237,3 +247,167 @@ LastFmConfig::onLastFmFinished() } } } + + +void +LastFmConfig::syncLovedTracks( uint page ) +{ + QNetworkReply* reply = lastfm::User( username() ).getLovedTracks( 200, page ); + + m_ui->syncLovedTracks->setEnabled( false ); + m_ui->syncLovedTracks->setText( tr( "Synchronizing..." ) ); + m_ui->progressBar->show(); + emit sizeHintChanged(); + + NewClosure( reply, SIGNAL( finished() ), this, SLOT( onLovedFinished( QNetworkReply* ) ), reply ); + + DatabaseCommand_LoadSocialActions* cmd = new DatabaseCommand_LoadSocialActions( "Love", SourceList::instance()->getLocal() ); + connect( cmd, SIGNAL( done( DatabaseCommand_LoadSocialActions::TrackActions ) ), this, SLOT( localLovedLoaded( DatabaseCommand_LoadSocialActions::TrackActions ) ) ); + + Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) ); + +} + + +void +LastFmConfig::onLovedFinished( QNetworkReply* reply ) +{ + Q_ASSERT( reply ); + + try + { + lastfm::XmlQuery lfm; + lfm.parse( reply->readAll() ); + + if ( !lfm.children( "lovedtracks" ).isEmpty() ) + { + lastfm::XmlQuery loved = lfm.children( "lovedtracks" ).first(); + + const int thisPage = loved.attribute( "page" ).toInt(); + + if ( m_totalLovedPages < 0 ) + { + m_totalLovedPages = loved.attribute( "totalPages" ).toInt(); + m_ui->progressBar->setMaximum( m_totalLovedPages + 2 ); + } + + m_ui->progressBar->setValue( thisPage ); + foreach ( lastfm::XmlQuery e, loved.children( "track" ) ) + { +// tDebug() << "Found:" << e.children( "artist" ).first()["name"].text() << e["name"].text() << e["date"].attribute( "uts" ).toUInt(); + Tomahawk::query_ptr query = Tomahawk::Query::get( e.children( "artist" ).first()["name"].text(), e["name"].text(), QString(), QString(), false ); + if ( query.isNull() ) + continue; + + m_lastfmLoved.insert( query ); + } + + + if ( thisPage == m_totalLovedPages ) + { + m_doneFetchingLoved = true; + + if ( m_doneFetchingLocal ) + syncLoved(); + + return; + } + else + { + syncLovedTracks( thisPage + 1 ); + } + } + else + { + m_ui->syncLovedTracks->setText( "Failed" ); + m_ui->progressBar->hide(); + emit sizeHintChanged(); + } + } + catch( lastfm::ws::ParseError e ) + { + m_ui->syncLovedTracks->setText( "Failed" ); + m_ui->progressBar->hide(); + emit sizeHintChanged(); + tDebug() << "XmlQuery error:" << e.message(); + } +} + + +bool trackEquality( const Tomahawk::query_ptr& first, const Tomahawk::query_ptr& second ) +{ + return first->equals( second, true ); +} + + +void +LastFmConfig::localLovedLoaded( DatabaseCommand_LoadSocialActions::TrackActions tracks ) +{ + m_localLoved = tracks; + m_doneFetchingLocal = true; + + if ( m_doneFetchingLoved ) + syncLoved(); +} + + +void +LastFmConfig::syncLoved() +{ + QSet< Tomahawk::query_ptr > localToLove, lastFmToLove, lastFmToUnlove; + + const QSet< Tomahawk::query_ptr > myLoved = m_localLoved.keys().toSet(); + + m_ui->progressBar->setValue( m_ui->progressBar->value() + 1 ); + + foreach ( const Tomahawk::query_ptr& lastfmLoved, m_lastfmLoved ) + { + QSet< Tomahawk::query_ptr >::const_iterator iter = std::find_if( myLoved.begin(), myLoved.end(), boost::bind( &trackEquality, _1, boost::ref( lastfmLoved ) ) ); + if ( iter == myLoved.constEnd() ) + { +// qDebug() << "Found last.fm loved track that we didn't have loved locally:" << lastfmLoved->track() << lastfmLoved->artist(); + localToLove << lastfmLoved; + } + } + + foreach ( const Tomahawk::query_ptr& localLoved, myLoved ) + { + QSet< Tomahawk::query_ptr >::const_iterator iter = std::find_if( m_lastfmLoved.begin(), m_lastfmLoved.end(), boost::bind( &trackEquality, _1, boost::ref( localLoved ) ) ); + + // If we unloved it locally, but it's still loved on last.fm, unlove it + if ( m_localLoved[ localLoved ].value.toString() == "false" && iter != m_lastfmLoved.constEnd() ) + lastFmToUnlove << localLoved; + + // If we loved it locally but not loved on last.fm, love it + if ( m_localLoved[ localLoved ].value.toString() == "true" && iter == m_lastfmLoved.constEnd() ) + lastFmToLove << localLoved; + } + + foreach ( const Tomahawk::query_ptr& track, localToLove ) + { + // Don't use the infosystem as we don't want to tweet a few hundred times :) + DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( track, QString( "Love" ), QString( "true" ) ); + Database::instance()->enqueue( QSharedPointer(cmd) ); + } + + lastFmToLove.unite( lastFmToUnlove ); + + foreach ( const Tomahawk::query_ptr& track, lastFmToLove ) + { + lastfm::MutableTrack lfmTrack; + lfmTrack.stamp(); + + lfmTrack.setTitle( track->track() ); + lfmTrack.setArtist( track->artist() ); + lfmTrack.setSource( lastfm::Track::Player ); + + if ( lastFmToUnlove.contains( track ) ) + lfmTrack.unlove(); + else + lfmTrack.love(); + } + + m_ui->progressBar->setValue( m_ui->progressBar->value() + 1 ); + m_ui->syncLovedTracks->setText( tr( "Synchronization Finished" ) ); +} + diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.h b/src/libtomahawk/accounts/lastfm/LastFmConfig.h index c7c53f2b9..b443b85a5 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.h +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.h @@ -1,6 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2010-2011, Leo Franchi + * Copyright 2010-2012, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,12 @@ #ifndef LASTFMCONFIG_H #define LASTFMCONFIG_H +#include "Query.h" +#include "database/DatabaseCommand_LoadSocialActions.h" + #include +#include +#include class Ui_LastFmConfig; @@ -45,19 +50,31 @@ public slots: private slots: void enableButton(); - + void loadHistory(); void onHistoryLoaded(); + void syncLovedTracks() { syncLovedTracks( 1 ); } + void syncLovedTracks( uint page ); + void onLovedFinished( QNetworkReply* reply ); + void localLovedLoaded( DatabaseCommand_LoadSocialActions::TrackActions ); + signals: void sizeHintChanged(); private: + void syncLoved(); + LastFmAccount* m_account; Ui_LastFmConfig* m_ui; - + unsigned int m_page; unsigned int m_lastTimeStamp; + + int m_totalLovedPages; + bool m_doneFetchingLoved, m_doneFetchingLocal; + QSet< Tomahawk::query_ptr > m_lastfmLoved; + DatabaseCommand_LoadSocialActions::TrackActions m_localLoved; }; } diff --git a/src/libtomahawk/accounts/lastfm/LastFmConfig.ui b/src/libtomahawk/accounts/lastfm/LastFmConfig.ui index 1a75ae970..20a07ced7 100644 --- a/src/libtomahawk/accounts/lastfm/LastFmConfig.ui +++ b/src/libtomahawk/accounts/lastfm/LastFmConfig.ui @@ -23,7 +23,7 @@ - :/data/images/lastfm-icon.png + :/data/images/lastfm-icon.png Qt::AlignCenter @@ -84,6 +84,13 @@ + + + + Synchronize Loved Tracks + + + diff --git a/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp b/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp index f330678ea..a5d643dbf 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp +++ b/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp @@ -679,7 +679,7 @@ SpotifyAccount::setSubscribedForPlaylist( const playlist_ptr& playlist, bool sub sendMessage( msg, this ); updater->setSync( subscribed ); - updater->setSubscribed( subscribed ); + updater->setSubscribedStatus( subscribed ); } @@ -733,7 +733,7 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg QObject* receiver = m_qidToSlotMap[ qid ].first; QString slot = m_qidToSlotMap[ qid ].second; m_qidToSlotMap.remove( qid ); - + QVariant extraData; if ( m_qidToExtraData.contains( qid ) ) extraData = m_qidToExtraData.take( qid ); @@ -1214,7 +1214,7 @@ SpotifyAccount::sendMessage( const QVariantMap &m, QObject* obj, const QString& } m_qidToExtraData[ qid ] = extraData; - + m_spotifyResolver.data()->sendMessage( msg ); return qid; @@ -1312,7 +1312,7 @@ SpotifyAccount::setSyncForPlaylist( const QString& spotifyPlaylistId, bool sync if ( info ) info->sync = sync; - + if ( !m_configWidget.isNull() ) m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists.values() ); diff --git a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp index e2c4ab252..28c3cf748 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp +++ b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp @@ -65,7 +65,7 @@ SpotifyUpdaterFactory::create( const Tomahawk::playlist_ptr& pl, const QVariantH SpotifyPlaylistUpdater* updater = new SpotifyPlaylistUpdater( m_account.data(), latestRev, spotifyId, pl ); updater->setSync( sync ); updater->setCanSubscribe( canSubscribe ); - updater->setSubscribed( isSubscribed ); + updater->setSubscribedStatus( isSubscribed ); m_account.data()->registerUpdaterForPlaylist( spotifyId, updater ); return updater; @@ -131,44 +131,28 @@ SpotifyPlaylistUpdater::remove( bool askToDeletePlaylist ) void -SpotifyPlaylistUpdater::aboutToDelete() +SpotifyPlaylistUpdater::unsyncOrDelete( bool toDelete ) { if ( QThread::currentThread() != QApplication::instance()->thread() ) - QMetaObject::invokeMethod( const_cast(this), "aboutToDelete", Qt::BlockingQueuedConnection ); + QMetaObject::invokeMethod( const_cast(this), "unsyncOrDelete", Qt::BlockingQueuedConnection, Q_ARG( bool, toDelete ) ); else { if ( m_subscribed ) { m_spotify.data()->setSubscribedForPlaylist( playlist(), false ); } - else if ( m_sync ) + else if ( m_sync && toDelete ) { - checkDeleteDialog(); + // User wants to delete it! + QVariantMap msg; + msg[ "_msgtype" ] = "deletePlaylist"; + msg[ "playlistid" ] = m_spotifyId; + m_spotify.data()->sendMessage( msg ); } } } -void -SpotifyPlaylistUpdater::checkDeleteDialog() const -{ - // Ask if we should delete the playlist on the spotify side as well - QMessageBox askDelete( QMessageBox::Question, tr( "Delete in Spotify?" ), tr( "Would you like to delete the corresponding Spotify playlist as well?" ), QMessageBox::Yes | QMessageBox::No, 0 ); - int ret = askDelete.exec(); - if ( ret == QMessageBox::Yes ) - { - if ( m_spotify.isNull() ) - return; - - // User wants to delete it! - QVariantMap msg; - msg[ "_msgtype" ] = "deletePlaylist"; - msg[ "playlistid" ] = m_spotifyId; - m_spotify.data()->sendMessage( msg ); - } -} - - void SpotifyPlaylistUpdater::playlistRevisionLoaded() { @@ -242,8 +226,9 @@ SpotifyPlaylistUpdater::sync() const return m_sync; } + void -SpotifyPlaylistUpdater::setSubscribed( bool subscribed ) +SpotifyPlaylistUpdater::setSubscribedStatus( bool subscribed ) { if ( m_subscribed == subscribed ) return; @@ -255,6 +240,16 @@ SpotifyPlaylistUpdater::setSubscribed( bool subscribed ) } +void +SpotifyPlaylistUpdater::setSubscribed( bool subscribed ) +{ + if ( !m_spotify.isNull() ) + m_spotify.data()->setSubscribedForPlaylist( playlist(), subscribed ); + + // Spotify account will in turn call setSUbscribedStatus +} + + bool SpotifyPlaylistUpdater::subscribed() const { @@ -282,6 +277,25 @@ SpotifyPlaylistUpdater::canSubscribe() const } +PlaylistDeleteQuestions +SpotifyPlaylistUpdater::deleteQuestions() const +{ + // 1234 is our magic key + if ( m_sync && !m_subscribed ) + return Tomahawk::PlaylistDeleteQuestions() << qMakePair( tr( "Delete associated Spotify playlist?" ), 1234 ); + else + return Tomahawk::PlaylistDeleteQuestions(); +} + + +void +SpotifyPlaylistUpdater::setQuestionResults( const QMap< int, bool > results ) +{ + const bool toDelete = results.value( 1234, false ); + unsyncOrDelete( toDelete ); +} + + void SpotifyPlaylistUpdater::spotifyTracksAdded( const QVariantList& tracks, const QString& startPosId, const QString& newRev, const QString& oldRev ) { diff --git a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h index b5de8e4b9..133ab1274 100644 --- a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h +++ b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h @@ -2,7 +2,7 @@ * * Copyright 2010-2012, Leo Franchi * Copyright 2012, Hugo Lindström - * + * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -23,6 +23,7 @@ #include "playlist/PlaylistUpdaterInterface.h" #include "utils/Closure.h" #include "DllMacro.h" +#include "Typedefs.h" #include #include @@ -55,11 +56,18 @@ public: bool sync() const; void setSync( bool sync ); bool subscribed() const; + // actually change the subscribed value in spotify void setSubscribed( bool subscribed ); + // Just set the subscribed flag + void setSubscribedStatus( bool subscribed ); bool canSubscribe() const; void setCanSubscribe( bool canSub ); QString spotifyId() const { return m_spotifyId; } + virtual bool hasCustomDeleter() const { return true; } + virtual Tomahawk::PlaylistDeleteQuestions deleteQuestions() const; + virtual void setQuestionResults( const QMap< int, bool > results ); + void remove( bool askToDeletePlaylist = true ); public slots: /// Spotify callbacks when we are directly instructed from the resolver @@ -73,15 +81,13 @@ public slots: void tomahawkTracksMoved( const QList& ,int ); void tomahawkPlaylistRenamed( const QString&, const QString& ); - void aboutToDelete(); - private slots: // SpotifyResolver message handlers, all take msgtype, msg as argument void onTracksInsertedReturn( const QString& msgType, const QVariantMap& msg, const QVariant& extraData ); void onTracksRemovedReturn( const QString& msgType, const QVariantMap& msg, const QVariant& extraData ); void onTracksMovedReturn( const QString& msgType, const QVariantMap& msg, const QVariant& extraData ); - void checkDeleteDialog() const; + void unsyncOrDelete( bool toDelete ); void playlistRevisionLoaded(); private: diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp index e8f07c45c..137a58a61 100644 --- a/src/libtomahawk/audio/AudioEngine.cpp +++ b/src/libtomahawk/audio/AudioEngine.cpp @@ -42,6 +42,7 @@ #include "jobview/ErrorStatusMessage.h" #include "utils/Logger.h" +#include "SingleTrackPlaylistInterface.h" using namespace Tomahawk; @@ -574,7 +575,7 @@ AudioEngine::loadNextTrack() void -AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result ) +AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery ) { tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ); @@ -582,7 +583,11 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk: m_playlist.data()->reset(); setPlaylist( playlist ); - m_currentTrackPlaylist = playlist; + + if ( playlist.isNull() && !fromQuery.isNull() ) + m_currentTrackPlaylist = playlistinterface_ptr( new SingleTrackPlaylistInterface( fromQuery ) ); + else + m_currentTrackPlaylist = playlist; if ( !result.isNull() ) { @@ -606,7 +611,7 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk: { if ( query->numResults() && query->results().first()->isOnline() ) { - playItem( playlist, query->results().first() ); + playItem( playlist, query->results().first(), query ); return; } diff --git a/src/libtomahawk/audio/AudioEngine.h b/src/libtomahawk/audio/AudioEngine.h index e5183ea40..df5d5f5f8 100644 --- a/src/libtomahawk/audio/AudioEngine.h +++ b/src/libtomahawk/audio/AudioEngine.h @@ -86,11 +86,11 @@ public slots: void seek( qint64 ms ); void seek( int ms ); // for compatibility with seekbar in audiocontrols void setVolume( int percentage ); - void lowerVolume(); + void lowerVolume(); void raiseVolume(); void mute(); - void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result ); + void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery = Tomahawk::query_ptr() ); void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::query_ptr& query ); void playItem( const Tomahawk::artist_ptr& artist ); void playItem( const Tomahawk::album_ptr& album ); diff --git a/src/libtomahawk/context/ContextWidget.cpp b/src/libtomahawk/context/ContextWidget.cpp index bbf0e8334..618d1a0fb 100644 --- a/src/libtomahawk/context/ContextWidget.cpp +++ b/src/libtomahawk/context/ContextWidget.cpp @@ -84,6 +84,7 @@ ContextWidget::ContextWidget( QWidget* parent ) QPalette whitePal = ui->toggleButton->palette(); whitePal.setColor( QPalette::Foreground, Qt::white ); ui->toggleButton->setPalette( whitePal ); + ui->toggleButton->setCursor( Qt::PointingHandCursor ); QFont boldFont = ui->toggleButton->font(); boldFont.setPixelSize( 12 ); diff --git a/src/libtomahawk/database/DatabaseCollection.cpp b/src/libtomahawk/database/DatabaseCollection.cpp index 2dca1980d..9744b428e 100644 --- a/src/libtomahawk/database/DatabaseCollection.cpp +++ b/src/libtomahawk/database/DatabaseCollection.cpp @@ -144,6 +144,8 @@ DatabaseCollection::autoPlaylistCreated( const source_ptr& source, const QVarian data[7].toBool(), //shared data[8].toInt(), //lastmod data[9].toString() ), &QObject::deleteLater ); //GUID + p->setWeakSelf( p.toWeakRef() ); + addAutoPlaylist( p ); } @@ -162,6 +164,8 @@ DatabaseCollection::stationCreated( const source_ptr& source, const QVariantList data[7].toBool(), //shared data[8].toInt(), //lastmod data[9].toString() ), &QObject::deleteLater ); //GUID + p->setWeakSelf( p.toWeakRef() ); + addStation( p ); } diff --git a/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp b/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp index 43179d10d..ede7245b7 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp +++ b/src/libtomahawk/database/DatabaseCommand_LoadAllPlaylists.cpp @@ -72,6 +72,7 @@ DatabaseCommand_LoadAllPlaylists::exec( DatabaseImpl* dbi ) query.value(4).toInt(), //lastmod query.value(0).toString() //GUID ), &QObject::deleteLater ); + p->setWeakSelf( p.toWeakRef() ); plists.append( p ); } diff --git a/src/libtomahawk/database/DatabaseCommand_LoadAllSortedPlaylists.cpp b/src/libtomahawk/database/DatabaseCommand_LoadAllSortedPlaylists.cpp index 8e0c33c50..95bd87136 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadAllSortedPlaylists.cpp +++ b/src/libtomahawk/database/DatabaseCommand_LoadAllSortedPlaylists.cpp @@ -70,38 +70,7 @@ DatabaseCommand_LoadAllSortedPlaylists::exec( DatabaseImpl* dbi ) while ( query.next() ) { plists << QPair< int, QString >( query.value(9).toInt(), query.value(0).toString() ); -// playlist_ptr p; -// bool dynamic = query.value(8).toBool(); -// source_ptr s = SourceList::instance()->get( query.value(9).toInt() ); -// -// if ( dynamic ) -// { -// p = dynplaylist_ptr( new DynamicPlaylist( s, -// query.value(6).toString(), //current rev -// query.value(1).toString(), //title -// query.value(2).toString(), //info -// query.value(3).toString(), //creator -// query.value(7).toInt(), //createdOn -// query.value(10).toString(), //type -// (GeneratorMode)query.value(11).toInt(), // mode -// query.value(5).toBool(), //shared -// query.value(4).toInt(), //lastmod -// query.value(0).toString() //GUID -// ) ); -// } else -// { -// p = playlist_ptr( new Playlist( s, //src -// query.value(6).toString(), //current rev -// query.value(1).toString(), //title -// query.value(2).toString(), //info -// query.value(3).toString(), //creator -// query.value(7).toInt(), //createdOn -// query.value(5).toBool(), //shared -// query.value(4).toInt(), //lastmod -// query.value(0).toString() //GUID -// ) ); -// } -// plists.append( p ); + } emit done( plists ); diff --git a/src/libtomahawk/database/DatabaseCommand_LoadDynamicPlaylist.cpp b/src/libtomahawk/database/DatabaseCommand_LoadDynamicPlaylist.cpp index f0444ae01..70df163aa 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadDynamicPlaylist.cpp +++ b/src/libtomahawk/database/DatabaseCommand_LoadDynamicPlaylist.cpp @@ -60,6 +60,8 @@ Tomahawk::DatabaseCommand_LoadDynamicPlaylist::exec( DatabaseImpl* dbi ) query.value(5).toInt(), //lastmod query.value(0).toString() ) ); //GUID + p->setWeakSelf( p.toWeakRef() ); +/* tLog() << "Loaded individual dynamic playlist:" << query.value(7).toString() //current rev << query.value(1).toString() //title << query.value(2).toString() //info @@ -69,7 +71,7 @@ Tomahawk::DatabaseCommand_LoadDynamicPlaylist::exec( DatabaseImpl* dbi ) << static_cast(query.value(9).toInt()) // dynamic mode << query.value(6).toBool() //shared << query.value(5).toInt() //lastmod - << query.value(0).toString(); //GUID + << query.value(0).toString(); //GUID */ emit dynamicPlaylistLoaded( p ); } diff --git a/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.cpp b/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.cpp index 49e6b7e25..cc53e781f 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.cpp +++ b/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.cpp @@ -37,40 +37,74 @@ DatabaseCommand_LoadSocialActions::exec( DatabaseImpl* dbi ) TomahawkSqlQuery query = dbi->newquery(); - QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id(); - - int artid = dbi->artistId( m_artist, false ); - if( artid < 1 ) - return; - - int trkid = dbi->trackId( artid, m_track, false ); - if( trkid < 1 ) - return; - - QString whereToken; - whereToken = QString( "WHERE id IS %1" ).arg( trkid ); - - QString sql = QString( - "SELECT k, v, timestamp, source " - "FROM social_attributes %1 " - "ORDER BY timestamp ASC" ).arg( whereToken ); - - query.prepare( sql ); - query.exec(); - - QList< Tomahawk::SocialAction > allSocialActions; - while ( query.next() ) + if ( m_actionOnly.isNull() ) { - Tomahawk::SocialAction action; - action.action = query.value( 0 ); // action - action.value = query.value( 1 ); // comment - action.timestamp = query.value( 2 ); // timestamp - action.source = SourceList::instance()->get( query.value( 3 ).toInt() ); // source - - if ( !action.source.isNull() ) - allSocialActions.append( action ); - } + // Load for just specified track + int artid = dbi->artistId( m_artist, false ); + if( artid < 1 ) + return; - m_query->setAllSocialActions( allSocialActions ); + int trkid = dbi->trackId( artid, m_track, false ); + if( trkid < 1 ) + return; + + QString whereToken; + whereToken = QString( "WHERE id IS %1" ).arg( trkid ); + + QString sql = QString( + "SELECT k, v, timestamp, source " + "FROM social_attributes %1 " + "ORDER BY timestamp ASC" ).arg( whereToken ); + + query.prepare( sql ); + query.exec(); + + QList< Tomahawk::SocialAction > allSocialActions; + while ( query.next() ) + { + Tomahawk::SocialAction action; + action.action = query.value( 0 ); // action + action.value = query.value( 1 ); // comment + action.timestamp = query.value( 2 ); // timestamp + action.source = SourceList::instance()->get( query.value( 3 ).toInt() ); // source + + if ( !action.source.isNull() ) + allSocialActions.append( action ); + } + + m_query->setAllSocialActions( allSocialActions ); + } + else + { + // Load all tracks with this social action + const QString srcStr = source()->isLocal() ? "IS NULL" : QString( "=%1" ).arg( source()->id() ); + + query.prepare( QString( "SELECT id, v, timestamp FROM social_attributes WHERE source %1 AND k = ? " ).arg( srcStr ) ); + query.addBindValue( m_actionOnly ); + + query.exec(); + + DatabaseCommand_LoadSocialActions::TrackActions trackActions; + while ( query.next() ) + { + const QVariantMap track = dbi->track( query.value( 0 ).toInt() ); + if ( track.value( "artist" ).toString().isEmpty() || track.value( "name" ).toString().isEmpty() ) + continue; + + const QVariantMap artist = dbi->artist( track.value( "artist" ).toInt() ); + + const query_ptr trackQuery = Query::get( artist.value( "name" ).toString(), track.value( "name" ).toString(), QString(), QString(), false ); + + Tomahawk::SocialAction action; + action.action = m_actionOnly; // action + action.value = query.value( 1 ); // comment + action.timestamp = query.value( 2 ); // timestamp + action.source = source(); // source + + trackActions[ trackQuery ] = action; + } + + emit done( trackActions ); + } } diff --git a/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h b/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h index 8656823b3..fdc987bd5 100644 --- a/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h +++ b/src/libtomahawk/database/DatabaseCommand_LoadSocialActions.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2011, Christopher Reichert + * Copyright 2012, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,6 +46,7 @@ class DLLEXPORT DatabaseCommand_LoadSocialActions : public DatabaseCommand Q_OBJECT public: + typedef QMap TrackActions; /** * \brief Default constructor for DatabaseCommand_LoadSocialActions. * @@ -69,6 +71,16 @@ public: setTrack( query->track() ); } + /** + * Load all tracks with a specific social action + */ + explicit DatabaseCommand_LoadSocialActions( const QString& action, const Tomahawk::source_ptr& source, QObject* parent = 0 ) + : DatabaseCommand( parent ), m_actionOnly( action ) + { + setSource( source ); + qRegisterMetaType( "DatabaseCommand_LoadSocialAction::TrackActions" ); + } + /** * \brief Returns the name of this database command. * \return QString containing the database command name 'loadsocialaction'. @@ -114,21 +126,22 @@ public: */ void setTrack( const QString& s ) { m_track = s; } + virtual bool doesMutates() const { return false; } signals: - /** - * \brief Emitted when the database command has finished the Query successfully - * - * \param QList of all social actions - * \see QList + * All loaded social actions for each track found, for queries that generate all tracks + * with matching actions. */ - void done( QList< Tomahawk::SocialAction >& allSocialActions ); + void done( DatabaseCommand_LoadSocialActions::TrackActions actionsForTracks ); private: Tomahawk::query_ptr m_query; QString m_artist; QString m_track; + QString m_actionOnly; }; +Q_DECLARE_METATYPE( DatabaseCommand_LoadSocialActions::TrackActions ) + #endif // DATABASECOMMAND_LOADSOCIALACTIONS_H diff --git a/src/libtomahawk/database/DatabaseCommand_PlaybackHistory.cpp b/src/libtomahawk/database/DatabaseCommand_PlaybackHistory.cpp index a2093dd25..67aea6dc4 100644 --- a/src/libtomahawk/database/DatabaseCommand_PlaybackHistory.cpp +++ b/src/libtomahawk/database/DatabaseCommand_PlaybackHistory.cpp @@ -49,7 +49,7 @@ DatabaseCommand_PlaybackHistory::exec( DatabaseImpl* dbi ) query.prepare( sql ); query.exec(); - while( query.next() ) + while ( query.next() ) { TomahawkSqlQuery query_track = dbi->newquery(); @@ -66,6 +66,8 @@ DatabaseCommand_PlaybackHistory::exec( DatabaseImpl* dbi ) if ( query_track.next() ) { Tomahawk::query_ptr q = Tomahawk::Query::get( query_track.value( 1 ).toString(), query_track.value( 0 ).toString(), QString() ); + if ( q.isNull() ) + continue; if ( query.value( 3 ).toUInt() == 0 ) { diff --git a/src/libtomahawk/database/DatabaseCommand_Resolve.cpp b/src/libtomahawk/database/DatabaseCommand_Resolve.cpp index f9f631f70..bcb708429 100644 --- a/src/libtomahawk/database/DatabaseCommand_Resolve.cpp +++ b/src/libtomahawk/database/DatabaseCommand_Resolve.cpp @@ -219,7 +219,7 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) emit albums( m_query->id(), albumList ); } - + if ( trackPairs.length() == 0 ) { qDebug() << "No candidates found in first pass, aborting resolve" << m_query->fullTextQuery(); diff --git a/src/libtomahawk/jobview/JobStatusItem.cpp b/src/libtomahawk/jobview/JobStatusItem.cpp index 9db2726a2..8c2dd2b1d 100644 --- a/src/libtomahawk/jobview/JobStatusItem.cpp +++ b/src/libtomahawk/jobview/JobStatusItem.cpp @@ -18,10 +18,12 @@ #include "JobStatusItem.h" +#include JobStatusItem::JobStatusItem() : QObject() + , m_createdOn( QDateTime::currentMSecsSinceEpoch() ) { } diff --git a/src/libtomahawk/jobview/JobStatusItem.h b/src/libtomahawk/jobview/JobStatusItem.h index e2d8ca606..dc85d8ae4 100644 --- a/src/libtomahawk/jobview/JobStatusItem.h +++ b/src/libtomahawk/jobview/JobStatusItem.h @@ -65,12 +65,16 @@ public: virtual void createDelegate( QObject* parent ); virtual QStyledItemDelegate* customDelegate() const; + qint64 age() const { return m_createdOn; } signals: /// Ask for an update void statusChanged(); /// Job is finished, will be deleted by the model void finished(); + +private: + qint64 m_createdOn; }; Q_DECLARE_METATYPE( JobStatusItem* ); diff --git a/src/libtomahawk/jobview/JobStatusModel.cpp b/src/libtomahawk/jobview/JobStatusModel.cpp index 1744a5d4b..8a364e926 100644 --- a/src/libtomahawk/jobview/JobStatusModel.cpp +++ b/src/libtomahawk/jobview/JobStatusModel.cpp @@ -82,14 +82,14 @@ JobStatusSortModel::refreshDelegatesSlot() bool JobStatusSortModel::lessThan( const QModelIndex& left, const QModelIndex& right ) const { - QVariant leftVar = left.data( JobStatusModel::JobDataRole ); - JobStatusItem* leftItem = leftVar.value< JobStatusItem* >(); - QVariant rightVar = right.data( JobStatusModel::JobDataRole ); - JobStatusItem* rightItem = rightVar.value< JobStatusItem* >(); - if ( !leftItem || !rightItem ) - return false; + const int leftSort = left.data( JobStatusModel::SortRole ).toInt(); + const int rightSort = right.data( JobStatusModel::SortRole ).toInt(); - return leftItem->weight() < rightItem->weight(); + if ( leftSort == rightSort ) + return left.data( JobStatusModel::AgeRole ).toUInt() > right.data( JobStatusModel::AgeRole ).toUInt(); + + + return leftSort < rightSort; } @@ -204,6 +204,15 @@ JobStatusModel::data( const QModelIndex& index, int role ) const case JobDataRole: return QVariant::fromValue< JobStatusItem* >( item ); + + case SortRole: + return item->weight(); + + case AgeRole: + return item->age(); + + default: + return QVariant(); } return QVariant(); diff --git a/src/libtomahawk/jobview/JobStatusModel.h b/src/libtomahawk/jobview/JobStatusModel.h index dc4d80ca5..358a581c7 100644 --- a/src/libtomahawk/jobview/JobStatusModel.h +++ b/src/libtomahawk/jobview/JobStatusModel.h @@ -37,7 +37,9 @@ public: // DisplayRole is main col RightColumnRole = Qt::UserRole + 1, AllowMultiLineRole = Qt::UserRole + 2, - JobDataRole = Qt::UserRole + 3 + JobDataRole = Qt::UserRole + 3, + SortRole = Qt::UserRole + 4, + AgeRole = Qt::UserRole + 5 }; explicit JobStatusModel( QObject* parent = 0 ); diff --git a/src/libtomahawk/jobview/TransferStatusItem.cpp b/src/libtomahawk/jobview/TransferStatusItem.cpp index ae5794013..ec696a974 100644 --- a/src/libtomahawk/jobview/TransferStatusItem.cpp +++ b/src/libtomahawk/jobview/TransferStatusItem.cpp @@ -55,7 +55,7 @@ TransferStatusItem::mainText() const return QString( "%1" ).arg( QString( "%1 - %2" ).arg( m_stream.data()->track()->artist()->name() ).arg( m_stream.data()->track()->track() ) ); else if ( !m_stream.data()->source().isNull() && !m_stream.data()->track().isNull() ) return QString( "%1 %2 %3" ).arg( QString( "%1 - %2" ).arg( m_stream.data()->track()->artist()->name() ).arg( m_stream.data()->track()->track() ) ) - .arg( m_stream.data()->type() == StreamConnection::RECEIVING ? tr( "from" ) : tr( "to" ) ) + .arg( m_stream.data()->type() == StreamConnection::RECEIVING ? tr( "from", "streaming artist - track from friend" ) : tr( "to", "streaming artist - track to friend" ) ) .arg( m_stream.data()->source()->friendlyName() ); else return QString(); diff --git a/src/libtomahawk/network/ControlConnection.cpp b/src/libtomahawk/network/ControlConnection.cpp index 59704fc4b..a3f069c8e 100644 --- a/src/libtomahawk/network/ControlConnection.cpp +++ b/src/libtomahawk/network/ControlConnection.cpp @@ -96,12 +96,14 @@ ControlConnection::~ControlConnection() m_dbsyncconn->deleteLater(); } + source_ptr ControlConnection::source() const { return m_source; } + Connection* ControlConnection::clone() { diff --git a/src/libtomahawk/playlist/FlexibleView.cpp b/src/libtomahawk/playlist/FlexibleView.cpp index 3a6d7534d..187b3e34c 100644 --- a/src/libtomahawk/playlist/FlexibleView.cpp +++ b/src/libtomahawk/playlist/FlexibleView.cpp @@ -27,12 +27,39 @@ #include "playlist/TrackView.h" #include "playlist/GridView.h" #include "playlist/PlaylistLargeItemDelegate.h" +#include "PlayableProxyModelPlaylistInterface.h" #include "utils/TomahawkUtilsGui.h" #include "utils/Logger.h" using namespace Tomahawk; +class FlexibleViewInterface : public PlayableProxyModelPlaylistInterface { + Q_OBJECT +public: + explicit FlexibleViewInterface( PlayableProxyModel* proxy, FlexibleView* view ) : PlayableProxyModelPlaylistInterface( proxy ), m_view( view ) {} + + virtual bool hasChildInterface( playlistinterface_ptr playlistInterface ) + { + if ( m_view.isNull() ) + return false; + + if ( m_view.data()->detailedView() && m_view.data()->detailedView()->proxyModel()->playlistInterface() == playlistInterface ) + return true; + + if ( m_view.data()->gridView() && m_view.data()->gridView()->playlistInterface()->hasChildInterface( playlistInterface ) ) + return true; + + if ( m_view.data()->trackView() && m_view.data()->trackView()->proxyModel()->playlistInterface() == playlistInterface ) + return true; + + return false; + } + +private: + QWeakPointer m_view; +}; + FlexibleView::FlexibleView( QWidget* parent ) : QWidget( parent ) , m_header( new FlexibleHeader( this ) ) @@ -43,6 +70,8 @@ FlexibleView::FlexibleView( QWidget* parent ) { qRegisterMetaType< FlexibleViewMode >( "FlexibleViewMode" ); + m_playlistInterface = playlistinterface_ptr( new FlexibleViewInterface( m_trackView->proxyModel(), this ) ); + PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LovedTracks, m_trackView, m_trackView->proxyModel() ); connect( del, SIGNAL( updateIndex( QModelIndex ) ), m_trackView, SLOT( update( QModelIndex ) ) ); m_trackView->setItemDelegate( del ); @@ -79,8 +108,12 @@ FlexibleView::setTrackView( TrackView* view ) delete m_trackView; } + if ( view && m_trackView != view ) + m_playlistInterface = playlistinterface_ptr( new FlexibleViewInterface( view->proxyModel(), this ) ); + m_trackView = view; m_stack->addWidget( view ); + } @@ -169,7 +202,7 @@ FlexibleView::setCurrentMode( FlexibleViewMode mode ) Tomahawk::playlistinterface_ptr FlexibleView::playlistInterface() const { - return m_trackView->playlistInterface(); + return m_playlistInterface; } @@ -232,3 +265,5 @@ FlexibleView::setPixmap( const QPixmap& pixmap ) m_pixmap = pixmap; m_header->setPixmap( pixmap ); } + +#include "FlexibleView.moc" diff --git a/src/libtomahawk/playlist/FlexibleView.h b/src/libtomahawk/playlist/FlexibleView.h index 3b502643a..a78104116 100644 --- a/src/libtomahawk/playlist/FlexibleView.h +++ b/src/libtomahawk/playlist/FlexibleView.h @@ -29,6 +29,7 @@ class GridView; class TrackView; class PlayableModel; class FlexibleHeader; +class FlexibleViewInterface; class DLLEXPORT FlexibleView : public QWidget, public Tomahawk::ViewPage { @@ -80,10 +81,14 @@ private: TrackView* m_detailedView; GridView* m_gridView; + Tomahawk::playlistinterface_ptr m_playlistInterface; + PlayableModel* m_model; QStackedWidget* m_stack; FlexibleViewMode m_mode; + + friend class ::FlexibleViewInterface; }; Q_DECLARE_METATYPE( FlexibleView::FlexibleViewMode ); diff --git a/src/libtomahawk/playlist/GridItemDelegate.cpp b/src/libtomahawk/playlist/GridItemDelegate.cpp index 6110608bc..a79104a96 100644 --- a/src/libtomahawk/playlist/GridItemDelegate.cpp +++ b/src/libtomahawk/playlist/GridItemDelegate.cpp @@ -459,6 +459,8 @@ GridItemDelegate::onPlaybackFinished() foreach ( ImageButton* button, m_pauseButton ) button->deleteLater(); m_pauseButton.clear(); + + emit stoppedPlaying( QModelIndex() ); } @@ -501,6 +503,8 @@ GridItemDelegate::onPlaylistChanged( const QPersistentModelIndex& index ) m_spinner[ index ]->deleteLater(); m_spinner.remove( index ); } + + emit stoppedPlaying( index ); } } } @@ -532,6 +536,8 @@ GridItemDelegate::onPlaybackStarted( const QPersistentModelIndex& index ) connect( button, SIGNAL( clicked( bool ) ), AudioEngine::instance(), SLOT( playPause() ) ); m_pauseButton[ index ] = button; + + emit startedPlaying( index ); } diff --git a/src/libtomahawk/playlist/GridItemDelegate.h b/src/libtomahawk/playlist/GridItemDelegate.h index b05b171a3..a14414715 100644 --- a/src/libtomahawk/playlist/GridItemDelegate.h +++ b/src/libtomahawk/playlist/GridItemDelegate.h @@ -58,6 +58,9 @@ protected: signals: void updateIndex( const QModelIndex& idx ); + void startedPlaying( const QPersistentModelIndex& ); + void stoppedPlaying( const QPersistentModelIndex& ); + private slots: void modelChanged(); void doUpdateIndex( const QPersistentModelIndex& idx ); diff --git a/src/libtomahawk/playlist/GridView.cpp b/src/libtomahawk/playlist/GridView.cpp index 0b0197f2c..4c5e635ca 100644 --- a/src/libtomahawk/playlist/GridView.cpp +++ b/src/libtomahawk/playlist/GridView.cpp @@ -34,6 +34,8 @@ #include "GridItemDelegate.h" #include "AlbumModel.h" #include "PlayableModel.h" +#include "PlayableProxyModelPlaylistInterface.h" +#include "SingleTrackPlaylistInterface.h" #include "ContextMenu.h" #include "ViewManager.h" #include "utils/Logger.h" @@ -44,6 +46,34 @@ using namespace Tomahawk; +class GridPlaylistInterface : public PlayableProxyModelPlaylistInterface { + Q_OBJECT +public: + explicit GridPlaylistInterface( PlayableProxyModel* proxy, GridView* view ) : PlayableProxyModelPlaylistInterface( proxy ), m_view( view ) {} + + virtual bool hasChildInterface( playlistinterface_ptr playlistInterface ) + { + if ( m_view.isNull() || !m_view.data()->m_playing.isValid() ) + { + return false; + } + + PlayableItem* item = m_view.data()->model()->itemFromIndex( m_view.data()->proxyModel()->mapToSource( m_view.data()->m_playing ) ); + if ( item ) + { + if ( !item->album().isNull() ) + return item->album()->playlistInterface( Tomahawk::Mixed ) == playlistInterface; + else if ( !item->artist().isNull() ) + return item->artist()->playlistInterface( Tomahawk::Mixed ) == playlistInterface; + else if ( !item->query().isNull() && !playlistInterface.dynamicCast< SingleTrackPlaylistInterface >().isNull() ) + return item->query() == playlistInterface.dynamicCast< SingleTrackPlaylistInterface >()->track(); + } + + return false; + } +private: + QWeakPointer m_view; +}; GridView::GridView( QWidget* parent ) : QListView( parent ) @@ -77,6 +107,8 @@ GridView::GridView( QWidget* parent ) setAutoResize( false ); setProxyModel( new PlayableProxyModel( this ) ); + m_playlistInterface = playlistinterface_ptr( new GridPlaylistInterface( m_proxyModel, this ) ); + connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); connect( this, SIGNAL( customContextMenuRequested( QPoint ) ), SLOT( onCustomContextMenu( QPoint ) ) ); @@ -103,6 +135,8 @@ GridView::setProxyModel( PlayableProxyModel* model ) m_delegate = new GridItemDelegate( this, m_proxyModel ); connect( m_delegate, SIGNAL( updateIndex( QModelIndex ) ), this, SLOT( update( QModelIndex ) ) ); + connect( m_delegate, SIGNAL( startedPlaying( QPersistentModelIndex ) ), this, SLOT( onDelegatePlaying( QPersistentModelIndex ) ) ); + connect( m_delegate, SIGNAL( stoppedPlaying( QPersistentModelIndex ) ), this, SLOT( onDelegateStopped( QPersistentModelIndex ) ) ); setItemDelegate( m_delegate ); QListView::setModel( m_proxyModel ); @@ -179,7 +213,7 @@ GridView::onItemActivated( const QModelIndex& index ) else if ( !item->artist().isNull() ) ViewManager::instance()->show( item->artist() ); else if ( !item->query().isNull() ) - AudioEngine::instance()->playItem( playlistinterface_ptr(), item->query() ); + ViewManager::instance()->show( item->query() ); } } @@ -238,6 +272,21 @@ GridView::verifySize() } +void +GridView::onDelegatePlaying( const QPersistentModelIndex& index ) +{ + m_playing = index; +} + + +void +GridView::onDelegateStopped( const QPersistentModelIndex& index ) +{ + if ( m_playing == index ) + m_playing = QPersistentModelIndex(); +} + + void GridView::layoutItems() { @@ -356,3 +405,27 @@ GridView::setFilter( const QString& filter ) m_proxyModel->setFilter( filter ); return true; } + +bool +GridView::jumpToCurrentTrack() +{ + if ( !m_playing.isValid() ) + return false; + + scrollTo( m_playing, QListView::PositionAtCenter ); + + return true; +} + + +QRect +GridView::currentTrackRect() const +{ + if ( !m_playing.isValid() ) + return QRect(); + + return visualRect( m_playing ); +} + + +#include "GridView.moc" diff --git a/src/libtomahawk/playlist/GridView.h b/src/libtomahawk/playlist/GridView.h index 7003f0573..a5b006d2b 100644 --- a/src/libtomahawk/playlist/GridView.h +++ b/src/libtomahawk/playlist/GridView.h @@ -37,6 +37,7 @@ namespace Tomahawk class AnimatedSpinner; class GridItemDelegate; class PlayableModel; +class GridPlaylistInterface; class DLLEXPORT GridView : public QListView, public Tomahawk::ViewPage { @@ -64,13 +65,16 @@ public: void setEmptyTip( const QString& tip ); virtual QWidget* widget() { return this; } - virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return proxyModel()->playlistInterface(); } + virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return m_playlistInterface; } virtual QString title() const { return m_model->title(); } virtual QString description() const { return m_model->description(); } virtual bool setFilter( const QString& filter ); - virtual bool jumpToCurrentTrack() { return false; } + virtual bool jumpToCurrentTrack(); + QRect currentTrackRect() const; + + virtual bool isBeingPlayed() const { return m_playing.isValid(); } public slots: void onItemActivated( const QModelIndex& index ); @@ -94,6 +98,9 @@ private slots: void onFilterChanged( const QString& filter ); void onCustomContextMenu( const QPoint& pos ); + void onDelegatePlaying( const QPersistentModelIndex& idx ); + void onDelegateStopped( const QPersistentModelIndex& idx ); + void layoutItems(); void verifySize(); @@ -103,8 +110,11 @@ private: GridItemDelegate* m_delegate; AnimatedSpinner* m_loadingSpinner; OverlayWidget* m_overlay; + Tomahawk::playlistinterface_ptr m_playlistInterface; QModelIndex m_contextMenuIndex; + QPersistentModelIndex m_playing; + Tomahawk::ContextMenu* m_contextMenu; QString m_emptyTip; @@ -113,6 +123,8 @@ private: bool m_autoResize; QRect m_paintRect; + + friend class ::GridPlaylistInterface; }; #endif // GRIDVIEW_H diff --git a/src/libtomahawk/playlist/LovedTracksModel.cpp b/src/libtomahawk/playlist/LovedTracksModel.cpp index b0552d76e..63d6f5a01 100644 --- a/src/libtomahawk/playlist/LovedTracksModel.cpp +++ b/src/libtomahawk/playlist/LovedTracksModel.cpp @@ -29,6 +29,8 @@ #include "utils/TomahawkUtils.h" #include "utils/Logger.h" +#include + #define LOVED_TRACK_ITEMS 25 using namespace Tomahawk; @@ -36,8 +38,13 @@ using namespace Tomahawk; LovedTracksModel::LovedTracksModel( QObject* parent ) : PlaylistModel( parent ) + , m_smoothingTimer( new QTimer ) , m_limit( LOVED_TRACK_ITEMS ) { + m_smoothingTimer->setInterval( 300 ); + m_smoothingTimer->setSingleShot( true ); + + connect( m_smoothingTimer, SIGNAL( timeout() ), this, SLOT( loadTracks() ) ); } @@ -49,10 +56,6 @@ LovedTracksModel::~LovedTracksModel() void LovedTracksModel::loadTracks() { - if ( rowCount( QModelIndex() ) ) - { - clear(); - } startLoading(); QString sql; @@ -74,7 +77,7 @@ LovedTracksModel::loadTracks() } DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( sql, DatabaseCommand_GenericSelect::Track, -1, 0 ); - connect( cmd, SIGNAL( tracks( QList ) ), this, SLOT( appendQueries( QList ) ) ); + connect( cmd, SIGNAL( tracks( QList ) ), this, SLOT( tracksLoaded( QList ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); } @@ -122,7 +125,7 @@ LovedTracksModel::onSourceAdded( const Tomahawk::source_ptr& source ) void LovedTracksModel::onTrackLoved() { - loadTracks(); + m_smoothingTimer->start(); } @@ -131,3 +134,26 @@ LovedTracksModel::isTemporary() const { return true; } + + +void +LovedTracksModel::tracksLoaded( QList< query_ptr > newLoved ) +{ + finishLoading(); + + QList< query_ptr > tracks; + + foreach ( const plentry_ptr ple, playlistEntries() ) + tracks << ple->query(); + + bool changed = false; + QList< query_ptr > mergedTracks = TomahawkUtils::mergePlaylistChanges( tracks, newLoved, changed ); + + if ( changed ) + { + QList el = playlist()->entriesFromQueries( mergedTracks, true ); + + clear(); + appendEntries( el ); + } +} diff --git a/src/libtomahawk/playlist/LovedTracksModel.h b/src/libtomahawk/playlist/LovedTracksModel.h index 6b3b40d1d..43210b6a7 100644 --- a/src/libtomahawk/playlist/LovedTracksModel.h +++ b/src/libtomahawk/playlist/LovedTracksModel.h @@ -50,8 +50,10 @@ private slots: void onTrackLoved(); void loadTracks(); + void tracksLoaded( QList ); private: Tomahawk::source_ptr m_source; + QTimer* m_smoothingTimer; unsigned int m_limit; }; diff --git a/src/libtomahawk/playlist/PlaylistModel.cpp b/src/libtomahawk/playlist/PlaylistModel.cpp index b324b2f42..f5724aaa4 100644 --- a/src/libtomahawk/playlist/PlaylistModel.cpp +++ b/src/libtomahawk/playlist/PlaylistModel.cpp @@ -80,7 +80,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn setReadOnly( !m_playlist->author()->isLocal() ); setTitle( playlist->title() ); setDescription( tr( "A playlist by %1, created %2" ) - .arg( playlist->author()->isLocal() ? tr( "you" ) : playlist->author()->friendlyName() ) + .arg( playlist->creator().isEmpty() ? ( playlist->author()->isLocal() ? tr( "you" ) : playlist->author()->friendlyName() ) : playlist->creator() ) .arg( TomahawkUtils::ageToString( QDateTime::fromTime_t( playlist->createdOn() ), true ) ) ); m_isTemporary = false; diff --git a/src/libtomahawk/playlist/PlaylistModel.h b/src/libtomahawk/playlist/PlaylistModel.h index 88ac0ec90..3963c2faa 100644 --- a/src/libtomahawk/playlist/PlaylistModel.h +++ b/src/libtomahawk/playlist/PlaylistModel.h @@ -77,6 +77,7 @@ protected: bool waitForRevision( const QString& revisionguid ) const { return m_waitForRevision.contains( revisionguid ); } void removeFromWaitList( const QString& revisionguid ) { m_waitForRevision.removeAll( revisionguid ); } + QList playlistEntries() const; private slots: void onRevisionLoaded( Tomahawk::PlaylistRevision revision ); void parsedDroppedTracks( QList ); @@ -86,8 +87,6 @@ private: void beginPlaylistChanges(); void endPlaylistChanges(); - QList playlistEntries() const; - Tomahawk::playlist_ptr m_playlist; bool m_isTemporary; bool m_changesOngoing; diff --git a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h index 0776451bd..1d569e1a2 100644 --- a/src/libtomahawk/playlist/PlaylistUpdaterInterface.h +++ b/src/libtomahawk/playlist/PlaylistUpdaterInterface.h @@ -25,6 +25,7 @@ #include #include +#include #ifndef ENABLE_HEADLESS #include @@ -35,6 +36,12 @@ namespace Tomahawk /** * PlaylistUpdaters are attached to playlists. They usually manipulate the playlist in some way * due to external input (spotify syncing) or timers (xspf updating) + * + * Updaters have 2 modes of operation: syncing and subscribing. Syncing implies two-way sync, that is, this + * playlist is reproduced on some other service (e.g. spotify or rdio). + * + * Subscribing implies the playlist is being updated periodically with changes from some source, and the user + * is working with a copy: e.g. an xspf updater or a spotify subscribed playlist. */ class PlaylistUpdaterFactory; @@ -71,7 +78,18 @@ public: static void registerUpdaterFactory( PlaylistUpdaterFactory* f ); - virtual bool sync() const { return true; } + virtual bool sync() const { return false; } + virtual void setSync( bool ) {} + + virtual bool canSubscribe() const { return false; } + virtual bool subscribed() const { return false; } + virtual void setSubscribed( bool ) {} + + // The int data value associated with each question must be unique across *all* playlist updaters, + // as setQuestionResults is called with all questions from all updaters. + virtual bool hasCustomDeleter() const { return false; } + virtual PlaylistDeleteQuestions deleteQuestions() const { return PlaylistDeleteQuestions(); } + virtual void setQuestionResults( const QMap< int, bool > ) {} signals: void changed(); diff --git a/src/libtomahawk/playlist/SingleTrackPlaylistInterface.h b/src/libtomahawk/playlist/SingleTrackPlaylistInterface.h new file mode 100644 index 000000000..5438debdf --- /dev/null +++ b/src/libtomahawk/playlist/SingleTrackPlaylistInterface.h @@ -0,0 +1,59 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef SINGLE_TRACK_PLAYLIST_INTERFACE +#define SINGLE_TRACK_PLAYLIST_INTERFACE + +#include "PlaylistInterface.h" +#include "DllMacro.h" +#include "Query.h" +#include "Typedefs.h" +#include "Result.h" + +namespace Tomahawk +{ + +class DLLEXPORT SingleTrackPlaylistInterface : public PlaylistInterface +{ + Q_OBJECT +public: + explicit SingleTrackPlaylistInterface( const query_ptr& query ) + : PlaylistInterface() + , m_track( query ) + { + } + + query_ptr track() const { return m_track; } + void setQuery( const query_ptr& track ) { m_track = track; } + + virtual result_ptr currentItem() const { return result_ptr(); } + virtual PlaylistModes::RepeatMode repeatMode() const { return PlaylistModes::NoRepeat; } + virtual void setRepeatMode( PlaylistModes::RepeatMode ) {} + virtual void setShuffled( bool ) {} + virtual bool shuffled() const { return false; } + virtual result_ptr siblingItem( int itemsAway ) { return result_ptr(); } + virtual int trackCount() const { return 1; } + virtual QList< query_ptr > tracks() { return QList< query_ptr >(); } + +private: + query_ptr m_track; +}; + +} + +#endif diff --git a/src/libtomahawk/playlist/XspfUpdater.cpp b/src/libtomahawk/playlist/XspfUpdater.cpp index 879184ba2..585707c9c 100644 --- a/src/libtomahawk/playlist/XspfUpdater.cpp +++ b/src/libtomahawk/playlist/XspfUpdater.cpp @@ -144,6 +144,8 @@ XspfUpdater::setAutoUpdate( bool autoUpdate ) // Update immediately as well if ( m_autoUpdate ) QTimer::singleShot( 0, this, SLOT( updateNow() ) ); + + emit changed(); } void @@ -158,3 +160,10 @@ XspfUpdater::setInterval( int intervalMsecs ) m_timer->setInterval( intervalMsecs ); } + + +void +XspfUpdater::setSubscribed( bool subscribed ) +{ + setAutoUpdate( subscribed ); +} diff --git a/src/libtomahawk/playlist/XspfUpdater.h b/src/libtomahawk/playlist/XspfUpdater.h index cbe875119..6cff1d875 100644 --- a/src/libtomahawk/playlist/XspfUpdater.h +++ b/src/libtomahawk/playlist/XspfUpdater.h @@ -48,6 +48,10 @@ public: void setInterval( int intervalMsecs ) ; int intervalMsecs() const { return m_timer->interval(); } + bool canSubscribe() const { return true; } + bool subscribed() const { return m_autoUpdate; } + void setSubscribed( bool subscribed ); + public slots: void updateNow(); void setAutoUpdate( bool autoUpdate ); diff --git a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp index 85ceda9f4..4cea498c1 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicPlaylist.cpp @@ -155,6 +155,7 @@ DynamicPlaylist::create( const Tomahawk::source_ptr& author, ) { dynplaylist_ptr dynplaylist = Tomahawk::dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, mode, shared, autoLoad ), &QObject::deleteLater ); + dynplaylist->setWeakSelf( dynplaylist.toWeakRef() ); DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist, autoLoad ); connect( cmd, SIGNAL(finished()), dynplaylist.data(), SIGNAL(created()) ); diff --git a/src/libtomahawk/resolvers/QtScriptResolver.cpp b/src/libtomahawk/resolvers/QtScriptResolver.cpp index e58a7b090..6b1d1ec5e 100644 --- a/src/libtomahawk/resolvers/QtScriptResolver.cpp +++ b/src/libtomahawk/resolvers/QtScriptResolver.cpp @@ -411,6 +411,11 @@ QtScriptResolver::parseResultVariantList( const QVariantList& reslist ) if ( m.value( "artist" ).toString().trimmed().isEmpty() || m.value( "track" ).toString().trimmed().isEmpty() ) continue; + // TODO we need to handle preview urls separately. they should never trump a real url, and we need to display + // the purchaseUrl for the user to upgrade to a full stream. + if ( m.value( "preview" ).toBool() == true ) + continue; + Tomahawk::result_ptr rp = Tomahawk::Result::get( m.value( "url" ).toString() ); Tomahawk::artist_ptr ap = Tomahawk::Artist::get( m.value( "artist" ).toString(), false ); rp->setArtist( ap ); diff --git a/src/libtomahawk/utils/AnimatedSpinner.cpp b/src/libtomahawk/utils/AnimatedSpinner.cpp index 2d66e7273..9c9f7c878 100644 --- a/src/libtomahawk/utils/AnimatedSpinner.cpp +++ b/src/libtomahawk/utils/AnimatedSpinner.cpp @@ -165,7 +165,7 @@ AnimatedSpinner::drawFrame( QPainter* p, const QRect& rect ) void AnimatedSpinner::fadeIn() { - if ( parentWidget() && isVisible() ) + if ( ( parentWidget() && isVisible() ) || m_animation->state() == QTimeLine::Running ) return; m_animation->start(); diff --git a/src/libtomahawk/utils/Closure.cpp b/src/libtomahawk/utils/Closure.cpp index 2b2a608bb..daa1003b2 100644 --- a/src/libtomahawk/utils/Closure.cpp +++ b/src/libtomahawk/utils/Closure.cpp @@ -1,5 +1,6 @@ /* This file is part of Clementine. Copyright 2011, David Sansome + Copyright 2012, Leo Franchi Clementine is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,9 +17,15 @@ */ #include "Closure.h" +#include namespace _detail { +static bool on_this_thread(QObject* obj) +{ + return QCoreApplication::instance()->thread() == obj->thread(); +} + Closure::Closure(QObject* sender, const char* signal, QObject* receiver, @@ -27,9 +34,10 @@ Closure::Closure(QObject* sender, const ClosureArgumentWrapper* val1, const ClosureArgumentWrapper* val2, const ClosureArgumentWrapper* val3) - : QObject(receiver), + : QObject(on_this_thread(receiver) ? receiver : 0), callback_(NULL), - autoDelete_( true ), + autoDelete_(true), + outOfThreadReceiver_(on_this_thread(receiver) ? 0 : receiver ), val0_(val0), val1_(val1), val2_(val2), @@ -77,7 +85,7 @@ void Closure::Invoked() { callback_(); } else { slot_.invoke( - parent(), + parent() ? parent() : outOfThreadReceiver_, val0_ ? val0_->arg() : QGenericArgument(), val1_ ? val1_->arg() : QGenericArgument(), val2_ ? val2_->arg() : QGenericArgument(), diff --git a/src/libtomahawk/utils/Closure.h b/src/libtomahawk/utils/Closure.h index 591712358..de47502bc 100644 --- a/src/libtomahawk/utils/Closure.h +++ b/src/libtomahawk/utils/Closure.h @@ -89,6 +89,7 @@ class DLLEXPORT Closure : public QObject, boost::noncopyable { QMetaMethod slot_; std::tr1::function callback_; bool autoDelete_; + QObject* outOfThreadReceiver_; boost::scoped_ptr val0_; boost::scoped_ptr val1_; diff --git a/src/libtomahawk/utils/ProxyStyle.cpp b/src/libtomahawk/utils/ProxyStyle.cpp index cb7cd45e1..fe57817c8 100644 --- a/src/libtomahawk/utils/ProxyStyle.cpp +++ b/src/libtomahawk/utils/ProxyStyle.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2012, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -76,9 +77,29 @@ ProxyStyle::drawControl( ControlElement ce, const QStyleOption* opt, QPainter* p if ( !splitter->sizes().contains( 0 ) ) { p->setPen( QColor( 0x8c, 0x8c, 0x8c ) ); - p->drawLine( opt->rect.topLeft(), opt->rect.bottomRight() ); + // We must special-case this because of the AnimatedSplitterHandle which has a + // SizeHint of 0,0. + if( splitter->orientation() == Qt::Vertical ) + p->drawLine( opt->rect.topLeft(), opt->rect.topRight() ); + else + p->drawLine( opt->rect.topLeft(), opt->rect.bottomRight() ); } } else QProxyStyle::drawControl( ce, opt, p, w ); } + +QSize +ProxyStyle::sizeFromContents( QStyle::ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget ) const +{ + if( type == CT_Splitter ) + { + const QSplitter* splitter = qobject_cast< const QSplitter* >( widget ); + if( splitter->orientation() == Qt::Horizontal ) + return QSize( 1, size.height() ); + else + return QSize( size.width(), 1 ); + } + else + return QProxyStyle::sizeFromContents( type, option, size, widget ); +} diff --git a/src/libtomahawk/utils/ProxyStyle.h b/src/libtomahawk/utils/ProxyStyle.h index 0a8d636ca..aa1dec625 100644 --- a/src/libtomahawk/utils/ProxyStyle.h +++ b/src/libtomahawk/utils/ProxyStyle.h @@ -31,6 +31,7 @@ public: virtual void drawPrimitive( PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w = 0 ) const; virtual void drawControl( ControlElement ce, const QStyleOption *opt, QPainter *p, const QWidget *w = 0 ) const; + virtual QSize sizeFromContents( ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget ) const; }; #endif // PROXYSTYLE_H diff --git a/src/libtomahawk/utils/SpotifyParser.cpp b/src/libtomahawk/utils/SpotifyParser.cpp index d312934c2..48de033d6 100644 --- a/src/libtomahawk/utils/SpotifyParser.cpp +++ b/src/libtomahawk/utils/SpotifyParser.cpp @@ -105,7 +105,7 @@ SpotifyParser::lookupSpotifyBrowse( const QString& linkRaw ) m_browseUri.replace( "/", ":" ); m_browseUri = "spotify:" + m_browseUri; } - + if ( m_browseUri.contains( "playlist" ) && Tomahawk::Accounts::SpotifyAccount::instance() != 0 && Tomahawk::Accounts::SpotifyAccount::instance()->loggedIn() ) @@ -237,6 +237,7 @@ SpotifyParser::spotifyBrowseFinished() tLog() << "Setting resulthint to " << trackResult.value( "trackuri" ); q->setResultHint( trackResult.value( "trackuri" ).toString() ); + q->setProperty( "annotation", trackResult.value( "trackuri" ).toString() ); m_tracks << q; } @@ -303,7 +304,7 @@ SpotifyParser::spotifyTrackLookupFinished() if ( !q.isNull() ) { q->setResultHint( t.value( "trackuri" ).toString() ); - + m_tracks << q; } } @@ -333,10 +334,17 @@ SpotifyParser::playlistListingResult( const QString& msgType, const QVariantMap& { QVariantMap trackMap = blob.toMap(); const query_ptr q = Query::get( trackMap.value( "artist" ).toString(), trackMap.value( "track" ).toString(), trackMap.value( "album" ).toString(), uuid(), false ); - + if ( q.isNull() ) continue; - + + const QString id = trackMap.value( "id" ).toString(); + if( !id.isEmpty() ) + { + q->setResultHint( id ); + q->setProperty( "annotation", id ); + } + m_tracks << q; } @@ -355,12 +363,19 @@ SpotifyParser::checkBrowseFinished() if ( m_createNewPlaylist && !m_tracks.isEmpty() ) { + QString spotifyUsername; + + if ( Accounts::SpotifyAccount::instance() && Accounts::SpotifyAccount::instance()->loggedIn() ) + { + QVariantHash creds = Accounts::SpotifyAccount::instance()->credentials(); + spotifyUsername = creds.value( "username" ).toString(); + } m_playlist = Playlist::create( SourceList::instance()->getLocal(), uuid(), m_title, m_info, - m_creator, + spotifyUsername == m_creator ? QString() : m_creator, false, m_tracks ); @@ -371,10 +386,9 @@ SpotifyParser::checkBrowseFinished() SpotifyPlaylistUpdater* updater = new SpotifyPlaylistUpdater( Accounts::SpotifyAccount::instance(), m_playlist->currentrevision(), m_browseUri, m_playlist ); - QVariantHash creds = Accounts::SpotifyAccount::instance()->credentials(); // If the user isnt dropping a playlist the he owns, its subscribeable - if ( !m_browseUri.contains( creds.value( "username" ).toString() ) ) + if ( !m_browseUri.contains( spotifyUsername ) ) updater->setCanSubscribe( true ); // Just register the infos diff --git a/src/libtomahawk/widgets/AnimatedSplitter.cpp b/src/libtomahawk/widgets/AnimatedSplitter.cpp index 539433136..95992e19a 100644 --- a/src/libtomahawk/widgets/AnimatedSplitter.cpp +++ b/src/libtomahawk/widgets/AnimatedSplitter.cpp @@ -298,9 +298,8 @@ AnimatedSplitterHandle::sizeHint() const m_lastCount = splitter()->count(); } - // sizeHint is 0,0 if widget below handle has size 0 or is hidden - if ( splitter()->widget( m_indexInSplitter )->height() == 0 ) - return QSize( 0, 0 ); - else - return QSize( 1, 1 ); + // Since we are in an AnimatedSplitter, we always return 0,0 for SizeHint, simply + // because we know there's going to be a handle in the bottom widget to move the + // splitter. + return QSize( 0, 0 ); } diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog.cpp b/src/libtomahawk/widgets/SourceTreePopupDialog.cpp new file mode 100644 index 000000000..d6943a357 --- /dev/null +++ b/src/libtomahawk/widgets/SourceTreePopupDialog.cpp @@ -0,0 +1,220 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#include "SourceTreePopupDialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef QT_MAC_USE_COCOA +#include "SourceTreePopupDialog_mac.h" +#endif + +using namespace Tomahawk; + +SourceTreePopupDialog::SourceTreePopupDialog() + : QWidget( 0 ) + , m_layout( 0 ) + , m_result( false ) + , m_label( 0 ) + , m_buttons( 0 ) +{ + setWindowFlags( Qt::FramelessWindowHint ); + setWindowFlags( Qt::Popup ); + + setAutoFillBackground( false ); + setAttribute( Qt::WA_TranslucentBackground, true ); + + setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + m_label = new QLabel( this ); + m_buttons = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this ); + m_buttons->button( QDialogButtonBox::Ok )->setIcon( QIcon() ); + m_buttons->button( QDialogButtonBox::Cancel )->setIcon( QIcon() ); + + connect( m_buttons, SIGNAL( accepted() ), this, SLOT( onAccepted() ) ); + connect( m_buttons, SIGNAL( rejected() ), this, SLOT( onRejected() ) ); + + m_layout = new QVBoxLayout; + setLayout( m_layout ); + + layout()->addWidget( m_label ); + layout()->addWidget( m_buttons ); + setContentsMargins( contentsMargins().left() + 2, contentsMargins().top(), contentsMargins().right(), contentsMargins().bottom() ); + +/* + m_buttons->button( QDialogButtonBox::Ok )->setStyleSheet( + "QPushButton { \ + background-color: #F15C5E; \ + border-style: solid; \ + border-width: 1px; \ + border-radius: 10px; \ + border-color: #B64547; \ + padding: 2px; \ + } \ + QPushButton:pressed { \ + border-style: solid; \ + border-width: 1px; \ + border-radius: 10px; \ + border-color: #B64547; \ + background-color: #D35052; \ + border-style: flat; \ + }" );*/ +} + + +void +SourceTreePopupDialog::setMainText( const QString& text ) +{ + m_label->setText( text ); +} + + +void +SourceTreePopupDialog::setOkButtonText( const QString& text ) +{ + if ( m_buttons && m_buttons->button( QDialogButtonBox::Ok ) ) + m_buttons->button( QDialogButtonBox::Ok )->setText( text ); +} + + +void +SourceTreePopupDialog::setExtraQuestions( const Tomahawk::PlaylistDeleteQuestions& questions ) +{ + m_questions = questions; + + int idx = m_layout->indexOf( m_label ) + 1; + foreach ( const Tomahawk::PlaylistDeleteQuestion& question, m_questions ) + { + QCheckBox* cb = new QCheckBox( question.first, this ); + cb->setLayoutDirection( Qt::RightToLeft ); + cb->setProperty( "data", question.second ); + + QHBoxLayout* h = new QHBoxLayout; + h->addStretch( 1 ); + h->addWidget( cb ); +// m_layout->insertLayout( h, cb, 0 ); + m_layout->insertLayout( idx, h, 0 ); + + m_questionCheckboxes << cb; + idx++; + } +} + + +void +SourceTreePopupDialog::paintEvent( QPaintEvent* event ) +{ + // Constants for painting + const int leftTriangleWidth = 20; + const int cornerRounding = 8; + const int leftEdgeOffset = offset() - 6; + const QRect brect = rect().adjusted( 2, 3, -2, -3 ); + + QPainterPath outline; + // Left triangle top branch + outline.moveTo( brect.left(), brect.top() + brect.height() / 2 ); + outline.lineTo( leftEdgeOffset, brect.top() + brect.height() / 2 - leftTriangleWidth / 2 ); + + // main outline + outline.lineTo( leftEdgeOffset, cornerRounding ); + outline.quadTo( QPoint( leftEdgeOffset, brect.top() ), QPoint( leftEdgeOffset + cornerRounding, brect.top() ) ); + outline.lineTo( brect.width() - cornerRounding, brect.top() ); + outline.quadTo( QPoint( brect.width(), brect.top() ), QPoint( brect.width(), cornerRounding ) ); + outline.lineTo( brect.width(), brect.height() - cornerRounding ); + outline.quadTo( brect.bottomRight(), QPoint( brect.right() - cornerRounding, brect.height() ) ); + outline.lineTo( leftEdgeOffset + cornerRounding, brect.height() ); + outline.quadTo( QPoint( leftEdgeOffset, brect.height() ), QPoint( leftEdgeOffset, brect.height() - cornerRounding ) ); + + // Left triangle bottom branch + outline.lineTo( leftEdgeOffset, brect.top() + brect.height() / 2 + leftTriangleWidth / 2 ); + outline.lineTo( brect.left(), brect.top() + brect.height() / 2 ); + + QPainter p( this ); + + p.setRenderHint( QPainter::Antialiasing ); + + QPen pen( QColor( "#3F4247" ) ); + pen.setWidth( 2 ); + p.setPen( pen ); + p.drawPath( outline ); + + p.setOpacity( 0.93 ); + p.fillPath( outline, QColor( "#D6E3F1" ) ); + +#ifdef QT_MAC_USE_COCOA + // Work around bug in Qt/Mac Cocoa where opening subsequent popups + // would incorrectly calculate the background due to it not being + // invalidated. + SourceTreePopupHelper::clearBackground( this ); +#endif +} + + +void +SourceTreePopupDialog::focusOutEvent( QFocusEvent* ) +{ + hide(); +} + + +void +SourceTreePopupDialog::showEvent( QShowEvent* ) +{ + m_result = false; +} + + +void +SourceTreePopupDialog::onAccepted() +{ + hide(); + m_result = true; + calculateResults(); + emit result( m_result ); +} + + +void +SourceTreePopupDialog::onRejected() +{ + hide(); + m_result = false; + calculateResults(); + emit result( m_result ); +} + + +void +SourceTreePopupDialog::calculateResults() +{ + foreach ( const QCheckBox* b, m_questionCheckboxes ) + { + if ( b->property( "data" ).toInt() != 0 ) + { + m_questionResults[ b->property( "data" ).toInt() ] = ( b->checkState() == Qt::Checked ); + } + } +} diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog.h b/src/libtomahawk/widgets/SourceTreePopupDialog.h new file mode 100644 index 000000000..a7d3e3e9b --- /dev/null +++ b/src/libtomahawk/widgets/SourceTreePopupDialog.h @@ -0,0 +1,85 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef SOURCETREE_POPUP_DIALOG +#define SOURCETREE_POPUP_DIALOG + +#include "DllMacro.h" +#include "Typedefs.h" + +#include +#include + +class QVBoxLayout; +class QShowEvent; +class QLabel; +class QDialogButtonBox; +class QPushButton; +class QFocusEvent; +class QCheckBox; + +/** + * Place me at offset() to the left of the right edge of the sourcetree. + */ +class DLLEXPORT SourceTreePopupDialog : public QWidget +{ + Q_OBJECT +public: + explicit SourceTreePopupDialog(); + + int offset() const { return 16; } + + void setMainText( const QString& text ); + void setOkButtonText( const QString& text ); + void setExtraQuestions( const Tomahawk::PlaylistDeleteQuestions& questions ); + + bool resultValue() const { return m_result; } + QMap< int, bool > questionResults() const { return m_questionResults; } + +signals: + void result( bool accepted ); + +protected: + virtual void paintEvent( QPaintEvent* ); + virtual void focusOutEvent( QFocusEvent* ); + virtual void showEvent( QShowEvent* ); + +private slots: + void onAccepted(); + void onRejected(); + +private: + void calculateResults(); + + QVBoxLayout* m_layout; + QList< QCheckBox* > m_questionCheckboxes; + + QString m_text; + bool m_result; + Tomahawk::PlaylistDeleteQuestions m_questions; + QMap< int, bool > m_questionResults; + + QLabel* m_label; + QDialogButtonBox* m_buttons; +}; + + +Q_DECLARE_METATYPE( SourceTreePopupDialog* ) +#endif + +class QCheckBox; diff --git a/src/libtomahawk/widgets/SourceTreePopupDialog_mac.h b/src/libtomahawk/widgets/SourceTreePopupDialog_mac.h new file mode 100644 index 000000000..86649cbb5 --- /dev/null +++ b/src/libtomahawk/widgets/SourceTreePopupDialog_mac.h @@ -0,0 +1,29 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012 Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef SOURCETREE_POPUP_DIALOG_MAC_H +#define SOURCETREE_POPUP_DIALOG_MAC_H + +class QWidget; + +namespace SourceTreePopupHelper { + +void clearBackground( QWidget* widget ); + +} +#endif diff --git a/src/SettingsListDelegate.h b/src/libtomahawk/widgets/SourceTreePopupDialog_mac.mm similarity index 59% rename from src/SettingsListDelegate.h rename to src/libtomahawk/widgets/SourceTreePopupDialog_mac.mm index 730de7858..8ae495eaf 100644 --- a/src/SettingsListDelegate.h +++ b/src/libtomahawk/widgets/SourceTreePopupDialog_mac.mm @@ -1,7 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2011, Michael Zanetti - * Copyright 2011, Leo Franchi + * Copyright 2012 Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,23 +16,20 @@ * along with Tomahawk. If not, see . */ -#ifndef SETTINGSLISTDELEGATE_H -#define SETTINGSLISTDELEGATE_H +#include "SourceTreePopupDialog_mac.h" -#include +#include -class SettingsListDelegate : public QStyledItemDelegate +#import +#import +#import + +void +SourceTreePopupHelper::clearBackground( QWidget* widget ) { - Q_OBJECT -public: - explicit SettingsListDelegate(QObject *parent = 0); - - virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - -signals: - -public slots: - -}; - -#endif // SETTINGSLISTDELEGATE_H + Q_ASSERT( widget ); + // Workaround from QTBUG-15368 + NSView* view = reinterpret_cast< NSView* >( widget->winId() ); + NSWindow* cocoaWindow = [view window]; + [cocoaWindow invalidateShadow]; +} diff --git a/src/libtomahawk/widgets/WelcomeWidget.cpp b/src/libtomahawk/widgets/WelcomeWidget.cpp index 7456233d2..37f80611e 100644 --- a/src/libtomahawk/widgets/WelcomeWidget.cpp +++ b/src/libtomahawk/widgets/WelcomeWidget.cpp @@ -43,6 +43,54 @@ using namespace Tomahawk; +class WelcomeWidgetInterface : public Tomahawk::PlaylistInterface +{ + Q_OBJECT +public: + explicit WelcomeWidgetInterface( WelcomeWidget* w ) + : PlaylistInterface() + , m_w( w ) + { + connect( m_w->ui->tracksView->proxyModel()->playlistInterface().data(), SIGNAL( repeatModeChanged( Tomahawk::PlaylistModes::RepeatMode ) ), + SIGNAL( repeatModeChanged( Tomahawk::PlaylistModes::RepeatMode ) ) ); + + connect( m_w->ui->tracksView->proxyModel()->playlistInterface().data(), SIGNAL( shuffleModeChanged( bool ) ), + SIGNAL( shuffleModeChanged( bool ) ) ); + } + virtual ~WelcomeWidgetInterface() {} + + + virtual Tomahawk::PlaylistModes::RepeatMode repeatMode() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->repeatMode(); } + virtual bool shuffled() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->shuffled(); } + + virtual Tomahawk::result_ptr currentItem() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->currentItem(); } + virtual Tomahawk::result_ptr siblingItem( int itemsAway ) { return m_w->ui->tracksView->proxyModel()->playlistInterface()->siblingItem( itemsAway ); } + virtual int trackCount() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->trackCount(); } + virtual QList< Tomahawk::query_ptr > tracks() { return m_w->ui->tracksView->proxyModel()->playlistInterface()->tracks(); } + + virtual bool hasChildInterface( Tomahawk::playlistinterface_ptr other ) + { + return m_w->ui->tracksView->proxyModel()->playlistInterface() == other || + m_w->ui->tracksView->proxyModel()->playlistInterface()->hasChildInterface( other ) || + m_w->ui->additionsView->playlistInterface()->hasChildInterface( other ); + } + + virtual void setRepeatMode( Tomahawk::PlaylistModes::RepeatMode mode ) + { + m_w->ui->tracksView->proxyModel()->playlistInterface()->setRepeatMode( mode ); + } + + virtual void setShuffled( bool enabled ) + { + m_w->ui->tracksView->proxyModel()->playlistInterface()->setShuffled( enabled ); + } + +private: + WelcomeWidget* m_w; + +}; + + WelcomeWidget::WelcomeWidget( QWidget* parent ) : QWidget( parent ) , ui( new Ui::WelcomeWidget ) @@ -78,6 +126,8 @@ WelcomeWidget::WelcomeWidget( QWidget* parent ) ui->additionsView->setPlayableModel( m_recentAlbumsModel ); ui->additionsView->proxyModel()->sort( -1 ); + m_playlistInterface = playlistinterface_ptr( new WelcomeWidgetInterface( this ) ); + connect( SourceList::instance(), SIGNAL( ready() ), SLOT( onSourcesReady() ) ); connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) ); connect( ui->playlistWidget, SIGNAL( activated( QModelIndex ) ), SLOT( onPlaylistActivated( QModelIndex ) ) ); @@ -101,20 +151,29 @@ WelcomeWidget::loadData() Tomahawk::playlistinterface_ptr WelcomeWidget::playlistInterface() const { - return ui->tracksView->playlistInterface(); + return m_playlistInterface; } bool WelcomeWidget::jumpToCurrentTrack() { - return ui->tracksView->jumpToCurrentTrack(); + if ( ui->tracksView->jumpToCurrentTrack() ) + return true; + + if ( ui->additionsView->jumpToCurrentTrack() ) + return true; + + return false; } bool WelcomeWidget::isBeingPlayed() const { + if ( ui->additionsView->isBeingPlayed() ) + return true; + return AudioEngine::instance()->currentTrackPlaylist() == ui->tracksView->playlistInterface(); } @@ -320,3 +379,4 @@ PlaylistWidget::setModel( QAbstractItemModel* model ) emit modelChanged(); } +#include "WelcomeWidget.moc" diff --git a/src/libtomahawk/widgets/WelcomeWidget.h b/src/libtomahawk/widgets/WelcomeWidget.h index 5233f1594..e941f055f 100644 --- a/src/libtomahawk/widgets/WelcomeWidget.h +++ b/src/libtomahawk/widgets/WelcomeWidget.h @@ -37,6 +37,7 @@ class AlbumModel; class RecentlyPlayedModel; class OverlayWidget; +class WelcomeWidgetInterface; namespace Ui { @@ -125,6 +126,9 @@ private: RecentlyPlayedModel* m_tracksModel; AlbumModel* m_recentAlbumsModel; + Tomahawk::playlistinterface_ptr m_playlistInterface; + + friend class ::WelcomeWidgetInterface; }; #endif // WELCOMEWIDGET_H diff --git a/src/libtomahawk/widgets/WhatsHotWidget.cpp b/src/libtomahawk/widgets/WhatsHotWidget.cpp index 8dba1e009..b064c46f1 100644 --- a/src/libtomahawk/widgets/WhatsHotWidget.cpp +++ b/src/libtomahawk/widgets/WhatsHotWidget.cpp @@ -130,6 +130,9 @@ WhatsHotWidget::isBeingPlayed() const if ( AudioEngine::instance()->currentTrackPlaylist() == ui->tracksViewLeft->playlistInterface() ) return true; + if ( ui->albumsView->isBeingPlayed() ) + return true; + return false; } @@ -137,10 +140,13 @@ WhatsHotWidget::isBeingPlayed() const bool WhatsHotWidget::jumpToCurrentTrack() { - if ( ui->artistsViewLeft->jumpToCurrentTrack() ) + if ( ui->artistsViewLeft->model() && ui->artistsViewLeft->jumpToCurrentTrack() ) return true; - if ( ui->tracksViewLeft->jumpToCurrentTrack() ) + if ( ui->tracksViewLeft->model() && ui->tracksViewLeft->jumpToCurrentTrack() ) + return true; + + if ( ui->albumsView->model() && ui->albumsView->jumpToCurrentTrack() ) return true; return false; diff --git a/src/libtomahawk/widgets/WhatsHotWidget_p.h b/src/libtomahawk/widgets/WhatsHotWidget_p.h index e75d4aa62..8be446db3 100644 --- a/src/libtomahawk/widgets/WhatsHotWidget_p.h +++ b/src/libtomahawk/widgets/WhatsHotWidget_p.h @@ -65,7 +65,8 @@ public: virtual bool hasChildInterface( Tomahawk::playlistinterface_ptr other ) { return m_w->ui->tracksViewLeft->playlistInterface() == other || - m_w->ui->artistsViewLeft->playlistInterface() == other; + m_w->ui->artistsViewLeft->playlistInterface() == other || + m_w->ui->albumsView->playlistInterface()->hasChildInterface( other ); } diff --git a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp index 442a25977..e5a61c1c8 100644 --- a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.cpp @@ -20,6 +20,7 @@ #include "AlbumInfoWidget.h" #include "ui_AlbumInfoWidget.h" +#include "AlbumInfoWidget_p.h" #include "audio/AudioEngine.h" #include "ViewManager.h" @@ -61,6 +62,7 @@ AlbumInfoWidget::AlbumInfoWidget( const Tomahawk::album_ptr& album, QWidget* par m_pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::ScaledCover, QSize( 48, 48 ) ); + m_playlistInterface = playlistinterface_ptr( new MetaAlbumInfoInterface( this ) ); load( album ); } @@ -74,7 +76,7 @@ AlbumInfoWidget::~AlbumInfoWidget() Tomahawk::playlistinterface_ptr AlbumInfoWidget::playlistInterface() const { - return ui->tracksView->playlistInterface(); + return m_playlistInterface; } @@ -84,16 +86,27 @@ AlbumInfoWidget::isBeingPlayed() const //tDebug() << Q_FUNC_INFO << "audioengine playlistInterface = " << AudioEngine::instance()->currentTrackPlaylist()->id(); //tDebug() << Q_FUNC_INFO << "albumsView playlistInterface = " << ui->albumsView->playlistInterface()->id(); //tDebug() << Q_FUNC_INFO << "tracksView playlistInterface = " << ui->tracksView->playlistInterface()->id(); - if ( ui->albumsView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + + if ( ui->albumsView && ui->albumsView->isBeingPlayed() ) return true; - if ( ui->tracksView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + if ( ui->albumsView && ui->albumsView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + return true; + + if ( ui->tracksView && ui->tracksView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; return false; } +bool +AlbumInfoWidget::jumpToCurrentTrack() +{ + return ui->albumsView && ui->albumsView->jumpToCurrentTrack(); +} + + artist_ptr AlbumInfoWidget::descriptionArtist() const { if ( !m_album.isNull() && !m_album->artist().isNull() ) diff --git a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.h b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.h index 0c7c7248b..c4f756e51 100644 --- a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.h +++ b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget.h @@ -41,6 +41,7 @@ class PlayableModel; class TreeModel; +class MetaAlbumInfoInterface; namespace Ui { @@ -70,7 +71,7 @@ public: virtual bool isTemporaryPage() const { return true; } virtual bool isBeingPlayed() const; - virtual bool jumpToCurrentTrack() { return false; } + virtual bool jumpToCurrentTrack(); public slots: /** \brief Loads information for a given album. @@ -104,10 +105,14 @@ private: PlayableModel* m_albumsModel; TreeModel* m_tracksModel; + Tomahawk::playlistinterface_ptr m_playlistInterface; + QString m_title; QString m_description; QString m_longDescription; QPixmap m_pixmap; + + friend class MetaAlbumInfoInterface; }; #endif // ALBUMINFOWIDGET_H diff --git a/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget_p.h b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget_p.h new file mode 100644 index 000000000..b39fe65eb --- /dev/null +++ b/src/libtomahawk/widgets/infowidgets/AlbumInfoWidget_p.h @@ -0,0 +1,78 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef ALBUMINFOWIDGET_P_H +#define ALBUMINFOWIDGET_P_H + +#include "AlbumInfoWidget.h" +#include "ui_AlbumInfoWidget.h" +#include "PlaylistInterface.h" +#include "TreeProxyModel.h" +#include "Result.h" +#include "Typedefs.h" + +#include + +class MetaAlbumInfoInterface : public Tomahawk::PlaylistInterface +{ + Q_OBJECT +public: + explicit MetaAlbumInfoInterface( AlbumInfoWidget* w ) + : PlaylistInterface() + , m_w( w ) + { + connect( m_w->ui->tracksView->proxyModel()->playlistInterface().data(), SIGNAL( repeatModeChanged( Tomahawk::PlaylistModes::RepeatMode ) ), + SIGNAL( repeatModeChanged( Tomahawk::PlaylistModes::RepeatMode ) ) ); + + connect( m_w->ui->tracksView->proxyModel()->playlistInterface().data(), SIGNAL( shuffleModeChanged( bool ) ), + SIGNAL( shuffleModeChanged( bool ) ) ); + } + virtual ~MetaAlbumInfoInterface() {} + + + virtual Tomahawk::PlaylistModes::RepeatMode repeatMode() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->repeatMode(); } + virtual bool shuffled() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->shuffled(); } + + virtual Tomahawk::result_ptr currentItem() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->currentItem(); } + virtual Tomahawk::result_ptr siblingItem( int itemsAway ) { return m_w->ui->tracksView->proxyModel()->playlistInterface()->siblingItem( itemsAway ); } + virtual int trackCount() const { return m_w->ui->tracksView->proxyModel()->playlistInterface()->trackCount(); } + virtual QList< Tomahawk::query_ptr > tracks() { return m_w->ui->tracksView->proxyModel()->playlistInterface()->tracks(); } + + virtual bool hasChildInterface( Tomahawk::playlistinterface_ptr other ) + { + return m_w->ui->tracksView->proxyModel()->playlistInterface() == other || + m_w->ui->tracksView->proxyModel()->playlistInterface()->hasChildInterface( other ) || + m_w->ui->albumsView->playlistInterface()->hasChildInterface( other ); + } + + virtual void setRepeatMode( Tomahawk::PlaylistModes::RepeatMode mode ) + { + m_w->ui->tracksView->proxyModel()->playlistInterface()->setRepeatMode( mode ); + } + + virtual void setShuffled( bool enabled ) + { + m_w->ui->tracksView->proxyModel()->playlistInterface()->setShuffled( enabled ); + } + +private: + AlbumInfoWidget* m_w; + +}; + +#endif diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp index 766abbb53..8ae6b0661 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.cpp @@ -51,121 +51,110 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget* , ui( new Ui::ArtistInfoWidget ) , m_artist( artist ) { - qDebug() << "*********************************************************************"; + QWidget* widget = new QWidget; + ui->setupUi( widget ); - setResizeMode(QDeclarativeView::SizeRootObjectToView); + QPalette pal = palette(); + pal.setColor( QPalette::Window, QColor( "#454e59" ) ); + widget->setPalette( pal ); + widget->setAutoFillBackground( true ); - m_albumsModel = new PlayableModel( this ); - rootContext()->setContextProperty("albumsModel", m_albumsModel); - engine()->addImageProvider(QLatin1String("albums"), new AlbumArtImageProvider); + m_plInterface = Tomahawk::playlistinterface_ptr( new MetaArtistInfoInterface( this ) ); - setSource(QUrl("qrc" RESPATH "qml/ArtistInfoScene.qml")); +/* TomahawkUtils::unmarginLayout( ui->layoutWidget->layout() ); + TomahawkUtils::unmarginLayout( ui->layoutWidget1->layout() ); + TomahawkUtils::unmarginLayout( ui->layoutWidget2->layout() ); + TomahawkUtils::unmarginLayout( ui->albumHeader->layout() );*/ -// QWidget* widget = new QWidget; -// ui->setupUi( widget ); + m_albumsModel = new PlayableModel( ui->albums ); + ui->albums->setPlayableModel( m_albumsModel ); + ui->topHits->setEmptyTip( tr( "Sorry, we could not find any albums for this artist!" ) ); -// QPalette pal = palette(); -// pal.setColor( QPalette::Window, QColor( "#454e59" ) ); + m_relatedModel = new PlayableModel( ui->relatedArtists ); + ui->relatedArtists->setPlayableModel( m_relatedModel ); + ui->relatedArtists->proxyModel()->sort( -1 ); + ui->topHits->setEmptyTip( tr( "Sorry, we could not find any related artists!" ) ); -// widget->setPalette( pal ); -// widget->setAutoFillBackground( true ); + m_topHitsModel = new PlaylistModel( ui->topHits ); + ui->topHits->proxyModel()->setStyle( PlayableProxyModel::Short ); + ui->topHits->setPlayableModel( m_topHitsModel ); + ui->topHits->setSortingEnabled( false ); + ui->topHits->setEmptyTip( tr( "Sorry, we could not find any top hits for this artist!" ) ); -// m_plInterface = Tomahawk::playlistinterface_ptr( new MetaPlaylistInterface( this ) ); + ui->relatedArtists->setAutoFitItems( false ); + ui->relatedArtists->setWrapping( false ); + ui->relatedArtists->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); + ui->relatedArtists->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); + ui->relatedArtists->delegate()->setItemSize( QSize( 170, 170 ) ); -///* TomahawkUtils::unmarginLayout( ui->layoutWidget->layout() ); -// TomahawkUtils::unmarginLayout( ui->layoutWidget1->layout() ); -// TomahawkUtils::unmarginLayout( ui->layoutWidget2->layout() ); -// TomahawkUtils::unmarginLayout( ui->albumHeader->layout() );*/ + ui->albums->setAutoFitItems( false ); + ui->albums->setWrapping( false ); + ui->albums->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); + ui->albums->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); + ui->albums->delegate()->setItemSize( QSize( 170, 170 ) ); + ui->albums->proxyModel()->setHideDupeItems( true ); -// m_albumsModel = new PlayableModel( ui->albums ); -// ui->albums->setPlayableModel( m_albumsModel ); -// ui->topHits->setEmptyTip( tr( "Sorry, we could not find any albums for this artist!" ) ); + ui->topHits->setFrameShape( QFrame::StyledPanel ); + ui->topHits->setAttribute( Qt::WA_MacShowFocusRect, 0 ); -// m_relatedModel = new PlayableModel( ui->relatedArtists ); -// ui->relatedArtists->setPlayableModel( m_relatedModel ); -// ui->relatedArtists->proxyModel()->sort( -1 ); -// ui->topHits->setEmptyTip( tr( "Sorry, we could not find any related artists!" ) ); + m_pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultArtistImage, TomahawkUtils::ScaledCover, QSize( 48, 48 ) ); + ui->cover->setPixmap( TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultArtistImage, TomahawkUtils::ScaledCover, QSize( ui->cover->sizeHint() ) ) ); -// m_topHitsModel = new PlaylistModel( ui->topHits ); -// m_topHitsModel->setStyle( PlayableModel::Short ); -// ui->topHits->setPlayableModel( m_topHitsModel ); -// ui->topHits->setSortingEnabled( false ); -// ui->topHits->setEmptyTip( tr( "Sorry, we could not find any top hits for this artist!" ) ); + ui->biography->setFrameShape( QFrame::NoFrame ); + ui->biography->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + TomahawkUtils::styleScrollBar( ui->biography->verticalScrollBar() ); -// ui->relatedArtists->setAutoFitItems( false ); -// ui->relatedArtists->setWrapping( false ); -// ui->relatedArtists->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); -// ui->relatedArtists->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); -// m_relatedModel->setItemSize( QSize( 170, 170 ) ); + QFont f = font(); + f.setBold( true ); + f.setPixelSize( 18 ); + ui->artistLabel->setFont( f ); -// ui->albums->setAutoFitItems( false ); -// ui->albums->setWrapping( false ); -// ui->albums->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); -// ui->albums->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); -// m_albumsModel->setItemSize( QSize( 170, 170 ) ); -// ui->albums->proxyModel()->setHideDupeItems( true ); + QPalette p = ui->biography->palette(); + p.setColor( QPalette::Foreground, Qt::white ); + p.setColor( QPalette::Text, Qt::white ); -// ui->topHits->setFrameShape( QFrame::StyledPanel ); -// ui->topHits->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + ui->artistLabel->setPalette( p ); + ui->biography->setPalette( p ); + ui->label->setPalette( p ); + ui->label_2->setPalette( p ); + ui->label_3->setPalette( p ); -// m_pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultArtistImage, TomahawkUtils::ScaledCover, QSize( 48, 48 ) ); -// ui->cover->setPixmap( TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultArtistImage, TomahawkUtils::ScaledCover, QSize( ui->cover->sizeHint() ) ) ); + QScrollArea* area = new QScrollArea(); + area->setWidgetResizable( true ); + area->setWidget( widget ); -// ui->biography->setFrameShape( QFrame::NoFrame ); -// ui->biography->setAttribute( Qt::WA_MacShowFocusRect, 0 ); -// TomahawkUtils::styleScrollBar( ui->biography->verticalScrollBar() ); + area->setStyleSheet( "QScrollArea { background-color: #454e59; }" ); + area->setFrameShape( QFrame::NoFrame ); + area->setAttribute( Qt::WA_MacShowFocusRect, 0 ); -// QFont f = font(); -// f.setBold( true ); -// f.setPixelSize( 18 ); -// ui->artistLabel->setFont( f ); + QVBoxLayout* layout = new QVBoxLayout(); + layout->addWidget( area ); + setLayout( layout ); + TomahawkUtils::unmarginLayout( layout ); -// QPalette p = ui->biography->palette(); -// p.setColor( QPalette::Foreground, Qt::white ); -// p.setColor( QPalette::Text, Qt::white ); + TomahawkUtils::styleScrollBar( ui->albums->horizontalScrollBar() ); + TomahawkUtils::styleScrollBar( ui->relatedArtists->horizontalScrollBar() ); -// ui->artistLabel->setPalette( p ); -// ui->biography->setPalette( p ); -// ui->label->setPalette( p ); -// ui->label_2->setPalette( p ); -// ui->label_3->setPalette( p ); + ui->biography->setStyleSheet( "QTextBrowser#biography { background-color: transparent; }" ); -// QScrollArea* area = new QScrollArea(); -// area->setWidgetResizable( true ); -// area->setWidget( widget ); + ui->albums->setStyleSheet( "QListView { background-color: transparent; }" ); + ui->albumFrame->setStyleSheet( "QFrame#albumFrame { background-color: transparent; }" + "QFrame#albumFrame { " + "border-image: url(" RESPATH "images/scrollbar-vertical-handle.png) 3 3 3 3 stretch stretch;" + "border-top: 3px transparent; border-bottom: 3px transparent; border-right: 3px transparent; border-left: 3px transparent; }" ); -// area->setStyleSheet( "QScrollArea { background-color: #454e59; }" ); -// area->setFrameShape( QFrame::NoFrame ); -// area->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + ui->relatedArtists->setStyleSheet( "QListView { background-color: transparent; }" ); + ui->artistFrame->setStyleSheet( "QFrame#artistFrame { background-color: transparent; }" + "QFrame#artistFrame { " + "border-image: url(" RESPATH "images/scrollbar-vertical-handle.png) 3 3 3 3 stretch stretch;" + "border-top: 3px transparent; border-bottom: 3px transparent; border-right: 3px transparent; border-left: 3px transparent; }" ); -// QVBoxLayout* layout = new QVBoxLayout(); -// layout->addWidget( area ); -// setLayout( layout ); -// TomahawkUtils::unmarginLayout( layout ); - -// TomahawkUtils::styleScrollBar( ui->albums->horizontalScrollBar() ); -// TomahawkUtils::styleScrollBar( ui->relatedArtists->horizontalScrollBar() ); - -// ui->biography->setStyleSheet( "QTextBrowser#biography { background-color: transparent; }" ); - -// ui->albums->setStyleSheet( "QListView { background-color: transparent; }" ); -// ui->albumFrame->setStyleSheet( "QFrame#albumFrame { background-color: transparent; }" -// "QFrame#albumFrame { " -// "border-image: url(" RESPATH "images/scrollbar-vertical-handle.png) 3 3 3 3 stretch stretch;" -// "border-top: 3px transparent; border-bottom: 3px transparent; border-right: 3px transparent; border-left: 3px transparent; }" ); - -// ui->relatedArtists->setStyleSheet( "QListView { background-color: transparent; }" ); -// ui->artistFrame->setStyleSheet( "QFrame#artistFrame { background-color: transparent; }" -// "QFrame#artistFrame { " -// "border-image: url(" RESPATH "images/scrollbar-vertical-handle.png) 3 3 3 3 stretch stretch;" -// "border-top: 3px transparent; border-bottom: 3px transparent; border-right: 3px transparent; border-left: 3px transparent; }" ); - -//// ui->topHits->setStyleSheet( "QTreeView#topHits { background-color: transparent; }" ); -// ui->trackFrame->setStyleSheet( "QFrame#trackFrame { background-color: transparent; }" -// "QFrame#trackFrame { " -// "border-image: url(" RESPATH "images/scrollbar-vertical-handle.png) 3 3 3 3 stretch stretch;" -// "border-top: 3px transparent; border-bottom: 3px transparent; border-right: 3px transparent; border-left: 3px transparent; }" ); +// ui->topHits->setStyleSheet( "QTreeView#topHits { background-color: transparent; }" ); + ui->trackFrame->setStyleSheet( "QFrame#trackFrame { background-color: transparent; }" + "QFrame#trackFrame { " + "border-image: url(" RESPATH "images/scrollbar-vertical-handle.png) 3 3 3 3 stretch stretch;" + "border-top: 3px transparent; border-bottom: 3px transparent; border-right: 3px transparent; border-left: 3px transparent; }" ); load( artist ); } @@ -187,13 +176,19 @@ ArtistInfoWidget::playlistInterface() const bool ArtistInfoWidget::isBeingPlayed() const { - if ( ui->albums->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + if ( ui->albums && ui->albums->isBeingPlayed() ) return true; - if ( ui->relatedArtists->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + if ( ui->relatedArtists && ui->relatedArtists->isBeingPlayed() ) return true; - if ( ui->topHits->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + if ( ui->albums && ui->albums->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + return true; + + if ( ui->relatedArtists && ui->relatedArtists->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + return true; + + if ( ui->topHits && ui->topHits->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; return false; @@ -203,13 +198,19 @@ ArtistInfoWidget::isBeingPlayed() const bool ArtistInfoWidget::jumpToCurrentTrack() { - if ( ui->albums->jumpToCurrentTrack() ) + if ( ui->albums && ui->albums->jumpToCurrentTrack() ) return true; - if ( ui->relatedArtists->jumpToCurrentTrack() ) + if ( ui->relatedArtists && ui->relatedArtists->jumpToCurrentTrack() ) return true; - if ( ui->topHits->jumpToCurrentTrack() ) + if ( ui->topHits && ui->topHits->jumpToCurrentTrack() ) + return true; + + if ( ui->albums && ui->albums->jumpToCurrentTrack() ) + return true; + + if ( ui->relatedArtists && ui->relatedArtists->jumpToCurrentTrack() ) return true; return false; diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h index e80f36968..24d1473a8 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget.h @@ -48,7 +48,7 @@ namespace Ui class ArtistInfoWidget; } -class MetaPlaylistInterface; +class MetaArtistInfoInterface; class DLLEXPORT ArtistInfoWidget : public QDeclarativeView, public Tomahawk::ViewPage { @@ -115,7 +115,7 @@ private: QString m_longDescription; QPixmap m_pixmap; - friend class MetaPlaylistInterface; + friend class ::MetaArtistInfoInterface; }; #endif // ARTISTINFOWIDGET_H diff --git a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h index 10f6776b4..f923a5374 100644 --- a/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h +++ b/src/libtomahawk/widgets/infowidgets/ArtistInfoWidget_p.h @@ -29,11 +29,11 @@ #include -class MetaPlaylistInterface : public Tomahawk::PlaylistInterface +class MetaArtistInfoInterface : public Tomahawk::PlaylistInterface { Q_OBJECT public: - explicit MetaPlaylistInterface( ArtistInfoWidget* w ) + explicit MetaArtistInfoInterface( ArtistInfoWidget* w ) : PlaylistInterface() , m_w( w ) { @@ -51,7 +51,7 @@ public: connect( m_w->ui->topHits->proxyModel()->playlistInterface().data(), SIGNAL( shuffleModeChanged( bool ) ), SLOT( anyShuffleChanged( bool ) ) ); } - virtual ~MetaPlaylistInterface() {} + virtual ~MetaArtistInfoInterface() {} // Any one is fine, we keep them all synched @@ -70,7 +70,9 @@ public: { return ( m_w->ui->albums->playlistInterface() == other ) || ( m_w->ui->relatedArtists->playlistInterface() == other ) || - ( m_w->ui->topHits->playlistInterface() == other ); + ( m_w->ui->topHits->playlistInterface() == other ) || + ( m_w->ui->albums->playlistInterface()->hasChildInterface( other ) ) || + ( m_w->ui->relatedArtists->playlistInterface()->hasChildInterface( other ) ); } public slots: diff --git a/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.cpp b/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.cpp index 98d20957f..c8c4f4a45 100644 --- a/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.cpp @@ -38,6 +38,7 @@ using namespace Tomahawk; TrackInfoWidget::TrackInfoWidget( const Tomahawk::query_ptr& query, QWidget* parent ) : QWidget( parent ) , ui( new Ui::TrackInfoWidget ) + , m_scrollArea( 0 ) { QWidget* widget = new QWidget; ui->setupUi( widget ); @@ -98,17 +99,17 @@ TrackInfoWidget::TrackInfoWidget( const Tomahawk::query_ptr& query, QWidget* par m_pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::ScaledCover, QSize( 48, 48 ) ); ui->cover->setPixmap( TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::ScaledCover, QSize( ui->cover->sizeHint() ) ) ); - QScrollArea* area = new QScrollArea(); - area->setWidgetResizable( true ); - area->setWidget( widget ); - area->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); + m_scrollArea = new QScrollArea(); + m_scrollArea->setWidgetResizable( true ); + m_scrollArea->setWidget( widget ); + m_scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); - area->setStyleSheet( "QScrollArea { background-color: #454e59 }" ); - area->setFrameShape( QFrame::NoFrame ); - area->setAttribute( Qt::WA_MacShowFocusRect, 0 ); + m_scrollArea->setStyleSheet( "QScrollArea { background-color: #454e59 }" ); + m_scrollArea->setFrameShape( QFrame::NoFrame ); + m_scrollArea->setAttribute( Qt::WA_MacShowFocusRect, 0 ); QVBoxLayout* layout = new QVBoxLayout(); - layout->addWidget( area ); + layout->addWidget( m_scrollArea ); setLayout( layout ); TomahawkUtils::unmarginLayout( layout ); @@ -141,12 +142,28 @@ TrackInfoWidget::playlistInterface() const bool TrackInfoWidget::isBeingPlayed() const { - //tDebug() << Q_FUNC_INFO << "audioengine playlistInterface = " << AudioEngine::instance()->currentTrackPlaylist()->id(); - //tDebug() << Q_FUNC_INFO << "albumsView playlistInterface = " << ui->albumsView->playlistInterface()->id(); - //tDebug() << Q_FUNC_INFO << "tracksView playlistInterface = " << ui->tracksView->playlistInterface()->id(); if ( ui->similarTracksView->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) return true; + if ( ui->similarTracksView->playlistInterface()->hasChildInterface( AudioEngine::instance()->currentTrackPlaylist() ) ) + return true; + + return false; +} + + +bool +TrackInfoWidget::jumpToCurrentTrack() +{ + if ( ui->similarTracksView->jumpToCurrentTrack() && !ui->similarTracksView->currentTrackRect().isEmpty() ) + { + // We embed the view in a scrollarea, so we have to manually ensure we make it visible + const QRect itemRect = ui->similarTracksView->currentTrackRect(); + m_scrollArea->ensureVisible( itemRect.right(), itemRect.bottom(), 50, 50 ); + + return true; + } + return false; } diff --git a/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.h b/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.h index 48766be37..1e26ebfae 100644 --- a/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.h +++ b/src/libtomahawk/widgets/infowidgets/TrackInfoWidget.h @@ -40,6 +40,7 @@ #include "Typedefs.h" class PlayableModel; +class QScrollArea; namespace Ui { @@ -68,7 +69,7 @@ public: virtual bool isTemporaryPage() const { return true; } virtual bool showInfoBar() const { return false; } - virtual bool jumpToCurrentTrack() { return false; } + virtual bool jumpToCurrentTrack(); public slots: void load( const Tomahawk::query_ptr& query ); @@ -88,6 +89,7 @@ private slots: private: Ui::TrackInfoWidget *ui; + QScrollArea* m_scrollArea; Tomahawk::query_ptr m_query; Tomahawk::artist_ptr m_artist; diff --git a/src/sourcetree/SourceDelegate.cpp b/src/sourcetree/SourceDelegate.cpp index 5a0571a0b..233fb15c2 100644 --- a/src/sourcetree/SourceDelegate.cpp +++ b/src/sourcetree/SourceDelegate.cpp @@ -1,7 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser - * Copyright 2011, Leo Franchi + * Copyright 2011-2012, Leo Franchi * Copyright 2011, Michael Zanetti * Copyright 2010-2012, Jeff Mitchell * @@ -143,7 +143,7 @@ SourceDelegate::paintDecorations( QPainter* painter, const QStyleOptionViewItem& iconW = ah->originalSize().height() - 4; } } - + QRect iconRect = QRect( 4, option.rect.y() + 2, iconW, iconW ); QPixmap speaker = option.state & QStyle::State_Selected ? m_nowPlayingSpeaker : m_nowPlayingSpeakerDark; speaker = speaker.scaledToHeight( iconW, Qt::SmoothTransformation ); @@ -549,6 +549,22 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co else QStyledItemDelegate::paint( painter, o, index ); } + else if ( type == SourcesModel::StaticPlaylist ) + { + QStyledItemDelegate::paint( painter, o, index ); + + PlaylistItem* plItem = qobject_cast< PlaylistItem* >( item ); + if ( plItem->canSubscribe() && !plItem->subscribedIcon().isNull() ) + { + const int padding = 2; + const int imgWidth = o.rect.height() - 2*padding; + + const QPixmap icon = plItem->subscribedIcon().scaled( imgWidth, imgWidth, Qt::KeepAspectRatio, Qt::SmoothTransformation ); + + const QRect subRect( o.rect.right() - padding - imgWidth, o.rect.top() + padding, imgWidth, imgWidth ); + painter->drawPixmap( subRect, icon ); + } + } else QStyledItemDelegate::paint( painter, o, index ); } @@ -639,10 +655,29 @@ SourceDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const QSt } } } + else if ( event->type() == QEvent::MouseButtonRelease && type == SourcesModel::StaticPlaylist ) + { + PlaylistItem* plItem = qobject_cast< PlaylistItem* >( index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >() ); + Q_ASSERT( plItem ); + + QMouseEvent* mev = static_cast< QMouseEvent* >( event ); + if ( plItem->canSubscribe() && !plItem->subscribedIcon().isNull() ) + { + const int padding = 2; + const int imgWidth = option.rect.height() - 2*padding; + const QRect subRect( option.rect.right() - padding - imgWidth, option.rect.top() + padding, imgWidth, imgWidth ); + + if ( subRect.contains( mev->pos() ) ) + { + // Toggle playlist subscription + plItem->setSubscribed( !plItem->subscribed() ); + } + } + } } // We emit our own clicked() signal instead of relying on QTreeView's, because that is fired whether or not a delegate accepts - // a mouse press event. Since we want to swallow click events when they are on headphones other action items, here wemake sure we only + // a mouse press event. Since we want to swallow click events when they are on headphones other action items, here we make sure we only // emit if we really want to if ( event->type() == QEvent::MouseButtonRelease ) { diff --git a/src/sourcetree/SourceTreeView.cpp b/src/sourcetree/SourceTreeView.cpp index 55a97a338..c439b6316 100644 --- a/src/sourcetree/SourceTreeView.cpp +++ b/src/sourcetree/SourceTreeView.cpp @@ -51,6 +51,8 @@ #include "LatchManager.h" #include "utils/TomahawkUtilsGui.h" #include "utils/Logger.h" +#include "utils/Closure.h" +#include "widgets/SourceTreePopupDialog.h" using namespace Tomahawk; @@ -362,29 +364,59 @@ SourceTreeView::deletePlaylist( const QModelIndex& idxIn ) Q_ASSERT( false ); } - QMessageBox askDelete( QMessageBox::Question, tr( "Delete %1?", "playlist/station/..." ).arg( typeDesc ), - tr( "Would you like to delete the %1 \"%2\"?", "e.g. Would you like to delete the playlist named Foobar?" ) - .arg( typeDesc ).arg( idx.data().toString() ), - QMessageBox::Yes | QMessageBox::No, this ); + PlaylistItem* item = itemFromIndex< PlaylistItem >( idx ); + playlist_ptr playlist = item->playlist(); -#ifdef Q_OS_MAC - askDelete.setWindowModality( Qt::WindowModal ); -#endif + const QPoint rightCenter = viewport()->mapToGlobal( visualRect( idx ).topRight() + QPoint( 0, visualRect( idx ).height() / 2 ) ); + if ( playlist->hasCustomDeleter() ) + { + playlist->customDelete( rightCenter ); + } + else + { + if ( m_popupDialog.isNull() ) + { + m_popupDialog = QWeakPointer< SourceTreePopupDialog >( new SourceTreePopupDialog() ); + connect( m_popupDialog.data(), SIGNAL( result( bool ) ), this, SLOT( onDeletePlaylistResult( bool ) ) ); + } - int r = askDelete.exec(); - if ( r != QMessageBox::Yes ) + m_popupDialog.data()->setMainText( tr( "Would you like to delete the %1 \"%2\"?", "e.g. Would you like to delete the playlist named Foobar?" ) + .arg( typeDesc ).arg( idx.data().toString() ) ); + m_popupDialog.data()->setOkButtonText( tr( "Delete" ) ); + m_popupDialog.data()->setProperty( "idx", QVariant::fromValue< QModelIndex >( idx ) ); + + m_popupDialog.data()->move( rightCenter.x() - m_popupDialog.data()->offset(), rightCenter.y() - m_popupDialog.data()->sizeHint().height() / 2. ); + m_popupDialog.data()->show(); + } + +} + + +void +SourceTreeView::onDeletePlaylistResult( bool result ) +{ + Q_ASSERT( !m_popupDialog.isNull() ); + + const QModelIndex idx = m_popupDialog.data()->property( "idx" ).value< QModelIndex >(); + Q_ASSERT( idx.isValid() ); + + if ( !result ) return; + SourcesModel::RowType type = ( SourcesModel::RowType )model()->data( idx, SourcesModel::SourceTreeItemTypeRole ).toInt(); + if ( type == SourcesModel::StaticPlaylist ) { PlaylistItem* item = itemFromIndex< PlaylistItem >( idx ); playlist_ptr playlist = item->playlist(); + qDebug() << "Doing delete of playlist:" << playlist->title(); Playlist::remove( playlist ); } else if ( type == SourcesModel::AutomaticPlaylist || type == SourcesModel::Station ) { DynamicPlaylistItem* item = itemFromIndex< DynamicPlaylistItem >( idx ); dynplaylist_ptr playlist = item->dynPlaylist(); + qDebug() << "Doing delete of playlist:" << playlist->title(); DynamicPlaylist::remove( playlist ); } } @@ -806,6 +838,13 @@ SourceTreeView::drawRow( QPainter* painter, const QStyleOptionViewItem& option, QTreeView::drawRow( painter, option, index ); } +void +SourceTreeView::drawBranches( QPainter *painter, const QRect &rect, const QModelIndex &index ) const +{ + if( !QString( qApp->style()->metaObject()->className() ).toLower().contains( "qtcurve" ) ) + QTreeView::drawBranches( painter, rect, index ); +} + template< typename T > T* SourceTreeView::itemFromIndex( const QModelIndex& index ) const diff --git a/src/sourcetree/SourceTreeView.h b/src/sourcetree/SourceTreeView.h index 775ecb62b..83d330ee9 100644 --- a/src/sourcetree/SourceTreeView.h +++ b/src/sourcetree/SourceTreeView.h @@ -26,6 +26,7 @@ #include #include +class SourceTreePopupDialog; class CollectionModel; class PlaylistModel; class SourcesModel; @@ -84,8 +85,11 @@ private slots: void onCustomContextMenu( const QPoint& pos ); void onSelectionChanged(); + void onDeletePlaylistResult( bool result ); + protected: void drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + void drawBranches( QPainter *painter, const QRect &rect, const QModelIndex &index ) const; virtual void paintEvent( QPaintEvent* event ); @@ -106,6 +110,7 @@ private: QModelIndex m_contextMenuIndex; SourceDelegate* m_delegate; Tomahawk::LatchManager* m_latchManager; + QWeakPointer m_popupDialog; QMenu m_playlistMenu; QMenu m_roPlaylistMenu; @@ -115,7 +120,7 @@ private: bool m_dragging; QRect m_dropRect; QPersistentModelIndex m_dropIndex; - + QPersistentModelIndex m_selectedIndex; }; diff --git a/src/sourcetree/items/GenericPageItems.cpp b/src/sourcetree/items/GenericPageItems.cpp index 3ce127d40..97a790ad3 100644 --- a/src/sourcetree/items/GenericPageItems.cpp +++ b/src/sourcetree/items/GenericPageItems.cpp @@ -86,7 +86,16 @@ bool GenericPageItem::isBeingPlayed() const { if ( m_get() ) - return m_get()->isBeingPlayed(); + { + if ( m_get()->isBeingPlayed() ) + return true; + + if ( !m_get()->playlistInterface().isNull() && m_get()->playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() ) + return true; + + if ( !m_get()->playlistInterface().isNull() && m_get()->playlistInterface()->hasChildInterface( AudioEngine::instance()->currentTrackPlaylist() ) ) + return true; + } return false; } diff --git a/src/sourcetree/items/PlaylistItems.cpp b/src/sourcetree/items/PlaylistItems.cpp index 8fb322915..3630b1f0d 100644 --- a/src/sourcetree/items/PlaylistItems.cpp +++ b/src/sourcetree/items/PlaylistItems.cpp @@ -1,6 +1,6 @@ /* * - * Copyright 2010-2011, Leo Franchi + * Copyright 2010-2012, Leo Franchi * * 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 @@ -40,6 +40,8 @@ using namespace Tomahawk; PlaylistItem::PlaylistItem( SourcesModel* mdl, SourceTreeItem* parent, const playlist_ptr& pl, int index ) : SourceTreeItem( mdl, parent, SourcesModel::StaticPlaylist, index ) , m_loaded( false ) + , m_canSubscribe( false ) + , m_showSubscribed( false ) , m_playlist( pl ) { connect( pl.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), @@ -106,8 +108,13 @@ PlaylistItem::IDValue() const bool PlaylistItem::isBeingPlayed() const { - if ( ViewManager::instance()->pageForPlaylist( m_playlist ) ) - return AudioEngine::instance()->currentTrackPlaylist() == ViewManager::instance()->pageForPlaylist( m_playlist )->playlistInterface(); + if ( ViewPage* page = ViewManager::instance()->pageForPlaylist( m_playlist ) ) + { + if ( AudioEngine::instance()->currentTrackPlaylist() == page->playlistInterface() ) + return true; + if ( page->playlistInterface()->hasChildInterface( AudioEngine::instance()->currentTrackPlaylist() ) ) + return true; + } return false; } @@ -280,6 +287,7 @@ PlaylistItem::onUpdated() if ( !newOverlay && !m_overlaidIcon.isNull() ) m_overlaidIcon = QIcon(); + emit updated(); } @@ -292,6 +300,23 @@ PlaylistItem::createOverlay() if ( m_playlist->updaters().isEmpty() ) return false; + m_showSubscribed = false; + m_canSubscribe = false; + foreach ( PlaylistUpdaterInterface* updater, m_playlist->updaters() ) + { + if ( updater->canSubscribe() ) + { + m_canSubscribe = true; + m_showSubscribed = updater->subscribed(); + break; + } + } + + if ( m_canSubscribe && m_showSubscribed && m_subscribedOnIcon.isNull() ) + m_subscribedOnIcon = QPixmap( RESPATH "images/subscribe-on.png" ); + else if ( m_canSubscribe && !m_showSubscribed && m_subscribedOffIcon.isNull() ) + m_subscribedOffIcon = QPixmap( RESPATH "images/subscribe-off.png" ); + QList< QPixmap > icons; foreach ( PlaylistUpdaterInterface* updater, m_playlist->updaters() ) { @@ -299,6 +324,9 @@ PlaylistItem::createOverlay() icons << updater->typeIcon(); } + m_overlaidIcon = QIcon(); + m_overlaidUpdaters = m_playlist->updaters(); + if ( icons.isEmpty() ) return false; @@ -307,8 +335,6 @@ PlaylistItem::createOverlay() if ( icons.size() > 2 ) icons = icons.mid( 0, 2 ); - m_overlaidIcon = QIcon(); - m_overlaidUpdaters = m_playlist->updaters(); QPixmap base = m_icon.pixmap( 48, 48 ); QPainter p( &base ); @@ -370,6 +396,27 @@ PlaylistItem::activateCurrent() } +void +PlaylistItem::setSubscribed( bool subscribed ) +{ + Q_ASSERT( !m_overlaidUpdaters.isEmpty() ); + if ( m_overlaidUpdaters.isEmpty() ) + { + qWarning() << "NO playlist updater but got a toggle subscribed action on the playlist item!?"; + return; + } + else if ( m_overlaidUpdaters.size() > 1 ) + { + qWarning() << "Got TWO subscribed updaters at the same time? Toggling both... wtf"; + } + + foreach( PlaylistUpdaterInterface* updater, m_overlaidUpdaters ) + { + updater->setSubscribed( subscribed ); + } +} + + DynamicPlaylistItem::DynamicPlaylistItem( SourcesModel* mdl, SourceTreeItem* parent, const dynplaylist_ptr& pl, int index ) : PlaylistItem( mdl, parent, pl.staticCast< Playlist >(), index ) , m_dynplaylist( pl ) diff --git a/src/sourcetree/items/PlaylistItems.h b/src/sourcetree/items/PlaylistItems.h index 31198e778..e1bc3ea6e 100644 --- a/src/sourcetree/items/PlaylistItems.h +++ b/src/sourcetree/items/PlaylistItems.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011, Leo Franchi + * Copyright 2010-2012, Leo Franchi * * 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 @@ -42,6 +42,12 @@ public: virtual SourceTreeItem* activateCurrent(); + // subscription management + bool canSubscribe() const { return m_canSubscribe; } + bool subscribed() const { return m_showSubscribed; } + QPixmap subscribedIcon() const { return m_showSubscribed ? m_subscribedOnIcon : m_subscribedOffIcon; } + void setSubscribed( bool subscribed ); + public slots: virtual void activate(); virtual void doubleClicked(); @@ -58,9 +64,10 @@ private slots: private: bool createOverlay(); - bool m_loaded; + bool m_loaded, m_canSubscribe, m_showSubscribed; Tomahawk::playlist_ptr m_playlist; QIcon m_icon, m_overlaidIcon; + QPixmap m_subscribedOnIcon, m_subscribedOffIcon; QList m_overlaidUpdaters; }; Q_DECLARE_OPERATORS_FOR_FLAGS(PlaylistItem::DropTypes)