From 4ab4bbc23ff9f090612c23c0a78322f4789e2aa5 Mon Sep 17 00:00:00 2001 From: John Maguire Date: Thu, 27 Mar 2014 18:55:58 +0100 Subject: [PATCH] Remove Last.fm radio support. Fixes #4259 --- data/data.qrc | 7 - data/last.fm/ban.png | Bin 1777 -> 0 bytes data/last.fm/my_friends.png | Bin 1461 -> 0 bytes data/last.fm/my_neighbours.png | Bin 1367 -> 0 bytes data/last.fm/neighbour_radio.png | Bin 637 -> 0 bytes data/last.fm/personal_radio.png | Bin 580 -> 0 bytes data/last.fm/recommended_radio.png | Bin 1040 -> 0 bytes src/CMakeLists.txt | 6 +- src/core/application.cpp | 11 +- src/core/application.h | 3 + src/core/player.cpp | 2 +- src/core/player.h | 4 +- src/globalsearch/lastfmsearchprovider.cpp | 86 ---- src/globalsearch/lastfmsearchprovider.h | 43 -- src/internet/internetmodel.cpp | 16 +- src/internet/lastfmservice.cpp | 585 +--------------------- src/internet/lastfmservice.h | 121 +---- src/internet/lastfmsettingspage.cpp | 45 +- src/internet/lastfmsettingspage.h | 2 - src/internet/lastfmsettingspage.ui | 2 +- src/internet/lastfmstationdialog.cpp | 36 -- src/internet/lastfmstationdialog.h | 41 -- src/internet/lastfmstationdialog.ui | 119 ----- src/internet/lastfmurlhandler.cpp | 46 -- src/internet/scrobbler.h | 36 ++ src/networkremote/incomingdataparser.cpp | 6 +- src/ui/macsystemtrayicon.h | 2 +- src/ui/macsystemtrayicon.mm | 3 +- src/ui/mainwindow.cpp | 123 ++--- src/ui/mainwindow.ui | 29 -- src/ui/qtsystemtrayicon.cpp | 21 +- src/ui/qtsystemtrayicon.h | 7 +- src/ui/systemtrayicon.cpp | 3 +- src/ui/systemtrayicon.h | 5 +- 34 files changed, 128 insertions(+), 1282 deletions(-) delete mode 100644 data/last.fm/ban.png delete mode 100644 data/last.fm/my_friends.png delete mode 100644 data/last.fm/my_neighbours.png delete mode 100644 data/last.fm/neighbour_radio.png delete mode 100644 data/last.fm/personal_radio.png delete mode 100644 data/last.fm/recommended_radio.png delete mode 100644 src/globalsearch/lastfmsearchprovider.cpp delete mode 100644 src/globalsearch/lastfmsearchprovider.h delete mode 100644 src/internet/lastfmstationdialog.cpp delete mode 100644 src/internet/lastfmstationdialog.h delete mode 100644 src/internet/lastfmstationdialog.ui delete mode 100644 src/internet/lastfmurlhandler.cpp create mode 100644 src/internet/scrobbler.h diff --git a/data/data.qrc b/data/data.qrc index b620e7134..5603e732e 100644 --- a/data/data.qrc +++ b/data/data.qrc @@ -245,18 +245,11 @@ last.fm/as_disabled.png last.fm/as_light.png last.fm/as.png - last.fm/ban.png last.fm/icon_radio.png last.fm/icon_tag.png last.fm/icon_user.png last.fm/lastfm.png - last.fm/loved_radio.png last.fm/love.png - last.fm/my_friends.png - last.fm/my_neighbours.png - last.fm/neighbour_radio.png - last.fm/personal_radio.png - last.fm/recommended_radio.png last.fm/user_purple.png logo.png lumberjacksong.txt diff --git a/data/last.fm/ban.png b/data/last.fm/ban.png deleted file mode 100644 index 5cbf154e42af882a50da7e5a78a074cf3dac24b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1777 zcmVPx#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGf6951U69E94oEQKA23ko(K~z}7rI&e7Rdp1{eJrAn zJrNBA6wp*$h(!_EWHk(Ykib(=k-!B7HAT{-aZD2vQ*t387&Es36%djj7e>=uXVA=4 zd@hJ+ZY@s!(I2Ptz1@3#4@4fu%xC6ue&>A8_x}`~(G+@jW`M2zsnE;Sc_OOIvnm5)NweWA`s>t%*Fv+gm};j=_EcI7SR>$kDEOu)C6u#m$0= z<$4+5#F$;ff~fWDa{8n0xWJQxhv{P0Dys0CNLl8N*OHWd>&BT_7rPquTn%uH7}k)3 z+(-Ls<@$%EHFWg7w01ku&HyL)l{k+g&DsKbTJ-}x<;D_6R4J5c*6#$TO=fUj$1v_9 zW5n3x028ZCbIk0|912&{johtr{k@_+bdXP}_Dtv)z_b_kdz&t2uc626_(}P9?Km7Y zomN{q@8EQ6M#*#+QHn7~#*2xW(4$w;&LIKRv@&0=znYUrg$^DhT^%|GHdqbJXoyXv zM>{J7?icQ+3$s3y|CgwbOoG7H4hGvmG-HolQT4RRuNgN<(30xW1HE(%;KotVcQ`fW ztfPm;r2^+uvxv9yLjCwDa!dlTSD3(`A!EsmTxjl44=t${J%;_h!!llJn+`2#O10>Po>~T6KRY!!ogREq zBJguY4t;FV{|tTs6UxK)qiLZ#mu1`%>T--%b~s zJ8t4)bEXdy3=_4%adJ-U+AY+)WHnWJgm-2_39UoC3%6!25o#`{FNJ}6*#Hm4t((i% zQ0tn_0{gupaLG*-x6x4BMD^%M(j;ZjwTMKz;u9rM_TMeH!@-2sPJ4GbzmW$MJ+%!y zZ(fl{_f~BXC>h{Q@0-5q-exOh6J@;qYk*1z#5ytot!=h$a_(inXc%~|W8iL1F14&! zCr~`Vi+Fm6zT|wqFyT6yu7*z10kM~vfY!D?ZgSo)!Lhmq)?2yWX=_dd=QDEA1V zTuYY;9SoIhqI{4KU5`}jfLL1-(Aw4CQ_g7&jv@4v4Xm|vX}CBelUi~<6*wFbkA!8f zm~7d^zQMk9LzSchV%jF4RXrk5UjHc|iqKOwu+qYL>+z^5)bi0PfwP>%Q(E20<@LhE z(6OY6OV$A~$po}c21Uzjb>5+bp0WXciY4#!3gzaXQ1kq3x~@*4oi4&q1?p>J|1f{L znV6~rVlV-%>j^XD_};gC@KjBf4FsB4_20r%dU5(3x|24KZYR&8qX82zD4RQZt*wMY~COm>Qz?HTGzSEi@Z-OL37=O-mn>2Tp(ZqjEaR6Tnygo$I}Dp>ws49wz=P#ghaYo zjG9Sd=7^+-u}Cq;S*$UZ2JW@LjyX`500000NkvXXu0mjf-PJ)n diff --git a/data/last.fm/my_friends.png b/data/last.fm/my_friends.png deleted file mode 100644 index 912432ecd20a9314aac5622a3dbc4fb4240f0448..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1461 zcmV;m1xosfP)N za-^dx&73peoO9-$Bb;;GPSF5D2$c4?_iMv=sWzncn0e<6XO8_CfL%JhVUbR4 zNkpdhr6hk|<6}EU_^) z015hY?Y$3wc>mC6JGO11u~4G?!i$fNj4zzKj+=^2L}YBL5yc{bGO=ki{xbrlMJ_+E zA>Wbv-THN%pK?NDO6#8VGo9aWESJ)IHf{apUH9LIF)>~$Nl=^}^2X2HEfRjQecixU z3f-BB|#m zk3DN*Yi(qda~5k1#u#D{vc3O92M<5=#DRPIvPuc6wP>elJaY8upO5VWCR!N)8@pbu z)UNei8RnJ(D)or|?kvu+6R3?9CtrE*@29E1S7h$|80X)3V|*E|V#W5Jd?xDzOfS^P zW_)sKZ_viBcWsJrCaBkn)1`1{cP@pLlJSWu&V(hP{+sLX{OHZ6hNn6c{y=C=1=Did#wJU9GIq0ql=`{35tVb6`8d~NRC zvwsE%og2L#);s5e+9!n&<00;4z%(k;V}E__$=}zjUp$;iCo{9N*JnqLKlOx-DibRJ z;haMVp@5`H<@ZXzeK&$AS}L9*4lYRuzn&```NBu{{%~N&_Ws4dhPE05AR*yyWx;^qH^V}3o~z?JUSLF zmpeb!SNO^9LkGJPxeR^Qc7|c_$gf|zbW9}tzir)ff6va3AGj~&>pRPfl@qVOa`g1v zyBFd$DN@N?{;r{~e(Qll4}5QMAd8JHXD{#hbZKUyK5_1a5uNng{al8iR>#j~@Y~uj zxUA~v>)m(w(PQ`SEfjKTkK)|&-RWG{j^o4Mco0~)@rq*0X5aG;3~tI(4Gb}YJ2rPE zEb=n|&RT1OI<67o!aCMO04|Q%RoKu`$Yzq1sv&*r+sJoh_QjUXYa@`ta}NGBxx}@Z zGJZmlZ_A>jkbsJpmZ+XMMZ*{(FF|x|5&>u>yz+9yYnSF&Sgh0Eoh6K{RZ@5>0LjWP z2Tn+ZQcV>?uI>OR0kWk+G#wnyLDNTTgjB8NTUy1+IZ8JTl~yPvS1qMPdKxJ}c^aYQ zDp$#tk47h&UEt<>wVGXXC6o5)>PX`yG+N&1g9rh_)6K81n^CmOl;9wu{br4C$+*h0LuSuWUln04>XX_Q;`0b zjg2~6Pf+;iU|Ph_*Ij(^gZx%T=Kll$9*_Z2H>Dv0szCk!0^ClK+-CVVejHY^4&}7i P00000NkvXXu0mjfy=ciT diff --git a/data/last.fm/my_neighbours.png b/data/last.fm/my_neighbours.png deleted file mode 100644 index 98e4fbbe7d112dda444c759731116f4506ff35fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1367 zcmV-d1*rOoP)DpPpdJmP^t0IBUe|LTC?H|3_1DXxr5rBvQ0yeg95-W_3DIqZ8 zW%H+#ry&6KMoq`dYqxKCqVm2~D9oiXzyHANM@Q#|h-j)eUWW~}o%S^datQkH!^)0VA9!jTv<_j}F?h+;7HjnQ zdIcnnQ~N@uY2_|Q!VbJ(tYO-DaXRn@0q_lgP1M%fxNcYf=Kk#~nrgw!xcukX&O&nJ z!in6>UL6`^0xg*hjMmUv!w0Bb$TfW%Htk;b$lAD57DGC{*d22C_2|(4tpLWCE)Ou! zAf)I?R43rNKG-l4wUvM|-2n2#$%$Vk|2PJBGKra!!#H{7%xDf6BXFmaaN5sg4JA2XKnFpPT%29(PSjLDYlDTEc`!K5%x+xB56*wFXR0a^ZSjrH47llU zUEo5Ts68{EG1;suq>xyc%fijODF$>2z-JzxO^xgs7#L_?QNN;t4V#N&7mi#iWPe!F z4^I1T)vTBAC!$dwe2|%SRLJ2I!$-dI0`J*qH0mraETkqc9oy|Qk1qp=nL$JnK+GZP zvxVpd5X^_+?;03kX8)CnwwIoHsPFxjuFmF#WGemZ;NUkOr!KxV!`cVXRwLyW0%`*0 z%L~RF29Rdv@Rll~uv%HBqqVoMDp9q=7?Vj&PhB5PogbD&RiAhDf7rX@>AFa{gC=9D zeBXQR)1OB6NziW(RyNirn!C4ImUVwFmphc2ICbozn+Z!oWD`}lHuk)^@!?0`X>4mi zpf$!u#vfOQlkQM%=BSEA6VY-9UfxAC?jTxG0UsQ%5UOEy&*pvIy=z*_92>K#x%ETG z?XJml2cH8lcS{v8Yu! zZmp_GKuAJkO9Py^vz5W^r7szKD-b6_$MB;aN}u#f_P3>O!XJ@h*YS|hL`2(C5aH`z&d8 zQc5r}gb*MpZYqR;uoMIV(o!WlAqY}R7-JxnEcUhk0>tcCF+@T@2O7(!L;zW;xJOmd z3osZ2r4*ue1VReM5>iN#_Qd#A7&agROu&GOSO6G;Ae4dtLqrrvN&sL>O64vr zV(iicj9I#vucJ!bbWs67-k7PsCQp4de&s}`S;~kaWpXfw2yj3ISQ3B%lmrAJ0uh@H z!{MI?_q|tO9a~BzDG^EMjhQL|Xf{_2%CfPEtjMQ^jr?A|rtZbjf8 Z%ip{9P!=&jO!fc(002ovPDHLkV1g`aYHt7l diff --git a/data/last.fm/neighbour_radio.png b/data/last.fm/neighbour_radio.png deleted file mode 100644 index 28ab99a9a0976f3eb81bdccec26dd15ead63327b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 637 zcmV-@0)qXCP)Xf7{msNVKWqD01p<$3P1&y zU}7LPNDPZQ9*_Z|AO*8JXa5IbsA3HxdBYYb9hci63}S=Cu&5IS8-PWz0uXBhu{#ul z*a}$GfeqlnqFBgO*{sM+#r&GFqR|ag9u#&sM2PwkufKR-49b$fgJ+_K!VS0FJEXsBp-1JtVv55(HU z+W#O7G~jwmOUt6V^7{9^O}+p3Y~THV$CmBCu3x|Ybla9~Kl@tx{!eI|@E>T{TcBPe zkO2~|dhS;mQtSVNFo+Ela|?10eh$*yRp0f$s<7(agb5SYmgSYd+qY}a|B|$l|5oZY zw?KN~1~g?f{s&>G0eaRNwl`CPQ~vMXwhQEypQlfsez5CVld5Jy2Vh^+xq(45)yKiV_u zKMVlH%Yir=Nu3Zl8i7~@h~=Od#FmA*3YZp<4Twfl$A%*_qPVIYia~5$jNFJVi;{u? Xfq{dg$I$A600000NkvXXu0mjfG;Su{ diff --git a/data/last.fm/personal_radio.png b/data/last.fm/personal_radio.png deleted file mode 100644 index 0f10eeaf8a976a8d1b5b7d99a979e221447f279d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 580 zcmV-K0=xZ*P)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGf6951U69E94oEQKA0j)_yK~y-)rIJfX0$~uxjWVI~ zK@jO7dT6Kc9GDP9Bt#D*A_^p^&JjUGN(+jb5>W)b4?!oTAkj1f1v>L+5pQMH1- zK4h?rUZl1168BEw)@+5%@tIGKEXyW* zKHt8_8NMf~G*M5ctg2c!)5X((% z?>e1sDVxo*nM|e#4u2Sp#s!H)GKS}Ceib}V%mP7KEEdl(472L>dW$=7I2`Lzsnl3H zED*d*nSh{-Jryzvd{HhR76^6~-9YdHWx3$5AE_D9BeOhuzNh7HCbSg=|KS_|yA2h! SZ8xI;0000 diff --git a/data/last.fm/recommended_radio.png b/data/last.fm/recommended_radio.png deleted file mode 100644 index 0b7bdfcce641ff3ad5481618e17a45dd059325f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1040 zcmV+r1n>KaP)Px#AY({UO#lFTB>(_`g8%^e{{R4h=>PzAFaQARU;qF* zm;eA5Z<1fdMgRZ+32;bRa{vGf6951U69E94oEQKA19?eAK~y*q1;I^h6jcDg@&B9m zW_EYFUAlD3whK$4)!GUaBx*y%q9G84iW-d&14b{RMlX60ZiEWK7?t2bj3QA8pa(C~ z#7GDvL@#ZsDa44i-?R%9>hx=OXXnj4e?Ot@#InwpzL+#7Ea;&0>8+cW&n$Qo^XY6` z@K67F@-5qFd;E2)@6t!{%!-ZKhEY#zIIz0?d7>ads1UoR3Keq@QsCb&;!XcMXiS6x0;!a#tFI%TOb}|HyFrCY z*>9EeGl4 z`M8WJinDWA(n$b934siCFmq?{W;8!NK5jcn=_ISyE_kD|9C(zqL`H6OZ=!!_Y#_91 zaxIPNY@6$*at{b$*(wZ!xxahAKT;{pVN5jrP{+OxlbNL5{_qC&zR<~oO*sG?V_I!V zX?SGJ`~1Y|@n8Bb-!_r91dsp{fb;0KgKw;CTXXcq?M>|6xrr;+1{fHcM7c2*XNuVR zzy6)uJFJ$LmJK~UJr}yVy1Erm0!r&PzuTN^e(de)Wr~^E1-?G_YcVR9?sRSK$lH#s zj4|knUO(_>e@~%MxURJ>0wu9#)0;@;*bPljoN`juzEpjh>5&oY?fZXx*1dn}g`ch# zE7)ze>)>qD zIL^q}knf@4rmCq?PT`@Q9);6qN1U#S&0PsJ92Z>D1u5$4J0000< KMNUMnLSTYAq||o+ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd5182a31..ed573024e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -494,6 +494,7 @@ set(HEADERS internet/magnatunesettingspage.h internet/oauthenticator.h internet/savedradio.h + internet/scrobbler.h internet/searchboxwidget.h internet/somafmservice.h internet/somafmurlhandler.h @@ -817,13 +818,10 @@ optional_source(ENABLE_VISUALISATIONS optional_source(HAVE_LIBLASTFM SOURCES covers/lastfmcoverprovider.cpp - globalsearch/lastfmsearchprovider.cpp internet/fixlastfm.cpp internet/lastfmcompat.cpp internet/lastfmservice.cpp internet/lastfmsettingspage.cpp - internet/lastfmstationdialog.cpp - internet/lastfmurlhandler.cpp songinfo/echonestsimilarartists.cpp songinfo/echonesttags.cpp songinfo/lastfmtrackinfoprovider.cpp @@ -832,14 +830,12 @@ optional_source(HAVE_LIBLASTFM covers/lastfmcoverprovider.h internet/lastfmservice.h internet/lastfmsettingspage.h - internet/lastfmstationdialog.h songinfo/echonestsimilarartists.h songinfo/echonesttags.h songinfo/lastfmtrackinfoprovider.h songinfo/tagwidget.h UI internet/lastfmsettingspage.ui - internet/lastfmstationdialog.ui ) diff --git a/src/core/application.cpp b/src/core/application.cpp index 4201d2d1a..cb06b4dd8 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -39,6 +39,10 @@ #include "podcasts/podcastdownloader.h" #include "podcasts/podcastupdater.h" +#ifdef HAVE_LIBLASTFM +#include "internet/lastfmservice.h" +#endif // HAVE_LIBLASTFM + #ifdef HAVE_MOODBAR #include "moodbar/moodbarcontroller.h" #include "moodbar/moodbarloader.h" @@ -69,7 +73,8 @@ Application::Application(QObject* parent) moodbar_loader_(nullptr), moodbar_controller_(nullptr), network_remote_(nullptr), - network_remote_helper_(nullptr) { + network_remote_helper_(nullptr), + scrobbler_(nullptr) { tag_reader_client_ = new TagReaderClient(this); MoveToNewThread(tag_reader_client_); tag_reader_client_->Start(); @@ -116,6 +121,10 @@ Application::Application(QObject* parent) // crash when a client connects before the manager is initialized! network_remote_helper_ = new NetworkRemoteHelper(this); +#ifdef HAVE_LIBLASTFM + scrobbler_ = new LastFMService(this, this); +#endif // HAVE_LIBLASTFM + library_->Init(); DoInAMinuteOrSo(database_, SLOT(DoBackup())); diff --git a/src/core/application.h b/src/core/application.h index 9eadafb66..27fdc73ea 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -44,6 +44,7 @@ class PodcastDownloader; class PlaylistManager; class PodcastBackend; class PodcastUpdater; +class Scrobbler; class TagReaderClient; class TaskManager; @@ -86,6 +87,7 @@ class Application : public QObject { NetworkRemoteHelper* network_remote_helper() const { return network_remote_helper_; } + Scrobbler* scrobbler() const { return scrobbler_; } LibraryBackend* library_backend() const; LibraryModel* library_model() const; @@ -128,6 +130,7 @@ signals: MoodbarController* moodbar_controller_; NetworkRemote* network_remote_; NetworkRemoteHelper* network_remote_helper_; + Scrobbler* scrobbler_; QList objects_in_threads_; QList threads_; diff --git a/src/core/player.cpp b/src/core/player.cpp index 269272021..979c94726 100644 --- a/src/core/player.cpp +++ b/src/core/player.cpp @@ -76,7 +76,7 @@ void Player::Init() { engine_->SetVolume(settings_.value("volume", 50).toInt()); #ifdef HAVE_LIBLASTFM - lastfm_ = InternetModel::Service(); + lastfm_ = app_->scrobbler(); #endif } diff --git a/src/core/player.h b/src/core/player.h index bcbbecb1a..9dd26eab4 100644 --- a/src/core/player.h +++ b/src/core/player.h @@ -31,7 +31,7 @@ #include "playlist/playlistitem.h" class Application; -class LastFMService; +class Scrobbler; class PlayerInterface : public QObject { Q_OBJECT @@ -173,7 +173,7 @@ class Player : public PlayerInterface { private: Application* app_; - LastFMService* lastfm_; + Scrobbler* lastfm_; QSettings settings_; PlaylistItemPtr current_item_; diff --git a/src/globalsearch/lastfmsearchprovider.cpp b/src/globalsearch/lastfmsearchprovider.cpp deleted file mode 100644 index b1e2b9fcf..000000000 --- a/src/globalsearch/lastfmsearchprovider.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - Clementine 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. - - Clementine 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 Clementine. If not, see . -*/ - -#include "lastfmsearchprovider.h" -#include "core/logging.h" -#include "internet/lastfmservice.h" - -LastFMSearchProvider::LastFMSearchProvider(LastFMService* service, - Application* app, QObject* parent) - : SimpleSearchProvider(app, parent), service_(service) { - Init("Last.fm", "lastfm", QIcon(":last.fm/as.png"), - CanShowConfig | CanGiveSuggestions); - icon_ = ScaleAndPad(QImage(":last.fm/as.png")); - - set_safe_words(QStringList() << "lastfm" - << "last.fm"); - set_max_suggestion_count(3); - - connect(service, SIGNAL(SavedItemsChanged()), SLOT(MaybeRecreateItems())); - - // Load the friends list on startup only if it doesn't involve going to update - // info from the server. - if (!service_->IsFriendsListStale()) RecreateItems(); -} - -void LastFMSearchProvider::LoadArtAsync(int id, const Result& result) { - // TODO: Maybe we should try to get user pictures for friends? - - emit ArtLoaded(id, icon_); -} - -void LastFMSearchProvider::RecreateItems() { - QList items; - - items << Item(tr("My Last.fm Recommended Radio"), - QUrl("lastfm://user/USERNAME/recommended"), "recommended"); - items << Item(tr("My Last.fm Library"), - QUrl("lastfm://user/USERNAME/library"), "radio"); - items << Item(tr("My Last.fm Mix Radio"), QUrl("lastfm://user/USERNAME/mix"), - "mix"); - items << Item(tr("My Last.fm Neighborhood"), - QUrl("lastfm://user/USERNAME/neighbours"), "neighborhood"); - - const QStringList artists = service_->SavedArtistRadioNames(); - const QStringList tags = service_->SavedTagRadioNames(); - const QStringList friends = service_->FriendNames(); - - for (const QString& name : artists) { - items << Item(tr(LastFMService::kTitleArtist).arg(name), - QUrl(QString(LastFMService::kUrlArtist).arg(name)), name); - } - - for (const QString& name : tags) { - items << Item(tr(LastFMService::kTitleTag).arg(name), - QUrl(QString(LastFMService::kUrlTag).arg(name)), name); - } - - for (const QString& name : friends) { - items << Item(tr("Last.fm Radio Station - %1").arg(name), - QUrl("lastfm://user/" + name + "/library"), name); - items << Item(tr("Last.fm Mix Radio - %1").arg(name), - QUrl("lastfm://user/" + name + "/mix"), name); - items << Item(tr("Last.fm Neighbor Radio - %1").arg(name), - QUrl("lastfm://user/" + name + "/neighbours"), name); - } - - SetItems(items); -} - -bool LastFMSearchProvider::IsLoggedIn() { return service_->IsAuthenticated(); } - -void LastFMSearchProvider::ShowConfig() { service_->ShowConfig(); } diff --git a/src/globalsearch/lastfmsearchprovider.h b/src/globalsearch/lastfmsearchprovider.h deleted file mode 100644 index a71d01584..000000000 --- a/src/globalsearch/lastfmsearchprovider.h +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - Clementine 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. - - Clementine 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 Clementine. If not, see . -*/ - -#ifndef LASTFMSEARCHPROVIDER_H -#define LASTFMSEARCHPROVIDER_H - -#include "simplesearchprovider.h" - -class LastFMService; - -class LastFMSearchProvider : public SimpleSearchProvider { - public: - LastFMSearchProvider(LastFMService* service, Application* app, - QObject* parent); - - void LoadArtAsync(int id, const Result& result); - - bool IsLoggedIn(); - void ShowConfig(); - - protected: - void RecreateItems(); - - private: - LastFMService* service_; - QImage icon_; -}; - -#endif // LASTFMSEARCHPROVIDER_H diff --git a/src/internet/internetmodel.cpp b/src/internet/internetmodel.cpp index 7a16fd38e..fb190d828 100644 --- a/src/internet/internetmodel.cpp +++ b/src/internet/internetmodel.cpp @@ -38,9 +38,6 @@ #include "podcasts/podcastservice.h" #include "smartplaylists/generatormimedata.h" -#ifdef HAVE_LIBLASTFM -#include "lastfmservice.h" -#endif #ifdef HAVE_GOOGLE_DRIVE #include "googledriveservice.h" #endif @@ -57,7 +54,7 @@ #include "boxservice.h" #endif #ifdef HAVE_VK - #include "vkservice.h" +#include "vkservice.h" #endif using smart_playlists::Generator; @@ -80,9 +77,6 @@ InternetModel::InternetModel(Application* app, QObject* parent) AddService(new DigitallyImportedService(app, this)); AddService(new IcecastService(app, this)); AddService(new JamendoService(app, this)); -#ifdef HAVE_LIBLASTFM - AddService(new LastFMService(app, this)); -#endif #ifdef HAVE_GOOGLE_DRIVE AddService(new GoogleDriveService(app, this)); #endif @@ -172,13 +166,13 @@ InternetService* InternetModel::ServiceByName(const QString& name) { return nullptr; } -InternetService* InternetModel::ServiceForItem(const QStandardItem* item) - const { +InternetService* InternetModel::ServiceForItem( + const QStandardItem* item) const { return ServiceForIndex(indexFromItem(item)); } -InternetService* InternetModel::ServiceForIndex(const QModelIndex& index) - const { +InternetService* InternetModel::ServiceForIndex( + const QModelIndex& index) const { QModelIndex current_index = index; while (current_index.isValid()) { InternetService* service = diff --git a/src/internet/lastfmservice.cpp b/src/internet/lastfmservice.cpp index 0647b00f8..e3091eb2f 100644 --- a/src/internet/lastfmservice.cpp +++ b/src/internet/lastfmservice.cpp @@ -43,8 +43,6 @@ #endif #include "lastfmcompat.h" -#include "lastfmstationdialog.h" -#include "lastfmurlhandler.h" #include "internetmodel.h" #include "internetplaylistitem.h" #include "core/application.h" @@ -55,8 +53,6 @@ #include "core/taskmanager.h" #include "covers/coverproviders.h" #include "covers/lastfmcoverprovider.h" -#include "globalsearch/globalsearch.h" -#include "globalsearch/lastfmsearchprovider.h" #include "ui/iconloader.h" #include "ui/settingsdialog.h" @@ -73,72 +69,20 @@ const char* LastFMService::kAudioscrobblerClientId = "tng"; const char* LastFMService::kApiKey = "75d20fb472be99275392aefa2760ea09"; const char* LastFMService::kSecret = "d3072b60ae626be12be69448f5c46e70"; -const char* LastFMService::kUrlArtist = "lastfm://artist/%1/similarartists"; -const char* LastFMService::kUrlTag = "lastfm://globaltags/%1"; -const char* LastFMService::kUrlCustom = "lastfm://rql/%1"; - -const char* LastFMService::kTitleArtist = - QT_TR_NOOP("Last.fm Similar Artists to %1"); -const char* LastFMService::kTitleTag = QT_TR_NOOP("Last.fm Tag Radio: %1"); -const char* LastFMService::kTitleCustom = - QT_TR_NOOP("Last.fm Custom Radio: %1"); - -const int LastFMService::kFriendsCacheDurationSecs = 60 * 60 * 24; // 1 day - -LastFMService::LastFMService(Application* app, InternetModel* parent) - : InternetService(kServiceName, app, parent, parent), - url_handler_(new LastFMUrlHandler(this, this)), +LastFMService::LastFMService(Application* app, QObject* parent) + : Scrobbler(parent), scrobbler_(nullptr), already_scrobbled_(false), - station_dialog_(new LastFMStationDialog), - context_menu_(new QMenu), - initial_tune_(false), - tune_task_id_(0), scrobbling_enabled_(false), - root_item_(nullptr), - artist_list_(nullptr), - tag_list_(nullptr), - custom_list_(nullptr), - friends_list_(nullptr), - neighbours_list_(nullptr), - friend_names_(kSettingsGroup, "friend_names", kFriendsCacheDurationSecs), - connection_problems_(false) { + connection_problems_(false), + app_(app) { ReloadSettings(); // we emit the signal the first time to be sure the buttons are in the right // state emit ScrobblingEnabledChanged(scrobbling_enabled_); - context_menu_->addActions(GetPlaylistActions()); - remove_action_ = context_menu_->addAction(IconLoader::Load("list-remove"), - tr("Remove"), this, SLOT(Remove())); - context_menu_->addSeparator(); - add_artist_action_ = context_menu_->addAction( - QIcon(":last.fm/icon_radio.png"), tr("Play artist radio..."), this, - SLOT(AddArtistRadio())); - add_tag_action_ = context_menu_->addAction(QIcon(":last.fm/icon_tag.png"), - tr("Play tag radio..."), this, - SLOT(AddTagRadio())); - add_custom_action_ = context_menu_->addAction( - QIcon(":last.fm/icon_radio.png"), tr("Play custom radio..."), this, - SLOT(AddCustomRadio())); - refresh_friends_action_ = context_menu_->addAction( - IconLoader::Load("view-refresh"), tr("Refresh friends list"), this, - SLOT(ForceRefreshFriends())); - context_menu_->addAction(IconLoader::Load("configure"), - tr("Configure Last.fm..."), this, - SLOT(ShowConfig())); - - remove_action_->setEnabled(false); - add_artist_action_->setEnabled(false); - add_tag_action_->setEnabled(false); - add_custom_action_->setEnabled(false); - - app_->player()->RegisterUrlHandler(url_handler_); app_->cover_providers()->AddProvider(new LastFmCoverProvider(this)); - - app_->global_search()->AddProvider( - new LastFMSearchProvider(this, app_, this)); } LastFMService::~LastFMService() {} @@ -154,7 +98,6 @@ void LastFMService::ReloadSettings() { scrobble_button_visible_ = settings.value("ShowScrobbleButton", true).toBool(); prefer_albumartist_ = settings.value("PreferAlbumArtist", false).toBool(); - friend_names_.Load(); // avoid emitting signal if it's not changed if (scrobbling_enabled_old != scrobbling_enabled_) @@ -178,121 +121,6 @@ bool LastFMService::IsSubscriber() const { return settings.value("Subscriber", false).toBool(); } -QStandardItem* LastFMService::CreateRootItem() { - root_item_ = new QStandardItem(QIcon(":last.fm/as.png"), kServiceName); - root_item_->setData(true, InternetModel::Role_CanLazyLoad); - return root_item_; -} - -void LastFMService::LazyPopulate(QStandardItem* parent) { - switch (parent->data(InternetModel::Role_Type).toInt()) { - case InternetModel::Type_Service: - // Normal radio types - CreateStationItem(parent, tr("My Recommendations"), - ":last.fm/recommended_radio.png", - QUrl("lastfm://user/USERNAME/recommended"), - tr("My Last.fm Recommended Radio")); - CreateStationItem( - parent, tr("My Radio Station"), ":last.fm/personal_radio.png", - QUrl("lastfm://user/USERNAME/library"), tr("My Last.fm Library")); - CreateStationItem(parent, tr("My Mix Radio"), ":last.fm/loved_radio.png", - QUrl("lastfm://user/USERNAME/mix"), - tr("My Last.fm Mix Radio")); - CreateStationItem(parent, tr("My Neighborhood"), - ":last.fm/neighbour_radio.png", - QUrl("lastfm://user/USERNAME/neighbours"), - tr("My Last.fm Neighborhood")); - - // Types that have children - artist_list_ = new QStandardItem(QIcon(":last.fm/icon_radio.png"), - tr("Artist radio")); - artist_list_->setData(Type_Artists, InternetModel::Role_Type); - parent->appendRow(artist_list_); - - tag_list_ = - new QStandardItem(QIcon(":last.fm/icon_tag.png"), tr("Tag radio")); - tag_list_->setData(Type_Tags, InternetModel::Role_Type); - parent->appendRow(tag_list_); - - custom_list_ = new QStandardItem(QIcon(":last.fm/icon_radio.png"), - tr("Custom radio")); - custom_list_->setData(Type_Custom, InternetModel::Role_Type); - parent->appendRow(custom_list_); - - RestoreList("artists", kUrlArtist, tr(kTitleArtist), - QIcon(":last.fm/icon_radio.png"), artist_list_); - RestoreList("tags", kUrlTag, tr(kTitleTag), - QIcon(":last.fm/icon_tag.png"), tag_list_); - RestoreList("custom", kUrlCustom, tr(kTitleCustom), - QIcon(":last.fm/icon_radio.png"), custom_list_); - - friends_list_ = - new QStandardItem(QIcon(":last.fm/my_friends.png"), tr("Friends")); - friends_list_->setData(Type_Friends, InternetModel::Role_Type); - friends_list_->setData(true, InternetModel::Role_CanLazyLoad); - parent->appendRow(friends_list_); - - neighbours_list_ = new QStandardItem(QIcon(":last.fm/my_neighbours.png"), - tr("Neighbors")); - neighbours_list_->setData(Type_Neighbours, InternetModel::Role_Type); - neighbours_list_->setData(true, InternetModel::Role_CanLazyLoad); - parent->appendRow(neighbours_list_); - - if (!IsAuthenticated()) ShowConfig(); - - add_artist_action_->setEnabled(true); - add_tag_action_->setEnabled(true); - add_custom_action_->setEnabled(true); - break; - - case Type_Friends: - RefreshFriends(false); - break; - - case Type_Neighbours: - RefreshNeighbours(); - break; - - case Type_OtherUser: - CreateStationItem(parent, - tr("Last.fm Radio Station - %1").arg(parent->text()), - ":last.fm/personal_radio.png", - QUrl("lastfm://user/" + parent->text() + "/library"), - tr("Last.fm Library - %1").arg(parent->text())); - CreateStationItem(parent, - tr("Last.fm Mix Radio - %1").arg(parent->text()), - ":last.fm/loved_radio.png", - QUrl("lastfm://user/" + parent->text() + "/mix"), - tr("Last.fm Mix Radio - %1").arg(parent->text())); - CreateStationItem(parent, - tr("Last.fm Neighbor Radio - %1").arg(parent->text()), - ":last.fm/neighbour_radio.png", - QUrl("lastfm://user/" + parent->text() + "/neighbours"), - tr("Last.fm Neighbor Radio - %1").arg(parent->text())); - break; - - default: - break; - } -} - -QStandardItem* LastFMService::CreateStationItem(QStandardItem* parent, - const QString& name, - const QString& icon, - const QUrl& url, - const QString& title) { - Song song; - song.set_url(url); - song.set_title(title); - - QStandardItem* ret = new QStandardItem(QIcon(icon), name); - ret->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata); - ret->setData(InternetModel::PlayBehaviour_SingleItem, - InternetModel::Role_PlayBehaviour); - parent->appendRow(ret); - return ret; -} - void LastFMService::Authenticate(const QString& username, const QString& password) { QMap params; @@ -311,8 +139,6 @@ void LastFMService::SignOut() { lastfm::ws::Username.clear(); lastfm::ws::SessionKey.clear(); - friend_names_.Update(QStringList()); - QSettings settings; settings.beginGroup(kSettingsGroup); @@ -386,51 +212,6 @@ QUrl LastFMService::FixupUrl(const QUrl& url) { return ret; } -QUrl LastFMService::DeququeNextMediaUrl() { - if (playlist_.empty()) { - return QUrl(); - } - - lastfm::MutableTrack track = playlist_.dequeue(); - track.stamp(); - - already_scrobbled_ = false; - last_track_ = track; - if (playlist_.empty()) { - FetchMoreTracks(); - } - - next_metadata_ = track; - StreamMetadataReady(); - - return last_track_.url(); -} - -void LastFMService::StreamMetadataReady() { - Song metadata; - metadata.InitFromLastFM(next_metadata_); - - if (art_urls_.contains(next_metadata_)) - metadata.set_art_automatic(art_urls_[next_metadata_]); - - emit StreamMetadataFound(last_url_, metadata); -} - -void LastFMService::TunerError(lastfm::ws::Error error) { - qLog(Warning) << "Last.fm error" << error; - if (!initial_tune_) return; - - app_->task_manager()->SetTaskFinished(tune_task_id_); - tune_task_id_ = 0; - - if (error == lastfm::ws::NotEnoughContent) { - url_handler_->TunerError(); - return; - } - - emit StreamError(ErrorString(error)); -} - QString LastFMService::ErrorString(lastfm::ws::Error error) const { switch (error) { case lastfm::ws::InvalidService: @@ -477,13 +258,6 @@ QString LastFMService::ErrorString(lastfm::ws::Error error) const { } } -void LastFMService::TunerTrackAvailable() { - if (initial_tune_) { - url_handler_->TunerTrackAvailable(); - initial_tune_ = false; - } -} - bool LastFMService::InitScrobbler() { if (!IsAuthenticated() || !IsScrobblingEnabled()) return false; @@ -610,357 +384,6 @@ void LastFMService::Ban() { app_->player()->Next(); } -void LastFMService::ShowContextMenu(const QPoint& global_pos) { - switch (model() - ->current_index() - .parent() - .data(InternetModel::Role_Type) - .toInt()) { - case Type_Artists: - case Type_Tags: - case Type_Custom: - remove_action_->setEnabled(true); - break; - - default: - remove_action_->setEnabled(false); - break; - } - - const bool playable = model()->IsPlayable(model()->current_index()); - GetAppendToPlaylistAction()->setEnabled(playable); - GetReplacePlaylistAction()->setEnabled(playable); - GetOpenInNewPlaylistAction()->setEnabled(playable); - context_menu_->popup(global_pos); -} - -QStringList LastFMService::FriendNames() { - // Update the list for next time, in the main thread. - if (IsFriendsListStale()) - metaObject()->invokeMethod(this, "RefreshFriends", Qt::QueuedConnection); - - return friend_names_.Data(); -} - -static QStringList SavedArtistOrTagRadioNames(const QString& name) { - QStringList ret; - - QSettings s; - s.beginGroup(LastFMService::kSettingsGroup); - int count = s.beginReadArray(name); - for (int i = 0; i < count; ++i) { - s.setArrayIndex(i); - ret << s.value("key").toString(); - } - s.endArray(); - - return ret; -} - -QStringList LastFMService::SavedArtistRadioNames() const { - return SavedArtistOrTagRadioNames("artists"); -} - -QStringList LastFMService::SavedTagRadioNames() const { - return SavedArtistOrTagRadioNames("tags"); -} - -void LastFMService::RefreshFriends() { RefreshFriends(false); } - -void LastFMService::ForceRefreshFriends() { RefreshFriends(true); } - -void LastFMService::RefreshFriends(bool force) { - if (!IsAuthenticated()) { - return; - } - - if (!friends_list_) { - root_item_->setData(false, InternetModel::Role_CanLazyLoad); - LazyPopulate(root_item_); - } - - if (!force && !IsFriendsListStale()) { - PopulateFriendsList(); - return; - } - - lastfm::compat::AuthenticatedUser user; - QNetworkReply* reply = user.getFriends(); - NewClosure(reply, SIGNAL(finished()), this, - SLOT(RefreshFriendsFinished(QNetworkReply*)), reply); -} - -void LastFMService::RefreshNeighbours() { - if (!neighbours_list_ || !IsAuthenticated()) return; - - lastfm::compat::AuthenticatedUser user; - QNetworkReply* reply = user.getNeighbours(); - NewClosure(reply, SIGNAL(finished()), this, - SLOT(RefreshNeighboursFinished(QNetworkReply*)), reply); -} - -void LastFMService::RefreshFriendsFinished(QNetworkReply* reply) { - QList friends; - if (!lastfm::compat::ParseUserList(reply, &friends)) { - return; - } - - QStringList names; - for (const lastfm::User& f : friends) { - names << f.name(); - } - - friend_names_.Update(names); - - PopulateFriendsList(); - emit SavedItemsChanged(); -} - -void LastFMService::PopulateFriendsList() { - if (friends_list_->hasChildren()) - friends_list_->removeRows(0, friends_list_->rowCount()); - - for (const QString& name : friend_names_) { - Song song; - song.set_url(QUrl("lastfm://user/" + name + "/library")); - song.set_title(tr("Last.fm Library - %1").arg(name)); - - QStandardItem* item = - new QStandardItem(QIcon(":last.fm/icon_user.png"), name); - item->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata); - item->setData(true, InternetModel::Role_CanLazyLoad); - item->setData(Type_OtherUser, InternetModel::Role_Type); - item->setData(InternetModel::PlayBehaviour_SingleItem, - InternetModel::Role_PlayBehaviour); - friends_list_->appendRow(item); - } -} - -void LastFMService::RefreshNeighboursFinished(QNetworkReply* reply) { - QList neighbours; - if (!lastfm::compat::ParseUserList(reply, &neighbours)) { - return; - } - - if (neighbours_list_->hasChildren()) - neighbours_list_->removeRows(0, neighbours_list_->rowCount()); - - for (const lastfm::User& n : neighbours) { - Song song; - song.set_url(QUrl("lastfm://user/" + n.name() + "/library")); - song.set_title(tr("Last.fm Library - %1").arg(n.name())); - - QStandardItem* item = - new QStandardItem(QIcon(":last.fm/user_purple.png"), n.name()); - item->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata); - item->setData(true, InternetModel::Role_CanLazyLoad); - item->setData(Type_OtherUser, InternetModel::Role_Type); - item->setData(InternetModel::PlayBehaviour_SingleItem, - InternetModel::Role_PlayBehaviour); - neighbours_list_->appendRow(item); - } -} - -void LastFMService::AddArtistRadio() { - AddArtistOrTag("artists", LastFMStationDialog::Artist, kUrlArtist, - tr(kTitleArtist), ":last.fm/icon_radio.png", artist_list_); -} - -void LastFMService::AddTagRadio() { - AddArtistOrTag("tags", LastFMStationDialog::Tag, kUrlTag, tr(kTitleTag), - ":last.fm/icon_tag.png", tag_list_); -} - -void LastFMService::AddCustomRadio() { - AddArtistOrTag("custom", LastFMStationDialog::Custom, kUrlCustom, - tr(kTitleCustom), ":last.fm/icon_radio.png", custom_list_); -} - -void LastFMService::AddArtistOrTag(const QString& name, - LastFMStationDialog::Type dialog_type, - const QString& url_pattern, - const QString& title_pattern, - const QString& icon, QStandardItem* list) { - station_dialog_->SetType(dialog_type); - if (station_dialog_->exec() == QDialog::Rejected) return; - - if (station_dialog_->content().isEmpty()) return; - - QString content = station_dialog_->content(); - QString url; - if (name == "custom" && content.startsWith("lastfm://")) { - url = content; - } else if (name == "custom") { - url = url_pattern.arg(QString(content.toUtf8().toBase64())); - } else { - url = url_pattern.arg(content); - } - - Song song; - song.set_url(QUrl((url))); - song.set_title(title_pattern.arg(content)); - - QStandardItem* item = new QStandardItem(QIcon(icon), content); - item->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata); - item->setData(InternetModel::PlayBehaviour_SingleItem, - InternetModel::Role_PlayBehaviour); - list->appendRow(item); - emit AddItemToPlaylist(item->index(), AddMode_Append); - - SaveList(name, list); - - emit SavedItemsChanged(); -} - -void LastFMService::SaveList(const QString& name, QStandardItem* list) const { - QSettings settings; - settings.beginGroup(kSettingsGroup); - - settings.beginWriteArray(name, list->rowCount()); - for (int i = 0; i < list->rowCount(); ++i) { - settings.setArrayIndex(i); - settings.setValue("key", list->child(i)->text()); - } - settings.endArray(); -} - -void LastFMService::RestoreList(const QString& name, const QString& url_pattern, - const QString& title_pattern, const QIcon& icon, - QStandardItem* parent) { - if (parent->hasChildren()) parent->removeRows(0, parent->rowCount()); - - const QStringList keys = SavedArtistOrTagRadioNames(name); - - for (const QString& key : keys) { - QString url; - if (name == "custom" && key.startsWith("lastfm://")) { - url = key; - } else if (name == "custom") { - url = url_pattern.arg(QString(key.toUtf8().toBase64())); - } else { - url = url_pattern.arg(key); - } - - Song song; - song.set_url(QUrl(url)); - song.set_title(title_pattern.arg(key)); - - QStandardItem* item = new QStandardItem(icon, key); - item->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata); - item->setData(InternetModel::PlayBehaviour_SingleItem, - InternetModel::Role_PlayBehaviour); - parent->appendRow(item); - } -} - -void LastFMService::Remove() { - QStandardItem* context_item = - model()->itemFromIndex(model()->current_index()); - int type = context_item->parent()->data(InternetModel::Role_Type).toInt(); - - context_item->parent()->removeRow(context_item->row()); - - if (type == Type_Artists) - SaveList("artists", artist_list_); - else if (type == Type_Tags) - SaveList("tags", tag_list_); - else if (type == Type_Custom) - SaveList("custom", custom_list_); -} - -void LastFMService::FetchMoreTracks() { - QMap params; - params["method"] = "radio.getPlaylist"; - params["rtp"] = "1"; - QNetworkReply* reply = lastfm::ws::post(params); - NewClosure(reply, SIGNAL(finished()), this, - SLOT(FetchMoreTracksFinished(QNetworkReply*)), reply); -} - -void LastFMService::FetchMoreTracksFinished(QNetworkReply* reply) { - reply->deleteLater(); - app_->task_manager()->SetTaskFinished(tune_task_id_); - tune_task_id_ = 0; - - lastfm::XmlQuery query(lastfm::compat::EmptyXmlQuery()); - if (lastfm::compat::ParseQuery(reply->readAll(), &query)) { - const XmlQuery& playlist = query["playlist"]; - for (const XmlQuery& q : playlist["trackList"].children("track")) { - lastfm::MutableTrack t; - t.setUrl(QUrl(q["location"].text())); - t.setExtra("trackauth", q["extension"]["trackauth"].text()); - t.setTitle(q["title"].text()); - t.setArtist(q["creator"].text()); - t.setAlbum(q["album"].text()); - t.setDuration(q["duration"].text().toInt() / 1000); - t.setSource(lastfm::Track::LastFmRadio); - - art_urls_[t] = q["image"].text(); - playlist_ << t; - } - } else { - emit StreamError(tr("Couldn't load the last.fm radio station")); - return; - } - - TunerTrackAvailable(); -} - -void LastFMService::Tune(const QUrl& url) { - if (!tune_task_id_) - tune_task_id_ = - app_->task_manager()->StartTask(tr("Loading Last.fm radio")); - - last_url_ = url; - initial_tune_ = true; - const lastfm::RadioStation station(FixupUrl(url).toString()); - - playlist_.clear(); - - // Remove all the old album art URLs - art_urls_.clear(); - - QMap params; - params["method"] = "radio.tune"; - params["station"] = station.url(); - QNetworkReply* reply = lastfm::ws::post(params); - NewClosure(reply, SIGNAL(finished()), this, - SLOT(TuneFinished(QNetworkReply*)), reply); -} - -void LastFMService::TuneFinished(QNetworkReply* reply) { - reply->deleteLater(); - FetchMoreTracks(); -} - -PlaylistItem::Options LastFMService::playlistitem_options() const { - return PlaylistItem::LastFMControls | PlaylistItem::PauseDisabled | - PlaylistItem::SeekDisabled; -} - -PlaylistItemPtr LastFMService::PlaylistItemForUrl(const QUrl& url) { - // This is a bit of a hack, it's only used by the artist/song info tag - // widgets for tag radio and similar artists radio. - - if (url.scheme() != "lastfm") return PlaylistItemPtr(); - - QStringList sections(url.path().split("/", QString::SkipEmptyParts)); - - Song song; - song.set_url(url); - - if (sections.count() == 2 && url.host() == "artist" && - sections[1] == "similarartists") { - song.set_title(tr(kTitleArtist).arg(sections[0])); - } else if (sections.count() == 1 && url.host() == "globaltags") { - song.set_title(tr(kTitleTag).arg(sections[0])); - } else { - return PlaylistItemPtr(); - } - - return PlaylistItemPtr(new InternetPlaylistItem(this, song)); -} - void LastFMService::ToggleScrobbling() { // toggle status scrobbling_enabled_ = !scrobbling_enabled_; diff --git a/src/internet/lastfmservice.h b/src/internet/lastfmservice.h index 485e9a07f..aae8b8e2b 100644 --- a/src/internet/lastfmservice.h +++ b/src/internet/lastfmservice.h @@ -21,7 +21,6 @@ #include namespace lastfm { -class RadioStation; class Track; } @@ -30,29 +29,19 @@ uint qHash(const lastfm::Track& track); #include "lastfmcompat.h" -#include "internetmodel.h" -#include "internetservice.h" -#include "lastfmstationdialog.h" -#include "core/cachedlist.h" -#include "core/song.h" -#include "playlist/playlistitem.h" - -#include -#include -#include -#include +#include "internet/scrobbler.h" +class Application; class LastFMUrlHandler; - class QAction; class QNetworkAccessManager; +class Song; -class LastFMService : public InternetService { +class LastFMService : public Scrobbler { Q_OBJECT - friend class LastFMUrlHandler; public: - LastFMService(Application* app, InternetModel* parent); + LastFMService(Application* app, QObject* parent = nullptr); ~LastFMService(); static const char* kServiceName; @@ -61,34 +50,6 @@ class LastFMService : public InternetService { static const char* kApiKey; static const char* kSecret; - static const char* kUrlArtist; - static const char* kUrlTag; - static const char* kUrlCustom; - - static const char* kTitleArtist; - static const char* kTitleTag; - static const char* kTitleCustom; - - static const int kFriendsCacheDurationSecs; - - enum ItemType { - Type_Root = InternetModel::TypeCount, - Type_Artists, - Type_Tags, - Type_Custom, - Type_Friends, - Type_Neighbours, - Type_OtherUser, - }; - - // InternetService - QStandardItem* CreateRootItem(); - void LazyPopulate(QStandardItem* parent); - - void ShowContextMenu(const QPoint& global_pos); - - PlaylistItem::Options playlistitem_options() const; - void ReloadSettings(); virtual QString Icon() { return ":last.fm/lastfm.png"; } @@ -106,18 +67,6 @@ class LastFMService : public InternetService { void SignOut(); void UpdateSubscriberStatus(); - void FetchMoreTracks(); - QUrl DeququeNextMediaUrl(); - - PlaylistItemPtr PlaylistItemForUrl(const QUrl& url); - - bool IsFriendsListStale() const { return friend_names_.IsStale(); } - - // Thread safe - QStringList FriendNames(); - QStringList SavedArtistRadioNames() const; - QStringList SavedTagRadioNames() const; - public slots: void NowPlaying(const Song& song); void Scrobble(); @@ -142,91 +91,35 @@ signals: private slots: void AuthenticateReplyFinished(QNetworkReply* reply); void UpdateSubscriberStatusFinished(QNetworkReply* reply); - void RefreshFriendsFinished(QNetworkReply* reply); - void RefreshNeighboursFinished(QNetworkReply* reply); - void TunerTrackAvailable(); - void TunerError(lastfm::ws::Error error); void ScrobblerStatus(int value); - void AddArtistRadio(); - void AddTagRadio(); - void AddCustomRadio(); - void ForceRefreshFriends(); - void RefreshFriends(); - void Remove(); - - // Radio tuner. - void FetchMoreTracksFinished(QNetworkReply* reply); - void TuneFinished(QNetworkReply* reply); - - void StreamMetadataReady(); - private: - QStandardItem* CreateStationItem(QStandardItem* parent, const QString& name, - const QString& icon, const QUrl& url, - const QString& title); QString ErrorString(lastfm::ws::Error error) const; bool InitScrobbler(); lastfm::Track TrackFromSong(const Song& song) const; - void RefreshFriends(bool force); - void RefreshNeighbours(); - void AddArtistOrTag(const QString& name, - LastFMStationDialog::Type dialog_type, - const QString& url_pattern, const QString& title_pattern, - const QString& icon, QStandardItem* list); - void SaveList(const QString& name, QStandardItem* list) const; - void RestoreList(const QString& name, const QString& url_pattern, - const QString& title_pattern, const QIcon& icon, - QStandardItem* parent); static QUrl FixupUrl(const QUrl& url); - void Tune(const QUrl& station); - - void PopulateFriendsList(); - - void AddSelectedToPlaylist(bool clear_first); private: - LastFMUrlHandler* url_handler_; - lastfm::Audioscrobbler* scrobbler_; lastfm::Track last_track_; lastfm::Track next_metadata_; - QQueue playlist_; bool already_scrobbled_; - std::unique_ptr station_dialog_; - - std::unique_ptr context_menu_; - QAction* remove_action_; - QAction* add_artist_action_; - QAction* add_tag_action_; - QAction* add_custom_action_; - QAction* refresh_friends_action_; - QUrl last_url_; - bool initial_tune_; - int tune_task_id_; bool scrobbling_enabled_; bool buttons_visible_; bool scrobble_button_visible_; bool prefer_albumartist_; - QStandardItem* root_item_; - QStandardItem* artist_list_; - QStandardItem* tag_list_; - QStandardItem* custom_list_; - QStandardItem* friends_list_; - QStandardItem* neighbours_list_; - QHash art_urls_; - CachedList friend_names_; - // Useful to inform the user that we can't scrobble right now bool connection_problems_; + + Application* app_; }; #endif // LASTFMSERVICE_H diff --git a/src/internet/lastfmsettingspage.cpp b/src/internet/lastfmsettingspage.cpp index ba55a8a35..58715669e 100644 --- a/src/internet/lastfmsettingspage.cpp +++ b/src/internet/lastfmsettingspage.cpp @@ -16,21 +16,21 @@ */ #include "lastfmsettingspage.h" -#include "lastfmservice.h" -#include "internetmodel.h" #include "ui_lastfmsettingspage.h" -#include "ui/iconloader.h" #include #include -#include #include +#include "lastfmservice.h" +#include "internetmodel.h" +#include "core/application.h" +#include "ui/iconloader.h" + LastFMSettingsPage::LastFMSettingsPage(SettingsDialog* dialog) : SettingsPage(dialog), - service_( - static_cast(InternetModel::ServiceByName("Last.fm"))), + service_(static_cast(dialog->app()->scrobbler())), ui_(new Ui_LastFMSettingsPage), waiting_for_auth_(false) { ui_->setupUi(this); @@ -40,8 +40,6 @@ LastFMSettingsPage::LastFMSettingsPage(SettingsDialog* dialog) connect(service_, SIGNAL(AuthenticationComplete(bool, QString)), SLOT(AuthenticationComplete(bool, QString))); - connect(service_, SIGNAL(UpdatedSubscriberStatus(bool)), - SLOT(UpdatedSubscriberStatus(bool))); connect(ui_->login_state, SIGNAL(LogoutClicked()), SLOT(Logout())); connect(ui_->login_state, SIGNAL(LoginClicked()), SLOT(Login())); connect(ui_->login, SIGNAL(clicked()), SLOT(Login())); @@ -83,7 +81,6 @@ void LastFMSettingsPage::AuthenticationComplete(bool success, } RefreshControls(success); - service_->UpdateSubscriberStatus(); } void LastFMSettingsPage::Load() { @@ -92,31 +89,9 @@ void LastFMSettingsPage::Load() { ui_->scrobble_button->setChecked(service_->IsScrobbleButtonVisible()); ui_->prefer_albumartist->setChecked(service_->PreferAlbumArtist()); - if (service_->IsAuthenticated()) { - service_->UpdateSubscriberStatus(); - } - RefreshControls(service_->IsAuthenticated()); } -void LastFMSettingsPage::UpdatedSubscriberStatus(bool is_subscriber) { - ui_->login_state->SetAccountTypeVisible(!is_subscriber); - - if (!is_subscriber) { - if (service_->HasConnectionProblems()) { - ui_->login_state->SetAccountTypeText( - tr("Clementine couldn't fetch your subscription status since there " - "are problems " - "with your connection. Played tracks will be cached and sent " - "later to Last.fm.")); - } else { - ui_->login_state->SetAccountTypeText( - tr("You will not be able to play Last.fm radio stations " - "as you are not a Last.fm subscriber.")); - } - } -} - void LastFMSettingsPage::Save() { QSettings s; s.beginGroup(LastFMService::kSettingsGroup); @@ -141,12 +116,4 @@ void LastFMSettingsPage::RefreshControls(bool authenticated) { ui_->login_state->SetLoggedIn( authenticated ? LoginStateWidget::LoggedIn : LoginStateWidget::LoggedOut, lastfm::ws::Username); - ui_->login_state->SetAccountTypeVisible(!authenticated); - - if (!authenticated) { - ui_->login_state->SetAccountTypeText( - tr("You can scrobble tracks for free, but only " - "paid subscribers " - "can stream Last.fm radio from Clementine.")); - } } diff --git a/src/internet/lastfmsettingspage.h b/src/internet/lastfmsettingspage.h index 329be560b..cf5e12580 100644 --- a/src/internet/lastfmsettingspage.h +++ b/src/internet/lastfmsettingspage.h @@ -37,12 +37,10 @@ class LastFMSettingsPage : public SettingsPage { void Login(); void AuthenticationComplete(bool success, const QString& error_message); void Logout(); - void UpdatedSubscriberStatus(bool is_subscriber); private: LastFMService* service_; Ui_LastFMSettingsPage* ui_; - QMovie* loading_icon_; bool waiting_for_auth_; diff --git a/src/internet/lastfmsettingspage.ui b/src/internet/lastfmsettingspage.ui index 1b5c04eb5..cf8f865b6 100644 --- a/src/internet/lastfmsettingspage.ui +++ b/src/internet/lastfmsettingspage.ui @@ -83,7 +83,7 @@ - Show the "love" and "ban" buttons + Show the "love" button true diff --git a/src/internet/lastfmstationdialog.cpp b/src/internet/lastfmstationdialog.cpp deleted file mode 100644 index 2a16dc3b3..000000000 --- a/src/internet/lastfmstationdialog.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - Clementine 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. - - Clementine 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 Clementine. If not, see . -*/ - -#include "lastfmstationdialog.h" -#include "ui_lastfmstationdialog.h" - -LastFMStationDialog::LastFMStationDialog(QWidget* parent) - : QDialog(parent), ui_(new Ui_LastFMStationDialog) { - ui_->setupUi(this); - - resize(sizeHint()); -} - -LastFMStationDialog::~LastFMStationDialog() { delete ui_; } - -void LastFMStationDialog::SetType(Type type) { - ui_->type->setCurrentIndex(type); - ui_->content->clear(); - ui_->content->setFocus(Qt::OtherFocusReason); -} - -QString LastFMStationDialog::content() const { return ui_->content->text(); } diff --git a/src/internet/lastfmstationdialog.h b/src/internet/lastfmstationdialog.h deleted file mode 100644 index a59e126f7..000000000 --- a/src/internet/lastfmstationdialog.h +++ /dev/null @@ -1,41 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - Clementine 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. - - Clementine 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 Clementine. If not, see . -*/ - -#ifndef LASTFMSTATIONDIALOG_H -#define LASTFMSTATIONDIALOG_H - -#include - -class Ui_LastFMStationDialog; - -class LastFMStationDialog : public QDialog { - Q_OBJECT - - public: - LastFMStationDialog(QWidget* parent = nullptr); - ~LastFMStationDialog(); - - enum Type { Artist, Tag, Custom, }; - - void SetType(Type type); - QString content() const; - - private: - Ui_LastFMStationDialog* ui_; -}; - -#endif // LASTFMSTATIONDIALOG_H diff --git a/src/internet/lastfmstationdialog.ui b/src/internet/lastfmstationdialog.ui deleted file mode 100644 index 241d95edd..000000000 --- a/src/internet/lastfmstationdialog.ui +++ /dev/null @@ -1,119 +0,0 @@ - - - LastFMStationDialog - - - - 0 - 0 - 407 - 126 - - - - Play Artist or Tag - - - - :/last.fm/as.png:/last.fm/as.png - - - - - - Enter an <b>artist</b> or <b>tag</b> to start listening to Last.fm radio. - - - true - - - - - - - - - - Artist - - - - - Tag - - - - - Custom - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 7 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - - buttonBox - accepted() - LastFMStationDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - LastFMStationDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/src/internet/lastfmurlhandler.cpp b/src/internet/lastfmurlhandler.cpp deleted file mode 100644 index 2750c2294..000000000 --- a/src/internet/lastfmurlhandler.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* This file is part of Clementine. - Copyright 2010, David Sansome - - Clementine 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. - - Clementine 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 Clementine. If not, see . -*/ - -#include "lastfmservice.h" -#include "lastfmurlhandler.h" - -LastFMUrlHandler::LastFMUrlHandler(LastFMService* service, QObject* parent) - : UrlHandler(parent), service_(service) {} - -UrlHandler::LoadResult LastFMUrlHandler::StartLoading(const QUrl& url) { - if (!service_->IsAuthenticated()) return LoadResult(); - - service_->Tune(url); - return LoadResult(url, LoadResult::WillLoadAsynchronously); -} - -void LastFMUrlHandler::TunerTrackAvailable() { - emit AsyncLoadComplete(LoadNext(service_->last_url_)); -} - -void LastFMUrlHandler::TunerError() { - emit AsyncLoadComplete( - LoadResult(service_->last_url_, LoadResult::NoMoreTracks)); -} - -UrlHandler::LoadResult LastFMUrlHandler::LoadNext(const QUrl& url) { - const QUrl media_url = service_->DeququeNextMediaUrl(); - if (media_url.isEmpty()) { - return LoadResult(); - } - return LoadResult(url, LoadResult::TrackAvailable, media_url); -} diff --git a/src/internet/scrobbler.h b/src/internet/scrobbler.h new file mode 100644 index 000000000..9beece9fa --- /dev/null +++ b/src/internet/scrobbler.h @@ -0,0 +1,36 @@ +#ifndef SCROBBLER_H +#define SCROBBLER_H + +#include + +class Song; + +class Scrobbler : public QObject { + Q_OBJECT + + public: + Scrobbler(QObject* parent = nullptr) {} + + virtual bool IsAuthenticated() const = 0; + virtual bool IsScrobblingEnabled() const = 0; + virtual bool AreButtonsVisible() const = 0; + virtual bool IsScrobbleButtonVisible() const = 0; + virtual bool PreferAlbumArtist() const = 0; + + public slots: + virtual void NowPlaying(const Song& song) = 0; + virtual void Scrobble() = 0; + virtual void Love() = 0; + virtual void ToggleScrobbling() = 0; + virtual void ShowConfig() = 0; + +signals: + void AuthenticationComplete(bool success, const QString& error_message); + void ScrobblingEnabledChanged(bool value); + void ButtonVisibilityChanged(bool value); + void ScrobbleButtonVisibilityChanged(bool value); + void ScrobbleSubmitted(); + void ScrobbleError(int value); +}; + +#endif // SCROBBLER_H diff --git a/src/networkremote/incomingdataparser.cpp b/src/networkremote/incomingdataparser.cpp index 80e2aca3d..8cc9a0b66 100644 --- a/src/networkremote/incomingdataparser.cpp +++ b/src/networkremote/incomingdataparser.cpp @@ -70,10 +70,7 @@ IncomingDataParser::IncomingDataParser(Application* app) : app_(app) { SLOT(RateCurrentSong(double))); #ifdef HAVE_LIBLASTFM - connect(this, SIGNAL(Love()), InternetModel::Service(), - SLOT(Love())); - connect(this, SIGNAL(Ban()), InternetModel::Service(), - SLOT(Ban())); + connect(this, SIGNAL(Love()), app_->scrobbler(), SLOT(Love())); #endif } @@ -261,7 +258,6 @@ void IncomingDataParser::RemoveSongs(const pb::remote::Message& msg) { } void IncomingDataParser::ClientConnect(const pb::remote::Message& msg) { - // Always sned the Clementine infos emit SendClementineInfo(); diff --git a/src/ui/macsystemtrayicon.h b/src/ui/macsystemtrayicon.h index 6fa5b5898..a3c61502d 100644 --- a/src/ui/macsystemtrayicon.h +++ b/src/ui/macsystemtrayicon.h @@ -33,7 +33,7 @@ class MacSystemTrayIcon : public SystemTrayIcon { void SetupMenu(QAction* previous, QAction* play, QAction* stop, QAction* stop_after, QAction* next, QAction* mute, - QAction* love, QAction* ban, QAction* quit); + QAction* love, QAction* quit); void SetNowPlaying(const Song& song, const QString& image_path); void ClearNowPlaying(); diff --git a/src/ui/macsystemtrayicon.mm b/src/ui/macsystemtrayicon.mm index f789ec458..c2f309ab2 100644 --- a/src/ui/macsystemtrayicon.mm +++ b/src/ui/macsystemtrayicon.mm @@ -177,7 +177,7 @@ MacSystemTrayIcon::~MacSystemTrayIcon() {} void MacSystemTrayIcon::SetupMenu(QAction* previous, QAction* play, QAction* stop, QAction* stop_after, QAction* next, QAction* mute, QAction* love, - QAction* ban, QAction* quit) { + QAction* quit) { p_.reset(new MacSystemTrayIconPrivate()); SetupMenuItem(previous); SetupMenuItem(play); @@ -188,7 +188,6 @@ void MacSystemTrayIcon::SetupMenu(QAction* previous, QAction* play, SetupMenuItem(mute); p_->AddSeparator(); SetupMenuItem(love); - SetupMenuItem(ban); Q_UNUSED(quit); // Mac already has a Quit item. } diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 194dbfd0f..20d07962f 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -149,7 +149,7 @@ #endif #ifdef HAVE_VK -# include "internet/vkservice.h" +#include "internet/vkservice.h" #endif #ifdef Q_OS_DARWIN @@ -342,15 +342,13 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, SLOT(StopAfterCurrent())); connect(ui_->action_mute, SIGNAL(triggered()), app_->player(), SLOT(Mute())); #ifdef HAVE_LIBLASTFM - connect(ui_->action_ban, SIGNAL(triggered()), - InternetModel::Service(), SLOT(Ban())); connect(ui_->action_love, SIGNAL(triggered()), SLOT(Love())); - connect(ui_->action_toggle_scrobbling, SIGNAL(triggered()), - InternetModel::Service(), SLOT(ToggleScrobbling())); + connect(ui_->action_toggle_scrobbling, SIGNAL(triggered()), app_->scrobbler(), + SLOT(ToggleScrobbling())); #endif #ifdef HAVE_VK - connect(ui_->action_love, SIGNAL(triggered()), + connect(ui_->action_love, SIGNAL(triggered()), InternetModel::Service(), SLOT(AddToMyMusicCurrent())); #endif @@ -424,7 +422,6 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, ui_->pause_play_button->setDefaultAction(ui_->action_play_pause); ui_->stop_button->setDefaultAction(ui_->action_stop); ui_->love_button->setDefaultAction(ui_->action_love); - ui_->ban_button->setDefaultAction(ui_->action_ban); ui_->scrobbling_button->setDefaultAction(ui_->action_toggle_scrobbling); ui_->clear_playlist_button->setDefaultAction(ui_->action_clear_playlist); ui_->playlist->SetActions( @@ -654,14 +651,13 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, connect(app_->internet_model(), SIGNAL(ScrollToIndex(QModelIndex)), SLOT(ScrollToInternetIndex(QModelIndex))); #ifdef HAVE_LIBLASTFM - LastFMService* lastfm_service = InternetModel::Service(); - connect(lastfm_service, SIGNAL(ButtonVisibilityChanged(bool)), + connect(app_->scrobbler(), SIGNAL(ButtonVisibilityChanged(bool)), SLOT(LastFMButtonVisibilityChanged(bool))); - connect(lastfm_service, SIGNAL(ScrobbleButtonVisibilityChanged(bool)), + connect(app_->scrobbler(), SIGNAL(ScrobbleButtonVisibilityChanged(bool)), SLOT(ScrobbleButtonVisibilityChanged(bool))); - connect(lastfm_service, SIGNAL(ScrobblingEnabledChanged(bool)), + connect(app_->scrobbler(), SIGNAL(ScrobblingEnabledChanged(bool)), SLOT(ScrobblingEnabledChanged(bool))); - connect(lastfm_service, SIGNAL(ScrobbledRadioStream()), + connect(app_->scrobbler(), SIGNAL(ScrobbledRadioStream()), SLOT(ScrobbledRadioStream())); #endif connect(app_->internet_model()->Service(), @@ -681,7 +677,7 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, tray_icon_->SetupMenu(ui_->action_previous_track, ui_->action_play_pause, ui_->action_stop, ui_->action_stop_after_this_track, ui_->action_next_track, ui_->action_mute, - ui_->action_love, ui_->action_ban, ui_->action_quit); + ui_->action_love, ui_->action_quit); connect(tray_icon_, SIGNAL(PlayPause()), app_->player(), SLOT(PlayPause())); connect(tray_icon_, SIGNAL(SeekForward()), app_->player(), SLOT(SeekForward())); @@ -698,7 +694,7 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, << ui_->action_previous_track << ui_->action_play_pause << ui_->action_stop << ui_->action_next_track << nullptr // spacer - << ui_->action_love << ui_->action_ban); + << ui_->action_love); #if (defined(Q_OS_DARWIN) && defined(HAVE_SPARKLE)) || defined(Q_OS_WIN32) // Add check for updates item to application menu. @@ -744,8 +740,7 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, connect(global_shortcuts_, SIGNAL(TogglePrettyOSD()), app_->player(), SLOT(TogglePrettyOSD())); #ifdef HAVE_LIBLASTFM - connect(global_shortcuts_, SIGNAL(ToggleScrobbling()), - app_->internet_model()->InternetModel::Service(), + connect(global_shortcuts_, SIGNAL(ToggleScrobbling()), app_->scrobbler(), SLOT(ToggleScrobbling())); #endif @@ -844,20 +839,14 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, SLOT(ShuffleModeChanged(PlaylistSequence::ShuffleMode))); #ifdef HAVE_LIBLASTFM - connect(InternetModel::Service(), SIGNAL(ScrobbleSubmitted()), + connect(app_->scrobbler(), SIGNAL(ScrobbleSubmitted()), SLOT(ScrobbleSubmitted())); - connect(InternetModel::Service(), SIGNAL(ScrobbleError(int)), + connect(app_->scrobbler(), SIGNAL(ScrobbleError(int)), SLOT(ScrobbleError(int))); - LastFMButtonVisibilityChanged(app_->internet_model() - ->InternetModel::Service() - ->AreButtonsVisible()); - ScrobbleButtonVisibilityChanged(app_->internet_model() - ->InternetModel::Service() - ->IsScrobbleButtonVisible()); - ScrobblingEnabledChanged(app_->internet_model() - ->InternetModel::Service() - ->IsScrobblingEnabled()); + LastFMButtonVisibilityChanged(app_->scrobbler()->AreButtonsVisible()); + ScrobbleButtonVisibilityChanged(app_->scrobbler()->IsScrobbleButtonVisible()); + ScrobblingEnabledChanged(app_->scrobbler()->IsScrobblingEnabled()); #else LastFMButtonVisibilityChanged(false); ScrobbleButtonVisibilityChanged(false); @@ -869,7 +858,7 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd, restoreGeometry(settings_.value("geometry").toByteArray()); if (!ui_->splitter->restoreState( - settings_.value("splitter_state").toByteArray())) { + settings_.value("splitter_state").toByteArray())) { ui_->splitter->setSizes(QList() << 300 << width() - 300); } ui_->tabs->SetCurrentIndex( @@ -989,10 +978,8 @@ void MainWindow::MediaStopped() { ui_->action_play_pause->setEnabled(true); - ui_->action_ban->setEnabled(false); ui_->action_love->setEnabled(false); tray_icon_->LastFMButtonLoveStateChanged(false); - tray_icon_->LastFMButtonBanStateChanged(false); track_position_timer_->stop(); ui_->track_slider->SetStopped(); @@ -1028,18 +1015,10 @@ void MainWindow::MediaPlaying() { ui_->track_slider->SetCanSeek(can_seek); #ifdef HAVE_LIBLASTFM - bool is_lastfm = (app_->player()->GetCurrentItem()->options() & - PlaylistItem::LastFMControls); - LastFMService* lastfm = InternetModel::Service(); - bool enable_ban = lastfm->IsScrobblingEnabled() && is_lastfm; - bool enable_love = lastfm->IsScrobblingEnabled(); - - ui_->action_ban->setEnabled(enable_ban); + bool enable_love = app_->scrobbler()->IsScrobblingEnabled(); ui_->action_love->setEnabled(enable_love); - tray_icon_->LastFMButtonBanStateChanged(enable_ban); tray_icon_->LastFMButtonLoveStateChanged(enable_love); - - tray_icon_->SetPlaying(enable_play_pause, enable_ban, enable_love); + tray_icon_->SetPlaying(enable_play_pause, enable_love); #else tray_icon_->SetPlaying(enable_play_pause); #endif @@ -1059,8 +1038,7 @@ void MainWindow::SongChanged(const Song& song) { #ifdef HAVE_LIBLASTFM if (ui_->action_toggle_scrobbling->isVisible()) - SetToggleScrobblingIcon( - InternetModel::Service()->IsScrobblingEnabled()); + SetToggleScrobblingIcon(app_->scrobbler()->IsScrobblingEnabled()); #endif } @@ -1104,17 +1082,12 @@ void MainWindow::ScrobblingEnabledChanged(bool value) { } } - bool is_lastfm = (app_->player()->GetCurrentItem()->options() & - PlaylistItem::LastFMControls); - ui_->action_ban->setEnabled(value && is_lastfm); - tray_icon_->LastFMButtonBanStateChanged(value && is_lastfm); ui_->action_love->setEnabled(value); tray_icon_->LastFMButtonLoveStateChanged(value); } #endif void MainWindow::LastFMButtonVisibilityChanged(bool value) { - ui_->action_ban->setVisible(value); ui_->action_love->setVisible(value); ui_->last_fm_controls->setVisible(value); tray_icon_->LastFMButtonVisibilityChanged(value); @@ -1132,9 +1105,7 @@ void MainWindow::ScrobbleButtonVisibilityChanged(bool value) { ui_->action_toggle_scrobbling->setIcon(QIcon(":/last.fm/as.png")); } else { #ifdef HAVE_LIBLASTFM - SetToggleScrobblingIcon(app_->internet_model() - ->InternetModel::Service() - ->IsScrobblingEnabled()); + SetToggleScrobblingIcon(app_->scrobbler()->IsScrobblingEnabled()); #endif } } @@ -1300,20 +1271,19 @@ void MainWindow::UpdateTrackPosition() { return; } #ifdef HAVE_LIBLASTFM - LastFMService* lastfm_service = InternetModel::Service(); const bool last_fm_enabled = ui_->action_toggle_scrobbling->isVisible() && - lastfm_service->IsScrobblingEnabled() && - lastfm_service->IsAuthenticated(); + app_->scrobbler()->IsScrobblingEnabled() && + app_->scrobbler()->IsAuthenticated(); #endif // Time to scrobble? if (position >= scrobble_point) { if (playlist->get_lastfm_status() == Playlist::LastFM_New) { #ifdef HAVE_LIBLASTFM - if (lastfm_service->IsScrobblingEnabled() && - lastfm_service->IsAuthenticated()) { + if (app_->scrobbler()->IsScrobblingEnabled() && + app_->scrobbler()->IsAuthenticated()) { qLog(Info) << "Scrobbling at" << scrobble_point; - lastfm_service->Scrobble(); + app_->scrobbler()->Scrobble(); } #endif } @@ -1355,7 +1325,7 @@ void MainWindow::ScrobbledRadioStream() { } void MainWindow::Love() { - InternetModel::Service()->Love(); + app_->scrobbler()->Love(); ui_->action_love->setEnabled(false); tray_icon_->LastFMButtonLoveStateChanged(false); } @@ -1432,10 +1402,8 @@ void MainWindow::AddToPlaylist(QAction* action) { PlaylistItemList items; // get the selected playlist items - for (const QModelIndex& index : ui_->playlist->view() - ->selectionModel() - ->selection() - .indexes()) { + for (const QModelIndex& index : + ui_->playlist->view()->selectionModel()->selection().indexes()) { if (index.column() != 0) continue; int row = app_->playlist_manager()->current()->proxy()->mapToSource(index).row(); @@ -1693,10 +1661,8 @@ void MainWindow::EditTracks() { SongList songs; PlaylistItemList items; - for (const QModelIndex& index : ui_->playlist->view() - ->selectionModel() - ->selection() - .indexes()) { + for (const QModelIndex& index : + ui_->playlist->view()->selectionModel()->selection().indexes()) { if (index.column() != 0) continue; int row = app_->playlist_manager()->current()->proxy()->mapToSource(index).row(); @@ -2078,10 +2044,8 @@ void MainWindow::AddFilesToTranscoder() { QStringList filenames; - for (const QModelIndex& index : ui_->playlist->view() - ->selectionModel() - ->selection() - .indexes()) { + for (const QModelIndex& index : + ui_->playlist->view()->selectionModel()->selection().indexes()) { if (index.column() != 0) continue; int row = app_->playlist_manager()->current()->proxy()->mapToSource(index).row(); @@ -2249,9 +2213,8 @@ void MainWindow::DeleteFinished(const SongList& songs_with_errors) { void MainWindow::PlaylistQueue() { QModelIndexList indexes; - for (const QModelIndex& proxy_index : ui_->playlist->view() - ->selectionModel() - ->selectedRows()) { + for (const QModelIndex& proxy_index : + ui_->playlist->view()->selectionModel()->selectedRows()) { indexes << app_->playlist_manager()->current()->proxy()->mapToSource( proxy_index); } @@ -2261,9 +2224,8 @@ void MainWindow::PlaylistQueue() { void MainWindow::PlaylistSkip() { QModelIndexList indexes; - for (const QModelIndex& proxy_index : ui_->playlist->view() - ->selectionModel() - ->selectedRows()) { + for (const QModelIndex& proxy_index : + ui_->playlist->view()->selectionModel()->selectedRows()) { indexes << app_->playlist_manager()->current()->proxy()->mapToSource( proxy_index); } @@ -2545,10 +2507,8 @@ void MainWindow::AutoCompleteTags() { // Get the selected songs and start fetching tags for them SongList songs; autocomplete_tag_items_.clear(); - for (const QModelIndex& index : ui_->playlist->view() - ->selectionModel() - ->selection() - .indexes()) { + for (const QModelIndex& index : + ui_->playlist->view()->selectionModel()->selection().indexes()) { if (index.column() != 0) continue; int row = app_->playlist_manager()->current()->proxy()->mapToSource(index).row(); @@ -2613,10 +2573,9 @@ void MainWindow::SetToggleScrobblingIcon(bool value) { #ifdef HAVE_LIBLASTFM void MainWindow::ScrobbleSubmitted() { - const LastFMService* lastfm_service = InternetModel::Service(); const bool last_fm_enabled = ui_->action_toggle_scrobbling->isVisible() && - lastfm_service->IsScrobblingEnabled() && - lastfm_service->IsAuthenticated(); + app_->scrobbler()->IsScrobblingEnabled() && + app_->scrobbler()->IsAuthenticated(); app_->playlist_manager()->active()->set_lastfm_status( Playlist::LastFM_Scrobbled); diff --git a/src/ui/mainwindow.ui b/src/ui/mainwindow.ui index 34856cb02..e926e841f 100644 --- a/src/ui/mainwindow.ui +++ b/src/ui/mainwindow.ui @@ -200,19 +200,6 @@ - - - - - 22 - 22 - - - - true - - - @@ -435,7 +422,6 @@ - @@ -567,21 +553,6 @@ Ctrl+L - - - false - - - - :/last.fm/ban.png:/last.fm/ban.png - - - Ban - - - Ctrl+B - - Clear playlist diff --git a/src/ui/qtsystemtrayicon.cpp b/src/ui/qtsystemtrayicon.cpp index 0dceb18a1..39677bc21 100644 --- a/src/ui/qtsystemtrayicon.cpp +++ b/src/ui/qtsystemtrayicon.cpp @@ -36,8 +36,7 @@ QtSystemTrayIcon::QtSystemTrayIcon(QObject* parent) action_stop_(nullptr), action_stop_after_this_track_(nullptr), action_mute_(nullptr), - action_love_(nullptr), - action_ban_(nullptr) { + action_love_(nullptr) { QIcon theme_icon = IconLoader::Load("clementine-panel"); QIcon theme_icon_grey = IconLoader::Load("clementine-panel-grey"); @@ -97,7 +96,7 @@ bool QtSystemTrayIcon::eventFilter(QObject* object, QEvent* event) { void QtSystemTrayIcon::SetupMenu(QAction* previous, QAction* play, QAction* stop, QAction* stop_after, QAction* next, QAction* mute, QAction* love, - QAction* ban, QAction* quit) { + QAction* quit) { // Creating new actions and connecting them to old ones. This allows us to // use old actions without displaying shortcuts that can not be used when // Clementine's window is hidden @@ -123,10 +122,6 @@ void QtSystemTrayIcon::SetupMenu(QAction* previous, QAction* play, menu_->addAction(love->icon(), love->text(), love, SLOT(trigger())); action_love_->setVisible(love->isVisible()); action_love_->setEnabled(love->isEnabled()); - action_ban_ = - menu_->addAction(ban->icon(), ban->text(), ban, SLOT(trigger())); - action_ban_->setVisible(ban->isVisible()); - action_ban_->setEnabled(ban->isEnabled()); #endif menu_->addSeparator(); @@ -171,8 +166,7 @@ void QtSystemTrayIcon::SetPaused() { action_play_pause_->setEnabled(true); } -void QtSystemTrayIcon::SetPlaying(bool enable_play_pause, bool enable_ban, - bool enable_love) { +void QtSystemTrayIcon::SetPlaying(bool enable_play_pause, bool enable_love) { SystemTrayIcon::SetPlaying(); action_stop_->setEnabled(true); @@ -181,7 +175,6 @@ void QtSystemTrayIcon::SetPlaying(bool enable_play_pause, bool enable_ban, action_play_pause_->setText(tr("Pause")); action_play_pause_->setEnabled(enable_play_pause); #ifdef HAVE_LIBLASTFM - action_ban_->setEnabled(enable_ban); action_love_->setEnabled(enable_love); #endif } @@ -197,14 +190,12 @@ void QtSystemTrayIcon::SetStopped() { action_play_pause_->setEnabled(true); #ifdef HAVE_LIBLASTFM - action_ban_->setEnabled(false); action_love_->setEnabled(false); #endif } void QtSystemTrayIcon::LastFMButtonVisibilityChanged(bool value) { #ifdef HAVE_LIBLASTFM - action_ban_->setVisible(value); action_love_->setVisible(value); #endif } @@ -215,12 +206,6 @@ void QtSystemTrayIcon::LastFMButtonLoveStateChanged(bool value) { #endif } -void QtSystemTrayIcon::LastFMButtonBanStateChanged(bool value) { -#ifdef HAVE_LIBLASTFM - action_ban_->setEnabled(value); -#endif -} - void QtSystemTrayIcon::MuteButtonStateChanged(bool value) { if (action_mute_) action_mute_->setChecked(value); } diff --git a/src/ui/qtsystemtrayicon.h b/src/ui/qtsystemtrayicon.h index b3d8fbc5e..ff1d8a0e1 100644 --- a/src/ui/qtsystemtrayicon.h +++ b/src/ui/qtsystemtrayicon.h @@ -31,7 +31,7 @@ class QtSystemTrayIcon : public SystemTrayIcon { void SetupMenu(QAction* previous, QAction* play, QAction* stop, QAction* stop_after, QAction* next, QAction* mute, - QAction* love, QAction* ban, QAction* quit); + QAction* love, QAction* quit); bool IsVisible() const; void SetVisible(bool visible); @@ -44,12 +44,10 @@ class QtSystemTrayIcon : public SystemTrayIcon { // SystemTrayIcon void UpdateIcon(); void SetPaused(); - void SetPlaying(bool enable_play_pause = false, bool enable_ban = false, - bool enable_love = false); + void SetPlaying(bool enable_play_pause = false, bool enable_love = false); void SetStopped(); void LastFMButtonVisibilityChanged(bool value); void LastFMButtonLoveStateChanged(bool value); - void LastFMButtonBanStateChanged(bool value); void MuteButtonStateChanged(bool value); // QObject @@ -66,7 +64,6 @@ class QtSystemTrayIcon : public SystemTrayIcon { QAction* action_stop_after_this_track_; QAction* action_mute_; QAction* action_love_; - QAction* action_ban_; QString pattern_; diff --git a/src/ui/systemtrayicon.cpp b/src/ui/systemtrayicon.cpp index a293a5d66..d3fabf650 100644 --- a/src/ui/systemtrayicon.cpp +++ b/src/ui/systemtrayicon.cpp @@ -86,8 +86,7 @@ void SystemTrayIcon::SetPaused() { UpdateIcon(); } -void SystemTrayIcon::SetPlaying(bool enable_play_pause, bool enable_ban, - bool enable_love) { +void SystemTrayIcon::SetPlaying(bool enable_play_pause, bool enable_love) { current_state_icon_ = playing_icon_; UpdateIcon(); } diff --git a/src/ui/systemtrayicon.h b/src/ui/systemtrayicon.h index 614001434..d8bf0e1ba 100644 --- a/src/ui/systemtrayicon.h +++ b/src/ui/systemtrayicon.h @@ -33,7 +33,7 @@ class SystemTrayIcon : public QObject { // Called once to create the icon's context menu virtual void SetupMenu(QAction* previous, QAction* play, QAction* stop, QAction* stop_after, QAction* next, QAction* mute, - QAction* love, QAction* ban, QAction* quit) = 0; + QAction* love, QAction* quit) = 0; virtual bool IsVisible() const { return true; } virtual void SetVisible(bool visible) {} @@ -54,11 +54,10 @@ class SystemTrayIcon : public QObject { void SetProgress(int percentage); virtual void SetPaused(); virtual void SetPlaying(bool enable_play_pause = false, - bool enable_ban = false, bool enable_love = false); + bool enable_love = false); virtual void SetStopped(); virtual void LastFMButtonVisibilityChanged(bool value) {} virtual void LastFMButtonLoveStateChanged(bool value) {} - virtual void LastFMButtonBanStateChanged(bool value) {} virtual void MuteButtonStateChanged(bool value) {} signals: