/*****************************************************************************
* AudioListActivity.java
*****************************************************************************
* Copyright © 2011-2012 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
package org.videolan.vlc.gui.audio;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import org.videolan.libvlc.util.AndroidUtil;
import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.PlaybackService;
import org.videolan.vlc.R;
import org.videolan.vlc.VLCApplication;
import org.videolan.vlc.gui.PlaybackServiceFragment;
import org.videolan.vlc.gui.SecondaryActivity;
import org.videolan.vlc.util.AndroidDevices;
import org.videolan.vlc.util.Util;
import org.videolan.vlc.util.WeakHandler;
import org.videolan.vlc.widget.SwipeRefreshLayout;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class AudioAlbumsSongsFragment extends PlaybackServiceFragment implements SwipeRefreshLayout.OnRefreshListener {
public final static String TAG = "VLC/AudioAlbumsSongsFragment";
private static final int DELETE_MEDIA = 0;
private static final int DELETE_DURATION = 3000;
private MediaLibrary mMediaLibrary;
private PlaybackService.Client mClient;
private SwipeRefreshLayout mSwipeRefreshLayout;
private ViewPager mViewPager;
private AudioBrowserListAdapter mSongsAdapter;
private AudioBrowserListAdapter mAlbumsAdapter;
public final static int MODE_ALBUM = 0;
public final static int MODE_SONG = 1;
public final static int MODE_TOTAL = 2; // Number of audio browser modes
private ArrayList<MediaWrapper> mMediaList;
private String mTitle;
/* All subclasses of Fragment must include a public empty constructor. */
public AudioAlbumsSongsFragment() { }
public void setMediaList(ArrayList<MediaWrapper> mediaList, String title) {
mMediaList = mediaList;
mTitle = title;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAlbumsAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITH_COVER);
mSongsAdapter = new AudioBrowserListAdapter(getActivity(), AudioBrowserListAdapter.ITEM_WITH_COVER);
mAlbumsAdapter.setContextPopupMenuListener(mContextPopupMenuListener);
mSongsAdapter.setContextPopupMenuListener(mContextPopupMenuListener);
mMediaLibrary = MediaLibrary.getInstance();
if (savedInstanceState != null)
setMediaList(savedInstanceState.<MediaWrapper>getParcelableArrayList("list"), savedInstanceState.getString("title"));
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
updateList();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.audio_albums_songs, container, false);
ListView albumsList = (ListView) v.findViewById(R.id.albums);
ListView songsList = (ListView) v.findViewById(R.id.songs);
List<View> lists = Arrays.asList((View)albumsList, songsList);
String[] titles = new String[] {getString(R.string.albums), getString(R.string.songs)};
mViewPager = (ViewPager) v.findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(MODE_TOTAL - 1);
mViewPager.setAdapter(new AudioPagerAdapter(lists, titles));
mViewPager.setOnTouchListener(mSwipeFilter);
TabLayout mTabLayout = (TabLayout) v.findViewById(R.id.sliding_tabs);
mTabLayout.setupWithViewPager(mViewPager);
songsList.setAdapter(mSongsAdapter);
albumsList.setAdapter(mAlbumsAdapter);
songsList.setOnItemClickListener(songsListener);
albumsList.setOnItemClickListener(albumsListener);
registerForContextMenu(albumsList);
registerForContextMenu(songsList);
mSwipeRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipeLayout);
mSwipeRefreshLayout.setColorSchemeResources(R.color.orange700);
mSwipeRefreshLayout.setOnRefreshListener(this);
songsList.setOnScrollListener(mScrollListener);
albumsList.setOnScrollListener(mScrollListener);
getActivity().setTitle(mTitle);
return v;
}
AbsListView.OnScrollListener mScrollListener = new AbsListView.OnScrollListener(){
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
mSwipeRefreshLayout.setEnabled(firstVisibleItem == 0);
}
};
@Override
public void onRefresh() {
updateList();
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("list", mMediaList);
outState.putString("title", mTitle);
super.onSaveInstanceState(outState);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
int position = 0;
if (menuInfo instanceof AdapterContextMenuInfo)
position = ((AdapterContextMenuInfo)menuInfo).position;
if (mViewPager.getCurrentItem() == MODE_SONG && mSongsAdapter.getItem(position).mIsSeparator)
return;
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.audio_list_browser, menu);
setContextMenuItems(menu, v, position);
}
private void setContextMenuItems(Menu menu, View v, int position) {
if (mViewPager.getCurrentItem() != MODE_SONG) {
menu.setGroupVisible(R.id.songs_view_only, false);
menu.setGroupVisible(R.id.phone_only, false);
}
if (!AndroidDevices.isPhone())
menu.setGroupVisible(R.id.phone_only, false);
menu.findItem(R.id.audio_list_browser_play).setVisible(true);
}
@Override
public boolean onContextItemSelected(MenuItem menu) {
if(!getUserVisibleHint())
return super.onContextItemSelected(menu);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menu.getMenuInfo();
if (info != null && handleContextItemSelected(menu, info.position))
return true;
return super.onContextItemSelected(menu);
}
private boolean handleContextItemSelected(MenuItem item, int position) {
int startPosition;
List<MediaWrapper> medias;
int id = item.getItemId();
boolean useAllItems = id == R.id.audio_list_browser_play_all;
boolean append = id == R.id.audio_list_browser_append;
if (id == R.id.audio_list_browser_delete) {
Snackbar.make(getView(), getString(R.string.file_deleted), Snackbar.LENGTH_LONG)
.setAction(android.R.string.cancel, mCancelDeleteMediaListener)
.show();
Message msg = mHandler.obtainMessage(DELETE_MEDIA, position, 0);
mHandler.sendMessageDelayed(msg, DELETE_DURATION);
return true;
}
if (id == R.id.audio_list_browser_set_song) {
AudioUtil.setRingtone(mSongsAdapter.getItem(position).mMediaList.get(0), getActivity());
return true;
}
if (useAllItems) {
medias = new ArrayList<MediaWrapper>();
startPosition = mSongsAdapter.getListWithPosition(medias, position);
}
else {
startPosition = 0;
switch (mViewPager.getCurrentItem())
{
case MODE_ALBUM: // albums
medias = mAlbumsAdapter.getMedias(position);
break;
case MODE_SONG: // songs
medias = mSongsAdapter.getMedias(position);
break;
default:
return true;
}
}
if (mService != null) {
if (append)
mService.append(medias);
else
mService.load(medias, startPosition);
}
return super.onContextItemSelected(item);
}
private void updateList() {
if (mMediaList == null || getActivity() == null)
return;
final Activity activity = getActivity();
mAlbumsAdapter.clear();
mSongsAdapter.clear();
VLCApplication.runBackground(new Runnable() {
@Override
public void run() {
Collections.sort(mMediaList, MediaComparators.byAlbum);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < mMediaList.size(); ++i) {
MediaWrapper media = mMediaList.get(i);
mAlbumsAdapter.addSeparator(Util.getMediaReferenceArtist(activity, media), media);
mAlbumsAdapter.add(Util.getMediaAlbum(activity, media), null, media);
mSongsAdapter.addSeparator(Util.getMediaAlbum(activity, media), media);
}
mSongsAdapter.sortByAlbum();
mAlbumsAdapter.notifyDataSetChanged();
mSongsAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
});
}
OnItemClickListener albumsListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View v, int p, long id) {
ArrayList<MediaWrapper> mediaList = mAlbumsAdapter.getMedias(p);
Intent i = new Intent(getActivity(), SecondaryActivity.class);
i.putExtra("fragment", SecondaryActivity.ALBUM);
i.putParcelableArrayListExtra("list", mediaList);
i.putExtra("filter", mAlbumsAdapter.getTitle(p));
startActivity(i);
}
};
OnItemClickListener songsListener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View v, int p, long id) {
if (mService != null) {
final List<MediaWrapper> media = mSongsAdapter.getItem(p).mMediaList;
mService.load(media, 0);
}
}
};
AudioBrowserListAdapter.ContextPopupMenuListener mContextPopupMenuListener
= new AudioBrowserListAdapter.ContextPopupMenuListener() {
@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onPopupMenu(View anchor, final int position) {
if (!AndroidUtil.isHoneycombOrLater()) {
// Call the "classic" context menu
anchor.performLongClick();
return;
}
PopupMenu popupMenu = new PopupMenu(getActivity(), anchor);
popupMenu.getMenuInflater().inflate(R.menu.audio_list_browser, popupMenu.getMenu());
setContextMenuItems(popupMenu.getMenu(), anchor, position);
popupMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return handleContextItemSelected(item, position);
}
});
popupMenu.show();
}
};
/*
* Disable Swipe Refresh while scrolling horizontally
*/
private View.OnTouchListener mSwipeFilter = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mSwipeRefreshLayout.setEnabled(false);
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
mSwipeRefreshLayout.setEnabled(true);
break;
}
return false;
}
};
public void clear(){
mAlbumsAdapter.clear();
mSongsAdapter.clear();
}
View.OnClickListener mCancelDeleteMediaListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
mHandler.removeMessages(DELETE_MEDIA);
}
};
Handler mHandler = new AudioAlbumsSongsFragmentHandler(this);
private static class AudioAlbumsSongsFragmentHandler extends WeakHandler<AudioAlbumsSongsFragment>{
public AudioAlbumsSongsFragmentHandler(AudioAlbumsSongsFragment owner) {
super(owner);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
final AudioAlbumsSongsFragment fragment = getOwner();
switch (msg.what){
case DELETE_MEDIA:
AudioBrowserListAdapter.ListItem listItem = fragment.mSongsAdapter.getItem(msg.arg1);
MediaWrapper media = listItem.mMediaList.get(0);
final String path = media.getUri().getPath();
fragment.mMediaLibrary.getMediaItems().remove(media);
fragment.mSongsAdapter.removeMedia(media);
fragment.mAlbumsAdapter.removeMedia(media);
if (fragment.mService != null)
fragment.mService.removeLocation(media.getLocation());
fragment.mMediaLibrary.getMediaItems().remove(media);
VLCApplication.runBackground(new Runnable() {
public void run() {
Util.recursiveDelete(VLCApplication.getAppContext(), new File(path));
}
});
break;
}
}
}
}