summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java98
-rw-r--r--src/de/danoeh/antennapod/activity/PreferenceActivity.java42
-rw-r--r--src/de/danoeh/antennapod/adapter/DefaultFeedItemlistAdapter.java9
-rw-r--r--src/de/danoeh/antennapod/adapter/DownloadLogAdapter.java8
-rw-r--r--src/de/danoeh/antennapod/adapter/FeedlistAdapter.java19
-rw-r--r--src/de/danoeh/antennapod/adapter/InternalFeedItemlistAdapter.java8
-rw-r--r--src/de/danoeh/antennapod/adapter/MiroGuideItemlistAdapter.java6
-rw-r--r--src/de/danoeh/antennapod/feed/FeedManager.java83
-rw-r--r--src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java68
-rw-r--r--src/de/danoeh/antennapod/preferences/UserPreferences.java26
-rw-r--r--src/de/danoeh/antennapod/service/PlaybackService.java38
-rw-r--r--src/de/danoeh/antennapod/util/Converter.java1
-rw-r--r--src/de/danoeh/antennapod/util/UndoBarController.java135
-rw-r--r--src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java2
14 files changed, 423 insertions, 120 deletions
diff --git a/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java b/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java
index 89001f7f5..7269f7549 100644
--- a/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java
+++ b/src/de/danoeh/antennapod/activity/OrganizeQueueActivity.java
@@ -3,6 +3,8 @@ package de.danoeh.antennapod.activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -21,19 +23,23 @@ import de.danoeh.antennapod.feed.EventDistributor;
import de.danoeh.antennapod.feed.FeedItem;
import de.danoeh.antennapod.feed.FeedManager;
import de.danoeh.antennapod.preferences.UserPreferences;
+import de.danoeh.antennapod.util.UndoBarController;
-public class OrganizeQueueActivity extends SherlockListActivity {
+public class OrganizeQueueActivity extends SherlockListActivity implements
+ UndoBarController.UndoListener {
private static final String TAG = "OrganizeQueueActivity";
private static final int MENU_ID_ACCEPT = 2;
private OrganizeAdapter adapter;
+ private UndoBarController undoBarController;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(UserPreferences.getTheme());
super.onCreate(savedInstanceState);
setContentView(R.layout.organize_queue);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
DragSortListView listView = (DragSortListView) getListView();
listView.setDropListener(dropListener);
@@ -41,6 +47,9 @@ public class OrganizeQueueActivity extends SherlockListActivity {
adapter = new OrganizeAdapter(this);
setListAdapter(adapter);
+
+ undoBarController = new UndoBarController(findViewById(R.id.undobar),
+ this);
}
@Override
@@ -50,6 +59,13 @@ public class OrganizeQueueActivity extends SherlockListActivity {
}
@Override
+ protected void onStop() {
+ super.onStop();
+ FeedManager.getInstance().autodownloadUndownloadedItems(
+ getApplicationContext());
+ }
+
+ @Override
protected void onResume() {
super.onResume();
EventDistributor.getInstance().register(contentUpdate);
@@ -82,27 +98,24 @@ public class OrganizeQueueActivity extends SherlockListActivity {
@Override
public void remove(int which) {
FeedManager manager = FeedManager.getInstance();
- manager.removeQueueItem(OrganizeQueueActivity.this,
- (FeedItem) getListAdapter().getItem(which));
+ FeedItem item = (FeedItem) getListAdapter().getItem(which);
+ manager.removeQueueItem(OrganizeQueueActivity.this, item, false);
+ undoBarController.showUndoBar(false,
+ getString(R.string.removed_from_queue), new UndoToken(item,
+ which));
}
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
- TypedArray drawables = obtainStyledAttributes(new int[] { R.attr.navigation_accept });
- menu.add(Menu.NONE, MENU_ID_ACCEPT, Menu.NONE, R.string.confirm_label)
- .setIcon(drawables.getDrawable(0))
- .setShowAsAction(
- MenuItem.SHOW_AS_ACTION_IF_ROOM
- | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
- case MENU_ID_ACCEPT:
+ case android.R.id.home:
finish();
return true;
default:
@@ -110,11 +123,18 @@ public class OrganizeQueueActivity extends SherlockListActivity {
}
}
- /**
- * WARNING: If the PlaybackService is playing an episode from the queue,
- * this list adapter will ignore the first item in the list to make sure
- * that the position of the first queue item cannot be changed.
- */
+ @Override
+ public void onUndo(Parcelable token) {
+ // Perform the undo
+ UndoToken undoToken = (UndoToken) token;
+ FeedItem feedItem = undoToken.getFeedItem();
+ int position = undoToken.getPosition();
+
+ FeedManager manager = FeedManager.getInstance();
+ manager.addQueueItemAt(OrganizeQueueActivity.this, feedItem, position,
+ false);
+ }
+
private static class OrganizeAdapter extends BaseAdapter {
private Context context;
@@ -185,4 +205,52 @@ public class OrganizeQueueActivity extends SherlockListActivity {
}
+ private static class UndoToken implements Parcelable {
+ private long itemId;
+ private long feedId;
+ private int position;
+
+ public UndoToken(FeedItem item, int position) {
+ FeedManager manager = FeedManager.getInstance();
+ this.itemId = item.getId();
+ this.feedId = item.getFeed().getId();
+ this.position = position;
+ }
+
+ private UndoToken(Parcel in) {
+ itemId = in.readLong();
+ feedId = in.readLong();
+ position = in.readInt();
+ }
+
+ public static final Parcelable.Creator<UndoToken> CREATOR = new Parcelable.Creator<UndoToken>() {
+ public UndoToken createFromParcel(Parcel in) {
+ return new UndoToken(in);
+ }
+
+ public UndoToken[] newArray(int size) {
+ return new UndoToken[size];
+ }
+ };
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeLong(itemId);
+ out.writeLong(feedId);
+ out.writeInt(position);
+ }
+
+ public FeedItem getFeedItem() {
+ FeedManager manager = FeedManager.getInstance();
+ return manager.getFeedItem(itemId, feedId);
+ }
+
+ public int getPosition() {
+ return position;
+ }
+ }
+
}
diff --git a/src/de/danoeh/antennapod/activity/PreferenceActivity.java b/src/de/danoeh/antennapod/activity/PreferenceActivity.java
index 994cd2df6..9fcf57ac2 100644
--- a/src/de/danoeh/antennapod/activity/PreferenceActivity.java
+++ b/src/de/danoeh/antennapod/activity/PreferenceActivity.java
@@ -12,6 +12,7 @@ import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
@@ -166,13 +167,40 @@ public class PreferenceActivity extends SherlockPreferenceActivity {
return true;
}
});
-
+ buildUpdateIntervalPreference();
buildAutodownloadSelectedNetworsPreference();
setSelectedNetworksEnabled(UserPreferences
.isEnableAutodownloadWifiFilter());
}
+ private void buildUpdateIntervalPreference() {
+ ListPreference pref = (ListPreference) findPreference(UserPreferences.PREF_UPDATE_INTERVAL);
+ String[] values = getResources().getStringArray(
+ R.array.update_intervall_values);
+ String[] entries = new String[values.length];
+ for (int x = 0; x < values.length; x++) {
+ Integer v = Integer.parseInt(values[x]);
+ switch (v) {
+ case 0:
+ entries[x] = getString(R.string.pref_update_interval_hours_manual);
+ break;
+ case 1:
+ entries[x] = v
+ + " "
+ + getString(R.string.pref_update_interval_hours_singular);
+ break;
+ default:
+ entries[x] = v + " "
+ + getString(R.string.pref_update_interval_hours_plural);
+ break;
+
+ }
+ }
+ pref.setEntries(entries);
+
+ }
+
private void setSelectedNetworksEnabled(boolean b) {
if (selectedNetworks != null) {
for (Preference p : selectedNetworks) {
@@ -205,9 +233,15 @@ public class PreferenceActivity extends SherlockPreferenceActivity {
}
private void setEpisodeCacheSizeText(int cacheSize) {
- findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE).setSummary(
- Integer.toString(cacheSize)
- + getString(R.string.episodes_suffix));
+ String s;
+ if (cacheSize == getResources().getInteger(
+ R.integer.episode_cache_size_unlimited)) {
+ s = getString(R.string.pref_episode_cache_unlimited);
+ } else {
+ s = Integer.toString(cacheSize)
+ + getString(R.string.episodes_suffix);
+ }
+ findPreference(UserPreferences.PREF_EPISODE_CACHE_SIZE).setSummary(s);
}
private void setDataFolderText() {
diff --git a/src/de/danoeh/antennapod/adapter/DefaultFeedItemlistAdapter.java b/src/de/danoeh/antennapod/adapter/DefaultFeedItemlistAdapter.java
index b603bb54f..2b49795c3 100644
--- a/src/de/danoeh/antennapod/adapter/DefaultFeedItemlistAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/DefaultFeedItemlistAdapter.java
@@ -1,7 +1,5 @@
package de.danoeh.antennapod.adapter;
-import java.text.DateFormat;
-
import android.content.Context;
import android.content.res.TypedArray;
import android.text.format.DateUtils;
@@ -75,10 +73,9 @@ public class DefaultFeedItemlistAdapter extends BaseAdapter {
holder.title.setText(item.getTitle());
holder.published.setText(convertView.getResources().getString(
R.string.published_prefix)
- + DateUtils.formatSameDayTime(item.getPubDate().getTime(),
- System.currentTimeMillis(), DateFormat.MEDIUM,
- DateFormat.SHORT));
-
+ + DateUtils.getRelativeTimeSpanString(
+ item.getPubDate().getTime(),
+ System.currentTimeMillis(), 0, 0));
if (item.getMedia() == null) {
holder.type.setVisibility(View.GONE);
holder.lenSize.setVisibility(View.GONE);
diff --git a/src/de/danoeh/antennapod/adapter/DownloadLogAdapter.java b/src/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
index c0ccdc7fe..f97210cf3 100644
--- a/src/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/DownloadLogAdapter.java
@@ -1,7 +1,5 @@
package de.danoeh.antennapod.adapter;
-import java.text.DateFormat;
-
import android.content.Context;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
@@ -60,9 +58,9 @@ public class DownloadLogAdapter extends BaseAdapter {
} else {
holder.title.setText(R.string.download_log_title_unknown);
}
- holder.date.setText(DateUtils.formatSameDayTime(status
- .getCompletionDate().getTime(), System.currentTimeMillis(),
- DateFormat.SHORT, DateFormat.SHORT));
+ holder.date.setText(DateUtils.getRelativeTimeSpanString(
+ status.getCompletionDate().getTime(),
+ System.currentTimeMillis(), 0, 0));
if (status.isSuccessful()) {
holder.successful.setTextColor(convertView.getResources().getColor(
R.color.download_success_green));
diff --git a/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java b/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java
index d7ea0c160..03b46cce5 100644
--- a/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/FeedlistAdapter.java
@@ -1,7 +1,5 @@
package de.danoeh.antennapod.adapter;
-import java.text.DateFormat;
-
import android.content.Context;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
@@ -77,16 +75,21 @@ public class FeedlistAdapter extends BaseAdapter {
}
holder.title.setText(feed.getTitle());
+ int numOfItems = feed.getNumOfItems(true);
if (DownloadRequester.getInstance().isDownloadingFile(feed)) {
holder.lastUpdate.setText(R.string.refreshing_label);
} else {
- holder.lastUpdate.setText(convertView.getResources().getString(
- R.string.last_update_prefix)
- + DateUtils.formatSameDayTime(feed.getLastUpdate()
- .getTime(), System.currentTimeMillis(),
- DateFormat.MEDIUM, DateFormat.SHORT));
+ if (numOfItems > 0) {
+ holder.lastUpdate.setText(convertView.getResources().getString(
+ R.string.most_recent_prefix)
+ + DateUtils.getRelativeTimeSpanString(
+ feed.getItemAtIndex(true, 0).getPubDate().getTime(),
+ System.currentTimeMillis(), 0, 0));
+ } else {
+ holder.lastUpdate.setText("");
+ }
}
- holder.numberOfEpisodes.setText(feed.getNumOfItems(true)
+ holder.numberOfEpisodes.setText(numOfItems
+ convertView.getResources()
.getString(R.string.episodes_suffix));
diff --git a/src/de/danoeh/antennapod/adapter/InternalFeedItemlistAdapter.java b/src/de/danoeh/antennapod/adapter/InternalFeedItemlistAdapter.java
index 7b898385e..e5c12f018 100644
--- a/src/de/danoeh/antennapod/adapter/InternalFeedItemlistAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/InternalFeedItemlistAdapter.java
@@ -1,7 +1,5 @@
package de.danoeh.antennapod.adapter;
-import java.text.DateFormat;
-
import android.content.Context;
import android.content.res.TypedArray;
import android.text.format.DateUtils;
@@ -122,9 +120,9 @@ public class InternalFeedItemlistAdapter extends DefaultFeedItemlistAdapter {
holder.published.setText(convertView.getResources().getString(
R.string.published_prefix)
- + DateUtils.formatSameDayTime(item.getPubDate().getTime(),
- System.currentTimeMillis(), DateFormat.MEDIUM,
- DateFormat.SHORT));
+ + DateUtils.getRelativeTimeSpanString(
+ item.getPubDate().getTime(),
+ System.currentTimeMillis(), 0, 0));
FeedMedia media = item.getMedia();
if (media == null) {
diff --git a/src/de/danoeh/antennapod/adapter/MiroGuideItemlistAdapter.java b/src/de/danoeh/antennapod/adapter/MiroGuideItemlistAdapter.java
index 4cee0a64a..f12345f84 100644
--- a/src/de/danoeh/antennapod/adapter/MiroGuideItemlistAdapter.java
+++ b/src/de/danoeh/antennapod/adapter/MiroGuideItemlistAdapter.java
@@ -1,6 +1,5 @@
package de.danoeh.antennapod.adapter;
-import java.text.DateFormat;
import java.util.List;
import android.content.Context;
@@ -42,9 +41,8 @@ public class MiroGuideItemlistAdapter extends ArrayAdapter<MiroGuideItem> {
holder.title.setText(item.getName());
if (item.getDate() != null) {
- holder.date.setText(DateUtils.formatSameDayTime(item.getDate()
- .getTime(), System.currentTimeMillis(), DateFormat.SHORT,
- DateFormat.SHORT));
+ holder.date.setText(DateUtils.getRelativeTimeSpanString(
+ item.getDate().getTime(), System.currentTimeMillis(), 0, 0));
holder.date.setVisibility(View.VISIBLE);
} else {
holder.date.setVisibility(View.GONE);
diff --git a/src/de/danoeh/antennapod/feed/FeedManager.java b/src/de/danoeh/antennapod/feed/FeedManager.java
index bdffdc667..a1a8c6c32 100644
--- a/src/de/danoeh/antennapod/feed/FeedManager.java
+++ b/src/de/danoeh/antennapod/feed/FeedManager.java
@@ -10,6 +10,7 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.Comparator;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
@@ -676,8 +677,12 @@ public class FeedManager {
int deletedEpisodes = performAutoCleanup(context,
getPerformAutoCleanupArgs(undownloadedEpisodes));
int episodeSpaceLeft = undownloadedEpisodes;
- if (UserPreferences.getEpisodeCacheSize() < downloadedEpisodes
- + undownloadedEpisodes) {
+ boolean cacheIsUnlimited = UserPreferences.getEpisodeCacheSize() == UserPreferences
+ .getEpisodeCacheSizeUnlimited();
+
+ if (!cacheIsUnlimited
+ && UserPreferences.getEpisodeCacheSize() < downloadedEpisodes
+ + undownloadedEpisodes) {
episodeSpaceLeft = UserPreferences.getEpisodeCacheSize()
- (downloadedEpisodes - deletedEpisodes);
}
@@ -732,7 +737,9 @@ public class FeedManager {
* that the number of episodes fits into the episode cache.
* */
private int getPerformAutoCleanupArgs(final int episodeNumber) {
- if (episodeNumber >= 0) {
+ if (episodeNumber >= 0
+ && UserPreferences.getEpisodeCacheSize() != UserPreferences
+ .getEpisodeCacheSizeUnlimited()) {
int downloadedEpisodes = getNumberOfDownloadedEpisodes();
if (downloadedEpisodes + episodeNumber >= UserPreferences
.getEpisodeCacheSize()) {
@@ -760,24 +767,45 @@ public class FeedManager {
* @return The number of episodes that were actually deleted
* */
private int performAutoCleanup(Context context, final int episodeNumber) {
- int counter = 0;
- if (episodeNumber > 0) {
- int episodesLeft = episodeNumber;
- feedloop: for (Feed feed : feeds) {
- for (FeedItem item : feed.getItems()) {
- if (item.hasMedia() && item.getMedia().isDownloaded()) {
- if (!isInQueue(item) && item.isRead()) {
- deleteFeedMedia(context, item.getMedia());
- counter++;
- episodesLeft--;
- if (episodesLeft == 0) {
- break feedloop;
- }
- }
- }
+ List<FeedItem> candidates = new ArrayList<FeedItem>();
+ List<FeedItem> delete;
+ for (Feed feed : feeds) {
+ for (FeedItem item : feed.getItems()) {
+ if (item.hasMedia() && item.getMedia().isDownloaded()
+ && !isInQueue(item) && item.isRead()) {
+ candidates.add(item);
}
}
}
+
+ Collections.sort(candidates, new Comparator<FeedItem>() {
+ @Override
+ public int compare(FeedItem lhs, FeedItem rhs) {
+ Date l = lhs.getMedia().getPlaybackCompletionDate();
+ Date r = rhs.getMedia().getPlaybackCompletionDate();
+
+ if (l == null) {
+ l = new Date(0);
+ }
+ if (r == null) {
+ r = new Date(0);
+ }
+ return l.compareTo(r);
+ }
+ });
+
+ if (candidates.size() > episodeNumber) {
+ delete = candidates.subList(0, episodeNumber);
+ } else {
+ delete = candidates;
+ }
+
+ for (FeedItem item : delete) {
+ deleteFeedMedia(context, item.getMedia());
+ }
+
+ int counter = delete.size();
+
if (AppConfig.DEBUG)
Log.d(TAG, String.format(
"Auto-delete deleted %d episodes (%d requested)", counter,
@@ -970,7 +998,8 @@ public class FeedManager {
}
/** Removes a FeedItem from the queue. */
- public void removeQueueItem(final Context context, FeedItem item) {
+ public void removeQueueItem(final Context context, FeedItem item,
+ final boolean performAutoDownload) {
boolean removed = queue.remove(item);
if (removed) {
dbExec.execute(new Runnable() {
@@ -985,12 +1014,14 @@ public class FeedManager {
});
}
- new Thread() {
- @Override
- public void run() {
- autodownloadUndownloadedItems(context);
- }
- }.start();
+ if (performAutoDownload) {
+ new Thread() {
+ @Override
+ public void run() {
+ autodownloadUndownloadedItems(context);
+ }
+ }.start();
+ }
eventDist.sendQueueUpdateBroadcast();
}
@@ -1980,4 +2011,4 @@ public class FeedManager {
}
}
-} \ No newline at end of file
+}
diff --git a/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
index a1dfa51d4..10f43718f 100644
--- a/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/src/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
@@ -9,7 +9,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
-import android.graphics.Picture;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@@ -23,10 +22,9 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.webkit.WebChromeClient;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebView;
-import android.webkit.WebView.PictureListener;
+import android.webkit.WebViewClient;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragment;
@@ -101,7 +99,6 @@ public class ItemDescriptionFragment extends SherlockFragment {
if (AppConfig.DEBUG)
Log.d(TAG, "Creating view");
webvDescription = new WebView(getActivity());
-
if (UserPreferences.getTheme() == R.style.Theme_AntennaPod_Dark) {
if (Build.VERSION.SDK_INT >= 11
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
@@ -115,6 +112,32 @@ public class ItemDescriptionFragment extends SherlockFragment {
LayoutAlgorithm.NARROW_COLUMNS);
webvDescription.getSettings().setLoadWithOverviewMode(true);
webvDescription.setOnLongClickListener(webViewLongClickListener);
+ webvDescription.setWebViewClient(new WebViewClient() {
+
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ startActivity(intent);
+ return true;
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Page finished");
+ // Restoring the scroll position might not always work
+ view.postDelayed(new Runnable() {
+
+ @Override
+ public void run() {
+ restoreFromPreference();
+ }
+
+ }, 50);
+ }
+
+ });
registerForContextMenu(webvDescription);
return webvDescription;
}
@@ -336,7 +359,6 @@ public class ItemDescriptionFragment extends SherlockFragment {
String data;
- @SuppressWarnings("deprecation")
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
@@ -350,16 +372,6 @@ public class ItemDescriptionFragment extends SherlockFragment {
if (AppConfig.DEBUG)
Log.d(TAG, "Webview loaded");
webViewLoader = null;
- webvDescription.setPictureListener(new PictureListener() {
-
- @Override
- @Deprecated
- public void onNewPicture(WebView view, Picture picture) {
- restoreFromPreference();
-
- }
- });
-
}
@Override
@@ -434,17 +446,21 @@ public class ItemDescriptionFragment extends SherlockFragment {
if (saveState) {
if (AppConfig.DEBUG)
Log.d(TAG, "Restoring from preferences");
- SharedPreferences prefs = getActivity().getSharedPreferences(PREF,
- Activity.MODE_PRIVATE);
- String id = prefs.getString(PREF_PLAYABLE_ID, "");
- int scrollY = prefs.getInt(PREF_SCROLL_Y, -1);
- if (scrollY != -1 && media != null
- && id.equals(media.getIdentifier().toString())
- && webvDescription != null) {
- if (AppConfig.DEBUG)
- Log.d(TAG, "Restored scroll Position: " + scrollY);
- webvDescription.scrollTo(webvDescription.getScrollX(), scrollY);
- return true;
+ Activity activity = getActivity();
+ if (activity != null) {
+ SharedPreferences prefs = activity.getSharedPreferences(
+ PREF, Activity.MODE_PRIVATE);
+ String id = prefs.getString(PREF_PLAYABLE_ID, "");
+ int scrollY = prefs.getInt(PREF_SCROLL_Y, -1);
+ if (scrollY != -1 && media != null
+ && id.equals(media.getIdentifier().toString())
+ && webvDescription != null) {
+ if (AppConfig.DEBUG)
+ Log.d(TAG, "Restored scroll Position: " + scrollY);
+ webvDescription.scrollTo(webvDescription.getScrollX(),
+ scrollY);
+ return true;
+ }
}
}
return false;
diff --git a/src/de/danoeh/antennapod/preferences/UserPreferences.java b/src/de/danoeh/antennapod/preferences/UserPreferences.java
index bd491a5cf..f2f35f41d 100644
--- a/src/de/danoeh/antennapod/preferences/UserPreferences.java
+++ b/src/de/danoeh/antennapod/preferences/UserPreferences.java
@@ -42,6 +42,8 @@ public class UserPreferences implements
private static final String PREF_AUTODL_SELECTED_NETWORKS = "prefAutodownloadSelectedNetworks";
public static final String PREF_EPISODE_CACHE_SIZE = "prefEpisodeCacheSize";
+ private static int EPISODE_CACHE_SIZE_UNLIMITED = -1;
+
private static UserPreferences instance;
private Context context;
@@ -86,6 +88,8 @@ public class UserPreferences implements
private void loadPreferences() {
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(context);
+ EPISODE_CACHE_SIZE_UNLIMITED = context.getResources().getInteger(
+ R.integer.episode_cache_size_unlimited);
pauseOnHeadsetDisconnect = sp.getBoolean(
PREF_PAUSE_ON_HEADSET_DISCONNECT, true);
followQueue = sp.getBoolean(PREF_FOLLOW_QUEUE, false);
@@ -101,7 +105,7 @@ public class UserPreferences implements
PREF_ENABLE_AUTODL_WIFI_FILTER, false);
autodownloadSelectedNetworks = StringUtils.split(
sp.getString(PREF_AUTODL_SELECTED_NETWORKS, ""), ',');
- episodeCacheSize = Integer.valueOf(sp.getString(
+ episodeCacheSize = readEpisodeCacheSize(sp.getString(
PREF_EPISODE_CACHE_SIZE, "20"));
enableAutodownload = sp.getBoolean(PREF_ENABLE_AUTODL, false);
}
@@ -122,6 +126,15 @@ public class UserPreferences implements
return TimeUnit.HOURS.toMillis(hours);
}
+ private int readEpisodeCacheSize(String valueFromPrefs) {
+ if (valueFromPrefs.equals(context
+ .getString(R.string.pref_episode_cache_unlimited))) {
+ return EPISODE_CACHE_SIZE_UNLIMITED;
+ } else {
+ return Integer.valueOf(valueFromPrefs);
+ }
+ }
+
private static void instanceAvailable() {
if (instance == null) {
throw new IllegalStateException(
@@ -179,6 +192,15 @@ public class UserPreferences implements
return instance.autodownloadSelectedNetworks;
}
+ public static int getEpisodeCacheSizeUnlimited() {
+ return EPISODE_CACHE_SIZE_UNLIMITED;
+ }
+
+ /**
+ * Returns the capacity of the episode cache. This method will return the
+ * negative integer EPISODE_CACHE_SIZE_UNLIMITED if the cache size is set to
+ * 'unlimited'.
+ */
public static int getEpisodeCacheSize() {
instanceAvailable();
return instance.episodeCacheSize;
@@ -224,7 +246,7 @@ public class UserPreferences implements
autodownloadSelectedNetworks = StringUtils.split(
sp.getString(PREF_AUTODL_SELECTED_NETWORKS, ""), ',');
} else if (key.equals(PREF_EPISODE_CACHE_SIZE)) {
- episodeCacheSize = Integer.valueOf(sp.getString(
+ episodeCacheSize = readEpisodeCacheSize(sp.getString(
PREF_EPISODE_CACHE_SIZE, "20"));
} else if (key.equals(PREF_ENABLE_AUTODL)) {
enableAutodownload = sp.getBoolean(PREF_ENABLE_AUTODL, false);
diff --git a/src/de/danoeh/antennapod/service/PlaybackService.java b/src/de/danoeh/antennapod/service/PlaybackService.java
index 11da79015..409ac6b48 100644
--- a/src/de/danoeh/antennapod/service/PlaybackService.java
+++ b/src/de/danoeh/antennapod/service/PlaybackService.java
@@ -73,8 +73,8 @@ public class PlaybackService extends Service {
public static final String EXTRA_PREPARE_IMMEDIATELY = "extra.de.danoeh.antennapod.service.prepareImmediately";
public static final String ACTION_PLAYER_STATUS_CHANGED = "action.de.danoeh.antennapod.service.playerStatusChanged";
- private static final String AVRCP_ACTION_PLAYER_STATUS_CHANGED= "com.android.music.playstatechanged";
-
+ private static final String AVRCP_ACTION_PLAYER_STATUS_CHANGED = "com.android.music.playstatechanged";
+
public static final String ACTION_PLAYER_NOTIFICATION = "action.de.danoeh.antennapod.service.playerNotification";
public static final String EXTRA_NOTIFICATION_CODE = "extra.de.danoeh.antennapod.service.notificationCode";
public static final String EXTRA_NOTIFICATION_TYPE = "extra.de.danoeh.antennapod.service.notificationType";
@@ -363,13 +363,15 @@ public class PlaybackService extends Service {
}
// Intent values appear to be valid
// check if already playing and playbackType is the same
- } else if (media == null || playable != media
+ } else if (media == null
+ || !playable.getIdentifier().equals(media.getIdentifier())
|| playbackType != shouldStream) {
pause(true, false);
player.reset();
sendNotificationBroadcast(NOTIFICATION_TYPE_RELOAD, 0);
if (media == null
- || playable.getIdentifier() != media.getIdentifier()) {
+ || !playable.getIdentifier().equals(
+ media.getIdentifier())) {
media = playable;
}
@@ -730,7 +732,7 @@ public class PlaybackService extends Service {
isInQueue = media instanceof FeedMedia
&& manager.isInQueue(((FeedMedia) media).getItem());
if (isInQueue) {
- manager.removeQueueItem(PlaybackService.this, item);
+ manager.removeQueueItem(PlaybackService.this, item, true);
}
manager.addItemToPlaybackHistory(PlaybackService.this, item);
manager.setFeedMedia(PlaybackService.this, (FeedMedia) media);
@@ -1226,23 +1228,23 @@ public class PlaybackService extends Service {
private void bluetoothNotifyChange() {
boolean isPlaying = false;
-
+
if (status == PlayerStatus.PLAYING) {
isPlaying = true;
}
-
- Intent i = new Intent(AVRCP_ACTION_PLAYER_STATUS_CHANGED);
- i.putExtra("id", 1);
- i.putExtra("artist", "");
- i.putExtra("album", media.getFeedTitle());
- i.putExtra("track", media.getEpisodeTitle());
- i.putExtra("playing", isPlaying);
- i.putExtra("ListSize", manager.getQueueSize(false));
- i.putExtra("duration", media.getDuration());
- i.putExtra("position", media.getPosition());
- sendBroadcast(i);
+
+ Intent i = new Intent(AVRCP_ACTION_PLAYER_STATUS_CHANGED);
+ i.putExtra("id", 1);
+ i.putExtra("artist", "");
+ i.putExtra("album", media.getFeedTitle());
+ i.putExtra("track", media.getEpisodeTitle());
+ i.putExtra("playing", isPlaying);
+ i.putExtra("ListSize", manager.getQueueSize(false));
+ i.putExtra("duration", media.getDuration());
+ i.putExtra("position", media.getPosition());
+ sendBroadcast(i);
}
-
+
/**
* Pauses playback when the headset is disconnected and the preference is
* set
diff --git a/src/de/danoeh/antennapod/util/Converter.java b/src/de/danoeh/antennapod/util/Converter.java
index f02e8ea69..6ef47af31 100644
--- a/src/de/danoeh/antennapod/util/Converter.java
+++ b/src/de/danoeh/antennapod/util/Converter.java
@@ -78,4 +78,5 @@ public final class Converter {
return String.format("%02d:%02d", h, m);
}
+
}
diff --git a/src/de/danoeh/antennapod/util/UndoBarController.java b/src/de/danoeh/antennapod/util/UndoBarController.java
new file mode 100644
index 000000000..e726717a1
--- /dev/null
+++ b/src/de/danoeh/antennapod/util/UndoBarController.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2012 Roman Nurik
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package de.danoeh.antennapod.util;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewPropertyAnimator;
+import android.widget.TextView;
+
+import de.danoeh.antennapod.R;
+
+public class UndoBarController {
+ private View mBarView;
+ private TextView mMessageView;
+ private ViewPropertyAnimator mBarAnimator;
+ private Handler mHideHandler = new Handler();
+
+ private UndoListener mUndoListener;
+
+ // State objects
+ private Parcelable mUndoToken;
+ private CharSequence mUndoMessage;
+
+ public interface UndoListener {
+ void onUndo(Parcelable token);
+ }
+
+ public UndoBarController(View undoBarView, UndoListener undoListener) {
+ mBarView = undoBarView;
+ mBarAnimator = mBarView.animate();
+ mUndoListener = undoListener;
+
+ mMessageView = (TextView) mBarView.findViewById(R.id.undobar_message);
+ mBarView.findViewById(R.id.undobar_button)
+ .setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ hideUndoBar(false);
+ mUndoListener.onUndo(mUndoToken);
+ }
+ });
+
+ hideUndoBar(true);
+ }
+
+ public void showUndoBar(boolean immediate, CharSequence message, Parcelable undoToken) {
+ mUndoToken = undoToken;
+ mUndoMessage = message;
+ mMessageView.setText(mUndoMessage);
+
+ mHideHandler.removeCallbacks(mHideRunnable);
+ mHideHandler.postDelayed(mHideRunnable,
+ mBarView.getResources().getInteger(R.integer.undobar_hide_delay));
+
+ mBarView.setVisibility(View.VISIBLE);
+ if (immediate) {
+ mBarView.setAlpha(1);
+ } else {
+ mBarAnimator.cancel();
+ mBarAnimator
+ .alpha(1)
+ .setDuration(
+ mBarView.getResources()
+ .getInteger(android.R.integer.config_shortAnimTime))
+ .setListener(null);
+ }
+ }
+
+ public void hideUndoBar(boolean immediate) {
+ mHideHandler.removeCallbacks(mHideRunnable);
+ if (immediate) {
+ mBarView.setVisibility(View.GONE);
+ mBarView.setAlpha(0);
+ mUndoMessage = null;
+ mUndoToken = null;
+
+ } else {
+ mBarAnimator.cancel();
+ mBarAnimator
+ .alpha(0)
+ .setDuration(mBarView.getResources()
+ .getInteger(android.R.integer.config_shortAnimTime))
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mBarView.setVisibility(View.GONE);
+ mUndoMessage = null;
+ mUndoToken = null;
+ }
+ });
+ }
+ }
+
+ public void onSaveInstanceState(Bundle outState) {
+ outState.putCharSequence("undo_message", mUndoMessage);
+ outState.putParcelable("undo_token", mUndoToken);
+ }
+
+ public void onRestoreInstanceState(Bundle savedInstanceState) {
+ if (savedInstanceState != null) {
+ mUndoMessage = savedInstanceState.getCharSequence("undo_message");
+ mUndoToken = savedInstanceState.getParcelable("undo_token");
+
+ if (mUndoToken != null || !TextUtils.isEmpty(mUndoMessage)) {
+ showUndoBar(true, mUndoMessage, mUndoToken);
+ }
+ }
+ }
+
+ private Runnable mHideRunnable = new Runnable() {
+ @Override
+ public void run() {
+ hideUndoBar(false);
+ }
+ };
+}
diff --git a/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java b/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java
index 64bcb1cf2..472124bf7 100644
--- a/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java
+++ b/src/de/danoeh/antennapod/util/menuhandler/FeedItemMenuHandler.java
@@ -140,7 +140,7 @@ public class FeedItemMenuHandler {
manager.addQueueItem(context, selectedItem);
break;
case R.id.remove_from_queue_item:
- manager.removeQueueItem(context, selectedItem);
+ manager.removeQueueItem(context, selectedItem, true);
break;
case R.id.stream_item:
manager.playMedia(context, selectedItem.getMedia(), true, true,