diff --git a/ChangeLog b/ChangeLog index cb01d412d..76f103cc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,40 +1,49 @@ Version 0.4.1: + * Fixed various crashes. + * Fixed issues with auto-updating XSPF playlists. + * Double-clicking a playlist starts playing it. + * Resolvers can now return disc number and album position for results. + * Fixed sorting playlists by track number. + * Fixed issues with changing proxy. + * Fixed Twitter authentication issues. + * Fixed Grooveshark support on Windows. + * Fixed volume issue (too quiet) on Windows. Version 0.4.0: - * Added visual notification for database indexing job. - * Fixed icons not appearing in resolvers list. - * Fixed various UI glitches and stray error messages in stations. - * Fixed bug where album page would resolve bottom-to-top. - * Fixed bug where Footnotes would not update when changing selected album in Album View. - * Fixed dragging albums and artists from charts, album, and artist views. - * Fixed bug where filter text would be one step behind filter value. - * Fixed bug where resolvers would enable themselves after auto-updating. - * Fixed occasional crash when dropping tracks onto New Station item. - * Added jump-to-current-track support for search results page. - * Fixed out of sync Show/Hide menu items on OS X when hidden with cmd-h. - * Fixed non-resolving tracks when dragging from album view. - * Fixed /Volumes directory not showing up on OS X. - * Fixed fetching album covers for albums with special characters. - * Show errors and continue gracefully when resolved audio is not available. - * Fixed various crashes on exit. - * Added basic command-line options for playback control. - * Bumped up web api timeouts to allow web clients to finish resolving. - * Added filename suggestion when exporting a playlist. - * Cleaned up highlighting of artist names in album view. - * Cleaned up alignment of playlist items. - * Fixed potential crash when searching. - * Added support for disc number. - * Added SoundCloudWall.com charts. - * Added ability to "lock on" to a user when listening along, to skip along. - * Fixed bug where loved tracks would be refreshed much too often. - * Fixed startup crash on OS X. - * Fixed some font size issues. - * Sped up Tomahawk startup by moving chart loading into a separate thread. - * Added support for parsing Grooveshark and Tinysong tracks and playlists. - * Reorganized sidebar to follow more logical item groupings. - * Added artist and album results to global searches. - * Fixed style and contrast issues when using GTK styles. - * Fixed paths to artwork when using MPRIS2 interface. + * Added visual notification for database indexing job. + * Fixed icons not appearing in resolvers list. + * Fixed various UI glitches and stray error messages in stations. + * Fixed bug where album page would resolve bottom-to-top. + * Fixed bug where Footnotes would not update when changing selected album in Album View. + * Fixed dragging albums and artists from charts, album, and artist views. + * Fixed bug where filter text would be one step behind filter value. + * Fixed bug where resolvers would enable themselves after auto-updating. + * Fixed occasional crash when dropping tracks onto New Station item. + * Added jump-to-current-track support for search results page. + * Fixed out of sync Show/Hide menu items on OS X when hidden with cmd-h. + * Fixed non-resolving tracks when dragging from album view. + * Fixed /Volumes directory not showing up on OS X. + * Fixed fetching album covers for albums with special characters. + * Show errors and continue gracefully when resolved audio is not available. + * Fixed various crashes on exit. + * Added basic command-line options for playback control. + * Bumped up web api timeouts to allow web clients to finish resolving. + * Added filename suggestion when exporting a playlist. + * Cleaned up highlighting of artist names in album view. + * Cleaned up alignment of playlist items. + * Fixed potential crash when searching. + * Added support for disc number. + * Added SoundCloudWall.com charts. + * Added ability to "lock on" to a user when listening along, to skip along. + * Fixed bug where loved tracks would be refreshed much too often. + * Fixed startup crash on OS X. + * Fixed some font size issues. + * Sped up Tomahawk startup by moving chart loading into a separate thread. + * Added support for parsing Grooveshark and Tinysong tracks and playlists. + * Reorganized sidebar to follow more logical item groupings. + * Added artist and album results to global searches. + * Fixed style and contrast issues when using GTK styles. + * Fixed paths to artwork when using MPRIS2 interface. Version 0.3.3: * Automatically load Super Collection tracks when no official release diff --git a/data/images/account-settings.png b/data/images/account-settings.png index 45b9e932a..085d48abc 100644 Binary files a/data/images/account-settings.png and b/data/images/account-settings.png differ diff --git a/data/images/advanced-settings.png b/data/images/advanced-settings.png index 68238ba31..05f019e30 100644 Binary files a/data/images/advanced-settings.png and b/data/images/advanced-settings.png differ diff --git a/data/images/collection.png b/data/images/collection.png new file mode 100644 index 000000000..abc20d3ca Binary files /dev/null and b/data/images/collection.png differ diff --git a/data/images/music-settings.png b/data/images/music-settings.png index aa4b8b6b3..356b1cf8a 100644 Binary files a/data/images/music-settings.png and b/data/images/music-settings.png differ diff --git a/data/images/user-avatar.png b/data/images/user-avatar.png index 75059d551..32a4b3895 100644 Binary files a/data/images/user-avatar.png and b/data/images/user-avatar.png differ diff --git a/lang/tomahawk_bg.ts b/lang/tomahawk_bg.ts index 1bc820745..1830d5928 100644 --- a/lang/tomahawk_bg.ts +++ b/lang/tomahawk_bg.ts @@ -194,12 +194,12 @@ Remember: Only allow peers to connect if you trust who they are and if you have AlbumView - + After you have scanned your music collection you will find your latest album additions right here. След като сканирате музикалната ви колекция, ще откриете най-скоро добавените албуми тук. - + This collection doesn't have any recent albums. В тази колекция все още няма добавени наскоро албуми @@ -241,17 +241,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have ArtistView - + After you have scanned your music collection you will find your tracks right here. След като приключи сканирането на музикалната ти колекция, ще откриеш твоята музика тук. - + This collection is currently empty. Базата данни с песни е празна. - + Sorry, your filter '%1' did not match any results. Съжалявам. Твоят филтър '%1' не върна никакъв резултат. @@ -333,17 +333,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have AudioEngine - + Tomahawk is stopped. Tomahawk е спрян - + Tomahawk is playing "%1" by %2%3. Tomahawk изпълнява "%1" от %2%3. - + on album %1 от албум %1 @@ -714,17 +714,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistLargeItemDelegate - + played %1 by you изпълнена %1 от мен - + played %1 by %2 изпълнена %1 от %2 - + added %1 добавен %1 @@ -793,7 +793,7 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistView - + This playlist is currently empty. Add some tracks to it and enjoy the music! Този списък в момента е празен. Добави няколко изпълнения и се наслади на музиката! @@ -1873,7 +1873,7 @@ Please change the filters or try again. Try tweaking the filters for a new set of songs to play. Станцията изчерпа изпълненията по зададените критерии. -Опитай да добевиш/въведеш нови за да продължи изпълнението. +Опитай да добавиш/въведеш нови за да продължи изпълнението. @@ -2311,29 +2311,29 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::LastFmPlugin - + Top Tracks - + Най-актуални песни - + Loved Tracks - + Харесвани песни - + Hyped Tracks - + Песни слушани най-често - + Top Artists - + Най-слушани артисти - + Hyped Artists - + Артисти слушани най-често @@ -2349,27 +2349,27 @@ Try tweaking the filters for a new set of songs to play. New Playlist - + Нов списък Failed to save tracks - + Неуспех при запаметяване на песни Some tracks in the playlist do not contain an artist and a title. They will be ignored. - + Някои песни в списъкът за изпълнение нямат артист и заглавие. Те ще бъдат игнорирани. XSPF Error - + XSPF грешка This is not a valid XSPF playlist. - + Това не е валиден XSPF списък @@ -2389,39 +2389,39 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and и - + You Ти - + you ти - + and и - + %n other(s) - % други + %n друг%n други - + %1 people %1 хора - + loved this track - + хареса тази песен @@ -2446,32 +2446,32 @@ Try tweaking the filters for a new set of songs to play. Scanning (%L1 tracks) - + Сканиране (%L1 песни) Scanning - + Сканирам Checking - + Проверявам Fetching - + Извличам Parsing - + Сортирам Saving (%1%) - + Запазвам (%1%) @@ -2485,7 +2485,7 @@ Try tweaking the filters for a new set of songs to play. TomahawkApp - + My Collection Моята колекция @@ -2502,7 +2502,7 @@ Try tweaking the filters for a new set of songs to play. After authenticating on Twitter's web site, enter the displayed PIN number here: След удостоверяване в Twitter, - въведете генерираният код тук: + въведи генерираният код тук: @@ -2511,17 +2511,17 @@ enter the displayed PIN number here: Hide Tomahawk Window - + Скрий главният прозорец Show Tomahawk Window - + Покажи главният прозорец Currently not playing. - + В момента не се изпълнява нищо @@ -2629,12 +2629,12 @@ enter the displayed PIN number here: Show Offline Sources - Покажи източници извън интернет + Покажи източници извън линия Hide Offline Sources - Скрий източници извън интернет + Скрий източници извън линия @@ -2988,7 +2988,7 @@ enter the displayed PIN number here: TreeItemDelegate - + Unknown @@ -3058,12 +3058,12 @@ enter the displayed PIN number here: Configure this Twitter account - + Настрой Twitter профил The Twitter plugin allows you to discover and play music from your Twitter friends running Tomahawk and post messages to your account. - Тази приставка за Twitter ще ти позволи да откриваш и изпълняваш музика, от твоите приятели в Twitter ползващи Tomahawk и побликуващи съобщения в твоя профил. + Приставката за Twitter ще ти позволи да откриваш и изпълняваш музика, от твоите приятели ползващи Tomahawk и побликуващи съобщения в твоят профил. @@ -3089,12 +3089,12 @@ If you want to connect Tomahawk to your friends using Twitter, select the type o You can re-send a sync message at any time simply by sending another tweet using the button. -Ако само желаете да побликуваш съобщения, си готов. - Ако желаеш да се свържеш с твои приятели, ползващи Twitter, избери тип на съобщението и натисни бутонът от долу, за изпращане. -Трябва взаимно да се следвате, за да можете да ползвате функцията DM. След изпращане, бъди търпелив. Може да изминат няколко минути преди побликуване. +Трябва взаимно да се следвате, за да можете да ползвате функцията DM. +След изпращане, бъди търпелив. +Може да изминат няколко минути преди побликуване. -Можеш да изпращаш съобщения за повторно свързване по всяко време, само като натиснеш бутонът. +Можеш да изпращаш съобщения за повторно свързване по всяко време, само като натиснеш бутонът по-долу. @@ -3165,7 +3165,7 @@ You can re-send a sync message at any time simply by sending another tweet using No recently created playlists in your network. - Няма наскоро създавани списъзи в твоята мрежа + Не откривам наскоро създадени списъци в твоята мрежа diff --git a/lang/tomahawk_de.ts b/lang/tomahawk_de.ts index 2cca18a5a..e0e0817f4 100644 --- a/lang/tomahawk_de.ts +++ b/lang/tomahawk_de.ts @@ -195,12 +195,12 @@ Denk dran: Erlaube das nur, wenn du dem Anderen vertraust und du die Rechte zum AlbumView - + After you have scanned your music collection you will find your latest album additions right here. Nachdem Tomahawk deine Sammlung durchsucht hast siehst du hier deine neuesten Alben. - + This collection doesn't have any recent albums. Diese Sammlung ist leer. @@ -242,17 +242,17 @@ Denk dran: Erlaube das nur, wenn du dem Anderen vertraust und du die Rechte zum ArtistView - + After you have scanned your music collection you will find your tracks right here. Nachdem Tomahawk deine Sammlung durchsucht hat siehst du deine Lieder hier. - + This collection is currently empty. Diese Sammlung is momentan leer. - + Sorry, your filter '%1' did not match any results. Entschuldige, dein Filter '%1' erzeugte keine Ergebnisse. @@ -333,17 +333,17 @@ Denk dran: Erlaube das nur, wenn du dem Anderen vertraust und du die Rechte zum AudioEngine - + Tomahawk is stopped. Tomahawk ist gestoppt. - + Tomahawk is playing "%1" by %2%3. Tomahawk spielt "%1" von %2%3. - + on album %1 auf dem Album %1 @@ -713,17 +713,17 @@ Denk dran: Erlaube das nur, wenn du dem Anderen vertraust und du die Rechte zum PlaylistLargeItemDelegate - + played %1 by you angehört %1 von dir - + played %1 by %2 - + added %1 @@ -792,7 +792,7 @@ Denk dran: Erlaube das nur, wenn du dem Anderen vertraust und du die Rechte zum PlaylistView - + This playlist is currently empty. Add some tracks to it and enjoy the music! Diese Playliste ist derzeit leer. Füge einige Stücke hinzu und genieße die Musik! @@ -2302,27 +2302,27 @@ Versuch die Filter anzupassen für neue Lieder. Tomahawk::InfoSystem::LastFmPlugin - + Top Tracks Größte Hits - + Loved Tracks Lieblings Lieder - + Hyped Tracks Angesagte Stücke - + Top Artists - + Hyped Artists @@ -2380,37 +2380,37 @@ Versuch die Filter anzupassen für neue Lieder. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -2476,7 +2476,7 @@ Versuch die Filter anzupassen für neue Lieder. TomahawkApp - + My Collection Meine Sammlung @@ -2977,7 +2977,7 @@ Tomahawk auf Twitter's Website authentifiziert hast: TreeItemDelegate - + Unknown Unbekannt diff --git a/lang/tomahawk_en.ts b/lang/tomahawk_en.ts index ef71723be..8581dd5ee 100644 --- a/lang/tomahawk_en.ts +++ b/lang/tomahawk_en.ts @@ -195,12 +195,12 @@ Remember: Only allow peers to connect if you trust who they are and if you have AlbumView - + After you have scanned your music collection you will find your latest album additions right here. After you have scanned your music collection you will find your latest album additions right here. - + This collection doesn't have any recent albums. This collection doesn't have any recent albums. @@ -242,17 +242,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have ArtistView - + 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 currently empty. This collection is currently empty. - + Sorry, your filter '%1' did not match any results. Sorry, your filter '%1' did not match any results. @@ -333,17 +333,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have AudioEngine - + Tomahawk is stopped. Tomahawk is stopped. - + Tomahawk is playing "%1" by %2%3. Tomahawk is playing "%1" by %2%3. - + on album %1 on album %1 @@ -713,17 +713,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistLargeItemDelegate - + played %1 by you played %1 by you - + played %1 by %2 played %1 by %2 - + added %1 added %1 @@ -792,7 +792,7 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistView - + This playlist is currently empty. Add some tracks to it and enjoy the music! This playlist is currently empty. Add some tracks to it and enjoy the music! @@ -2309,27 +2309,27 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::LastFmPlugin - + Top Tracks Top Tracks - + Loved Tracks Loved Tracks - + Hyped Tracks Hyped Tracks - + Top Artists Top Artists - + Hyped Artists Hyped Artists @@ -2387,37 +2387,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and and - + You You - + you you - + and and - + %n other(s) %n other%n others - + %1 people %1 people - + loved this track loved this track @@ -2483,7 +2483,7 @@ Try tweaking the filters for a new set of songs to play. TomahawkApp - + My Collection My Collection @@ -2984,7 +2984,7 @@ enter the displayed PIN number here: TreeItemDelegate - + Unknown Unknown diff --git a/lang/tomahawk_es.ts b/lang/tomahawk_es.ts index 7971aa187..b7826d6b4 100644 --- a/lang/tomahawk_es.ts +++ b/lang/tomahawk_es.ts @@ -193,12 +193,12 @@ Remember: Only allow peers to connect if you trust who they are and if you have AlbumView - + After you have scanned your music collection you will find your latest album additions right here. Tras haber escaneado su colección aquí encontrará los últimos álbumes añadidos. - + This collection doesn't have any recent albums. Esta colección no tiene álbumes recientes. @@ -240,17 +240,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have ArtistView - + After you have scanned your music collection you will find your tracks right here. Tras haber escaneado su colección aquí encontrará las últimas pistas añadidas. - + This collection is currently empty. Esta colección está vacía. - + Sorry, your filter '%1' did not match any results. Tu filtro '%1' no reportó ningún resultado. @@ -331,17 +331,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have AudioEngine - + Tomahawk is stopped. Tomahawk está parado. - + Tomahawk is playing "%1" by %2%3. Tomahawk está reproduciendo "%1" de %2%3. - + on album %1 @@ -711,17 +711,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistLargeItemDelegate - + played %1 by you - + played %1 by %2 - + added %1 @@ -790,7 +790,7 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistView - + This playlist is currently empty. Add some tracks to it and enjoy the music! Esta lista de reproducción está vacía. ¡Añada algunas pistas y disfrute de la música! @@ -2301,27 +2301,27 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::LastFmPlugin - + Top Tracks Pistas más escuchadas - + Loved Tracks Pistas favoritas - + Hyped Tracks Pistas en alza - + Top Artists Artistas más escuchados - + Hyped Artists Artistas en alza @@ -2379,37 +2379,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -2475,7 +2475,7 @@ Try tweaking the filters for a new set of songs to play. TomahawkApp - + My Collection Mi colección @@ -2976,7 +2976,7 @@ introduzca su número PIN aquí: TreeItemDelegate - + Unknown Desconocido diff --git a/lang/tomahawk_ja.ts b/lang/tomahawk_ja.ts index 96f4ed5b8..3b466e14d 100644 --- a/lang/tomahawk_ja.ts +++ b/lang/tomahawk_ja.ts @@ -193,12 +193,12 @@ Remember: Only allow peers to connect if you trust who they are and if you have AlbumView - + After you have scanned your music collection you will find your latest album additions right here. - + This collection doesn't have any recent albums. @@ -240,17 +240,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have ArtistView - + After you have scanned your music collection you will find your tracks right here. - + This collection is currently empty. - + Sorry, your filter '%1' did not match any results. @@ -331,17 +331,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have AudioEngine - + Tomahawk is stopped. - + Tomahawk is playing "%1" by %2%3. - + on album %1 @@ -711,17 +711,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistLargeItemDelegate - + played %1 by you - + played %1 by %2 - + added %1 @@ -790,7 +790,7 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistView - + This playlist is currently empty. Add some tracks to it and enjoy the music! @@ -2298,27 +2298,27 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::LastFmPlugin - + Top Tracks - + Loved Tracks - + Hyped Tracks - + Top Artists - + Hyped Artists @@ -2376,37 +2376,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -2472,7 +2472,7 @@ Try tweaking the filters for a new set of songs to play. TomahawkApp - + My Collection @@ -2972,7 +2972,7 @@ enter the displayed PIN number here: TreeItemDelegate - + Unknown diff --git a/lang/tomahawk_pl.ts b/lang/tomahawk_pl.ts index fc3aeaf89..152566d00 100644 --- a/lang/tomahawk_pl.ts +++ b/lang/tomahawk_pl.ts @@ -193,12 +193,12 @@ Remember: Only allow peers to connect if you trust who they are and if you have AlbumView - + After you have scanned your music collection you will find your latest album additions right here. Po zeskanowaniu swojej kolekcji muzycznej znajdziesz ostatnio dodane albumy właśnie tutaj. - + This collection doesn't have any recent albums. Ta kolekcja nie zawiera żadnych nowo dodanych albumów. @@ -240,17 +240,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have ArtistView - + After you have scanned your music collection you will find your tracks right here. Po zeskanowaniu swojej kolekcji muzycznej znajdziesz utwory właśnie tutaj. - + This collection is currently empty. Ta kolekcja jest aktualnie pusta. - + Sorry, your filter '%1' did not match any results. Przepraszamy, twój filtr %1' nie pasuje do żadnych wyników. @@ -331,17 +331,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have AudioEngine - + Tomahawk is stopped. Tomahawk jest zatrzymany. - + Tomahawk is playing "%1" by %2%3. Tomahawk odtwarza "%1" wykonawcy %2%3. - + on album %1 @@ -711,17 +711,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistLargeItemDelegate - + played %1 by you - + played %1 by %2 - + added %1 @@ -790,7 +790,7 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistView - + This playlist is currently empty. Add some tracks to it and enjoy the music! Ta lista jest aktualnie pusta. Dodaj do niej trochę piosenek i ciesz się muzyką! @@ -2302,27 +2302,27 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::LastFmPlugin - + Top Tracks - + Loved Tracks - + Hyped Tracks - + Top Artists - + Hyped Artists @@ -2380,37 +2380,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -2476,7 +2476,7 @@ Try tweaking the filters for a new set of songs to play. TomahawkApp - + My Collection Moja Kolekcja @@ -2977,7 +2977,7 @@ wprowadź pokazany numer PIN tutaj: TreeItemDelegate - + Unknown Nieznany diff --git a/lang/tomahawk_pt_BR.ts b/lang/tomahawk_pt_BR.ts index bb207db70..567e2fdb7 100644 --- a/lang/tomahawk_pt_BR.ts +++ b/lang/tomahawk_pt_BR.ts @@ -193,12 +193,12 @@ Remember: Only allow peers to connect if you trust who they are and if you have AlbumView - + After you have scanned your music collection you will find your latest album additions right here. Depois que você escanear a sua biblioteca musical você encontrará aqui o último álbum adicionado. - + This collection doesn't have any recent albums. Essa biblioteca não tem nenhum álbum recente. @@ -240,17 +240,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have ArtistView - + After you have scanned your music collection you will find your tracks right here. Depois que você escanear a sua biblioteca musical você encontrará aqui as suas faixas. - + This collection is currently empty. Essa biblioteca está vazia. - + Sorry, your filter '%1' did not match any results. Desculpe, o seu filtro '%1' não encontreou nenhum resultado. @@ -331,17 +331,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have AudioEngine - + Tomahawk is stopped. Tomahawk está inativo. - + Tomahawk is playing "%1" by %2%3. Tomahawk está reproduzindo "%1" por %2%3. - + on album %1 @@ -711,17 +711,17 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistLargeItemDelegate - + played %1 by you - + played %1 by %2 - + added %1 @@ -790,7 +790,7 @@ Remember: Only allow peers to connect if you trust who they are and if you have PlaylistView - + This playlist is currently empty. Add some tracks to it and enjoy the music! Esta lista de reprodução está vazia. Adicione algumas faixas para disfrutar de uma música! @@ -2301,27 +2301,27 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::LastFmPlugin - + Top Tracks Faixas principais - + Loved Tracks Faixas favoritas - + Hyped Tracks Faixas mais populares - + Top Artists Artistas principais - + Hyped Artists Artistas mais populares @@ -2379,37 +2379,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -2475,7 +2475,7 @@ Try tweaking the filters for a new set of songs to play. TomahawkApp - + My Collection Minha biblioteca @@ -2976,7 +2976,7 @@ colocar o número PIN mostrado aqui: TreeItemDelegate - + Unknown Desconhecido diff --git a/lang/tomahawk_sv.ts b/lang/tomahawk_sv.ts index 70b7db6cb..9d4b9ac2b 100644 --- a/lang/tomahawk_sv.ts +++ b/lang/tomahawk_sv.ts @@ -195,12 +195,12 @@ Kom ihåg: Tillåt endast anslutning från klienter du litar på, och som har la AlbumView - + After you have scanned your music collection you will find your latest album additions right here. Efter att du har scannat din musiksamling kommer du finna dina senaste tillagda album här. - + This collection doesn't have any recent albums. Den här samlingen inga nya album. @@ -242,17 +242,17 @@ Kom ihåg: Tillåt endast anslutning från klienter du litar på, och som har la ArtistView - + After you have scanned your music collection you will find your tracks right here. Efter att du har scannat din musiksamling kommer du finna dina senaste tillagda låtar här. - + This collection is currently empty. Denna samling är tom. - + Sorry, your filter '%1' did not match any results. Tyvärr, ditt filter "%1" matchade inte några resultat. @@ -333,17 +333,17 @@ Kom ihåg: Tillåt endast anslutning från klienter du litar på, och som har la AudioEngine - + Tomahawk is stopped. Tomahawk är stoppad. - + Tomahawk is playing "%1" by %2%3. Tomahawk spelar upp "%1" av %2%3. - + on album %1 på album %1 @@ -713,17 +713,17 @@ Kom ihåg: Tillåt endast anslutning från klienter du litar på, och som har la PlaylistLargeItemDelegate - + played %1 by you %1 spelades av dig - + played %1 by %2 %1 spelades av %2 - + added %1 %1 tillagd @@ -792,7 +792,7 @@ Kom ihåg: Tillåt endast anslutning från klienter du litar på, och som har la PlaylistView - + This playlist is currently empty. Add some tracks to it and enjoy the music! Denna spellista är för närvarande tom. Lägg till några spår och njut av musiken! @@ -2299,27 +2299,27 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::InfoSystem::LastFmPlugin - + Top Tracks - + Loved Tracks - + Hyped Tracks - + Top Artists - + Hyped Artists @@ -2377,37 +2377,37 @@ Try tweaking the filters for a new set of songs to play. Tomahawk::Query - + and - + You - + you - + and - + %n other(s) - + %1 people - + loved this track @@ -2473,7 +2473,7 @@ Try tweaking the filters for a new set of songs to play. TomahawkApp - + My Collection @@ -2973,7 +2973,7 @@ enter the displayed PIN number here: TreeItemDelegate - + Unknown Okänt diff --git a/resources.qrc b/resources.qrc index 9ea770807..f1ad95bd6 100644 --- a/resources.qrc +++ b/resources.qrc @@ -140,5 +140,6 @@ data/sql/dbmigrate-27_to_28.sql data/images/process-stop.png data/icons/tomahawk-icon-128x128-grayscale.png + data/images/collection.png diff --git a/src/accounts/lastfm/lastfmplugin.cpp b/src/accounts/lastfm/lastfmplugin.cpp index 07f6895ab..833c1ec71 100644 --- a/src/accounts/lastfm/lastfmplugin.cpp +++ b/src/accounts/lastfm/lastfmplugin.cpp @@ -127,13 +127,14 @@ LastFmPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) void -LastFmPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ) +LastFmPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { Q_UNUSED( caller ) + Q_UNUSED( pushFlags ) switch ( type ) { case InfoSubmitNowPlaying: - nowPlaying( input ); + nowPlaying( pushInfoPair.second ); break; case InfoSubmitScrobble: @@ -142,7 +143,7 @@ LastFmPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoTy case InfoLove: case InfoUnLove: - sendLoveSong( type, input ); + sendLoveSong( type, pushInfoPair.second ); break; default: diff --git a/src/accounts/lastfm/lastfmplugin.h b/src/accounts/lastfm/lastfmplugin.h index b19b0b74e..6d84b2b3c 100644 --- a/src/accounts/lastfm/lastfmplugin.h +++ b/src/accounts/lastfm/lastfmplugin.h @@ -62,7 +62,7 @@ protected slots: virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ); - virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data ); + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ); private: void fetchCoverArt( Tomahawk::InfoSystem::InfoRequestData requestData ); diff --git a/src/accounts/xmpp/XmppInfoPlugin.cpp b/src/accounts/xmpp/XmppInfoPlugin.cpp index 27166c829..1b7a7c8cc 100644 --- a/src/accounts/xmpp/XmppInfoPlugin.cpp +++ b/src/accounts/xmpp/XmppInfoPlugin.cpp @@ -44,6 +44,10 @@ Tomahawk::InfoSystem::XmppInfoPlugin::XmppInfoPlugin(XmppSipPlugin* sipPlugin) m_pubSubManager = new Jreen::PubSub::Manager( sipPlugin->m_client ); m_pubSubManager->addEntityType< Jreen::Tune >(); + // Clear status + Jreen::Tune::Ptr tune( new Jreen::Tune() ); + m_pubSubManager->publishItems(QList() << tune, Jreen::JID()); + m_pauseTimer.setSingleShot( true ); connect( &m_pauseTimer, SIGNAL( timeout() ), this, SLOT( audioStopped() ) ); @@ -52,13 +56,19 @@ Tomahawk::InfoSystem::XmppInfoPlugin::XmppInfoPlugin(XmppSipPlugin* sipPlugin) Tomahawk::InfoSystem::XmppInfoPlugin::~XmppInfoPlugin() { - delete m_pubSubManager; + //Note: the next two lines don't currently work, because the deletion wipes out internally posted events, need to talk to euro about a fix + Jreen::Tune::Ptr tune( new Jreen::Tune() ); + m_pubSubManager->publishItems(QList() << tune, Jreen::JID()); + m_pubSubManager->deleteLater(); } void -Tomahawk::InfoSystem::XmppInfoPlugin::pushInfo(QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input) +Tomahawk::InfoSystem::XmppInfoPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { + Q_UNUSED( caller ) + Q_UNUSED( pushFlags ) + tDebug() << Q_FUNC_INFO << m_sipPlugin->m_client->jid().full(); if( m_sipPlugin->m_account->configuration().value("publishtracks").toBool() == false ) @@ -72,8 +82,7 @@ Tomahawk::InfoSystem::XmppInfoPlugin::pushInfo(QString caller, Tomahawk::InfoSys case InfoNowPlaying: case InfoNowResumed: m_pauseTimer.stop(); - if ( input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) - audioStarted( input.value< Tomahawk::InfoSystem::InfoStringHash >() ); + audioStarted( pushInfoPair ); break; case InfoNowPaused: m_pauseTimer.start( PAUSE_TIMEOUT * 1000 ); @@ -91,18 +100,29 @@ Tomahawk::InfoSystem::XmppInfoPlugin::pushInfo(QString caller, Tomahawk::InfoSys void -Tomahawk::InfoSystem::XmppInfoPlugin::audioStarted(const Tomahawk::InfoSystem::InfoStringHash& info) +Tomahawk::InfoSystem::XmppInfoPlugin::audioStarted( const Tomahawk::InfoSystem::PushInfoPair &pushInfoPair ) { + if ( !pushInfoPair.second.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + { + tDebug() << Q_FUNC_INFO << "did not find an infostringhash"; + return; + } + + Tomahawk::InfoSystem::InfoStringHash info = pushInfoPair.second.value< Tomahawk::InfoSystem::InfoStringHash >(); tDebug() << Q_FUNC_INFO << m_sipPlugin->m_client->jid().full() << info; - + Jreen::Tune::Ptr tune( new Jreen::Tune() ); tune->setTitle( info.value( "title" ) ); tune->setArtist( info.value( "artist" ) ); tune->setLength( info.value("duration").toInt() ); tune->setTrack( info.value("albumpos") ); - tune->setUri( GlobalActionManager::instance()->openLink( info.value( "title" ), info.value( "artist" ), info.value( "album" ) ) ); + if ( pushInfoPair.first.contains( "shorturl" ) ) + tune->setUri( pushInfoPair.first[ "shorturl" ].toUrl() ); + else + tune->setUri( GlobalActionManager::instance()->openLink( info.value( "title" ), info.value( "artist" ), info.value( "album" ) ) ); + tDebug() << Q_FUNC_INFO << "Setting URI of " << tune->uri().toString(); //TODO: provide a rating once available in Tomahawk tune->setRating( 10 ); diff --git a/src/accounts/xmpp/XmppInfoPlugin.h b/src/accounts/xmpp/XmppInfoPlugin.h index f7d298de4..96f515381 100644 --- a/src/accounts/xmpp/XmppInfoPlugin.h +++ b/src/accounts/xmpp/XmppInfoPlugin.h @@ -47,11 +47,11 @@ namespace Tomahawk { void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ); protected slots: - void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ); + void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ); void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); private slots: - void audioStarted( const Tomahawk::InfoSystem::InfoStringHash& info ); + void audioStarted( const Tomahawk::InfoSystem::PushInfoPair& pushInfoPair ); void audioStopped(); void audioPaused(); diff --git a/src/accounts/xmpp/sip/xmppsip.cpp b/src/accounts/xmpp/sip/xmppsip.cpp index 56981e75e..10fb265b4 100644 --- a/src/accounts/xmpp/sip/xmppsip.cpp +++ b/src/accounts/xmpp/sip/xmppsip.cpp @@ -213,7 +213,7 @@ XmppSipPlugin::connectPlugin() QTimer::singleShot( 1000, m_client, SLOT( connectToServer() ) ); if ( m_client->connection() ) - connect(m_client->connection(), SIGNAL(error(SocketError)), SLOT(onError(SocketError))); + connect(m_client->connection(), SIGNAL(error(Jreen::Connection::SocketError)), SLOT(onError(Jreen::Connection::SocketError))); m_state = Account::Connecting; emit stateChanged( m_state ); diff --git a/src/audiocontrols.cpp b/src/audiocontrols.cpp index f680ba9b4..64190e9bc 100644 --- a/src/audiocontrols.cpp +++ b/src/audiocontrols.cpp @@ -358,7 +358,7 @@ void AudioControls::onPlaybackTimer( qint64 msElapsed ) { const int seconds = msElapsed / 1000; - if ( seconds != m_lastTextSecondShown ) + if ( seconds != m_lastTextSecondShown && !m_currentTrack.isNull() ) { ui->timeLabel->setText( TomahawkUtils::timeToString( seconds ) ); ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( m_currentTrack->duration() - seconds ) ); diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 78401e69c..797f2acb1 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -120,6 +120,7 @@ set( libGuiSources utils/proxystyle.cpp utils/tomahawkutilsgui.cpp utils/closure.cpp + utils/PixmapDelegateFader.cpp widgets/animatedcounterlabel.cpp widgets/checkdirtree.cpp diff --git a/src/libtomahawk/TomahawkSettingsGui.cpp b/src/libtomahawk/TomahawkSettingsGui.cpp index 32f70a4b8..829381a38 100644 --- a/src/libtomahawk/TomahawkSettingsGui.cpp +++ b/src/libtomahawk/TomahawkSettingsGui.cpp @@ -44,7 +44,7 @@ TomahawkSettingsGui::~TomahawkSettingsGui() QString TomahawkSettingsGui::storageCacheLocation() const { - return QDesktopServices::storageLocation( QDesktopServices::CacheLocation ) + "/InfoSystemCache/"; + return QDesktopServices::storageLocation( QDesktopServices::CacheLocation ); } diff --git a/src/libtomahawk/album.cpp b/src/libtomahawk/album.cpp index 3b52e7166..1ea9fe8c1 100644 --- a/src/libtomahawk/album.cpp +++ b/src/libtomahawk/album.cpp @@ -78,6 +78,7 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr& , m_name( name ) , m_artist( artist ) , m_infoLoaded( false ) + , m_infoLoading( false ) #ifndef ENABLE_HEADLESS , m_cover( 0 ) #endif @@ -107,11 +108,11 @@ Album::artist() const QPixmap Album::cover( const QSize& size, bool forceLoad ) const { - if ( !m_infoLoaded ) + if ( !m_infoLoaded && !m_infoLoading ) { if ( !forceLoad ) return QPixmap(); - + m_uuid = uuid(); Tomahawk::InfoSystem::InfoStringHash trackInfo; @@ -127,12 +128,14 @@ Album::cover( const QSize& size, bool forceLoad ) const 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 ) ) ); Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); + + m_infoLoading = true; } if ( !m_cover && !m_coverBuffer.isEmpty() ) @@ -163,7 +166,7 @@ Album::cover( const QSize& size, bool forceLoad ) const void -Album::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) +Album::infoSystemInfo( const Tomahawk::InfoSystem::InfoRequestData& requestData, const QVariant& output ) { if ( requestData.caller != m_uuid || requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt ) @@ -178,22 +181,22 @@ Album::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVaria if ( ba.length() ) { m_coverBuffer = ba; + + emit coverChanged(); } } } void -Album::infoSystemFinished( QString target ) +Album::infoSystemFinished( const QString& target ) { - Q_UNUSED( target ); - if ( target != m_uuid ) return; 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 ) ) ); diff --git a/src/libtomahawk/album.h b/src/libtomahawk/album.h index 07ab9a75f..42c6344bf 100644 --- a/src/libtomahawk/album.h +++ b/src/libtomahawk/album.h @@ -60,12 +60,13 @@ public: signals: void tracksAdded( const QList& tracks ); void updated(); + void coverChanged(); private slots: void onTracksAdded( const QList& tracks ); - void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); - void infoSystemFinished( QString target ); + void infoSystemInfo( const Tomahawk::InfoSystem::InfoRequestData& requestData, const QVariant& output ); + void infoSystemFinished( const QString& target ); private: Q_DISABLE_COPY( Album ) @@ -75,6 +76,7 @@ private: artist_ptr m_artist; QByteArray m_coverBuffer; bool m_infoLoaded; + mutable bool m_infoLoading; mutable QString m_uuid; #ifndef ENABLE_HEADLESS diff --git a/src/libtomahawk/artist.cpp b/src/libtomahawk/artist.cpp index d2b124240..f2830ff0e 100644 --- a/src/libtomahawk/artist.cpp +++ b/src/libtomahawk/artist.cpp @@ -77,6 +77,7 @@ Artist::Artist( unsigned int id, const QString& name ) , m_id( id ) , m_name( name ) , m_infoLoaded( false ) + , m_infoLoading( false ) #ifndef ENABLE_HEADLESS , m_cover( 0 ) #endif @@ -99,7 +100,7 @@ Artist::onTracksAdded( const QList& tracks ) QPixmap Artist::cover( const QSize& size, bool forceLoad ) const { - if ( !m_infoLoaded ) + if ( !m_infoLoaded && !m_infoLoading ) { if ( !forceLoad ) return QPixmap(); @@ -117,12 +118,14 @@ Artist::cover( const QSize& size, bool forceLoad ) const 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 ) ) ); Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData ); + + m_infoLoading = true; } if ( !m_cover && !m_coverBuffer.isEmpty() ) @@ -168,6 +171,7 @@ Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVari if ( ba.length() ) { m_coverBuffer = ba; + emit coverChanged(); } } } @@ -177,13 +181,13 @@ void Artist::infoSystemFinished( QString target ) { Q_UNUSED( target ); - + if ( target != m_uuid ) return; 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 ) ) ); diff --git a/src/libtomahawk/artist.h b/src/libtomahawk/artist.h index 8c8153441..fcd3c6f29 100644 --- a/src/libtomahawk/artist.h +++ b/src/libtomahawk/artist.h @@ -59,6 +59,7 @@ public: signals: void tracksAdded( const QList& tracks ); void updated(); + void coverChanged(); private slots: void onTracksAdded( const QList& tracks ); @@ -74,6 +75,7 @@ private: QString m_sortname; QByteArray m_coverBuffer; bool m_infoLoaded; + mutable bool m_infoLoading; mutable QString m_uuid; #ifndef ENABLE_HEADLESS diff --git a/src/libtomahawk/audio/audioengine.cpp b/src/libtomahawk/audio/audioengine.cpp index 492c112bb..31129bc0e 100644 --- a/src/libtomahawk/audio/audioengine.cpp +++ b/src/libtomahawk/audio/audioengine.cpp @@ -148,7 +148,8 @@ AudioEngine::play() Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowResumed, - QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ) ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ), + Tomahawk::InfoSystem::PushNoFlag ); } } else @@ -164,7 +165,7 @@ AudioEngine::pause() m_mediaObject->pause(); emit paused(); - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPaused, QVariant() ); + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPaused, QVariant(), Tomahawk::InfoSystem::PushNoFlag ); } @@ -199,7 +200,7 @@ AudioEngine::stop() map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< QVariantMap >( stopInfo ); } - Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map ); + Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map, Tomahawk::InfoSystem::PushNoFlag ); } @@ -332,7 +333,8 @@ AudioEngine::sendWaitingNotificationSlot() const retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track from this source." ); Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, - QVariant::fromValue< QVariantMap >( retryInfo ) ); + QVariant::fromValue< QVariantMap >( retryInfo ), + Tomahawk::InfoSystem::PushNoFlag ); } @@ -354,6 +356,7 @@ AudioEngine::sendNowPlayingNotification() void AudioEngine::onNowPlayingInfoReady() { + tDebug( LOGVERBOSE ) << Q_FUNC_INFO; if ( m_currentTrack.isNull() || m_currentTrack->track().isNull() || m_currentTrack->artist().isNull() ) @@ -379,7 +382,8 @@ AudioEngine::onNowPlayingInfoReady() Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser, - QVariant::fromValue< QVariantMap >( playInfo ) ); + QVariant::fromValue< QVariantMap >( playInfo ), + Tomahawk::InfoSystem::PushNoFlag ); } @@ -474,7 +478,8 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result ) Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowPlaying, - QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ) ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ), + Tomahawk::InfoSystem::PushShortUrlFlag ); } } } diff --git a/src/libtomahawk/context/ContextWidget.cpp b/src/libtomahawk/context/ContextWidget.cpp index a778dcaf7..ec11afaaf 100644 --- a/src/libtomahawk/context/ContextWidget.cpp +++ b/src/libtomahawk/context/ContextWidget.cpp @@ -96,7 +96,7 @@ ContextWidget::ContextWidget( QWidget* parent ) ensurePolished(); QPalette pal = palette(); - pal.setBrush( QPalette::Window, StyleHelper::headerLowerColor() ); + pal.setBrush( QPalette::Window, QColor( "#454e59" ) ); setPalette( pal ); connect( ui->toggleButton, SIGNAL( clicked() ), SLOT( toggleSize() ) ); diff --git a/src/libtomahawk/globalactionmanager.cpp b/src/libtomahawk/globalactionmanager.cpp index f607c604a..03053f7ee 100644 --- a/src/libtomahawk/globalactionmanager.cpp +++ b/src/libtomahawk/globalactionmanager.cpp @@ -123,12 +123,12 @@ GlobalActionManager::openLink( const QString& title, const QString& artist, cons void -GlobalActionManager::shortenLink( const QUrl& url ) +GlobalActionManager::shortenLink( const QUrl& url, const QVariantMap &callbackMap ) { if ( QThread::currentThread() != thread() ) { qDebug() << "Reinvoking in correct thread:" << Q_FUNC_INFO; - QMetaObject::invokeMethod( this, "shortenLink", Qt::QueuedConnection, Q_ARG( QUrl, url ) ); + QMetaObject::invokeMethod( this, "shortenLink", Qt::QueuedConnection, Q_ARG( QUrl, url ), Q_ARG( QVariantMap, callbackMap ) ); return; } @@ -136,6 +136,8 @@ GlobalActionManager::shortenLink( const QUrl& url ) request.setUrl( url ); QNetworkReply *reply = TomahawkUtils::nam()->get( request ); + if ( !callbackMap.empty() ) + reply->setProperty( "callbackMap", callbackMap ); connect( reply, SIGNAL( finished() ), SLOT( shortenLinkRequestFinished() ) ); connect( reply, SIGNAL( error( QNetworkReply::NetworkError ) ), SLOT( shortenLinkRequestError( QNetworkReply::NetworkError ) ) ); } @@ -894,10 +896,14 @@ GlobalActionManager::shortenLinkRequestFinished() // NOTE: this should never happen if( !reply ) { - emit shortLinkReady( QUrl( "" ), QUrl( "" ) ); + emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() ); return; } + QVariantMap callbackMap; + if ( reply->property( "callbackMap" ).canConvert< QVariantMap >() && !reply->property( "callbackMap" ).toMap().isEmpty() ) + callbackMap = reply->property( "callbackMap" ).toMap(); + // Check for the redirect attribute, as this should be the shortened link QVariant urlVariant = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ); @@ -926,9 +932,9 @@ GlobalActionManager::shortenLinkRequestFinished() else { if ( !error ) - emit shortLinkReady( longUrl, shortUrl ); + emit shortLinkReady( longUrl, shortUrl, callbackMap ); else - emit shortLinkReady( longUrl, longUrl ); + emit shortLinkReady( longUrl, longUrl, callbackMap ); } reply->deleteLater(); @@ -946,12 +952,15 @@ GlobalActionManager::shortenLinkRequestError( QNetworkReply::NetworkError error // NOTE: this should never happen if( !reply ) { - emit shortLinkReady( QUrl( "" ), QUrl( "" ) ); + emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() ); return; } + QVariantMap callbackMap; + if ( reply->property( "callbackMap" ).canConvert< QVariantMap >() && !reply->property( "callbackMap" ).toMap().isEmpty() ) + callbackMap = reply->property( "callbackMap" ).toMap(); reply->deleteLater(); - emit shortLinkReady( QUrl( "" ), QUrl( "" ) ); + emit shortLinkReady( QUrl( "" ), QUrl( "" ), callbackMap ); } diff --git a/src/libtomahawk/globalactionmanager.h b/src/libtomahawk/globalactionmanager.h index a5ae08503..da8ad246f 100644 --- a/src/libtomahawk/globalactionmanager.h +++ b/src/libtomahawk/globalactionmanager.h @@ -56,7 +56,7 @@ public: void savePlaylistToFile( const Tomahawk::playlist_ptr& playlist, const QString& filename ); public slots: - void shortenLink( const QUrl& url ); + void shortenLink( const QUrl& url, const QVariantMap &callbackMap = QVariantMap() ); bool parseTomahawkLink( const QString& link ); void waitingForResolved( bool ); @@ -67,7 +67,7 @@ public slots: void handlePlayTrack( const Tomahawk::query_ptr& qry ); signals: - void shortLinkReady( QUrl longUrl, QUrl shortUrl ) const; + void shortLinkReady( QUrl longUrl, QUrl shortUrl, QVariantMap callbackMap ) const; private slots: void shortenLinkRequestFinished(); diff --git a/src/libtomahawk/infosystem/infoplugins/generic/RoviPlugin.h b/src/libtomahawk/infosystem/infoplugins/generic/RoviPlugin.h index 27ff78021..e6ac23186 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/RoviPlugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/RoviPlugin.h @@ -42,8 +42,13 @@ public: protected: virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ); - virtual void pushInfo( QString, Tomahawk::InfoSystem::InfoType, QVariant ) - {} + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) + { + Q_UNUSED( caller ) + Q_UNUSED( type) + Q_UNUSED( pushInfoPair ) + Q_UNUSED( pushFlags ) + } virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); diff --git a/src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.h index 6649c2460..57c4f7b78 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.h @@ -60,11 +60,12 @@ protected slots: virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ); - virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data ) + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { Q_UNUSED( caller ) - Q_UNUSED( type ) - Q_UNUSED( data ) + Q_UNUSED( type) + Q_UNUSED( pushInfoPair ) + Q_UNUSED( pushFlags ) } private: diff --git a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h index 2278ae80c..92251de36 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/echonestplugin.h @@ -49,11 +49,12 @@ public: protected slots: virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); - virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { - Q_UNUSED( caller ); - Q_UNUSED( type ); - Q_UNUSED( data ); + Q_UNUSED( caller ) + Q_UNUSED( type) + Q_UNUSED( pushInfoPair ) + Q_UNUSED( pushFlags ) } virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) diff --git a/src/libtomahawk/infosystem/infoplugins/generic/hypemPlugin.h b/src/libtomahawk/infosystem/infoplugins/generic/hypemPlugin.h index 773cd0e5f..9ad833a01 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/hypemPlugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/hypemPlugin.h @@ -58,11 +58,12 @@ public slots: protected slots: virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ); - virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ) + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { Q_UNUSED( caller ) Q_UNUSED( type) - Q_UNUSED( input ) + Q_UNUSED( pushInfoPair ) + Q_UNUSED( pushFlags ) } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/musicbrainzPlugin.h b/src/libtomahawk/infosystem/infoplugins/generic/musicbrainzPlugin.h index b6d1cc6bd..c3e485553 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/musicbrainzPlugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/musicbrainzPlugin.h @@ -43,11 +43,12 @@ protected slots: virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); virtual void notInCacheSlot( InfoStringHash criteria, InfoRequestData requestData ); - virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data ) + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { - Q_UNUSED( caller ); - Q_UNUSED( type ); - Q_UNUSED( data ); + Q_UNUSED( caller ) + Q_UNUSED( type) + Q_UNUSED( pushInfoPair ) + Q_UNUSED( pushFlags ) } diff --git a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h index 1faf32506..407fd6ee7 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/musixmatchplugin.h @@ -46,11 +46,12 @@ public slots: protected slots: virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); - virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data ) + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { - Q_UNUSED( caller ); - Q_UNUSED( type ); - Q_UNUSED( data ); + Q_UNUSED( caller ) + Q_UNUSED( type) + Q_UNUSED( pushInfoPair ) + Q_UNUSED( pushFlags ) } virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) diff --git a/src/libtomahawk/infosystem/infoplugins/generic/spotifyPlugin.h b/src/libtomahawk/infosystem/infoplugins/generic/spotifyPlugin.h index ed73fb81e..644bbf383 100644 --- a/src/libtomahawk/infosystem/infoplugins/generic/spotifyPlugin.h +++ b/src/libtomahawk/infosystem/infoplugins/generic/spotifyPlugin.h @@ -58,11 +58,12 @@ public slots: protected slots: virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ); - virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input ) + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { Q_UNUSED( caller ) Q_UNUSED( type) - Q_UNUSED( input ) + Q_UNUSED( pushInfoPair ) + Q_UNUSED( pushFlags ) } private: diff --git a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp index de3c8715e..7502e8525 100644 --- a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.cpp @@ -74,9 +74,6 @@ AdiumPlugin::AdiumPlugin() m_pauseTimer->setSingleShot( true ); connect( m_pauseTimer, SIGNAL( timeout() ), this, SLOT( clearStatus() ) ); - - connect( GlobalActionManager::instance(), SIGNAL( shortLinkReady( QUrl, QUrl ) ), - SLOT( shortLinkReady( QUrl, QUrl ) ) ); } @@ -87,33 +84,6 @@ AdiumPlugin::~AdiumPlugin() setStatus( "" ); } -void -AdiumPlugin::shortLinkReady( QUrl longUrl, QUrl shortUrl ) -{ - // The URL we received is either from a previous track, or not requested by us - if( longUrl != m_currentLongUrl ) - return; - - // Build the core of the now-playing string - QString nowPlaying = ""; - nowPlaying.append( m_currentArtist ); - nowPlaying.append(" - "); - nowPlaying.append( m_currentTitle ); - nowPlaying.replace( "\"", "\\\"" ); // Escape quotes, or Applescript gets confused - - // We failed to get the short URL, just update the status with the metadata - if( ( longUrl.toString() == "" ) ) - { - setStatus( nowPlaying ); - return; - } - - // Add the short URL - nowPlaying.append( " " ); - nowPlaying.append( shortUrl.toEncoded() ); - setStatus( nowPlaying ); - -} void AdiumPlugin::clearStatus() @@ -131,7 +101,7 @@ AdiumPlugin::settingsChanged() void -AdiumPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ) +AdiumPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { qDebug() << Q_FUNC_INFO; @@ -141,13 +111,13 @@ AdiumPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVar switch ( type ) { case InfoNowPlaying: - audioStarted( input ); + audioStarted( pushInfoPair ); break; case InfoNowPaused: audioPaused(); return; case InfoNowResumed: - audioResumed( input ); + audioResumed( pushInfoPair ); break; case InfoNowStopped: audioStopped(); @@ -164,14 +134,15 @@ AdiumPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVar /** Audio state slots */ void -AdiumPlugin::audioStarted( const QVariant &input ) +AdiumPlugin::audioStarted( const Tomahawk::InfoSystem::PushInfoPair pushInfoPair ) { - qDebug() << Q_FUNC_INFO; - - if ( !input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + if ( !pushInfoPair.second.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) return; - InfoStringHash hash = input.value< Tomahawk::InfoSystem::InfoStringHash >(); + Tomahawk::InfoSystem::InfoStringHash hash = pushInfoPair.second.value< Tomahawk::InfoSystem::InfoStringHash >(); + + qDebug() << Q_FUNC_INFO; + if ( !hash.contains( "title" ) || !hash.contains( "artist" ) ) return; @@ -179,24 +150,29 @@ AdiumPlugin::audioStarted( const QVariant &input ) m_currentArtist = hash["artist"]; // Request a short URL - m_currentLongUrl = openLinkFromHash( hash ); - GlobalActionManager::instance()->shortenLink( m_currentLongUrl ); -} + m_currentLongUrl = GlobalActionManager::instance()->openLink( hash.value( "title" ), hash.value( "artist" ), hash.value( "album" ) ); -QUrl -AdiumPlugin::openLinkFromHash( const Tomahawk::InfoSystem::InfoStringHash& hash ) const -{ - QString title, artist, album; + QUrl shortUrl = m_currentLongUrl; + if ( pushInfoPair.first.contains( "shortUrl" ) ) + shortUrl = pushInfoPair.first[ "shortUrl" ].toUrl(); + + QString nowPlaying = ""; + nowPlaying.append( m_currentArtist ); + nowPlaying.append(" - "); + nowPlaying.append( m_currentTitle ); + nowPlaying.replace( "\"", "\\\"" ); // Escape quotes, or Applescript gets confused - if( !hash.isEmpty() && hash.contains( "title" ) && hash.contains( "artist" ) ) + // We failed to get the short URL, just update the status with the metadata + if( ( m_currentLongUrl.toString() == "" ) ) { - title = hash["title"]; - artist = hash["artist"]; - if( hash.contains( "album" ) ) - album = hash["album"]; + setStatus( nowPlaying ); + return; } - return GlobalActionManager::instance()->openLink( title, artist, album ); + // Add the short URL + nowPlaying.append( " " ); + nowPlaying.append( shortUrl.toEncoded() ); + setStatus( nowPlaying ); } void @@ -220,9 +196,9 @@ AdiumPlugin::audioPaused() } void -AdiumPlugin::audioResumed( const QVariant &input ) +AdiumPlugin::audioResumed( const Tomahawk::InfoSystem::PushInfoPair pushInfoPair ) { qDebug() << Q_FUNC_INFO; - audioStarted( input ); + audioStarted( pushInfoPair ); } diff --git a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h index 4ccad297d..1238d4d11 100644 --- a/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/mac/adiumplugin.h @@ -47,7 +47,7 @@ protected slots: Q_UNUSED( requestData ); } - void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ); + void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ); public slots: virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) @@ -57,19 +57,15 @@ public slots: } private slots: - void shortLinkReady( QUrl longUrl, QUrl shortUrl ); - void clearStatus(); void settingsChanged(); private: - void audioStarted( const QVariant &input ); + void audioStarted( const Tomahawk::InfoSystem::PushInfoPair pushInfoPair ); void audioFinished( const QVariant &input ); void audioStopped(); void audioPaused(); - void audioResumed( const QVariant &input ); - - QUrl openLinkFromHash( const InfoStringHash& hash ) const; + void audioResumed( const Tomahawk::InfoSystem::PushInfoPair pushInfoPair ); bool m_active; QString m_beforeStatus; diff --git a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp index ea71ba3ff..fb82fc4a2 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp @@ -63,10 +63,12 @@ FdoNotifyPlugin::~FdoNotifyPlugin() } void -FdoNotifyPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant pushData ) +FdoNotifyPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { Q_UNUSED( caller ); + Q_UNUSED( pushFlags ); qDebug() << Q_FUNC_INFO; + QVariant pushData = pushInfoPair.second; if ( type != Tomahawk::InfoSystem::InfoNotifyUser || !pushData.canConvert< QVariantMap >() ) { qDebug() << Q_FUNC_INFO << " not the right type or could not convert the hash"; diff --git a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h index 13b8644fd..6b513f766 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.h @@ -42,7 +42,7 @@ protected slots: Q_UNUSED( requestData ); } - virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant pushData ); + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ); virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) { diff --git a/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.cpp b/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.cpp index 002ad5873..cb9ef87e6 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.cpp @@ -469,16 +469,17 @@ MprisPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) void -MprisPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ) +MprisPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { Q_UNUSED( caller ); + Q_UNUSED( pushFlags ); bool isPlayingInfo = false; switch ( type ) { case InfoNowPlaying: isPlayingInfo = true; - audioStarted( input ); + audioStarted( pushInfoPair.second ); break; case InfoNowPaused: isPlayingInfo = true; @@ -486,7 +487,7 @@ MprisPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVar break; case InfoNowResumed: isPlayingInfo = true; - audioResumed( input ); + audioResumed( pushInfoPair.second ); break; case InfoNowStopped: isPlayingInfo = true; diff --git a/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.h b/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.h index f6b94d231..f8db49d87 100644 --- a/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.h +++ b/src/libtomahawk/infosystem/infoplugins/unix/mprisplugin.h @@ -141,7 +141,7 @@ public slots: protected slots: void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); - void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ); + void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ); private slots: void stateChanged( AudioState newState, AudioState oldState ); diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index 17eaca963..94c62fd6f 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -172,23 +172,24 @@ InfoSystem::getInfo( const QString &caller, const QVariantMap &customData, const bool -InfoSystem::pushInfo( const QString &caller, const InfoType type, const QVariant& input ) +InfoSystem::pushInfo( const QString &caller, const InfoType type, const QVariant& input, const PushInfoFlags pushFlags ) { - tDebug() << Q_FUNC_INFO; + tDebug() << Q_FUNC_INFO << "type is " << type; if ( !m_inited || !m_infoSystemWorkerThreadController->worker() ) { init(); return false; } - QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ) ); + PushInfoPair currPair( QVariantMap(), input ); + QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( Tomahawk::InfoSystem::PushInfoPair, currPair ), Q_ARG( Tomahawk::InfoSystem::PushInfoFlags, pushFlags ) ); return true; } bool -InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input ) +InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input, const PushInfoFlags pushFlags ) { if ( !m_inited || !m_infoSystemWorkerThreadController->worker() ) { @@ -197,7 +198,10 @@ InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input ) } Q_FOREACH( InfoType type, input.keys() ) - QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input[ type ] ) ); + { + PushInfoPair currPair( QVariantMap(), input[ type ] ); + QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( Tomahawk::InfoSystem::PushInfoPair, currPair ), Q_ARG( Tomahawk::InfoSystem::PushInfoFlags, pushFlags ) ); + } return true; } diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index 64800ac4b..1f6cbf418 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -44,6 +44,11 @@ namespace InfoSystem { class InfoSystemCache; class InfoSystemWorker; +enum PushInfoFlags { // must be powers of 2 + PushNoFlag = 1, + PushShortUrlFlag = 2 +}; + enum InfoType { // as items are saved in cache, mark them here to not change them InfoNoInfo = 0, //WARNING: *ALWAYS* keep this first! InfoTrackID = 1, @@ -162,6 +167,7 @@ struct InfoRequestData { typedef QMap< InfoType, QVariant > InfoTypeMap; typedef QMap< InfoType, uint > InfoTimeoutMap; typedef QHash< QString, QString > InfoStringHash; +typedef QPair< QVariantMap, QVariant > PushInfoPair; class DLLEXPORT InfoPlugin : public QObject { @@ -183,7 +189,7 @@ signals: protected slots: virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) = 0; - virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data ) = 0; + virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair pushInfoPair, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) = 0; virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) = 0; protected: @@ -240,8 +246,8 @@ public: bool getInfo( const InfoRequestData &requestData ); //WARNING: if changing timeoutMillis above, also change in below function in .cpp file bool getInfo( const QString &caller, const QVariantMap &customData, const InfoTypeMap &inputMap, const InfoTimeoutMap &timeoutMap = InfoTimeoutMap(), bool allSources = false ); - bool pushInfo( const QString &caller, const InfoType type, const QVariant &input ); - bool pushInfo( const QString &caller, const InfoTypeMap &input ); + bool pushInfo( const QString &caller, const InfoType type, const QVariant &input, const PushInfoFlags pushFlags ); + bool pushInfo( const QString &caller, const InfoTypeMap &input, const PushInfoFlags pushFlags ); public slots: // InfoSystem takes ownership of InfoPlugins @@ -292,6 +298,9 @@ inline uint qHash( Tomahawk::InfoSystem::InfoStringHash hash ) Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoRequestData ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoStringHash ); +Q_DECLARE_METATYPE( Tomahawk::InfoSystem::PushInfoPair ); +Q_DECLARE_METATYPE( Tomahawk::InfoSystem::PushInfoFlags ); +Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoType ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoSystemCache* ); Q_DECLARE_METATYPE( QList< Tomahawk::InfoSystem::InfoStringHash > ); Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoPlugin* ); diff --git a/src/libtomahawk/infosystem/infosystemcache.cpp b/src/libtomahawk/infosystem/infosystemcache.cpp index 7d5893557..ac626ecd0 100644 --- a/src/libtomahawk/infosystem/infosystemcache.cpp +++ b/src/libtomahawk/infosystem/infosystemcache.cpp @@ -42,7 +42,7 @@ namespace InfoSystem InfoSystemCache::InfoSystemCache( QObject* parent ) : QObject( parent ) , m_cacheBaseDir( TomahawkSettings::instance()->storageCacheLocation() + "/InfoSystemCache/" ) - , m_cacheVersion( 2 ) + , m_cacheVersion( 3 ) { tDebug() << Q_FUNC_INFO; TomahawkSettings *s = TomahawkSettings::instance(); @@ -73,6 +73,27 @@ InfoSystemCache::~InfoSystemCache() tDebug() << Q_FUNC_INFO; } + +void +InfoSystemCache::performWipe( QString directory ) +{ + QDir dir; + for ( int i = InfoNoInfo; i <= InfoLastInfo; i++ ) + { + InfoType type = (InfoType)(i); + const QString cacheDirName = directory + QString::number( (int)type ); + QFileInfoList fileList = QDir( cacheDirName ).entryInfoList( QDir::Files | QDir::NoDotAndDotDot ); + foreach ( QFileInfo file, fileList ) + { + if ( !QFile::remove( file.canonicalFilePath() ) ) + tLog() << "During upgrade, failed to remove cache file " << file.canonicalFilePath(); + } + dir.rmdir( cacheDirName ); + } + dir.rmdir( directory ); +} + + void InfoSystemCache::doUpgrade( uint oldVersion, uint newVersion ) { @@ -82,17 +103,16 @@ InfoSystemCache::doUpgrade( uint oldVersion, uint newVersion ) { qDebug() << Q_FUNC_INFO << "Wiping cache"; - for ( int i = InfoNoInfo; i <= InfoLastInfo; i++ ) - { - InfoType type = (InfoType)(i); - const QString cacheDirName = m_cacheBaseDir + QString::number( (int)type ); - QFileInfoList fileList = QDir( cacheDirName ).entryInfoList( QDir::Files | QDir::NoDotAndDotDot ); - foreach ( QFileInfo file, fileList ) - { - if ( !QFile::remove( file.canonicalFilePath() ) ) - tLog() << "During upgrade, failed to remove cache file " << file.canonicalFilePath(); - } - } + performWipe( m_cacheBaseDir ); + } + + if ( oldVersion == 2 ) + { + qDebug() << Q_FUNC_INFO << "Wiping cache"; + + performWipe( m_cacheBaseDir ); + + performWipe( m_cacheBaseDir + "/InfoSystemCache/" ); } } diff --git a/src/libtomahawk/infosystem/infosystemcache.h b/src/libtomahawk/infosystem/infosystemcache.h index 1fae1ba74..aa2544816 100644 --- a/src/libtomahawk/infosystem/infosystemcache.h +++ b/src/libtomahawk/infosystem/infosystemcache.h @@ -56,6 +56,7 @@ private slots: private: void notInCache( QObject *receiver, Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ); void doUpgrade( uint oldVersion, uint newVersion ); + void performWipe( QString directory ); const QString criteriaMd5( const Tomahawk::InfoSystem::InfoStringHash &criteria, Tomahawk::InfoSystem::InfoType type = Tomahawk::InfoSystem::InfoNoInfo ) const; QString m_cacheBaseDir; diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index 787ae463b..03386dbc3 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -31,6 +31,7 @@ #include "infoplugins/generic/spotifyPlugin.h" #include "infoplugins/generic/musicbrainzPlugin.h" #include "infoplugins/generic/hypemPlugin.h" +#include "globalactionmanager.h" #include "utils/tomahawkutils.h" #include "utils/logger.h" @@ -78,6 +79,7 @@ void InfoSystemWorker::init( Tomahawk::InfoSystem::InfoSystemCache* cache ) { tDebug() << Q_FUNC_INFO; + m_shortLinksWaiting = 0; m_cache = cache; #ifndef ENABLE_HEADLESS addInfoPlugin( new EchoNestPlugin() ); @@ -113,20 +115,22 @@ InfoSystemWorker::addInfoPlugin( InfoPlugin* plugin ) SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), this, SLOT( infoSlot( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), - Qt::UniqueConnection + Qt::QueuedConnection ); connect( plugin, SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ), m_cache, - SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ) + SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoRequestData ) ), + Qt::QueuedConnection ); connect( plugin, SIGNAL( updateCache( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ), m_cache, - SLOT( updateCacheSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ) + SLOT( updateCacheSlot( Tomahawk::InfoSystem::InfoStringHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ), + Qt::QueuedConnection ); } @@ -216,18 +220,97 @@ InfoSystemWorker::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) void -InfoSystemWorker::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ) +InfoSystemWorker::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair input, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) { -// qDebug() << Q_FUNC_INFO; + tDebug() << Q_FUNC_INFO << "type is " << type; + + if ( pushFlags != PushNoFlag ) + { + if ( pushFlags & PushShortUrlFlag ) + { + pushFlags = Tomahawk::InfoSystem::PushInfoFlags( pushFlags & ~PushShortUrlFlag ); + QMetaObject::invokeMethod( this, "getShortUrl", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( Tomahawk::InfoSystem::PushInfoPair, input ), Q_ARG( Tomahawk::InfoSystem::PushInfoFlags, pushFlags ) ); + return; + } + } Q_FOREACH( InfoPluginPtr ptr, m_infoPushMap[ type ] ) { if( ptr ) - QMetaObject::invokeMethod( ptr.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ) ); + QMetaObject::invokeMethod( ptr.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( Tomahawk::InfoSystem::PushInfoPair, input ), Q_ARG( Tomahawk::InfoSystem::PushInfoFlags, pushFlags ) ); } } +void +InfoSystemWorker::getShortUrl( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair input, Tomahawk::InfoSystem::PushInfoFlags pushFlags ) +{ + tDebug() << Q_FUNC_INFO << "type is " << type; + if ( !input.second.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) + { + QMetaObject::invokeMethod( this, "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( Tomahawk::InfoSystem::PushInfoPair, input ), Q_ARG( Tomahawk::InfoSystem::PushInfoFlags, pushFlags ) ); + return; + } + + Tomahawk::InfoSystem::InfoStringHash hash = input.second.value< Tomahawk::InfoSystem::InfoStringHash >(); + + if ( hash.isEmpty() || !hash.contains( "title" ) || !hash.contains( "artist" ) ) + { + QMetaObject::invokeMethod( this, "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( Tomahawk::InfoSystem::PushInfoPair, input ), Q_ARG( Tomahawk::InfoSystem::PushInfoFlags, pushFlags ) ); + return; + } + + QString title, artist, album; + title = hash[ "title" ]; + artist = hash[ "artist" ]; + if( hash.contains( "album" ) ) + album = hash[ "album" ]; + + QUrl longUrl = GlobalActionManager::instance()->openLink( title, artist, album ); + + QVariantMap callbackMap; + callbackMap[ "caller" ] = caller; + callbackMap[ "type" ] = QVariant::fromValue< Tomahawk::InfoSystem::InfoType >( type ); + callbackMap[ "pushinfopair" ] = QVariant::fromValue< Tomahawk::InfoSystem::PushInfoPair >( input ); + callbackMap[ "pushflags" ] = QVariant::fromValue< Tomahawk::InfoSystem::PushInfoFlags >( pushFlags ); + GlobalActionManager::instance()->shortenLink( longUrl, callbackMap ); + connect( GlobalActionManager::instance(), SIGNAL( shortLinkReady( QUrl, QUrl, QVariantMap ) ), this, SLOT( shortLinkReady( QUrl, QUrl, QVariantMap ) ), Qt::UniqueConnection ); + m_shortLinksWaiting++; +} + + +void +InfoSystemWorker::shortLinkReady( QUrl longUrl, QUrl shortUrl, QVariantMap callbackMap ) +{ + tDebug() << Q_FUNC_INFO << "long url = " << longUrl << ", shortUrl = " << shortUrl; + m_shortLinksWaiting--; + if ( !m_shortLinksWaiting ) + disconnect( GlobalActionManager::instance(), SIGNAL( shortLinkReady( QUrl, QUrl, QVariantMap ) ) ); + + if ( callbackMap.isEmpty() || !callbackMap.contains( "caller" ) || !callbackMap.contains( "type" ) || !callbackMap.contains( "pushinfopair" ) || !callbackMap.contains( "pushflags" ) ) + { + tDebug() << Q_FUNC_INFO << "callback map was empty, cannot continue"; + return; + } + + QString caller = callbackMap[ "caller" ].toString(); + Tomahawk::InfoSystem::InfoType type = callbackMap[ "type" ].value< Tomahawk::InfoSystem::InfoType >(); + Tomahawk::InfoSystem::PushInfoPair pushInfoPair = callbackMap[ "pushinfopair" ].value< Tomahawk::InfoSystem::PushInfoPair >(); + Tomahawk::InfoSystem::PushInfoFlags pushFlags = callbackMap[ "pushflags" ].value< Tomahawk::InfoSystem::PushInfoFlags >(); + + if ( !shortUrl.isEmpty() && longUrl != shortUrl ) + { + QVariantMap flagProps = pushInfoPair.first; + flagProps[ "shorturl" ] = shortUrl; + pushInfoPair.first = flagProps; + } + + tDebug() << Q_FUNC_INFO << "pushInfoPair first is: " << pushInfoPair.first.keys(); + + QMetaObject::invokeMethod( this, "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( Tomahawk::InfoSystem::PushInfoPair, pushInfoPair ), Q_ARG( Tomahawk::InfoSystem::PushInfoFlags, pushFlags ) ); +} + + void InfoSystemWorker::infoSlot( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ) { diff --git a/src/libtomahawk/infosystem/infosystemworker.h b/src/libtomahawk/infosystem/infosystemworker.h index d9972bb7e..fbd22dd70 100644 --- a/src/libtomahawk/infosystem/infosystemworker.h +++ b/src/libtomahawk/infosystem/infosystemworker.h @@ -59,11 +59,15 @@ signals: public slots: void init( Tomahawk::InfoSystem::InfoSystemCache* cache ); void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ); - void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input ); + void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair input, Tomahawk::InfoSystem::PushInfoFlags pushFlags ); + void infoSlot( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output ); void addInfoPlugin( Tomahawk::InfoSystem::InfoPlugin* plugin ); + + void getShortUrl( QString caller, Tomahawk::InfoSystem::InfoType type, Tomahawk::InfoSystem::PushInfoPair input, Tomahawk::InfoSystem::PushInfoFlags pushFlags ); + void shortLinkReady( QUrl longUrl, QUrl shortUrl, QVariantMap callbackMap ); private slots: void checkTimeoutsTimerFired(); @@ -88,6 +92,8 @@ private: QMap< InfoType, QList< InfoPluginPtr > > m_infoPushMap; QTimer m_checkTimeoutsTimer; + + quint64 m_shortLinksWaiting; }; } diff --git a/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp b/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp index 760795143..e1b3de5a1 100644 --- a/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp +++ b/src/libtomahawk/playlist/PlaylistChartItemDelegate.cpp @@ -27,6 +27,7 @@ #include "source.h" #include "sourcelist.h" +#include "playlistview.h" #include "trackmodel.h" #include "trackmodelitem.h" #include "trackproxymodel.h" @@ -35,6 +36,8 @@ #include "utils/tomahawkutilsgui.h" #include "utils/logger.h" +#include +#include using namespace Tomahawk; @@ -55,6 +58,11 @@ PlaylistChartItemDelegate::PlaylistChartItemDelegate( TrackView* parent, TrackPr m_bottomOption = QTextOption( Qt::AlignBottom ); m_bottomOption.setWrapMode( QTextOption::NoWrap ); + + connect( m_model->sourceModel(), SIGNAL( modelReset() ), this, SLOT( modelChanged() ) ); + if ( PlaylistView* plView = qobject_cast< PlaylistView* >( parent ) ) + connect( plView, SIGNAL( modelChanged() ), this, SLOT( modelChanged() ) ); + } @@ -127,7 +135,7 @@ PlaylistChartItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& if ( m_view->header()->visualIndex( index.column() ) > 0 ) return; - QPixmap pixmap, avatar; + QPixmap avatar; QString artist, track, upperText, lowerText; unsigned int duration = 0; @@ -204,11 +212,15 @@ PlaylistChartItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& painter->setPen( opt.palette.text().color() ); QRect pixmapRect = r.adjusted( figureRect.width() + 6, 0, -option.rect.width() + figureRect.width() + option.rect.height() - 6 + r.left(), 0 ); - pixmap = item->query()->cover( pixmapRect.size(), false ); - if ( !pixmap ) + + if ( !m_pixmaps.contains( index ) ) { - pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::ScaledCover, pixmapRect.size() ); + m_pixmaps.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->query(), pixmapRect.size(), TomahawkUtils::ScaledCover, false ) ) ); + _detail::Closure* closure = NewClosure( m_pixmaps[ index ], SIGNAL( repaintRequest() ), const_cast(this), SLOT( doUpdateIndex( const QPersistentModelIndex& ) ), QPersistentModelIndex( index ) ); + closure->setAutoDelete( false ); } + + const QPixmap pixmap = m_pixmaps[ index ]->currentPixmap(); painter->drawPixmap( pixmapRect, pixmap ); r.adjust( pixmapRect.width() + figureRect.width() + 18, 1, -28, 0 ); @@ -232,3 +244,18 @@ PlaylistChartItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& } painter->restore(); } + + +void +PlaylistChartItemDelegate::doUpdateIndex( const QPersistentModelIndex& idx ) +{ + emit updateRequest( idx ); +} + + +void +PlaylistChartItemDelegate::modelChanged() +{ + m_pixmaps.clear(); +} + diff --git a/src/libtomahawk/playlist/PlaylistChartItemDelegate.h b/src/libtomahawk/playlist/PlaylistChartItemDelegate.h index 1819be8a0..7735c9cda 100644 --- a/src/libtomahawk/playlist/PlaylistChartItemDelegate.h +++ b/src/libtomahawk/playlist/PlaylistChartItemDelegate.h @@ -24,6 +24,10 @@ #include "dllmacro.h" +namespace Tomahawk { +class PixmapDelegateFader; +} + class TrackModel; class TrackModelItem; class TrackProxyModel; @@ -36,11 +40,18 @@ Q_OBJECT public: PlaylistChartItemDelegate( TrackView* parent = 0, TrackProxyModel* proxy = 0 ); +signals: + void updateRequest( const QModelIndex& idx ); + protected: void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; +private slots: + void modelChanged(); + void doUpdateIndex( const QPersistentModelIndex& idx ); + private: void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, TrackModelItem* item ) const; @@ -51,6 +62,8 @@ private: TrackView* m_view; TrackProxyModel* m_model; + + mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_pixmaps; }; #endif // PLAYLISTCHARTITEMDELEGATE_H diff --git a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp index 561e69366..8acdd6eda 100644 --- a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp +++ b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp @@ -28,6 +28,7 @@ #include "source.h" #include "sourcelist.h" +#include "playlistview.h" #include "trackmodel.h" #include "trackmodelitem.h" #include "trackproxymodel.h" @@ -36,6 +37,8 @@ #include "utils/tomahawkutilsgui.h" #include "utils/logger.h" +#include +#include using namespace Tomahawk; @@ -54,6 +57,10 @@ PlaylistLargeItemDelegate::PlaylistLargeItemDelegate( DisplayMode mode, TrackVie m_bottomOption = QTextOption( Qt::AlignBottom ); m_bottomOption.setWrapMode( QTextOption::NoWrap ); + + connect( proxy->sourceModel(), SIGNAL( modelReset() ), this, SLOT( modelChanged() ) ); + if ( PlaylistView* plView = qobject_cast< PlaylistView* >( parent ) ) + connect( plView, SIGNAL( modelChanged() ), this, SLOT( modelChanged() ) ); } @@ -129,7 +136,7 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& if ( m_view->header()->visualIndex( index.column() ) > 0 ) return; - QPixmap pixmap, avatar; + QPixmap avatar; QString artist, track, lowerText; unsigned int duration = 0; @@ -188,12 +195,15 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& QRect avatarRect = r.adjusted( option.rect.width() - r.left() - 12 - avatarSize.width(), ( option.rect.height() - avatarSize.height() ) / 2 - 5, 0, 0 ); avatarRect.setSize( avatarSize ); - pixmap = item->query()->cover( pixmapRect.size(), false ); - if ( !pixmap ) + + if ( !m_pixmaps.contains( index ) ) { - pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, TomahawkUtils::ScaledCover, pixmapRect.size() ); + m_pixmaps.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->query(), pixmapRect.size(), TomahawkUtils::ScaledCover, false ) ) ); + _detail::Closure* closure = NewClosure( m_pixmaps[ index ], SIGNAL( repaintRequest() ), const_cast(this), SLOT( doUpdateIndex( const QPersistentModelIndex& ) ), QPersistentModelIndex( index ) ); + closure->setAutoDelete( false ); } + const QPixmap pixmap = m_pixmaps[ index ]->currentPixmap(); painter->drawPixmap( pixmapRect, pixmap ); if ( !avatar.isNull() ) @@ -245,3 +255,18 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& } painter->restore(); } + + +void +PlaylistLargeItemDelegate::doUpdateIndex( const QPersistentModelIndex& idx ) +{ + if ( idx.isValid() ) + emit updateIndex( idx ); +} + + +void +PlaylistLargeItemDelegate::modelChanged() +{ + m_pixmaps.clear(); +} diff --git a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h index ad2210a75..7416b03f0 100644 --- a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h +++ b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h @@ -24,6 +24,11 @@ #include #include "dllmacro.h" +#include + +namespace Tomahawk { +class PixmapDelegateFader; +} class TrackModel; class TrackModelItem; @@ -45,6 +50,13 @@ protected: QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; +signals: + void updateIndex( const QModelIndex& idx ); + +private slots: + void modelChanged(); + void doUpdateIndex( const QPersistentModelIndex& idx ); + private: void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, TrackModelItem* item ) const; void drawRichText( QPainter* painter, const QRect& rect, int flags, QTextDocument& text ) const; @@ -53,6 +65,8 @@ private: QTextOption m_centerRightOption; QTextOption m_bottomOption; + mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_pixmaps; + TrackView* m_view; TrackProxyModel* m_model; DisplayMode m_mode; diff --git a/src/libtomahawk/playlist/albumitemdelegate.cpp b/src/libtomahawk/playlist/albumitemdelegate.cpp index b8c9072d2..705bfe0fa 100644 --- a/src/libtomahawk/playlist/albumitemdelegate.cpp +++ b/src/libtomahawk/playlist/albumitemdelegate.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011-2012, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,9 +29,12 @@ #include "utils/tomahawkutils.h" #include "utils/logger.h" +#include "utils/PixmapDelegateFader.h" +#include #include "playlist/albumitem.h" #include "playlist/albumproxymodel.h" +#include "albumview.h" #include #include @@ -40,6 +44,8 @@ AlbumItemDelegate::AlbumItemDelegate( QAbstractItemView* parent, AlbumProxyModel , m_view( parent ) , m_model( proxy ) { + if ( m_view && m_view->metaObject()->indexOfSignal( "modelChanged()" ) > -1 ) + connect( m_view, SIGNAL( modelChanged() ), this, SLOT( modelChanged() ) ); } @@ -89,18 +95,16 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, } QRect r = option.rect.adjusted( 6, 5, -6, -41 ); - QPixmap cover; - if ( !item->album().isNull() ) + + if ( !m_covers.contains( index ) ) { - cover = item->album()->cover( r.size() ); - if ( cover.isNull() ) - cover = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::CoverInCase, r.size() ); - } - else if ( !item->artist().isNull() ) - { - cover = item->artist()->cover( r.size() ); + m_covers.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->album(), r.size(), TomahawkUtils::CoverInCase ) ) ); + _detail::Closure* closure = NewClosure( m_covers[ index ], SIGNAL( repaintRequest() ), const_cast(this), SLOT( doUpdateIndex( const QPersistentModelIndex& ) ), QPersistentModelIndex( index ) ); + closure->setAutoDelete( false ); } + const QPixmap cover = m_covers[ index ]->currentPixmap(); + if ( option.state & QStyle::State_Selected ) { #if defined(Q_WS_MAC) || defined(Q_WS_WIN) @@ -258,3 +262,24 @@ AlbumItemDelegate::whitespaceMouseEvent() emit updateIndex( old ); } } + + +void +AlbumItemDelegate::modelChanged() +{ + m_artistNameRects.clear(); + m_hoveringOver = QPersistentModelIndex(); + + if ( AlbumView* view = qobject_cast< AlbumView* >( m_view ) ) + m_model = view->proxyModel(); +} + + +void +AlbumItemDelegate::doUpdateIndex( const QPersistentModelIndex& idx ) +{ + if ( !idx.isValid() ) + return; + emit updateIndex( idx ); +} + diff --git a/src/libtomahawk/playlist/albumitemdelegate.h b/src/libtomahawk/playlist/albumitemdelegate.h index 7d29f6c81..eabf4a8d4 100644 --- a/src/libtomahawk/playlist/albumitemdelegate.h +++ b/src/libtomahawk/playlist/albumitemdelegate.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2011-2012, Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,6 +24,10 @@ #include "dllmacro.h" +namespace Tomahawk { + class PixmapDelegateFader; +} + class QEvent; class AlbumProxyModel; @@ -40,16 +45,21 @@ protected: QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); -// QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; signals: void updateIndex( const QModelIndex& idx ); +private slots: + void modelChanged(); + void doUpdateIndex( const QPersistentModelIndex& idx ); + private: QAbstractItemView* m_view; AlbumProxyModel* m_model; mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects; + mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_covers; + QPersistentModelIndex m_hoveringOver; QPixmap m_shadowPixmap; diff --git a/src/libtomahawk/playlist/albumview.cpp b/src/libtomahawk/playlist/albumview.cpp index 98b5f0f37..27eadd6d3 100644 --- a/src/libtomahawk/playlist/albumview.cpp +++ b/src/libtomahawk/playlist/albumview.cpp @@ -112,6 +112,8 @@ AlbumView::setAlbumModel( AlbumModel* model ) connect( m_model, SIGNAL( itemCountChanged( unsigned int ) ), SLOT( onItemCountChanged( unsigned int ) ) ); connect( m_model, SIGNAL( loadingStarted() ), m_loadingSpinner, SLOT( fadeIn() ) ); connect( m_model, SIGNAL( loadingFinished() ), m_loadingSpinner, SLOT( fadeOut() ) ); + + emit modelChanged(); } diff --git a/src/libtomahawk/playlist/albumview.h b/src/libtomahawk/playlist/albumview.h index e19975a5d..fa4df45dd 100644 --- a/src/libtomahawk/playlist/albumview.h +++ b/src/libtomahawk/playlist/albumview.h @@ -66,6 +66,9 @@ public: public slots: void onItemActivated( const QModelIndex& index ); +signals: + void modelChanged(); + protected: virtual void startDrag( Qt::DropActions supportedActions ); diff --git a/src/libtomahawk/playlist/artistview.cpp b/src/libtomahawk/playlist/artistview.cpp index 9b74fa8a4..351c76d48 100644 --- a/src/libtomahawk/playlist/artistview.cpp +++ b/src/libtomahawk/playlist/artistview.cpp @@ -102,7 +102,9 @@ void ArtistView::setProxyModel( TreeProxyModel* model ) { m_proxyModel = model; - setItemDelegate( new TreeItemDelegate( this, m_proxyModel ) ); + TreeItemDelegate* del = new TreeItemDelegate( this, m_proxyModel ); + connect( del, SIGNAL( updateIndex( QModelIndex ) ), this, SLOT( update( QModelIndex ) ) ); + setItemDelegate( del ); QTreeView::setModel( m_proxyModel ); } diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index a5b8a4263..7d32c4c4d 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -80,6 +80,8 @@ PlaylistView::setPlaylistModel( PlaylistModel* model ) connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); connect( m_model, SIGNAL( playlistDeleted() ), SLOT( onDeleted() ) ); connect( m_model, SIGNAL( playlistChanged() ), SLOT( onChanged() ) ); + + emit modelChanged(); } diff --git a/src/libtomahawk/playlist/playlistview.h b/src/libtomahawk/playlist/playlistview.h index a02f10100..1a94f6890 100644 --- a/src/libtomahawk/playlist/playlistview.h +++ b/src/libtomahawk/playlist/playlistview.h @@ -56,6 +56,7 @@ public: signals: void nameChanged( const QString& title ); void destroyed( QWidget* widget ); + void modelChanged(); protected: void keyPressEvent( QKeyEvent* event ); diff --git a/src/libtomahawk/playlist/treeitemdelegate.cpp b/src/libtomahawk/playlist/treeitemdelegate.cpp index c5c6f2377..135bd41ec 100644 --- a/src/libtomahawk/playlist/treeitemdelegate.cpp +++ b/src/libtomahawk/playlist/treeitemdelegate.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2012 Leo Franchi * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +29,8 @@ #include "utils/tomahawkutilsgui.h" #include "utils/logger.h" +#include "utils/closure.h" +#include "utils/PixmapDelegateFader.h" #include "treemodelitem.h" #include "treeproxymodel.h" @@ -150,20 +153,24 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, QRect r = option.rect.adjusted( 4, 4, -option.rect.width() + option.rect.height() - 4, -4 ); // painter->drawPixmap( r, QPixmap( RESPATH "images/cover-shadow.png" ) ); - QPixmap cover; - if ( !item->album().isNull() ) + if ( !m_pixmaps.contains( index ) ) { - cover = item->album()->cover( r.size(), false ); - if ( cover.isNull() ) - cover = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, TomahawkUtils::ScaledCover, r.size() ); - } - else if ( !item->artist().isNull() ) - { - cover = item->artist()->cover( r.size(), false ); - if ( cover.isNull() ) - cover = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultArtistImage, TomahawkUtils::ScaledCover, r.size() ); + if ( !item->album().isNull() ) + { + m_pixmaps.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->album(), r.size(), TomahawkUtils::ScaledCover, false ) ) ); + _detail::Closure* closure = NewClosure( m_pixmaps[ index ], SIGNAL( repaintRequest() ), const_cast(this), SLOT( doUpdateIndex( const QPersistentModelIndex& ) ), QPersistentModelIndex( index ) ); + closure->setAutoDelete( false ); + } + else if ( !item->artist().isNull() ) + { + m_pixmaps.insert( index, QSharedPointer< Tomahawk::PixmapDelegateFader >( new Tomahawk::PixmapDelegateFader( item->artist(), r.size(), TomahawkUtils::ScaledCover, false ) ) ); + _detail::Closure* closure = NewClosure( m_pixmaps[ index ], SIGNAL( repaintRequest() ), const_cast(this), SLOT( doUpdateIndex( const QPersistentModelIndex& ) ), QPersistentModelIndex( index ) ); + closure->setAutoDelete( false ); + } } + const QPixmap cover = m_pixmaps[ index ]->currentPixmap(); + painter->drawPixmap( r, cover ); QTextOption to; @@ -175,3 +182,11 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, painter->restore(); } + + +void +TreeItemDelegate::doUpdateIndex( const QPersistentModelIndex& index ) +{ + emit updateIndex( index ); +} + diff --git a/src/libtomahawk/playlist/treeitemdelegate.h b/src/libtomahawk/playlist/treeitemdelegate.h index 2ed8b42d3..85a2924e2 100644 --- a/src/libtomahawk/playlist/treeitemdelegate.h +++ b/src/libtomahawk/playlist/treeitemdelegate.h @@ -23,6 +23,10 @@ #include "dllmacro.h" +namespace Tomahawk { +class PixmapDelegateFader; +} + class ArtistView; class TreeProxyModel; @@ -39,9 +43,17 @@ protected: // QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const; +signals: + void updateIndex( const QModelIndex& idx ); + +private slots: + void doUpdateIndex( const QPersistentModelIndex& index ); + private: ArtistView* m_view; TreeProxyModel* m_model; + + mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_pixmaps; }; #endif // TREEITEMDELEGATE_H diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index bd2310ee7..ea7ae1dc4 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -589,11 +589,12 @@ Query::setLoved( bool loved ) Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( id(), Tomahawk::InfoSystem::InfoLove, - QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ) ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ), + Tomahawk::InfoSystem::PushNoFlag ); DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( q, QString( "Love" ), loved ? QString( "true" ) : QString( "false" ) ); Database::instance()->enqueue( QSharedPointer(cmd) ); - + emit socialActionsLoaded(); } } @@ -637,7 +638,7 @@ Query::socialActionDescription( const QString& action, DescriptionMode mode ) co else desc += ", "; } - + if ( sa.source->isLocal() ) { if ( loveCounter == 1 ) @@ -653,13 +654,13 @@ Query::socialActionDescription( const QString& action, DescriptionMode mode ) co { if ( loveCounter > 3 ) desc += " " + tr( "and" ) + " " + tr( "%n other(s)", "", loveCounter - 3 ) + ""; - + if ( mode == Short ) desc = "" + tr( "%1 people" ).arg( loveCounter ) + ""; desc += " " + tr( "loved this track" ); //FIXME: more action descs required } - + return desc; } @@ -673,7 +674,9 @@ Query::cover( const QSize& size, bool forceLoad ) const m_artistPtr = Artist::get( artist(), false ); m_albumPtr = Album::get( m_artistPtr, album(), false ); connect( m_artistPtr.data(), SIGNAL( updated() ), SIGNAL( updated() ), Qt::UniqueConnection ); + connect( m_artistPtr.data(), SIGNAL( coverChanged() ), SIGNAL( coverChanged() ), Qt::UniqueConnection ); connect( m_albumPtr.data(), SIGNAL( updated() ), SIGNAL( updated() ), Qt::UniqueConnection ); + connect( m_albumPtr.data(), SIGNAL( coverChanged() ), SIGNAL( coverChanged() ), Qt::UniqueConnection ); } m_albumPtr->cover( size, forceLoad ); @@ -684,7 +687,7 @@ Query::cover( const QSize& size, bool forceLoad ) const return m_artistPtr->cover( size ); } - + return QPixmap(); } #endif diff --git a/src/libtomahawk/query.h b/src/libtomahawk/query.h index de0b946dc..c9270c951 100644 --- a/src/libtomahawk/query.h +++ b/src/libtomahawk/query.h @@ -139,6 +139,8 @@ signals: void playableStateChanged( bool state ); void resolvingFinished( bool hasResults ); + void coverChanged(); + // emitted when social actions are loaded void socialActionsLoaded(); void updated(); diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index ff40668fb..f188104bd 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -435,7 +435,7 @@ TomahawkSettings::setInfoSystemCacheVersion( uint version ) uint TomahawkSettings::infoSystemCacheVersion() const { - return value( "infosystemcacheversion", 0 ).toUInt(); + return value( "infosystemcacheversion", 3 ).toUInt(); } diff --git a/src/libtomahawk/utils/PixmapDelegateFader.cpp b/src/libtomahawk/utils/PixmapDelegateFader.cpp new file mode 100644 index 000000000..d11c4fb50 --- /dev/null +++ b/src/libtomahawk/utils/PixmapDelegateFader.cpp @@ -0,0 +1,244 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2010-2012, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 "PixmapDelegateFader.h" +#include "tomahawkutilsgui.h" + +#include +#include + +using namespace Tomahawk; + +#define COVER_FADEIN 1000 + +PixmapDelegateFader::PixmapDelegateFader( const artist_ptr& artist, const QSize& size, TomahawkUtils::ImageMode mode, bool forceLoad ) + : m_artist( artist ) + , m_size( size ) + , m_mode( mode ) +{ + if ( !m_artist.isNull() ) + { + connect( m_artist.data(), SIGNAL( coverChanged() ), this, SLOT( artistChanged() ) ); + m_currentReference = m_artist->cover( size, forceLoad ); + } + + init(); +} + +PixmapDelegateFader::PixmapDelegateFader( const album_ptr& album, const QSize& size, TomahawkUtils::ImageMode mode, bool forceLoad ) + : m_album( album ) + , m_size( size ) + , m_mode( mode ) +{ + if ( !m_album.isNull() ) + { + connect( m_album.data(), SIGNAL( coverChanged() ), this, SLOT( albumChanged() ) ); + m_currentReference = m_album->cover( size, forceLoad ); + } + + init(); +} + + +PixmapDelegateFader::PixmapDelegateFader( const query_ptr& track, const QSize& size, TomahawkUtils::ImageMode mode, bool forceLoad ) + : m_track( track ) + , m_size( size ) + , m_mode( mode ) +{ + if ( !m_track.isNull() ) + { + connect( m_track.data(), SIGNAL( coverChanged() ), this, SLOT( trackChanged() ) ); + m_currentReference = m_track->cover( size, forceLoad ); + } + + init(); +} + + +PixmapDelegateFader::~PixmapDelegateFader() +{ + +} + + +void +PixmapDelegateFader::init() +{ + m_current = QPixmap( m_size ); + m_current.fill( Qt::transparent ); + + m_crossfadeTimeline.setDuration( COVER_FADEIN ); + m_crossfadeTimeline.setUpdateInterval( 20 ); + m_crossfadeTimeline.setFrameRange( 0, 1000 ); + m_crossfadeTimeline.setDirection( QTimeLine::Forward ); + connect( &m_crossfadeTimeline, SIGNAL( frameChanged( int ) ), this, SLOT( onAnimationStep( int ) ) ); + connect( &m_crossfadeTimeline, SIGNAL( finished() ), this, SLOT( onAnimationFinished() ) ); + + if ( m_currentReference.isNull() ) + { + // No cover loaded yet, use default and don't fade in + if ( !m_album.isNull() ) + m_current = m_currentReference = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultAlbumCover, m_mode, m_size ); + else if ( !m_artist.isNull() ) + m_current = m_currentReference = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultArtistImage, m_mode, m_size ); + else if ( !m_track.isNull() ) + m_current = m_currentReference = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultTrackImage, m_mode, m_size ); + + return; + } + + m_crossfadeTimeline.start(); +} + + +void +PixmapDelegateFader::albumChanged() +{ + if ( m_album.isNull() ) + return; + + setPixmap( m_album->cover( m_size ) ); +} + +void +PixmapDelegateFader::artistChanged() +{ + if ( m_artist.isNull() ) + return; + + setPixmap( m_artist->cover( m_size ) ); +} + + +void +PixmapDelegateFader::trackChanged() +{ + if ( m_track.isNull() ) + return; + + setPixmap( m_track->cover( m_size ) ); +} + + +void +PixmapDelegateFader::setPixmap( const QPixmap& pixmap ) +{ + if ( pixmap.isNull() ) + return; + + if ( m_crossfadeTimeline.state() == QTimeLine::Running ) + { + m_pixmapQueue.enqueue( pixmap ); + return; + } + + m_oldReference = m_currentReference; + m_currentReference = pixmap; + + m_crossfadeTimeline.start(); +} + + +void +PixmapDelegateFader::onAnimationStep( int step ) +{ + const qreal opacity = ((qreal)step / 1000.); + const qreal oldOpacity = ( 1000. - step ) / 1000. ; + m_current.fill( Qt::transparent ); + + // Update our pixmap with the new opacity + QPainter p( &m_current ); + + if ( !m_oldReference.isNull() ) + { + p.setOpacity( oldOpacity ); + p.drawPixmap( 0, 0, m_oldReference ); + } + + Q_ASSERT( !m_currentReference.isNull() ); + if ( !m_currentReference.isNull() ) // Should never be null.. + { + p.setOpacity( opacity ); + p.drawPixmap( 0, 0, m_currentReference ); + } + + p.end(); + + emit repaintRequest(); + /** + * Avoids using setOpacity that is slow on X11 (turns off graphics-backed painting, forces fallback to + * software rasterizer. + * + * but a bit buggy. + */ + /* + const int opacity = ((float)step* / 1000.) * 255; + const int oldOpacity = 255 - opacity; + if ( !m_oldReference.isNull() ) + { + p.setCompositionMode( QPainter::CompositionMode_Source ); + p.drawPixmap( 0, 0, m_oldReference ); + + // Reduce the source opacity by the value of the alpha channel + p.setCompositionMode( QPainter::CompositionMode_DestinationIn ); + qDebug() << Q_FUNC_INFO << "Drawing old pixmap w/ opacity;" << oldOpacity; + p.fillRect( m_current.rect(), QColor( 0, 0, 0, oldOpacity ) ); + } + + Q_ASSERT( !m_currentReference.isNull() ); + if ( !m_currentReference.isNull() ) // Should never be null.. + { + QPixmap temp( m_size ); + temp.fill( Qt::transparent ); + + QPainter p2( &temp ); + p2.drawPixmap( 0, 0, m_currentReference ); + + p2.setCompositionMode( QPainter::CompositionMode_DestinationIn ); + qDebug() << Q_FUNC_INFO << "Drawing NEW pixmap w/ opacity;" << opacity; + + p2.fillRect( temp.rect(), QColor( 0, 0, 0, opacity ) ); + p2.end(); + + p.setCompositionMode( QPainter::CompositionMode_Source ); + p.drawPixmap( 0, 0, temp ); + } + */ + +} + + +void +PixmapDelegateFader::onAnimationFinished() +{ + m_oldReference = QPixmap(); + onAnimationStep( 1000 ); + + if ( !m_pixmapQueue.isEmpty() ) + { + setPixmap( m_pixmapQueue.dequeue() ); + } +} + + + +QPixmap +PixmapDelegateFader::currentPixmap() const +{ + return m_current; +} diff --git a/src/libtomahawk/utils/PixmapDelegateFader.h b/src/libtomahawk/utils/PixmapDelegateFader.h new file mode 100644 index 000000000..2bc3c51b5 --- /dev/null +++ b/src/libtomahawk/utils/PixmapDelegateFader.h @@ -0,0 +1,79 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011-2012, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + +#ifndef PIXMAPDELEGATEFADER_H +#define PIXMAPDELEGATEFADER_H + +#include "artist.h" +#include "album.h" +#include "query.h" + +#include +#include +#include + +namespace Tomahawk +{ + +/** + * No parent, manage it yourself! + * + * TODO: Handle changing sizes + */ + +class PixmapDelegateFader : public QObject +{ + Q_OBJECT +public: + PixmapDelegateFader( const artist_ptr& artist, const QSize& size, TomahawkUtils::ImageMode mode = TomahawkUtils::Original, bool forceLoad = true ); + PixmapDelegateFader( const album_ptr& album, const QSize& size, TomahawkUtils::ImageMode mode = TomahawkUtils::Original, bool forceLoad = true ); + PixmapDelegateFader( const query_ptr& track, const QSize& size, TomahawkUtils::ImageMode mode = TomahawkUtils::Original, bool forceLoad = true ); + + virtual ~PixmapDelegateFader(); + + void setPixmap( const QPixmap& pixmap ); + + QPixmap currentPixmap() const; + +signals: + void repaintRequest(); + +private slots: + void artistChanged(); + void albumChanged(); + void trackChanged(); + + void onAnimationStep( int ); + void onAnimationFinished(); +private: + void init(); + + artist_ptr m_artist; + album_ptr m_album; + query_ptr m_track; + QSize m_size; + TomahawkUtils::ImageMode m_mode; + + QQueue m_pixmapQueue; + QTimeLine m_crossfadeTimeline; + QPixmap m_currentReference, m_oldReference, m_current; +}; + +} + +#endif // PIXMAPDELEGATEFADER_H diff --git a/src/libtomahawk/utils/closure.cpp b/src/libtomahawk/utils/closure.cpp index 8a68b63e1..4249c45a4 100644 --- a/src/libtomahawk/utils/closure.cpp +++ b/src/libtomahawk/utils/closure.cpp @@ -29,6 +29,7 @@ Closure::Closure(QObject* sender, const ClosureArgumentWrapper* val3) : QObject(receiver), callback_(NULL), + autoDelete_( true ), val0_(val0), val1_(val1), val2_(val2), @@ -72,7 +73,9 @@ void Closure::Invoked() { val2_ ? val2_->arg() : QGenericArgument(), val3_ ? val3_->arg() : QGenericArgument()); } - deleteLater(); + + if ( autoDelete_ ) + deleteLater(); } void Closure::Cleanup() { diff --git a/src/libtomahawk/utils/closure.h b/src/libtomahawk/utils/closure.h index f5351b53e..c9f91b529 100644 --- a/src/libtomahawk/utils/closure.h +++ b/src/libtomahawk/utils/closure.h @@ -63,6 +63,8 @@ class Closure : public QObject, boost::noncopyable { Closure(QObject* sender, const char* signal, std::tr1::function callback); + void setAutoDelete( bool autoDelete ) { autoDelete_ = autoDelete; } + virtual ~Closure(); private slots: @@ -74,6 +76,7 @@ class Closure : public QObject, boost::noncopyable { QMetaMethod slot_; std::tr1::function callback_; + bool autoDelete_; boost::scoped_ptr val0_; boost::scoped_ptr val1_; diff --git a/src/libtomahawk/utils/stylehelper.cpp b/src/libtomahawk/utils/stylehelper.cpp index 7d6dcea0e..470575ea5 100644 --- a/src/libtomahawk/utils/stylehelper.cpp +++ b/src/libtomahawk/utils/stylehelper.cpp @@ -26,14 +26,14 @@ QColor StyleHelper::headerUpperColor() { - return QColor( 80, 80, 80 ); + return QColor( "#464e57" ); } QColor StyleHelper::headerLowerColor() { - return QColor( 72, 72, 72 ); + return QColor( "#3f4650" ); } diff --git a/src/libtomahawk/viewmanager.cpp b/src/libtomahawk/viewmanager.cpp index 5104b9882..92eb4fba5 100644 --- a/src/libtomahawk/viewmanager.cpp +++ b/src/libtomahawk/viewmanager.cpp @@ -444,7 +444,9 @@ ViewManager::showTopLovedPage() if ( !m_topLovedWidget ) { CustomPlaylistView* view = new CustomPlaylistView( CustomPlaylistView::TopLovedTracks, source_ptr(), m_widget ); - view->setItemDelegate( new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LovedTracks, view, view->proxyModel() ) ); + PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LovedTracks, view, view->proxyModel() ); + connect( del, SIGNAL( updateIndex( QModelIndex ) ), view, SLOT( update( QModelIndex ) ) ); + view->setItemDelegate( del ); m_topLovedWidget = view; } @@ -465,7 +467,10 @@ ViewManager::showRecentPlaysPage() RecentlyPlayedModel* raModel = new RecentlyPlayedModel( source_ptr(), pv ); raModel->setStyle( TrackModel::Large ); - pv->setItemDelegate( new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::RecentlyPlayed, pv, pv->proxyModel() ) ); + PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::RecentlyPlayed, pv, pv->proxyModel() ); + connect( del, SIGNAL( updateIndex( QModelIndex ) ), pv, SLOT( update( QModelIndex ) ) ); + pv->setItemDelegate( del ); + pv->setPlaylistModel( raModel ); m_recentPlaysWidget = pv; diff --git a/src/libtomahawk/widgets/whatshotwidget.cpp b/src/libtomahawk/widgets/whatshotwidget.cpp index 3a262af74..f8d698822 100644 --- a/src/libtomahawk/widgets/whatshotwidget.cpp +++ b/src/libtomahawk/widgets/whatshotwidget.cpp @@ -83,7 +83,9 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent ) ui->tracksViewLeft->overlay()->setEnabled( false ); ui->tracksViewLeft->setHeaderHidden( true ); ui->tracksViewLeft->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); - ui->tracksViewLeft->setItemDelegate( new PlaylistChartItemDelegate( ui->tracksViewLeft, ui->tracksViewLeft->proxyModel() ) ); + PlaylistChartItemDelegate* del = new PlaylistChartItemDelegate( ui->tracksViewLeft, ui->tracksViewLeft->proxyModel() ); + connect( del, SIGNAL( updateRequest( QModelIndex ) ), ui->tracksViewLeft, SLOT( update( QModelIndex ) ) ); + ui->tracksViewLeft->setItemDelegate( del ); ui->tracksViewLeft->setUniformRowHeights( false ); TreeProxyModel* artistsProxy = new TreeProxyModel( ui->artistsViewLeft ); diff --git a/src/scrobbler.cpp b/src/scrobbler.cpp index 85587b4d7..61e3d640b 100644 --- a/src/scrobbler.cpp +++ b/src/scrobbler.cpp @@ -88,7 +88,8 @@ Scrobbler::trackStarted( const Tomahawk::result_ptr& track ) Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_scInfoIdentifier, Tomahawk::InfoSystem::InfoSubmitNowPlaying, - QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ) ); + QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ), + Tomahawk::InfoSystem::PushNoFlag ); // liblastfm forces 0-length tracks to scrobble after 4 minutes, stupid. if ( track->duration() == 0 ) @@ -140,7 +141,7 @@ Scrobbler::scrobble() Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_scInfoIdentifier, Tomahawk::InfoSystem::InfoSubmitScrobble, - QVariant() ); + QVariant(), Tomahawk::InfoSystem::PushNoFlag ); } diff --git a/src/sourcetree/items/sourceitem.cpp b/src/sourcetree/items/sourceitem.cpp index c1767734f..cdc4b6f02 100644 --- a/src/sourcetree/items/sourceitem.cpp +++ b/src/sourcetree/items/sourceitem.cpp @@ -62,7 +62,7 @@ SourceItem::SourceItem( SourcesModel* mdl, SourceTreeItem* parent, const Tomahaw return; } - m_collectionItem = new GenericPageItem( model(), this, tr( "Collection" ), QIcon( RESPATH "images/drop-song.png" ), //FIXME different icon + m_collectionItem = new GenericPageItem( model(), this, tr( "Collection" ), QIcon( RESPATH "images/collection.png" ), //FIXME different icon boost::bind( &SourceItem::collectionClicked, this ), boost::bind( &SourceItem::getCollectionPage, this ) ); @@ -127,7 +127,7 @@ SourceItem::SourceItem( SourcesModel* mdl, SourceTreeItem* parent, const Tomahaw SLOT( onAutoPlaylistsAdded( QList ) ), Qt::QueuedConnection ); connect( source->collection().data(), SIGNAL( stationsAdded( QList ) ), SLOT( onStationsAdded( QList ) ), Qt::QueuedConnection ); - + if ( m_source->isLocal() ) QTimer::singleShot( 0, this, SLOT( requestExpanding() ) ); } @@ -504,7 +504,9 @@ SourceItem::lovedTracksClicked() if ( !m_lovedTracksPage ) { CustomPlaylistView* view = new CustomPlaylistView( m_source.isNull() ? CustomPlaylistView::TopLovedTracks : CustomPlaylistView::SourceLovedTracks, m_source, ViewManager::instance()->widget() ); - view->setItemDelegate( new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LovedTracks, view, view->proxyModel() ) ); + PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LovedTracks, view, view->proxyModel() ); + connect( del, SIGNAL( updateIndex( QModelIndex ) ), view, SLOT( update( QModelIndex ) ) ); + view->setItemDelegate( del ); m_lovedTracksPage = view; } @@ -533,7 +535,10 @@ SourceItem::latestAdditionsClicked() RecentlyAddedModel* raModel = new RecentlyAddedModel( m_source, cv ); raModel->setStyle( TrackModel::Large ); - cv->setItemDelegate( new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LatestAdditions, cv, cv->proxyModel() ) ); + PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::LatestAdditions, cv, cv->proxyModel() ); + connect( del, SIGNAL( updateIndex( QModelIndex ) ), cv, SLOT( update( QModelIndex ) ) ); + cv->setItemDelegate( del ); + cv->setTrackModel( raModel ); cv->sortByColumn( TrackModel::Age, Qt::DescendingOrder ); @@ -564,7 +569,10 @@ SourceItem::recentPlaysClicked() RecentlyPlayedModel* raModel = new RecentlyPlayedModel( m_source, pv ); raModel->setStyle( TrackModel::Large ); - pv->setItemDelegate( new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::RecentlyPlayed, pv, pv->proxyModel() ) ); + PlaylistLargeItemDelegate* del = new PlaylistLargeItemDelegate( PlaylistLargeItemDelegate::RecentlyPlayed, pv, pv->proxyModel() ); + connect( del, SIGNAL( updateIndex( QModelIndex ) ), pv, SLOT( update( QModelIndex ) ) ); + pv->setItemDelegate( del ); + pv->setPlaylistModel( raModel ); m_recentPlaysPage = pv; diff --git a/src/tomahawkapp.cpp b/src/tomahawkapp.cpp index 6cca3e436..a91ba3ca0 100644 --- a/src/tomahawkapp.cpp +++ b/src/tomahawkapp.cpp @@ -447,6 +447,8 @@ TomahawkApp::registerMetaTypes() qRegisterMetaType< Tomahawk::InfoSystem::InfoStringHash >( "Tomahawk::InfoSystem::InfoStringHash" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoType >( "Tomahawk::InfoSystem::InfoType" ); + qRegisterMetaType< Tomahawk::InfoSystem::PushInfoFlags >( "Tomahawk::InfoSystem::PushInfoFlags" ); + qRegisterMetaType< Tomahawk::InfoSystem::PushInfoPair >( "Tomahawk::InfoSystem::PushInfoPair" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoRequestData >( "Tomahawk::InfoSystem::InfoRequestData" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoSystemCache* >( "Tomahawk::InfoSystem::InfoSystemCache*" ); qRegisterMetaType< Tomahawk::InfoSystem::InfoPlugin* >( "Tomahawk::InfoSystem::InfoPlugin*" );