1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-08-17 03:24:15 +02:00

Merge remote-tracking branch 'origin/master' into spotifyplaylists

Conflicts:
	src/libtomahawk/globalactionmanager.cpp
This commit is contained in:
Leo Franchi
2012-04-11 10:24:02 -04:00
32 changed files with 1154 additions and 617 deletions

View File

@@ -196,7 +196,7 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<message>
<location filename="../src/libtomahawk/playlist/albumview.cpp" line="157"/>
<source>After you have scanned your music collection you will find your latest album additions right here.</source>
<translation>След като сканирате музикалната ви колекция, ще откриете най-скоро добавените албуми тук.</translation>
<translation>След като бъде сканирана музикалната ти колекция, ще откриеш тук най-скоро добавените албуми.</translation>
</message>
<message>
<location filename="../src/libtomahawk/playlist/albumview.cpp" line="159"/>
@@ -243,7 +243,7 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<message>
<location filename="../src/libtomahawk/playlist/artistview.cpp" line="274"/>
<source>After you have scanned your music collection you will find your tracks right here.</source>
<translation>След като приключи сканирането на музикалната ти колекция, ще откриеш твоята музика тук.</translation>
<translation>След като приключи сканирането на музикалната ти колекция, ще откриеш музиката си тук.</translation>
</message>
<message>
<location filename="../src/libtomahawk/playlist/artistview.cpp" line="276"/>
@@ -330,24 +330,6 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<translation>100%</translation>
</message>
</context>
<context>
<name>AudioEngine</name>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="203"/>
<source>Tomahawk is stopped.</source>
<translation>Tomahawk е спрян</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="375"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation>Tomahawk изпълнява &quot;%1&quot; от %2%3.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="378"/>
<source>on album %1</source>
<translation>от албум %1</translation>
</message>
</context>
<context>
<name>CategoryAddItem</name>
<message>
@@ -734,7 +716,7 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<message>
<location filename="../src/libtomahawk/playlist/playlistmodel.cpp" line="77"/>
<source>A playlist by %1, created %2</source>
<translation>Списък за изпълнение от %1, създаден %2</translation>
<translation>A playlist by %1, created %2</translation>
</message>
<message>
<location filename="../src/libtomahawk/playlist/playlistmodel.cpp" line="78"/>
@@ -1327,7 +1309,7 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<message>
<location filename="../src/accounts/spotify/SpotifyAccountConfig.ui" line="186"/>
<source>This product uses SPOTIFY(R) CORE but is not endorsed, certified or otherwise approved in any way by Spotify. Spotify is the registered trade mark of the Spotify Group.</source>
<translation>Този продукт ползва ядрото на SPOTIFY(R), но не е поддържан, сертифицират или одобрен по какъвто и да е начин от Spotify.
<translation>Този продукт ползва ядрото на SPOTIFY(R), но не е поддържан, сертифициран или одобрен по какъвто и да е начин от Spotify.
Spotify e TM на Spotify Group.</translation>
</message>
</context>
@@ -1716,16 +1698,6 @@ You may wish to try re-authenticating.</source>
<source>Add to &amp;Queue</source>
<translation>Добави към &amp;опашката</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue playback after this track</source>
<translation>&amp;Продължи възпроизвеждането след тази песен</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop playback after this track</source>
<translation>&amp;Спри възпроизвеждането след тази песен</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="96"/>
<location filename="../src/libtomahawk/contextmenu.cpp" line="277"/>
@@ -1757,6 +1729,16 @@ You may wish to try re-authenticating.</source>
<source>&amp;Delete Items</source>
<translation>&amp;Изтрий позициите</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="110"/>
<source>&amp;Delete Item</source>
@@ -2308,6 +2290,19 @@ Try tweaking the filters for a new set of songs to play.</source>
<translation>Песни</translation>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::FdoNotifyPlugin</name>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="134"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="137"/>
<source>on &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::LastFmPlugin</name>
<message>
@@ -2485,7 +2480,7 @@ Try tweaking the filters for a new set of songs to play.</source>
<context>
<name>TomahawkApp</name>
<message>
<location filename="../src/tomahawkapp.cpp" line="535"/>
<location filename="../src/tomahawkapp.cpp" line="537"/>
<source>My Collection</source>
<translation>Моята колекция</translation>
</message>
@@ -2743,7 +2738,8 @@ enter the displayed PIN number here:</source>
<message>
<location filename="../src/tomahawkwindow.cpp" line="565"/>
<source>Some tracks in the playlist do not contain an artist and a title. They will be ignored.</source>
<translation>Някои от песните в този списък нямат артист и заглавие. Те ще бъдат игнорирани.</translation>
<translation>Някои от песните в този списък нямат артист и заглавие.
Те ще бъдат игнорирани.</translation>
</message>
<message>
<location filename="../src/tomahawkwindow.cpp" line="579"/>
@@ -3137,7 +3133,7 @@ You can re-send a sync message at any time simply by sending another tweet using
<message>
<location filename="../src/libtomahawk/viewmanager.cpp" line="384"/>
<source>Combined libraries of all your online friends</source>
<translation>Комбинирани библиотеки от всичките ти приятели на линия</translation>
<translation>Комбинирани библиотеки от всичките ми приятели на линия</translation>
</message>
<message>
<location filename="../src/libtomahawk/viewmanager.cpp" line="385"/>
@@ -3501,7 +3497,7 @@ Lyrics for &quot;%1&quot; by %2:
<message>
<location filename="../src/accounts/xmpp/sip/xmppsip.cpp" line="670"/>
<source>I&apos;m sorry -- I&apos;m just an automatic presence used by Tomahawk Player (http://gettomahawk.com). If you are getting this message, the person you are trying to reach is probably not signed on, so please try again later!</source>
<translation>Извинявай.. Аз съм режимът за автоматични отговори изпълзван от Tomahawk. (http://gettomahawk.com) Щом получаваш това съобщение, този с който се опитваш да се свържеш вероятно не е на линия. Моля, потай отново по-късно.</translation>
<translation>Извинявай.. Аз съм режимът за автоматични отговори изпълзван от Tomahawk. ( http://gettomahawk.com ) Щом получаваш това съобщение, този с който се опитваш да се свържеш вероятно не е на линия. Моля, опитай отново по-късно.</translation>
</message>
<message>
<location filename="../src/accounts/xmpp/sip/xmppsip.cpp" line="768"/>

View File

@@ -330,24 +330,6 @@ Denk dran: Erlaube das nur, wenn du dem Anderen vertraust und du die Rechte zum
<translation>Hoch</translation>
</message>
</context>
<context>
<name>AudioEngine</name>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="203"/>
<source>Tomahawk is stopped.</source>
<translation>Tomahawk ist gestoppt.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="375"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation>Tomahawk spielt &quot;%1&quot; von %2%3.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="378"/>
<source>on album %1</source>
<translation>auf dem Album %1</translation>
</message>
</context>
<context>
<name>CategoryAddItem</name>
<message>
@@ -1172,7 +1154,7 @@ Denk dran: Erlaube das nur, wenn du dem Anderen vertraust und du die Rechte zum
<message>
<location filename="../src/sourcetree/items/sourceitem.cpp" line="77"/>
<source>Recently Played</source>
<translation>Kürzlich gehörte Lieder</translation>
<translation>Kürzlich gehörte Lieder FOO</translation>
</message>
<message>
<location filename="../src/sourcetree/items/sourceitem.cpp" line="81"/>
@@ -1273,7 +1255,7 @@ Denk dran: Erlaube das nur, wenn du dem Anderen vertraust und du die Rechte zum
<message>
<location filename="../src/sourcetree/sourcesmodel.cpp" line="290"/>
<source>Recently Played</source>
<translation type="unfinished"/>
<translation>Kürzlich gehörte Lieder</translation>
</message>
<message>
<location filename="../src/sourcetree/sourcesmodel.cpp" line="295"/>
@@ -1706,16 +1688,6 @@ You may wish to try re-authenticating.</source>
<source>Add to &amp;Queue</source>
<translation>In &amp;Warteschlange einreihen</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop playback after this track</source>
<translation>&amp;Beende Wiedergabe nach diesem Stück</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="96"/>
<location filename="../src/libtomahawk/contextmenu.cpp" line="277"/>
@@ -1747,6 +1719,16 @@ You may wish to try re-authenticating.</source>
<source>&amp;Delete Items</source>
<translation>Elemente &amp;entfernen</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="110"/>
<source>&amp;Delete Item</source>
@@ -2299,6 +2281,19 @@ Versuch die Filter anzupassen für neue Lieder.</translation>
<translation>Stücke</translation>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::FdoNotifyPlugin</name>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="134"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="137"/>
<source>on &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::LastFmPlugin</name>
<message>
@@ -2476,7 +2471,7 @@ Versuch die Filter anzupassen für neue Lieder.</translation>
<context>
<name>TomahawkApp</name>
<message>
<location filename="../src/tomahawkapp.cpp" line="535"/>
<location filename="../src/tomahawkapp.cpp" line="537"/>
<source>My Collection</source>
<translation>Meine Sammlung</translation>
</message>

View File

@@ -330,24 +330,6 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<translation>High</translation>
</message>
</context>
<context>
<name>AudioEngine</name>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="203"/>
<source>Tomahawk is stopped.</source>
<translation>Tomahawk is stopped.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="375"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation>Tomahawk is playing &quot;%1&quot; by %2%3.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="378"/>
<source>on album %1</source>
<translation>on album %1</translation>
</message>
</context>
<context>
<name>CategoryAddItem</name>
<message>
@@ -1713,16 +1695,6 @@ You may wish to try re-authenticating.</translation>
<source>Add to &amp;Queue</source>
<translation>Add to &amp;Queue</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue playback after this track</source>
<translation>&amp;Continue playback after this track</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop playback after this track</source>
<translation>&amp;Stop playback after this track</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="96"/>
<location filename="../src/libtomahawk/contextmenu.cpp" line="277"/>
@@ -1754,6 +1726,16 @@ You may wish to try re-authenticating.</translation>
<source>&amp;Delete Items</source>
<translation>&amp;Delete Items</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue Playback after this Track</source>
<translation>&amp;Continue Playback after this Track</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop Playback after this Track</source>
<translation>&amp;Stop Playback after this Track</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="110"/>
<source>&amp;Delete Item</source>
@@ -2306,6 +2288,19 @@ Try tweaking the filters for a new set of songs to play.</translation>
<translation>Tracks</translation>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::FdoNotifyPlugin</name>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="134"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation>Tomahawk is playing &quot;%1&quot; by %2%3.</translation>
</message>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="137"/>
<source>on &quot;%1&quot;</source>
<translation>on &quot;%1&quot;</translation>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::LastFmPlugin</name>
<message>
@@ -2483,7 +2478,7 @@ Try tweaking the filters for a new set of songs to play.</translation>
<context>
<name>TomahawkApp</name>
<message>
<location filename="../src/tomahawkapp.cpp" line="535"/>
<location filename="../src/tomahawkapp.cpp" line="537"/>
<source>My Collection</source>
<translation>My Collection</translation>
</message>

View File

@@ -328,24 +328,6 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<translation>Subir volumen</translation>
</message>
</context>
<context>
<name>AudioEngine</name>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="203"/>
<source>Tomahawk is stopped.</source>
<translation>Tomahawk está parado.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="375"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation>Tomahawk está reproduciendo &quot;%1&quot; de %2%3.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="378"/>
<source>on album %1</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>CategoryAddItem</name>
<message>
@@ -1707,16 +1689,6 @@ You may wish to try re-authenticating.</source>
<source>Add to &amp;Queue</source>
<translation>Añadir a la &amp;cola</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="96"/>
<location filename="../src/libtomahawk/contextmenu.cpp" line="277"/>
@@ -1748,6 +1720,16 @@ You may wish to try re-authenticating.</source>
<source>&amp;Delete Items</source>
<translation>&amp;Eliminar de la cola</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="110"/>
<source>&amp;Delete Item</source>
@@ -2298,6 +2280,19 @@ Try tweaking the filters for a new set of songs to play.</source>
<translation>Pistas</translation>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::FdoNotifyPlugin</name>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="134"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="137"/>
<source>on &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::LastFmPlugin</name>
<message>
@@ -2475,7 +2470,7 @@ Try tweaking the filters for a new set of songs to play.</source>
<context>
<name>TomahawkApp</name>
<message>
<location filename="../src/tomahawkapp.cpp" line="535"/>
<location filename="../src/tomahawkapp.cpp" line="537"/>
<source>My Collection</source>
<translation>Mi colección</translation>
</message>

View File

@@ -328,24 +328,6 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<translation type="unfinished"/>
</message>
</context>
<context>
<name>AudioEngine</name>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="203"/>
<source>Tomahawk is stopped.</source>
<translation>Tomahawkは中止しています</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="375"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="378"/>
<source>on album %1</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>CategoryAddItem</name>
<message>
@@ -1706,16 +1688,6 @@ You may wish to try re-authenticating.</source>
<source>Add to &amp;Queue</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="96"/>
<location filename="../src/libtomahawk/contextmenu.cpp" line="277"/>
@@ -1747,6 +1719,16 @@ You may wish to try re-authenticating.</source>
<source>&amp;Delete Items</source>
<translation></translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="110"/>
<source>&amp;Delete Item</source>
@@ -2295,6 +2277,19 @@ Try tweaking the filters for a new set of songs to play.</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::FdoNotifyPlugin</name>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="134"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="137"/>
<source>on &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::LastFmPlugin</name>
<message>
@@ -2472,7 +2467,7 @@ Try tweaking the filters for a new set of songs to play.</source>
<context>
<name>TomahawkApp</name>
<message>
<location filename="../src/tomahawkapp.cpp" line="535"/>
<location filename="../src/tomahawkapp.cpp" line="537"/>
<source>My Collection</source>
<translation type="unfinished"/>
</message>

View File

@@ -328,24 +328,6 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<translation>Wysoko</translation>
</message>
</context>
<context>
<name>AudioEngine</name>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="203"/>
<source>Tomahawk is stopped.</source>
<translation>Tomahawk jest zatrzymany.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="375"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation>Tomahawk odtwarza &quot;%1&quot; wykonawcy %2%3.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="378"/>
<source>on album %1</source>
<translation>z albumu %1</translation>
</message>
</context>
<context>
<name>CategoryAddItem</name>
<message>
@@ -1708,16 +1690,6 @@ You may wish to try re-authenticating.</source>
<source>Add to &amp;Queue</source>
<translation>Dodaj do &amp;Kolejki</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="96"/>
<location filename="../src/libtomahawk/contextmenu.cpp" line="277"/>
@@ -1749,6 +1721,16 @@ You may wish to try re-authenticating.</source>
<source>&amp;Delete Items</source>
<translation>&amp;Usuń pozycje</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="110"/>
<source>&amp;Delete Item</source>
@@ -2299,6 +2281,19 @@ Try tweaking the filters for a new set of songs to play.</source>
<translation>Utwory</translation>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::FdoNotifyPlugin</name>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="134"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="137"/>
<source>on &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::LastFmPlugin</name>
<message>
@@ -2476,7 +2471,7 @@ Try tweaking the filters for a new set of songs to play.</source>
<context>
<name>TomahawkApp</name>
<message>
<location filename="../src/tomahawkapp.cpp" line="535"/>
<location filename="../src/tomahawkapp.cpp" line="537"/>
<source>My Collection</source>
<translation>Moja Kolekcja</translation>
</message>

View File

@@ -328,24 +328,6 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<translation>Aumentar</translation>
</message>
</context>
<context>
<name>AudioEngine</name>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="203"/>
<source>Tomahawk is stopped.</source>
<translation>Tomahawk está inativo.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="375"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation>Tomahawk está reproduzindo &quot;%1&quot; por %2%3.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="378"/>
<source>on album %1</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>CategoryAddItem</name>
<message>
@@ -1707,16 +1689,6 @@ You may wish to try re-authenticating.</source>
<source>Add to &amp;Queue</source>
<translation>Adicionar à &amp;lista</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="96"/>
<location filename="../src/libtomahawk/contextmenu.cpp" line="277"/>
@@ -1748,6 +1720,16 @@ You may wish to try re-authenticating.</source>
<source>&amp;Delete Items</source>
<translation>&amp;Eliminar itens</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="110"/>
<source>&amp;Delete Item</source>
@@ -2298,6 +2280,19 @@ Try tweaking the filters for a new set of songs to play.</source>
<translation>Faixas</translation>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::FdoNotifyPlugin</name>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="134"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="137"/>
<source>on &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::LastFmPlugin</name>
<message>
@@ -2475,7 +2470,7 @@ Try tweaking the filters for a new set of songs to play.</source>
<context>
<name>TomahawkApp</name>
<message>
<location filename="../src/tomahawkapp.cpp" line="535"/>
<location filename="../src/tomahawkapp.cpp" line="537"/>
<source>My Collection</source>
<translation>Minha biblioteca</translation>
</message>

View File

@@ -328,24 +328,6 @@ Remember: Only allow peers to connect if you trust who they are and if you have
<translation>Громче</translation>
</message>
</context>
<context>
<name>AudioEngine</name>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="203"/>
<source>Tomahawk is stopped.</source>
<translation>Tomahawk остановлен.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="375"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation>Tomahawk играет &quot;%1&quot; by %2%3.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="378"/>
<source>on album %1</source>
<translation>на альбом %1</translation>
</message>
</context>
<context>
<name>CategoryAddItem</name>
<message>
@@ -1704,16 +1686,6 @@ You may wish to try re-authenticating.</source>
<source>Add to &amp;Queue</source>
<translation>Добавить В &amp;Очередь</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="96"/>
<location filename="../src/libtomahawk/contextmenu.cpp" line="277"/>
@@ -1745,6 +1717,16 @@ You may wish to try re-authenticating.</source>
<source>&amp;Delete Items</source>
<translation>&amp;Удалить Песни</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="110"/>
<source>&amp;Delete Item</source>
@@ -2295,6 +2277,19 @@ Try tweaking the filters for a new set of songs to play.</source>
<translation>Песни</translation>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::FdoNotifyPlugin</name>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="134"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="137"/>
<source>on &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::LastFmPlugin</name>
<message>
@@ -2472,7 +2467,7 @@ Try tweaking the filters for a new set of songs to play.</source>
<context>
<name>TomahawkApp</name>
<message>
<location filename="../src/tomahawkapp.cpp" line="535"/>
<location filename="../src/tomahawkapp.cpp" line="537"/>
<source>My Collection</source>
<translation>Моя коллекция</translation>
</message>

View File

@@ -330,24 +330,6 @@ Kom ihåg: Tillåt endast anslutning från klienter du litar på, och som har la
<translation>Hög</translation>
</message>
</context>
<context>
<name>AudioEngine</name>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="203"/>
<source>Tomahawk is stopped.</source>
<translation>Tomahawk är stoppad.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="375"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation>Tomahawk spelar upp &quot;%1&quot; av %2%3.</translation>
</message>
<message>
<location filename="../src/libtomahawk/audio/audioengine.cpp" line="378"/>
<source>on album %1</source>
<translation> album %1</translation>
</message>
</context>
<context>
<name>CategoryAddItem</name>
<message>
@@ -1707,16 +1689,6 @@ You may wish to try re-authenticating.</source>
<source>Add to &amp;Queue</source>
<translation>Lägg till i &amp;</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop playback after this track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="96"/>
<location filename="../src/libtomahawk/contextmenu.cpp" line="277"/>
@@ -1748,6 +1720,16 @@ You may wish to try re-authenticating.</source>
<source>&amp;Delete Items</source>
<translation>&amp;Ta bort objekt</translation>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="87"/>
<source>&amp;Continue Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="89"/>
<source>&amp;Stop Playback after this Track</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/contextmenu.cpp" line="110"/>
<source>&amp;Delete Item</source>
@@ -2296,6 +2278,19 @@ Try tweaking the filters for a new set of songs to play.</source>
<translation>Spår</translation>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::FdoNotifyPlugin</name>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="134"/>
<source>Tomahawk is playing &quot;%1&quot; by %2%3.</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../src/libtomahawk/infosystem/infoplugins/unix/fdonotifyplugin.cpp" line="137"/>
<source>on &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
</context>
<context>
<name>Tomahawk::InfoSystem::LastFmPlugin</name>
<message>
@@ -2473,7 +2468,7 @@ Try tweaking the filters for a new set of songs to play.</source>
<context>
<name>TomahawkApp</name>
<message>
<location filename="../src/tomahawkapp.cpp" line="535"/>
<location filename="../src/tomahawkapp.cpp" line="537"/>
<source>My Collection</source>
<translation type="unfinished"/>
</message>

View File

@@ -137,6 +137,7 @@
<file>data/images/lastfm-icon.png</file>
<file>data/images/spotifycore-logo.png</file>
<file>data/images/playlist-header-tiled.png</file>
<file>data/images/share.png</file>
<file>data/sql/dbmigrate-27_to_28.sql</file>
<file>data/images/process-stop.png</file>
<file>data/icons/tomahawk-icon-128x128-grayscale.png</file>

View File

@@ -89,6 +89,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui}
LoadXSPFDialog.cpp
AccountFactoryWrapper.cpp
AccountFactoryWrapperDelegate.cpp
SocialWidget.cpp
)
IF( WITH_BREAKPAD )
@@ -105,10 +106,9 @@ SET( tomahawkUI ${tomahawkUI}
accounts/spotify/SpotifyAccountConfig.ui
audiocontrols.ui
LoadXSPFDialog.ui
AccountFactoryWrapper.ui
SocialWidget.ui
)
INCLUDE_DIRECTORIES(

267
src/SocialWidget.cpp Normal file
View File

@@ -0,0 +1,267 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "SocialWidget.h"
#include "ui_SocialWidget.h"
#include <QPainter>
#include <QDialog>
#include <QPropertyAnimation>
#include "globalactionmanager.h"
#include "utils/logger.h"
#define CORNER_ROUNDNESS 8.0
#define FADING_DURATION 500
#define FONT_SIZE 16
#define OPACITY 0.70
SocialWidget::SocialWidget( QWidget* parent )
: QWidget( parent ) // this is on purpose!
, ui( new Ui::SocialWidget )
, m_opacity( 0.00 )
, m_parent( parent )
, m_parentRect( parent->rect() )
{
ui->setupUi( this );
setAttribute( Qt::WA_TranslucentBackground, true );
setOpacity( m_opacity );
m_timer.setSingleShot( true );
connect( &m_timer, SIGNAL( timeout() ), this, SLOT( hide() ) );
#ifdef Q_WS_MAC
QFont f( font() );
f.setPointSize( f.pointSize() - 2 );
setFont( f );
#endif
ui->charsLeftLabel->setForegroundRole( QPalette::HighlightedText );
m_parent->installEventFilter( this );
connect( ui->buttonBox, SIGNAL( accepted() ), SLOT( accept() ) );
connect( ui->buttonBox, SIGNAL( rejected() ), SLOT( deleteLater() ) );
connect( ui->textEdit, SIGNAL( textChanged() ), SLOT( onChanged() ) );
connect( ui->facebookButton, SIGNAL( clicked( bool ) ), SLOT( onChanged() ) );
connect( ui->twitterButton, SIGNAL( clicked( bool ) ), SLOT( onChanged() ) );
connect( GlobalActionManager::instance(), SIGNAL( shortLinkReady( QUrl, QUrl, QVariant ) ), SLOT( onShortLinkReady( QUrl, QUrl, QVariant ) ) );
onChanged();
}
SocialWidget::~SocialWidget()
{
delete ui;
}
void
SocialWidget::setOpacity( qreal opacity )
{
m_opacity = opacity;
if ( m_opacity == 0.00 && !isHidden() )
{
QWidget::hide();
}
else if ( m_opacity > 0.00 && isHidden() )
{
QWidget::show();
}
repaint();
}
void
SocialWidget::setPosition( QPoint position )
{
m_position = position;
onGeometryUpdate();
}
void
SocialWidget::show( int timeoutSecs )
{
if ( !isEnabled() )
return;
QPropertyAnimation* animation = new QPropertyAnimation( this, "opacity" );
animation->setDuration( FADING_DURATION );
animation->setEndValue( 1.0 );
animation->start();
if( timeoutSecs > 0 )
m_timer.start( timeoutSecs * 1000 );
}
void
SocialWidget::hide()
{
if ( !isEnabled() )
return;
QPropertyAnimation* animation = new QPropertyAnimation( this, "opacity" );
animation->setDuration( FADING_DURATION );
animation->setEndValue( 0.00 );
animation->start();
}
bool
SocialWidget::shown() const
{
if ( !isEnabled() )
return false;
return m_opacity == OPACITY;
}
void
SocialWidget::paintEvent( QPaintEvent* event )
{
Q_UNUSED( event );
QPainter p( this );
QRect r = contentsRect();
p.setBackgroundMode( Qt::TransparentMode );
p.setRenderHint( QPainter::Antialiasing );
p.setOpacity( m_opacity );
QPen pen( palette().dark().color(), .5 );
p.setPen( pen );
p.setBrush( QColor( 30, 30, 30, 255.0 * OPACITY ) );
p.drawRoundedRect( r, CORNER_ROUNDNESS, CORNER_ROUNDNESS );
QWidget::paintEvent( event );
return;
QTextOption to( Qt::AlignCenter );
to.setWrapMode( QTextOption::WrapAtWordBoundaryOrAnywhere );
// shrink to fit if needed
QFont f( font() );
f.setPointSize( FONT_SIZE );
f.setBold( true );
QRectF textRect = r.adjusted( 8, 8, -8, -8 );
qreal availHeight = textRect.height();
QFontMetricsF fm( f );
qreal textHeight = fm.boundingRect( textRect, Qt::AlignCenter | Qt::TextWordWrap, "SocialWidget" ).height();
while( textHeight > availHeight )
{
if( f.pointSize() <= 4 ) // don't try harder
break;
f.setPointSize( f.pointSize() - 1 );
fm = QFontMetricsF( f );
textHeight = fm.boundingRect( textRect, Qt::AlignCenter | Qt::TextWordWrap, "SocialWidget" ).height();
}
p.setFont( f );
p.setPen( palette().highlightedText().color() );
p.drawText( r.adjusted( 8, 8, -8, -8 ), "SocialWidget", to );
}
void
SocialWidget::onShortLinkReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj )
{
if ( m_query->album().isEmpty() )
ui->textEdit->setText( tr( "Listening to \"%1\" by %2 and loving it! %4" ).arg( m_query->track() ).arg( m_query->artist() ).arg( shortUrl.toString() ) );
else
ui->textEdit->setText( tr( "Listening to \"%1\" by %2 on \"%3\" and loving it! %4" ).arg( m_query->track() ).arg( m_query->artist() ).arg( m_query->album() ).arg( shortUrl.toString() ) );
}
void
SocialWidget::setQuery( const Tomahawk::query_ptr& query )
{
m_query = query;
ui->coverImage->setPixmap( query->cover( ui->coverImage->size() ) );
onShortLinkReady( QString(), QString(), QVariant() );
onChanged();
QUrl longUrl = GlobalActionManager::instance()->openLinkFromQuery( query );
GlobalActionManager::instance()->shortenLink( longUrl );
}
void
SocialWidget::onChanged()
{
const int remaining = charsAvailable() - ui->textEdit->toPlainText().length();
ui->charsLeftLabel->setText( tr( "%1 characters left" ).arg( remaining ) );
ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( remaining >= 0 && ( ui->facebookButton->isChecked() || ui->twitterButton->isChecked() ) );
}
void
SocialWidget::accept()
{
tDebug() << "Sharing social link!";
deleteLater();
}
unsigned int
SocialWidget::charsAvailable() const
{
if ( ui->twitterButton->isChecked() )
return 140;
return 420; // facebook max length
}
void
SocialWidget::onGeometryUpdate()
{
QPoint p( m_parent->rect().width() - m_parentRect.width(), m_parent->rect().height() - m_parentRect.height() );
m_position += p;
m_parentRect = m_parent->rect();
QPoint position( m_position - QPoint( size().width(), size().height() ) );
if ( position != pos() )
{
move( position );
}
}
bool
SocialWidget::eventFilter( QObject* object, QEvent* event )
{
if ( event->type() == QEvent::Resize )
{
onGeometryUpdate();
}
return QObject::eventFilter( object, event );
}

84
src/SocialWidget.h Normal file
View File

@@ -0,0 +1,84 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SOCIALWIDGET_H
#define SOCIALWIDGET_H
#include <QWidget>
#include <QAbstractItemView>
#include <QTimer>
#include "query.h"
namespace Ui
{
class SocialWidget;
}
class SocialWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY( qreal opacity READ opacity WRITE setOpacity )
public:
SocialWidget( QWidget* parent );
~SocialWidget();
Tomahawk::query_ptr query() const { return m_query; }
void setQuery( const Tomahawk::query_ptr& query );
qreal opacity() const { return m_opacity; }
void setOpacity( qreal opacity );
QPoint position() const { return m_position; }
void setPosition( QPoint position );
bool shown() const;
public slots:
void show( int timeoutSecs = 0 );
void hide();
protected:
// void changeEvent( QEvent* e );
void paintEvent( QPaintEvent* event );
bool eventFilter( QObject* object, QEvent* event );
private slots:
void accept();
void onChanged();
void onShortLinkReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj );
void onGeometryUpdate();
private:
unsigned int charsAvailable() const;
Ui::SocialWidget* ui;
Tomahawk::query_ptr m_query;
qreal m_opacity;
QPoint m_position;
QWidget* m_parent;
QRect m_parentRect;
QTimer m_timer;
};
#endif // SOCIALWIDGET_H

