Merge pull request #974 from mfietz/feature/episodes-actions
Perform action on episodes
This commit is contained in:
commit
cff363e474
|
@ -0,0 +1,416 @@
|
|||
package de.danoeh.antennapod.dialog;
|
||||
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.joanzapata.android.iconify.IconDrawable;
|
||||
import com.joanzapata.android.iconify.Iconify;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import de.danoeh.antennapod.R;
|
||||
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
|
||||
import de.danoeh.antennapod.core.feed.FeedItem;
|
||||
import de.danoeh.antennapod.core.storage.DBTasks;
|
||||
import de.danoeh.antennapod.core.storage.DBWriter;
|
||||
import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
|
||||
public class EpisodesApplyActionFragment extends Fragment {
|
||||
|
||||
public String TAG = "EpisodeActionFragment";
|
||||
|
||||
private ListView mListView;
|
||||
private ArrayAdapter<String> mAdapter;
|
||||
|
||||
private Button btnAddToQueue;
|
||||
private Button btnMarkAsPlayed;
|
||||
private Button btnMarkAsUnplayed;
|
||||
private Button btnDownload;
|
||||
private Button btnDelete;
|
||||
|
||||
private final Map<Long,FeedItem> idMap;
|
||||
private final List<FeedItem> episodes;
|
||||
private final List<String> titles = new ArrayList();
|
||||
private final LongList checkedIds = new LongList();
|
||||
|
||||
private MenuItem mSelectToggle;
|
||||
|
||||
private int textColor;
|
||||
|
||||
public EpisodesApplyActionFragment(List<FeedItem> episodes) {
|
||||
this.episodes = episodes;
|
||||
this.idMap = new HashMap<>(episodes.size());
|
||||
for(FeedItem episode : episodes) {
|
||||
this.idMap.put(episode.getId(), episode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.episodes_apply_action_fragment, container, false);
|
||||
|
||||
mListView = (ListView) view.findViewById(android.R.id.list);
|
||||
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
||||
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> ListView, View view, int position, long rowId) {
|
||||
long id = episodes.get(position).getId();
|
||||
if (checkedIds.contains(id)) {
|
||||
checkedIds.remove(id);
|
||||
} else {
|
||||
checkedIds.add(id);
|
||||
}
|
||||
refreshCheckboxes();
|
||||
}
|
||||
});
|
||||
|
||||
for(FeedItem episode : episodes) {
|
||||
titles.add(episode.getTitle());
|
||||
}
|
||||
|
||||
mAdapter = new ArrayAdapter<>(getActivity(),
|
||||
android.R.layout.simple_list_item_multiple_choice, titles);
|
||||
mListView.setAdapter(mAdapter);
|
||||
checkAll();
|
||||
|
||||
btnAddToQueue = (Button) view.findViewById(R.id.btnAddToQueue);
|
||||
btnAddToQueue.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
queueChecked();
|
||||
}
|
||||
});
|
||||
btnMarkAsPlayed = (Button) view.findViewById(R.id.btnMarkAsPlayed);
|
||||
btnMarkAsPlayed.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
markedCheckedPlayed();
|
||||
}
|
||||
});
|
||||
btnMarkAsUnplayed = (Button) view.findViewById(R.id.btnMarkAsUnplayed);
|
||||
btnMarkAsUnplayed.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
markedCheckedUnplayed();
|
||||
}
|
||||
});
|
||||
btnDownload = (Button) view.findViewById(R.id.btnDownload);
|
||||
btnDownload.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
downloadChecked();
|
||||
}
|
||||
});
|
||||
btnDelete = (Button) view.findViewById(R.id.btnDelete);
|
||||
btnDelete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
deleteChecked();
|
||||
}
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.episodes_apply_action_options, menu);
|
||||
|
||||
int[] attrs = { android.R.attr.textColor };
|
||||
TypedArray ta = getActivity().obtainStyledAttributes(attrs);
|
||||
textColor = ta.getColor(0, Color.GRAY);
|
||||
ta.recycle();
|
||||
|
||||
menu.findItem(R.id.sort).setIcon(new IconDrawable(getActivity(),
|
||||
Iconify.IconValue.fa_sort).color(textColor).actionBarSize());
|
||||
|
||||
mSelectToggle = menu.findItem(R.id.select_toggle);
|
||||
mSelectToggle.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (checkedIds.size() == episodes.size()) {
|
||||
checkNone();
|
||||
} else {
|
||||
checkAll();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
menu.findItem(R.id.select_options).setIcon(new IconDrawable(getActivity(),
|
||||
Iconify.IconValue.fa_caret_down).color(textColor).actionBarSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepareOptionsMenu (Menu menu) {
|
||||
Iconify.IconValue iVal;
|
||||
if(checkedIds.size() == episodes.size()) {
|
||||
iVal = Iconify.IconValue.fa_check_square_o;
|
||||
} else if(checkedIds.size() == 0) {
|
||||
iVal = Iconify.IconValue.fa_square_o;
|
||||
} else {
|
||||
iVal = Iconify.IconValue.fa_minus_square_o;
|
||||
}
|
||||
mSelectToggle.setIcon(new IconDrawable(getActivity(), iVal).color(textColor).actionBarSize());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int resId = 0;
|
||||
switch(item.getItemId()) {
|
||||
case R.id.select_options:
|
||||
return true;
|
||||
case R.id.check_all:
|
||||
checkAll();
|
||||
resId = R.string.selected_all_label;
|
||||
break;
|
||||
case R.id.check_none:
|
||||
checkNone();
|
||||
resId = R.string.deselected_all_label;
|
||||
break;
|
||||
case R.id.check_played:
|
||||
checkPlayed(true);
|
||||
resId = R.string.selected_played_label;
|
||||
break;
|
||||
case R.id.check_unplayed:
|
||||
checkPlayed(false);
|
||||
resId = R.string.selected_unplayed_label;
|
||||
break;
|
||||
case R.id.check_downloaded:
|
||||
checkDownloaded(true);
|
||||
resId = R.string.selected_downloaded_label;
|
||||
break;
|
||||
case R.id.check_not_downloaded:
|
||||
checkDownloaded(false);
|
||||
resId = R.string.selected_not_downloaded_label;
|
||||
break;
|
||||
case R.id.sort_title_a_z:
|
||||
sortByTitle(false);
|
||||
return true;
|
||||
case R.id.sort_title_z_a:
|
||||
sortByTitle(true);
|
||||
return true;
|
||||
case R.id.sort_date_new_old:
|
||||
sortByDate(true);
|
||||
return true;
|
||||
case R.id.sort_date_old_new:
|
||||
sortByDate(false);
|
||||
return true;
|
||||
case R.id.sort_duration_long_short:
|
||||
sortByDuration(true);
|
||||
return true;
|
||||
case R.id.sort_duration_short_long:
|
||||
sortByDuration(false);
|
||||
return true;
|
||||
}
|
||||
if(resId != 0) {
|
||||
Toast.makeText(getActivity(), resId, Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void sortByTitle(final boolean reverse) {
|
||||
Collections.sort(episodes, new Comparator<FeedItem>() {
|
||||
@Override
|
||||
public int compare(FeedItem lhs, FeedItem rhs) {
|
||||
if (reverse) {
|
||||
return -1 * lhs.getTitle().compareTo(rhs.getTitle());
|
||||
} else {
|
||||
return lhs.getTitle().compareTo(rhs.getTitle());
|
||||
}
|
||||
}
|
||||
});
|
||||
refreshTitles();
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void sortByDate(final boolean reverse) {
|
||||
Collections.sort(episodes, new Comparator<FeedItem>() {
|
||||
@Override
|
||||
public int compare(FeedItem lhs, FeedItem rhs) {
|
||||
if (lhs.getPubDate() == null) {
|
||||
return -1;
|
||||
} else if (rhs.getPubDate() == null) {
|
||||
return 1;
|
||||
}
|
||||
int code = lhs.getPubDate().compareTo(rhs.getPubDate());
|
||||
if (reverse) {
|
||||
return -1 * code;
|
||||
} else {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
});
|
||||
refreshTitles();
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void sortByDuration(final boolean reverse) {
|
||||
Collections.sort(episodes, new Comparator<FeedItem>() {
|
||||
@Override
|
||||
public int compare(FeedItem lhs, FeedItem rhs) {
|
||||
int ordering;
|
||||
if (false == lhs.hasMedia()) {
|
||||
ordering = 1;
|
||||
} else if (false == rhs.hasMedia()) {
|
||||
ordering = -1;
|
||||
} else {
|
||||
ordering = lhs.getMedia().getDuration() - rhs.getMedia().getDuration();
|
||||
}
|
||||
if(reverse) {
|
||||
return -1 * ordering;
|
||||
} else {
|
||||
return ordering;
|
||||
}
|
||||
}
|
||||
});
|
||||
refreshTitles();
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void checkAll() {
|
||||
for (FeedItem episode : episodes) {
|
||||
if(false == checkedIds.contains(episode.getId())) {
|
||||
checkedIds.add(episode.getId());
|
||||
}
|
||||
}
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void checkNone() {
|
||||
checkedIds.clear();
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void checkPlayed(boolean isPlayed) {
|
||||
for (FeedItem episode : episodes) {
|
||||
if(episode.isRead() == isPlayed) {
|
||||
if(!checkedIds.contains(episode.getId())) {
|
||||
checkedIds.add(episode.getId());
|
||||
}
|
||||
} else {
|
||||
if(checkedIds.contains(episode.getId())) {
|
||||
checkedIds.remove(episode.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void checkDownloaded(boolean isDownloaded) {
|
||||
for (FeedItem episode : episodes) {
|
||||
if(episode.hasMedia() && episode.getMedia().isDownloaded() == isDownloaded) {
|
||||
if(!checkedIds.contains(episode.getId())) {
|
||||
checkedIds.add(episode.getId());
|
||||
}
|
||||
} else {
|
||||
if(checkedIds.contains(episode.getId())) {
|
||||
checkedIds.remove(episode.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
refreshCheckboxes();
|
||||
}
|
||||
|
||||
private void refreshTitles() {
|
||||
titles.clear();
|
||||
for(FeedItem episode : episodes) {
|
||||
titles.add(episode.getTitle());
|
||||
}
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void refreshCheckboxes() {
|
||||
for (int i = 0; i < episodes.size(); i++) {
|
||||
FeedItem episode = episodes.get(i);
|
||||
boolean checked = checkedIds.contains(episode.getId());
|
||||
mListView.setItemChecked(i, checked);
|
||||
}
|
||||
ActivityCompat.invalidateOptionsMenu(EpisodesApplyActionFragment.this.getActivity());
|
||||
}
|
||||
|
||||
private void queueChecked() {
|
||||
LongList orderedIds = new LongList();
|
||||
for(FeedItem episode : episodes) {
|
||||
if(checkedIds.contains(episode.getId())) {
|
||||
orderedIds.add((episode.getId()));
|
||||
}
|
||||
}
|
||||
DBWriter.addQueueItem(getActivity(), false, orderedIds.toArray());
|
||||
close();
|
||||
}
|
||||
|
||||
private void markedCheckedPlayed() {
|
||||
DBWriter.markItemRead(getActivity(), true, checkedIds.toArray());
|
||||
close();
|
||||
}
|
||||
|
||||
private void markedCheckedUnplayed() {
|
||||
DBWriter.markItemRead(getActivity(), false, checkedIds.toArray());
|
||||
close();
|
||||
}
|
||||
|
||||
private void downloadChecked() {
|
||||
// download the check episodes in the same order as they are currently displayed
|
||||
List<FeedItem> toDownload = new ArrayList<FeedItem>(checkedIds.size());
|
||||
for(FeedItem episode : episodes) {
|
||||
if(checkedIds.contains(episode.getId())) {
|
||||
toDownload.add(episode);
|
||||
}
|
||||
}
|
||||
try {
|
||||
DBTasks.downloadFeedItems(getActivity(), toDownload.toArray(new FeedItem[0]));
|
||||
} catch (DownloadRequestException e) {
|
||||
e.printStackTrace();
|
||||
DownloadRequestErrorDialogCreator.newRequestErrorDialog(getActivity(), e.getMessage());
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
private void deleteChecked() {
|
||||
for(long id : checkedIds.toArray()) {
|
||||
FeedItem episode = idMap.get(id);
|
||||
if(episode.hasMedia()) {
|
||||
DBWriter.deleteFeedMediaOfItem(getActivity(), episode.getMedia().getId());
|
||||
}
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
private void close() {
|
||||
getActivity().getSupportFragmentManager().popBackStack();
|
||||
}
|
||||
|
||||
}
|
|
@ -4,13 +4,15 @@ import android.annotation.SuppressLint;
|
|||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.util.Log;
|
||||
|
@ -29,6 +31,7 @@ import android.widget.ListView;
|
|||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.joanzapata.android.iconify.IconDrawable;
|
||||
import com.joanzapata.android.iconify.Iconify;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
|
@ -61,6 +64,7 @@ import de.danoeh.antennapod.core.storage.DownloadRequestException;
|
|||
import de.danoeh.antennapod.core.storage.DownloadRequester;
|
||||
import de.danoeh.antennapod.core.util.LongList;
|
||||
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
|
||||
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
|
||||
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
|
||||
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
|
||||
import de.danoeh.antennapod.menuhandler.MenuItemUtils;
|
||||
|
@ -156,6 +160,7 @@ public class ItemlistFragment extends ListFragment {
|
|||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
Log.d(TAG, "onResume()");
|
||||
updateProgressBarVisibility();
|
||||
startItemLoader();
|
||||
}
|
||||
|
@ -222,6 +227,13 @@ public class ItemlistFragment extends ListFragment {
|
|||
menu.findItem(R.id.share_link_item).setVisible(false);
|
||||
menu.findItem(R.id.visit_website_item).setVisible(false);
|
||||
}
|
||||
int[] attrs = { android.R.attr.textColor };
|
||||
TypedArray ta = getActivity().obtainStyledAttributes(attrs);
|
||||
int textColor = ta.getColor(0, Color.GRAY);
|
||||
ta.recycle();
|
||||
|
||||
menu.findItem(R.id.episode_actions).setIcon(new IconDrawable(getActivity(),
|
||||
Iconify.IconValue.fa_gears).color(textColor).actionBarSize());
|
||||
|
||||
isUpdatingFeed = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
|
||||
}
|
||||
|
@ -240,6 +252,10 @@ public class ItemlistFragment extends ListFragment {
|
|||
try {
|
||||
if (!FeedMenuHandler.onOptionsItemClicked(getActivity(), item, feed)) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.episode_actions:
|
||||
Fragment fragment = new EpisodesApplyActionFragment(feed.getItems());
|
||||
((MainActivity)getActivity()).loadChildFragment(fragment);
|
||||
return true;
|
||||
case R.id.remove_item:
|
||||
final FeedRemover remover = new FeedRemover(
|
||||
getActivity(), feed) {
|
||||
|
@ -406,6 +422,9 @@ public class ItemlistFragment extends ListFragment {
|
|||
private boolean insideOnFragmentLoaded = false;
|
||||
|
||||
private void onFragmentLoaded() {
|
||||
if(!isVisible()) {
|
||||
return;
|
||||
}
|
||||
insideOnFragmentLoaded = true;
|
||||
if (adapter == null) {
|
||||
setListAdapter(null);
|
||||
|
|
|
@ -72,7 +72,7 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
|
|||
Log.d(TAG, "remove(" + which + ")");
|
||||
stopItemLoader();
|
||||
FeedItem item = (FeedItem) listView.getAdapter().getItem(which);
|
||||
DBWriter.markItemRead(getActivity(), item.getId(), true);
|
||||
DBWriter.markItemRead(getActivity(), true, item.getId());
|
||||
undoBarController.showUndoBar(false,
|
||||
getString(R.string.marked_as_read_label), new FeedItemUndoToken(item,
|
||||
which)
|
||||
|
@ -88,7 +88,7 @@ public class NewEpisodesFragment extends AllEpisodesFragment {
|
|||
public void onUndo(FeedItemUndoToken token) {
|
||||
if (token != null) {
|
||||
long itemId = token.getFeedItemId();
|
||||
DBWriter.markItemRead(context, itemId, false);
|
||||
DBWriter.markItemRead(context, false, itemId);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
|
|
|
@ -41,7 +41,6 @@ public class FeedMenuHandler {
|
|||
}
|
||||
|
||||
Log.d(TAG, "Preparing options menu");
|
||||
menu.findItem(R.id.mark_all_read_item).setVisible(selectedFeed.hasNewItems());
|
||||
if (selectedFeed.getPaymentLink() != null && selectedFeed.getFlattrStatus().flattrable()) {
|
||||
menu.findItem(R.id.support_item).setVisible(true);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bottomBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="68dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="4dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnAddToQueue"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="?attr/content_new"
|
||||
android:text="@string/add_to_queue_label"
|
||||
android:textSize="10sp"
|
||||
android:background="@android:color/transparent"/>
|
||||
|
||||
<View xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="4dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
tools:background="@android:color/holo_red_dark" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnMarkAsPlayed"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="?attr/navigation_accept"
|
||||
android:text="@string/mark_read_label"
|
||||
android:textSize="10sp"
|
||||
android:background="@android:color/transparent"/>
|
||||
|
||||
<View xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="4dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
tools:background="@android:color/holo_red_dark" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnMarkAsUnplayed"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="?attr/navigation_cancel"
|
||||
android:text="@string/mark_unread_label"
|
||||
android:textSize="10sp"
|
||||
android:background="@android:color/transparent"/>
|
||||
|
||||
<View xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="4dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
tools:background="@android:color/holo_red_dark" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnDownload"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="?attr/av_download"
|
||||
android:text="@string/download_label"
|
||||
android:textSize="10sp"
|
||||
android:background="@android:color/transparent"/>
|
||||
|
||||
<View xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="4dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
tools:background="@android:color/holo_red_dark" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnDelete"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:drawableTop="?attr/content_discard"
|
||||
android:text="@string/remove_episode_lable"
|
||||
android:textSize="10sp"
|
||||
android:background="@android:color/transparent"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
android:paddingBottom="4dp"
|
||||
android:layout_above="@id/bottomBar"
|
||||
tools:background="@android:color/holo_red_dark" />
|
||||
|
||||
<ListView
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/divider">
|
||||
|
||||
</ListView>
|
||||
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/sort"
|
||||
android:title="@string/sort"
|
||||
app:showAsAction="always">
|
||||
<menu>
|
||||
<item android:id="@+id/sort_title"
|
||||
android:title="@string/sort_title"/>
|
||||
<item android:id="@+id/sort_title_a_z"
|
||||
android:title="@string/sort_title_a_z"/>
|
||||
<item android:id="@+id/sort_title_z_a"
|
||||
android:title="@string/sort_title_z_a"/>
|
||||
<item android:id="@+id/sort_date_new_old"
|
||||
android:title="@string/sort_date_new_old"/>
|
||||
<item android:id="@+id/sort_date_old_new"
|
||||
android:title="@string/sort_date_old_new"/>
|
||||
<item android:id="@+id/sort_duration_short_long"
|
||||
android:title="@string/sort_duration_short_long"/>
|
||||
<item android:id="@+id/sort_duration_long_short"
|
||||
android:title="@string/sort_duration_long_short"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/select_toggle"
|
||||
android:title="@string/select_all_label"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/select_options"
|
||||
android:title="@string/all_label"
|
||||
app:showAsAction="always">
|
||||
|
||||
<menu>
|
||||
<item android:id="@+id/select_label"
|
||||
android:title="@string/select_label"/>
|
||||
<item android:id="@+id/check_all"
|
||||
android:title="@string/all_label"/>
|
||||
<item android:id="@+id/check_none"
|
||||
android:title="@string/none_label"/>
|
||||
<item android:id="@+id/check_played"
|
||||
android:title="@string/played_label"/>
|
||||
<item android:id="@+id/check_unplayed"
|
||||
android:title="@string/unplayed_label"/>
|
||||
<item android:id="@+id/check_downloaded"
|
||||
android:title="@string/downloaded_label"/>
|
||||
<item android:id="@+id/check_not_downloaded"
|
||||
android:title="@string/not_downloaded_label"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
</menu>
|
|
@ -9,6 +9,12 @@
|
|||
android:title="@string/hide_episodes_title"
|
||||
custom:showAsAction="always">
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/episode_actions"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/episode_actions"
|
||||
custom:showAsAction="always">
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/refresh_item"
|
||||
android:icon="?attr/navigation_refresh"
|
||||
|
@ -30,13 +36,6 @@
|
|||
custom:actionViewClass="android.support.v7.widget.SearchView"
|
||||
android:title="@string/search_label"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/mark_all_read_item"
|
||||
android:menuCategory="container"
|
||||
android:title="@string/mark_all_read_label"
|
||||
custom:showAsAction="collapseActionView">
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/support_item"
|
||||
android:menuCategory="container"
|
||||
|
|
|
@ -375,14 +375,21 @@ public class DBWriter {
|
|||
|
||||
}
|
||||
|
||||
public static Future<?> addQueueItem(final Context context,
|
||||
final long... itemIds) {
|
||||
return addQueueItem(context, false, itemIds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends FeedItem objects to the end of the queue. The 'read'-attribute of all items will be set to true.
|
||||
* If a FeedItem is already in the queue, the FeedItem will not change its position in the queue.
|
||||
*
|
||||
* @param context A context that is used for opening a database connection.
|
||||
* @param performAutoDownload true if an auto-download process should be started after the operation.
|
||||
* @param itemIds IDs of the FeedItem objects that should be added to the queue.
|
||||
*/
|
||||
public static Future<?> addQueueItem(final Context context,
|
||||
public static Future<?> addQueueItem(final Context context, final boolean performAutoDownload,
|
||||
final long... itemIds) {
|
||||
return dbExec.submit(new Runnable() {
|
||||
|
||||
|
@ -408,7 +415,7 @@ public class DBWriter {
|
|||
boolean addToFront = UserPreferences.enqueueAtFront();
|
||||
|
||||
if(addToFront){
|
||||
queue.add(0, item);
|
||||
queue.add(0+i, item);
|
||||
} else {
|
||||
queue.add(item);
|
||||
}
|
||||
|
@ -423,11 +430,12 @@ public class DBWriter {
|
|||
}
|
||||
}
|
||||
adapter.close();
|
||||
DBTasks.autodownloadUndownloadedItems(context);
|
||||
if (performAutoDownload) {
|
||||
DBTasks.autodownloadUndownloadedItems(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -595,16 +603,24 @@ public class DBWriter {
|
|||
adapter.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'read'-attribute of a FeedItem to the specified value.
|
||||
/*
|
||||
* Sets the 'read'-attribute of all specified FeedItems
|
||||
*
|
||||
* @param context A context that is used for opening a database connection.
|
||||
* @param itemId ID of the FeedItem
|
||||
* @param read New value of the 'read'-attribute
|
||||
* @param itemIds IDs of the FeedItems.
|
||||
*/
|
||||
public static Future<?> markItemRead(final Context context, final long itemId,
|
||||
final boolean read) {
|
||||
return markItemRead(context, itemId, read, 0, false);
|
||||
public static Future<?> markItemRead(final Context context, final boolean read, final long... itemIds) {
|
||||
return dbExec.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final PodDBAdapter adapter = new PodDBAdapter(context);
|
||||
adapter.open();
|
||||
adapter.setFeedItemRead(read, itemIds);
|
||||
adapter.close();
|
||||
EventDistributor.getInstance().sendUnreadItemsUpdateBroadcast();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
<string name="feed_remover_msg">Removing Feed</string>
|
||||
<string name="load_complete_feed">Refresh complete Feed</string>
|
||||
<string name="hide_episodes_title">Hide Episodes</string>
|
||||
<string name="episode_actions">Apply actions</string>
|
||||
<string name="hide_unplayed_episodes_label">Unplayed</string>
|
||||
<string name="hide_paused_episodes_label">Paused</string>
|
||||
<string name="hide_played_episodes_label">Played</string>
|
||||
|
@ -115,8 +116,8 @@
|
|||
<string name="remove_label">Remove</string>
|
||||
<string name="remove_episode_lable">Remove Episode</string>
|
||||
<string name="mark_read_label">Mark as played</string>
|
||||
<string name="mark_unread_label">Mark as unplayed</string>
|
||||
<string name="marked_as_read_label">Marked as played</string>
|
||||
<string name="mark_unread_label">Mark as unplayed</string>
|
||||
<string name="add_to_queue_label">Add to Queue</string>
|
||||
<string name="added_to_queue_label">Added to Queue</string>
|
||||
<string name="remove_from_queue_label">Remove from Queue</string>
|
||||
|
@ -346,6 +347,7 @@
|
|||
<string name="opml_import_error_dir_empty">The import directory is empty.</string>
|
||||
<string name="select_all_label">Select all</string>
|
||||
<string name="deselect_all_label">Deselect all</string>
|
||||
<string name="select_options_label">Select ...</string>
|
||||
<string name="choose_file_from_filesystem">From local filesystem</string>
|
||||
<string name="choose_file_from_external_application">Use external application</string>
|
||||
<string name="opml_export_label">OPML export</string>
|
||||
|
@ -450,4 +452,25 @@
|
|||
|
||||
<string name="sp_apps_importing_feeds_msg">Importing subscriptions from single-purpose apps…</string>
|
||||
<string name="search_itunes_label">Search iTunes</string>
|
||||
|
||||
<string name="select_label"><b>Select ...</b></string>
|
||||
<string name="all_label">All</string>
|
||||
<string name="selected_all_label">Selected all Episodes</string>
|
||||
<string name="none_label">None</string>
|
||||
<string name="deselected_all_label">Deselected all Episodes</string>
|
||||
<string name="played_label">Played</string>
|
||||
<string name="selected_played_label">Selected played Episodes</string>
|
||||
<string name="unplayed_label">Unplayed</string>
|
||||
<string name="selected_unplayed_label">Selected unplayed Episodes</string>
|
||||
<string name="downloaded_label">Downloaded</string>
|
||||
<string name="selected_downloaded_label">Selected downloaded Episodes</string>
|
||||
<string name="not_downloaded_label">Not downloaded</string>
|
||||
<string name="selected_not_downloaded_label">Selected not downloaded Episodes</string>
|
||||
<string name="sort_title"><b>Sort by ...</b></string>
|
||||
<string name="sort_title_a_z">Title (A \u2192 Z)</string>
|
||||
<string name="sort_title_z_a">Title (Z \u2192 A)</string>
|
||||
<string name="sort_date_new_old">Date (New \u2192 Old)</string>
|
||||
<string name="sort_date_old_new">Date (Old \u2192 New)</string>
|
||||
<string name="sort_duration_short_long">Duration (Short \u2192 Long)</string>
|
||||
<string name="sort_duration_long_short">Duration (Long \u2192 Short)</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue