416 lines
15 KiB
Java
416 lines
15 KiB
Java
|
/*
|
||
|
This file is part of Subsonic.
|
||
|
|
||
|
Subsonic 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.
|
||
|
|
||
|
Subsonic 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 Subsonic. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
Copyright 2009 (C) Sindre Mehus
|
||
|
*/
|
||
|
package com.thejoshwa.ultrasonic.androidapp.activity;
|
||
|
|
||
|
import android.content.Intent;
|
||
|
import android.net.Uri;
|
||
|
import android.os.AsyncTask;
|
||
|
import android.os.Bundle;
|
||
|
import android.view.MenuItem;
|
||
|
import android.view.View;
|
||
|
import android.widget.AdapterView;
|
||
|
import android.widget.ImageView;
|
||
|
import android.widget.ListView;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.R;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.domain.MusicDirectory.Entry;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.service.DownloadFile;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.service.MusicService;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.service.MusicServiceFactory;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.util.Constants;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.util.FileUtil;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.util.Pair;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.util.TabActivityBackgroundTask;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.util.Util;
|
||
|
import com.thejoshwa.ultrasonic.androidapp.view.EntryAdapter;
|
||
|
|
||
|
import java.io.File;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.List;
|
||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase;
|
||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
|
||
|
import com.handmark.pulltorefresh.library.PullToRefreshListView;
|
||
|
|
||
|
public class BookmarkActivity extends SubsonicTabActivity {
|
||
|
|
||
|
private PullToRefreshListView refreshAlbumListView;
|
||
|
private ListView albumListView;
|
||
|
private View albumButtons;
|
||
|
private View emptyView;
|
||
|
private ImageView selectButton;
|
||
|
private ImageView playNowButton;
|
||
|
private ImageView playNextButton;
|
||
|
private ImageView playLastButton;
|
||
|
private ImageView pinButton;
|
||
|
private ImageView unpinButton;
|
||
|
private ImageView downloadButton;
|
||
|
private ImageView deleteButton;
|
||
|
private ImageView moreButton;
|
||
|
|
||
|
/**
|
||
|
* Called when the activity is first created.
|
||
|
*/
|
||
|
@Override
|
||
|
public void onCreate(Bundle savedInstanceState) {
|
||
|
super.onCreate(savedInstanceState);
|
||
|
setContentView(R.layout.select_album);
|
||
|
|
||
|
albumButtons = findViewById(R.id.menu_album);
|
||
|
|
||
|
refreshAlbumListView = (PullToRefreshListView) findViewById(R.id.select_album_entries);
|
||
|
albumListView = refreshAlbumListView.getRefreshableView();
|
||
|
|
||
|
refreshAlbumListView.setOnRefreshListener(new OnRefreshListener<ListView>() {
|
||
|
@Override
|
||
|
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
|
||
|
new GetDataTask().execute();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
albumListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
|
||
|
|
||
|
albumListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||
|
@Override
|
||
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||
|
if (position >= 0) {
|
||
|
Entry entry = (Entry) parent.getItemAtPosition(position);
|
||
|
|
||
|
if (entry.isVideo()) {
|
||
|
playVideo(entry);
|
||
|
} else {
|
||
|
enableButtons();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
selectButton = (ImageView) findViewById(R.id.select_album_select);
|
||
|
playNowButton = (ImageView) findViewById(R.id.select_album_play_now);
|
||
|
playNextButton = (ImageView) findViewById(R.id.select_album_play_next);
|
||
|
playLastButton = (ImageView) findViewById(R.id.select_album_play_last);
|
||
|
pinButton = (ImageView) findViewById(R.id.select_album_pin);
|
||
|
unpinButton = (ImageView) findViewById(R.id.select_album_unpin);
|
||
|
downloadButton = (ImageView) findViewById(R.id.select_album_download);
|
||
|
deleteButton = (ImageView) findViewById(R.id.select_album_delete);
|
||
|
moreButton = (ImageView) findViewById(R.id.select_album_more);
|
||
|
emptyView = findViewById(R.id.select_album_empty);
|
||
|
|
||
|
selectButton.setVisibility(View.GONE);
|
||
|
playNextButton.setVisibility(View.GONE);
|
||
|
playLastButton.setVisibility(View.GONE);
|
||
|
moreButton.setVisibility(View.GONE);
|
||
|
|
||
|
playNowButton.setOnClickListener(new View.OnClickListener() {
|
||
|
@Override
|
||
|
public void onClick(View view) {
|
||
|
playNow(getSelectedSongs(albumListView));
|
||
|
}
|
||
|
});
|
||
|
|
||
|
selectButton.setOnClickListener(new View.OnClickListener() {
|
||
|
@Override
|
||
|
public void onClick(View view) {
|
||
|
selectAllOrNone();
|
||
|
}
|
||
|
});
|
||
|
pinButton.setOnClickListener(new View.OnClickListener() {
|
||
|
@Override
|
||
|
public void onClick(View view) {
|
||
|
downloadBackground(true);
|
||
|
selectAll(false, false);
|
||
|
}
|
||
|
});
|
||
|
unpinButton.setOnClickListener(new View.OnClickListener() {
|
||
|
@Override
|
||
|
public void onClick(View view) {
|
||
|
unpin();
|
||
|
selectAll(false, false);
|
||
|
}
|
||
|
});
|
||
|
downloadButton.setOnClickListener(new View.OnClickListener() {
|
||
|
@Override
|
||
|
public void onClick(View view) {
|
||
|
downloadBackground(false);
|
||
|
selectAll(false, false);
|
||
|
}
|
||
|
});
|
||
|
deleteButton.setOnClickListener(new View.OnClickListener() {
|
||
|
@Override
|
||
|
public void onClick(View view) {
|
||
|
delete();
|
||
|
selectAll(false, false);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
registerForContextMenu(albumListView);
|
||
|
|
||
|
enableButtons();
|
||
|
|
||
|
View browseMenuItem = findViewById(R.id.menu_bookmarks);
|
||
|
menuDrawer.setActiveView(browseMenuItem);
|
||
|
|
||
|
getBookmarks();
|
||
|
|
||
|
}
|
||
|
|
||
|
private void getBookmarks() {
|
||
|
getActionBar().setSubtitle(R.string.button_bar_bookmarks);
|
||
|
|
||
|
new LoadTask() {
|
||
|
@Override
|
||
|
protected MusicDirectory load(MusicService service) throws Exception {
|
||
|
return Util.getSongsFromBookmarks(service.getBookmarks(BookmarkActivity.this, this));
|
||
|
}
|
||
|
}.execute();
|
||
|
}
|
||
|
|
||
|
private void playNow(List<Entry> songs) {
|
||
|
if(getSelectedSongs(albumListView).size() > 0) {
|
||
|
int position = songs.get(0).getBookmarkPosition();
|
||
|
getDownloadService().restore(songs, 0, position, true, true);
|
||
|
selectAll(false, false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private List<MusicDirectory.Entry> getSelectedSongs(ListView albumListView) {
|
||
|
List<MusicDirectory.Entry> songs = new ArrayList<MusicDirectory.Entry>(10);
|
||
|
|
||
|
if (albumListView != null) {
|
||
|
int count = albumListView.getCount();
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
if (albumListView.isItemChecked(i)) {
|
||
|
songs.add((MusicDirectory.Entry) albumListView.getItemAtPosition(i));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return songs;
|
||
|
}
|
||
|
|
||
|
private void refresh() {
|
||
|
finish();
|
||
|
Intent intent = getIntent();
|
||
|
intent.putExtra(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||
|
Util.startActivityWithoutTransition(this, intent);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||
|
switch (item.getItemId()) {
|
||
|
case android.R.id.home:
|
||
|
menuDrawer.toggleMenu();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private void selectAllOrNone() {
|
||
|
boolean someUnselected = false;
|
||
|
int count = albumListView.getCount();
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
if (!albumListView.isItemChecked(i) && albumListView.getItemAtPosition(i) instanceof MusicDirectory.Entry) {
|
||
|
someUnselected = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
selectAll(someUnselected, true);
|
||
|
}
|
||
|
|
||
|
private void selectAll(boolean selected, boolean toast) {
|
||
|
int count = albumListView.getCount();
|
||
|
int selectedCount = 0;
|
||
|
for (int i = 0; i < count; i++) {
|
||
|
MusicDirectory.Entry entry = (MusicDirectory.Entry) albumListView.getItemAtPosition(i);
|
||
|
if (entry != null && !entry.isDirectory() && !entry.isVideo()) {
|
||
|
albumListView.setItemChecked(i, selected);
|
||
|
selectedCount++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Display toast: N tracks selected / N tracks unselected
|
||
|
if (toast) {
|
||
|
int toastResId = selected ? R.string.select_album_n_selected : R.string.select_album_n_unselected;
|
||
|
Util.toast(this, getString(toastResId, selectedCount));
|
||
|
}
|
||
|
|
||
|
enableButtons();
|
||
|
}
|
||
|
|
||
|
private void enableButtons() {
|
||
|
if (getDownloadService() == null) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
List<MusicDirectory.Entry> selection = getSelectedSongs(albumListView);
|
||
|
boolean enabled = !selection.isEmpty();
|
||
|
boolean unpinEnabled = false;
|
||
|
boolean deleteEnabled = false;
|
||
|
|
||
|
int pinnedCount = 0;
|
||
|
|
||
|
for (MusicDirectory.Entry song : selection) {
|
||
|
DownloadFile downloadFile = getDownloadService().forSong(song);
|
||
|
if (downloadFile.isWorkDone()) {
|
||
|
deleteEnabled = true;
|
||
|
}
|
||
|
|
||
|
if (downloadFile.isSaved()) {
|
||
|
pinnedCount++;
|
||
|
unpinEnabled = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
playNowButton.setVisibility(enabled && deleteEnabled ? View.VISIBLE : View.GONE);
|
||
|
pinButton.setVisibility((enabled && !Util.isOffline(this) && selection.size() > pinnedCount) ? View.VISIBLE : View.GONE);
|
||
|
unpinButton.setVisibility(enabled && unpinEnabled ? View.VISIBLE : View.GONE);
|
||
|
downloadButton.setVisibility(enabled && !deleteEnabled && !Util.isOffline(this) ? View.VISIBLE : View.GONE);
|
||
|
deleteButton.setVisibility(enabled && deleteEnabled ? View.VISIBLE : View.GONE);
|
||
|
}
|
||
|
|
||
|
private void downloadBackground(final boolean save) {
|
||
|
List<MusicDirectory.Entry> songs = getSelectedSongs(albumListView);
|
||
|
if(songs.isEmpty()) {
|
||
|
selectAll(true, false);
|
||
|
songs = getSelectedSongs(albumListView);
|
||
|
}
|
||
|
downloadBackground(save, songs);
|
||
|
}
|
||
|
|
||
|
private void downloadBackground(final boolean save, final List<MusicDirectory.Entry> songs) {
|
||
|
if (getDownloadService() == null) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Runnable onValid = new Runnable() {
|
||
|
@Override
|
||
|
public void run() {
|
||
|
warnIfNetworkOrStorageUnavailable();
|
||
|
getDownloadService().downloadBackground(songs, save);
|
||
|
|
||
|
if (save) {
|
||
|
Util.toast(BookmarkActivity.this, getResources().getQuantityString(R.plurals.select_album_n_songs_pinned, songs.size(), songs.size()));
|
||
|
} else {
|
||
|
Util.toast(BookmarkActivity.this, getResources().getQuantityString(R.plurals.select_album_n_songs_downloaded, songs.size(), songs.size()));
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
checkLicenseAndTrialPeriod(onValid);
|
||
|
}
|
||
|
|
||
|
private void delete() {
|
||
|
List<MusicDirectory.Entry> songs = getSelectedSongs(albumListView);
|
||
|
if(songs.isEmpty()) {
|
||
|
selectAll(true, false);
|
||
|
songs = getSelectedSongs(albumListView);
|
||
|
}
|
||
|
if (getDownloadService() != null) {
|
||
|
getDownloadService().delete(songs);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void unpin() {
|
||
|
if (getDownloadService() != null) {
|
||
|
List<MusicDirectory.Entry> songs = getSelectedSongs(albumListView);
|
||
|
Util.toast(BookmarkActivity.this, getResources().getQuantityString(R.plurals.select_album_n_songs_unpinned, songs.size(), songs.size()));
|
||
|
getDownloadService().unpin(songs);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void deleteRecursively(MusicDirectory.Entry album) {
|
||
|
File dir = FileUtil.getAlbumDirectory(this, album);
|
||
|
Util.recursiveDelete(dir);
|
||
|
if(Util.isOffline(this)) {
|
||
|
refresh();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private abstract class LoadTask extends TabActivityBackgroundTask<Pair<MusicDirectory, Boolean>> {
|
||
|
|
||
|
public LoadTask() {
|
||
|
super(BookmarkActivity.this, true);
|
||
|
}
|
||
|
|
||
|
protected abstract MusicDirectory load(MusicService service) throws Exception;
|
||
|
|
||
|
@Override
|
||
|
protected Pair<MusicDirectory, Boolean> doInBackground() throws Throwable {
|
||
|
MusicService musicService = MusicServiceFactory.getMusicService(BookmarkActivity.this);
|
||
|
MusicDirectory dir = load(musicService);
|
||
|
boolean valid = musicService.isLicenseValid(BookmarkActivity.this, this);
|
||
|
return new Pair<MusicDirectory, Boolean>(dir, valid);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected void done(Pair<MusicDirectory, Boolean> result) {
|
||
|
MusicDirectory musicDirectory = result.getFirst();
|
||
|
List<MusicDirectory.Entry> entries = musicDirectory.getChildren();
|
||
|
|
||
|
int songCount = 0;
|
||
|
for (MusicDirectory.Entry entry : entries) {
|
||
|
if (!entry.isDirectory()) {
|
||
|
songCount++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
final int listSize = getIntent().getIntExtra(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0);
|
||
|
|
||
|
if (songCount > 0) {
|
||
|
pinButton.setVisibility(View.VISIBLE);
|
||
|
unpinButton.setVisibility(View.VISIBLE);
|
||
|
downloadButton.setVisibility(View.VISIBLE);
|
||
|
deleteButton.setVisibility(View.VISIBLE);
|
||
|
playNowButton.setVisibility(View.VISIBLE);
|
||
|
} else {
|
||
|
pinButton.setVisibility(View.GONE);
|
||
|
unpinButton.setVisibility(View.GONE);
|
||
|
downloadButton.setVisibility(View.GONE);
|
||
|
deleteButton.setVisibility(View.GONE);
|
||
|
playNowButton.setVisibility(View.GONE);
|
||
|
|
||
|
if (listSize == 0 || result.getFirst().getChildren().size() < listSize) {
|
||
|
albumButtons.setVisibility(View.GONE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
enableButtons();
|
||
|
|
||
|
emptyView.setVisibility(entries.isEmpty() ? View.VISIBLE : View.GONE);
|
||
|
|
||
|
albumListView.setAdapter(new EntryAdapter(BookmarkActivity.this, getImageLoader(), entries, true));
|
||
|
licenseValid = result.getSecond();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private class GetDataTask extends AsyncTask<Void, Void, String[]> {
|
||
|
@Override
|
||
|
protected void onPostExecute(String[] result) {
|
||
|
refreshAlbumListView.onRefreshComplete();
|
||
|
super.onPostExecute(result);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected String[] doInBackground(Void... params) {
|
||
|
refresh();
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
}
|