118
src/SocialWidget.ui Normal file
View File

@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SocialWidget</class>
<widget class="QWidget" name="SocialWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>365</width>
<height>190</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>8</number>
</property>
<property name="topMargin">
<number>8</number>
</property>
<property name="rightMargin">
<number>8</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="facebookButton">
<property name="text">
<string>Facebook</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="twitterButton">
<property name="text">
<string>Twitter</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="coverImage">
<property name="minimumSize">
<size>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="text">
<string>Cover</string>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="textEdit">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>96</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="charsLeftLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -99,13 +99,27 @@ Tomahawk::InfoSystem::XmppInfoPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushDa
void
Tomahawk::InfoSystem::XmppInfoPlugin::audioStarted( const Tomahawk::InfoSystem::PushInfoPair &pushInfoPair )
{
if ( !pushInfoPair.second.canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
if ( !pushInfoPair.second.canConvert< QVariantMap >() )
{
tDebug() << Q_FUNC_INFO << "Failed to convert data to a QVariantMap";
return;
}
QVariantMap map = pushInfoPair.second.toMap();
if ( map.contains( "private" ) && map[ "private" ] == TomahawkSettings::FullyPrivate )
{
Jreen::Tune::Ptr tune( new Jreen::Tune() );
m_pubSubManager->publishItems( QList<Jreen::Payload::Ptr>() << tune, Jreen::JID() );
return;
}
if ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
{
tDebug() << Q_FUNC_INFO << "did not find an infostringhash";
return;
}
Tomahawk::InfoSystem::InfoStringHash info = pushInfoPair.second.value< Tomahawk::InfoSystem::InfoStringHash >();
Tomahawk::InfoSystem::InfoStringHash info = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
tDebug() << Q_FUNC_INFO << m_sipPlugin->m_client->jid().full() << info;
Jreen::Tune::Ptr tune( new Jreen::Tune() );

View File

@@ -32,6 +32,7 @@
#include "utils/logger.h"
#include "album.h"
#include "dropjob.h"
#include "SocialWidget.h"
#include "globalactionmanager.h"
#include "viewmanager.h"
@@ -44,6 +45,7 @@ AudioControls::AudioControls( QWidget* parent )
, m_repeatMode( PlaylistInterface::NoRepeat )
, m_shuffled( false )
, m_lastSliderCheck( 0 )
, m_parent( parent )
{
ui->setupUi( this );
setAcceptDrops( true );
@@ -82,6 +84,7 @@ AudioControls::AudioControls( QWidget* parent )
ui->repeatButton->setPixmap( RESPATH "images/repeat-off-pressed.png", QIcon::Off, QIcon::Active );
ui->volumeLowButton->setPixmap( RESPATH "images/volume-icon-muted.png" );
ui->volumeHighButton->setPixmap( RESPATH "images/volume-icon-full.png" );
ui->socialButton->setPixmap( RESPATH "images/share.png" );
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
ui->loveButton->setCheckable( true );
@@ -118,8 +121,9 @@ AudioControls::AudioControls( QWidget* parent )
connect( ui->shuffleButton, SIGNAL( clicked() ), SLOT( onShuffleClicked() ) );
connect( ui->artistTrackLabel, SIGNAL( clickedArtist() ), SLOT( onArtistClicked() ) );
connect( ui->artistTrackLabel, SIGNAL( clickedTrack() ), SLOT( onTrackClicked() ) );
connect( ui->albumLabel, SIGNAL( clickedAlbum() ), SLOT( onAlbumClicked() ) );
connect( ui->artistTrackLabel, SIGNAL( clickedTrack() ), SLOT( onTrackClicked() ) );
connect( ui->albumLabel, SIGNAL( clickedAlbum() ), SLOT( onAlbumClicked() ) );
connect( ui->socialButton, SIGNAL( clicked() ), SLOT( onSocialButtonClicked() ) );
connect( ui->loveButton, SIGNAL( clicked( bool ) ), SLOT( onLoveButtonClicked( bool ) ) );
// <From AudioEngine>
@@ -247,6 +251,8 @@ AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result )
ui->loveButton->setEnabled( true );
ui->loveButton->setVisible( true );
ui->socialButton->setEnabled( true );
ui->socialButton->setVisible( true );
setCover();
setSocialActions();
@@ -319,7 +325,6 @@ AudioControls::onPlaybackResumed()
{
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
ui->stackedLayout->setCurrentWidget( ui->pauseButton );
ui->loveButton->setVisible( true );
m_sliderTimeLine.resume();
}
@@ -354,6 +359,8 @@ AudioControls::onPlaybackStopped()
ui->stackedLayout->setCurrentWidget( ui->playPauseButton );
ui->loveButton->setEnabled( false );
ui->loveButton->setVisible( false );
ui->socialButton->setEnabled( false );
ui->socialButton->setVisible( false );
}
@@ -590,6 +597,16 @@ AudioControls::droppedTracks( QList< query_ptr > tracks )
}
void
AudioControls::onSocialButtonClicked()
{
SocialWidget* sw = new SocialWidget( m_parent );
sw->setPosition( QCursor::pos() );
sw->setQuery( m_currentTrack->toQuery() );
sw->show();
}
void
AudioControls::onLoveButtonClicked( bool checked )
{

View File

@@ -78,6 +78,7 @@ private slots:
void onArtistClicked();
void onAlbumClicked();
void onTrackClicked();
void onSocialButtonClicked();
void onLoveButtonClicked( bool );
void droppedTracks( QList<Tomahawk::query_ptr> );
@@ -89,7 +90,7 @@ private:
void setCover();
void setSocialActions();
Ui::AudioControls *ui;
Ui::AudioControls* ui;
Tomahawk::result_ptr m_currentTrack;
Tomahawk::PlaylistInterface::RepeatMode m_repeatMode;
@@ -101,6 +102,8 @@ private:
qint64 m_lastSliderCheck;
bool m_noTimeChange;
qint64 m_lastTextSecondShown;
QWidget* m_parent;
};
#endif // AUDIOCONTROLS_H

