diff --git a/admin/mac/build-release-osx.sh b/admin/mac/build-release-osx.sh
index 66cf4d648..5413399dc 100755
--- a/admin/mac/build-release-osx.sh
+++ b/admin/mac/build-release-osx.sh
@@ -45,6 +45,9 @@ VERSION=$1
header "Creating DMG"
cd ..
+ header "Signing bundle"
+ codesign -s "Developer ID Application: Leonardo Franchi" -f -v ./Tomahawk.app
+
$ROOT/../admin/mac/create-dmg.sh Tomahawk.app
mv Tomahawk.dmg Tomahawk-$VERSION.dmg
diff --git a/data/icons/tomahawk-icon-128x128-grayscale.png b/data/icons/tomahawk-icon-128x128-grayscale.png
index f9daadb33..b7368f2bc 100644
Binary files a/data/icons/tomahawk-icon-128x128-grayscale.png and b/data/icons/tomahawk-icon-128x128-grayscale.png differ
diff --git a/data/icons/tomahawk-icon-128x128.png b/data/icons/tomahawk-icon-128x128.png
index 4701db23a..5bbe89c0f 100644
Binary files a/data/icons/tomahawk-icon-128x128.png and b/data/icons/tomahawk-icon-128x128.png differ
diff --git a/data/icons/tomahawk-icon-16x16.png b/data/icons/tomahawk-icon-16x16.png
index 8d2cd8589..a08e02e80 100644
Binary files a/data/icons/tomahawk-icon-16x16.png and b/data/icons/tomahawk-icon-16x16.png differ
diff --git a/data/icons/tomahawk-icon-256x256.png b/data/icons/tomahawk-icon-256x256.png
index 559067acd..bdc9c0ef0 100644
Binary files a/data/icons/tomahawk-icon-256x256.png and b/data/icons/tomahawk-icon-256x256.png differ
diff --git a/data/icons/tomahawk-icon-32x32.png b/data/icons/tomahawk-icon-32x32.png
index 952151ba2..be06f5166 100644
Binary files a/data/icons/tomahawk-icon-32x32.png and b/data/icons/tomahawk-icon-32x32.png differ
diff --git a/data/icons/tomahawk-icon-512x512.png b/data/icons/tomahawk-icon-512x512.png
index 14db6cbc3..b7524186c 100644
Binary files a/data/icons/tomahawk-icon-512x512.png and b/data/icons/tomahawk-icon-512x512.png differ
diff --git a/data/icons/tomahawk-icon-64x64.png b/data/icons/tomahawk-icon-64x64.png
index e27712df7..b64010805 100644
Binary files a/data/icons/tomahawk-icon-64x64.png and b/data/icons/tomahawk-icon-64x64.png differ
diff --git a/data/icons/tomahawk-icon.svg b/data/icons/tomahawk-icon.svg
index 05b80614d..2570b4bef 100644
--- a/data/icons/tomahawk-icon.svg
+++ b/data/icons/tomahawk-icon.svg
@@ -1,80 +1,101 @@
-
-
-
-
\ No newline at end of file
+
+
+
+
diff --git a/data/images/view-toggle-icon-grid-active.png b/data/images/view-toggle-icon-grid-active.png
new file mode 100644
index 000000000..2c475716f
Binary files /dev/null and b/data/images/view-toggle-icon-grid-active.png differ
diff --git a/data/images/view-toggle-icon-grid-inactive.png b/data/images/view-toggle-icon-grid-inactive.png
new file mode 100644
index 000000000..0ceb65da5
Binary files /dev/null and b/data/images/view-toggle-icon-grid-inactive.png differ
diff --git a/data/stylesheets/topbar-radiobuttons.css b/data/stylesheets/topbar-radiobuttons.css
index 6ee4719d6..402d3c1cb 100644
--- a/data/stylesheets/topbar-radiobuttons.css
+++ b/data/stylesheets/topbar-radiobuttons.css
@@ -10,7 +10,7 @@ QRadioButton {
padding:0;
background-repeat: none;
/*width:0; height:0;*/
-}
+}
QRadioButton::indicator {
width: 29px;
@@ -18,15 +18,15 @@ QRadioButton::indicator {
}
QRadioButton::indicator::unchecked {
- background-image: url(:/data/images/view-toggle-inactive-right.png);
+ background-image: url(:/data/images/view-toggle-inactive-centre.png);
image: url(:/data/images/view-toggle-icon-list-inactive.png);
}
QRadioButton::indicator::checked {
- background-image: url(:/data/images/view-toggle-active-right.png);
+ background-image: url(:/data/images/view-toggle-active-centre.png);
image: url(:/data/images/view-toggle-icon-list-active.png);
}
QRadioButton::indicator::pressed {
- background-image: url(:/data/images/view-toggle-pressed-right.png);
+ background-image: url(:/data/images/view-toggle-pressed-centre.png);
image: url(:/data/images/view-toggle-icon-list-active.png);
}
QRadioButton#radioNormal::indicator::unchecked {
@@ -43,13 +43,13 @@ QRadioButton#radioNormal::indicator::pressed {
}
QRadioButton#radioCloud::indicator::unchecked {
background-image: url(:/data/images/view-toggle-inactive-right.png);
- image: url(:/data/images/view-toggle-icon-cloud-inactive.png);
+ image: url(:/data/images/view-toggle-icon-grid-inactive.png);
}
QRadioButton#radioCloud::indicator::checked {
background-image: url(:/data/images/view-toggle-active-right.png);
- image: url(:/data/images/view-toggle-icon-cloud-active.png);
+ image: url(:/data/images/view-toggle-icon-grid-active.png);
}
QRadioButton#radioCloud::indicator::pressed {
background-image: url(:/data/images/view-toggle-pressed-right.png);
- image: url(:/data/images/view-toggle-icon-cloud-active.png);
+ image: url(:/data/images/view-toggle-icon-grid-active.png);
}
diff --git a/lang/tomahawk_ar.ts b/lang/tomahawk_ar.ts
index 41f6e1ebd..548d1bd66 100644
--- a/lang/tomahawk_ar.ts
+++ b/lang/tomahawk_ar.ts
@@ -474,11 +474,19 @@ connect and stream from you?
&Copy to Clipboard
-
+ &نسخ إلى الحافظة
Open &Log-file
+ فتح &ملف السجل
+
+
+
+ FlexibleHeader
+
+
+ Filter...
@@ -557,7 +565,7 @@ connect and stream from you?
%1 is listening along with you!
-
+ %1 يستمع معك!
@@ -617,12 +625,32 @@ connect and stream from you?
LovedTracksItem
-
+
+ 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
+
+
+
+
Loved Tracks
الأغاني المحبوبة
@@ -735,7 +763,7 @@ connect and stream from you?
تقدم
-
+
- Properties
- خصائص
@@ -845,6 +873,31 @@ connect and stream from you?
إسم
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1369,7 +1422,7 @@ connect and stream from you?
-
+
Latest Additions
أحدث الإضافات
@@ -1384,37 +1437,37 @@ connect and stream from you?
سوبر كولكشن
-
+
Latest additions to your collection
آخر إضافات على مجموعتك
-
+
Latest additions to %1's collection
آخر إضافات على مجموعة %1
-
+
Sorry, we could not find any recent additions!
نعتذر، لم نستطيع إيجاد إضافة جديدة!
-
+
Recently Played Tracks
الأغاني التي إستمعت إليها مؤخرا
-
+
Your recently played tracks
الأغاني التي إستمعت إليها مؤخرا
-
+
%1's recently played tracks
الأغاني التي سمعها مؤخرا %1
-
+
Sorry, we could not find any recent plays!
نعتذر، لم نستطيع إيجاد أغاني مسموعة مؤخرا!
@@ -1492,77 +1545,72 @@ connect and stream from you?
SourcesModel
-
+
Group
فئة
-
+
Collection
مجموعة
-
+
Playlist
قائمة الأغاني
-
+
Automatic Playlist
قائمة أغاني أوتوماتيكية
-
+
Station
إذاعة
-
+
Browse
تصفح
-
+
Search History
تاريخ البحث
-
+
My Music
موسيقتي الخاصة
-
+
SuperCollection
سوبر كولكشن
-
- Top Loved Tracks
- الأغاني المحبوبة الأكثر شهرة
-
-
-
+
Dashboard
لوحة القيادة
-
+
Recently Played
تم الاستماع لها مؤخرا
-
+
Charts
الرسوم البيانية
-
+
New Releases
جديد الاصدارات
-
+
Friends
الأصدقاء
@@ -1623,12 +1671,12 @@ connect and stream from you?
SpotifyPlaylistUpdater
-
+
Delete in Spotify?
أحذف في سبوتيفي (Spotify)؟
-
+
Would you like to delete the corresponding Spotify playlist as well?
هل ترغب في حذف قائمة التشغيل المطابقة على سبوتيفي (Spotify)؟
@@ -1935,17 +1983,37 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccount
-
+
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)
@@ -1953,28 +2021,28 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
جاري تسجيل الدخول...
-
+
Failed: %1
فشل: %1
-
-
- Logged in as %1
-
-
- Log Out
-
+ Logged in as %1
+ مسجل تحت اسم %1
-
-
+
+ Log Out
+ تسجيل الخروج
+
+
+
+
Log In
تسجيل الدخول
@@ -1982,7 +2050,7 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
إسمع موسيقى و زامن قوائم تشغيلك مع سبوتيفي بريميوم (Spotify Premium)
@@ -2203,7 +2271,7 @@ You may wish to try re-authenticating.
Properties...
-
+ خصائص...
@@ -2221,39 +2289,6 @@ You may wish to try re-authenticating.
&أظهر صفحة الفنان
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- الأغاني المحبوبة الأكثر شهرة
-
-
-
- Your loved tracks
- الأغاني التي أحببتها
-
-
-
- %1's loved tracks
- الأغاني المحبوبة ل%1
-
-
-
- The most loved tracks from all your friends
- الأغاني المحبوبة كثيرا بين أصدقائك
-
-
-
- All of your loved tracks
- جميع الأغاني التي أحببتها
-
-
-
- All of %1's loved tracks
- جميع الأغاني المحبوبة ل%1
-
-
Tomahawk::DropJobNotifier
@@ -2995,7 +3030,7 @@ Try tweaking the filters for a new set of songs to play.
Tomahawk::SpotifyParser
-
+
Error fetching Spotify information from the network!
مشكلة في جلب معلومات "Spotify" من الشبكة!
@@ -3011,7 +3046,7 @@ Try tweaking the filters for a new set of songs to play.
TomahawkApp
-
+
My Collection
مجموعتي الخاصة
@@ -3623,35 +3658,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts
index 0ae5c430d..41646624d 100644
--- a/lang/tomahawk_bg.ts
+++ b/lang/tomahawk_bg.ts
@@ -484,6 +484,14 @@ Tomahaw създаде доклад относно това и изпращай
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -619,12 +627,32 @@ Tomahaw създаде доклад относно това и изпращай
LovedTracksItem
-
+
+ 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
+
+
+
+
Loved Tracks
@@ -737,7 +765,7 @@ Tomahaw създаде доклад относно това и изпращай
-
+
- Properties
@@ -847,6 +875,31 @@ Tomahaw създаде доклад относно това и изпращай
Име
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1369,7 +1422,7 @@ Tomahaw създаде доклад относно това и изпращай
-
+
Latest Additions
Последно добавени
@@ -1385,37 +1438,37 @@ Tomahaw създаде доклад относно това и изпращай
/Сборен излед от локалните и наличните в колекциите на приятелите ти/
-
+
Latest additions to your collection
Последно добавени към колекцията
-
+
Latest additions to %1's collection
Последно добавени в колекцията на %1
-
+
Sorry, we could not find any recent additions!
Съжалявам, но не откривам нито една ново-добавена позиция!
-
+
Recently Played Tracks
Наскоро изпълнени песни
-
+
Your recently played tracks
Наскоро изпълнени песни от теб
-
+
%1's recently played tracks
Наскоро изпълнените песни от %1
-
+
Sorry, we could not find any recent plays!
Съжалявам, но не откривам нито една наскоро изпълнена песен!
@@ -1493,78 +1546,73 @@ Tomahaw създаде доклад относно това и изпращай
SourcesModel
-
+
Group
Гпупирай
-
+
Collection
Колекция
-
+
Playlist
Списък за изпълнение
-
+
Automatic Playlist
Автоматичен списък
-
+
Station
Станция
-
+
Browse
Разгледай
-
+
Search History
Търси в историята
-
+
My Music
Моята музика
-
+
SuperCollection
Супер колекция
/Сборен излед от локалните и наличните в колекциите на приятелите ти/
-
- Top Loved Tracks
- Най-харесвани песни
-
-
-
+
Dashboard
Табло
-
+
Recently Played
Наскоро изпълнени песни
-
+
Charts
Класации
-
+
New Releases
Нови албуми
-
+
Friends
Приятели
@@ -1625,12 +1673,12 @@ Tomahaw създаде доклад относно това и изпращай
SpotifyPlaylistUpdater
-
+
Delete in Spotify?
Изтривам и в Spotify?
-
+
Would you like to delete the corresponding Spotify playlist as well?
Желаеш ли да изтриеш и съответните Spotify списъци?
@@ -1941,17 +1989,37 @@ Tomahaw създаде доклад относно това и изпращай
Tomahawk::Accounts::SpotifyAccount
-
+
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
@@ -1959,28 +2027,28 @@ Tomahaw създаде доклад относно това и изпращай
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
Влизам...
-
+
Failed: %1
Неуспех: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
Влез
@@ -1988,7 +2056,7 @@ Tomahaw създаде доклад относно това и изпращай
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
Слушай музика и синхронизирай твоите списъци със Spotify Premium
@@ -2229,39 +2297,6 @@ You may wish to try re-authenticating.
&Покажи страницата на артистът
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- Най-харесвани песни
-
-
-
- Your loved tracks
- Песните, които харесам.
-
-
-
- %1's loved tracks
- Песните, каресвани от %1
-
-
-
- The most loved tracks from all your friends
- Най-харесваните песни от всички твои приятели.
-
-
-
- All of your loved tracks
- Всички песни, които харесвам.
-
-
-
- All of %1's loved tracks
- Всички песни, харесвани от %1
-
-
Tomahawk::DropJobNotifier
@@ -3002,7 +3037,7 @@ Try tweaking the filters for a new set of songs to play.
Tomahawk::SpotifyParser
-
+
Error fetching Spotify information from the network!
Грешка при извличане на информация от Spotify
@@ -3018,7 +3053,7 @@ Try tweaking the filters for a new set of songs to play.
TomahawkApp
-
+
My Collection
Моята колекция
@@ -3634,36 +3669,41 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_ca.ts b/lang/tomahawk_ca.ts
index 578d03edc..39bdc19ae 100644
--- a/lang/tomahawk_ca.ts
+++ b/lang/tomahawk_ca.ts
@@ -481,6 +481,14 @@ connect and stream from you?
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -616,12 +624,32 @@ connect and stream from you?
LovedTracksItem
-
+
+ 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
+
+
+
+
Loved Tracks
@@ -734,7 +762,7 @@ connect and stream from you?
-
+
- Properties
@@ -844,6 +872,31 @@ connect and stream from you?
Nom
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1367,7 +1420,7 @@ connect and stream from you?
-
+
Latest Additions
Darreres Novetats
@@ -1382,37 +1435,37 @@ connect and stream from you?
SuperCol·lecció
-
+
Latest additions to your collection
Darreres novetats a la vostra col·lecció
-
+
Latest additions to %1's collection
Darreres novetats a la col·lecció de %1
-
+
Sorry, we could not find any recent additions!
-
+
Recently Played Tracks
Cançons Escoltades Recentment
-
+
Your recently played tracks
Cançons Escoltades Recentment
-
+
%1's recently played tracks
Cançons Escoltades Recentment per %1
-
+
Sorry, we could not find any recent plays!
@@ -1490,77 +1543,72 @@ connect and stream from you?
SourcesModel
-
+
Group
Grup
-
+
Collection
Col·lecció
-
+
Playlist
Llista de Reproducció
-
+
Automatic Playlist
Llista de Reproducció Automàtica
-
+
Station
Emissora
-
+
Browse
Cerca
-
+
Search History
Historial de Cerca
-
+
My Music
La Meva Música
-
+
SuperCollection
SuperCol·lecció
-
- Top Loved Tracks
- Top de Cançons Preferides
-
-
-
+
Dashboard
Presentació
-
+
Recently Played
Escoltades Recentment
-
+
Charts
Llistes
-
+
New Releases
Nous Llançaments
-
+
Friends
Amics
@@ -1621,12 +1669,12 @@ 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é?
@@ -1934,17 +1982,37 @@ i emissores de ràdio basades en el vostre gust musical.
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
Sincronitza amb Spotify
-
+
Re-enable syncing with Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
Atura la sincronització amb Spotify
@@ -1952,28 +2020,28 @@ i emissores de ràdio basades en el vostre gust musical.
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
Iniciant sessió...
-
+
Failed: %1
Error: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
Incia Sessió
@@ -1981,7 +2049,7 @@ i emissores de ràdio basades en el vostre gust musical.
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
Reprodueix música i sincronitza les llistes de reproducció amb Spotify Premium
@@ -2220,39 +2288,6 @@ Torneu a autenticar-vos.
&Mostra la pàgina de l'artista
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- Top de Cançons Preferides
-
-
-
- Your loved tracks
- Les meves cançons preferides
-
-
-
- %1's loved tracks
- Les cançons preferides de %1
-
-
-
- The most loved tracks from all your friends
- Les cançons preferides de tots els amics
-
-
-
- All of your loved tracks
- Totes les meves cançons preferides
-
-
-
- All of %1's loved tracks
- Totes les cançons preferides de %1
-
-
Tomahawk::DropJobNotifier
@@ -2994,7 +3029,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!
@@ -3010,7 +3045,7 @@ Intenteu ajustar els filtres per reproduir noves cançons.
TomahawkApp
-
+
My Collection
La meva Col·lecció
@@ -3622,35 +3657,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts
index 5bbf3920d..eddf0e796 100644
--- a/lang/tomahawk_de.ts
+++ b/lang/tomahawk_de.ts
@@ -482,6 +482,14 @@ erlauben sich mit dir zu verbinden?
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -617,12 +625,32 @@ erlauben sich mit dir zu verbinden?
LovedTracksItem
-
+
+ Top Loved Tracks
+
+
+
+
Sorry, we could not find any loved tracks!
Sorry, wir konnten keine Lieblingslieder finden!
-
+
+ The most loved tracks from all your friends
+
+
+
+
+ All of your loved tracks
+
+
+
+
+ All of %1's loved tracks
+
+
+
+
Loved Tracks
Lieblingslieder
@@ -735,7 +763,7 @@ erlauben sich mit dir zu verbinden?
Vorwärts
-
+
- Properties
- Eigenschaften
@@ -845,6 +873,31 @@ erlauben sich mit dir zu verbinden?
Name
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1368,7 +1421,7 @@ erlauben sich mit dir zu verbinden?
-
+
Latest Additions
Kürzlich hinzugekommen
@@ -1383,37 +1436,37 @@ erlauben sich mit dir zu verbinden?
Supersammlung
-
+
Latest additions to your collection
Neueste Lieder in deiner Sammlung
-
+
Latest additions to %1's collection
Neueste Lieder in %1's Sammlung
-
+
Sorry, we could not find any recent additions!
Sorry, wir konnten keine Lieder finden die kürzlich hinzugefügt wurden!
-
+
Recently Played Tracks
Zuletzt gehörte Lieder
-
+
Your recently played tracks
Deine zuletzt gehörten Lieder
-
+
%1's recently played tracks
%1's zuletzt gehörte Lieder
-
+
Sorry, we could not find any recent plays!
Sorry, wir konnten keine kürzlich gespielten Lieder finden!
@@ -1491,77 +1544,72 @@ erlauben sich mit dir zu verbinden?
SourcesModel
-
+
Group
Gruppe
-
+
Collection
Sammlung
-
+
Playlist
Playlist
-
+
Automatic Playlist
Automatische Playlist
-
+
Station
Station
-
+
Browse
Stöbern
-
+
Search History
Suchverlauf
-
+
My Music
Meine Musik
-
+
SuperCollection
Supersammlung
-
- Top Loved Tracks
- Gemeinsame Lieblingslieder
-
-
-
+
Dashboard
Dashboard
-
+
Recently Played
Kürzlich gehörte Lieder
-
+
Charts
Charts
-
+
New Releases
Neuerscheinungen
-
+
Friends
Freunde
@@ -1622,12 +1670,12 @@ 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?
@@ -1932,17 +1980,37 @@ erlauben sich mit dir zu verbinden?
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
Mit Spotify synchronisieren
-
+
Re-enable syncing with Spotify
Synchronisierung mit Spotify re-aktivieren
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
Synchronisation beenden
@@ -1950,28 +2018,28 @@ erlauben sich mit dir zu verbinden?
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
Anmelden...
-
+
Failed: %1
Fehler: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
Anmelden
@@ -1979,7 +2047,7 @@ erlauben sich mit dir zu verbinden?
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
Musik abspielen und Playlisten synchronisieren mit Spotify Premium
@@ -2216,39 +2284,6 @@ You may wish to try re-authenticating.
&Gehe zur Künstler Seite
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- Meist geliebte Lieder
-
-
-
- Your loved tracks
- Deine Lieblingslieder
-
-
-
- %1's loved tracks
- Die Lieblingslieder von %1
-
-
-
- The most loved tracks from all your friends
- Die Lieblingslieder deiner Freunde
-
-
-
- All of your loved tracks
- All deine Lieblingslieder
-
-
-
- All of %1's loved tracks
- Alle Lieblingslieder von %1
-
-
Tomahawk::DropJobNotifier
@@ -2990,7 +3025,7 @@ Versuch die Filter anzupassen für neue Lieder.
Tomahawk::SpotifyParser
-
+
Error fetching Spotify information from the network!
Konnte Spotify-Daten nicht laden!
@@ -3006,7 +3041,7 @@ Versuch die Filter anzupassen für neue Lieder.
TomahawkApp
-
+
My Collection
Meine Sammlung
@@ -3613,35 +3648,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts
index 52dafea70..730a84a58 100644
--- a/lang/tomahawk_en.ts
+++ b/lang/tomahawk_en.ts
@@ -482,6 +482,14 @@ connect and stream from you?
Open &Log-file
+
+ FlexibleHeader
+
+
+ Filter...
+ Filter...
+
+
GlobalSearchWidget
@@ -617,12 +625,32 @@ connect and stream from you?
LovedTracksItem
-
+
+ Top Loved Tracks
+ Top Loved Tracks
+
+
+
Sorry, we could not find any loved tracks!
Sorry, we could not find any loved tracks!
-
+
+ The most loved tracks from all your friends
+ The most loved tracks from all your friends
+
+
+
+ All of your loved tracks
+ All of your loved tracks
+
+
+
+ All of %1's loved tracks
+ All of %1's loved tracks
+
+
+
Loved Tracks
Loved Tracks
@@ -735,7 +763,7 @@ connect and stream from you?
Forward
-
+
- Properties
- Properties
@@ -845,6 +873,31 @@ connect and stream from you?
Name
+
+ PlaylistHeader
+
+
+ InfoBar
+ InfoBar
+
+
+
+ Caption
+ Caption
+
+
+
+ Description
+ Description
+
+
+
+
+
+ RadioButton
+ RadioButton
+
+
PlaylistItemDelegate
@@ -1368,7 +1421,7 @@ connect and stream from you?
-
+
Latest Additions
Latest Additions
@@ -1383,37 +1436,37 @@ connect and stream from you?
SuperCollection
-
+
Latest additions to your collection
Latest additions to your collection
-
+
Latest additions to %1's collection
Latest additions to %1's collection
-
+
Sorry, we could not find any recent additions!
Sorry, we could not find any recent additions!
-
+
Recently Played Tracks
Recently Played Tracks
-
+
Your recently played tracks
Your recently played tracks
-
+
%1's recently played tracks
%1's recently played tracks
-
+
Sorry, we could not find any recent plays!
Sorry, we could not find any recent plays!
@@ -1491,77 +1544,72 @@ connect and stream from you?
SourcesModel
-
+
Group
Group
-
+
Collection
Collection
-
+
Playlist
Playlist
-
+
Automatic Playlist
Automatic Playlist
-
+
Station
Station
-
+
Browse
Browse
-
+
Search History
Search History
-
+
My Music
My Music
-
+
SuperCollection
SuperCollection
-
- Top Loved Tracks
- Top Loved Tracks
-
-
-
+
Dashboard
Dashboard
-
+
Recently Played
Recently Played
-
+
Charts
Charts
-
+
New Releases
New Releases
-
+
Friends
Friends
@@ -1622,12 +1670,12 @@ 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?
@@ -1935,17 +1983,37 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
Sync with Spotify
-
+
Re-enable syncing with Spotify
Re-enable syncing with Spotify
-
+
+ Create local copy
+ Create local copy
+
+
+
+ Subscribe to playlist changes
+ Subscribe to playlist changes
+
+
+
+ Re-enable playlist subscription
+ Re-enable playlist subscription
+
+
+
+ Stop subscribing to changes
+ Stop subscribing to changes
+
+
+
Stop syncing with Spotify
Stop syncing with Spotify
@@ -1953,28 +2021,28 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
Logging in...
-
+
Failed: %1
Failed: %1
-
+
Logged in as %1
Logged in as %1
-
+
Log Out
Log Out
-
-
+
+
Log In
Log In
@@ -1982,7 +2050,7 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
Play music from and sync your playlists with Spotify Premium
@@ -2221,39 +2289,6 @@ You may wish to try re-authenticating.
&Show Artist Page
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- Top Loved Tracks
-
-
-
- Your loved tracks
- Your loved tracks
-
-
-
- %1's loved tracks
- %1's loved tracks
-
-
-
- The most loved tracks from all your friends
- The most loved tracks from all your friends
-
-
-
- All of your loved tracks
- All of your loved tracks
-
-
-
- All of %1's loved tracks
- All of %1's loved tracks
-
-
Tomahawk::DropJobNotifier
@@ -2995,7 +3030,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!
@@ -3011,7 +3046,7 @@ Try tweaking the filters for a new set of songs to play.
TomahawkApp
-
+
My Collection
My Collection
@@ -3623,35 +3658,40 @@ 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!
+
WelcomeWidget
diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts
index ad5dbfa8a..1e15f3b45 100644
--- a/lang/tomahawk_es.ts
+++ b/lang/tomahawk_es.ts
@@ -481,6 +481,14 @@ connect and stream from you?
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -616,12 +624,32 @@ connect and stream from you?
LovedTracksItem
-
+
+ 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
+
+
+
+
Loved Tracks
@@ -734,7 +762,7 @@ connect and stream from you?
-
+
- Properties
@@ -844,6 +872,31 @@ connect and stream from you?
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1366,7 +1419,7 @@ connect and stream from you?
-
+
Latest Additions
Añadidos recientemente
@@ -1381,37 +1434,37 @@ connect and stream from you?
SuperColección
-
+
Latest additions to your collection
Últimas novedades en mi colección
-
+
Latest additions to %1's collection
Últimas novedadoes en la colección de %1
-
+
Sorry, we could not find any recent additions!
-
+
Recently Played Tracks
Temas Escuchados Recientemente
-
+
Your recently played tracks
Mis canciones escuchadas recientemente
-
+
%1's recently played tracks
Las canciones escuchadas recientemente por %1
-
+
Sorry, we could not find any recent plays!
@@ -1489,77 +1542,72 @@ connect and stream from you?
SourcesModel
-
+
Group
Grupo
-
+
Collection
Colección
-
+
Playlist
Lista de reproducción
-
+
Automatic Playlist
Lista de reproducción automática
-
+
Station
Estación
-
+
Browse
Buscar
-
+
Search History
Historial de Búsqueda
-
+
My Music
Mi Musica
-
+
SuperCollection
SuperColección
-
- Top Loved Tracks
- Pistas favoritas
-
-
-
+
Dashboard
Panel de inicio
-
+
Recently Played
Reproducido recientemente
-
+
Charts
Listas
-
+
New Releases
Últimas novedades
-
+
Friends
Amigos
@@ -1620,12 +1668,12 @@ 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?
@@ -1933,17 +1981,37 @@ y estaciones basadas en sus gustos personales.
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
Sincronizar con Spotify
-
+
Re-enable syncing with Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
Dejar de sincronizar con Spotify
@@ -1951,28 +2019,28 @@ y estaciones basadas en sus gustos personales.
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
Inciando sesión...
-
+
Failed: %1
Fallo: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
Iniciar Sesión
@@ -1980,7 +2048,7 @@ y estaciones basadas en sus gustos personales.
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
Reproduce música de Spotofy Premium y sincroniza las listas de reprodución
@@ -2219,39 +2287,6 @@ Hay que volverse a autenticar.
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- Pistas favoritas
-
-
-
- Your loved tracks
- Tus pistas favoritas
-
-
-
- %1's loved tracks
- Pistas favoritas de %1
-
-
-
- The most loved tracks from all your friends
- Las pistas favoritas de tus amigos
-
-
-
- All of your loved tracks
- Todas tus pistas favoritas
-
-
-
- All of %1's loved tracks
- Todas las pistas favoritas de %1
-
-
Tomahawk::DropJobNotifier
@@ -2993,7 +3028,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!
@@ -3009,7 +3044,7 @@ Intente ajustar los filtros para reproducir nuevas canciones.
TomahawkApp
-
+
My Collection
Mi colección
@@ -3621,35 +3656,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_fr.ts b/lang/tomahawk_fr.ts
index b02fa3971..278c8e8e0 100644
--- a/lang/tomahawk_fr.ts
+++ b/lang/tomahawk_fr.ts
@@ -474,11 +474,19 @@ de se connecter et streamer de vous?
&Copy to Clipboard
-
+ &Copier à la planchette
Open &Log-file
+ Ouvrir le &fichier journal
+
+
+
+ FlexibleHeader
+
+
+ Filter...
@@ -557,7 +565,7 @@ de se connecter et streamer de vous?
%1 is listening along with you!
-
+ %1 écoute avec vous!
@@ -617,12 +625,32 @@ de se connecter et streamer de vous?
LovedTracksItem
-
+
+ Top Loved Tracks
+
+
+
+
Sorry, we could not find any loved tracks!
Désolé, on a pas pu trouver aucune piste favoris!
-
+
+ The most loved tracks from all your friends
+
+
+
+
+ All of your loved tracks
+
+
+
+
+ All of %1's loved tracks
+
+
+
+
Loved Tracks
Titres favoris
@@ -735,7 +763,7 @@ de se connecter et streamer de vous?
Avancer
-
+
- Properties
- Propriétés
@@ -845,6 +873,31 @@ de se connecter et streamer de vous?
Nom
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1368,7 +1421,7 @@ de se connecter et streamer de vous?
-
+
Latest Additions
Derniers ajouts
@@ -1383,37 +1436,37 @@ de se connecter et streamer de vous?
SuperCollection
-
+
Latest additions to your collection
Derniers ajouts à votre collection
-
+
Latest additions to %1's collection
Derniers ajouts à la collection de %1
-
+
Sorry, we could not find any recent additions!
Désolé, on a pas pu trouver des dernier ajouts!
-
+
Recently Played Tracks
Derniers titres joués
-
+
Your recently played tracks
Les derniers titres que vous avez joués
-
+
%1's recently played tracks
Derniers titres joués par %1
-
+
Sorry, we could not find any recent plays!
Désolé, on a pas pu trouver aucune piste récement joués!
@@ -1491,77 +1544,72 @@ de se connecter et streamer de vous?
SourcesModel
-
+
Group
Groupe
-
+
Collection
Collection
-
+
Playlist
Liste de lecture
-
+
Automatic Playlist
Liste de lecture automatique
-
+
Station
Station
-
+
Browse
Parcourir
-
+
Search History
Chercher dans l'historique
-
+
My Music
Ma Musique
-
+
SuperCollection
SuperCollection
-
- Top Loved Tracks
- Top des titres favoris
-
-
-
+
Dashboard
Tableau de bord
-
+
Recently Played
Joués récemment
-
+
Charts
Charts
-
+
New Releases
Nouveautés
-
+
Friends
Amis
@@ -1622,12 +1670,12 @@ 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 ?
@@ -1935,17 +1983,37 @@ et des stations basées sur vos goûts.
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
Synchroniser avec Spotify
-
+
Re-enable syncing with Spotify
Réactiver la synchronisation avec Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
Stopper la synchronisation avec Spotify
@@ -1953,28 +2021,28 @@ et des stations basées sur vos goûts.
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
Connexion...
-
+
Failed: %1
Echec : %1
-
-
- Logged in as %1
-
-
- Log Out
-
+ Logged in as %1
+ Connecté sous %1
-
-
+
+ Log Out
+ Déconnectez-vous
+
+
+
+
Log In
Connexion
@@ -1982,7 +2050,7 @@ et des stations basées sur vos goûts.
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
Jouer la musique et synchroniser vos listes avec Spotify Premium
@@ -2203,7 +2271,7 @@ Essayez de vous authentifier de nouveau.
Properties...
-
+ Propriétés...
@@ -2221,39 +2289,6 @@ Essayez de vous authentifier de nouveau.
&Afficher la page artiste
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- Top des titres favoris
-
-
-
- Your loved tracks
- Vos titres favoris
-
-
-
- %1's loved tracks
- Titres favoris de %1
-
-
-
- The most loved tracks from all your friends
- Les titres favoris de vos amis
-
-
-
- All of your loved tracks
- Tous vos titres favoris
-
-
-
- All of %1's loved tracks
- Tous les titres favoris de %1
-
-
Tomahawk::DropJobNotifier
@@ -2995,7 +3030,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!
@@ -3011,7 +3046,7 @@ Essayez de changer les filtres pour avoir de nouveaux morceaux à jouer.
TomahawkApp
-
+
My Collection
Ma Collection
@@ -3623,35 +3658,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts
index 664ad2fbf..e662672b0 100644
--- a/lang/tomahawk_ja.ts
+++ b/lang/tomahawk_ja.ts
@@ -15,7 +15,7 @@ connect and stream from you?
Deny Access
-
+ アクセスを拒否
@@ -36,7 +36,7 @@ connect and stream from you?
Description goes here
-
+ 内容
@@ -147,12 +147,12 @@ 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!
-
+ このアルバムの曲は見つかりませんでした。
@@ -194,7 +194,7 @@ connect and stream from you?
Artist
-
+ アーティスト
@@ -204,7 +204,7 @@ connect and stream from you?
Cover
-
+ カバー
@@ -214,12 +214,12 @@ connect and stream from you?
Sorry, we could not find any related artists!
-
+ 関連アーティストは見つかりませんでした。
Sorry, we could not find any top hits for this artist!
-
+ このアーティストの大ヒット曲は見つかりませんでした。
@@ -257,7 +257,7 @@ connect and stream from you?
Owner
-
+ オーナー
@@ -305,17 +305,17 @@ connect and stream from you?
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を見つかりませんでした。
@@ -474,12 +474,20 @@ connect and stream from you?
&Copy to Clipboard
-
+ クリップボードにコピー
Open &Log-file
-
+ ログファイルを開く
+
+
+
+ FlexibleHeader
+
+
+ Filter...
+ フィルター...
@@ -557,7 +565,7 @@ connect and stream from you?
%1 is listening along with you!
-
+ %1さんが一緒に聴いています。
@@ -617,14 +625,34 @@ connect and stream from you?
LovedTracksItem
-
- Sorry, we could not find any loved tracks!
-
+
+ Top Loved Tracks
+ 最もLove トラック
-
+
+ Sorry, we could not find any loved tracks!
+ Love トラックが見つかりませんでした。
+
+
+
+ The most loved tracks from all your friends
+ 友達の最もLove トラック
+
+
+
+ All of your loved tracks
+ 自分のLove トラック
+
+
+
+ All of %1's loved tracks
+ %1さんのLove トラック
+
+
+
Loved Tracks
-
+ Love トラック
@@ -632,112 +660,112 @@ 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
-
+ 次へ
-
+
- Properties
-
+ - 情報
@@ -845,6 +873,31 @@ connect and stream from you?
名前
+
+ PlaylistHeader
+
+
+ InfoBar
+ インフォメーションバー
+
+
+
+ Caption
+ 表題
+
+
+
+ Description
+ 内容
+
+
+
+
+
+ RadioButton
+ RadioButton
+
+
PlaylistItemDelegate
@@ -909,12 +962,12 @@ connect and stream from you?
Just a regular old playlist... Give it a name, drag in some tracks, and go!
-
+ 普通のプレイリスト... 名付けて、曲をドラッグ・アンド・ドロップして行こう!
Don't know exactly what you want? Give Tomahawk a few pointers and let it build a playlist for you!
-
+ 欲しいのが分かりませんか?Tomahawkに何らかのヒントを与えたら、プレイリストの作成を任せて下さい!
@@ -1202,12 +1255,12 @@ connect and stream from you?
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.
-
+ 本当に全てのアクセス制御のエントリーを削除しますか?ピア接続に対して、改めて同意を求めます。
@@ -1220,7 +1273,7 @@ connect and stream from you?
Popular New Albums From Your Friends
-
+ 友達に人気のある新アルバム
@@ -1230,7 +1283,7 @@ connect and stream from you?
Most Played Tracks You Don't Have
-
+ あなたの無い最も再生された曲
@@ -1238,47 +1291,47 @@ connect and stream from you?
Form
-
+ フォーム
Facebook
-
+ Facebook
Twitter
-
+ Twitter
Cover
-
+ カバー
TextLabel
-
+ TextLabel
Tweet
-
+ ツイート
Listening to "%1" by %2. %3
-
+ %2の"%1"を聴いています。%3
Listening to "%1" by %2 on "%3". %4
-
+ %2の"%3"の"%1"を聴いています。%4
%1 characters left
-
+ 残り%1文字
@@ -1301,29 +1354,29 @@ connect and stream from you?
Local
-
+ ローカル
Top 10
-
+ トップ10
All available tracks
-
+ 利用可能トラック
Show
-
+ 表示
Hide
-
+ 隠す
@@ -1331,32 +1384,32 @@ connect and stream from you?
Recent Albums
-
+ 最近のアルバム
Latest Additions
-
+ 最新追加した項目
Recently Played Tracks
-
+ 最近再生したトラック
New Additions
-
+ 新しく追加した項目
My recent activity
-
+ 自分の最近の活動
Recent activity from %1
-
+ %1の最近の活動
@@ -1368,14 +1421,14 @@ connect and stream from you?
-
+
Latest Additions
-
+ 最新追加した項目
Recently Played
-
+ 最近聴いたトラック
@@ -1383,39 +1436,39 @@ connect and stream from you?
スーパーコレクション
-
+
Latest additions to your collection
-
+ コレクションの最新追加した項目
-
+
Latest additions to %1's collection
-
+ %1のコレクションの最新追加した項目
-
+
Sorry, we could not find any recent additions!
-
+ 最近追加した項目が見つかりませんでした。
-
+
Recently Played Tracks
-
+ 最近再生したトラック
-
+
Your recently played tracks
-
+ あなたの最近再生したトラック
-
+
%1's recently played tracks
-
+ %1の最近再生したトラック
-
+
Sorry, we could not find any recent plays!
-
+ 最近の再生した項目が見つかりませんでした。
@@ -1428,54 +1481,54 @@ connect and stream from you?
&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を削除しますか?
@@ -1485,85 +1538,80 @@ connect and stream from you?
Playlists (*.xspf)
-
+ プレイリスト (*.xspf)
SourcesModel
-
+
Group
-
+ グループ
-
+
Collection
コレクション
-
+
Playlist
プレイリスト
-
+
Automatic Playlist
-
+ 自動プレイリスト
-
+
Station
ステーション
-
-
- Browse
-
-
- Search History
-
+ Browse
+ 閲覧
-
+
+ Search History
+ 履歴を検索
+
+
+
My Music
マイミュージック
-
+
SuperCollection
スーパーコレクション
-
- Top Loved Tracks
-
-
-
-
+
Dashboard
ダッシュボード
-
+
Recently Played
最近聴いたトラック
-
+
Charts
-
+ チャート
-
+
New Releases
-
+ ニューリリース
-
+
Friends
-
+ 友達
@@ -1576,12 +1624,12 @@ connect and stream from you?
Configure your Spotify account
-
+ Spotifyのアカウントを設定
Username or Facebook Email
-
+ ユーザーネームまたはFacebookのメールアドレス
@@ -1591,45 +1639,45 @@ connect and stream from you?
Right click on any Tomahawk playlist to sync it to Spotify.
-
+ Tomahawkのプレイリストを右クリクすると、Spotifyに同期することができます。
High Quality Streams
-
+ 高音質ストリーム
Spotify playlists to keep in sync:
-
+ 同期するSpotifyのプレイリスト:
Delete Tomahawk playlist when removing synchronization
-
+ 同期を無効すれば、Tomahawkのプレイリストを削除
Username:
-
+ ユーザー名
Password:
-
+ パスワード
SpotifyPlaylistUpdater
-
+
Delete in Spotify?
-
+ Spotifyにも削除しますか?
-
+
Would you like to delete the corresponding Spotify playlist as well?
-
+ 同期のSpotifyのプレイリストも削除してもよろしいですか?
@@ -1637,7 +1685,7 @@ connect and stream from you?
Tomahawk Settings
-
+ 設定
@@ -1932,17 +1980,37 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
-
+
Re-enable syncing with Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
@@ -1950,28 +2018,28 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
ログイン中...
-
+
Failed: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
ログイン
@@ -1979,7 +2047,7 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
@@ -2215,39 +2283,6 @@ You may wish to try re-authenticating.
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
-
-
-
-
- Your loved tracks
-
-
-
-
- %1's loved tracks
-
-
-
-
- The most loved tracks from all your friends
-
-
-
-
- All of your loved tracks
-
-
-
-
- All of %1's loved tracks
-
-
-
Tomahawk::DropJobNotifier
@@ -2985,7 +3020,7 @@ Try tweaking the filters for a new set of songs to play.
Tomahawk::SpotifyParser
-
+
Error fetching Spotify information from the network!
@@ -3001,7 +3036,7 @@ Try tweaking the filters for a new set of songs to play.
TomahawkApp
-
+
My Collection
@@ -3613,35 +3648,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts
index 638f26874..6184f3d42 100644
--- a/lang/tomahawk_pl.ts
+++ b/lang/tomahawk_pl.ts
@@ -481,6 +481,14 @@ connect and stream from you?
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -616,12 +624,32 @@ connect and stream from you?
LovedTracksItem
-
+
+ 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
+
+
+
+
Loved Tracks
@@ -734,7 +762,7 @@ connect and stream from you?
-
+
- Properties
@@ -844,6 +872,31 @@ connect and stream from you?
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1366,7 +1419,7 @@ connect and stream from you?
-
+
Latest Additions
Ostatnio Dodane
@@ -1381,37 +1434,37 @@ connect and stream from you?
Superkolekcja
-
+
Latest additions to your collection
-
+
Latest additions to %1's collection
-
+
Sorry, we could not find any recent additions!
-
+
Recently Played Tracks
-
+
Your recently played tracks
-
+
%1's recently played tracks
-
+
Sorry, we could not find any recent plays!
@@ -1489,77 +1542,72 @@ connect and stream from you?
SourcesModel
-
+
Group
Grupa
-
+
Collection
kolekcja
-
+
Playlist
Lista
-
+
Automatic Playlist
Automatyczna Lista
-
+
Station
Stacja
-
+
Browse
Przeglądaj
-
+
Search History
Historia wyszukiwania
-
+
My Music
Moja Muzyka
-
+
SuperCollection
Superkolekcja
-
- Top Loved Tracks
-
-
-
-
+
Dashboard
-
+
Recently Played
Ostatnio Odtworzone
-
+
Charts
Listy Przebojów
-
+
New Releases
Nowe Wydania
-
+
Friends
Znajomi
@@ -1620,12 +1668,12 @@ connect and stream from you?
SpotifyPlaylistUpdater
-
+
Delete in Spotify?
-
+
Would you like to delete the corresponding Spotify playlist as well?
@@ -1934,17 +1982,37 @@ indywidualnego profilu gustu.
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
-
+
Re-enable syncing with Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
@@ -1952,28 +2020,28 @@ indywidualnego profilu gustu.
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
-
+
Failed: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
@@ -1981,7 +2049,7 @@ indywidualnego profilu gustu.
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
@@ -2217,39 +2285,6 @@ You may wish to try re-authenticating.
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- Najbardziej Lubiane Utwory
-
-
-
- Your loved tracks
- Twoje ulubione utwory
-
-
-
- %1's loved tracks
- Ulubione utwory %1
-
-
-
- The most loved tracks from all your friends
- Najbardziej lubiane utwory wszystkich twoich znajomych
-
-
-
- All of your loved tracks
- Wszystkie twoje ulubione utwory
-
-
-
- All of %1's loved tracks
- Wszystkie ulubione utwory %1
-
-
Tomahawk::DropJobNotifier
@@ -2989,7 +3024,7 @@ Try tweaking the filters for a new set of songs to play.
Tomahawk::SpotifyParser
-
+
Error fetching Spotify information from the network!
@@ -3005,7 +3040,7 @@ Try tweaking the filters for a new set of songs to play.
TomahawkApp
-
+
My Collection
Moja Kolekcja
@@ -3617,35 +3652,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts
index 58ae843f8..8be3fe8aa 100644
--- a/lang/tomahawk_pt_BR.ts
+++ b/lang/tomahawk_pt_BR.ts
@@ -482,6 +482,14 @@ se conecte e faça o stream de você?
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -617,12 +625,32 @@ se conecte e faça o stream de você?
LovedTracksItem
-
+
+ Top Loved Tracks
+
+
+
+
Sorry, we could not find any loved tracks!
Desculpe, não encontramos nenhuma faixa favorita!
-
+
+ The most loved tracks from all your friends
+
+
+
+
+ All of your loved tracks
+
+
+
+
+ All of %1's loved tracks
+
+
+
+
Loved Tracks
Faixas Favoritas
@@ -735,7 +763,7 @@ se conecte e faça o stream de você?
Avançar
-
+
- Properties
- Propriedades
@@ -845,6 +873,31 @@ se conecte e faça o stream de você?
Nome
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1368,7 +1421,7 @@ se conecte e faça o stream de você?
-
+
Latest Additions
Últimas Adições
@@ -1383,37 +1436,37 @@ se conecte e faça o stream de você?
SuperColeção
-
+
Latest additions to your collection
Últimas adições à sua coleção
-
+
Latest additions to %1's collection
Últimas adições à coleção de %1
-
+
Sorry, we could not find any recent additions!
Desculpe, não foi possível encontrar adições recentes!
-
+
Recently Played Tracks
Faixas Reproduzidas Recentemente
-
+
Your recently played tracks
Suas faixas reproduzidas recentemente
-
+
%1's recently played tracks
Faixas reproduzidas recentemente por %1
-
+
Sorry, we could not find any recent plays!
Desculpe, não foi possível encontrar playlists recentes!
@@ -1491,77 +1544,72 @@ se conecte e faça o stream de você?
SourcesModel
-
+
Group
Grupo
-
+
Collection
Coleção
-
+
Playlist
Playlist
-
+
Automatic Playlist
Playlist Automática
-
+
Station
Estação
-
+
Browse
Navegar
-
+
Search History
Histórico de Busca
-
+
My Music
Minhas Músicas
-
+
SuperCollection
SuperColeção
-
- Top Loved Tracks
- Faixas Favoritas
-
-
-
+
Dashboard
Painel
-
+
Recently Played
Ouvidas Recentemente
-
+
Charts
Charts
-
+
New Releases
Lançamentos
-
+
Friends
Amigos
@@ -1622,12 +1670,12 @@ 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?
@@ -1935,17 +1983,37 @@ automáticas baseadas no seu gosto pessoal.
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
Sincronizar com o Spotify
-
+
Re-enable syncing with Spotify
Reativar sincronização com Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
Parar a sincronização com o Spotify
@@ -1953,28 +2021,28 @@ automáticas baseadas no seu gosto pessoal.
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
Logando...
-
+
Failed: %1
Falha: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
Log In
@@ -1982,7 +2050,7 @@ automáticas baseadas no seu gosto pessoal.
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
Reproduzir e sincronizar suas playlists com o Spotify Premium
@@ -2221,39 +2289,6 @@ Você pode tentar re-autenticar.
&Mostrar Página do Artista
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- Faixas Favoritas
-
-
-
- Your loved tracks
- Suas faixas favoritas
-
-
-
- %1's loved tracks
- Faixas favoritas de %1
-
-
-
- The most loved tracks from all your friends
- As faixas favoritas de todos os seus amigos
-
-
-
- All of your loved tracks
- Todas as suas faixas favoritas
-
-
-
- All of %1's loved tracks
- Todas as faixas favoritas de %1
-
-
Tomahawk::DropJobNotifier
@@ -2995,7 +3030,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!
@@ -3011,7 +3046,7 @@ Tente ajustar os filtros para ouvir um novo conjunto de músicas.
TomahawkApp
-
+
My Collection
Minha Coleção
@@ -3623,35 +3658,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_ru.ts b/lang/tomahawk_ru.ts
index c8e9962d1..2bd49de0c 100644
--- a/lang/tomahawk_ru.ts
+++ b/lang/tomahawk_ru.ts
@@ -481,6 +481,14 @@ connect and stream from you?
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -616,12 +624,32 @@ connect and stream from you?
LovedTracksItem
-
+
+ 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
+
+
+
+
Loved Tracks
@@ -734,7 +762,7 @@ connect and stream from you?
-
+
- Properties
@@ -844,6 +872,31 @@ connect and stream from you?
Имя
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1367,7 +1420,7 @@ connect and stream from you?
-
+
Latest Additions
Последние добавленные
@@ -1382,37 +1435,37 @@ connect and stream from you?
Общая коллекция
-
+
Latest additions to your collection
Последние добавления в коллекцию
-
+
Latest additions to %1's collection
-
+
Sorry, we could not find any recent additions!
-
+
Recently Played Tracks
Недавно Воспроизводимые
-
+
Your recently played tracks
Ваши Недавно Воспроизводимые
-
+
%1's recently played tracks
-
+
Sorry, we could not find any recent plays!
@@ -1490,77 +1543,72 @@ connect and stream from you?
SourcesModel
-
+
Group
Группа
-
+
Collection
Коллекция
-
+
Playlist
Плейлист
-
+
Automatic Playlist
Автоматический плейлист
-
+
Station
Станция
-
+
Browse
Просмотреть
-
+
Search History
История поиска
-
+
My Music
Моя музыка
-
+
SuperCollection
Общая коллекция
-
- Top Loved Tracks
- Топ любимых песен
-
-
-
+
Dashboard
Панель
-
+
Recently Played
Последние воспроизводимые
-
+
Charts
Чарты
-
+
New Releases
Новые релизы
-
+
Friends
Друзья
@@ -1621,12 +1669,12 @@ connect and stream from you?
SpotifyPlaylistUpdater
-
+
Delete in Spotify?
Удалить в Spotify?
-
+
Would you like to delete the corresponding Spotify playlist as well?
@@ -1931,17 +1979,37 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
Синхронизировать с Spotify
-
+
Re-enable syncing with Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
Прекратить синхронизацию с Spotify
@@ -1949,28 +2017,28 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
Вхожу...
-
+
Failed: %1
Ошибка: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
Войти
@@ -1978,7 +2046,7 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
@@ -2217,39 +2285,6 @@ You may wish to try re-authenticating.
&Показать Станицу Исполнителя
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- Топ любимых песен
-
-
-
- Your loved tracks
- Ваши любимые песни
-
-
-
- %1's loved tracks
- %1's любимая песня
-
-
-
- The most loved tracks from all your friends
- Самые любимые песни от всех ваших друзей
-
-
-
- All of your loved tracks
- Все любимые песни
-
-
-
- All of %1's loved tracks
- Все от %1 любимые песни
-
-
Tomahawk::DropJobNotifier
@@ -2989,7 +3024,7 @@ Try tweaking the filters for a new set of songs to play.
Tomahawk::SpotifyParser
-
+
Error fetching Spotify information from the network!
Возникла ошибка при получении информации из Spotify!
@@ -3005,7 +3040,7 @@ Try tweaking the filters for a new set of songs to play.
TomahawkApp
-
+
My Collection
Моя коллекция
@@ -3615,35 +3650,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts
index f73257155..ad6f19cb3 100644
--- a/lang/tomahawk_sv.ts
+++ b/lang/tomahawk_sv.ts
@@ -481,6 +481,14 @@ connect and stream from you?
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -616,12 +624,32 @@ connect and stream from you?
LovedTracksItem
-
+
+ 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
+
+
+
+
Loved Tracks
@@ -734,7 +762,7 @@ connect and stream from you?
-
+
- Properties
@@ -844,6 +872,31 @@ connect and stream from you?
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1367,7 +1420,7 @@ connect and stream from you?
-
+
Latest Additions
Senast tillagda
@@ -1382,37 +1435,37 @@ connect and stream from you?
SuperCollection
-
+
Latest additions to your collection
-
+
Latest additions to %1's collection
-
+
Sorry, we could not find any recent additions!
-
+
Recently Played Tracks
-
+
Your recently played tracks
-
+
%1's recently played tracks
-
+
Sorry, we could not find any recent plays!
@@ -1490,77 +1543,72 @@ connect and stream from you?
SourcesModel
-
+
Group
Grupp
-
+
Collection
Samling
-
+
Playlist
Spellista
-
+
Automatic Playlist
Automatisk spellista
-
+
Station
Station
-
+
Browse
Bläddra
-
+
Search History
Sökhistorik
-
+
My Music
Min Musik
-
+
SuperCollection
SuperCollection
-
- Top Loved Tracks
- Mest älskade spår
-
-
-
+
Dashboard
-
+
Recently Played
-
+
Charts
Topplistor
-
+
New Releases
-
+
Friends
Vänner
@@ -1621,12 +1669,12 @@ connect and stream from you?
SpotifyPlaylistUpdater
-
+
Delete in Spotify?
-
+
Would you like to delete the corresponding Spotify playlist as well?
@@ -1931,17 +1979,37 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
-
+
Re-enable syncing with Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
@@ -1949,28 +2017,28 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
-
+
Failed: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
@@ -1978,7 +2046,7 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
@@ -2214,39 +2282,6 @@ You may wish to try re-authenticating.
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
- Mest älskade spår
-
-
-
- Your loved tracks
- Dina älskade spår
-
-
-
- %1's loved tracks
- Älskade spår för %1
-
-
-
- The most loved tracks from all your friends
- De mest älskade spåren från alla dina vänner
-
-
-
- All of your loved tracks
- Alla dina älskade spår
-
-
-
- All of %1's loved tracks
- Alla spår som %1 älskar
-
-
Tomahawk::DropJobNotifier
@@ -2984,7 +3019,7 @@ Try tweaking the filters for a new set of songs to play.
Tomahawk::SpotifyParser
-
+
Error fetching Spotify information from the network!
@@ -3000,7 +3035,7 @@ Try tweaking the filters for a new set of songs to play.
TomahawkApp
-
+
My Collection
@@ -3606,35 +3641,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_tr.ts b/lang/tomahawk_tr.ts
index 7149903f6..2243d4b64 100644
--- a/lang/tomahawk_tr.ts
+++ b/lang/tomahawk_tr.ts
@@ -481,6 +481,14 @@ connect and stream from you?
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -616,12 +624,32 @@ connect and stream from you?
LovedTracksItem
-
+
+ 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
+
+
+
+
Loved Tracks
@@ -734,7 +762,7 @@ connect and stream from you?
-
+
- Properties
@@ -844,6 +872,31 @@ connect and stream from you?
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1366,7 +1419,7 @@ connect and stream from you?
-
+
Latest Additions
@@ -1381,37 +1434,37 @@ connect and stream from you?
-
+
Latest additions to your collection
-
+
Latest additions to %1's collection
-
+
Sorry, we could not find any recent additions!
-
+
Recently Played Tracks
-
+
Your recently played tracks
-
+
%1's recently played tracks
-
+
Sorry, we could not find any recent plays!
@@ -1489,77 +1542,72 @@ connect and stream from you?
SourcesModel
-
+
Group
-
+
Collection
-
+
Playlist
-
+
Automatic Playlist
-
+
Station
-
+
Browse
-
+
Search History
-
+
My Music
-
+
SuperCollection
-
- Top Loved Tracks
-
-
-
-
+
Dashboard
-
+
Recently Played
-
+
Charts
-
+
New Releases
-
+
Friends
@@ -1620,12 +1668,12 @@ connect and stream from you?
SpotifyPlaylistUpdater
-
+
Delete in Spotify?
-
+
Would you like to delete the corresponding Spotify playlist as well?
@@ -1930,17 +1978,37 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
-
+
Re-enable syncing with Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
@@ -1948,28 +2016,28 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
-
+
Failed: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
@@ -1977,7 +2045,7 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
@@ -2213,39 +2281,6 @@ You may wish to try re-authenticating.
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
-
-
-
-
- Your loved tracks
-
-
-
-
- %1's loved tracks
-
-
-
-
- The most loved tracks from all your friends
-
-
-
-
- All of your loved tracks
-
-
-
-
- All of %1's loved tracks
-
-
-
Tomahawk::DropJobNotifier
@@ -2983,7 +3018,7 @@ Try tweaking the filters for a new set of songs to play.
Tomahawk::SpotifyParser
-
+
Error fetching Spotify information from the network!
@@ -2999,7 +3034,7 @@ Try tweaking the filters for a new set of songs to play.
TomahawkApp
-
+
My Collection
@@ -3605,35 +3640,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_zh_CN.ts b/lang/tomahawk_zh_CN.ts
index 4daaeaeab..629cf3e86 100644
--- a/lang/tomahawk_zh_CN.ts
+++ b/lang/tomahawk_zh_CN.ts
@@ -481,6 +481,14 @@ connect and stream from you?
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -616,12 +624,32 @@ connect and stream from you?
LovedTracksItem
-
+
+ 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
+
+
+
+
Loved Tracks
喜爱曲目
@@ -734,7 +762,7 @@ connect and stream from you?
-
+
- Properties
@@ -844,6 +872,31 @@ connect and stream from you?
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1366,7 +1419,7 @@ connect and stream from you?
-
+
Latest Additions
@@ -1381,37 +1434,37 @@ connect and stream from you?
-
+
Latest additions to your collection
-
+
Latest additions to %1's collection
-
+
Sorry, we could not find any recent additions!
-
+
Recently Played Tracks
最近播放曲目
-
+
Your recently played tracks
你最近播放的曲目
-
+
%1's recently played tracks
%1最近播放的曲目
-
+
Sorry, we could not find any recent plays!
@@ -1489,77 +1542,72 @@ connect and stream from you?
SourcesModel
-
+
Group
-
+
Collection
-
+
Playlist
-
+
Automatic Playlist
-
+
Station
-
+
Browse
随便看看
-
+
Search History
搜索历史
-
+
My Music
我的音乐
-
+
SuperCollection
-
- Top Loved Tracks
-
-
-
-
+
Dashboard
-
+
Recently Played
最近播放
-
+
Charts
排行榜
-
+
New Releases
新专辑
-
+
Friends
@@ -1620,12 +1668,12 @@ connect and stream from you?
SpotifyPlaylistUpdater
-
+
Delete in Spotify?
-
+
Would you like to delete the corresponding Spotify playlist as well?
@@ -1930,17 +1978,37 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
-
+
Re-enable syncing with Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
@@ -1948,28 +2016,28 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
-
+
Failed: %1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
@@ -1977,7 +2045,7 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
@@ -2213,39 +2281,6 @@ You may wish to try re-authenticating.
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
-
-
-
-
- Your loved tracks
-
-
-
-
- %1's loved tracks
-
-
-
-
- The most loved tracks from all your friends
-
-
-
-
- All of your loved tracks
-
-
-
-
- All of %1's loved tracks
-
-
-
Tomahawk::DropJobNotifier
@@ -2983,7 +3018,7 @@ Try tweaking the filters for a new set of songs to play.
Tomahawk::SpotifyParser
-
+
Error fetching Spotify information from the network!
@@ -2999,7 +3034,7 @@ Try tweaking the filters for a new set of songs to play.
TomahawkApp
-
+
My Collection
@@ -3605,35 +3640,40 @@ 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!
+
+
WelcomeWidget
diff --git a/lang/tomahawk_zh_TW.ts b/lang/tomahawk_zh_TW.ts
index cb8ce803d..9366a8bbb 100644
--- a/lang/tomahawk_zh_TW.ts
+++ b/lang/tomahawk_zh_TW.ts
@@ -481,6 +481,14 @@ connect and stream from you?
+
+ FlexibleHeader
+
+
+ Filter...
+
+
+
GlobalSearchWidget
@@ -616,12 +624,32 @@ connect and stream from you?
LovedTracksItem
-
+
+ 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
+
+
+
+
Loved Tracks
@@ -734,7 +762,7 @@ connect and stream from you?
-
+
- Properties
@@ -844,6 +872,31 @@ connect and stream from you?
+
+ PlaylistHeader
+
+
+ InfoBar
+
+
+
+
+ Caption
+
+
+
+
+ Description
+
+
+
+
+
+
+ RadioButton
+
+
+
PlaylistItemDelegate
@@ -1366,7 +1419,7 @@ connect and stream from you?
-
+
Latest Additions
最新加入
@@ -1381,37 +1434,37 @@ connect and stream from you?
超級收藏
-
+
Latest additions to your collection
-
+
Latest additions to %1's collection
-
+
Sorry, we could not find any recent additions!
-
+
Recently Played Tracks
-
+
Your recently played tracks
-
+
%1's recently played tracks
-
+
Sorry, we could not find any recent plays!
@@ -1489,77 +1542,72 @@ connect and stream from you?
SourcesModel
-
+
Group
-
+
Collection
收藏
-
+
Playlist
播放清單
-
+
Automatic Playlist
自動播放清單
-
+
Station
-
+
Browse
瀏覽
-
+
Search History
搜尋記錄
-
+
My Music
我的音樂
-
+
SuperCollection
超級收藏
-
- Top Loved Tracks
- 最喜愛的曲目
-
-
-
+
Dashboard
儀表板
-
+
Recently Played
最近播放的
-
+
Charts
-
+
New Releases
新版本
-
+
Friends
朋友
@@ -1620,12 +1668,12 @@ connect and stream from you?
SpotifyPlaylistUpdater
-
+
Delete in Spotify?
-
+
Would you like to delete the corresponding Spotify playlist as well?
@@ -1930,17 +1978,37 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccount
-
+
Sync with Spotify
-
+
Re-enable syncing with Spotify
-
+
+ Create local copy
+
+
+
+
+ Subscribe to playlist changes
+
+
+
+
+ Re-enable playlist subscription
+
+
+
+
+ Stop subscribing to changes
+
+
+
+
Stop syncing with Spotify
@@ -1948,28 +2016,28 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountConfig
-
+
Logging in...
登錄中...
-
+
Failed: %1
失敗:%1
-
+
Logged in as %1
-
+
Log Out
-
-
+
+
Log In
登錄
@@ -1977,7 +2045,7 @@ connect and stream from you?
Tomahawk::Accounts::SpotifyAccountFactory
-
+
Play music from and sync your playlists with Spotify Premium
@@ -2213,39 +2281,6 @@ You may wish to try re-authenticating.
-
- Tomahawk::CustomPlaylistView
-
-
- Top Loved Tracks
-
-
-
-
- Your loved tracks
-
-
-
-
- %1's loved tracks
-
-
-
-
- The most loved tracks from all your friends
- 在您所有的朋友中,最受喜愛的曲目
-
-
-
- All of your loved tracks
-
-
-
-
- All of %1's loved tracks
-
-
-
Tomahawk::DropJobNotifier
@@ -2983,7 +3018,7 @@ Try tweaking the filters for a new set of songs to play.
Tomahawk::SpotifyParser
-
+
Error fetching Spotify information from the network!
@@ -2999,7 +3034,7 @@ Try tweaking the filters for a new set of songs to play.
TomahawkApp
-
+
My Collection
我的收藏
@@ -3605,35 +3640,40 @@ 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!
+
+
WelcomeWidget
diff --git a/resources.qrc b/resources.qrc
index 4e39e93b0..f4e960b76 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -45,6 +45,8 @@
data/images/view-toggle-icon-artist-inactive.png
data/images/view-toggle-icon-cloud-active.png
data/images/view-toggle-icon-cloud-inactive.png
+ data/images/view-toggle-icon-grid-active.png
+ data/images/view-toggle-icon-grid-inactive.png
data/images/view-toggle-icon-list-active.png
data/images/view-toggle-icon-list-inactive.png
data/images/view-toggle-inactive-centre.png
diff --git a/src/libtomahawk/AlbumPlaylistInterface.cpp b/src/libtomahawk/AlbumPlaylistInterface.cpp
index d74af3811..e8217186e 100644
--- a/src/libtomahawk/AlbumPlaylistInterface.cpp
+++ b/src/libtomahawk/AlbumPlaylistInterface.cpp
@@ -92,6 +92,31 @@ AlbumPlaylistInterface::hasNextItem()
}
+bool
+AlbumPlaylistInterface::hasPreviousItem()
+{
+ int p = m_currentTrack;
+ p--;
+ if ( p < 0 || p >= m_queries.count() )
+ return false;
+
+ return true;
+}
+
+
+bool
+AlbumPlaylistInterface::setCurrentTrack( unsigned int albumpos )
+{
+ albumpos--;
+ if ( albumpos >= m_queries.count() )
+ return false;
+
+ m_currentTrack = albumpos;
+ m_currentItem = m_queries.at( albumpos )->results().first();
+ return true;
+}
+
+
QList< Tomahawk::query_ptr >
AlbumPlaylistInterface::tracks()
{
@@ -114,6 +139,10 @@ AlbumPlaylistInterface::tracks()
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
+
+ connect( Tomahawk::InfoSystem::InfoSystem::instance(),
+ SIGNAL( finished( QString ) ),
+ SLOT( infoSystemFinished( QString ) ) );
}
else if ( m_mode == DatabaseMode && !m_databaseLoaded )
{
@@ -178,9 +207,24 @@ AlbumPlaylistInterface::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData re
}
}
+ if ( !m_queries.isEmpty() )
+ {
+ infoSystemFinished( id() );
+ }
+}
+
+
+void
+AlbumPlaylistInterface::infoSystemFinished( const QString& infoId )
+{
+ if ( infoId != id() )
+ return;
+
m_infoSystemLoaded = true;
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
this, SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
+ disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ),
+ this, SLOT( infoSystemFinished( QString ) ) );
if ( m_queries.isEmpty() && m_mode == Mixed )
{
diff --git a/src/libtomahawk/AlbumPlaylistInterface.h b/src/libtomahawk/AlbumPlaylistInterface.h
index b2c9d471c..c479b6342 100644
--- a/src/libtomahawk/AlbumPlaylistInterface.h
+++ b/src/libtomahawk/AlbumPlaylistInterface.h
@@ -47,6 +47,7 @@ public:
virtual Tomahawk::result_ptr siblingItem( int itemsAway );
virtual bool hasNextItem();
+ virtual bool hasPreviousItem();
virtual Tomahawk::result_ptr currentItem() const;
virtual PlaylistModes::RepeatMode repeatMode() const { return PlaylistModes::NoRepeat; }
@@ -54,6 +55,7 @@ public:
virtual void setRepeatMode( PlaylistModes::RepeatMode ) {}
virtual void setShuffled( bool ) {}
+ virtual bool setCurrentTrack( unsigned int albumpos );
signals:
void tracksLoaded( Tomahawk::ModelMode mode, const Tomahawk::collection_ptr& collection );
@@ -61,6 +63,7 @@ signals:
private slots:
void onTracksLoaded( const QList< Tomahawk::query_ptr >& tracks );
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
+ void infoSystemFinished( const QString& infoId );
private:
QList< Tomahawk::query_ptr > m_queries;
diff --git a/src/libtomahawk/Artist.cpp b/src/libtomahawk/Artist.cpp
index 6d8dcb9f9..a178dcc77 100644
--- a/src/libtomahawk/Artist.cpp
+++ b/src/libtomahawk/Artist.cpp
@@ -32,6 +32,8 @@
#include
+#define ID_THREAD_DEBUG 0
+
using namespace Tomahawk;
QHash< QString, artist_ptr > Artist::s_artistsByName = QHash< QString, artist_ptr >();
@@ -55,6 +57,9 @@ Artist::get( const QString& name, bool autoCreate )
if ( !Database::instance() || !Database::instance()->impl() )
return artist_ptr();
+#if ID_THREAD_DEBUG
+ qDebug() << "Creating artist:" << name;
+#endif
artist_ptr artist = artist_ptr( new Artist( name ), &QObject::deleteLater );
artist->setWeakRef( artist.toWeakRef() );
artist->loadId( autoCreate );
@@ -274,8 +279,20 @@ Artist::id() const
if ( waiting )
{
+
+#if ID_THREAD_DEBUG
+ qDebug() << Q_FUNC_INFO << "Asked for artist ID and NOT loaded yet" << m_name << m_idFuture.isFinished();
+#endif
+ m_idFuture.waitForFinished();
+#if ID_THREAD_DEBUG
+ qDebug() << "DONE WAITING:" << m_idFuture.resultCount() << m_idFuture.isResultReadyAt(0) << m_idFuture.isCanceled() << m_idFuture.isFinished() << m_idFuture.isPaused() << m_idFuture.isRunning() << m_idFuture.isStarted();
+#endif
finalid = m_idFuture.result();
+#if ID_THREAD_DEBUG
+ qDebug() << Q_FUNC_INFO << "Got loaded artist:" << m_name << finalid;
+#endif
+
s_idMutex.lockForWrite();
m_id = finalid;
m_waitingForFuture = false;
diff --git a/src/libtomahawk/ArtistPlaylistInterface.cpp b/src/libtomahawk/ArtistPlaylistInterface.cpp
index 977edec2c..750c08c4b 100644
--- a/src/libtomahawk/ArtistPlaylistInterface.cpp
+++ b/src/libtomahawk/ArtistPlaylistInterface.cpp
@@ -112,6 +112,10 @@ ArtistPlaylistInterface::tracks()
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
+
+ connect( Tomahawk::InfoSystem::InfoSystem::instance(),
+ SIGNAL( finished( QString ) ),
+ SLOT( infoSystemFinished( QString ) ) );
}
else if ( m_mode == DatabaseMode && !m_databaseLoaded )
{
@@ -176,9 +180,23 @@ ArtistPlaylistInterface::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData r
}
}
+ if ( !m_queries.isEmpty() )
+ infoSystemFinished( id() );
+}
+
+
+void
+ArtistPlaylistInterface::infoSystemFinished( const QString &infoId )
+{
+ if ( infoId != id() )
+ return;
+
m_infoSystemLoaded = true;
+
disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
this, SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
+ disconnect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ),
+ this, SLOT( infoSystemFinished( QString) ) );
if ( m_queries.isEmpty() && m_mode == Mixed )
{
diff --git a/src/libtomahawk/ArtistPlaylistInterface.h b/src/libtomahawk/ArtistPlaylistInterface.h
index 655832d1f..fd8ecf302 100644
--- a/src/libtomahawk/ArtistPlaylistInterface.h
+++ b/src/libtomahawk/ArtistPlaylistInterface.h
@@ -60,6 +60,7 @@ signals:
private slots:
void onTracksLoaded( const QList< Tomahawk::query_ptr >& tracks );
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
+ void infoSystemFinished( const QString& infoId );
private:
Q_DISABLE_COPY( ArtistPlaylistInterface )
diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt
index 0e7fcf2ea..371b4db42 100644
--- a/src/libtomahawk/CMakeLists.txt
+++ b/src/libtomahawk/CMakeLists.txt
@@ -48,6 +48,7 @@ set( libGuiSources
infobar/InfoBar.cpp
+ playlist/FlexibleHeader.cpp
playlist/FlexibleView.cpp
playlist/TreeModel.cpp
playlist/TreeProxyModel.cpp
@@ -66,8 +67,8 @@ set( libGuiSources
playlist/GridItemDelegate.cpp
playlist/GridView.cpp
playlist/TreeView.cpp
- playlist/CustomPlaylistView.cpp
playlist/ViewHeader.cpp
+ playlist/LovedTracksModel.cpp
playlist/RecentlyAddedModel.cpp
playlist/RecentlyPlayedModel.cpp
playlist/PlaylistLargeItemDelegate.cpp
@@ -90,8 +91,6 @@ set( libGuiSources
playlist/dynamic/widgets/CollapsibleControls.cpp
playlist/dynamic/widgets/DynamicSetupWidget.cpp
-
-
ExternalResolverGui.cpp
resolvers/ScriptResolver.cpp
resolvers/QtScriptResolver.cpp
@@ -324,6 +323,7 @@ set( libUI ${libUI}
widgets/infowidgets/AlbumInfoWidget.ui
widgets/infowidgets/TrackInfoWidget.ui
playlist/QueueView.ui
+ playlist/PlaylistHeader.ui
filemetadata/MetadataEditor.ui
context/ContextWidget.ui
infobar/InfoBar.ui
diff --git a/src/libtomahawk/ContextMenu.cpp b/src/libtomahawk/ContextMenu.cpp
index 8092aa00c..b4573d804 100644
--- a/src/libtomahawk/ContextMenu.cpp
+++ b/src/libtomahawk/ContextMenu.cpp
@@ -336,12 +336,12 @@ ContextMenu::onSocialActionsLoaded()
if ( m_queries.isEmpty() || m_queries.first().isNull() )
return;
- if ( m_queries.first()->loved() )
+ if ( m_loveAction && m_queries.first()->loved() )
{
m_loveAction->setText( tr( "Un-&Love" ) );
m_loveAction->setIcon( QIcon( RESPATH "images/not-loved.png" ) );
}
- else
+ else if ( m_loveAction )
{
m_loveAction->setText( tr( "&Love" ) );
m_loveAction->setIcon( QIcon( RESPATH "images/loved.png" ) );
diff --git a/src/libtomahawk/PlaylistInterface.h b/src/libtomahawk/PlaylistInterface.h
index e61b8c60c..3fcd8e6d4 100644
--- a/src/libtomahawk/PlaylistInterface.h
+++ b/src/libtomahawk/PlaylistInterface.h
@@ -47,6 +47,7 @@ public:
virtual Tomahawk::result_ptr currentItem() const = 0;
virtual Tomahawk::result_ptr previousItem();
virtual bool hasNextItem() { return true; }
+ virtual bool hasPreviousItem() { return true; }
virtual Tomahawk::result_ptr nextItem();
virtual Tomahawk::result_ptr siblingItem( int itemsAway ) = 0;
@@ -65,6 +66,8 @@ public:
virtual PlaylistModes::LatchMode latchMode() const { return m_latchMode; }
virtual void setLatchMode( PlaylistModes::LatchMode latchMode ) { m_latchMode = latchMode; }
+ virtual bool setCurrentTrack( unsigned int albumpos ) { Q_UNUSED( albumpos ); return false; }
+
virtual void reset() {}
//TODO: Get rid of the next two functions once all playlsitinterfaces are factored out
diff --git a/src/libtomahawk/ViewManager.cpp b/src/libtomahawk/ViewManager.cpp
index 9893378e6..d247e932b 100644
--- a/src/libtomahawk/ViewManager.cpp
+++ b/src/libtomahawk/ViewManager.cpp
@@ -38,7 +38,6 @@
#include "SourceList.h"
#include "TomahawkSettings.h"
-#include "CustomPlaylistView.h"
#include "PlaylistLargeItemDelegate.h"
#include "RecentlyPlayedModel.h"
#include "dynamic/widgets/DynamicWidget.h"
@@ -76,7 +75,6 @@ ViewManager::ViewManager( QObject* parent )
, m_welcomeWidget( new WelcomeWidget() )
, m_whatsHotWidget( new WhatsHotWidget() )
, m_newReleasesWidget( new NewReleasesWidget() )
- , m_topLovedWidget( 0 )
, m_recentPlaysWidget( 0 )
, m_currentPage( 0 )
, m_loaded( false )
@@ -126,7 +124,6 @@ ViewManager::~ViewManager()
delete m_whatsHotWidget;
delete m_newReleasesWidget;
delete m_welcomeWidget;
- delete m_topLovedWidget;
delete m_recentPlaysWidget;
delete m_contextWidget;
delete m_widget;
@@ -138,13 +135,14 @@ ViewManager::createPageForPlaylist( const playlist_ptr& playlist )
{
FlexibleView* view = new FlexibleView();
PlaylistModel* model = new PlaylistModel();
- view->setPlayableModel( model );
PlaylistView* pv = new PlaylistView();
pv->setPlaylistModel( model );
view->setDetailedView( pv );
+ view->setPixmap( pv->pixmap() );
model->loadPlaylist( playlist );
+ view->setPlayableModel( model );
playlist->resolve();
return view;
@@ -386,40 +384,24 @@ ViewManager::showNewReleasesPage()
}
-Tomahawk::ViewPage*
-ViewManager::showTopLovedPage()
-{
- if ( !m_topLovedWidget )
- {
- CustomPlaylistView* view = new CustomPlaylistView( CustomPlaylistView::TopLovedTracks, source_ptr(), m_widget );
- PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LovedTracks, view, view->proxyModel() );
- connect( del, SIGNAL( updateIndex( QModelIndex ) ), view, SLOT( update( QModelIndex ) ) );
- view->setItemDelegate( del );
-
- m_topLovedWidget = view;
- }
-
- return show( m_topLovedWidget );
-}
-
-
Tomahawk::ViewPage*
ViewManager::showRecentPlaysPage()
{
if ( !m_recentPlaysWidget )
{
- PlaylistView* pv = new PlaylistView( m_widget );
+ FlexibleView* pv = new FlexibleView( m_widget );
+ pv->setPixmap( QPixmap( RESPATH "images/recently-played.png" ) );
RecentlyPlayedModel* raModel = new RecentlyPlayedModel( pv );
raModel->setTitle( tr( "Recently Played Tracks" ) );
raModel->setDescription( tr( "Recently played tracks from all your friends" ) );
- pv->proxyModel()->setStyle( PlayableProxyModel::Large );
- PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::RecentlyPlayed, pv, pv->proxyModel() );
- connect( del, SIGNAL( updateIndex( QModelIndex ) ), pv, SLOT( update( QModelIndex ) ) );
- pv->setItemDelegate( del );
+ PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::RecentlyPlayed, pv->trackView(), pv->trackView()->proxyModel() );
+ connect( del, SIGNAL( updateIndex( QModelIndex ) ), pv->trackView(), SLOT( update( QModelIndex ) ) );
+ pv->trackView()->setItemDelegate( del );
- pv->setPlaylistModel( raModel );
+ pv->setPlayableModel( raModel );
+ pv->setEmptyTip( tr( "Sorry, we could not find any recent plays!" ) );
raModel->setSource( source_ptr() );
m_recentPlaysWidget = pv;
@@ -904,13 +886,6 @@ ViewManager::newReleasesWidget() const
}
-Tomahawk::ViewPage*
-ViewManager::topLovedWidget() const
-{
- return m_topLovedWidget;
-}
-
-
Tomahawk::ViewPage*
ViewManager::recentPlaysWidget() const
{
diff --git a/src/libtomahawk/ViewManager.h b/src/libtomahawk/ViewManager.h
index 5e97bb73f..8d59585e8 100644
--- a/src/libtomahawk/ViewManager.h
+++ b/src/libtomahawk/ViewManager.h
@@ -91,7 +91,6 @@ public:
Tomahawk::ViewPage* welcomeWidget() const;
Tomahawk::ViewPage* whatsHotWidget() const;
Tomahawk::ViewPage* newReleasesWidget() const;
- Tomahawk::ViewPage* topLovedWidget() const;
Tomahawk::ViewPage* recentPlaysWidget() const;
TreeView* superCollectionView() const;
@@ -134,7 +133,6 @@ public slots:
Tomahawk::ViewPage* showWelcomePage();
Tomahawk::ViewPage* showWhatsHotPage();
Tomahawk::ViewPage* showNewReleasesPage();
- Tomahawk::ViewPage* showTopLovedPage();
Tomahawk::ViewPage* showRecentPlaysPage();
void showCurrentTrack();
@@ -195,7 +193,6 @@ private:
WelcomeWidget* m_welcomeWidget;
WhatsHotWidget* m_whatsHotWidget;
NewReleasesWidget* m_newReleasesWidget;
- Tomahawk::ViewPage* m_topLovedWidget;
Tomahawk::ViewPage* m_recentPlaysWidget;
QList< Tomahawk::collection_ptr > m_superCollections;
diff --git a/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp b/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp
index a72b828ea..f330678ea 100644
--- a/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp
+++ b/src/libtomahawk/accounts/spotify/SpotifyAccount.cpp
@@ -62,6 +62,15 @@ static QString s_resolverId = "spotify-linux-x86";
static QString s_resolverId = "spotify-unknown";
#endif
+
+namespace {
+enum ActionType {
+ Sync = 0,
+ Subscribe
+};
+}
+
+
Account*
SpotifyAccountFactory::createAccount( const QString& accountId )
{
@@ -79,6 +88,14 @@ SpotifyAccountFactory::icon() const
}
+SpotifyAccount* SpotifyAccount::s_instance = 0;
+
+SpotifyAccount*
+SpotifyAccount::instance()
+{
+ return s_instance;
+}
+
SpotifyAccount::SpotifyAccount( const QString& accountId )
: CustomAtticaAccount( accountId )
, m_preventEnabling( false )
@@ -424,44 +441,126 @@ SpotifyAccount::aboutToShow( QAction* action, const playlist_ptr& playlist )
// If it's not being synced, allow the option to sync
bool found = false;
+ bool canSubscribe = false;
+ bool isSubscribed = false;
bool manuallyDisabled = false;
+ bool sync = false;
+ action->setVisible( true );
+
QList updaters = playlist->updaters();
foreach ( PlaylistUpdaterInterface* updater, updaters )
{
if ( SpotifyPlaylistUpdater* spotifyUpdater = qobject_cast< SpotifyPlaylistUpdater* >( updater ) )
{
found = true;
- if ( !spotifyUpdater->sync() )
+
+ canSubscribe = spotifyUpdater->canSubscribe();
+ isSubscribed = spotifyUpdater->subscribed();
+
+ if ( !canSubscribe && !spotifyUpdater->sync() )
manuallyDisabled = true;
+ if ( spotifyUpdater->sync() )
+ sync = true;
+
}
}
- if ( !found )
+ const ActionType actionType = static_cast< ActionType >( action->data().toInt() );
+
+ if ( actionType == Sync )
{
- action->setText( tr( "Sync with Spotify" ) );
+ if ( !found )
+ {
+ action->setText( tr( "Sync with Spotify" ) );
+ }
+ else if ( manuallyDisabled )
+ {
+ action->setText( tr( "Re-enable syncing with Spotify" ) );
+ }
+ else
+ {
+ // We dont want to sync a subscribeable playlist but if a playlist isnt
+ // collaborative, he will loose his changes on next update, thus,
+ // we create a new copy of it
+ if ( canSubscribe )
+ action->setText( tr( "Create local copy") );
+ else if ( sync )
+ action->setText( tr( "Stop syncing with Spotify" ) );
+ else
+ action->setVisible( false );
+ }
}
- else if ( manuallyDisabled )
+
+ // User can sync or subscribe on playlist.
+ // Sync means creating a new copy of it, subscribe is listening on changes from owner
+ if ( actionType == Subscribe )
{
- action->setText( tr( "Re-enable syncing with Spotify" ) );
- }
- else
- {
- action->setText( tr( "Stop syncing with Spotify" ) );
+ if ( found && canSubscribe )
+ {
+ if ( !isSubscribed )
+ {
+ action->setText( tr( "Subscribe to playlist changes" ) );
+ }
+ else if ( manuallyDisabled )
+ {
+ action->setText( tr( "Re-enable playlist subscription" ) );
+ }
+ else if ( isSubscribed )
+ {
+ action->setText( tr( "Stop subscribing to changes" ) );
+ }
+ else
+ {
+ // Hide the action, we dont have this option on the playlist
+ action->setVisible( false );
+ }
+ }
+ else
+ {
+ action->setVisible( false );
+ }
}
}
void
-SpotifyAccount::syncActionTriggered( bool checked )
+SpotifyAccount::subscribeActionTriggered( bool )
{
- Q_UNUSED( checked );
- QAction* action = qobject_cast< QAction* >( sender() );
+ const playlist_ptr playlist = playlistFromAction( qobject_cast< QAction* >( sender() ) );
- if ( !action || !m_customActions.contains( action ) )
+ if ( playlist.isNull() )
+ {
+ qWarning() << "Got context menu spotify sync action triggered, but invalid playlist payload!";
+ Q_ASSERT( false );
+ return;
+ }
+
+ SpotifyPlaylistUpdater* updater = 0;
+ QList updaters = playlist->updaters();
+ foreach ( PlaylistUpdaterInterface* u, updaters )
+ {
+ if ( SpotifyPlaylistUpdater* spotifyUpdater = qobject_cast< SpotifyPlaylistUpdater* >( u ) )
+ {
+ updater = spotifyUpdater;
+ break;
+ }
+ }
+
+ Q_ASSERT( updater );
+ if ( !updater )
return;
- const playlist_ptr playlist = action->property( "payload" ).value< playlist_ptr >();
+ // Toggle subscription status
+ setSubscribedForPlaylist( playlist, !updater->subscribed() );
+}
+
+
+void
+SpotifyAccount::syncActionTriggered( bool )
+{
+ const playlist_ptr playlist = playlistFromAction( qobject_cast< QAction* >( sender() ) );
+
if ( playlist.isNull() )
{
qWarning() << "Got context menu spotify sync action triggered, but invalid playlist payload!";
@@ -479,12 +578,16 @@ SpotifyAccount::syncActionTriggered( bool checked )
}
}
- if ( !updater )
+ if ( !updater || updater->canSubscribe() )
{
QVariantMap msg;
msg[ "_msgtype" ] = "createPlaylist";
msg[ "sync" ] = true;
- msg[ "title" ] = playlist->title();
+
+ if ( !updater )
+ msg[ "title" ] = playlist->title();
+ else
+ msg[ "title" ] = "Copy of " + playlist->title();
QList< query_ptr > queries;
foreach ( const plentry_ptr& ple, playlist->entries() )
@@ -492,27 +595,24 @@ SpotifyAccount::syncActionTriggered( bool checked )
QVariantList tracks = SpotifyPlaylistUpdater::queriesToVariant( queries );
msg[ "tracks" ] = tracks;
- const QString qid = sendMessage( msg, this, "playlistCreated" );
+ QString qid;
+ if ( !updater )
+ qid = sendMessage( msg, this, "playlistCreated" );
+ else
+ qid = sendMessage( msg, this, "playlistCopyCreated" );
+
m_waitingForCreateReply[ qid ] = playlist;
}
else
{
- SpotifyPlaylistInfo* info = 0;
- foreach ( SpotifyPlaylistInfo* ifo, m_allSpotifyPlaylists )
- {
- if ( ifo->plid == updater->spotifyId() )
- {
- info = ifo;
- break;
- }
- }
+ SpotifyPlaylistInfo* info = m_allSpotifyPlaylists.value( updater->spotifyId(), 0 );
Q_ASSERT( info );
if ( info )
info->sync = !updater->sync();
if ( m_configWidget.data() )
- m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists );
+ m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists.values() );
if ( !updater->sync() )
{
@@ -526,6 +626,75 @@ SpotifyAccount::syncActionTriggered( bool checked )
}
+void
+SpotifyAccount::setSubscribedForPlaylist( const playlist_ptr& playlist, bool subscribed )
+{
+ SpotifyPlaylistUpdater* updater = 0;
+ QList updaters = playlist->updaters();
+ foreach ( PlaylistUpdaterInterface* u, updaters )
+ {
+ if ( SpotifyPlaylistUpdater* spotifyUpdater = qobject_cast< SpotifyPlaylistUpdater* >( u ) )
+ {
+ updater = spotifyUpdater;
+ break;
+ }
+ }
+
+ if ( !updater )
+ {
+ tLog() << "No SpotifyPlaylistUpdater in payload slot of triggered action! Uh oh!!";
+ return;
+ }
+
+ SpotifyPlaylistInfo* info = m_allSpotifyPlaylists.value( updater->spotifyId(), 0 );
+
+ // When we unsubscribe, all playlists is resent
+ // and we will could loose the SpotifyPlaylistInfo, but all we really need is the id
+ if ( updater->spotifyId().isEmpty() )
+ {
+ tLog() << "No spotify id in updater, WTF?";
+ return;
+ }
+
+ if ( !info )
+ {
+ info = new SpotifyPlaylistInfo( playlist->title(),
+ updater->spotifyId(),
+ updater->spotifyId(),
+ false,
+ false
+ );
+
+ registerPlaylistInfo( info );
+ }
+
+ info->subscribed = subscribed;
+ info->sync = subscribed;
+
+ QVariantMap msg;
+ msg[ "_msgtype" ] = "setSubscription";
+ msg[ "subscribe" ] = info->subscribed;
+ msg[ "playlistid" ] = info->plid;
+
+ sendMessage( msg, this );
+
+ updater->setSync( subscribed );
+ updater->setSubscribed( subscribed );
+}
+
+
+playlist_ptr
+SpotifyAccount::playlistFromAction( QAction* action ) const
+{
+ Q_ASSERT( action );
+
+ if ( !action || !m_customActions.contains( action ) )
+ return playlist_ptr();
+
+ return action->property( "payload" ).value< playlist_ptr >();
+}
+
+
void
SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg )
{
@@ -564,13 +733,17 @@ 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 );
- QMetaObject::invokeMethod( receiver, slot.toLatin1(), Q_ARG( QString, msgType ), Q_ARG( QVariantMap, msg ) );
+ QMetaObject::invokeMethod( receiver, slot.toLatin1(), Q_ARG( QString, msgType ), Q_ARG( QVariantMap, msg ), Q_ARG( QVariant, extraData ) );
}
else if ( msgType == "allPlaylists" )
{
const QVariantList playlists = msg.value( "playlists" ).toList();
- qDeleteAll( m_allSpotifyPlaylists );
+ qDeleteAll( m_allSpotifyPlaylists.values() );
m_allSpotifyPlaylists.clear();
foreach ( const QVariant& playlist, playlists )
@@ -580,18 +753,20 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
const QString plid = plMap.value( "id" ).toString();
const QString revid = plMap.value( "revid" ).toString();
const bool sync = plMap.value( "sync" ).toBool();
+ const bool subscribed = plMap.value( "subscribed" ).toBool();
if ( name.isNull() || plid.isNull() || revid.isNull() )
{
qDebug() << "Did not get name and plid and revid for spotify playlist:" << name << plid << revid << plMap;
continue;
}
- m_allSpotifyPlaylists << new SpotifyPlaylistInfo( name, plid, revid, sync );
+
+ registerPlaylistInfo( new SpotifyPlaylistInfo( name, plid, revid, sync, subscribed ) );
}
if ( !m_configWidget.isNull() )
{
- m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists );
+ m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists.values() );
}
}
else if ( msgType == "tracksAdded" )
@@ -655,7 +830,7 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
updater->spotifyTracksMoved( tracksList, newStartPos, newRev, oldRev );
}
- else if( msgType == "playlistRenamed" )
+ else if ( msgType == "playlistRenamed" )
{
const QString plid = msg.value( "id" ).toString();
// We should already be syncing this playlist if we get updates for it
@@ -675,18 +850,18 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
updater->spotifyPlaylistRenamed( title, newRev, oldRev );
}
- else if( msgType == "spotifyError" )
+ else if ( msgType == "spotifyError" )
{
const QString error = msg.value( "msg" ).toString();
- if( error.isEmpty() )
+ if ( error.isEmpty() )
return;
- if( msg.value( "isDebugMsg" ).toBool() )
+ if ( msg.value( "isDebugMsg" ).toBool() )
tDebug( LOGVERBOSE ) << "SpotifyResolverError: " << error;
else
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( QString( "Spotify: %1" ).arg( error ) ) );
}
- else if( msgType == "userChanged" )
+ else if ( msgType == "userChanged" )
{
const QString rmsg = msg.value( "msg" ).toString();
clearUser( true );
@@ -710,8 +885,10 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
m_loggedIn = success;
if ( success )
+ {
createActions();
-
+ s_instance = this;
+ }
configurationWidget(); // ensure it's created so we can set the login button
if ( m_configWidget.data() )
{
@@ -737,7 +914,10 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
qDebug() << "Got status message with login info:" << loggedIn << username;
if ( !loggedIn || username.isEmpty() || credentials().value( "username").toString() != username )
+ {
m_loggedIn = false;
+ s_instance = 0;
+ }
QVariantMap msg;
msg[ "_msgtype" ] = "status";
@@ -762,7 +942,7 @@ SpotifyAccount::clearUser( bool permanentlyDelete )
m_updaters.clear();
- qDeleteAll( m_allSpotifyPlaylists );
+ qDeleteAll( m_allSpotifyPlaylists.values() );
m_allSpotifyPlaylists.clear();
m_qidToSlotMap.clear();
@@ -790,7 +970,7 @@ SpotifyAccount::configurationWidget()
m_configWidget = QWeakPointer< SpotifyAccountConfig >( new SpotifyAccountConfig( this ) );
connect( m_configWidget.data(), SIGNAL( login( QString,QString ) ), this, SLOT( login( QString,QString ) ) );
connect( m_configWidget.data(), SIGNAL( logout() ), this, SLOT( logout() ) );
- m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists );
+ m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists.values() );
}
if ( m_spotifyResolver.isNull() || !m_spotifyResolver.data()->running() )
@@ -847,7 +1027,7 @@ SpotifyAccount::saveConfig()
setConfiguration( config );
m_configWidget.data()->saveSettings();
- foreach ( SpotifyPlaylistInfo* pl, m_allSpotifyPlaylists )
+ foreach ( SpotifyPlaylistInfo* pl, m_allSpotifyPlaylists.values() )
{
// qDebug() << "Checking changed state:" << pl->changed << pl->name << pl->sync;
if ( pl->changed )
@@ -892,6 +1072,7 @@ SpotifyAccount::logout()
QVariantMap msg;
msg[ "_msgtype" ] = "logout";
m_spotifyResolver.data()->sendMessage( msg );
+ s_instance = 0;
}
@@ -911,7 +1092,7 @@ SpotifyAccount::startPlaylistSync( SpotifyPlaylistInfo* playlist )
void
-SpotifyAccount::startPlaylistSyncWithPlaylist( const QString& msgType, const QVariantMap& msg )
+SpotifyAccount::startPlaylistSyncWithPlaylist( const QString& msgType, const QVariantMap& msg, const QVariant& )
{
Q_UNUSED( msgType );
qDebug() << Q_FUNC_INFO << "Got full spotify playlist body, creating a tomahawk playlist and enabling sync!!";
@@ -957,9 +1138,39 @@ SpotifyAccount::startPlaylistSyncWithPlaylist( const QString& msgType, const QVa
}
}
+void
+SpotifyAccount::playlistCopyCreated( const QString& msgType, const QVariantMap& msg, const QVariant& )
+{
+ Q_UNUSED( msgType );
+
+ qDebug() << Q_FUNC_INFO << "Got response from our createCopyPlaylist command, now creating updater and attaching";
+ const bool success = msg.value( "success" ).toBool();
+
+ if ( !success )
+ {
+ qWarning() << "Got FAILED return code from spotify resolver createPlaylist command, aborting sync";
+ return;
+ }
+
+ const QString id = msg.value( "playlistid" ).toString();
+ const QString revid = msg.value( "playlistid" ).toString();
+ const QString qid = msg.value( "qid" ).toString();
+ const QString title = msg.value( "playlistname" ).toString();
+
+ qDebug() << msg;
+ if ( !m_waitingForCreateReply.contains( qid ) )
+ {
+ qWarning() << "Got a createPlaylist reply for a playlist/qid we were not waiting for :-/ " << qid << m_waitingForCreateReply;
+ return;
+ }
+
+ SpotifyPlaylistInfo *info = new SpotifyPlaylistInfo( title, id, revid, true, false );
+ startPlaylistSync( info );
+}
+
void
-SpotifyAccount::playlistCreated( const QString& msgType, const QVariantMap& msg )
+SpotifyAccount::playlistCreated( const QString& msgType, const QVariantMap& msg, const QVariant& )
{
Q_UNUSED( msgType );
@@ -990,20 +1201,20 @@ SpotifyAccount::playlistCreated( const QString& msgType, const QVariantMap& msg
QString
-SpotifyAccount::sendMessage( const QVariantMap &m, QObject* obj, const QString& slot )
+SpotifyAccount::sendMessage( const QVariantMap &m, QObject* obj, const QString& slot, const QVariant& extraData )
{
QVariantMap msg = m;
- QString qid;
+ const QString qid = uuid();
if ( obj )
{
- qid = QUuid::createUuid().toString().replace( "{", "" ).replace( "}", "" );
-
m_qidToSlotMap[ qid ] = qMakePair( obj, slot );
msg[ "qid" ] = qid;
}
+ m_qidToExtraData[ qid ] = extraData;
+
m_spotifyResolver.data()->sendMessage( msg );
return qid;
@@ -1016,6 +1227,18 @@ SpotifyAccount::registerUpdaterForPlaylist( const QString& plId, SpotifyPlaylist
m_updaters[ plId ] = updater;
}
+void
+SpotifyAccount::registerPlaylistInfo( const QString& name, const QString& plid, const QString &revid, const bool sync, const bool subscribed )
+{
+ m_allSpotifyPlaylists[ plid ] = new SpotifyPlaylistInfo( name, plid, revid, sync, subscribed );
+}
+
+void
+SpotifyAccount::registerPlaylistInfo( SpotifyPlaylistInfo* info )
+{
+ m_allSpotifyPlaylists[ info->plid ] = info;
+}
+
void
SpotifyAccount::unregisterUpdater( const QString& plid )
@@ -1051,6 +1274,7 @@ SpotifyAccount::stopPlaylistSync( SpotifyPlaylistInfo* playlist, bool forceDontD
if ( m_updaters.contains( playlist->plid ) )
{
+
SpotifyPlaylistUpdater* updater = m_updaters[ playlist->plid ];
updater->setSync( false );
@@ -1084,14 +1308,14 @@ SpotifyAccount::loadPlaylists()
void
SpotifyAccount::setSyncForPlaylist( const QString& spotifyPlaylistId, bool sync )
{
- foreach ( SpotifyPlaylistInfo* info, m_allSpotifyPlaylists )
- {
- if( info->plid == spotifyPlaylistId )
- info->sync = sync;
- }
+ SpotifyPlaylistInfo* info = m_allSpotifyPlaylists.value( spotifyPlaylistId, 0 );
+
+ if ( info )
+ info->sync = sync;
+
if ( !m_configWidget.isNull() )
- m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists );
+ m_configWidget.data()->setPlaylists( m_allSpotifyPlaylists.values() );
}
@@ -1101,11 +1325,20 @@ SpotifyAccount::createActions()
if ( !m_customActions.isEmpty() )
return;
- QAction* action = new QAction( 0 );
- action->setIcon( QIcon( RESPATH "images/spotify-logo.png" ) );
- connect( action, SIGNAL( triggered( bool ) ), this, SLOT( syncActionTriggered( bool ) ) );
- ActionCollection::instance()->addAction( ActionCollection::LocalPlaylists, action, this );
- m_customActions.append( action );
+ QAction* syncAction = new QAction( 0 );
+ syncAction->setIcon( QIcon( RESPATH "images/spotify-logo.png" ) );
+ connect( syncAction, SIGNAL( triggered( bool ) ), this, SLOT( syncActionTriggered( bool ) ) );
+ ActionCollection::instance()->addAction( ActionCollection::LocalPlaylists, syncAction, this );
+ syncAction->setData( Sync);
+ m_customActions.append( syncAction );
+
+ QAction* subscribeAction = new QAction( 0 );
+ subscribeAction->setIcon( QIcon( RESPATH "images/spotify-logo.png" ) );
+ connect( subscribeAction, SIGNAL( triggered( bool ) ), this, SLOT( subscribeActionTriggered( bool ) ) );
+ ActionCollection::instance()->addAction( ActionCollection::LocalPlaylists, subscribeAction, this );
+ subscribeAction->setData( Subscribe );
+ m_customActions.append( subscribeAction );
+
}
diff --git a/src/libtomahawk/accounts/spotify/SpotifyAccount.h b/src/libtomahawk/accounts/spotify/SpotifyAccount.h
index e524baed4..c31bcff2d 100644
--- a/src/libtomahawk/accounts/spotify/SpotifyAccount.h
+++ b/src/libtomahawk/accounts/spotify/SpotifyAccount.h
@@ -36,6 +36,8 @@ class ScriptResolver;
namespace Tomahawk {
+class SpotifyParser;
+
namespace InfoSystem
{
class SpotifyInfoPlugin;
@@ -48,11 +50,11 @@ class SpotifyAccountConfig;
// metadata for a playlist
struct SpotifyPlaylistInfo {
QString name, plid, revid;
- bool sync, changed;
+ bool sync, subscribed, changed;
- SpotifyPlaylistInfo( const QString& nname, const QString& pid, const QString& rrevid, bool ssync )
- : name( nname ), plid( pid ), revid( rrevid ), sync( ssync ), changed( false ) {}
+ SpotifyPlaylistInfo( const QString& nname, const QString& pid, const QString& rrevid, bool ssync, bool ssubscribed )
+ : name( nname ), plid( pid ), revid( rrevid ), sync( ssync ), subscribed( ssubscribed ), changed( false ) {}
SpotifyPlaylistInfo() : sync( false ), changed( false ) {}
};
@@ -83,7 +85,7 @@ public:
SpotifyAccount( const QString& accountId );
SpotifyAccount( const QString& accountId, const QString& path );
virtual ~SpotifyAccount();
-
+ static SpotifyAccount* instance();
virtual QPixmap icon() const;
virtual QWidget* configurationWidget();
virtual QWidget* aboutWidget();
@@ -99,9 +101,10 @@ public:
virtual SipPlugin* sipPlugin() { return 0; }
virtual bool preventEnabling() const { return m_preventEnabling; }
- QString sendMessage( const QVariantMap& msg, QObject* receiver = 0, const QString& slot = QString() );
void registerUpdaterForPlaylist( const QString& plId, SpotifyPlaylistUpdater* updater );
+ void registerPlaylistInfo( const QString& name, const QString& plid, const QString &revid, const bool sync, const bool subscribed );
+ void registerPlaylistInfo( SpotifyPlaylistInfo* info );
void unregisterUpdater( const QString& plid );
bool deleteOnUnsync() const;
@@ -111,8 +114,11 @@ public:
bool loggedIn() const;
public slots:
+ QString sendMessage( const QVariantMap& msg, QObject* receiver = 0, const QString& slot = QString(), const QVariant& extraData = QVariant() );
+
void aboutToShow( QAction* action, const Tomahawk::playlist_ptr& playlist );
void syncActionTriggered( bool );
+ void subscribeActionTriggered( bool );
void atticaLoaded(Attica::Content::List);
private slots:
@@ -125,10 +131,10 @@ private slots:
void logout();
// SpotifyResolver message handlers, all take msgtype, msg as argument
- // void ( const QString& msgType, const QVariantMap& msg );
- void startPlaylistSyncWithPlaylist( const QString& msgType, const QVariantMap& msg );
- void playlistCreated( const QString& msgType, const QVariantMap& msg );
-
+ // void ( const QString& msgType, const QVariantMap& msg, const QVariant& extraData );
+ void startPlaylistSyncWithPlaylist( const QString& msgType, const QVariantMap& msg, const QVariant& extraData );
+ void playlistCreated( const QString& msgType, const QVariantMap& msg, const QVariant& extraData );
+ void playlistCopyCreated( const QString& msgType, const QVariantMap& msg, const QVariant& extraData );
void delayedInit();
void hookupAfterDeletion( bool autoEnable );
@@ -146,9 +152,13 @@ private:
void fetchFullPlaylist( SpotifyPlaylistInfo* playlist );
void setSyncForPlaylist( const QString& spotifyPlaylistId, bool sync );
+ void setSubscribedForPlaylist( const playlist_ptr& pl, bool subscribed );
void createActions();
void removeActions();
+ playlist_ptr playlistFromAction( QAction* action ) const;
+
+ static SpotifyAccount* s_instance;
QWeakPointer m_configWidget;
QWeakPointer m_aboutWidget;
@@ -156,9 +166,10 @@ private:
QWeakPointer< InfoSystem::SpotifyInfoPlugin > m_infoPlugin;
QMap > m_qidToSlotMap;
+ QMap m_qidToExtraData;
// List of synced spotify playlists in config UI
- QList< SpotifyPlaylistInfo* > m_allSpotifyPlaylists;
+ QHash< QString, SpotifyPlaylistInfo* > m_allSpotifyPlaylists;
QHash< QString, SpotifyPlaylistUpdater* > m_updaters;
QHash< QString, playlist_ptr > m_waitingForCreateReply;
@@ -167,6 +178,7 @@ private:
SmartPointerList< QAction > m_customActions;
friend class ::SpotifyPlaylistUpdater;
+ friend class Tomahawk::SpotifyParser;
};
}
diff --git a/src/libtomahawk/accounts/spotify/SpotifyAccountConfig.cpp b/src/libtomahawk/accounts/spotify/SpotifyAccountConfig.cpp
index a91890abf..ec57e12e2 100644
--- a/src/libtomahawk/accounts/spotify/SpotifyAccountConfig.cpp
+++ b/src/libtomahawk/accounts/spotify/SpotifyAccountConfig.cpp
@@ -41,6 +41,8 @@ SpotifyAccountConfig::SpotifyAccountConfig( SpotifyAccount *account )
{
m_ui->setupUi( this );
+ m_ui->loginButton->setDefault( true );
+
connect( m_ui->loginButton, SIGNAL( clicked( bool ) ), this, SLOT( doLogin() ) );
connect( m_ui->usernameEdit, SIGNAL( textEdited( QString ) ), this, SLOT( resetLoginButton() ) );
diff --git a/src/libtomahawk/accounts/spotify/SpotifyInfoPlugin.cpp b/src/libtomahawk/accounts/spotify/SpotifyInfoPlugin.cpp
index 297b93fe2..b16e24351 100644
--- a/src/libtomahawk/accounts/spotify/SpotifyInfoPlugin.cpp
+++ b/src/libtomahawk/accounts/spotify/SpotifyInfoPlugin.cpp
@@ -103,9 +103,10 @@ SpotifyInfoPlugin::notInCacheSlot( InfoStringHash criteria, InfoRequestData requ
message[ "artist" ] = artist;
message[ "album" ] = album;
- const QString qid = m_account.data()->sendMessage( message, this, "albumListingResult" );
-
- m_waitingForResults[ qid ] = requestData;
+ QMetaObject::invokeMethod( m_account.data(), "sendMessage", Qt::QueuedConnection, Q_ARG( QVariantMap, message ),
+ Q_ARG( QObject*, this ),
+ Q_ARG( QString, "albumListingResult" ),
+ Q_ARG( QVariant, QVariant::fromValue< InfoRequestData >( requestData ) ) );
}
break;
}
@@ -119,15 +120,12 @@ SpotifyInfoPlugin::notInCacheSlot( InfoStringHash criteria, InfoRequestData requ
void
-SpotifyInfoPlugin::albumListingResult( const QString& msgType, const QVariantMap& msg )
+SpotifyInfoPlugin::albumListingResult( const QString& msgType, const QVariantMap& msg, const QVariant& extraData )
{
Q_ASSERT( msg.contains( "qid" ) );
- Q_ASSERT( m_waitingForResults.contains( msg.value( "qid" ).toString() ) );
+ Q_ASSERT( extraData.canConvert< InfoRequestData >() );
- if ( !msg.contains( "qid" ) || !m_waitingForResults.contains( msg.value( "qid" ).toString() ) )
- return;
-
- const InfoRequestData requestData = m_waitingForResults.take( msg.value( "qid" ).toString() );
+ const InfoRequestData requestData = extraData.value< InfoRequestData >();
QVariantList tracks = msg.value( "tracks" ).toList();
QStringList trackNameList;
diff --git a/src/libtomahawk/accounts/spotify/SpotifyInfoPlugin.h b/src/libtomahawk/accounts/spotify/SpotifyInfoPlugin.h
index fafc0cead..97c0b96ad 100644
--- a/src/libtomahawk/accounts/spotify/SpotifyInfoPlugin.h
+++ b/src/libtomahawk/accounts/spotify/SpotifyInfoPlugin.h
@@ -46,7 +46,7 @@ public:
virtual ~SpotifyInfoPlugin();
public slots:
- void albumListingResult( const QString& msgType, const QVariantMap& msg );
+ void albumListingResult( const QString& msgType, const QVariantMap& msg, const QVariant& extraData );
protected slots:
virtual void init() {}
@@ -62,8 +62,6 @@ private:
void dataError( InfoRequestData );
void trackListResult( const QStringList& trackNameList, const Tomahawk::InfoSystem::InfoRequestData& requestData );
- QHash< QString, InfoRequestData > m_waitingForResults;
-
QWeakPointer< Tomahawk::Accounts::SpotifyAccount > m_account;
};
diff --git a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp
index 43ee8cf70..e2c4ab252 100644
--- a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp
+++ b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.cpp
@@ -1,6 +1,7 @@
/* === This file is part of Tomahawk Player - ===
*
* 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
@@ -57,10 +58,14 @@ SpotifyUpdaterFactory::create( const Tomahawk::playlist_ptr& pl, const QVariantH
const QString spotifyId = settings.value( "spotifyId" ).toString();
const QString latestRev = settings.value( "latestrev" ).toString();
const bool sync = settings.value( "sync" ).toBool();
+ const bool canSubscribe = settings.value( "canSubscribe" ).toBool();
+ const bool isSubscribed = settings.value( "subscribed" ).toBool();
Q_ASSERT( !spotifyId.isEmpty() );
SpotifyPlaylistUpdater* updater = new SpotifyPlaylistUpdater( m_account.data(), latestRev, spotifyId, pl );
updater->setSync( sync );
+ updater->setCanSubscribe( canSubscribe );
+ updater->setSubscribed( isSubscribed );
m_account.data()->registerUpdaterForPlaylist( spotifyId, updater );
return updater;
@@ -74,6 +79,8 @@ SpotifyPlaylistUpdater::SpotifyPlaylistUpdater( SpotifyAccount* acct, const QStr
, m_spotifyId( spotifyId )
, m_blockUpdatesForNextRevision( false )
, m_sync( false )
+ , m_canSubscribe( false )
+ , m_subscribed( false )
{
init();
}
@@ -126,12 +133,18 @@ SpotifyPlaylistUpdater::remove( bool askToDeletePlaylist )
void
SpotifyPlaylistUpdater::aboutToDelete()
{
- if ( m_sync )
+ if ( QThread::currentThread() != QApplication::instance()->thread() )
+ QMetaObject::invokeMethod( const_cast(this), "aboutToDelete", Qt::BlockingQueuedConnection );
+ else
{
- if ( QThread::currentThread() != QApplication::instance()->thread() )
- QMetaObject::invokeMethod( const_cast(this), "checkDeleteDialog", Qt::BlockingQueuedConnection );
- else
- checkDeleteDialog();
+ if ( m_subscribed )
+ {
+ m_spotify.data()->setSubscribedForPlaylist( playlist(), false );
+ }
+ else if ( m_sync )
+ {
+ checkDeleteDialog();
+ }
}
}
@@ -177,6 +190,8 @@ SpotifyPlaylistUpdater::saveToSettings()
s[ "latestrev" ] = m_latestRev;
s[ "sync" ] = m_sync;
+ s[ "canSubscribe" ] = m_canSubscribe;
+ s[ "subscribed" ] = m_subscribed;
s[ "spotifyId" ] = m_spotifyId;
saveSettings( s );
@@ -227,6 +242,45 @@ SpotifyPlaylistUpdater::sync() const
return m_sync;
}
+void
+SpotifyPlaylistUpdater::setSubscribed( bool subscribed )
+{
+ if ( m_subscribed == subscribed )
+ return;
+
+ m_subscribed = subscribed;
+ setSync( subscribed );
+ saveToSettings();
+ emit changed();
+}
+
+
+bool
+SpotifyPlaylistUpdater::subscribed() const
+{
+ return m_subscribed;
+}
+
+
+void
+SpotifyPlaylistUpdater::setCanSubscribe( bool canSubscribe )
+{
+ if ( m_canSubscribe == canSubscribe )
+ return;
+
+ m_canSubscribe = canSubscribe;
+
+ saveToSettings();
+ emit changed();
+}
+
+
+bool
+SpotifyPlaylistUpdater::canSubscribe() const
+{
+ return m_canSubscribe;
+}
+
void
SpotifyPlaylistUpdater::spotifyTracksAdded( const QVariantList& tracks, const QString& startPosId, const QString& newRev, const QString& oldRev )
@@ -353,6 +407,8 @@ SpotifyPlaylistUpdater::tomahawkPlaylistRenamed(const QString &newT, const QStri
msg[ "newTitle" ] = newT;
msg[ "oldTitle" ] = oldT;
msg[ "playlistid" ] = m_spotifyId;
+
+ // TODO check return value
m_spotify.data()->sendMessage( msg, this, "onPlaylistRename" );
}
@@ -493,7 +549,7 @@ SpotifyPlaylistUpdater::plentryToVariant( const QList< plentry_ptr >& entries )
void
-SpotifyPlaylistUpdater::onTracksInsertedReturn( const QString& msgType, const QVariantMap& msg )
+SpotifyPlaylistUpdater::onTracksInsertedReturn( const QString& msgType, const QVariantMap& msg, const QVariant& )
{
const bool success = msg.value( "success" ).toBool();
@@ -577,7 +633,7 @@ SpotifyPlaylistUpdater::tomahawkTracksRemoved( const QList< query_ptr >& tracks
void
-SpotifyPlaylistUpdater::onTracksRemovedReturn( const QString& msgType, const QVariantMap& msg )
+SpotifyPlaylistUpdater::onTracksRemovedReturn( const QString& msgType, const QVariantMap& msg, const QVariant& )
{
const bool success = msg.value( "success" ).toBool();
@@ -626,7 +682,7 @@ SpotifyPlaylistUpdater::tomahawkTracksMoved( const QList< plentry_ptr >& tracks,
void
-SpotifyPlaylistUpdater::onTracksMovedReturn( const QString& msgType, const QVariantMap& msg )
+SpotifyPlaylistUpdater::onTracksMovedReturn( const QString& msgType, const QVariantMap& msg, const QVariant& )
{
const bool success = msg.value( "success" ).toBool();
@@ -678,8 +734,10 @@ SpotifyPlaylistUpdater::variantToQueries( const QVariantList& list )
continue;
if ( trackMap.contains( "id" ) )
+ {
+ q->setResultHint( trackMap.value( "id" ).toString() );
q->setProperty( "annotation", trackMap.value( "id" ) );
-
+ }
queries << q;
}
diff --git a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h
index 896e507d3..b5de8e4b9 100644
--- a/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h
+++ b/src/libtomahawk/accounts/spotify/SpotifyPlaylistUpdater.h
@@ -1,7 +1,8 @@
/* === This file is part of Tomahawk Player - ===
*
* 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
@@ -53,7 +54,10 @@ public:
bool sync() const;
void setSync( bool sync );
-
+ bool subscribed() const;
+ void setSubscribed( bool subscribed );
+ bool canSubscribe() const;
+ void setCanSubscribe( bool canSub );
QString spotifyId() const { return m_spotifyId; }
void remove( bool askToDeletePlaylist = true );
@@ -69,14 +73,13 @@ public slots:
void tomahawkTracksMoved( const QList& ,int );
void tomahawkPlaylistRenamed( const QString&, const QString& );
-protected:
void aboutToDelete();
-
+
private slots:
// SpotifyResolver message handlers, all take msgtype, msg as argument
- void onTracksInsertedReturn( const QString& msgType, const QVariantMap& msg );
- void onTracksRemovedReturn( const QString& msgType, const QVariantMap& msg );
- void onTracksMovedReturn( const QString& msgType, const QVariantMap& msg );
+ 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;
@@ -99,7 +102,8 @@ private:
bool m_blockUpdatesForNextRevision;
bool m_sync;
-
+ bool m_subscribed;
+ bool m_canSubscribe;
QQueue<_detail::Closure*> m_queuedOps;
#ifndef ENABLE_HEADLESS
static QPixmap* s_typePixmap;
diff --git a/src/libtomahawk/audio/AudioEngine.cpp b/src/libtomahawk/audio/AudioEngine.cpp
index 3b7d940ea..e8f07c45c 100644
--- a/src/libtomahawk/audio/AudioEngine.cpp
+++ b/src/libtomahawk/audio/AudioEngine.cpp
@@ -897,6 +897,9 @@ AudioEngine::checkStateQueue()
m_mediaObject->pause();
break;
}
+
+ default:
+ break;
}
}
else
diff --git a/src/libtomahawk/database/IdThreadWorker.cpp b/src/libtomahawk/database/IdThreadWorker.cpp
index a8ff77e14..3e9b3d268 100644
--- a/src/libtomahawk/database/IdThreadWorker.cpp
+++ b/src/libtomahawk/database/IdThreadWorker.cpp
@@ -87,6 +87,7 @@ internalGet( const artist_ptr& artist, const album_ptr& album, bool autoCreate,
item->album = album;
item->type = type;
item->create = autoCreate;
+ item->promise.reportStarted();
return item;
}
diff --git a/src/libtomahawk/filemetadata/MetadataEditor.cpp b/src/libtomahawk/filemetadata/MetadataEditor.cpp
index b881604e6..7611a5737 100644
--- a/src/libtomahawk/filemetadata/MetadataEditor.cpp
+++ b/src/libtomahawk/filemetadata/MetadataEditor.cpp
@@ -29,40 +29,50 @@
#include "Album.h"
#include "Typedefs.h"
#include "ScanManager.h"
+#include "PlaylistInterface.h"
+#include "AlbumPlaylistInterface.h"
#include "taglib/fileref.h"
#include "filemetadata/taghandlers/tag.h"
#include "utils/TomahawkUtils.h"
+#include "utils/Closure.h"
MetadataEditor::MetadataEditor( const Tomahawk::result_ptr& result, QWidget* parent )
: QDialog( parent )
, ui( new Ui::MetadataEditor )
, m_result( result )
+ , m_interface( 0 )
{
ui->setupUi( this );
setWindowTitle( QString( result->track() + tr( " - Properties" ) ) );
setAttribute( Qt::WA_DeleteOnClose );
- setTitle( result->track() );
- setArtist( result->artist()->name() );
- setAlbum( result->album()->name() );
- setDiscNumber( result->albumpos() );
- setDuration( result->duration() );
- setYear( result->year() );
- setBitrate( result->bitrate() );
+ NewClosure( ui->buttonBox, SIGNAL( accepted() ),
+ this, SLOT( writeMetadata( bool ) ), true )->setAutoDelete( false );
- QFileInfo fi( QUrl( m_result->url() ).toLocalFile() );
- setFileName( fi.fileName() );
- setFileSize( TomahawkUtils::filesizeToString( fi.size() ) );
-
- connect( ui->buttonBox, SIGNAL( accepted() ), SLOT( writeMetadata() ) );
connect( ui->buttonBox, SIGNAL( rejected() ), SLOT( close() ) );
+ connect( ui->forwardPushButton, SIGNAL( clicked() ), SLOT( loadNextResult() ) );
+ connect( ui->previousPushButton, SIGNAL( clicked() ), SLOT( loadPreviousResult() ) );
+
+ m_interface = Tomahawk::playlistinterface_ptr( new Tomahawk::AlbumPlaylistInterface(
+ result->album().data(),
+ Tomahawk::DatabaseMode,
+ result->collection() ) );
+ connect( m_interface.data(),
+ SIGNAL( tracksLoaded( Tomahawk::ModelMode,
+ const Tomahawk::collection_ptr& ) ),
+ SLOT( enablePushButtons() ) );
+
+ /* Initiate the interface */
+ m_interface->tracks();
+
+ loadResult( result );
}
void
-MetadataEditor::writeMetadata()
+MetadataEditor::writeMetadata( bool closeDlg )
{
QFileInfo fi( QUrl( m_result->url() ).toLocalFile() );
@@ -102,9 +112,68 @@ MetadataEditor::writeMetadata()
f.save();
- QStringList files = QStringList( fileName );
- ScanManager::instance()->runFileScan( files );
- close();
+ m_editFiles.append( fileName );
+
+ if ( closeDlg ) {
+ ScanManager::instance()->runFileScan( m_editFiles );
+ close();
+ }
+}
+
+
+void
+MetadataEditor::loadResult( const Tomahawk::result_ptr& result )
+{
+ if ( result.isNull() )
+ return;
+
+ m_result = result;
+ setTitle( result->track() );
+ setArtist( result->artist()->name() );
+ setAlbum( result->album()->name() );
+ setDiscNumber( result->albumpos() );
+ setDuration( result->duration() );
+ setYear( result->year() );
+ setBitrate( result->bitrate() );
+
+ QFileInfo fi( QUrl( m_result->url() ).toLocalFile() );
+ setFileName( fi.fileName() );
+ setFileSize( TomahawkUtils::filesizeToString( fi.size() ) );
+
+ enablePushButtons();
+}
+
+
+void MetadataEditor::enablePushButtons()
+{
+ if ( !m_interface->setCurrentTrack( m_result->albumpos() ) )
+ tDebug() << "Error setting current track for MetadataEditor.";
+
+ if ( m_interface->hasNextItem() )
+ ui->forwardPushButton->setEnabled( true );
+ else
+ ui->forwardPushButton->setEnabled( false );
+
+ if ( m_interface->hasPreviousItem() )
+ ui->previousPushButton->setEnabled( true );
+ else
+ ui->previousPushButton->setEnabled( false );
+}
+
+
+void
+MetadataEditor::loadNextResult()
+{
+ writeMetadata();
+ loadResult( m_interface->nextItem() );
+}
+
+
+void
+MetadataEditor::loadPreviousResult()
+{
+ writeMetadata();
+ loadResult( m_interface->previousItem() );
}
diff --git a/src/libtomahawk/filemetadata/MetadataEditor.h b/src/libtomahawk/filemetadata/MetadataEditor.h
index ccd743b92..641ca0049 100644
--- a/src/libtomahawk/filemetadata/MetadataEditor.h
+++ b/src/libtomahawk/filemetadata/MetadataEditor.h
@@ -45,9 +45,13 @@ protected:
int discnumber() const { return ui->discNumberSpinBox->value(); }
int year() const { return ui->yearSpinBox->value(); }
int bitrate() const { return ui->bitrateSpinBox->value(); }
+ void loadResult( const Tomahawk::result_ptr& result );
private slots:
- void writeMetadata();
+ void writeMetadata( bool closeDlg = false );
+ void enablePushButtons();
+ void loadNextResult();
+ void loadPreviousResult();
/* tag attributes */
void setTitle( const QString& title );
@@ -66,6 +70,8 @@ private:
Ui::MetadataEditor* ui;
Tomahawk::result_ptr m_result;
+ Tomahawk::playlistinterface_ptr m_interface;
+ QStringList m_editFiles;
};
#endif // METADATAEDITOR_H
diff --git a/src/libtomahawk/filemetadata/MetadataEditor.ui b/src/libtomahawk/filemetadata/MetadataEditor.ui
index 1ded5959d..1f40bc41b 100644
--- a/src/libtomahawk/filemetadata/MetadataEditor.ui
+++ b/src/libtomahawk/filemetadata/MetadataEditor.ui
@@ -227,7 +227,7 @@
-
-
-
+
false
@@ -237,7 +237,7 @@
-
-
+
false
diff --git a/src/libtomahawk/jobview/JobStatusModel.cpp b/src/libtomahawk/jobview/JobStatusModel.cpp
index 64ec73c05..1744a5d4b 100644
--- a/src/libtomahawk/jobview/JobStatusModel.cpp
+++ b/src/libtomahawk/jobview/JobStatusModel.cpp
@@ -110,7 +110,7 @@ JobStatusModel::~JobStatusModel()
void
JobStatusModel::addJob( JobStatusItem* item )
{
- tLog() << Q_FUNC_INFO << "current jobs of item type: " << m_jobTypeCount[ item->type() ] << ", current queue size of item type: " << m_jobQueue[ item->type() ].size();
+// tLog() << Q_FUNC_INFO << "current jobs of item type: " << m_jobTypeCount[ item->type() ] << ", current queue size of item type: " << m_jobQueue[ item->type() ].size();
if ( item->concurrentJobLimit() > 0 )
{
if ( m_jobTypeCount[ item->type() ] >= item->concurrentJobLimit() )
@@ -123,7 +123,7 @@ JobStatusModel::addJob( JobStatusItem* item )
m_jobTypeCount[ item->type() ] = currentJobCount;
}
- tLog() << Q_FUNC_INFO << "new current jobs of item type: " << m_jobTypeCount[ item->type() ];
+// tLog() << Q_FUNC_INFO << "new current jobs of item type: " << m_jobTypeCount[ item->type() ];
connect( item, SIGNAL( statusChanged() ), SLOT( itemUpdated() ) );
connect( item, SIGNAL( finished() ), SLOT( itemFinished() ) );
@@ -142,7 +142,7 @@ JobStatusModel::addJob( JobStatusItem* item )
}
}
- tLog() << Q_FUNC_INFO << "Adding item:" << item;
+// tLog() << Q_FUNC_INFO << "Adding item:" << item;
int currentEndRow = m_items.count();
beginInsertRows( QModelIndex(), currentEndRow, currentEndRow );
@@ -151,7 +151,7 @@ JobStatusModel::addJob( JobStatusItem* item )
if ( item->hasCustomDelegate() )
{
- tLog() << Q_FUNC_INFO << "job has custom delegate";
+// tLog() << Q_FUNC_INFO << "job has custom delegate";
emit customDelegateJobInserted( currentEndRow, item );
}
@@ -221,7 +221,7 @@ JobStatusModel::rowCount( const QModelIndex& parent ) const
void
JobStatusModel::itemFinished()
{
- tLog( LOGVERBOSE ) << Q_FUNC_INFO;
+// tLog( LOGVERBOSE ) << Q_FUNC_INFO;
JobStatusItem* item = qobject_cast< JobStatusItem* >( sender() );
Q_ASSERT( item );
@@ -278,7 +278,7 @@ JobStatusModel::itemFinished()
emit refreshDelegates();
- tLog() << Q_FUNC_INFO << "current jobs of item type: " << m_jobTypeCount[ item->type() ] << ", current queue size of item type: " << m_jobQueue[ item->type() ].size();
+// tLog() << Q_FUNC_INFO << "current jobs of item type: " << m_jobTypeCount[ item->type() ] << ", current queue size of item type: " << m_jobQueue[ item->type() ].size();
if ( item->concurrentJobLimit() > 0 )
{
int currentJobs = m_jobTypeCount[ item->type() ];
@@ -299,7 +299,7 @@ JobStatusModel::itemFinished()
void
JobStatusModel::itemUpdated()
{
- tLog( LOGVERBOSE ) << Q_FUNC_INFO;
+// tLog( LOGVERBOSE ) << Q_FUNC_INFO;
JobStatusItem* item = qobject_cast< JobStatusItem* >( sender() );
Q_ASSERT( item );
diff --git a/src/libtomahawk/jobview/JobStatusView.cpp b/src/libtomahawk/jobview/JobStatusView.cpp
index 26254ebff..46acc4413 100644
--- a/src/libtomahawk/jobview/JobStatusView.cpp
+++ b/src/libtomahawk/jobview/JobStatusView.cpp
@@ -101,17 +101,14 @@ JobStatusView::setModel( JobStatusSortModel* m )
void
JobStatusView::customDelegateJobInserted( int row, JobStatusItem* item )
{
- tLog() << Q_FUNC_INFO << "item is" << item << ", row is" << row;
if ( !item )
return;
item->createDelegate( m_view );
- tLog() << Q_FUNC_INFO << "item delegate is" << item->customDelegate();
m_view->setItemDelegateForRow( row, item->customDelegate() );
ACLJobDelegate* delegate = qobject_cast< ACLJobDelegate* >( item->customDelegate() );
if ( delegate )
{
- tLog() << Q_FUNC_INFO << "delegate found";
connect( delegate, SIGNAL( update( const QModelIndex& ) ), m_view, SLOT( update( const QModelIndex & ) ) );
connect( delegate, SIGNAL( aclResult( ACLRegistry::ACL ) ), item, SLOT( aclResult( ACLRegistry::ACL ) ) );
delegate->emitSizeHintChanged( m_model->index( row, 0 ) );
@@ -126,7 +123,6 @@ JobStatusView::customDelegateJobInserted( int row, JobStatusItem* item )
void
JobStatusView::customDelegateJobRemoved( int row )
{
- tLog() << Q_FUNC_INFO << "row is" << row;
checkCount();
}
@@ -134,11 +130,9 @@ JobStatusView::customDelegateJobRemoved( int row )
void
JobStatusView::refreshDelegates()
{
- tLog() << Q_FUNC_INFO;
int count = m_model->rowCount();
for ( int i = 0; i < count; i++ )
{
- tLog() << Q_FUNC_INFO << "checking row" << i;
QModelIndex index = m_model->index( i, 0 );
QVariant itemVar = index.data( JobStatusModel::JobDataRole );
if ( !itemVar.canConvert< JobStatusItem* >() || !itemVar.value< JobStatusItem* >() )
diff --git a/src/libtomahawk/playlist/CustomPlaylistView.cpp b/src/libtomahawk/playlist/CustomPlaylistView.cpp
deleted file mode 100644
index f29bac29b..000000000
--- a/src/libtomahawk/playlist/CustomPlaylistView.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/* === This file is part of Tomahawk Player - ===
- *
- * Copyright 2010-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 "CustomPlaylistView.h"
-
-#include "database/DatabaseCommand_GenericSelect.h"
-#include "database/Database.h"
-#include "utils/TomahawkUtils.h"
-#include "SourceList.h"
-#include "audio/AudioEngine.h"
-
-using namespace Tomahawk;
-
-CustomPlaylistView::CustomPlaylistView( CustomPlaylistView::PlaylistType type, const source_ptr& s, QWidget* parent )
- : PlaylistView( parent )
- , m_type( type )
- , m_source( s )
- , m_model( new PlaylistModel( this ) )
-{
- // Generate the tracks, add them to the playlist
- proxyModel()->setStyle( PlayableProxyModel::Large );
-
- setPlaylistModel( m_model );
- generateTracks();
-
- if ( m_type == SourceLovedTracks )
- {
- connect( m_source.data(), SIGNAL( socialAttributesChanged( QString ) ), SLOT( socialAttributesChanged( QString ) ) );
- }
- else if ( m_type == TopLovedTracks )
- {
- connect( SourceList::instance()->getLocal().data(), SIGNAL( socialAttributesChanged( QString ) ), SLOT( socialAttributesChanged( QString ) ) );
- foreach ( const source_ptr& s, SourceList::instance()->sources( true ) )
- connect( s.data(), SIGNAL( socialAttributesChanged( QString ) ), SLOT( socialAttributesChanged( QString ) ) );
-
- connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( sourceAdded( Tomahawk::source_ptr ) ) );
- }
-}
-
-
-CustomPlaylistView::~CustomPlaylistView()
-{
-}
-
-
-bool
-CustomPlaylistView::isBeingPlayed() const
-{
- return AudioEngine::instance()->currentTrackPlaylist() == playlistInterface();
-}
-
-
-bool
-CustomPlaylistView::jumpToCurrentTrack()
-{
- return PlaylistView::jumpToCurrentTrack();
-}
-
-
-void
-CustomPlaylistView::generateTracks()
-{
- m_model->startLoading();
-
- QString sql;
- switch ( m_type )
- {
- // TODO
- case SourceLovedTracks:
- sql = QString( "SELECT track.name, artist.name, COUNT(*) as counter "
- "FROM social_attributes, track, artist "
- "WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND social_attributes.v = 'true' AND social_attributes.source %1 "
- "GROUP BY track.id "
- "ORDER BY counter DESC, social_attributes.timestamp DESC " ).arg( m_source->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_source->id() ) );
- break;
- case TopLovedTracks:
- sql = QString( "SELECT track.name, artist.name, source, COUNT(*) as counter "
- "FROM social_attributes, track, artist "
- "WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND social_attributes.v = 'true' "
- "GROUP BY track.id "
- "ORDER BY counter DESC, social_attributes.timestamp DESC LIMIT 0, 50" );
- break;
- }
-
- DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( sql, DatabaseCommand_GenericSelect::Track, -1, 0 );
- connect( cmd, SIGNAL( tracks( QList ) ), this, SLOT( tracksGenerated( QList ) ) );
- Database::instance()->enqueue( QSharedPointer( cmd ) );
-}
-
-
-void
-CustomPlaylistView::tracksGenerated( QList< query_ptr > tracks )
-{
- bool changed = false;
- QList< query_ptr > newTracks = TomahawkUtils::mergePlaylistChanges( m_model->queries(), tracks, changed );
-
- m_model->finishLoading();
- if ( !changed )
- return;
-
- m_model->clear();
- m_model->appendQueries( newTracks );
-}
-
-
-QString
-CustomPlaylistView::title() const
-{
- if ( m_source.isNull() )
- return tr( "Top Loved Tracks" );
- else
- {
- if ( m_source->isLocal() )
- return tr( "Your loved tracks" );
- else
- return tr( "%1's loved tracks" ).arg( m_source->friendlyName() );
- }
-}
-
-
-QString
-CustomPlaylistView::description() const
-{
- if ( m_source.isNull() )
- return tr( "The most loved tracks from all your friends" );
- else
- {
- if ( m_source->isLocal() )
- return tr( "All of your loved tracks" );
- else
- return tr( "All of %1's loved tracks" ).arg( m_source->friendlyName() );
- }
-}
-
-
-QString
-CustomPlaylistView::longDescription() const
-{
- return QString();
-}
-
-
-QPixmap
-CustomPlaylistView::pixmap() const
-{
- return QPixmap( RESPATH "images/loved_playlist.png" );
-}
-
-
-void
-CustomPlaylistView::socialAttributesChanged( const QString& action )
-{
- if ( action == "Love" )
- {
- generateTracks();
- }
-}
-
-
-void
-CustomPlaylistView::sourceAdded( const source_ptr& s )
-{
- connect( s.data(), SIGNAL( socialAttributesChanged( QString ) ), this, SLOT( socialAttributesChanged( QString ) ) );
-}
diff --git a/src/libtomahawk/playlist/CustomPlaylistView.h b/src/libtomahawk/playlist/CustomPlaylistView.h
deleted file mode 100644
index 8ea0c828a..000000000
--- a/src/libtomahawk/playlist/CustomPlaylistView.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* === This file is part of Tomahawk Player - ===
- *
- * Copyright 2010-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 .
- */
-
-
-#ifndef CUSTOMPLAYLISTVIEW_H
-#define CUSTOMPLAYLISTVIEW_H
-
-#include "PlaylistView.h"
-
-#include "DllMacro.h"
-
-namespace Tomahawk
-{
-
-class DLLEXPORT CustomPlaylistView : public PlaylistView
-{
- Q_OBJECT
-public:
- enum PlaylistType
- {
- SourceLovedTracks,
- TopLovedTracks
- };
-
- explicit CustomPlaylistView( PlaylistType type, const source_ptr& s, QWidget* parent = 0 );
- virtual ~CustomPlaylistView();
-
- virtual bool showFilter() const { return true; }
-
- virtual QString title() const;
- virtual QPixmap pixmap() const;
- virtual QString description() const;
- virtual QString longDescription() const;
-
- virtual bool isTemporaryPage() const { return false; }
- virtual bool isBeingPlayed() const;
- virtual bool jumpToCurrentTrack();
-
-private slots:
- void tracksGenerated( QList tracks );
-
- void socialAttributesChanged( const QString& );
- void sourceAdded( const Tomahawk::source_ptr& );
-
-private:
- void generateTracks();
-
- PlaylistType m_type;
- source_ptr m_source;
- PlaylistModel* m_model;
-};
-
-}
-
-#endif // CUSTOMPLAYLISTVIEW_H
diff --git a/src/libtomahawk/playlist/FlexibleHeader.cpp b/src/libtomahawk/playlist/FlexibleHeader.cpp
new file mode 100644
index 000000000..e58a2ea02
--- /dev/null
+++ b/src/libtomahawk/playlist/FlexibleHeader.cpp
@@ -0,0 +1,156 @@
+/* === This file is part of Tomahawk Player - ===
+ *
+ * Copyright 2010-2011, Christian Muehlhaeuser
+ *
+ * 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 "FlexibleHeader.h"
+#include "ui_PlaylistHeader.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include "playlist/FlexibleView.h"
+#include "ViewManager.h"
+#include "thirdparty/Qocoa/qsearchfield.h"
+#include "utils/Closure.h"
+#include "utils/TomahawkUtilsGui.h"
+#include "utils/Logger.h"
+#include "widgets/QueryLabel.h"
+#include "Source.h"
+
+using namespace Tomahawk;
+
+
+FlexibleHeader::FlexibleHeader( FlexibleView* parent )
+ : QWidget( parent )
+ , m_parent( parent )
+ , ui( new Ui::PlaylistHeader )
+{
+ ui->setupUi( this );
+
+ QPalette pal = palette();
+ pal.setColor( QPalette::Foreground, Qt::white );
+
+ ui->captionLabel->setPalette( pal );
+ ui->descLabel->setPalette( pal );
+
+ QFont font = ui->captionLabel->font();
+ font.setPixelSize( 16 );
+ font.setBold( true );
+ ui->captionLabel->setFont( font );
+
+ font.setPixelSize( 11 );
+ ui->descLabel->setFont( font );
+
+ ui->radioNormal->setFocusPolicy( Qt::NoFocus );
+ ui->radioDetailed->setFocusPolicy( Qt::NoFocus );
+ ui->radioCloud->setFocusPolicy( Qt::NoFocus );
+
+ QFile f( RESPATH "stylesheets/topbar-radiobuttons.css" );
+ f.open( QFile::ReadOnly );
+ QString css = QString::fromAscii( f.readAll() );
+ f.close();
+
+ ui->modeWidget->setStyleSheet( css );
+
+ ui->radioNormal->setChecked( true );
+ ui->filter->setPlaceholderText( tr( "Filter..." ) );
+
+ pal = palette();
+ pal.setColor( QPalette::Window, QColor( "#454e59" ) );
+
+ setPalette( pal );
+ setAutoFillBackground( true );
+
+ connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( applyFilter() ) );
+ connect( ui->filter, SIGNAL( textChanged( QString ) ), SLOT( onFilterEdited() ) );
+
+ NewClosure( ui->radioNormal, SIGNAL( clicked() ), const_cast< FlexibleView* >( parent ), SLOT( setCurrentMode( FlexibleViewMode ) ), FlexibleView::Flat )->setAutoDelete( false );
+ NewClosure( ui->radioDetailed, SIGNAL( clicked() ), const_cast< FlexibleView* >( parent ), SLOT( setCurrentMode( FlexibleViewMode ) ), FlexibleView::Detailed )->setAutoDelete( false );
+ NewClosure( ui->radioCloud, SIGNAL( clicked() ), const_cast< FlexibleView* >( parent ), SLOT( setCurrentMode( FlexibleViewMode ) ), FlexibleView::Grid )->setAutoDelete( false );
+}
+
+
+FlexibleHeader::~FlexibleHeader()
+{
+ delete ui;
+}
+
+
+void
+FlexibleHeader::setCaption( const QString& s )
+{
+ ui->captionLabel->setText( s );
+}
+
+
+void
+FlexibleHeader::setDescription( const QString& s )
+{
+ ui->descLabel->setText( s );
+}
+
+
+void
+FlexibleHeader::setPixmap( const QPixmap& p )
+{
+ ui->imageLabel->setPixmap( p.scaledToHeight( ui->imageLabel->height(), Qt::SmoothTransformation ) );
+}
+
+
+void
+FlexibleHeader::setFilter( const QString& filter )
+{
+ ui->filter->setText( filter );
+}
+
+
+void
+FlexibleHeader::onFilterEdited()
+{
+ m_filter = ui->filter->text();
+
+ m_filterTimer.stop();
+ m_filterTimer.setInterval( 280 );
+ m_filterTimer.setSingleShot( true );
+ m_filterTimer.start();
+}
+
+
+void
+FlexibleHeader::applyFilter()
+{
+ emit filterTextChanged( ui->filter->text() );
+}
+
+
+void
+FlexibleHeader::changeEvent( QEvent* e )
+{
+ QWidget::changeEvent( e );
+ switch ( e->type() )
+ {
+ case QEvent::LanguageChange:
+// ui->retranslateUi( this );
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/src/libtomahawk/playlist/FlexibleHeader.h b/src/libtomahawk/playlist/FlexibleHeader.h
new file mode 100644
index 000000000..623293cec
--- /dev/null
+++ b/src/libtomahawk/playlist/FlexibleHeader.h
@@ -0,0 +1,68 @@
+/* === This file is part of Tomahawk Player - ===
+ *
+ * Copyright 2010-2011, Christian Muehlhaeuser
+ *
+ * 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 FLEXIBLEHEADER_H
+#define FLEXIBLEHEADER_H
+
+#include
+#include
+
+#include "DllMacro.h"
+#include "Artist.h"
+
+class FlexibleView;
+
+namespace Ui
+{
+ class PlaylistHeader;
+}
+
+class DLLEXPORT FlexibleHeader : public QWidget
+{
+Q_OBJECT
+
+public:
+ FlexibleHeader( FlexibleView* parent );
+ ~FlexibleHeader();
+
+public slots:
+ void setCaption( const QString& s );
+ void setDescription( const QString& s );
+ void setPixmap( const QPixmap& p );
+
+ void setFilter( const QString& filter );
+
+signals:
+ void filterTextChanged( const QString& filter );
+
+protected:
+ void changeEvent( QEvent* e );
+
+private slots:
+ void onFilterEdited();
+ void applyFilter();
+
+private:
+ FlexibleView* m_parent;
+ Ui::PlaylistHeader* ui;
+
+ QString m_filter;
+ QTimer m_filterTimer;
+};
+
+#endif
diff --git a/src/libtomahawk/playlist/FlexibleView.cpp b/src/libtomahawk/playlist/FlexibleView.cpp
index faf09383d..3a6d7534d 100644
--- a/src/libtomahawk/playlist/FlexibleView.cpp
+++ b/src/libtomahawk/playlist/FlexibleView.cpp
@@ -22,11 +22,11 @@
#include
#include
+#include "playlist/FlexibleHeader.h"
#include "playlist/PlayableModel.h"
#include "playlist/TrackView.h"
#include "playlist/GridView.h"
#include "playlist/PlaylistLargeItemDelegate.h"
-#include "utils/Closure.h"
#include "utils/TomahawkUtilsGui.h"
#include "utils/Logger.h"
@@ -35,6 +35,7 @@ using namespace Tomahawk;
FlexibleView::FlexibleView( QWidget* parent )
: QWidget( parent )
+ , m_header( new FlexibleHeader( this ) )
, m_trackView( new TrackView() )
, m_detailedView( new TrackView() )
, m_gridView( new GridView() )
@@ -51,54 +52,16 @@ FlexibleView::FlexibleView( QWidget* parent )
setLayout( new QVBoxLayout() );
TomahawkUtils::unmarginLayout( layout() );
- QWidget* modeBar = new QWidget();
- modeBar->setLayout( new QHBoxLayout() );
- TomahawkUtils::unmarginLayout( modeBar->layout() );
-
- QWidget* modeWidget = new QWidget();
- modeWidget->setLayout( new QHBoxLayout() );
- modeWidget->setFixedSize( QSize( 87, 30 ) );
- TomahawkUtils::unmarginLayout( modeWidget->layout() );
-
- QRadioButton* radioNormal = new QRadioButton();
- radioNormal->setObjectName( "radioNormal" );
- QRadioButton* radioDetailed = new QRadioButton();
- radioDetailed->setObjectName( "radioDetailed" );
- QRadioButton* radioCloud = new QRadioButton();
- radioCloud->setObjectName( "radioCloud" );
-
- radioNormal->setFocusPolicy( Qt::NoFocus );
- radioDetailed->setFocusPolicy( Qt::NoFocus );
- radioCloud->setFocusPolicy( Qt::NoFocus );
-
- QFile f( RESPATH "stylesheets/topbar-radiobuttons.css" );
- f.open( QFile::ReadOnly );
- QString css = QString::fromAscii( f.readAll() );
- f.close();
-
- modeWidget->setStyleSheet( css );
- modeWidget->layout()->addWidget( radioNormal );
- modeWidget->layout()->addWidget( radioDetailed );
- modeWidget->layout()->addWidget( radioCloud );
- modeWidget->layout()->addItem( new QSpacerItem( 1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-
- modeBar->layout()->addItem( new QSpacerItem( 1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed ) );
- modeBar->layout()->addWidget( modeWidget );
- modeBar->layout()->addItem( new QSpacerItem( 1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-
- layout()->addWidget( modeBar );
+ layout()->addWidget( m_header );
layout()->addWidget( m_stack );
m_stack->addWidget( m_trackView );
m_stack->addWidget( m_detailedView );
m_stack->addWidget( m_gridView );
- radioNormal->setChecked( true );
setCurrentMode( Flat );
- NewClosure( radioNormal, SIGNAL( clicked() ), const_cast< FlexibleView* >( this ), SLOT( setCurrentMode( FlexibleViewMode ) ), Flat )->setAutoDelete( false );
- NewClosure( radioDetailed, SIGNAL( clicked() ), const_cast< FlexibleView* >( this ), SLOT( setCurrentMode( FlexibleViewMode ) ), Detailed )->setAutoDelete( false );
- NewClosure( radioCloud, SIGNAL( clicked() ), const_cast< FlexibleView* >( this ), SLOT( setCurrentMode( FlexibleViewMode ) ), Grid )->setAutoDelete( false );
+ connect( m_header, SIGNAL( filterTextChanged( QString ) ), SLOT( setFilter( QString ) ) );
}
@@ -166,6 +129,10 @@ FlexibleView::setPlayableModel( PlayableModel* model )
m_trackView->proxyModel()->sort( -1 );
m_detailedView->proxyModel()->sort( -1 );
m_gridView->proxyModel()->sort( -1 );
+
+ m_header->setPixmap( m_pixmap );
+ m_header->setCaption( model->title() );
+ m_header->setDescription( model->description() );
}
@@ -223,7 +190,7 @@ FlexibleView::description() const
QPixmap
FlexibleView::pixmap() const
{
- return m_trackView->pixmap();
+ return m_pixmap;
}
@@ -238,13 +205,30 @@ FlexibleView::jumpToCurrentTrack()
bool
-FlexibleView::setFilter( const QString& filter )
+FlexibleView::setFilter( const QString& pattern )
{
- ViewPage::setFilter( filter );
+ ViewPage::setFilter( pattern );
- m_trackView->setFilter( filter );
- m_detailedView->setFilter( filter );
- m_gridView->setFilter( filter );
+ m_trackView->setFilter( pattern );
+ m_detailedView->setFilter( pattern );
+ m_gridView->setFilter( pattern );
return true;
}
+
+
+void
+FlexibleView::setEmptyTip( const QString& tip )
+{
+ m_trackView->setEmptyTip( tip );
+ m_detailedView->setEmptyTip( tip );
+ m_gridView->setEmptyTip( tip );
+}
+
+
+void
+FlexibleView::setPixmap( const QPixmap& pixmap )
+{
+ m_pixmap = pixmap;
+ m_header->setPixmap( pixmap );
+}
diff --git a/src/libtomahawk/playlist/FlexibleView.h b/src/libtomahawk/playlist/FlexibleView.h
index a18ab0ea9..3b502643a 100644
--- a/src/libtomahawk/playlist/FlexibleView.h
+++ b/src/libtomahawk/playlist/FlexibleView.h
@@ -28,6 +28,7 @@ class QStackedWidget;
class GridView;
class TrackView;
class PlayableModel;
+class FlexibleHeader;
class DLLEXPORT FlexibleView : public QWidget, public Tomahawk::ViewPage
{
@@ -47,23 +48,34 @@ public:
virtual QString description() const;
virtual QPixmap pixmap() const;
- virtual bool showFilter() const { return true; }
- virtual bool setFilter( const QString& filter );
+ virtual bool showInfoBar() const { return false; }
virtual bool jumpToCurrentTrack();
+ TrackView* trackView() const { return m_trackView; }
+ TrackView* detailedView() const { return m_detailedView; }
+ GridView* gridView() const { return m_gridView; }
+
void setTrackView( TrackView* view );
void setDetailedView( TrackView* view );
void setGridView( GridView* view );
+ void setPixmap( const QPixmap& pixmap );
void setPlayableModel( PlayableModel* model );
+ void setEmptyTip( const QString& tip );
public slots:
void setCurrentMode( FlexibleViewMode mode );
+ virtual bool setFilter( const QString& pattern );
signals:
void modeChanged( FlexibleViewMode mode );
+private slots:
+
private:
+ FlexibleHeader* m_header;
+ QPixmap m_pixmap;
+
TrackView* m_trackView;
TrackView* m_detailedView;
GridView* m_gridView;
diff --git a/src/libtomahawk/playlist/LovedTracksModel.cpp b/src/libtomahawk/playlist/LovedTracksModel.cpp
new file mode 100644
index 000000000..b0552d76e
--- /dev/null
+++ b/src/libtomahawk/playlist/LovedTracksModel.cpp
@@ -0,0 +1,133 @@
+/* === This file is part of Tomahawk Player - ===
+ *
+ * Copyright 2010-2012, Christian Muehlhaeuser
+ *
+ * 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 "LovedTracksModel.h"
+
+#include
+#include
+
+#include "Source.h"
+#include "SourceList.h"
+#include "database/Database.h"
+#include "database/DatabaseCommand_GenericSelect.h"
+#include "PlayableItem.h"
+#include "utils/TomahawkUtils.h"
+#include "utils/Logger.h"
+
+#define LOVED_TRACK_ITEMS 25
+
+using namespace Tomahawk;
+
+
+LovedTracksModel::LovedTracksModel( QObject* parent )
+ : PlaylistModel( parent )
+ , m_limit( LOVED_TRACK_ITEMS )
+{
+}
+
+
+LovedTracksModel::~LovedTracksModel()
+{
+}
+
+
+void
+LovedTracksModel::loadTracks()
+{
+ if ( rowCount( QModelIndex() ) )
+ {
+ clear();
+ }
+ startLoading();
+
+ QString sql;
+ if ( m_source.isNull() )
+ {
+ sql = QString( "SELECT track.name, artist.name, source, COUNT(*) as counter "
+ "FROM social_attributes, track, artist "
+ "WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND social_attributes.v = 'true' "
+ "GROUP BY track.id "
+ "ORDER BY counter DESC, social_attributes.timestamp DESC LIMIT 0, 50" );
+ }
+ else
+ {
+ sql = QString( "SELECT track.name, artist.name, COUNT(*) as counter "
+ "FROM social_attributes, track, artist "
+ "WHERE social_attributes.id = track.id AND artist.id = track.artist AND social_attributes.k = 'Love' AND social_attributes.v = 'true' AND social_attributes.source %1 "
+ "GROUP BY track.id "
+ "ORDER BY counter DESC, social_attributes.timestamp DESC " ).arg( m_source->isLocal() ? "IS NULL" : QString( "= %1" ).arg( m_source->id() ) );
+ }
+
+ DatabaseCommand_GenericSelect* cmd = new DatabaseCommand_GenericSelect( sql, DatabaseCommand_GenericSelect::Track, -1, 0 );
+ connect( cmd, SIGNAL( tracks( QList ) ), this, SLOT( appendQueries( QList ) ) );
+ Database::instance()->enqueue( QSharedPointer( cmd ) );
+}
+
+
+void
+LovedTracksModel::onSourcesReady()
+{
+ Q_ASSERT( m_source.isNull() );
+
+ loadTracks();
+
+ foreach ( const source_ptr& source, SourceList::instance()->sources() )
+ onSourceAdded( source );
+}
+
+
+void
+LovedTracksModel::setSource( const Tomahawk::source_ptr& source )
+{
+ m_source = source;
+ if ( source.isNull() )
+ {
+ if ( SourceList::instance()->isReady() )
+ onSourcesReady();
+ else
+ connect( SourceList::instance(), SIGNAL( ready() ), SLOT( onSourcesReady() ) );
+
+ connect( SourceList::instance(), SIGNAL( sourceAdded( Tomahawk::source_ptr ) ), SLOT( onSourceAdded( Tomahawk::source_ptr ) ) );
+ }
+ else
+ {
+ onSourceAdded( source );
+ loadTracks();
+ }
+}
+
+
+void
+LovedTracksModel::onSourceAdded( const Tomahawk::source_ptr& source )
+{
+ connect( source.data(), SIGNAL( socialAttributesChanged( QString ) ), SLOT( onTrackLoved() ), Qt::UniqueConnection );
+}
+
+
+void
+LovedTracksModel::onTrackLoved()
+{
+ loadTracks();
+}
+
+
+bool
+LovedTracksModel::isTemporary() const
+{
+ return true;
+}
diff --git a/src/libtomahawk/playlist/LovedTracksModel.h b/src/libtomahawk/playlist/LovedTracksModel.h
new file mode 100644
index 000000000..6b3b40d1d
--- /dev/null
+++ b/src/libtomahawk/playlist/LovedTracksModel.h
@@ -0,0 +1,58 @@
+/* === This file is part of Tomahawk Player - ===
+ *
+ * Copyright 2010-2011, Christian Muehlhaeuser
+ *
+ * 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 LOVEDTRACKSMODEL_H
+#define LOVEDTRACKSMODEL_H
+
+#include
+#include
+
+#include "Typedefs.h"
+#include "PlaylistModel.h"
+
+#include "DllMacro.h"
+
+class DLLEXPORT LovedTracksModel : public PlaylistModel
+{
+Q_OBJECT
+
+public:
+ explicit LovedTracksModel( QObject* parent = 0 );
+ ~LovedTracksModel();
+
+ unsigned int limit() const { return m_limit; }
+ void setLimit( unsigned int limit ) { m_limit = limit; }
+
+ bool isTemporary() const;
+
+public slots:
+ void setSource( const Tomahawk::source_ptr& source );
+
+private slots:
+ void onSourcesReady();
+ void onSourceAdded( const Tomahawk::source_ptr& source );
+
+ void onTrackLoved();
+ void loadTracks();
+
+private:
+ Tomahawk::source_ptr m_source;
+ unsigned int m_limit;
+};
+
+#endif // LOVEDTRACKSMODEL_H
diff --git a/src/libtomahawk/playlist/PlaylistHeader.ui b/src/libtomahawk/playlist/PlaylistHeader.ui
new file mode 100644
index 000000000..a55ea5fd7
--- /dev/null
+++ b/src/libtomahawk/playlist/PlaylistHeader.ui
@@ -0,0 +1,282 @@
+
+
+ PlaylistHeader
+
+
+
+ 0
+ 0
+ 774
+ 80
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 72
+
+
+
+ InfoBar
+
+
+
+ 8
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 64
+ 64
+
+
+
+
+ 64
+ 64
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 16
+ 20
+
+
+
+
+ -
+
+
+ 0
+
+
+ 0
+
+
+ 2
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Caption
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+
+
+ -
+
+
+ Description
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 1
+
+
+
+
+ -
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 156
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 87
+ 30
+
+
+
+
+ 87
+ 30
+
+
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ RadioButton
+
+
+
+ -
+
+
+ RadioButton
+
+
+
+ -
+
+
+ RadioButton
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 16
+ 20
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 220
+ 0
+
+
+
+
+ 220
+ 16777215
+
+
+
+
+
+
+
+
+ ElidedLabel
+ QLabel
+
+
+
+ QSearchField
+ QLineEdit
+ thirdparty/Qocoa/qsearchfield.h
+
+
+
+
+
diff --git a/src/libtomahawk/playlist/QueueProxyModel.cpp b/src/libtomahawk/playlist/QueueProxyModel.cpp
index 78a0f7cb0..c2023642a 100644
--- a/src/libtomahawk/playlist/QueueProxyModel.cpp
+++ b/src/libtomahawk/playlist/QueueProxyModel.cpp
@@ -33,7 +33,6 @@ QueueProxyModel::QueueProxyModel( TrackView* parent )
: PlayableProxyModel( parent )
{
connect( parent, SIGNAL( itemActivated( QModelIndex ) ), SLOT( onIndexActivated( QModelIndex ) ) );
- connect( playlistInterface().data(), SIGNAL( sourceTrackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) );
connect( AudioEngine::instance(), SIGNAL( loading( Tomahawk::result_ptr ) ), SLOT( onPlaybackStarted( Tomahawk::result_ptr ) ) );
}
@@ -52,7 +51,11 @@ QueueProxyModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
PlayableItem* item = itemFromIndex( mapToSource( idx ) );
if ( item && item->query() && ( item->query()->results().contains( result ) ||
item->query()->equals( result->toQuery() ) ) )
+ {
removeIndex( idx );
+ if ( !rowCount() )
+ ViewManager::instance()->hideQueue();
+ }
}
}
@@ -62,12 +65,7 @@ QueueProxyModel::onIndexActivated( const QModelIndex& index )
{
setCurrentIndex( QModelIndex() );
removeIndex( index );
-}
-
-void
-QueueProxyModel::onTrackCountChanged( unsigned int count )
-{
- if ( count == 0 )
+ if ( !rowCount() )
ViewManager::instance()->hideQueue();
}
diff --git a/src/libtomahawk/playlist/QueueProxyModel.h b/src/libtomahawk/playlist/QueueProxyModel.h
index 3c39a68dc..f2755a03a 100644
--- a/src/libtomahawk/playlist/QueueProxyModel.h
+++ b/src/libtomahawk/playlist/QueueProxyModel.h
@@ -37,7 +37,6 @@ public:
private slots:
void onIndexActivated( const QModelIndex& index );
- void onTrackCountChanged( unsigned int count );
void onPlaybackStarted( const Tomahawk::result_ptr& result );
};
diff --git a/src/libtomahawk/playlist/TreeProxyModel.cpp b/src/libtomahawk/playlist/TreeProxyModel.cpp
index d95232261..5cf9d2a1f 100644
--- a/src/libtomahawk/playlist/TreeProxyModel.cpp
+++ b/src/libtomahawk/playlist/TreeProxyModel.cpp
@@ -204,7 +204,7 @@ TreeProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent
PlayableItem* ti = sourceModel()->itemFromIndex( sourceModel()->index( i, 0, sourceParent ) );
- if ( ti && ti->name() == item->name() )
+ if ( ti && ti->name() == item->name() && !ti->query().isNull() )
{
if ( ti->query()->albumpos() == item->query()->albumpos() || ti->query()->albumpos() == 0 || item->query()->albumpos() == 0 )
{
diff --git a/src/libtomahawk/resolvers/ScriptResolver.cpp b/src/libtomahawk/resolvers/ScriptResolver.cpp
index ebfd79672..b5d5742cc 100644
--- a/src/libtomahawk/resolvers/ScriptResolver.cpp
+++ b/src/libtomahawk/resolvers/ScriptResolver.cpp
@@ -353,6 +353,9 @@ ScriptResolver::resolve( const Tomahawk::query_ptr& query )
m.insert( "artist", query->artist() );
m.insert( "track", query->track() );
m.insert( "qid", query->id() );
+
+ if ( !query->resultHint().isEmpty() )
+ m.insert( "resultHint", query->resultHint() );
}
const QByteArray msg = m_serializer.serialize( QVariant( m ) );
diff --git a/src/libtomahawk/utils/SpotifyParser.cpp b/src/libtomahawk/utils/SpotifyParser.cpp
index 7c37e1ed2..d312934c2 100644
--- a/src/libtomahawk/utils/SpotifyParser.cpp
+++ b/src/libtomahawk/utils/SpotifyParser.cpp
@@ -97,31 +97,50 @@ void
SpotifyParser::lookupSpotifyBrowse( const QString& linkRaw )
{
tLog() << "Parsing Spotify Browse URI:" << linkRaw;
- QString browseUri = linkRaw;
- if ( browseUri.contains( "open.spotify.com/" ) ) // convert to a URI
+ m_browseUri = linkRaw;
+
+ if ( m_browseUri.contains( "open.spotify.com/" ) ) // convert to a URI
{
- browseUri.replace( "http://open.spotify.com/", "" );
- browseUri.replace( "/", ":" );
- browseUri = "spotify:" + browseUri;
+ m_browseUri.replace( "http://open.spotify.com/", "" );
+ m_browseUri.replace( "/", ":" );
+ m_browseUri = "spotify:" + m_browseUri;
+ }
+
+ if ( m_browseUri.contains( "playlist" ) &&
+ Tomahawk::Accounts::SpotifyAccount::instance() != 0 &&
+ Tomahawk::Accounts::SpotifyAccount::instance()->loggedIn() )
+ {
+ // Do a playlist lookup locally
+ // Running resolver, so do the lookup through that
+ qDebug() << Q_FUNC_INFO << "Doing playlist lookup through spotify resolver:" << m_browseUri;
+ QVariantMap message;
+ message[ "_msgtype" ] = "playlistListing";
+ message[ "id" ] = m_browseUri;
+
+ QMetaObject::invokeMethod( Tomahawk::Accounts::SpotifyAccount::instance(), "sendMessage", Qt::QueuedConnection, Q_ARG( QVariantMap, message ),
+ Q_ARG( QObject*, this ),
+ Q_ARG( QString, "playlistListingResult" ) );
+
+ return;
}
DropJob::DropType type;
- if ( browseUri.contains( "spotify:user" ) )
+ if ( m_browseUri.contains( "spotify:user" ) )
type = DropJob::Playlist;
- if ( browseUri.contains( "spotify:artist" ) )
+ if ( m_browseUri.contains( "spotify:artist" ) )
type = DropJob::Artist;
- if ( browseUri.contains( "spotify:album" ) )
+ if ( m_browseUri.contains( "spotify:album" ) )
type = DropJob::Album;
- if ( browseUri.contains( "spotify:track" ) )
+ if ( m_browseUri.contains( "spotify:track" ) )
type = DropJob::Track;
QUrl url;
if( type != DropJob::Artist )
- url = QUrl( QString( SPOTIFY_PLAYLIST_API_URL "/browse/%1" ).arg( browseUri ) );
+ url = QUrl( QString( SPOTIFY_PLAYLIST_API_URL "/browse/%1" ).arg( m_browseUri ) );
else
- url = QUrl( QString( SPOTIFY_PLAYLIST_API_URL "/browse/%1/%2" ).arg( browseUri )
+ url = QUrl( QString( SPOTIFY_PLAYLIST_API_URL "/browse/%1/%2" ).arg( m_browseUri )
.arg ( m_limit ) );
tDebug() << "Looking up URL..." << url.toString();
@@ -216,6 +235,9 @@ SpotifyParser::spotifyBrowseFinished()
if ( q.isNull() )
continue;
+ tLog() << "Setting resulthint to " << trackResult.value( "trackuri" );
+ q->setResultHint( trackResult.value( "trackuri" ).toString() );
+
m_tracks << q;
}
}
@@ -279,7 +301,11 @@ SpotifyParser::spotifyTrackLookupFinished()
Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album, uuid(), m_trackMode );
if ( !q.isNull() )
+ {
+ q->setResultHint( t.value( "trackuri" ).toString() );
+
m_tracks << q;
+ }
}
else
{
@@ -293,6 +319,31 @@ SpotifyParser::spotifyTrackLookupFinished()
}
+void
+SpotifyParser::playlistListingResult( const QString& msgType, const QVariantMap& msg, const QVariant& extraData )
+{
+ Q_ASSERT( msgType == "playlistListing" );
+
+ m_title = msg.value( "name" ).toString();
+ m_single = false;
+ m_creator = msg.value( "creator" ).toString();
+
+ const QVariantList tracks = msg.value( "tracks" ).toList();
+ foreach ( const QVariant& blob, tracks )
+ {
+ 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;
+
+ m_tracks << q;
+ }
+
+ checkBrowseFinished();
+}
+
+
void
SpotifyParser::checkBrowseFinished()
{
@@ -304,6 +355,7 @@ SpotifyParser::checkBrowseFinished()
if ( m_createNewPlaylist && !m_tracks.isEmpty() )
{
+
m_playlist = Playlist::create( SourceList::instance()->getLocal(),
uuid(),
m_title,
@@ -311,10 +363,30 @@ SpotifyParser::checkBrowseFinished()
m_creator,
false,
m_tracks );
+
connect( m_playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( playlistCreated() ) );
+
+ if ( Accounts::SpotifyAccount::instance() && Accounts::SpotifyAccount::instance()->loggedIn() )
+ {
+ 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() ) )
+ updater->setCanSubscribe( true );
+
+ // Just register the infos
+ Accounts::SpotifyAccount::instance()->registerPlaylistInfo( m_title, m_browseUri, m_browseUri, false, false );
+ Accounts::SpotifyAccount::instance()->registerUpdaterForPlaylist( m_browseUri, updater );
+
+
+ Accounts::SpotifyAccount::instance()->setSubscribedForPlaylist( m_playlist, true );
+
+ }
return;
}
-
else if ( m_single && !m_tracks.isEmpty() )
emit track( m_tracks.first() );
else if ( !m_single && !m_tracks.isEmpty() )
diff --git a/src/libtomahawk/utils/SpotifyParser.h b/src/libtomahawk/utils/SpotifyParser.h
index 7f5c65b61..3675489ca 100644
--- a/src/libtomahawk/utils/SpotifyParser.h
+++ b/src/libtomahawk/utils/SpotifyParser.h
@@ -24,7 +24,8 @@
#include "Typedefs.h"
#include "Query.h"
#include "jobview/JobStatusItem.h"
-
+#include "accounts/spotify/SpotifyPlaylistUpdater.h"
+#include "accounts/spotify/SpotifyAccount.h"
#include
#include
#include
@@ -38,6 +39,8 @@
*/
class QNetworkReply;
+class SpotifyAccount;
+class SpotifyPlaylistUpdater;
namespace Tomahawk
{
@@ -57,6 +60,9 @@ public:
// the single track signal
void setSingleMode( bool single ) { m_single = single; }
+public slots:
+ void playlistListingResult( const QString& msgType, const QVariantMap& msg, const QVariant& extraData );
+
signals:
void track( const Tomahawk::query_ptr& track );
void tracks( const QList< Tomahawk::query_ptr > tracks );
@@ -84,7 +90,7 @@ private:
QString m_title, m_info, m_creator;
Tomahawk::playlist_ptr m_playlist;
DropJobNotifier* m_browseJob;
-
+ QString m_browseUri;
static QPixmap* s_pixmap;
};
diff --git a/src/sourcetree/SourceTreeView.cpp b/src/sourcetree/SourceTreeView.cpp
index ce9911c08..55a97a338 100644
--- a/src/sourcetree/SourceTreeView.cpp
+++ b/src/sourcetree/SourceTreeView.cpp
@@ -609,7 +609,6 @@ SourceTreeView::dragEnterEvent( QDragEnterEvent* event )
m_dropRect = QRect();
m_dropIndex = QPersistentModelIndex();
- qDebug() << Q_FUNC_INFO << "Accepting Drag Event";
event->setDropAction( Qt::CopyAction );
event->acceptProposedAction();
}
diff --git a/src/sourcetree/SourcesModel.cpp b/src/sourcetree/SourcesModel.cpp
index a2fe261ae..c800a13e1 100644
--- a/src/sourcetree/SourcesModel.cpp
+++ b/src/sourcetree/SourcesModel.cpp
@@ -30,6 +30,7 @@
#include "sourcetree/items/GroupItem.h"
#include "sourcetree/items/GenericPageItems.h"
#include "sourcetree/items/HistoryItem.h"
+#include "sourcetree/items/LovedTracksItem.h"
#include "SourceList.h"
#include "Playlist.h"
#include "Collection.h"
@@ -293,9 +294,7 @@ SourcesModel::appendGroups()
sc->setSortValue( 1 );
// browse section
- GenericPageItem* loved = new GenericPageItem( this, browse, tr( "Top Loved Tracks" ), QIcon( RESPATH "images/loved_playlist.png" ),
- boost::bind( &ViewManager::showTopLovedPage, ViewManager::instance() ),
- boost::bind( &ViewManager::topLovedWidget, ViewManager::instance() ) );
+ LovedTracksItem* loved = new LovedTracksItem( this, browse );
loved->setSortValue( 2 );
GenericPageItem* recent = new GenericPageItem( this, browse, tr( "Recently Played" ), QIcon( RESPATH "images/recently-played.png" ),
diff --git a/src/sourcetree/items/HistoryItem.cpp b/src/sourcetree/items/HistoryItem.cpp
index 0f941ec3f..93be20dc1 100644
--- a/src/sourcetree/items/HistoryItem.cpp
+++ b/src/sourcetree/items/HistoryItem.cpp
@@ -23,7 +23,6 @@
#include "GenericPageItems.h"
#include "utils/TomahawkUtilsGui.h"
#include "utils/Logger.h"
-#include "playlist/CustomPlaylistView.h"
#include "TemporaryPageItem.h"
#include "SourceList.h"
diff --git a/src/sourcetree/items/LovedTracksItem.cpp b/src/sourcetree/items/LovedTracksItem.cpp
index 8b468b99c..4623b3437 100644
--- a/src/sourcetree/items/LovedTracksItem.cpp
+++ b/src/sourcetree/items/LovedTracksItem.cpp
@@ -24,7 +24,9 @@
#include "DropJob.h"
#include "ViewManager.h"
-#include "playlist/CustomPlaylistView.h"
+#include "playlist/FlexibleView.h"
+#include "playlist/TrackView.h"
+#include "playlist/LovedTracksModel.h"
#include "playlist/PlaylistLargeItemDelegate.h"
using namespace Tomahawk;
@@ -33,6 +35,7 @@ using namespace Tomahawk;
LovedTracksItem::LovedTracksItem( SourcesModel* mdl, SourceTreeItem* parent )
: SourceTreeItem( mdl, parent, SourcesModel::LovedTracksPage )
, m_lovedTracksPage( 0 )
+ , m_sortValue( -150 )
{
}
@@ -42,23 +45,49 @@ LovedTracksItem::~LovedTracksItem()
}
+QString
+LovedTracksItem::text() const
+{
+ SourceItem* par = dynamic_cast< SourceItem* >( parent() );
+
+ if ( !par )
+ return QString( tr( "Top Loved Tracks" ) );
+ else
+ return QString( tr( "Loved Tracks" ) );
+}
+
+
void
LovedTracksItem::activate()
{
if ( !m_lovedTracksPage )
{
SourceItem* par = dynamic_cast< SourceItem* >( parent() );
+ FlexibleView* pv = new FlexibleView( ViewManager::instance()->widget() );
+ pv->setPixmap( QPixmap( RESPATH "images/loved_playlist.png" ) );
+
+ LovedTracksModel* raModel = new LovedTracksModel( pv );
+ raModel->setTitle( text() );
+
+ PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LovedTracks, pv->trackView(), pv->trackView()->proxyModel() );
+ connect( del, SIGNAL( updateIndex( QModelIndex ) ), pv->trackView(), SLOT( update( QModelIndex ) ) );
+ pv->trackView()->setItemDelegate( del );
+
+ pv->setEmptyTip( tr( "Sorry, we could not find any loved tracks!" ) );
if ( !par )
- return;
+ raModel->setDescription( tr( "The most loved tracks from all your friends" ) );
+ else
+ {
+ if ( par->source()->isLocal() )
+ raModel->setDescription( tr( "All of your loved tracks" ) );
+ else
+ raModel->setDescription( tr( "All of %1's loved tracks" ).arg( par->source()->friendlyName() ) );
+ }
- CustomPlaylistView* view = new CustomPlaylistView( par->source().isNull() ? CustomPlaylistView::TopLovedTracks :
- CustomPlaylistView::SourceLovedTracks, par->source(), ViewManager::instance()->widget() );
- PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate(PlaylistLargeItemDelegate::LovedTracks, view, view->proxyModel() );
- connect( del, SIGNAL( updateIndex( QModelIndex ) ), view, SLOT( update( QModelIndex ) ) );
- view->setItemDelegate( del );
- view->setEmptyTip( tr( "Sorry, we could not find any loved tracks!" ) );
+ pv->setPlayableModel( raModel );
+ raModel->setSource( !par ? source_ptr() : par->source() );
- m_lovedTracksPage = view;
+ m_lovedTracksPage = pv;
}
ViewManager::instance()->show( m_lovedTracksPage );
diff --git a/src/sourcetree/items/LovedTracksItem.h b/src/sourcetree/items/LovedTracksItem.h
index e2bec4ce1..81dae6016 100644
--- a/src/sourcetree/items/LovedTracksItem.h
+++ b/src/sourcetree/items/LovedTracksItem.h
@@ -33,20 +33,23 @@ public:
LovedTracksItem( SourcesModel* model, SourceTreeItem* parent );
virtual ~LovedTracksItem();
- virtual QString text() const { return QString( tr( "Loved Tracks" ) ); }
+ virtual QString text() const;
virtual QIcon icon() const { return QIcon( RESPATH "images/loved_playlist.png" ); }
- virtual int peerSortValue() const { return -150; }
+ virtual int peerSortValue() const { return m_sortValue; }
virtual void activate();
virtual bool willAcceptDrag( const QMimeData* data ) const;
virtual DropTypes supportedDropTypes( const QMimeData* data ) const;
virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action );
+ void setSortValue( int value ) { m_sortValue = value; }
+
private slots:
void loveDroppedTracks( QList< Tomahawk::query_ptr > qrys );
private:
Tomahawk::ViewPage* m_lovedTracksPage;
+ int m_sortValue;
};
#endif
diff --git a/src/sourcetree/items/PlaylistItems.cpp b/src/sourcetree/items/PlaylistItems.cpp
index f4806abf3..8fb322915 100644
--- a/src/sourcetree/items/PlaylistItems.cpp
+++ b/src/sourcetree/items/PlaylistItems.cpp
@@ -170,6 +170,34 @@ PlaylistItem::willAcceptDrag( const QMimeData* data ) const
PlaylistItem::DropTypes
PlaylistItem::supportedDropTypes( const QMimeData* data ) const
{
+ if ( data->hasFormat( "application/tomahawk.mixed" ) )
+ {
+ // If this is mixed but only queries/results, we can still handle them
+ bool mixedQueries = true;
+
+ QByteArray itemData = data->data( "application/tomahawk.mixed" );
+ QDataStream stream( &itemData, QIODevice::ReadOnly );
+ QString mimeType;
+ qlonglong val;
+
+ while ( !stream.atEnd() )
+ {
+ stream >> mimeType;
+ if ( mimeType != "application/tomahawk.query.list" &&
+ mimeType != "application/tomahawk.result.list" )
+ {
+ mixedQueries = false;
+ break;
+ }
+ stream >> val;
+ }
+
+ if ( mixedQueries )
+ return DropTypeThisTrack | DropTypeThisAlbum | DropTypeAllFromArtist | DropTypeLocalItems | DropTypeTop50;
+ else
+ return DropTypesNone;
+ }
+
if ( data->hasFormat( "application/tomahawk.query.list" ) )
return DropTypeThisTrack | DropTypeThisAlbum | DropTypeAllFromArtist | DropTypeLocalItems | DropTypeTop50;
else if ( data->hasFormat( "application/tomahawk.result.list" ) )
@@ -178,10 +206,6 @@ PlaylistItem::supportedDropTypes( const QMimeData* data ) const
return DropTypeThisAlbum | DropTypeAllFromArtist | DropTypeLocalItems | DropTypeTop50;
else if ( data->hasFormat( "application/tomahawk.metadata.artist" ) )
return DropTypeAllFromArtist | DropTypeLocalItems | DropTypeTop50;
- else if ( data->hasFormat( "application/tomahawk.mixed" ) )
- {
- return DropTypesNone;
- }
else if ( data->hasFormat( "text/plain" ) )
{
return DropTypesNone;
diff --git a/src/sourcetree/items/SourceItem.cpp b/src/sourcetree/items/SourceItem.cpp
index 8275f9f81..a70e4228c 100644
--- a/src/sourcetree/items/SourceItem.cpp
+++ b/src/sourcetree/items/SourceItem.cpp
@@ -28,7 +28,7 @@
#include "utils/TomahawkUtilsGui.h"
#include "utils/Logger.h"
#include "widgets/SocialPlaylistWidget.h"
-#include "playlist/CustomPlaylistView.h"
+#include "playlist/FlexibleView.h"
#include "playlist/PlaylistView.h"
#include "playlist/RecentlyAddedModel.h"
#include "playlist/RecentlyPlayedModel.h"
@@ -508,12 +508,10 @@ SourceItem::latestAdditionsClicked()
{
if ( !m_latestAdditionsPage )
{
- TrackView* cv = new TrackView( ViewManager::instance()->widget() );
- cv->setFrameShape( QFrame::NoFrame );
- cv->setAttribute( Qt::WA_MacShowFocusRect, 0 );
+ FlexibleView* pv = new FlexibleView( ViewManager::instance()->widget() );
+ pv->setPixmap( QPixmap( RESPATH "images/new-additions.png" ) );
- RecentlyAddedModel* raModel = new RecentlyAddedModel( cv );
- cv->proxyModel()->setStyle( PlayableProxyModel::Large );
+ RecentlyAddedModel* raModel = new RecentlyAddedModel( pv );
raModel->setTitle( tr( "Latest Additions" ) );
if ( m_source->isLocal() )
@@ -521,17 +519,17 @@ SourceItem::latestAdditionsClicked()
else
raModel->setDescription( tr( "Latest additions to %1's collection" ).arg( m_source->friendlyName() ) );
- PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LatestAdditions, cv, cv->proxyModel() );
- connect( del, SIGNAL( updateIndex( QModelIndex ) ), cv, SLOT( update( QModelIndex ) ) );
- cv->setItemDelegate( del );
-
- cv->setPlayableModel( raModel );
- cv->sortByColumn( PlayableModel::Age, Qt::DescendingOrder );
- cv->setEmptyTip( tr( "Sorry, we could not find any recent additions!" ) );
+ PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LatestAdditions, pv->trackView(), pv->trackView()->proxyModel() );
+ connect( del, SIGNAL( updateIndex( QModelIndex ) ), pv->trackView(), SLOT( update( QModelIndex ) ) );
+ pv->trackView()->setItemDelegate( del );
+ pv->setPlayableModel( raModel );
+ pv->trackView()->sortByColumn( PlayableModel::Age, Qt::DescendingOrder );
+ pv->detailedView()->sortByColumn( PlayableModel::Age, Qt::DescendingOrder );
+ pv->setEmptyTip( tr( "Sorry, we could not find any recent additions!" ) );
raModel->setSource( m_source );
- m_latestAdditionsPage = cv;
+ m_latestAdditionsPage = pv;
}
ViewManager::instance()->show( m_latestAdditionsPage );
@@ -551,12 +549,10 @@ SourceItem::recentPlaysClicked()
{
if ( !m_recentPlaysPage )
{
- PlaylistView* pv = new PlaylistView( ViewManager::instance()->widget() );
- pv->setFrameShape( QFrame::NoFrame );
- pv->setAttribute( Qt::WA_MacShowFocusRect, 0 );
+ FlexibleView* pv = new FlexibleView( ViewManager::instance()->widget() );
+ pv->setPixmap( QPixmap( RESPATH "images/recently-played.png" ) );
RecentlyPlayedModel* raModel = new RecentlyPlayedModel( pv );
- pv->proxyModel()->setStyle( PlayableProxyModel::Large );
raModel->setTitle( tr( "Recently Played Tracks" ) );
if ( m_source->isLocal() )
@@ -564,11 +560,11 @@ SourceItem::recentPlaysClicked()
else
raModel->setDescription( tr( "%1's recently played tracks" ).arg( m_source->friendlyName() ) );
- PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::RecentlyPlayed, pv, pv->proxyModel() );
- connect( del, SIGNAL( updateIndex( QModelIndex ) ), pv, SLOT( update( QModelIndex ) ) );
- pv->setItemDelegate( del );
+ PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::RecentlyPlayed, pv->trackView(), pv->trackView()->proxyModel() );
+ connect( del, SIGNAL( updateIndex( QModelIndex ) ), pv->trackView(), SLOT( update( QModelIndex ) ) );
+ pv->trackView()->setItemDelegate( del );
- pv->setPlaylistModel( raModel );
+ pv->setPlayableModel( raModel );
pv->setEmptyTip( tr( "Sorry, we could not find any recent plays!" ) );
raModel->setSource( m_source );
diff --git a/src/web/Api_v1.cpp b/src/web/Api_v1.cpp
index 4f8f78c9f..060ea0e1b 100644
--- a/src/web/Api_v1.cpp
+++ b/src/web/Api_v1.cpp
@@ -235,6 +235,11 @@ Api_v1::statResult( const QString& clientToken, const QString& name, bool valid
{
Q_UNUSED( clientToken )
Q_UNUSED( name )
+
+ Q_ASSERT( m_storedEvent );
+ if ( !m_storedEvent )
+ return;
+
QVariantMap m;
m.insert( "name", "playdar" );
m.insert( "version", "0.1.1" ); // TODO (needs to be >=0.1.1 for JS to work)