diff options
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod/dialog')
6 files changed, 935 insertions, 0 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java new file mode 100644 index 000000000..bdb2d68ba --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/AuthenticationDialog.java @@ -0,0 +1,89 @@ +package de.danoeh.antennapod.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import de.danoeh.antennapod.R; + +/** + * Displays a dialog with a username and password text field and an optional checkbox to save username and preferences. + */ +public abstract class AuthenticationDialog extends Dialog { + + private final int titleRes; + private final boolean enableUsernameField; + private final boolean showSaveCredentialsCheckbox; + private final String usernameInitialValue; + private final String passwordInitialValue; + + public AuthenticationDialog(Context context, int titleRes, boolean enableUsernameField, boolean showSaveCredentialsCheckbox, String usernameInitialValue, String passwordInitialValue) { + super(context); + this.titleRes = titleRes; + this.enableUsernameField = enableUsernameField; + this.showSaveCredentialsCheckbox = showSaveCredentialsCheckbox; + this.usernameInitialValue = usernameInitialValue; + this.passwordInitialValue = passwordInitialValue; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.authentication_dialog); + final EditText etxtUsername = (EditText) findViewById(R.id.etxtUsername); + final EditText etxtPassword = (EditText) findViewById(R.id.etxtPassword); + final CheckBox saveUsernamePassword = (CheckBox) findViewById(R.id.chkSaveUsernamePassword); + final Button butConfirm = (Button) findViewById(R.id.butConfirm); + final Button butCancel = (Button) findViewById(R.id.butCancel); + + if (titleRes != 0) { + setTitle(titleRes); + } else { + requestWindowFeature(Window.FEATURE_NO_TITLE); + } + etxtUsername.setEnabled(enableUsernameField); + if (showSaveCredentialsCheckbox) { + saveUsernamePassword.setVisibility(View.VISIBLE); + } else { + saveUsernamePassword.setVisibility(View.GONE); + } + if (usernameInitialValue != null) { + etxtUsername.setText(usernameInitialValue); + } + if (passwordInitialValue != null) { + etxtPassword.setText(passwordInitialValue); + } + setOnCancelListener(new OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + onCancelled(); + } + }); + butCancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + cancel(); + } + }); + butConfirm.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onConfirmed(etxtUsername.getText().toString(), + etxtPassword.getText().toString(), + showSaveCredentialsCheckbox && saveUsernamePassword.isChecked()); + dismiss(); + } + }); + } + + protected void onCancelled() { + + } + + protected abstract void onConfirmed(String username, String password, boolean saveUsernamePassword); +} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java new file mode 100644 index 000000000..1585f9b86 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/AutoFlattrPreferenceDialog.java @@ -0,0 +1,107 @@ +package de.danoeh.antennapod.dialog; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.view.View; +import android.widget.CheckBox; +import android.widget.SeekBar; +import android.widget.TextView; + +import org.apache.commons.lang3.Validate; + +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.preferences.UserPreferences; + +/** + * Creates a new AlertDialog that displays preferences for auto-flattring to the user. + */ +public class AutoFlattrPreferenceDialog { + + private AutoFlattrPreferenceDialog() { + } + + public static void newAutoFlattrPreferenceDialog(final Activity activity, final AutoFlattrPreferenceDialogInterface callback) { + Validate.notNull(activity); + Validate.notNull(callback); + + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + + @SuppressLint("InflateParams") View view = activity.getLayoutInflater().inflate(R.layout.autoflattr_preference_dialog, null); + final CheckBox chkAutoFlattr = (CheckBox) view.findViewById(R.id.chkAutoFlattr); + final SeekBar skbPercent = (SeekBar) view.findViewById(R.id.skbPercent); + final TextView txtvStatus = (TextView) view.findViewById(R.id.txtvStatus); + + chkAutoFlattr.setChecked(UserPreferences.isAutoFlattr()); + skbPercent.setEnabled(chkAutoFlattr.isChecked()); + txtvStatus.setEnabled(chkAutoFlattr.isChecked()); + + final int initialValue = (int) (UserPreferences.getAutoFlattrPlayedDurationThreshold() * 100.0f); + setStatusMsgText(activity, txtvStatus, initialValue); + skbPercent.setProgress(initialValue); + + chkAutoFlattr.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + skbPercent.setEnabled(chkAutoFlattr.isChecked()); + txtvStatus.setEnabled(chkAutoFlattr.isChecked()); + } + }); + + skbPercent.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + setStatusMsgText(activity, txtvStatus, progress); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + + } + }); + + builder.setTitle(R.string.pref_auto_flattr_title) + .setView(view) + .setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + float progDouble = ((float) skbPercent.getProgress()) / 100.0f; + callback.onConfirmed(chkAutoFlattr.isChecked(), progDouble); + dialog.dismiss(); + } + }) + .setNegativeButton(R.string.cancel_label, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + callback.onCancelled(); + dialog.dismiss(); + } + }) + .setCancelable(false).show(); + } + + private static void setStatusMsgText(Context context, TextView txtvStatus, int progress) { + if (progress == 0) { + txtvStatus.setText(R.string.auto_flattr_ater_beginning); + } else if (progress == 100) { + txtvStatus.setText(R.string.auto_flattr_ater_end); + } else { + txtvStatus.setText(context.getString(R.string.auto_flattr_after_percent, progress)); + } + } + + public static interface AutoFlattrPreferenceDialogInterface { + public void onCancelled(); + + public void onConfirmed(boolean autoFlattrEnabled, float autoFlattrValue); + } + + +} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/FeedItemDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/FeedItemDialog.java new file mode 100644 index 000000000..613cd1fec --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/FeedItemDialog.java @@ -0,0 +1,434 @@ +package de.danoeh.antennapod.dialog; + +import android.annotation.TargetApi; +import android.app.Dialog; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.content.res.TypedArray; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Bundle; +import android.support.v7.widget.PopupMenu; +import android.text.TextUtils; +import android.util.Log; +import android.util.TypedValue; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.ImageButton; +import android.widget.TextView; +import android.widget.Toast; + +import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.commons.lang3.Validate; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; + +import de.danoeh.antennapod.BuildConfig; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.adapter.DefaultActionButtonCallback; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.feed.FeedMedia; +import de.danoeh.antennapod.core.preferences.UserPreferences; +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.QueueAccess; +import de.danoeh.antennapod.core.util.ShownotesProvider; +import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; + +/** + * Shows information about a specific FeedItem and provides actions like playing, downloading, etc. + */ +public class FeedItemDialog extends Dialog { + private static final String TAG = "FeedItemDialog"; + + private FeedItem item; + private QueueAccess queue; + + private View header; + private TextView txtvTitle; + private WebView webvDescription; + private ImageButton butAction1; + private ImageButton butAction2; + private ImageButton butMore; + private PopupMenu popupMenu; + + public static FeedItemDialog newInstance(Context context, FeedItemDialogSavedInstance savedInstance) { + Validate.notNull(savedInstance); + FeedItemDialog dialog = newInstance(context, savedInstance.item, savedInstance.queueAccess); + if (savedInstance.isShowing) { + dialog.show(); + } + return dialog; + } + + public static FeedItemDialog newInstance(Context context, FeedItem item, QueueAccess queue) { + if (useDarkThemeWorkAround()) { + return new FeedItemDialog(context, R.style.Theme_AntennaPod_Dark, item, queue); + } else { + return new FeedItemDialog(context, item, queue); + } + } + + public FeedItemDialog(Context context, int theme, FeedItem item, QueueAccess queue) { + super(context, theme); + Validate.notNull(item); + Validate.notNull(queue); + this.item = item; + this.queue = queue; + } + + private FeedItemDialog(Context context, FeedItem item, QueueAccess queue) { + this(context, 0, item, queue); + } + + /** + * Returns true if the dialog should use a dark theme. This has to be done on Gingerbread devices + * because dialogs are only available in a dark theme. + */ + private static boolean useDarkThemeWorkAround() { + return Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1 + && UserPreferences.getTheme() != R.style.Theme_AntennaPod_Dark; + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + setContentView(R.layout.feeditem_dialog); + + txtvTitle = (TextView) findViewById(R.id.txtvTitle); + header = findViewById(R.id.header); + webvDescription = (WebView) findViewById(R.id.webview); + butAction1 = (ImageButton) findViewById(R.id.butAction1); + butAction2 = (ImageButton) findViewById(R.id.butAction2); + butMore = (ImageButton) findViewById(R.id.butMoreActions); + popupMenu = new PopupMenu(getContext(), butMore); + + webvDescription.setWebViewClient(new WebViewClient()); + + if (Build.VERSION.SDK_INT >= 14) { // ellipsize is causing problems on old versions, see #448 + txtvTitle.setEllipsize(TextUtils.TruncateAt.END); + } + + txtvTitle.setText(item.getTitle()); + + 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) { + webvDescription.setLayerType(View.LAYER_TYPE_SOFTWARE, null); + } + webvDescription.setBackgroundColor(getContext().getResources().getColor( + R.color.black)); + } + webvDescription.getSettings().setUseWideViewPort(false); + webvDescription.getSettings().setLayoutAlgorithm( + WebSettings.LayoutAlgorithm.NARROW_COLUMNS); + webvDescription.getSettings().setLoadWithOverviewMode(true); + webvDescription.setWebViewClient(new WebViewClient() { + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + try { + getContext().startActivity(intent); + } catch (ActivityNotFoundException e) { + e.printStackTrace(); + return false; + } + return true; + } + }); + + loadDescriptionWebview(item); + + butAction1.setOnClickListener(new View.OnClickListener() { + DefaultActionButtonCallback actionButtonCallback = new DefaultActionButtonCallback(getContext()); + + @Override + + public void onClick(View v) { + actionButtonCallback.onActionButtonPressed(item); + FeedMedia media = item.getMedia(); + if (media != null && media.isDownloaded()) { + // playback was started, dialog should close itself + dismiss(); + } + + } + } + ); + + butAction2.setOnClickListener(new View.OnClickListener() + + { + @Override + public void onClick(View v) { + if (item.hasMedia()) { + FeedMedia media = item.getMedia(); + if (!media.isDownloaded()) { + DBTasks.playMedia(getContext(), media, true, true, true); + dismiss(); + } else { + DBWriter.deleteFeedMediaOfItem(getContext(), media.getId()); + } + } else if (item.getLink() != null) { + Uri uri = Uri.parse(item.getLink()); + getContext().startActivity(new Intent(Intent.ACTION_VIEW, uri)); + } + } + } + ); + + butMore.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + popupMenu.getMenu().clear(); + popupMenu.inflate(R.menu.feeditem_dialog); + if (item.hasMedia()) { + FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, queue); + } else { + // these are already available via button1 and button2 + FeedItemMenuHandler.onPrepareMenu(popupMenuInterface, item, true, queue, + R.id.mark_read_item, R.id.visit_website_item); + } + popupMenu.show(); + } + } + ); + + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + + try { + return FeedItemMenuHandler.onMenuItemClicked(getContext(), menuItem.getItemId(), item); + } catch (DownloadRequestException e) { + e.printStackTrace(); + Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_LONG).show(); + return true; + } + } + } + ); + + updateMenuAppearance(); + } + + + private final FeedItemMenuHandler.MenuInterface popupMenuInterface = new FeedItemMenuHandler.MenuInterface() { + @Override + public void setItemVisibility(int id, boolean visible) { + MenuItem item = popupMenu.getMenu().findItem(id); + if (item != null) { + item.setVisible(visible); + } + } + }; + + public void updateMenuAppearance() { + if (item == null || queue == null) { + Log.w(TAG, "UpdateMenuAppearance called while item or queue was null"); + return; + } + FeedMedia media = item.getMedia(); + if (media == null) { + TypedArray drawables = getContext().obtainStyledAttributes(new int[]{R.attr.navigation_accept, + R.attr.location_web_site}); + + if (!item.isRead()) { + butAction1.setImageDrawable(drawables.getDrawable(0)); + butAction1.setContentDescription(getContext().getString(R.string.mark_read_label)); + butAction1.setVisibility(View.VISIBLE); + } else { + butAction1.setVisibility(View.INVISIBLE); + } + + if (item.getLink() != null) { + butAction2.setImageDrawable(drawables.getDrawable(1)); + butAction2.setContentDescription(getContext().getString(R.string.visit_website_label)); + } else { + butAction2.setEnabled(false); + } + + drawables.recycle(); + } else { + boolean isDownloading = DownloadRequester.getInstance().isDownloadingFile(media); + TypedArray drawables = getContext().obtainStyledAttributes(new int[]{R.attr.av_play, + R.attr.av_download, R.attr.action_stream, R.attr.content_discard, R.attr.navigation_cancel}); + + if (!media.isDownloaded()) { + butAction2.setImageDrawable(drawables.getDrawable(2)); + butAction2.setContentDescription(getContext().getString(R.string.stream_label)); + } else { + butAction2.setImageDrawable(drawables.getDrawable(3)); + butAction2.setContentDescription(getContext().getString(R.string.remove_episode_lable)); + } + + if (isDownloading) { + butAction1.setImageDrawable(drawables.getDrawable(4)); + butAction1.setContentDescription(getContext().getString(R.string.cancel_download_label)); + } else if (media.isDownloaded()) { + butAction1.setImageDrawable(drawables.getDrawable(0)); + butAction1.setContentDescription(getContext().getString(R.string.play_label)); + } else { + butAction1.setImageDrawable(drawables.getDrawable(1)); + butAction1.setContentDescription(getContext().getString(R.string.download_label)); + } + + drawables.recycle(); + } + } + + + private void loadDescriptionWebview(final ShownotesProvider shownotesProvider) { + AsyncTask<Void, Void, Void> loadTask = new AsyncTask<Void, Void, Void>() { + String data; + + + private String applyWebviewStyle(String textColor, String data) { + final String WEBVIEW_STYLE = "<html><head><style type=\"text/css\"> @font-face { font-family: 'Roboto-Light'; src: url('file:///android_asset/Roboto-Light.ttf'); } * { color: %s; font-family: roboto-Light; font-size: 11pt; } a { font-style: normal; text-decoration: none; font-weight: normal; color: #00A8DF; } img { display: block; margin: 10 auto; max-width: %s; height: auto; } body { margin: %dpx %dpx %dpx %dpx; }</style></head><body>%s</body></html>"; + final int pageMargin = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, 8, getContext().getResources() + .getDisplayMetrics() + ); + return String.format(WEBVIEW_STYLE, textColor, "100%", pageMargin, + pageMargin, pageMargin, pageMargin, data); + } + + + @Override + protected void onPostExecute(Void result) { + super.onPostExecute(result); + // /webvDescription.loadData(url, "text/html", "utf-8"); + if (FeedItemDialog.this.isShowing() && webvDescription != null) { + webvDescription.loadDataWithBaseURL(null, data, "text/html", + "utf-8", "about:blank"); + if (BuildConfig.DEBUG) + Log.d(TAG, "Webview loaded"); + } + } + + + @Override + protected Void doInBackground(Void... params) { + if (BuildConfig.DEBUG) + Log.d(TAG, "Loading Webview"); + try { + Callable<String> shownotesLoadTask = shownotesProvider.loadShownotes(); + final String shownotes = shownotesLoadTask.call(); + + data = StringEscapeUtils.unescapeHtml4(shownotes); + TypedArray res = getContext() + .getTheme() + .obtainStyledAttributes( + new int[]{android.R.attr.textColorPrimary}); + int colorResource; + if (useDarkThemeWorkAround()) { + colorResource = getContext().getResources().getColor(R.color.black); + } else { + colorResource = res.getColor(0, 0); + } + String colorString = String.format("#%06X", + 0xFFFFFF & colorResource); + Log.i(TAG, "text color: " + colorString); + res.recycle(); + data = applyWebviewStyle(colorString, data); + + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + }; + loadTask.execute(); + } + + /** + * Convenience method that calls setQueue() and setItemFromCollection() with + * the given arguments. + * + * @return true if one of the calls to setItemFromCollection returned true, + * false otherwise. + */ + public boolean updateContent(QueueAccess queue, List<FeedItem>... collections) { + setQueue(queue); + + boolean setItemFromCollectionResult = false; + if (collections != null) { + for (List<FeedItem> list : collections) { + setItemFromCollectionResult |= setItemFromCollection(list); + } + } + if (isShowing()) { + updateMenuAppearance(); + } + + return setItemFromCollectionResult; + } + + + public void setItem(FeedItem item) { + Validate.notNull(item); + this.item = item; + } + + /** + * Finds the FeedItem of this dialog in a collection and updates its state from that + * collection. + * + * @return true if the FeedItem was found, false otherwise. + */ + public boolean setItemFromCollection(Collection<FeedItem> items) { + for (FeedItem item : items) { + if (item.getId() == this.item.getId()) { + setItem(item); + return true; + } + } + return false; + } + + public void setQueue(QueueAccess queue) { + Validate.notNull(queue); + this.queue = queue; + } + + public FeedItem getItem() { + return item; + } + + public QueueAccess getQueue() { + return queue; + } + + public FeedItemDialogSavedInstance save() { + return new FeedItemDialogSavedInstance(item, queue, isShowing()); + } + + /** + * Used to save the FeedItemDialog's state across configuration changes + */ + public static class FeedItemDialogSavedInstance { + final FeedItem item; + final QueueAccess queueAccess; + final boolean isShowing; + + private FeedItemDialogSavedInstance(FeedItem item, QueueAccess queueAccess, boolean isShowing) { + this.item = item; + this.queueAccess = queueAccess; + this.isShowing = isShowing; + } + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java new file mode 100644 index 000000000..16fb77f2a --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/GpodnetSetHostnameDialog.java @@ -0,0 +1,67 @@ +package de.danoeh.antennapod.dialog; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.text.Editable; +import android.text.InputType; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.LinearLayout; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.gpoddernet.GpodnetService; +import de.danoeh.antennapod.core.preferences.GpodnetPreferences; + +/** + * Creates a dialog that lets the user change the hostname for the gpodder.net service. + */ +public class GpodnetSetHostnameDialog { + private static final String TAG = "GpodnetSetHostnameDialog"; + + public static AlertDialog createDialog(final Context context) { + AlertDialog.Builder dialog = new AlertDialog.Builder(context); + final EditText et = new EditText(context); + et.setText(GpodnetPreferences.getHostname()); + et.setInputType(InputType.TYPE_TEXT_VARIATION_URI); + dialog.setTitle(R.string.pref_gpodnet_sethostname_title) + .setView(setupContentView(context, et)) + .setPositiveButton(R.string.confirm_label, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final Editable e = et.getText(); + if (e != null) { + GpodnetPreferences.setHostname(e.toString()); + } + dialog.dismiss(); + } + }) + .setNegativeButton(R.string.cancel_label, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }) + .setNeutralButton(R.string.pref_gpodnet_sethostname_use_default_host, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + GpodnetPreferences.setHostname(GpodnetService.DEFAULT_BASE_HOST); + dialog.dismiss(); + } + }) + .setCancelable(true); + return dialog.show(); + } + + private static View setupContentView(Context context, EditText et) { + LinearLayout ll = new LinearLayout(context); + ll.addView(et); + LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) et.getLayoutParams(); + if (params != null) { + params.setMargins(8, 8, 8, 8); + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.MATCH_PARENT; + } + return ll; + } +} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/TimeDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/TimeDialog.java new file mode 100644 index 000000000..6561d501e --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/TimeDialog.java @@ -0,0 +1,138 @@ +package de.danoeh.antennapod.dialog; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.view.View; +import android.view.Window; +import android.view.inputmethod.InputMethodManager; +import android.widget.*; +import de.danoeh.antennapod.core.BuildConfig; +import de.danoeh.antennapod.R; + +import java.util.concurrent.TimeUnit; + +public abstract class TimeDialog extends Dialog { + private static final String TAG = "TimeDialog"; + + private static final int DEFAULT_SPINNER_POSITION = 1; + + private Context context; + + private EditText etxtTime; + private Spinner spTimeUnit; + private Button butConfirm; + private Button butCancel; + + private TimeUnit[] units = {TimeUnit.SECONDS, TimeUnit.MINUTES, + TimeUnit.HOURS}; + + public TimeDialog(Context context, int titleTextId, int leftButtonTextId) { + super(context); + this.context = context; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + String[] spinnerContent = new String[]{context.getString(R.string.time_unit_seconds), + context.getString(R.string.time_unit_minutes), + context.getString(R.string.time_unit_hours)}; + + setContentView(R.layout.time_dialog); + etxtTime = (EditText) findViewById(R.id.etxtTime); + spTimeUnit = (Spinner) findViewById(R.id.spTimeUnit); + butConfirm = (Button) findViewById(R.id.butConfirm); + butCancel = (Button) findViewById(R.id.butCancel); + + butConfirm.setText(R.string.set_sleeptimer_label); + butCancel.setText(R.string.cancel_label); + setTitle(R.string.set_sleeptimer_label); + ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>( + this.getContext(), android.R.layout.simple_spinner_item, + spinnerContent); + spinnerAdapter + .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spTimeUnit.setAdapter(spinnerAdapter); + spTimeUnit.setSelection(DEFAULT_SPINNER_POSITION); + butCancel.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + dismiss(); + } + }); + butConfirm.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + try { + long input = readTimeMillis(); + onTimeEntered(input); + dismiss(); + } catch (NumberFormatException e) { + e.printStackTrace(); + Toast toast = Toast.makeText(context, + R.string.time_dialog_invalid_input, + Toast.LENGTH_LONG); + toast.show(); + } + } + }); + etxtTime.addTextChangedListener(new TextWatcher() { + + @Override + public void afterTextChanged(Editable s) { + checkInputLength(s.length()); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, + int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, + int count) { + + } + }); + checkInputLength(etxtTime.getText().length()); + etxtTime.postDelayed(new Runnable() { + @Override + public void run() { + InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(etxtTime, InputMethodManager.SHOW_IMPLICIT); + } + }, 100); + + + + } + + private void checkInputLength(int length) { + if (length > 0) { + if (BuildConfig.DEBUG) + Log.d(TAG, "Length is larger than 0, enabling confirm button"); + butConfirm.setEnabled(true); + } else { + if (BuildConfig.DEBUG) + Log.d(TAG, "Length is smaller than 0, disabling confirm button"); + butConfirm.setEnabled(false); + } + } + + public abstract void onTimeEntered(long millis); + + private long readTimeMillis() { + TimeUnit selectedUnit = units[spTimeUnit.getSelectedItemPosition()]; + long value = Long.valueOf(etxtTime.getText().toString()); + return selectedUnit.toMillis(value); + } + +} diff --git a/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java new file mode 100644 index 000000000..8eba51540 --- /dev/null +++ b/app/src/main/java/de/danoeh/antennapod/dialog/VariableSpeedDialog.java @@ -0,0 +1,100 @@ +package de.danoeh.antennapod.dialog; + +import android.app.AlertDialog; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import de.danoeh.antennapod.R; +import de.danoeh.antennapod.core.preferences.UserPreferences; + +import java.util.Arrays; +import java.util.List; + +public class VariableSpeedDialog { + private VariableSpeedDialog() { + } + + public static void showDialog(final Context context) { + if (com.aocate.media.MediaPlayer.isPrestoLibraryInstalled(context)) { + showSpeedSelectorDialog(context); + } else { + showGetPluginDialog(context); + } + } + + private static void showGetPluginDialog(final Context context) { + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.no_playback_plugin_title); + builder.setMessage(R.string.no_playback_plugin_msg); + builder.setNegativeButton(R.string.close_label, null); + builder.setPositiveButton(R.string.download_plugin_label, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + try { + Intent playStoreIntent = new Intent( + Intent.ACTION_VIEW, + Uri.parse("market://details?id=com.falconware.prestissimo")); + context.startActivity(playStoreIntent); + } catch (ActivityNotFoundException e) { + // this is usually thrown on an emulator if the Android market is not installed + e.printStackTrace(); + } + } + }); + builder.create().show(); + } + + private static void showSpeedSelectorDialog(final Context context) { + final String[] speedValues = context.getResources().getStringArray( + R.array.playback_speed_values); + // According to Java spec these get initialized to false on creation + final boolean[] speedChecked = new boolean[speedValues.length]; + + // Build the "isChecked" array so that multiChoice dialog is + // populated correctly + List<String> selectedSpeedList = Arrays.asList(UserPreferences + .getPlaybackSpeedArray()); + for (int i = 0; i < speedValues.length; i++) { + speedChecked[i] = selectedSpeedList.contains(speedValues[i]); + } + + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.set_playback_speed_label); + builder.setMultiChoiceItems(R.array.playback_speed_values, + speedChecked, new DialogInterface.OnMultiChoiceClickListener() { + @Override + public void onClick(DialogInterface dialog, int which, + boolean isChecked) { + speedChecked[which] = isChecked; + } + + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + int choiceCount = 0; + for (int i = 0; i < speedChecked.length; i++) { + if (speedChecked[i]) { + choiceCount++; + } + } + String[] newSpeedValues = new String[choiceCount]; + int newSpeedIndex = 0; + for (int i = 0; i < speedChecked.length; i++) { + if (speedChecked[i]) { + newSpeedValues[newSpeedIndex++] = speedValues[i]; + } + } + + UserPreferences.setPlaybackSpeedArray(newSpeedValues); + + } + }); + builder.create().show(); + } +} |