View File

@@ -287,6 +287,22 @@
</property>
</spacer>
</item>
<item>
<widget class="ImageButton" name="socialButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>social</string>
</property>
</widget>
</item>
<item>
<widget class="ImageButton" name="loveButton">
<property name="sizePolicy">

View File

@@ -23,6 +23,7 @@
#include <QtCore/QUrl>
#include <QtNetwork/QNetworkReply>
#include <QTemporaryFile>
#include "playlistinterface.h"
#include "sourceplaylistinterface.h"
@@ -31,6 +32,7 @@
#include "database/databasecommand_logplayback.h"
#include "network/servent.h"
#include "utils/qnr_iodevicestream.h"
#include "utils/closure.h"
#include "headlesscheck.h"
#include "infosystem/infosystem.h"
#include "album.h"
@@ -77,8 +79,6 @@ AudioEngine::AudioEngine()
connect( m_audioOutput, SIGNAL( volumeChanged( qreal ) ), SLOT( onVolumeChanged( qreal ) ) );
connect( this, SIGNAL( sendWaitingNotification() ), SLOT( sendWaitingNotificationSlot() ), Qt::QueuedConnection );
onVolumeChanged( m_audioOutput->volume() );
#ifndef Q_WS_X11
@@ -137,23 +137,7 @@ AudioEngine::play()
setVolume( m_volume );
emit resumed();
if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate )
{
Tomahawk::InfoSystem::InfoStringHash trackInfo;
trackInfo["title"] = m_currentTrack->track();
trackInfo["artist"] = m_currentTrack->artist()->name();
trackInfo["album"] = m_currentTrack->album()->name();
trackInfo["albumpos"] = QString::number( m_currentTrack->albumpos() );
trackInfo["duration"] = QString::number( m_currentTrack->duration() );
Tomahawk::InfoSystem::InfoPushData pushData (
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowResumed,
QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ),
Tomahawk::InfoSystem::PushNoFlag );
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData );
}
sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowResumed );
}
else
next();
@@ -192,19 +176,12 @@ AudioEngine::stop()
setCurrentTrack( Tomahawk::result_ptr() );
Tomahawk::InfoSystem::InfoTypeMap map;
map[ Tomahawk::InfoSystem::InfoNowStopped ] = QVariant();
if ( m_waitingOnNewTrack )
emit sendWaitingNotification();
else if ( TomahawkSettings::instance()->verboseNotifications() )
{
QVariantMap stopInfo;
stopInfo["message"] = tr( "Tomahawk is stopped." );
map[ Tomahawk::InfoSystem::InfoNotifyUser ] = QVariant::fromValue< QVariantMap >( stopInfo );
}
sendWaitingNotification();
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( s_aeInfoIdentifier, map, Tomahawk::InfoSystem::PushNoFlag );
Tomahawk::InfoSystem::InfoPushData pushData( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowStopped, QVariant(), Tomahawk::InfoSystem::PushNoFlag );
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData );
}
@@ -326,18 +303,16 @@ AudioEngine::mute()
void
AudioEngine::sendWaitingNotificationSlot() const
AudioEngine::sendWaitingNotification() const
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
//since it's async, after this is triggered our result could come in, so don't show the popup in that case
if ( !m_playlist.isNull() && m_playlist->hasNextItem() )
return;
QVariantMap retryInfo;
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::InfoPushData pushData (
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser,
QVariant::fromValue< QVariantMap >( retryInfo ),
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoTrackUnresolved,
QVariant(),
Tomahawk::InfoSystem::PushNoFlag );
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData );
@@ -345,14 +320,14 @@ AudioEngine::sendWaitingNotificationSlot() const
void
AudioEngine::sendNowPlayingNotification()
AudioEngine::sendNowPlayingNotification( const Tomahawk::InfoSystem::InfoType type )
{
#ifndef ENABLE_HEADLESS
if ( m_currentTrack->album().isNull() || m_currentTrack->album()->infoLoaded() )
onNowPlayingInfoReady();
onNowPlayingInfoReady( type );
else
{
connect( m_currentTrack->album().data(), SIGNAL( updated() ), SLOT( onNowPlayingInfoReady() ), Qt::UniqueConnection );
_detail::Closure* closure = NewClosure( m_currentTrack->album().data(), SIGNAL( updated() ), const_cast< AudioEngine* >( this ), SLOT( onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType ) ), type );
m_currentTrack->album()->cover( QSize( 0, 0 ) );
}
#endif
@@ -360,7 +335,7 @@ AudioEngine::sendNowPlayingNotification()
void
AudioEngine::onNowPlayingInfoReady()
AudioEngine::onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType type )
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
if ( m_currentTrack.isNull() ||
@@ -372,24 +347,46 @@ AudioEngine::onNowPlayingInfoReady()
return;
QVariantMap playInfo;
playInfo["message"] = tr( "Tomahawk is playing \"%1\" by %2%3." )
.arg( m_currentTrack->track() )
.arg( m_currentTrack->artist()->name() )
.arg( m_currentTrack->album().isNull() ? QString() : QString( " %1" ).arg( tr( "on album %1" ).arg( m_currentTrack->album()->name() ) ) );
if ( !m_currentTrack->album().isNull() )
{
#ifndef ENABLE_HEADLESS
QImage cover;
cover = m_currentTrack->album()->cover( QSize( 0, 0 ) ).toImage();
playInfo["image"] = QVariant( cover );
playInfo["cover"] = cover;
QTemporaryFile coverTempFile( QDir::toNativeSeparators( QDir::tempPath() + "/" + m_currentTrack->artist()->name() + "_" + m_currentTrack->album()->name() + "_tomahawk_cover.png" ) );
if ( !coverTempFile.open() )
{
tDebug() << "WARNING: could not write temporary file for cover art!";
}
// Finally, save the image to the new temp file
if ( cover.save( &coverTempFile, "PNG" ) )
{
tDebug( LOGVERBOSE ) << "Saving cover image to:" << QFileInfo( coverTempFile ).absoluteFilePath();
coverTempFile.close();
playInfo["coveruri"] = QFileInfo( coverTempFile ).absoluteFilePath();
}
else
{
tDebug() << Q_FUNC_INFO << "failed to save cover image!";
coverTempFile.close();
}
#endif
}
Tomahawk::InfoSystem::InfoPushData pushData (
s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNotifyUser,
QVariant::fromValue< QVariantMap >( playInfo ),
Tomahawk::InfoSystem::PushNoFlag );
Tomahawk::InfoSystem::InfoStringHash trackInfo;
trackInfo["title"] = m_currentTrack->track();
trackInfo["artist"] = m_currentTrack->artist()->name();
trackInfo["album"] = m_currentTrack->album()->name();
trackInfo["duration"] = QString::number( m_currentTrack->duration() );
trackInfo["albumpos"] = QString::number( m_currentTrack->albumpos() );
playInfo["trackinfo"] = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
playInfo["private"] = TomahawkSettings::instance()->privateListeningMode();
Tomahawk::InfoSystem::InfoPushData pushData ( s_aeInfoIdentifier, type, playInfo, Tomahawk::InfoSystem::PushShortUrlFlag );
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData );
}
@@ -468,29 +465,13 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
m_mediaObject->play();
emit started( m_currentTrack );
if ( TomahawkSettings::instance()->verboseNotifications() )
sendNowPlayingNotification();
if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate )
{
DatabaseCommand_LogPlayback* cmd = new DatabaseCommand_LogPlayback( m_currentTrack, DatabaseCommand_LogPlayback::Started );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
Tomahawk::InfoSystem::InfoStringHash trackInfo;
trackInfo["title"] = m_currentTrack->track();
trackInfo["artist"] = m_currentTrack->artist()->name();
trackInfo["album"] = m_currentTrack->album()->name();
trackInfo["duration"] = QString::number( m_currentTrack->duration() );
trackInfo["albumpos"] = QString::number( m_currentTrack->albumpos() );
Tomahawk::InfoSystem::InfoPushData pushData (
s_aeInfoIdentifier,
Tomahawk::InfoSystem::InfoNowPlaying,
QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ),
Tomahawk::InfoSystem::PushShortUrlFlag );
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData );
}
sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying );
}
}

