1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
package net.sourceforge.subsonic.androidapp.activity; |
21 |
|
|
22 |
|
import java.util.ArrayList; |
23 |
|
import java.util.List; |
24 |
|
import java.util.Arrays; |
25 |
|
|
26 |
|
import android.content.Intent; |
27 |
|
import android.os.Bundle; |
28 |
|
import android.view.ContextMenu; |
29 |
|
import android.view.LayoutInflater; |
30 |
|
import android.view.MenuInflater; |
31 |
|
import android.view.View; |
32 |
|
import android.view.MenuItem; |
33 |
|
import android.widget.AdapterView; |
34 |
|
import android.widget.ImageButton; |
35 |
|
import android.widget.ListAdapter; |
36 |
|
import android.widget.ListView; |
37 |
|
import android.widget.TextView; |
38 |
|
import android.net.Uri; |
39 |
|
import net.sourceforge.subsonic.androidapp.R; |
40 |
|
import net.sourceforge.subsonic.androidapp.domain.Artist; |
41 |
|
import net.sourceforge.subsonic.androidapp.domain.MusicDirectory; |
42 |
|
import net.sourceforge.subsonic.androidapp.domain.SearchCritera; |
43 |
|
import net.sourceforge.subsonic.androidapp.domain.SearchResult; |
44 |
|
import net.sourceforge.subsonic.androidapp.service.MusicService; |
45 |
|
import net.sourceforge.subsonic.androidapp.service.MusicServiceFactory; |
46 |
|
import net.sourceforge.subsonic.androidapp.service.DownloadService; |
47 |
|
import net.sourceforge.subsonic.androidapp.util.ArtistAdapter; |
48 |
|
import net.sourceforge.subsonic.androidapp.util.BackgroundTask; |
49 |
|
import net.sourceforge.subsonic.androidapp.util.Constants; |
50 |
|
import net.sourceforge.subsonic.androidapp.util.EntryAdapter; |
51 |
|
import net.sourceforge.subsonic.androidapp.util.MergeAdapter; |
52 |
|
import net.sourceforge.subsonic.androidapp.util.TabActivityBackgroundTask; |
53 |
|
import net.sourceforge.subsonic.androidapp.util.Util; |
54 |
|
|
55 |
|
|
56 |
|
|
57 |
|
|
58 |
|
@author |
59 |
|
|
|
|
| 44,5% |
Uncovered Elements: 136 (245) |
Complexity: 54 |
Complexity Density: 0,32 |
|
60 |
|
public class SearchActivity extends SubsonicTabActivity { |
61 |
|
|
62 |
|
private static final int DEFAULT_ARTISTS = 3; |
63 |
|
private static final int DEFAULT_ALBUMS = 5; |
64 |
|
private static final int DEFAULT_SONGS = 10; |
65 |
|
|
66 |
|
private static final int MAX_ARTISTS = 10; |
67 |
|
private static final int MAX_ALBUMS = 20; |
68 |
|
private static final int MAX_SONGS = 25; |
69 |
|
private ListView list; |
70 |
|
|
71 |
|
private View artistsHeading; |
72 |
|
private View albumsHeading; |
73 |
|
private View songsHeading; |
74 |
|
private TextView searchButton; |
75 |
|
private View moreArtistsButton; |
76 |
|
private View moreAlbumsButton; |
77 |
|
private View moreSongsButton; |
78 |
|
private SearchResult searchResult; |
79 |
|
private MergeAdapter mergeAdapter; |
80 |
|
private ArtistAdapter artistAdapter; |
81 |
|
private ListAdapter moreArtistsAdapter; |
82 |
|
private EntryAdapter albumAdapter; |
83 |
|
private ListAdapter moreAlbumsAdapter; |
84 |
|
private ListAdapter moreSongsAdapter; |
85 |
|
private EntryAdapter songAdapter; |
86 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (19) |
Complexity: 1 |
Complexity Density: 0,05 |
|
87 |
3
|
@Override... |
88 |
|
public void onCreate(Bundle savedInstanceState) { |
89 |
3
|
super.onCreate(savedInstanceState); |
90 |
3
|
setContentView(R.layout.search); |
91 |
|
|
92 |
3
|
setTitle(R.string.search_title); |
93 |
|
|
94 |
3
|
View buttons = LayoutInflater.from(this).inflate(R.layout.search_buttons, null); |
95 |
|
|
96 |
3
|
artistsHeading = buttons.findViewById(R.id.search_artists); |
97 |
3
|
albumsHeading = buttons.findViewById(R.id.search_albums); |
98 |
3
|
songsHeading = buttons.findViewById(R.id.search_songs); |
99 |
|
|
100 |
3
|
searchButton = (TextView) buttons.findViewById(R.id.search_search); |
101 |
3
|
moreArtistsButton = buttons.findViewById(R.id.search_more_artists); |
102 |
3
|
moreAlbumsButton = buttons.findViewById(R.id.search_more_albums); |
103 |
3
|
moreSongsButton = buttons.findViewById(R.id.search_more_songs); |
104 |
|
|
105 |
3
|
list = (ListView) findViewById(R.id.search_list); |
106 |
|
|
107 |
3
|
list.setOnItemClickListener(new AdapterView.OnItemClickListener() { |
|
|
| 50% |
Uncovered Elements: 17 (34) |
Complexity: 9 |
Complexity Density: 0,5 |
|
108 |
1
|
@Override... |
109 |
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
110 |
1
|
if (view == searchButton) { |
111 |
0
|
onSearchRequested(); |
112 |
1
|
} else if (view == moreArtistsButton) { |
113 |
0
|
expandArtists(); |
114 |
1
|
} else if (view == moreAlbumsButton) { |
115 |
0
|
expandAlbums(); |
116 |
1
|
} else if (view == moreSongsButton) { |
117 |
0
|
expandSongs(); |
118 |
|
} else { |
119 |
1
|
Object item = parent.getItemAtPosition(position); |
120 |
1
|
if (item instanceof Artist) { |
121 |
0
|
onArtistSelected((Artist) item); |
122 |
1
|
} else if (item instanceof MusicDirectory.Entry) { |
123 |
1
|
MusicDirectory.Entry entry = (MusicDirectory.Entry) item; |
124 |
1
|
if (entry.isDirectory()) { |
125 |
1
|
onAlbumSelected(entry, false); |
126 |
0
|
} else if (entry.isVideo()) { |
127 |
0
|
onVideoSelected(entry); |
128 |
|
} else { |
129 |
0
|
onSongSelected(entry, false, true, true, false); |
130 |
|
} |
131 |
|
|
132 |
|
} |
133 |
|
} |
134 |
|
} |
135 |
|
}); |
136 |
3
|
registerForContextMenu(list); |
137 |
|
|
138 |
|
|
139 |
3
|
findViewById(R.id.action_button_1).setVisibility(View.GONE); |
140 |
|
|
141 |
|
|
142 |
3
|
final ImageButton actionSearchButton = (ImageButton)findViewById(R.id.action_button_2); |
143 |
3
|
actionSearchButton.setImageResource(R.drawable.ic_menu_search); |
144 |
3
|
actionSearchButton.setOnClickListener(new View.OnClickListener() { |
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
145 |
1
|
@Override... |
146 |
|
public void onClick(View view) { |
147 |
1
|
onSearchRequested(); |
148 |
|
} |
149 |
|
}); |
150 |
|
|
151 |
3
|
onNewIntent(getIntent()); |
152 |
|
} |
153 |
|
|
|
|
| 93,3% |
Uncovered Elements: 1 (15) |
Complexity: 3 |
Complexity Density: 0,27 |
|
154 |
5
|
@Override... |
155 |
|
protected void onNewIntent(Intent intent) { |
156 |
5
|
super.onNewIntent(intent); |
157 |
5
|
String query = intent.getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY); |
158 |
5
|
boolean autoplay = intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false); |
159 |
5
|
boolean requestsearch = intent.getBooleanExtra(Constants.INTENT_EXTRA_REQUEST_SEARCH, false); |
160 |
|
|
161 |
5
|
if (query != null) { |
162 |
1
|
mergeAdapter = new MergeAdapter(); |
163 |
1
|
list.setAdapter(mergeAdapter); |
164 |
1
|
search(query, autoplay); |
165 |
|
} else { |
166 |
4
|
populateList(); |
167 |
4
|
if (requestsearch) |
168 |
4
|
onSearchRequested(); |
169 |
|
} |
170 |
|
} |
171 |
|
|
|
|
| 62,5% |
Uncovered Elements: 6 (16) |
Complexity: 4 |
Complexity Density: 0,33 |
|
172 |
1
|
@Override... |
173 |
|
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { |
174 |
1
|
super.onCreateContextMenu(menu, view, menuInfo); |
175 |
|
|
176 |
1
|
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; |
177 |
1
|
Object selectedItem = list.getItemAtPosition(info.position); |
178 |
|
|
179 |
1
|
boolean isArtist = selectedItem instanceof Artist; |
180 |
1
|
boolean isAlbum = selectedItem instanceof MusicDirectory.Entry && ((MusicDirectory.Entry) selectedItem).isDirectory(); |
181 |
1
|
boolean isSong = selectedItem instanceof MusicDirectory.Entry && (!((MusicDirectory.Entry) selectedItem).isDirectory()) |
182 |
|
&& (!((MusicDirectory.Entry) selectedItem).isVideo()); |
183 |
|
|
184 |
1
|
if (isArtist || isAlbum) { |
185 |
1
|
MenuInflater inflater = getMenuInflater(); |
186 |
1
|
inflater.inflate(R.menu.select_album_context, menu); |
187 |
0
|
} else if (isSong) { |
188 |
0
|
MenuInflater inflater = getMenuInflater(); |
189 |
0
|
inflater.inflate(R.menu.select_song_context, menu); |
190 |
|
} |
191 |
|
} |
192 |
|
|
|
|
| 0% |
Uncovered Elements: 33 (33) |
Complexity: 10 |
Complexity Density: 0,37 |
|
193 |
0
|
@Override... |
194 |
|
public boolean onContextItemSelected(MenuItem menuItem) { |
195 |
0
|
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo(); |
196 |
0
|
Object selectedItem = list.getItemAtPosition(info.position); |
197 |
|
|
198 |
0
|
Artist artist = selectedItem instanceof Artist ? (Artist) selectedItem : null; |
199 |
0
|
MusicDirectory.Entry entry = selectedItem instanceof MusicDirectory.Entry ? (MusicDirectory.Entry) selectedItem : null; |
200 |
0
|
String id = artist != null ? artist.getId() : entry.getId(); |
201 |
|
|
202 |
0
|
switch (menuItem.getItemId()) { |
203 |
0
|
case R.id.album_menu_play_now: |
204 |
0
|
downloadRecursively(id, false, false, true); |
205 |
0
|
break; |
206 |
0
|
case R.id.album_menu_play_last: |
207 |
0
|
downloadRecursively(id, false, true, false); |
208 |
0
|
break; |
209 |
0
|
case R.id.album_menu_pin: |
210 |
0
|
downloadRecursively(id, true, true, false); |
211 |
0
|
break; |
212 |
0
|
case R.id.song_menu_play_now: |
213 |
0
|
onSongSelected(entry, false, false, true, false); |
214 |
0
|
break; |
215 |
0
|
case R.id.song_menu_play_next: |
216 |
0
|
onSongSelected(entry, false, true, false, true); |
217 |
0
|
break; |
218 |
0
|
case R.id.song_menu_play_last: |
219 |
0
|
onSongSelected(entry, false, true, false, false); |
220 |
0
|
break; |
221 |
0
|
default: |
222 |
0
|
return super.onContextItemSelected(menuItem); |
223 |
|
} |
224 |
|
|
225 |
0
|
return true; |
226 |
|
} |
227 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (2) |
Complexity: 1 |
Complexity Density: 0,5 |
|
228 |
1
|
private void search(final String query, final boolean autoplay) {... |
229 |
1
|
BackgroundTask<SearchResult> task = new TabActivityBackgroundTask<SearchResult>(this) { |
|
|
| 100% |
Uncovered Elements: 0 (3) |
Complexity: 1 |
Complexity Density: 0,33 |
|
230 |
1
|
@Override... |
231 |
|
protected SearchResult doInBackground() throws Throwable { |
232 |
1
|
SearchCritera criteria = new SearchCritera(query, MAX_ARTISTS, MAX_ALBUMS, MAX_SONGS); |
233 |
1
|
MusicService service = MusicServiceFactory.getMusicService(SearchActivity.this); |
234 |
1
|
return service.search(criteria, SearchActivity.this, this); |
235 |
|
} |
236 |
|
|
|
|
| 66,7% |
Uncovered Elements: 2 (6) |
Complexity: 2 |
Complexity Density: 0,5 |
|
237 |
1
|
@Override... |
238 |
|
protected void done(SearchResult result) { |
239 |
1
|
searchResult = result; |
240 |
1
|
populateList(); |
241 |
1
|
if (autoplay) { |
242 |
0
|
autoplay(); |
243 |
|
} |
244 |
|
|
245 |
|
} |
246 |
|
}; |
247 |
1
|
task.execute(); |
248 |
|
} |
249 |
|
|
|
|
| 52,2% |
Uncovered Elements: 22 (46) |
Complexity: 9 |
Complexity Density: 0,3 |
|
250 |
5
|
private void populateList() {... |
251 |
5
|
mergeAdapter = new MergeAdapter(); |
252 |
5
|
mergeAdapter.addView(searchButton, true); |
253 |
|
|
254 |
5
|
if (searchResult != null) { |
255 |
2
|
List<Artist> artists = searchResult.getArtists(); |
256 |
2
|
if (!artists.isEmpty()) { |
257 |
0
|
mergeAdapter.addView(artistsHeading); |
258 |
0
|
List<Artist> displayedArtists = new ArrayList<Artist>(artists.subList(0, Math.min(DEFAULT_ARTISTS, artists.size()))); |
259 |
0
|
artistAdapter = new ArtistAdapter(this, displayedArtists); |
260 |
0
|
mergeAdapter.addAdapter(artistAdapter); |
261 |
0
|
if (artists.size() > DEFAULT_ARTISTS) { |
262 |
0
|
moreArtistsAdapter = mergeAdapter.addView(moreArtistsButton, true); |
263 |
|
} |
264 |
|
} |
265 |
|
|
266 |
2
|
List<MusicDirectory.Entry> albums = searchResult.getAlbums(); |
267 |
2
|
if (!albums.isEmpty()) { |
268 |
2
|
mergeAdapter.addView(albumsHeading); |
269 |
2
|
List<MusicDirectory.Entry> displayedAlbums = new ArrayList<MusicDirectory.Entry>(albums.subList(0, Math.min(DEFAULT_ALBUMS, albums.size()))); |
270 |
2
|
albumAdapter = new EntryAdapter(this, getImageLoader(), displayedAlbums, false); |
271 |
2
|
mergeAdapter.addAdapter(albumAdapter); |
272 |
2
|
if (albums.size() > DEFAULT_ALBUMS) { |
273 |
0
|
moreAlbumsAdapter = mergeAdapter.addView(moreAlbumsButton, true); |
274 |
|
} |
275 |
|
} |
276 |
|
|
277 |
2
|
List<MusicDirectory.Entry> songs = searchResult.getSongs(); |
278 |
2
|
if (!songs.isEmpty()) { |
279 |
0
|
mergeAdapter.addView(songsHeading); |
280 |
0
|
List<MusicDirectory.Entry> displayedSongs = new ArrayList<MusicDirectory.Entry>(songs.subList(0, Math.min(DEFAULT_SONGS, songs.size()))); |
281 |
0
|
songAdapter = new EntryAdapter(this, getImageLoader(), displayedSongs, false); |
282 |
0
|
mergeAdapter.addAdapter(songAdapter); |
283 |
0
|
if (songs.size() > DEFAULT_SONGS) { |
284 |
0
|
moreSongsAdapter = mergeAdapter.addView(moreSongsButton, true); |
285 |
|
} |
286 |
|
} |
287 |
|
|
288 |
2
|
boolean empty = searchResult.getArtists().isEmpty() && searchResult.getAlbums().isEmpty() && searchResult.getSongs().isEmpty(); |
289 |
2
|
searchButton.setText(empty ? R.string.search_no_match : R.string.search_search); |
290 |
|
} |
291 |
|
|
292 |
5
|
list.setAdapter(mergeAdapter); |
293 |
|
} |
294 |
|
|
|
|
| 0% |
Uncovered Elements: 6 (6) |
Complexity: 1 |
Complexity Density: 0,17 |
|
295 |
0
|
private void expandArtists() {... |
296 |
0
|
artistAdapter.clear(); |
297 |
0
|
for (Artist artist : searchResult.getArtists()) { |
298 |
0
|
artistAdapter.add(artist); |
299 |
|
} |
300 |
0
|
artistAdapter.notifyDataSetChanged(); |
301 |
0
|
mergeAdapter.removeAdapter(moreArtistsAdapter); |
302 |
0
|
mergeAdapter.notifyDataSetChanged(); |
303 |
|
} |
304 |
|
|
|
|
| 0% |
Uncovered Elements: 6 (6) |
Complexity: 1 |
Complexity Density: 0,17 |
|
305 |
0
|
private void expandAlbums() {... |
306 |
0
|
albumAdapter.clear(); |
307 |
0
|
for (MusicDirectory.Entry album : searchResult.getAlbums()) { |
308 |
0
|
albumAdapter.add(album); |
309 |
|
} |
310 |
0
|
albumAdapter.notifyDataSetChanged(); |
311 |
0
|
mergeAdapter.removeAdapter(moreAlbumsAdapter); |
312 |
0
|
mergeAdapter.notifyDataSetChanged(); |
313 |
|
} |
314 |
|
|
|
|
| 0% |
Uncovered Elements: 6 (6) |
Complexity: 1 |
Complexity Density: 0,17 |
|
315 |
0
|
private void expandSongs() {... |
316 |
0
|
songAdapter.clear(); |
317 |
0
|
for (MusicDirectory.Entry song : searchResult.getSongs()) { |
318 |
0
|
songAdapter.add(song); |
319 |
|
} |
320 |
0
|
songAdapter.notifyDataSetChanged(); |
321 |
0
|
mergeAdapter.removeAdapter(moreSongsAdapter); |
322 |
0
|
mergeAdapter.notifyDataSetChanged(); |
323 |
|
} |
324 |
|
|
|
|
| 0% |
Uncovered Elements: 4 (4) |
Complexity: 1 |
Complexity Density: 0,25 |
|
325 |
0
|
private void onArtistSelected(Artist artist) {... |
326 |
0
|
Intent intent = new Intent(this, SelectAlbumActivity.class); |
327 |
0
|
intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, artist.getId()); |
328 |
0
|
intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, artist.getName()); |
329 |
0
|
Util.startActivityWithoutTransition(this, intent); |
330 |
|
} |
331 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (5) |
Complexity: 1 |
Complexity Density: 0,2 |
|
332 |
1
|
private void onAlbumSelected(MusicDirectory.Entry album, boolean autoplay) {... |
333 |
1
|
Intent intent = new Intent(SearchActivity.this, SelectAlbumActivity.class); |
334 |
1
|
intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, album.getId()); |
335 |
1
|
intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, album.getTitle()); |
336 |
1
|
intent.putExtra(Constants.INTENT_EXTRA_NAME_AUTOPLAY, autoplay); |
337 |
1
|
Util.startActivityWithoutTransition(SearchActivity.this, intent); |
338 |
|
} |
339 |
|
|
|
|
| 0% |
Uncovered Elements: 14 (14) |
Complexity: 4 |
Complexity Density: 0,5 |
|
340 |
0
|
private void onSongSelected(MusicDirectory.Entry song, boolean save, boolean append, boolean autoplay, boolean playNext) {... |
341 |
0
|
DownloadService downloadService = getDownloadService(); |
342 |
0
|
if (downloadService != null) { |
343 |
0
|
if (!append) { |
344 |
0
|
downloadService.clear(); |
345 |
|
} |
346 |
0
|
downloadService.download(Arrays.asList(song), save, false, playNext); |
347 |
0
|
if (autoplay) { |
348 |
0
|
downloadService.play(downloadService.size() - 1); |
349 |
|
} |
350 |
|
|
351 |
0
|
Util.toast(SearchActivity.this, getResources().getQuantityString(R.plurals.select_album_n_songs_added, 1, 1)); |
352 |
|
} |
353 |
|
} |
354 |
|
|
|
|
| 0% |
Uncovered Elements: 3 (3) |
Complexity: 1 |
Complexity Density: 0,33 |
|
355 |
0
|
private void onVideoSelected(MusicDirectory.Entry entry) {... |
356 |
0
|
Intent intent = new Intent(Intent.ACTION_VIEW); |
357 |
0
|
intent.setData(Uri.parse(MusicServiceFactory.getMusicService(this).getVideoUrl(this, entry.getId()))); |
358 |
0
|
startActivity(intent); |
359 |
|
} |
360 |
|
|
|
|
| 0% |
Uncovered Elements: 8 (8) |
Complexity: 3 |
Complexity Density: 0,75 |
|
361 |
0
|
private void autoplay() {... |
362 |
0
|
if (!searchResult.getSongs().isEmpty()) { |
363 |
0
|
onSongSelected(searchResult.getSongs().get(0), false, false, true, false); |
364 |
0
|
} else if (!searchResult.getAlbums().isEmpty()) { |
365 |
0
|
onAlbumSelected(searchResult.getAlbums().get(0), true); |
366 |
|
} |
367 |
|
} |
368 |
|
} |