diff options
author | Martin Fietz <marf@hadiko-99-4.hadiko.uni-karlsruhe.de> | 2015-05-09 21:19:22 +0200 |
---|---|---|
committer | Martin Fietz <Martin.Fietz@gmail.com> | 2015-05-19 11:58:38 +0200 |
commit | c829a4e9b2cf7ccee117269769d71c40432f92fa (patch) | |
tree | b2bd46f10c2c69645a52e01c1270a2132f6368a5 | |
parent | 518e8207da568d04c3e780b407f29bc51e2d1995 (diff) | |
download | AntennaPod-c829a4e9b2cf7ccee117269769d71c40432f92fa.zip |
Context dialog for feed item list
-rw-r--r-- | app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java | 2 | ||||
-rw-r--r-- | app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java | 2 | ||||
-rw-r--r-- | app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java | 2 | ||||
-rw-r--r-- | app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java | 2 | ||||
-rw-r--r-- | app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java | 57 | ||||
-rw-r--r-- | app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java | 176 | ||||
-rw-r--r-- | app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java | 87 | ||||
-rw-r--r-- | app/src/main/res/menu/feeditem.xml | 77 | ||||
-rw-r--r-- | app/src/main/res/menu/feeditem_options.xml (renamed from app/src/main/res/menu/feeditem_dialog.xml) | 2 | ||||
-rw-r--r-- | app/src/main/res/menu/feeditemlist_context.xml | 51 | ||||
-rw-r--r-- | app/src/main/res/menu/queue_context.xml | 19 | ||||
-rw-r--r-- | core/src/main/java/de/danoeh/antennapod/core/util/IntList.java | 240 | ||||
-rw-r--r-- | core/src/main/res/values/strings.xml | 10 |
13 files changed, 451 insertions, 276 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java index b90c4e2a1..ca4f2620f 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java @@ -45,7 +45,7 @@ public class DBReaderTest extends InstrumentationTestCase { private void expiredFeedListTestHelper(long lastUpdate, long expirationTime, boolean shouldReturn) { final Context context = getInstrumentation().getTargetContext(); Feed feed = new Feed(0, new Date(lastUpdate), "feed", "link", "descr", null, - null, null, null, "feed", null, null, "url", false, new FlattrStatus(), false, null, null); + null, null, null, "feed", null, null, "url", false, new FlattrStatus(), false, null, null, false); feed.setItems(new ArrayList<FeedItem>()); PodDBAdapter adapter = new PodDBAdapter(context); adapter.open(); diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java index 770b50952..16f50cf28 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java @@ -302,7 +302,7 @@ public class DBTasksTest extends InstrumentationTestCase { private void expiredFeedListTestHelper(long lastUpdate, long expirationTime, boolean shouldReturn) { UserPreferences.setUpdateInterval(context, expirationTime); Feed feed = new Feed(0, new Date(lastUpdate), "feed", "link", "descr", null, - null, null, null, "feed", null, null, "url", false, new FlattrStatus(), false, null, null); + null, null, null, "feed", null, null, "url", false, new FlattrStatus(), false, null, null, false); feed.setItems(new ArrayList<FeedItem>()); PodDBAdapter adapter = new PodDBAdapter(context); adapter.open(); diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java index fba3faa96..4f33cd798 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java @@ -47,7 +47,7 @@ public class DBTestUtils { adapter.open(); for (int i = 0; i < numFeeds; i++) { Feed f = new Feed(0, new Date(), "feed " + i, "link" + i, "descr", null, null, - null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null, null); + null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null, null, false); f.setItems(new ArrayList<FeedItem>()); for (int j = 0; j < numItems; j++) { FeedItem item = new FeedItem(0, "item " + j, "id" + j, "link" + j, new Date(), diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java index 10409a421..51a1e2252 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java @@ -270,7 +270,7 @@ public class ItemFragment extends Fragment implements LoaderManager.LoaderCallba return; } popupMenu.getMenu().clear(); - popupMenu.inflate(R.menu.feeditem_dialog); + popupMenu.inflate(R.menu.feeditem_options); if (item.hasMedia()) { FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, queue); } else { diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java index 0f4ee9013..aaa8cd645 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemlistFragment.java @@ -14,11 +14,13 @@ import android.support.v4.view.MenuItemCompat; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.util.Log; +import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; +import android.widget.AdapterView; import android.widget.IconTextView; import android.widget.ImageButton; import android.widget.ImageView; @@ -58,6 +60,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.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.FeedMenuHandler; import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.greenrobot.event.EventBus; @@ -78,6 +81,7 @@ public class ItemlistFragment extends ListFragment { public static final String ARGUMENT_FEED_ID = "argument.de.danoeh.antennapod.feed_id"; protected FeedItemlistAdapter adapter; + private ContextMenu contextMenu; private long feedID; private Feed feed; @@ -264,10 +268,61 @@ public class ItemlistFragment extends ListFragment { } else { return true; } + } + + private final FeedItemMenuHandler.MenuInterface contextMenuInterface = new FeedItemMenuHandler.MenuInterface() { + @Override + public void setItemVisibility(int id, boolean visible) { + if(contextMenu == null) { + return; + } + MenuItem item = contextMenu.findItem(id); + if (item != null) { + item.setVisible(visible); + } + } + }; + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo; + + // because of addHeaderView(), positions are increased by 1! + FeedItem item = itemAccess.getItem(adapterInfo.position-1); + + MenuInflater inflater = getActivity().getMenuInflater(); + inflater.inflate(R.menu.feeditemlist_context, menu); + if (item != null) { + menu.setHeaderTitle(item.getTitle()); + } + + contextMenu = menu; + FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item, false, queue); } @Override + public boolean onContextItemSelected(MenuItem item) { + AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); + // because of addHeaderView(), positions are increased by 1! + FeedItem selectedItem = itemAccess.getItem(menuInfo.position-1); + + if (selectedItem == null) { + Log.i(TAG, "Selected item at position " + menuInfo.position + " was null, ignoring selection"); + return super.onContextItemSelected(item); + } + + try { + return FeedItemMenuHandler.onMenuItemClicked(getActivity(), item.getItemId(), selectedItem); + } catch (DownloadRequestException e) { + // context menu doesn't contain download functionality + return true; + } + } + + + @Override public void setListAdapter(ListAdapter adapter) { // This workaround prevents the ListFragment from setting a list adapter when its state is restored. // This is only necessary on API 10 because addFooterView throws an internal exception in this case. @@ -281,6 +336,8 @@ public class ItemlistFragment extends ListFragment { super.onViewCreated(view, savedInstanceState); ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(""); + registerForContextMenu(getListView()); + viewsCreated = true; if (itemsLoaded) { onFragmentLoaded(); diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java index 46fe02ab9..0ccca3e55 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/QueueFragment.java @@ -1,7 +1,6 @@ package de.danoeh.antennapod.fragment; import android.app.Activity; -import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; @@ -22,10 +21,10 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; import com.mobeta.android.dslv.DragSortListView; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; @@ -40,18 +39,19 @@ import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.QueueEvent; -import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction; -import de.danoeh.antennapod.core.preferences.GpodnetPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.DownloadService; import de.danoeh.antennapod.core.service.download.Downloader; import de.danoeh.antennapod.core.storage.DBReader; 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.storage.DownloadRequester; +import de.danoeh.antennapod.core.util.LongList; import de.danoeh.antennapod.core.util.QueueSorter; import de.danoeh.antennapod.core.util.gui.FeedItemUndoToken; import de.danoeh.antennapod.core.util.gui.UndoBarController; +import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.greenrobot.event.EventBus; @@ -71,6 +71,8 @@ public class QueueFragment extends Fragment { private TextView txtvEmpty; private ProgressBar progLoading; + private ContextMenu contextMenu; + private UndoBarController<FeedItemUndoToken> undoBarController; private List<FeedItem> queue; @@ -296,6 +298,19 @@ public class QueueFragment extends Fragment { } + private final FeedItemMenuHandler.MenuInterface contextMenuInterface = new FeedItemMenuHandler.MenuInterface() { + @Override + public void setItemVisibility(int id, boolean visible) { + if(contextMenu == null) { + return; + } + MenuItem item = contextMenu.findItem(id); + if (item != null) { + item.setVisible(visible); + } + } + }; + @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); @@ -309,27 +324,12 @@ public class QueueFragment extends Fragment { menu.setHeaderTitle(item.getTitle()); } - menu.findItem(R.id.move_to_top_item).setEnabled(!queue.isEmpty() && queue.get(0) != item); - menu.findItem(R.id.move_to_bottom_item).setEnabled(!queue.isEmpty() && queue.get(queue.size() - 1) != item); - if(item.isRead()) { - menu.findItem(R.id.mark_read_item).setVisible(false); - } else if(!isResettable(item)){ - menu.findItem(R.id.reset_attributes).setVisible(false); - } - } - - private static boolean isResettable(FeedItem item) { - // TODO add auto_download - if(item.isRead()) { - return true; + contextMenu = menu; + LongList queueIds = new LongList(queue.size()); + for(FeedItem queueItem : queue) { + queueIds.add(queueItem.getId()); } - if(item.getMedia() != null) { - FeedMedia media = item.getMedia(); - if(media.getPosition() > 0 || media.getPlayedDuration() > 0) { - return true; - } - } - return false; + FeedItemMenuHandler.onPrepareMenu(contextMenuInterface, item, false, queueIds); } @Override @@ -342,132 +342,16 @@ public class QueueFragment extends Fragment { return super.onContextItemSelected(item); } - switch (item.getItemId()) { - case R.id.move_to_top_item: - DBWriter.moveQueueItemToTop(getActivity(), selectedItem.getId(), true); - return true; - case R.id.mark_read_item: - DBWriter.markItemRead(getActivity(), selectedItem, true, false); - selectedItem.setRead(true); - if(GpodnetPreferences.loggedIn()) { - FeedMedia media = selectedItem.getMedia(); - GpodnetEpisodeAction actionPlay = new GpodnetEpisodeAction.Builder(selectedItem, GpodnetEpisodeAction.Action.PLAY) - .currentDeviceId() - .currentTimestamp() - .started(media.getDuration() / 1000) - .position(media.getDuration() / 1000) - .total(media.getDuration() / 1000) - .build(); - GpodnetPreferences.enqueueEpisodeAction(actionPlay); - } - return true; - case R.id.reset_attributes: - showResetAttributesDialog(selectedItem); - return true; - case R.id.move_to_bottom_item: - DBWriter.moveQueueItemToBottom(getActivity(), selectedItem.getId(), true); - return true; - case R.id.remove_from_queue_item: - DBWriter.removeQueueItem(getActivity(), selectedItem, false); - return true; - default: - return super.onContextItemSelected(item); + try { + return FeedItemMenuHandler.onMenuItemClicked(getActivity(), item.getItemId(), selectedItem); + } catch (DownloadRequestException e) { + e.printStackTrace(); + Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show(); + return true; } } - private void showResetAttributesDialog(final FeedItem item) { - final String resetReadValue = "RESET_READ"; - final String resetPositionValue = "RESET_POSITION"; - final String activateAutoDownloadValue = "ACTIVATE_AUTO_DOWNLOAD"; - final String unflattrValue = "UNFLATTR"; - - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setTitle(R.string.reset_attributes_title); - final List<String> resettableItems = new ArrayList<String>(); - final List<String> resettableValues = new ArrayList<String>(); - if(item.isRead()) { - resettableItems.add(getString(R.string.mark_unread_label)); - resettableValues.add(resetReadValue); - } - // TODO - /* - if(false == item.getAutoDownload) { - resettableItems.add(getString(R.string.mark_unread_label)); - resettableValues.add("ACTIVATE_AUTO_DOWNLOAD"); - } - - if(item.getFlattrStatus().getUnflattred() == false) { - resettableItems.add(getString(R.string.reset)); - resettableValues.add("ACTIVATE_AUTO_DOWNLOAD"); - } - */ - if(item.getMedia() != null) { - FeedMedia media = item.getMedia(); - if(media.getPosition() > 0) { - resettableItems.add(getString(R.string.reset_attribute_position)); - resettableValues.add(resetPositionValue); - } - } - String[] items = resettableItems.toArray(new String[resettableItems.size()]); - final boolean[] checked = new boolean[items.length]; - builder.setMultiChoiceItems(items, checked, new DialogInterface.OnMultiChoiceClickListener() { - @Override - public void onClick(DialogInterface dialog, int which, boolean isChecked) { - checked[which] = isChecked; - if(resettableValues.get(which).equals(resetPositionValue) && isChecked) { - AlertDialog alertDialog = (AlertDialog) dialog; - int position = resettableValues.indexOf(resetReadValue); - alertDialog.getListView().setItemChecked(position, true); - } - } - }); - builder.setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - boolean markAsUnplayed = false; - boolean resetPosition = false; - boolean unflattr = false; - boolean activateAutoDownload = false; - for(int i=0; i < checked.length; i++) { - if(checked[i]) { - switch(resettableValues.get(i)) { - case resetReadValue: - markAsUnplayed = true; - break; - case resetPositionValue: - resetPosition = true; - break; - case unflattrValue: - unflattr = true; - break; - case activateAutoDownloadValue: - activateAutoDownload = true; - } - } - } - if(markAsUnplayed) { - DBWriter.markItemRead(getActivity(), item, false, resetPosition); - if(GpodnetPreferences.loggedIn()) { - GpodnetEpisodeAction actionNew = new GpodnetEpisodeAction.Builder(item, - GpodnetEpisodeAction.Action.NEW) - .currentDeviceId() - .currentTimestamp() - .build(); - GpodnetPreferences.enqueueEpisodeAction(actionNew); - } - } - if(unflattr) { - // TODO - } - if(activateAutoDownload) { - // TODO - } - } - }); - builder.setNegativeButton(R.string.cancel_label, null); - builder.create().show(); - } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { diff --git a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java index 453f984e8..974a7d4bf 100644 --- a/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java +++ b/app/src/main/java/de/danoeh/antennapod/menuhandler/FeedItemMenuHandler.java @@ -3,6 +3,7 @@ package de.danoeh.antennapod.menuhandler; import android.content.Context; import android.content.Intent; import android.net.Uri; +import android.util.Log; import de.danoeh.antennapod.R; import de.danoeh.antennapod.core.feed.FeedItem; @@ -10,6 +11,7 @@ import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction; import de.danoeh.antennapod.core.gpoddernet.model.GpodnetEpisodeAction.Action; import de.danoeh.antennapod.core.preferences.GpodnetPreferences; +import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.playback.PlaybackService; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.DBWriter; @@ -54,18 +56,12 @@ public class FeedItemMenuHandler { * @param queueAccess Used for testing if the queue contains the selected item * @return Returns true if selectedItem is not null. */ - public static boolean onPrepareMenu(MenuInterface mi, - FeedItem selectedItem, boolean showExtendedMenu, LongList queueAccess) { + public static boolean onPrepareMenu(MenuInterface mi, FeedItem selectedItem, + boolean showExtendedMenu, LongList queueAccess) { if (selectedItem == null) { return false; } - DownloadRequester requester = DownloadRequester.getInstance(); boolean hasMedia = selectedItem.getMedia() != null; - boolean downloaded = hasMedia && selectedItem.getMedia().isDownloaded(); - boolean downloading = hasMedia - && requester.isDownloadingFile(selectedItem.getMedia()); - boolean notLoadedAndNotLoading = hasMedia && (!downloaded) - && (!downloading); boolean isPlaying = hasMedia && selectedItem.getState() == FeedItem.State.PLAYING; @@ -74,21 +70,14 @@ public class FeedItemMenuHandler { if (!isPlaying) { mi.setItemVisibility(R.id.skip_episode_item, false); } - if (!downloaded || isPlaying) { - mi.setItemVisibility(R.id.play_item, false); - mi.setItemVisibility(R.id.remove_item, false); - } - if (!notLoadedAndNotLoading) { - mi.setItemVisibility(R.id.download_item, false); - } - if (!(notLoadedAndNotLoading | downloading) | isPlaying) { - mi.setItemVisibility(R.id.stream_item, false); - } - if (!downloading) { - mi.setItemVisibility(R.id.cancel_download_item, false); - } boolean isInQueue = queueAccess.contains(selectedItem.getId()); + if(queueAccess.size() == 0 || queueAccess.get(0) != selectedItem.getId()) { + mi.setItemVisibility(R.id.move_to_top_item, false); + } + if(queueAccess.size() == 0 || queueAccess.get(queueAccess.size()-1) != selectedItem.getId()) { + mi.setItemVisibility(R.id.move_to_bottom_item, false); + } if (!isInQueue || isPlaying) { mi.setItemVisibility(R.id.remove_from_queue_item, false); } @@ -99,11 +88,24 @@ public class FeedItemMenuHandler { mi.setItemVisibility(R.id.share_link_item, false); } + if (!(state == FeedItem.State.NEW || state == FeedItem.State.IN_PROGRESS)) { + mi.setItemVisibility(R.id.mark_read_item, false); + } if (!(state == FeedItem.State.IN_PROGRESS || state == FeedItem.State.READ)) { mi.setItemVisibility(R.id.mark_unread_item, false); } - if (!(state == FeedItem.State.NEW || state == FeedItem.State.IN_PROGRESS)) { - mi.setItemVisibility(R.id.mark_read_item, false); + + if(selectedItem.getMedia() == null || selectedItem.getMedia().getPosition() == 0) { + mi.setItemVisibility(R.id.reset_position, false); + } + + if(false == UserPreferences.isEnableAutodownload()) { + mi.setItemVisibility(R.id.activate_auto_download, false); + mi.setItemVisibility(R.id.deactivate_auto_download, false); + } else if(selectedItem.getAutoDownload()) { + mi.setItemVisibility(R.id.activate_auto_download, false); + } else { + mi.setItemVisibility(R.id.deactivate_auto_download, false); } if (!showExtendedMenu || selectedItem.getLink() == null) { @@ -140,24 +142,14 @@ public class FeedItemMenuHandler { DownloadRequester requester = DownloadRequester.getInstance(); switch (menuItemId) { case R.id.skip_episode_item: - context.sendBroadcast(new Intent( - PlaybackService.ACTION_SKIP_CURRENT_EPISODE)); - break; - case R.id.download_item: - DBTasks.downloadFeedItems(context, selectedItem); - break; - case R.id.play_item: - DBTasks.playMedia(context, selectedItem.getMedia(), true, true, - false); + context.sendBroadcast(new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE)); break; case R.id.remove_item: DBWriter.deleteFeedMediaOfItem(context, selectedItem.getMedia().getId()); break; - case R.id.cancel_download_item: - requester.cancelDownload(context, selectedItem.getMedia()); - break; case R.id.mark_read_item: - DBWriter.markItemRead(context, selectedItem, true, true); + selectedItem.setRead(true); + DBWriter.markItemRead(context, selectedItem, true, false); if(GpodnetPreferences.loggedIn()) { FeedMedia media = selectedItem.getMedia(); GpodnetEpisodeAction actionPlay = new GpodnetEpisodeAction.Builder(selectedItem, Action.PLAY) @@ -171,7 +163,8 @@ public class FeedItemMenuHandler { } break; case R.id.mark_unread_item: - DBWriter.markItemRead(context, selectedItem, false, true); + selectedItem.setRead(false); + DBWriter.markItemRead(context, selectedItem, false, false); if(GpodnetPreferences.loggedIn()) { GpodnetEpisodeAction actionNew = new GpodnetEpisodeAction.Builder(selectedItem, Action.NEW) .currentDeviceId() @@ -180,15 +173,28 @@ public class FeedItemMenuHandler { GpodnetPreferences.enqueueEpisodeAction(actionNew); } break; + case R.id.move_to_top_item: + DBWriter.moveQueueItemToTop(context, selectedItem.getId(), true); + return true; + case R.id.move_to_bottom_item: + DBWriter.moveQueueItemToBottom(context, selectedItem.getId(), true); case R.id.add_to_queue_item: DBWriter.addQueueItem(context, selectedItem.getId()); break; case R.id.remove_from_queue_item: DBWriter.removeQueueItem(context, selectedItem, true); break; - case R.id.stream_item: - DBTasks.playMedia(context, selectedItem.getMedia(), true, true, - true); + case R.id.reset_position: + selectedItem.getMedia().setPosition(0); + DBWriter.markItemRead(context, selectedItem, false, true); + break; + case R.id.activate_auto_download: + selectedItem.setAutoDownload(true); + DBWriter.setFeedItemAutoDownload(context, selectedItem, true); + break; + case R.id.deactivate_auto_download: + selectedItem.setAutoDownload(false); + DBWriter.setFeedItemAutoDownload(context, selectedItem, false); break; case R.id.visit_website_item: Uri uri = Uri.parse(selectedItem.getLink()); @@ -201,6 +207,7 @@ public class FeedItemMenuHandler { ShareUtils.shareFeedItemLink(context, selectedItem); break; default: + Log.d(TAG, "Unknown menuItemId: " + menuItemId); return false; } // Refresh menu state diff --git a/app/src/main/res/menu/feeditem.xml b/app/src/main/res/menu/feeditem.xml deleted file mode 100644 index 8227f8b14..000000000 --- a/app/src/main/res/menu/feeditem.xml +++ /dev/null @@ -1,77 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:custom="http://schemas.android.com/apk/res-auto"> - - <item - android:id="@+id/download_item" - android:icon="?attr/av_download" - custom:showAsAction="collapseActionView" - android:title="@string/download_label"> - </item> - <item - android:id="@+id/stream_item" - android:icon="?attr/action_stream" - custom:showAsAction="collapseActionView" - android:title="@string/stream_label"> - </item> - <item - android:id="@+id/play_item" - android:icon="?attr/av_play" - custom:showAsAction="collapseActionView" - android:title="@string/play_label"> - </item> - <item - android:id="@+id/remove_item" - android:icon="?attr/content_discard" - custom:showAsAction="collapseActionView" - android:title="@string/remove_label"> - </item> - <item - android:id="@id/skip_episode_item" - android:title="@string/skip_episode_label" - custom:showAsAction="collapseActionView"> - </item> - <item - android:id="@+id/cancel_download_item" - android:icon="?attr/navigation_cancel" - custom:showAsAction="ifRoom|collapseActionView" - android:title="@string/cancel_download_label"> - </item> - <item - android:id="@+id/mark_read_item" - custom:showAsAction="collapseActionView" - android:title="@string/mark_read_label"> - </item> - <item - android:id="@+id/mark_unread_item" - custom:showAsAction="collapseActionView" - android:title="@string/mark_unread_label"> - </item> - <item - android:id="@+id/add_to_queue_item" - custom:showAsAction="collapseActionView" - android:title="@string/add_to_queue_label"> - </item> - <item - android:id="@+id/remove_from_queue_item" - custom:showAsAction="collapseActionView" - android:title="@string/remove_from_queue_label"> - </item> - <item - android:id="@+id/share_link_item" - custom:showAsAction="collapseActionView" - android:title="@string/share_link_label"> - </item> - <item - android:id="@+id/visit_website_item" - android:icon="?attr/location_web_site" - custom:showAsAction="collapseActionView" - android:title="@string/visit_website_label"> - </item> - <item - android:id="@+id/support_item" - custom:showAsAction="collapseActionView" - android:title="@string/support_label"> - </item> - -</menu>
\ No newline at end of file diff --git a/app/src/main/res/menu/feeditem_dialog.xml b/app/src/main/res/menu/feeditem_options.xml index f33b7502a..bcffd019a 100644 --- a/app/src/main/res/menu/feeditem_dialog.xml +++ b/app/src/main/res/menu/feeditem_options.xml @@ -18,6 +18,7 @@ custom:showAsAction="collapseActionView" android:title="@string/mark_unread_label"> </item> + <item android:id="@+id/add_to_queue_item" custom:showAsAction="collapseActionView" @@ -28,6 +29,7 @@ custom:showAsAction="collapseActionView" android:title="@string/remove_from_queue_label"> </item> + <item android:id="@+id/share_link_item" custom:showAsAction="collapseActionView" diff --git a/app/src/main/res/menu/feeditemlist_context.xml b/app/src/main/res/menu/feeditemlist_context.xml new file mode 100644 index 000000000..69b2c6a7a --- /dev/null +++ b/app/src/main/res/menu/feeditemlist_context.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="utf-8"?> + +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + + <item + android:id="@+id/mark_read_item" + android:menuCategory="container" + android:title="@string/mark_read_label" /> + <item + android:id="@+id/mark_unread_item" + android:menuCategory="container" + android:title="@string/mark_unread_label" /> + + <item + android:id="@+id/add_to_queue_item" + android:menuCategory="container" + android:title="@string/add_to_queue_label" /> + <item + android:id="@+id/remove_from_queue_item" + android:menuCategory="container" + android:title="@string/remove_from_queue_label" /> + + <item + android:id="@+id/reset_position" + android:menuCategory="container" + android:title="@string/reset_position" /> + + <item + android:id="@+id/activate_auto_download" + android:menuCategory="container" + android:title="@string/activate_auto_download" /> + <item + android:id="@+id/deactivate_auto_download" + android:menuCategory="container" + android:title="@string/deactivate_auto_download" /> + + <item + android:id="@+id/share_link_item" + android:menuCategory="container" + android:title="@string/share_link_label" /> + <item + android:id="@+id/visit_website_item" + android:menuCategory="container" + android:title="@string/visit_website_label" /> + + <item + android:id="@+id/support_item" + android:menuCategory="container" + android:title="@string/support_label" /> + +</menu>
\ No newline at end of file diff --git a/app/src/main/res/menu/queue_context.xml b/app/src/main/res/menu/queue_context.xml index b1589af3b..7c9f8f928 100644 --- a/app/src/main/res/menu/queue_context.xml +++ b/app/src/main/res/menu/queue_context.xml @@ -13,9 +13,9 @@ android:title="@string/mark_read_label" /> <item - android:id="@+id/reset_attributes" + android:id="@+id/mark_unread_item_item" android:menuCategory="container" - android:title="@string/reset_attributes" /> + android:title="@string/mark_unread_label" /> <item android:id="@+id/remove_from_queue_item" @@ -23,6 +23,21 @@ android:title="@string/remove_from_queue_label" /> <item + android:id="@+id/reset_position" + android:menuCategory="container" + android:title="@string/reset_position" /> + + <item + android:id="@+id/activate_auto_download" + android:menuCategory="container" + android:title="@string/activate_auto_download" /> + + <item + android:id="@+id/deactivate_auto_download" + android:menuCategory="container" + android:title="@string/deactivate_auto_download" /> + + <item android:id="@+id/move_to_bottom_item" android:menuCategory="container" android:title="@string/move_to_bottom_label" /> diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/IntList.java b/core/src/main/java/de/danoeh/antennapod/core/util/IntList.java new file mode 100644 index 000000000..673c81235 --- /dev/null +++ b/core/src/main/java/de/danoeh/antennapod/core/util/IntList.java @@ -0,0 +1,240 @@ +package de.danoeh.antennapod.core.util; + +import java.util.Arrays; + +/** + * Fast and memory efficient int list + */ +public final class IntList { + + private int[] values; + protected int size; + + /** + * Constructs an empty instance with a default initial capacity. + */ + public IntList() { + this(4); + } + + /** + * Constructs an empty instance. + * + * @param initialCapacity {@code >= 0;} initial capacity of the list + */ + public IntList(int initialCapacity) { + if(initialCapacity < 0) { + throw new IllegalArgumentException("initial capacity must be 0 or higher"); + } + values = new int[initialCapacity]; + size = 0; + } + + @Override + public int hashCode() { + int hashCode = 1; + for (int i = 0; i < size; i++) { + int value = values[i]; + hashCode = 31 * hashCode + (int)(value ^ (value >>> 32)); + } + return hashCode; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if (! (other instanceof IntList)) { + return false; + } + IntList otherList = (IntList) other; + if (size != otherList.size) { + return false; + } + for (int i = 0; i < size; i++) { + if (values[i] != otherList.values[i]) { + return false; + } + } + return true; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(size * 5 + 10); + sb.append("IntList{"); + for (int i = 0; i < size; i++) { + if (i != 0) { + sb.append(", "); + } + sb.append(values[i]); + } + sb.append("}"); + return sb.toString(); + } + + /** + * Gets the number of elements in this list. + */ + public int size() { + return size; + } + + /** + * Gets the indicated value. + * + * @param n {@code >= 0, < size();} which element + * @return the indicated element's value + */ + public int get(int n) { + if (n >= size) { + throw new IndexOutOfBoundsException("n >= size()"); + } else if(n < 0) { + throw new IndexOutOfBoundsException("n < 0"); + } + return values[n]; + } + + /** + * Sets the value at the given index. + * + * @param index the index at which to put the specified object. + * @param value the object to add. + * @return the previous element at the index. + */ + public int set(int index, int value) { + if (index >= size) { + throw new IndexOutOfBoundsException("n >= size()"); + } else if(index < 0) { + throw new IndexOutOfBoundsException("n < 0"); + } + int result = values[index]; + values[index] = value; + return result; + } + + /** + * Adds an element to the end of the list. This will increase the + * list's capacity if necessary. + * + * @param value the value to add + */ + public void add(int value) { + growIfNeeded(); + values[size++] = value; + } + + /** + * Inserts element into specified index, moving elements at and above + * that index up one. May not be used to insert at an index beyond the + * current size (that is, insertion as a last element is legal but + * no further). + * + * @param n {@code >= 0, <=size();} index of where to insert + * @param value value to insert + */ + public void insert(int n, int value) { + if (n > size) { + throw new IndexOutOfBoundsException("n > size()"); + } else if(n < 0) { + throw new IndexOutOfBoundsException("n < 0"); + } + + growIfNeeded(); + + System.arraycopy (values, n, values, n+1, size - n); + values[n] = value; + size++; + } + + /** + * Removes value from this list. + * + * @param value value to remove + * return {@code true} if the value was removed, {@code false} otherwise + */ + public boolean remove(int value) { + for (int i = 0; i < size; i++) { + if (values[i] == value) { + size--; + System.arraycopy(values, i+1, values, i, size-i); + return true; + } + } + return false; + } + + /** + * Removes an element at a given index, shifting elements at greater + * indicies down one. + * + * @param index index of element to remove + */ + public void removeIndex(int index) { + if (index >= size) { + throw new IndexOutOfBoundsException("n >= size()"); + } else if(index < 0) { + throw new IndexOutOfBoundsException("n < 0"); + } + size--; + System.arraycopy (values, index + 1, values, index, size - index); + } + + /** + * Increases size of array if needed + */ + private void growIfNeeded() { + if (size == values.length) { + // Resize. + int[] newArray = new int[size * 3 / 2 + 10]; + System.arraycopy(values, 0, newArray, 0, size); + values = newArray; + } + } + + /** + * Returns the index of the given value, or -1 if the value does not + * appear in the list. + * + * @param value value to find + * @return index of value or -1 + */ + public int indexOf(int value) { + for (int i = 0; i < size; i++) { + if (values[i] == value) { + return i; + } + } + return -1; + } + + /** + * Removes all values from this list. + */ + public void clear() { + values = new int[4]; + size = 0; + } + + + /** + * Returns true if the given value is contained in the list + * + * @param value value to look for + * @return {@code true} if this list contains {@code value}, {@code false} otherwise + */ + public boolean contains(int value) { + return indexOf(value) >= 0; + } + + /** + * Returns an array with a copy of this list's values + * + * @return array with a copy of this list's values + */ + public int[] toArray() { + return Arrays.copyOf(values, size); + + } +} diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index cf2483b08..4400fc7f2 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -121,13 +121,9 @@ <string name="enqueue_all_new">Enqueue all</string> <string name="download_all">Download all</string> <string name="skip_episode_label">Skip episode</string> - <string name="reset_attributes">Reset episode ...</string> - - <!-- reset attributes dialog --> - <string name="reset_attributes_title">Reset episode</string> - <string name="reset_attribute_auto_download">Activate auto download</string> - <string name="reset_attribute_position">Reset playback position</string> - <string name="reset_attribute_unflattr">Unflattr episode</string> + <string name="activate_auto_download">Activate auto download</string> + <string name="deactivate_auto_download">Deactivate auto download</string> + <string name="reset_position">Reset playback position</string> <!-- Download messages and labels --> <string name="download_successful">successful</string> |