Changeset View
Changeset View
Standalone View
Standalone View
src/context/applets/lyrics/plugin/LyricsEngine.cpp
Show All 14 Lines | |||||
15 | * this program. If not, see <http://www.gnu.org/licenses/>. * | 15 | * this program. If not, see <http://www.gnu.org/licenses/>. * | ||
16 | ****************************************************************************************/ | 16 | ****************************************************************************************/ | ||
17 | 17 | | |||
18 | #define DEBUG_PREFIX "LyricsEngine" | 18 | #define DEBUG_PREFIX "LyricsEngine" | ||
19 | 19 | | |||
20 | #include "LyricsEngine.h" | 20 | #include "LyricsEngine.h" | ||
21 | 21 | | |||
22 | #include "EngineController.h" | 22 | #include "EngineController.h" | ||
23 | #include "scripting/scriptmanager/ScriptManager.h" | | |||
24 | #include "core/support/Amarok.h" | 23 | #include "core/support/Amarok.h" | ||
25 | #include "core/support/Debug.h" | 24 | #include "core/support/Debug.h" | ||
25 | #include "lyrics/LyricsManager.h" | ||||
26 | 26 | | |||
27 | #include <QFont> | 27 | #include <QFont> | ||
28 | 28 | | |||
29 | #include <KFontChooser> | 29 | #include <KFontChooser> | ||
30 | 30 | | |||
31 | 31 | | |||
32 | LyricsEngine::LyricsEngine( QObject* parent ) | 32 | LyricsEngine::LyricsEngine( QObject* parent ) | ||
33 | : QObject( parent ) | 33 | : QObject( parent ) | ||
34 | , LyricsObserver( LyricsManager::self() ) | | |||
35 | , m_fetching( false ) | 34 | , m_fetching( false ) | ||
36 | , m_isUpdateInProgress( false ) | 35 | , m_isUpdateInProgress( false ) | ||
37 | { | 36 | { | ||
38 | 37 | | |||
39 | EngineController* engine = The::engineController(); | 38 | EngineController* engine = The::engineController(); | ||
39 | LyricsManager* lyricsManager = LyricsManager::instance(); | ||||
40 | 40 | | |||
41 | connect( engine, &EngineController::trackChanged, | 41 | connect( engine, &EngineController::trackChanged, | ||
42 | this, &LyricsEngine::update ); | 42 | this, &LyricsEngine::update ); | ||
43 | connect( engine, &EngineController::trackMetadataChanged, | 43 | connect( engine, &EngineController::trackMetadataChanged, | ||
44 | this, &LyricsEngine::onTrackMetadataChanged ); | 44 | this, &LyricsEngine::onTrackMetadataChanged ); | ||
45 | connect( engine, &EngineController::trackPositionChanged, | 45 | connect( engine, &EngineController::trackPositionChanged, | ||
46 | this, &LyricsEngine::positionChanged ); | 46 | this, &LyricsEngine::positionChanged ); | ||
47 | connect( lyricsManager, &LyricsManager::newLyrics, this, &LyricsEngine::newLyrics ); | ||||
48 | connect( lyricsManager, &LyricsManager::newSuggestions, this, &LyricsEngine::newSuggestions ); | ||||
47 | } | 49 | } | ||
48 | 50 | | |||
49 | void LyricsEngine::onTrackMetadataChanged( Meta::TrackPtr track ) | 51 | void LyricsEngine::onTrackMetadataChanged( Meta::TrackPtr track ) | ||
50 | { | 52 | { | ||
51 | DEBUG_BLOCK | 53 | DEBUG_BLOCK | ||
52 | 54 | | |||
53 | // Only update if the lyrics have changed. | 55 | // Only update if the lyrics have changed. | ||
54 | QString artist = track->artist() ? track->artist()->name() : QString(); | 56 | if( m_lyrics != track->cachedLyrics() ) | ||
55 | if( m_lyrics.artist != artist || | | |||
56 | m_lyrics.title != track->name() || | | |||
57 | m_lyrics.text != track->cachedLyrics() ) | | |||
58 | update(); | 57 | update(); | ||
59 | } | 58 | } | ||
60 | 59 | | |||
61 | void LyricsEngine::update() | 60 | void LyricsEngine::update() | ||
62 | { | 61 | { | ||
63 | if( m_isUpdateInProgress ) | 62 | Meta::TrackPtr track = The::engineController()->currentTrack(); | ||
64 | return; | 63 | if( !track ) | ||
65 | | ||||
66 | m_isUpdateInProgress = true; | | |||
67 | | ||||
68 | // -- get current title and artist | | |||
69 | Meta::TrackPtr currentTrack = The::engineController()->currentTrack(); | | |||
70 | if( !currentTrack ) | | |||
71 | { | | |||
72 | debug() << "no current track"; | | |||
73 | m_lyrics.clear(); | | |||
74 | emit lyricsChanged(); | | |||
75 | m_isUpdateInProgress = false; | | |||
76 | return; | | |||
77 | } | | |||
78 | | ||||
79 | QString title = currentTrack->name(); | | |||
80 | QString artist = currentTrack->artist() ? currentTrack->artist()->name() : QString(); | | |||
81 | | ||||
82 | // -- clean up title | | |||
83 | const QString magnatunePreviewString = QLatin1String( "PREVIEW: buy it at www.magnatune.com" ); | | |||
84 | if( title.contains(magnatunePreviewString, Qt::CaseSensitive) ) | | |||
85 | title = title.remove( " (" + magnatunePreviewString + ')' ); | | |||
86 | if( artist.contains(magnatunePreviewString, Qt::CaseSensitive) ) | | |||
87 | artist = artist.remove( " (" + magnatunePreviewString + ')' ); | | |||
88 | | ||||
89 | if( title.isEmpty() && currentTrack ) | | |||
90 | { | 64 | { | ||
91 | /* If title is empty, try to use pretty title. | 65 | clearLyrics(); | ||
92 | The fact that it often (but not always) has "artist name" together, can be bad, | | |||
93 | but at least the user will hopefully get nice suggestions. */ | | |||
94 | QString prettyTitle = currentTrack->prettyName(); | | |||
95 | int h = prettyTitle.indexOf( QLatin1Char('-') ); | | |||
96 | if ( h != -1 ) | | |||
97 | { | | |||
98 | title = prettyTitle.mid( h + 1 ).trimmed(); | | |||
99 | if( title.contains(magnatunePreviewString, Qt::CaseSensitive) ) | | |||
100 | title = title.remove( " (" + magnatunePreviewString + ')' ); | | |||
101 | | ||||
102 | if( artist.isEmpty() ) | | |||
103 | { | | |||
104 | artist = prettyTitle.mid( 0, h ).trimmed(); | | |||
105 | if( artist.contains(magnatunePreviewString, Qt::CaseSensitive) ) | | |||
106 | artist = artist.remove( " (" + magnatunePreviewString + ')' ); | | |||
107 | } | | |||
108 | } | | |||
109 | } | | |||
110 | | ||||
111 | LyricsData lyrics = { currentTrack->cachedLyrics(), title, artist, QUrl() }; | | |||
112 | | ||||
113 | // Check if the title, the artist and the lyrics are still the same. | | |||
114 | if( !lyrics.text.isEmpty() && (lyrics.text == m_lyrics.text) ) | | |||
115 | { | | |||
116 | debug() << "nothing changed:" << lyrics.title; | | |||
117 | newLyrics( lyrics ); | | |||
118 | m_isUpdateInProgress = false; | | |||
119 | return; | 66 | return; | ||
120 | } | 67 | } | ||
121 | 68 | | |||
122 | // don't rely on caching for streams | 69 | if( LyricsManager::instance()->isEmpty( track->cachedLyrics() ) ) | ||
123 | const bool cached = !LyricsManager::self()->isEmpty( lyrics.text ) | | |||
124 | && !The::engineController()->isStream(); | | |||
125 | | ||||
126 | if( cached ) | | |||
127 | { | | |||
128 | newLyrics( lyrics ); | | |||
129 | } | | |||
130 | else | | |||
131 | { | | |||
132 | // no lyrics, and no lyrics script! | | |||
133 | if( !ScriptManager::instance()->lyricsScriptRunning() ) | | |||
134 | { | 70 | { | ||
135 | debug() << "no lyrics script running"; | | |||
136 | clearLyrics(); | 71 | clearLyrics(); | ||
137 | disconnect( ScriptManager::instance(), &ScriptManager::lyricsScriptStarted, this, 0 ); | | |||
138 | connect( ScriptManager::instance(), &ScriptManager::lyricsScriptStarted, this, &LyricsEngine::update ); | | |||
139 | m_isUpdateInProgress = false; | | |||
140 | return; | 72 | return; | ||
141 | } | 73 | } | ||
142 | 74 | | |||
143 | // fetch by lyrics script | 75 | newLyrics( track ); | ||
144 | clearLyrics(); | | |||
145 | m_fetching = true; | | |||
146 | emit fetchingChanged(); | | |||
147 | ScriptManager::instance()->notifyFetchLyrics( lyrics.artist, lyrics.title, "", currentTrack ); | | |||
148 | } | | |||
149 | m_isUpdateInProgress = false; | | |||
150 | } | 76 | } | ||
151 | 77 | | |||
152 | void LyricsEngine::newLyrics( const LyricsData &lyrics ) | 78 | void LyricsEngine::newLyrics( const Meta::TrackPtr &track ) | ||
153 | { | 79 | { | ||
154 | DEBUG_BLOCK | 80 | DEBUG_BLOCK | ||
155 | 81 | | |||
156 | m_lyrics = lyrics; | 82 | if( track != The::engineController()->currentTrack() ) | ||
83 | return; | ||||
84 | | ||||
85 | m_lyrics = track->cachedLyrics(); | ||||
157 | emit lyricsChanged(); | 86 | emit lyricsChanged(); | ||
158 | 87 | | |||
159 | m_fetching = false; | 88 | m_fetching = false; | ||
160 | emit fetchingChanged(); | 89 | emit fetchingChanged(); | ||
161 | } | 90 | } | ||
162 | 91 | | |||
163 | void LyricsEngine::newSuggestions( const QVariantList &suggested ) | 92 | void LyricsEngine::newSuggestions( const QVariantList &suggested ) | ||
164 | { | 93 | { | ||
Show All 27 Lines | |||||
192 | } | 121 | } | ||
193 | 122 | | |||
194 | void LyricsEngine::refetchLyrics() const | 123 | void LyricsEngine::refetchLyrics() const | ||
195 | { | 124 | { | ||
196 | Meta::TrackPtr currentTrack = The::engineController()->currentTrack(); | 125 | Meta::TrackPtr currentTrack = The::engineController()->currentTrack(); | ||
197 | if( !currentTrack ) | 126 | if( !currentTrack ) | ||
198 | return; | 127 | return; | ||
199 | 128 | | |||
200 | ScriptManager::instance()->notifyFetchLyrics( m_lyrics.artist, m_lyrics.title, "", currentTrack ); | 129 | LyricsManager::instance()->loadLyrics( currentTrack, true ); | ||
201 | } | | |||
202 | | ||||
203 | void LyricsEngine::refetchLyrics() | | |||
204 | { | | |||
205 | DEBUG_BLOCK | | |||
206 | | ||||
207 | auto currentTrack = The::engineController()->currentTrack(); | | |||
208 | | ||||
209 | if( currentTrack ) | | |||
210 | ScriptManager::instance()->notifyFetchLyrics( currentTrack->artist()->name(), | | |||
211 | currentTrack->name(), "", currentTrack ); | | |||
212 | | ||||
213 | m_fetching = true; | | |||
214 | emit fetchingChanged(); | | |||
215 | } | | |||
216 | | ||||
217 | void LyricsEngine::fetchLyrics(const QString& artist, const QString& title, const QString& url) | | |||
218 | { | | |||
219 | DEBUG_BLOCK | | |||
220 | | ||||
221 | if( !QUrl( url ).isValid() ) | | |||
222 | return; | | |||
223 | | ||||
224 | debug() << "clicked suggestion" << url; | | |||
225 | | ||||
226 | ScriptManager::instance()->notifyFetchLyrics( artist, title, url, Meta::TrackPtr() ); | | |||
227 | | ||||
228 | m_fetching = true; | | |||
229 | emit fetchingChanged(); | | |||
230 | } | 130 | } | ||
231 | 131 | | |||
232 | qreal LyricsEngine::fontSize() const | 132 | qreal LyricsEngine::fontSize() const | ||
233 | { | 133 | { | ||
234 | return Amarok::config( "Context" ).group( "Lyrics" ).readEntry( "fontSize", 18 ); | 134 | return Amarok::config( "Context" ).group( "Lyrics" ).readEntry( "fontSize", 18 ); | ||
235 | } | 135 | } | ||
236 | 136 | | |||
237 | void LyricsEngine::setFontSize(qreal fontSize) | 137 | void LyricsEngine::setFontSize(qreal fontSize) | ||
▲ Show 20 Lines • Show All 51 Lines • Show Last 20 Lines |