View File

@@ -27,6 +27,8 @@
#include <phonon/AudioOutput>
#include <phonon/BackendCapabilities>
#include "libtomahawk/infosystem/infosystem.h"
#include "result.h"
#include "typedefs.h"
#include "playlistinterface.h"
@@ -117,8 +119,6 @@ signals:
void error( AudioEngine::AudioErrorCode errorCode );
void sendWaitingNotification();
private slots:
bool loadTrack( const Tomahawk::result_ptr& result );
void loadPreviousTrack();
@@ -130,10 +130,10 @@ private slots:
void timerTriggered( qint64 time );
void setCurrentTrack( const Tomahawk::result_ptr& result );
void onNowPlayingInfoReady();
void onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType type );
void onPlaylistNextTrackReady();
void sendWaitingNotificationSlot() const;
void sendWaitingNotification() const;
private:
void setState( AudioState state );
@@ -141,7 +141,7 @@ private:
bool isHttpResult( const QString& ) const;
bool isLocalResult( const QString& ) const;
void sendNowPlayingNotification();
void sendNowPlayingNotification( const Tomahawk::InfoSystem::InfoType type );
QSharedPointer<QIODevice> m_input;

View File

@@ -76,7 +76,7 @@ ContextWidget::ContextWidget( QWidget* parent )
ui->contextView->setScene( m_scene );
ui->contextView->setFrameShape( QFrame::NoFrame );
ui->contextView->setStyleSheet( "background: transparent" );
ui->contextView->setStyleSheet( "QGraphicsView { background: transparent; }" );
ui->contextView->setAttribute( Qt::WA_MacShowFocusRect, 0 );
ui->contextView->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );

View File

@@ -84,9 +84,9 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
if ( m_supportedActions & ActionStopAfter && itemCount() == 1 )
{
if ( AudioEngine::instance()->stopAfterTrack() == queries.first() )
m_sigmap->setMapping( addAction( tr( "&Continue playback after this track" ) ), ActionStopAfter );
m_sigmap->setMapping( addAction( tr( "&Continue Playback after this Track" ) ), ActionStopAfter );
else
m_sigmap->setMapping( addAction( tr( "&Stop playback after this track" ) ), ActionStopAfter );
m_sigmap->setMapping( addAction( tr( "&Stop Playback after this Track" ) ), ActionStopAfter );
}
addSeparator();

View File

@@ -1,6 +1,7 @@
/*
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -45,7 +46,6 @@
#include "playlist/topbar/topbar.h"
#include "playlist/playlistview.h"
#include <QtGui/QApplication>
#include <QtGui/QClipboard>
@@ -123,7 +123,7 @@ GlobalActionManager::openLink( const QString& title, const QString& artist, cons
void
GlobalActionManager::shortenLink( const QUrl& url, const QVariant &callbackObj )
GlobalActionManager::shortenLink( const QUrl& url, const QVariant& callbackObj )
{
if ( QThread::currentThread() != thread() )
{
@@ -148,7 +148,8 @@ GlobalActionManager::copyPlaylistToClipboard( const dynplaylist_ptr& playlist )
{
QUrl link( QString( "%1/%2/create/" ).arg( hostname() ).arg( playlist->mode() == OnDemand ? "station" : "autoplaylist" ) );
if( playlist->generator()->type() != "echonest" ) {
if ( playlist->generator()->type() != "echonest" )
{
tLog() << "Only echonest generators are supported";
return QString();
}
@@ -157,19 +158,25 @@ GlobalActionManager::copyPlaylistToClipboard( const dynplaylist_ptr& playlist )
link.addQueryItem( "title", playlist->title() );
QList< dyncontrol_ptr > controls = playlist->generator()->controls();
foreach( const dyncontrol_ptr& c, controls ) {
if( c->selectedType() == "Artist" ) {
if( c->match().toInt() == Echonest::DynamicPlaylist::ArtistType )
foreach ( const dyncontrol_ptr& c, controls )
{
if ( c->selectedType() == "Artist" )
{
if ( c->match().toInt() == Echonest::DynamicPlaylist::ArtistType )
link.addQueryItem( "artist_limitto", c->input() );
else
link.addQueryItem( "artist", c->input() );
} else if( c->selectedType() == "Artist Description" ) {
}
else if ( c->selectedType() == "Artist Description" )
{
link.addQueryItem( "description", c->input() );
} else {
}
else
{
QString name = c->selectedType().toLower().replace( " ", "_" );
Echonest::DynamicPlaylist::PlaylistParam p = static_cast< Echonest::DynamicPlaylist::PlaylistParam >( c->match().toInt() );
// if it is a max, set that too
if( p == Echonest::DynamicPlaylist::MaxTempo || p == Echonest::DynamicPlaylist::MaxDuration || p == Echonest::DynamicPlaylist::MaxLoudness
if ( p == Echonest::DynamicPlaylist::MaxTempo || p == Echonest::DynamicPlaylist::MaxDuration || p == Echonest::DynamicPlaylist::MaxLoudness
|| p == Echonest::DynamicPlaylist::MaxDanceability || p == Echonest::DynamicPlaylist::MaxEnergy || p == Echonest::DynamicPlaylist::ArtistMaxFamiliarity
|| p == Echonest::DynamicPlaylist::ArtistMaxHotttnesss || p == Echonest::DynamicPlaylist::SongMaxHotttnesss || p == Echonest::DynamicPlaylist::ArtistMaxLatitude
|| p == Echonest::DynamicPlaylist::ArtistMaxLongitude )
@@ -204,7 +211,8 @@ GlobalActionManager::xspfCreated( const QByteArray& xspf )
QString filename = sender()->property( "filename" ).toString();
QFile f( filename );
if( !f.open( QIODevice::WriteOnly ) ) {
if ( !f.open( QIODevice::WriteOnly ) )
{
qWarning() << "Failed to open file to save XSPF:" << filename;
return;
}
@@ -220,7 +228,7 @@ void
GlobalActionManager::copyToClipboard( const query_ptr& query )
{
m_clipboardLongUrl = openLinkFromQuery( query );
GlobalActionManager::instance()->shortenLink( m_clipboardLongUrl );
shortenLink( m_clipboardLongUrl );
}
@@ -228,10 +236,11 @@ bool
GlobalActionManager::parseTomahawkLink( const QString& urlIn )
{
QString url = urlIn;
if( urlIn.startsWith( "http://toma.hk" ) )
if ( urlIn.startsWith( "http://toma.hk" ) )
url.replace( "http://toma.hk/", "tomahawk://" );
if( url.contains( "tomahawk://" ) ) {
if ( url.contains( "tomahawk://" ) )
{
QString cmd = url.mid( 11 );
cmd.replace( "%2B", "%20" );
tLog() << "Parsing tomahawk link command" << cmd;
@@ -240,8 +249,10 @@ GlobalActionManager::parseTomahawkLink( const QString& urlIn )
QUrl u = QUrl::fromEncoded( cmd.toUtf8() );
// for backwards compatibility
if( cmdType == "load" ) {
if( u.hasQueryItem( "xspf" ) ) {
if ( cmdType == "load" )
{
if ( u.hasQueryItem( "xspf" ) )
{
QUrl xspf = QUrl::fromUserInput( u.queryItemValue( "xspf" ) );
XSPFLoader* l = new XSPFLoader( true, this );
tDebug() << "Loading spiff:" << xspf.toString();
@@ -249,7 +260,9 @@ GlobalActionManager::parseTomahawkLink( const QString& urlIn )
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), ViewManager::instance(), SLOT( show( Tomahawk::playlist_ptr ) ) );
return true;
} else if( u.hasQueryItem( "jspf" ) ) {
}
else if ( u.hasQueryItem( "jspf" ) )
{
QUrl jspf = QUrl::fromUserInput( u.queryItemValue( "jspf" ) );
JSPFLoader* l = new JSPFLoader( true, this );
@@ -261,31 +274,54 @@ GlobalActionManager::parseTomahawkLink( const QString& urlIn )
}
}
if( cmdType == "playlist" ) {
if ( cmdType == "playlist" )
{
return handlePlaylistCommand( u );
} else if( cmdType == "collection" ) {
}
else if ( cmdType == "collection" )
{
return handleCollectionCommand( u );
} else if( cmdType == "queue" ) {
}
else if ( cmdType == "queue" )
{
return handleQueueCommand( u );
} else if( cmdType == "station" ) {
}
else if ( cmdType == "station" )
{
return handleStationCommand( u );
} else if( cmdType == "autoplaylist" ) {
}
else if ( cmdType == "autoplaylist" )
{
return handleAutoPlaylistCommand( u );
} else if( cmdType == "search" ) {
}
else if ( cmdType == "search" )
{
return handleSearchCommand( u );
} else if( cmdType == "play" ) {
}
else if ( cmdType == "play" )
{
return handlePlayCommand( u );
} else if( cmdType == "bookmark" ) {
}
else if ( cmdType == "bookmark" )
{
return handlePlayCommand( u );
} else if( cmdType == "open" ) {
}
else if ( cmdType == "open" )
{
return handleOpenCommand( u );
} else if( cmdType == "view" ) {
}
else if ( cmdType == "view" )
{
return handleViewCommand( u );
} else {
}
else
{
tLog() << "Tomahawk link not supported, command not known!" << cmdType << u.path();
return false;
}
} else {
}
else
{
tLog() << "Not a tomahawk:// link!";
return false;
}
@@ -296,13 +332,16 @@ bool
GlobalActionManager::handlePlaylistCommand( const QUrl& url )
{
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
if( parts.isEmpty() ) {
if ( parts.isEmpty() )
{
tLog() << "No specific playlist command:" << url.toString();
return false;
}
if( parts[ 0 ] == "import" ) {
if( !url.hasQueryItem( "xspf" ) ) {
if ( parts[ 0 ] == "import" )
{
if ( !url.hasQueryItem( "xspf" ) )
{
tDebug() << "No xspf to load...";
return false;
}
@@ -313,15 +352,21 @@ GlobalActionManager::handlePlaylistCommand( const QUrl& url )
l->load( xspf );
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), this, SLOT( playlistCreatedToShow( Tomahawk::playlist_ptr) ) );
} else if( parts [ 0 ] == "new" ) {
if( !url.hasQueryItem( "title" ) ) {
}
else if ( parts [ 0 ] == "new" )
{
if ( !url.hasQueryItem( "title" ) )
{
tLog() << "New playlist command needs a title...";
return false;
}
playlist_ptr pl = Playlist::create( SourceList::instance()->getLocal(), uuid(), url.queryItemValue( "title" ), QString(), QString(), false );
ViewManager::instance()->show( pl );
} else if( parts[ 0 ] == "add" ) {
if( !url.hasQueryItem( "playlistid" ) || !url.hasQueryItem( "title" ) || !url.hasQueryItem( "artist" ) ) {
}
else if ( parts[ 0 ] == "add" )
{
if ( !url.hasQueryItem( "playlistid" ) || !url.hasQueryItem( "title" ) || !url.hasQueryItem( "artist" ) )
{
tLog() << "Add to playlist command needs playlistid, track, and artist..." << url.toString();
return false;
}
@@ -353,12 +398,14 @@ bool
GlobalActionManager::handleCollectionCommand( const QUrl& url )
{
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
if( parts.isEmpty() ) {
if ( parts.isEmpty() )
{
tLog() << "No specific collection command:" << url.toString();
return false;
}
if( parts[ 0 ] == "add" ) {
if ( parts[ 0 ] == "add" )
{
// TODO implement
}
@@ -370,7 +417,8 @@ bool
GlobalActionManager::handleOpenCommand(const QUrl& url)
{
QStringList parts = url.path().split( "/" ).mid( 1 );
if( parts.isEmpty() ) {
if ( parts.isEmpty() )
{
tLog() << "No specific type to open:" << url.toString();
return false;
}
@@ -385,7 +433,8 @@ GlobalActionManager::handleOpenTrack ( const query_ptr& q )
ViewManager::instance()->queue()->model()->append( q );
ViewManager::instance()->showQueue();
if( !AudioEngine::instance()->isPlaying() && !AudioEngine::instance()->isPaused() ) {
if ( !AudioEngine::instance()->isPlaying() && !AudioEngine::instance()->isPaused() )
{
connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) );
m_waitingToPlay = q;
}
@@ -403,14 +452,18 @@ bool
GlobalActionManager::handleQueueCommand( const QUrl& url )
{
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
if( parts.isEmpty() ) {
if ( parts.isEmpty() )
{
tLog() << "No specific queue command:" << url.toString();
return false;
}
if( parts[ 0 ] == "add" ) {
if ( parts[ 0 ] == "add" )
{
doQueueAdd( parts.mid( 1 ), url.queryItems() );
} else {
}
else
{
tLog() << "Only queue/add/track is support at the moment, got:" << parts;
return false;
}
@@ -422,46 +475,55 @@ GlobalActionManager::handleQueueCommand( const QUrl& url )
bool
GlobalActionManager::doQueueAdd( const QStringList& parts, const QList< QPair< QString, QString > >& queryItems )
{
if( parts.size() && parts[ 0 ] == "track" ) {
if ( parts.size() && parts[ 0 ] == "track" )
{
if( queueSpotify( parts, queryItems ) )
if ( queueSpotify( parts, queryItems ) )
return true;
else if( queueRdio( parts, queryItems ) )
else if ( queueRdio( parts, queryItems ) )
return true;
QPair< QString, QString > pair;
QString title, artist, album, urlStr;
foreach( pair, queryItems ) {
foreach ( pair, queryItems ) {
pair.second = pair.second.replace( "+", " " ); // QUrl::queryItems doesn't decode + to a space :(
if( pair.first == "title" )
if ( pair.first == "title" )
title = pair.second;
else if( pair.first == "artist" )
else if ( pair.first == "artist" )
artist = pair.second;
else if( pair.first == "album" )
else if ( pair.first == "album" )
album = pair.second;
else if( pair.first == "url" )
else if ( pair.first == "url" )
urlStr = pair.second;
}
if( !title.isEmpty() || !artist.isEmpty() || !album.isEmpty() ) { // an individual; query to add to queue
if ( !title.isEmpty() || !artist.isEmpty() || !album.isEmpty() )
{
// an individual; query to add to queue
query_ptr q = Query::get( artist, title, album, uuid(), false );
if( !urlStr.isEmpty() )
if ( !urlStr.isEmpty() )
q->setResultHint( urlStr );
Pipeline::instance()->resolve( q, true );
handleOpenTrack( q );
return true;
} else { // a list of urls to add to the queue
foreach( pair, queryItems ) {
if( pair.first != "url" )
}
else
{ // a list of urls to add to the queue
foreach ( pair, queryItems )
{
if ( pair.first != "url" )
continue;
QUrl track = QUrl::fromUserInput( pair.second );
//FIXME: isLocalFile is Qt 4.8
if( track.toString().startsWith( "file://" ) ) { // it's local, so we see if it's in the DB and load it if so
if ( track.toString().startsWith( "file://" ) )
{
// it's local, so we see if it's in the DB and load it if so
// TODO
} else { // give it a web result hint
}
else
{ // give it a web result hint
QFileInfo info( track.path() );
query_ptr q = Query::get( QString(), info.baseName(), QString(), uuid(), false );
q->setResultHint( track.toString() );
@@ -485,14 +547,15 @@ GlobalActionManager::queueSpotify( const QStringList& , const QList< QPair< QStr
QString url;
QPair< QString, QString > pair;
foreach( pair, queryItems ) {
if( pair.first == "spotifyURL" )
foreach ( pair, queryItems )
{
if ( pair.first == "spotifyURL" )
url = pair.second;
else if( pair.first == "spotifyURI" )
else if ( pair.first == "spotifyURI" )
url = pair.second;
}
if( url.isEmpty() )
if ( url.isEmpty() )
return false;
openSpotifyLink( url );
@@ -507,14 +570,15 @@ GlobalActionManager::queueRdio( const QStringList& , const QList< QPair< QString
QString url;
QPair< QString, QString > pair;
foreach( pair, queryItems ) {
if( pair.first == "rdioURL" )
foreach ( pair, queryItems )
{
if ( pair.first == "rdioURL" )
url = pair.second;
else if( pair.first == "rdioURI" )
else if ( pair.first == "rdioURI" )
url = pair.second;
}
if( url.isEmpty() )
if ( url.isEmpty() )
return false;
openRdioLink( url );
@@ -533,16 +597,16 @@ GlobalActionManager::handleSearchCommand( const QUrl& url )
else
{
QStringList query;
if( url.hasQueryItem( "artist" ) )
if ( url.hasQueryItem( "artist" ) )
query << url.queryItemValue( "artist" );
if( url.hasQueryItem( "album" ) )
if ( url.hasQueryItem( "album" ) )
query << url.queryItemValue( "album" );
if( url.hasQueryItem( "title" ) )
if ( url.hasQueryItem( "title" ) )
query << url.queryItemValue( "title" );
queryStr = query.join( " " );
}
if( queryStr.trimmed().isEmpty() )
if ( queryStr.trimmed().isEmpty() )
return false;
ViewManager::instance()->show( new SearchWidget( queryStr.trimmed() ) );
@@ -554,7 +618,7 @@ bool
GlobalActionManager::handleViewCommand( const QUrl& url )
{
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
if( parts.isEmpty() ) {
if ( parts.isEmpty() ) {
tLog() << "No specific view command:" << url.toString();
return false;
}
@@ -604,135 +668,177 @@ Tomahawk::dynplaylist_ptr
GlobalActionManager::loadDynamicPlaylist( const QUrl& url, bool station )
{
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
if( parts.isEmpty() ) {
if ( parts.isEmpty() )
{
tLog() << "No specific station command:" << url.toString();
return Tomahawk::dynplaylist_ptr();
}
if( parts[ 0 ] == "create" ) {
if( !url.hasQueryItem( "title" ) || !url.hasQueryItem( "type" ) ) {
if ( parts[ 0 ] == "create" )
{
if ( !url.hasQueryItem( "title" ) || !url.hasQueryItem( "type" ) )
{
tLog() << "Station create command needs title and type..." << url.toString();
return Tomahawk::dynplaylist_ptr();
}
QString title = url.queryItemValue( "title" );
QString type = url.queryItemValue( "type" );
GeneratorMode m = Static;
if( station )
if ( station )
m = OnDemand;
dynplaylist_ptr pl = DynamicPlaylist::create( SourceList::instance()->getLocal(), uuid(), title, QString(), QString(), m, false, type );
pl->setMode( m );
QList< dyncontrol_ptr > controls;
QPair< QString, QString > param;
foreach( param, url.queryItems() ) {
if( param.first == "artist" ) {
foreach ( param, url.queryItems() )
{
if ( param.first == "artist" )
{
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistRadioType ) );
controls << c;
} else if( param.first == "artist_limitto" ) {
}
else if ( param.first == "artist_limitto" )
{
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistType ) );
controls << c;
} else if( param.first == "description" ) {
}
else if ( param.first == "description" )
{
dyncontrol_ptr c = pl->generator()->createControl( "Artist Description" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistDescriptionType ) );
controls << c;
} else if( param.first == "variety" ) {
}
else if ( param.first == "variety" )
{
dyncontrol_ptr c = pl->generator()->createControl( "Variety" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Variety ) );
controls << c;
} else if( param.first.startsWith( "tempo" ) ) {
}
else if ( param.first.startsWith( "tempo" ) )
{
dyncontrol_ptr c = pl->generator()->createControl( "Tempo" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinTempo + extra ) );
controls << c;
} else if( param.first.startsWith( "duration" ) ) {
}
else if ( param.first.startsWith( "duration" ) )
{
dyncontrol_ptr c = pl->generator()->createControl( "Duration" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDuration + extra ) );
controls << c;
} else if( param.first.startsWith( "loudness" ) ) {
}
else if ( param.first.startsWith( "loudness" ) )
{
dyncontrol_ptr c = pl->generator()->createControl( "Loudness" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinLoudness + extra ) );
controls << c;
} else if( param.first.startsWith( "danceability" ) ) {
}
else if ( param.first.startsWith( "danceability" ) )
{
dyncontrol_ptr c = pl->generator()->createControl( "Danceability" );
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDanceability + extra ) );
controls << c;
} else if( param.first.startsWith( "energy" ) ) {
}
else if ( param.first.startsWith( "energy" ) )
{
dyncontrol_ptr c = pl->generator()->createControl( "Energy" );
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinEnergy + extra ) );
controls << c;
} else if( param.first.startsWith( "artist_familiarity" ) ) {
}
else if ( param.first.startsWith( "artist_familiarity" ) )
{
dyncontrol_ptr c = pl->generator()->createControl( "Artist Familiarity" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinFamiliarity + extra ) );
controls << c;
} else if( param.first.startsWith( "artist_hotttnesss" ) ) {
}
else if ( param.first.startsWith( "artist_hotttnesss" ) )
{
dyncontrol_ptr c = pl->generator()->createControl( "Artist Hotttnesss" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinHotttnesss + extra ) );
controls << c;
} else if( param.first.startsWith( "song_hotttnesss" ) ) {
}
else if ( param.first.startsWith( "song_hotttnesss" ) )
{
dyncontrol_ptr c = pl->generator()->createControl( "Song Hotttnesss" );
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongMinHotttnesss + extra ) );
controls << c;
} else if( param.first.startsWith( "longitude" ) ) {
}
else if ( param.first.startsWith( "longitude" ) )
{
dyncontrol_ptr c = pl->generator()->createControl( "Longitude" );
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLongitude + extra ) );
controls << c;
} else if( param.first.startsWith( "latitude" ) ) {
}
else if ( param.first.startsWith( "latitude" ) )
{
dyncontrol_ptr c = pl->generator()->createControl( "Latitude" );
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLatitude + extra ) );
controls << c;
} else if( param.first == "key" ) {
}
else if ( param.first == "key" )
{
dyncontrol_ptr c = pl->generator()->createControl( "Key" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Key ) );
controls << c;
} else if( param.first == "mode" ) {
}
else if ( param.first == "mode" )
{
dyncontrol_ptr c = pl->generator()->createControl( "Mode" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mode ) );
controls << c;
} else if( param.first == "mood" ) {
}
else if ( param.first == "mood" )
{
dyncontrol_ptr c = pl->generator()->createControl( "Mood" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mood ) );
controls << c;
} else if( param.first == "style" ) {
}
else if ( param.first == "style" )
{
dyncontrol_ptr c = pl->generator()->createControl( "Style" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Style ) );
controls << c;
} else if( param.first == "song" ) {
}
else if ( param.first == "song" )
{
dyncontrol_ptr c = pl->generator()->createControl( "Song" );
c->setInput( param.second );
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongRadioType ) );
controls << c;
}
}
if( m == OnDemand )
if ( m == OnDemand )
pl->createNewRevision( uuid(), pl->currentrevision(), type, controls );
else
pl->createNewRevision( uuid(), pl->currentrevision(), type, controls, pl->entries() );
@@ -756,31 +862,35 @@ bool
GlobalActionManager::handlePlayCommand( const QUrl& url )
{
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
if( parts.isEmpty() ) {
if ( parts.isEmpty() )
{
tLog() << "No specific play command:" << url.toString();
return false;
}
if( parts[ 0 ] == "track" ) {
if( playSpotify( url ) )
if ( parts[ 0 ] == "track" )
{
if ( playSpotify( url ) )
return true;
else if( playRdio( url ) )
else if ( playRdio( url ) )
return true;
QPair< QString, QString > pair;
QString title, artist, album, urlStr;
foreach( pair, url.queryItems() ) {
if( pair.first == "title" )
foreach ( pair, url.queryItems() )
{
if ( pair.first == "title" )
title = pair.second;
else if( pair.first == "artist" )
else if ( pair.first == "artist" )
artist = pair.second;
else if( pair.first == "album" )
else if ( pair.first == "album" )
album = pair.second;
else if( pair.first == "url" )
else if ( pair.first == "url" )
urlStr = pair.second;
}
query_ptr q = Query::get( artist, title, album );
if( !urlStr.isEmpty() )
if ( !urlStr.isEmpty() )
q->setResultHint( urlStr );
playNow( q );
@@ -794,7 +904,7 @@ GlobalActionManager::handlePlayCommand( const QUrl& url )
bool
GlobalActionManager::playSpotify( const QUrl& url )
{
if( !url.hasQueryItem( "spotifyURI" ) && !url.hasQueryItem( "spotifyURL" ) )
if ( !url.hasQueryItem( "spotifyURI" ) && !url.hasQueryItem( "spotifyURL" ) )
return false;
QString spotifyUrl = url.hasQueryItem( "spotifyURI" ) ? url.queryItemValue( "spotifyURI" ) : url.queryItemValue( "spotifyURL" );
@@ -829,10 +939,9 @@ GlobalActionManager::playOrQueueNow( const query_ptr& q )
bool
GlobalActionManager::playRdio( const QUrl& url )
{
if( !url.hasQueryItem( "rdioURI" ) && !url.hasQueryItem( "rdioURL" ) )
if ( !url.hasQueryItem( "rdioURI" ) && !url.hasQueryItem( "rdioURL" ) )
return false;
QString rdioUrl = url.hasQueryItem( "rdioURI" ) ? url.queryItemValue( "spotifyURI" ) : url.queryItemValue( "rdioURL" );
RdioParser* p = new RdioParser( this );
p->parse( rdioUrl );
@@ -845,33 +954,36 @@ GlobalActionManager::playRdio( const QUrl& url )
bool GlobalActionManager::handleBookmarkCommand(const QUrl& url)
{
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
if( parts.isEmpty() ) {
if ( parts.isEmpty() )
{
tLog() << "No specific bookmark command:" << url.toString();
return false;
}
if( parts[ 0 ] == "track" ) {
if ( parts[ 0 ] == "track" )
{
QPair< QString, QString > pair;
QString title, artist, album, urlStr;
foreach( pair, url.queryItems() ) {
if( pair.first == "title" )
foreach ( pair, url.queryItems() )
{
if ( pair.first == "title" )
title = pair.second;
else if( pair.first == "artist" )
else if ( pair.first == "artist" )
artist = pair.second;
else if( pair.first == "album" )
else if ( pair.first == "album" )
album = pair.second;
else if( pair.first == "url" )
else if ( pair.first == "url" )
urlStr = pair.second;
}
query_ptr q = Query::get( artist, title, album );
if( !urlStr.isEmpty() )
if ( !urlStr.isEmpty() )
q->setResultHint( urlStr );
Pipeline::instance()->resolve( q, true );
// now we add it to the special "bookmarks" playlist, creating it if it doesn't exist. if nothing is playing, start playing the track
QSharedPointer< LocalCollection > col = SourceList::instance()->getLocal()->collection().dynamicCast< LocalCollection >();
playlist_ptr bookmarkpl = col->bookmarksPlaylist();
if( bookmarkpl.isNull() ) { // create it and do the deed then
if ( bookmarkpl.isNull() ) { // create it and do the deed then
m_waitingToBookmark = q;
col->createBookmarksPlaylist();
connect( col.data(), SIGNAL( bookmarkPlaylistCreated( Tomahawk::playlist_ptr ) ), this, SLOT( bookmarkPlaylistCreated( Tomahawk::playlist_ptr ) ), Qt::UniqueConnection );
@@ -894,7 +1006,7 @@ GlobalActionManager::shortenLinkRequestFinished()
bool error = false;
// NOTE: this should never happen
if( !reply )
if ( !reply )
{
emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() );
return;
@@ -908,14 +1020,14 @@ GlobalActionManager::shortenLinkRequestFinished()
QVariant urlVariant = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
// NOTE: this should never happen
if( urlVariant.isNull() || !urlVariant.isValid() )
if ( urlVariant.isNull() || !urlVariant.isValid() )
error = true;
QUrl longUrl = reply->request().url();
QUrl shortUrl = urlVariant.toUrl();
// NOTE: this should never happen
if( !shortUrl.isValid() )
if ( !shortUrl.isValid() )
error = true;
// Success! Here is the short link
@@ -950,7 +1062,7 @@ GlobalActionManager::shortenLinkRequestError( QNetworkReply::NetworkError error
QNetworkReply *reply = qobject_cast<QNetworkReply*>( sender() );
// NOTE: this should never happen
if( !reply )
if ( !reply )
{
emit shortLinkReady( QUrl( "" ), QUrl( "" ), QVariantMap() );
return;
@@ -1002,7 +1114,7 @@ GlobalActionManager::doBookmark( const playlist_ptr& pl, const query_ptr& q )
void
GlobalActionManager::showPlaylist()
{
if( m_toShow.isNull() )
if ( m_toShow.isNull() )
return;
ViewManager::instance()->show( m_toShow );

View File

@@ -67,7 +67,7 @@ public slots:
void handlePlayTrack( const Tomahawk::query_ptr& qry );
signals:
void shortLinkReady( QUrl longUrl, QUrl shortUrl, QVariant callbackObj ) const;
void shortLinkReady( const QUrl& longUrl, const QUrl& shortUrl, const QVariant& callbackObj );
private slots:
void shortenLinkRequestFinished();
@@ -83,6 +83,7 @@ private slots:
void playlistCreatedToShow( const Tomahawk::playlist_ptr& pl );
void playlistReadyToShow();
private:
explicit GlobalActionManager( QObject* parent = 0 );
void doBookmark( const Tomahawk::playlist_ptr& pl, const Tomahawk::query_ptr& q );

View File

@@ -136,12 +136,15 @@ AdiumPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
void
AdiumPlugin::audioStarted( const Tomahawk::InfoSystem::PushInfoPair pushInfoPair )
{
if ( !pushInfoPair.second.canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
if ( !pushInfoPair.second.canConvert< QVariantMap >() )
return;
Tomahawk::InfoSystem::InfoStringHash hash = pushInfoPair.second.value< Tomahawk::InfoSystem::InfoStringHash >();
QVariantMap map = pushInfoPair.second.toMap();
qDebug() << Q_FUNC_INFO;
if ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
return;
InfoStringHash hash = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) )
return;

View File

@@ -54,30 +54,87 @@ FdoNotifyPlugin::FdoNotifyPlugin()
: InfoPlugin()
{
qDebug() << Q_FUNC_INFO;
m_supportedPushTypes << Tomahawk::InfoSystem::InfoNotifyUser;
m_supportedPushTypes << InfoNotifyUser << InfoNowPlaying << InfoTrackUnresolved << InfoNowStopped;
}
FdoNotifyPlugin::~FdoNotifyPlugin()
{
qDebug() << Q_FUNC_INFO;
}
void
FdoNotifyPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
{
qDebug() << Q_FUNC_INFO;
QVariant inputData = pushData.infoPair.second;
if ( pushData.type != Tomahawk::InfoSystem::InfoNotifyUser || !inputData.canConvert< QVariantMap >() )
switch ( pushData.type )
{
qDebug() << Q_FUNC_INFO << " not the right type or could not convert the hash";
return;
case Tomahawk::InfoSystem::InfoTrackUnresolved:
notifyUser( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track from this source." );
return;
case Tomahawk::InfoSystem::InfoNotifyUser:
notifyUser( pushData.infoPair.second.toString() );
return;
case Tomahawk::InfoSystem::InfoNowStopped:
notifyUser( "Tomahawk is stopped." );
return;
case Tomahawk::InfoSystem::InfoNowPlaying:
nowPlaying( pushData.infoPair.second );
return;
default:
return;
}
QVariantMap hash = inputData.value< QVariantMap >();
if ( !hash.contains( "message" ) )
{
qDebug() << Q_FUNC_INFO << " hash did not contain a message";
}
void
FdoNotifyPlugin::notifyUser( const QString &messageText )
{
QDBusMessage message = QDBusMessage::createMethodCall( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", "Notify" );
QList<QVariant> arguments;
arguments << QString( "Tomahawk" ); //app_name
arguments << quint32( 0 ); //notification_id
arguments << QString(); //app_icon
arguments << QString( "Tomahawk" ); //summary
arguments << messageText; //body
arguments << QStringList(); //actions
QVariantMap dict;
dict["desktop-entry"] = QString( "tomahawk" );
dict[ "image_data" ] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-128x128.png" ) );
arguments << dict; //hints
arguments << qint32( -1 ); //expire_timeout
message.setArguments( arguments );
QDBusConnection::sessionBus().send( message );
}
void
FdoNotifyPlugin::nowPlaying( const QVariant &input )
{
if ( !input.canConvert< QVariantMap >() )
return;
}
QVariantMap map = input.toMap();
if ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
return;
InfoStringHash hash = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) )
return;
QString messageText = tr( "Tomahawk is playing \"%1\" by %2%3." )
.arg( hash[ "title" ] )
.arg( hash[ "artist" ] )
.arg( hash[ "album" ].isEmpty() ? QString() : QString( " %1" ).arg( tr( "on \"%1\"" ).arg( hash[ "album" ] ) ) );
QDBusMessage message = QDBusMessage::createMethodCall( "org.freedesktop.Notifications", "/org/freedesktop/Notifications", "org.freedesktop.Notifications", "Notify" );
QList<QVariant> arguments;
@@ -85,12 +142,12 @@ FdoNotifyPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
arguments << quint32( 0 ); //notification_id
arguments << QString(); //app_icon
arguments << QString( "Tomahawk" ); //summary
arguments << hash[ "message" ].toString(); //body
arguments << messageText; //body
arguments << QStringList(); //actions
QVariantMap dict;
dict["desktop-entry"] = QString( "tomahawk" );
if ( hash.contains( "image" ) && hash[ "image" ].canConvert< QImage >() )
dict[ "image_data" ] = ImageConverter::variantForImage( hash[ "image" ].value< QImage >() );
if ( map.contains( "cover" ) && map[ "cover" ].canConvert< QImage >() )
dict[ "image_data" ] = ImageConverter::variantForImage( map[ "cover" ].value< QImage >() );
else
dict[ "image_data" ] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-128x128.png" ) );
arguments << dict; //hints

View File

@@ -49,6 +49,11 @@ protected slots:
Q_UNUSED( criteria );
Q_UNUSED( requestData );
}
private:
void notifyUser( const QString &messageText );
void nowPlaying( const QVariant &input );
};
}

View File

@@ -41,7 +41,6 @@ static QString s_mpInfoIdentifier = QString( "MPRISPLUGIN" );
MprisPlugin::MprisPlugin()
: InfoPlugin()
, m_coverTempFile( 0 )
{
// init
m_playbackStatus = "Stopped";
@@ -75,22 +74,11 @@ MprisPlugin::MprisPlugin()
// Connect to AudioEngine's seeked signal
connect( AudioEngine::instance(), SIGNAL( seeked( qint64 ) ),
SLOT( onSeeked( qint64 ) ) );
// Connect to the InfoSystem (we need to get album covers via getInfo)
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 ) ) );
}
MprisPlugin::~MprisPlugin()
{
delete m_coverTempFile;
}
@@ -269,30 +257,15 @@ MprisPlugin::metadata() const
metadataMap.insert( "mpris:trackid", QString( "/track/" ) + track->id().replace( "-", "" ) );
metadataMap.insert( "mpris:length", track->duration() );
metadataMap.insert( "xesam:album", track->album()->name() );
metadataMap.insert( "xesam:artist", track->artist()->name() );
metadataMap.insert( "xesam:artist", QStringList( track->artist()->name() ) );
metadataMap.insert( "xesam:title", track->track() );
// Only return art if tempfile exists, and if its name contains the same "artist_album_tomahawk_cover.png"
if ( m_coverTempFile && m_coverTempFile->exists() &&
m_coverTempFile->fileName().contains( track->artist()->name() + "_" + track->album()->name() + "_tomahawk_cover.png" ) )
if ( !m_coverTempFile.isEmpty() )
{
metadataMap.insert( "mpris:artUrl", QString( QUrl::fromLocalFile( QFileInfo( *m_coverTempFile ).absoluteFilePath() ).toEncoded() ) );
}
else
{
// Need to fetch the album cover
Tomahawk::InfoSystem::InfoStringHash trackInfo;
trackInfo["artist"] = track->artist()->name();
trackInfo["album"] = track->album()->name();
Tomahawk::InfoSystem::InfoRequestData requestData;
requestData.caller = s_mpInfoIdentifier;
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
requestData.customData = QVariantMap();
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
QFile coverFile( m_coverTempFile );
if ( coverFile.exists() && coverFile.fileName().contains( track->artist()->name() + "_" + track->album()->name() + "_tomahawk_cover.png" ) )
metadataMap.insert( "mpris:artUrl", QString( QUrl::fromLocalFile( m_coverTempFile ).toEncoded() ) );
}
}
@@ -458,16 +431,6 @@ MprisPlugin::Stop()
// InfoPlugin Methods
void
MprisPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
{
Q_UNUSED( requestData );
return;
}
void
MprisPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
{
@@ -513,14 +476,23 @@ MprisPlugin::stateChanged( AudioState newState, AudioState oldState )
void
MprisPlugin::audioStarted( const QVariant& input )
{
if ( !input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
if ( !input.canConvert< QVariantMap >() )
return;
InfoStringHash hash = input.value< Tomahawk::InfoSystem::InfoStringHash >();
QVariantMap map = input.toMap();
if ( !map.contains( "trackinfo" ) || !map[ "trackinfo" ].canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
return;
InfoStringHash hash = map[ "trackinfo" ].value< Tomahawk::InfoSystem::InfoStringHash >();
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) )
return;
m_playbackStatus = "Playing";
if ( map.contains( "coveruri" ) )
m_coverTempFile = map[ "coveruri" ].toString();
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Metadata" );
}
@@ -596,80 +568,6 @@ MprisPlugin::onSeeked( qint64 ms )
}
void
MprisPlugin::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
{
// If the caller for the request was not us, or not the type of info we are seeking, ignore it
if ( requestData.caller != s_mpInfoIdentifier || requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
{
//notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Metadata" );
return;
}
if ( !output.canConvert< QVariantMap >() )
{
//notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Metadata" );
tDebug( LOGINFO ) << "Cannot convert fetched art from a QByteArray";
return;
}
// Pull image data into byte array
QVariantMap returnedData = output.value< QVariantMap >();
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
// Load from byte array to image
QImage image;
image.loadFromData( ba );
// Pull out request data for album+artist
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() )
{
qDebug() << "Cannot convert metadata input to album cover retrieval";
return;
}
Tomahawk::InfoSystem::InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash>();
// delete the old tempfile and make new one, to avoid caching of filename by mpris clients
if ( m_coverTempFile )
{
delete m_coverTempFile;
m_coverTempFile = 0;
}
if ( image.isNull() )
return;
m_coverTempFile = new QTemporaryFile( QDir::toNativeSeparators( QDir::tempPath() + "/" + hash["artist"] + "_" + hash["album"] + "_tomahawk_cover.png" ) );
if ( !m_coverTempFile->open() )
{
qDebug() << "WARNING: could not write temporary file for cover art!";
}
// Finally, save the image to the new temp file
if ( image.save( m_coverTempFile, "PNG" ) )
{
qDebug() << "Saving cover image to:" << QFileInfo( *m_coverTempFile ).absoluteFilePath();
m_coverTempFile->close();
notifyPropertyChanged( "org.mpris.MediaPlayer2.Player", "Metadata" );
}
else
{
tDebug() << Q_FUNC_INFO << "failed to save cover image!";
m_coverTempFile->close();
}
}
}
void
MprisPlugin::infoSystemFinished( QString target )
{
Q_UNUSED( target );
}
void
MprisPlugin::notifyPropertyChanged( const QString& interface, const QString& propertyName )
{

View File

@@ -140,7 +140,10 @@ public slots:
void Stop();
protected slots:
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
{
Q_UNUSED( requestData );
}
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData );
private slots:
@@ -150,9 +153,6 @@ private slots:
void onTrackCountChanged( unsigned int tracks );
void onSeeked( qint64 ms );
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
void infoSystemFinished( QString target );
signals:
void Seeked( qlonglong Position );
@@ -169,7 +169,7 @@ private:
// DBus
void notifyPropertyChanged( const QString& interface, const QString& propertyName );
QString m_playbackStatus;
QTemporaryFile* m_coverTempFile;
QString m_coverTempFile;
};
};

View File

@@ -122,6 +122,7 @@ enum InfoType { // as items are saved in cache, mark them here to not change the
InfoNowPaused = 81,
InfoNowResumed = 82,
InfoNowStopped = 83,
InfoTrackUnresolved = 84,
InfoLove = 90,
InfoUnLove = 91,

View File

@@ -212,5 +212,6 @@ private:
static TomahawkSettings* s_instance;
};
Q_DECLARE_METATYPE( TomahawkSettings::PrivateListeningMode );
#endif

View File

@@ -455,6 +455,8 @@ TomahawkApp::registerMetaTypes()
qRegisterMetaType< Tomahawk::InfoSystem::InfoPlugin* >( "Tomahawk::InfoSystem::InfoPlugin*" );
qRegisterMetaType< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > ");
qRegisterMetaType< TomahawkSettings::PrivateListeningMode >( "TomahawkSettings::PrivateListeningMode" );
qRegisterMetaTypeStreamOperators< QList< Tomahawk::InfoSystem::InfoStringHash > >("QList< Tomahawk::InfoSystem::InfoStringHash > ");
qRegisterMetaType< QPersistentModelIndex >( "QPersistentModelIndex" );