From c91e79f9d306d6d21e0d755e59ac6f902b6dc330 Mon Sep 17 00:00:00 2001 From: Eric Kok Date: Wed, 1 Apr 2015 16:54:01 +0200 Subject: [PATCH] Working contextual action modes, working menus. --- README.md | 2 +- app/build.gradle | 2 +- .../transdroid/core/gui/DetailsActivity.java | 16 ++- .../transdroid/core/gui/DetailsFragment.java | 46 ++++++--- .../transdroid/core/gui/ServerStatusView.java | 7 +- .../core/gui/TorrentTasksExecutor.java | 3 + .../transdroid/core/gui/TorrentsActivity.java | 92 +++++++++--------- .../transdroid/core/gui/TorrentsFragment.java | 45 +++++++-- .../core/gui/navigation/NavigationHelper.java | 11 --- .../gui/navigation/SelectionManagerMode.java | 14 ++- .../core/gui/navigation/SetLabelDialog.java | 69 ++++++------- .../transdroid/core/gui/rss/RssfeedView.java | 4 +- .../core/gui/rss/RssfeedsActivity.java | 9 +- .../core/gui/rss/RssitemsFragment.java | 12 ++- .../core/gui/search/SearchActivity.java | 8 +- .../gui/search/SearchHistoryProvider.java | 2 +- .../gui/search/SearchResultsFragment.java | 13 ++- .../gui/settings/SystemSettingsActivity.java | 43 ++++---- .../seedbox/XirvikSharedSettingsActivity.java | 46 +++++---- .../btn_cab_done_default_transdroid2.9.png | Bin 107 -> 0 bytes .../btn_cab_done_focused_transdroid2.9.png | Bin 118 -> 0 bytes .../btn_cab_done_pressed_transdroid2.9.png | Bin 118 -> 0 bytes .../main/res/drawable-hdpi/ic_action_copy.png | Bin 0 -> 287 bytes .../res/drawable-hdpi/ic_action_download.png | Bin 0 -> 277 bytes .../res/drawable-hdpi/ic_action_filter.png | Bin 0 -> 181 bytes ...c_action_rss.png.png => ic_action_rss.png} | Bin .../ic_action_turtle_disabled_light.png | Bin 1104 -> 0 bytes .../main/res/drawable-hdpi/ic_btn_sort.png | Bin 209 -> 0 bytes .../btn_cab_done_default_transdroid2.9.png | Bin 120 -> 0 bytes .../btn_cab_done_focused_transdroid2.9.png | Bin 124 -> 0 bytes .../btn_cab_done_pressed_transdroid2.9.png | Bin 124 -> 0 bytes .../res/drawable-xhdpi/ic_action_copy.png | Bin 0 -> 330 bytes .../res/drawable-xhdpi/ic_action_download.png | Bin 0 -> 282 bytes .../res/drawable-xhdpi/ic_action_filter.png | Bin 0 -> 202 bytes .../drawable-xhdpi/ic_action_info_dark.png | Bin 1223 -> 0 bytes .../drawable-xhdpi/ic_action_info_light.png | Bin 1348 -> 0 bytes .../main/res/drawable-xhdpi/ic_btn_sort.png | Bin 198 -> 0 bytes .../drawable-xhdpi/ic_storage_white_24dp.png | Bin 199 -> 0 bytes .../res/drawable-xxhdpi/ic_action_copy.png | Bin 0 -> 436 bytes .../drawable-xxhdpi/ic_action_download.png | Bin 0 -> 351 bytes .../res/drawable-xxhdpi/ic_action_filter.png | Bin 0 -> 225 bytes .../ic_action_forcerecheck_dark.png | Bin 1066 -> 0 bytes .../ic_action_forcerecheck_light.png | Bin 2411 -> 0 bytes .../drawable-xxhdpi/ic_action_info_dark.png | Bin 1968 -> 0 bytes .../drawable-xxhdpi/ic_action_info_light.png | Bin 2229 -> 0 bytes .../drawable-xxhdpi/ic_action_save_dark.png | Bin 495 -> 0 bytes .../drawable-xxhdpi/ic_action_save_light.png | Bin 500 -> 0 bytes .../{ic_btn_sort.png => ic_action_sort.png} | Bin .../ic_insert_link_white_24dp.png | Bin 670 -> 0 bytes .../res/drawable-xxxhdpi/ic_action_link.png | Bin 865 -> 0 bytes .../res/drawable-xxxhdpi/ic_action_search.png | Bin 1090 -> 0 bytes .../res/drawable-xxxhdpi/ic_action_white.png | Bin 269 -> 0 bytes .../main/res/drawable-xxxhdpi/ic_btn_sort.png | Bin 253 -> 0 bytes .../res/drawable/btn_cab_done_transdroid2.xml | 27 ----- .../res/layout-w600dp/activity_search.xml | 84 ++++++++++------ .../res/layout-w600dp/activity_torrents.xml | 20 +++- .../res/layout-w900dp/activity_torrents.xml | 22 ++++- .../main/res/layout/actionbar_searchsite.xml | 7 +- app/src/main/res/layout/activity_search.xml | 58 +++++++---- app/src/main/res/layout/activity_torrents.xml | 25 +++-- app/src/main/res/layout/fragment_details.xml | 16 ++- .../res/layout/fragment_searchresults.xml | 9 +- app/src/main/res/layout/list_item_filter.xml | 2 +- app/src/main/res/layout/list_item_rssfeed.xml | 6 +- .../res/layout/list_item_searchresult.xml | 35 ++++--- .../main/res/layout/list_item_searchsite.xml | 6 +- .../main/res/layout/list_item_separator.xml | 2 +- app/src/main/res/layout/list_item_simple.xml | 6 +- app/src/main/res/layout/list_item_torrent.xml | 32 ++++-- .../main/res/layout/list_item_torrentfile.xml | 14 ++- ..._cab.xml => fragment_details_cab_main.xml} | 15 ++- .../menu/fragment_details_cab_secondary.xml | 26 +++++ .../main/res/menu/fragment_torrents_cab.xml | 12 +-- app/src/main/res/values-v21/styles.xml | 2 +- app/src/main/res/values/dimens.xml | 1 + 75 files changed, 520 insertions(+), 351 deletions(-) delete mode 100644 app/src/main/res/drawable-hdpi/btn_cab_done_default_transdroid2.9.png delete mode 100644 app/src/main/res/drawable-hdpi/btn_cab_done_focused_transdroid2.9.png delete mode 100644 app/src/main/res/drawable-hdpi/btn_cab_done_pressed_transdroid2.9.png create mode 100755 app/src/main/res/drawable-hdpi/ic_action_copy.png create mode 100755 app/src/main/res/drawable-hdpi/ic_action_download.png create mode 100755 app/src/main/res/drawable-hdpi/ic_action_filter.png rename app/src/main/res/drawable-hdpi/{ic_action_rss.png.png => ic_action_rss.png} (100%) delete mode 100644 app/src/main/res/drawable-hdpi/ic_action_turtle_disabled_light.png delete mode 100755 app/src/main/res/drawable-hdpi/ic_btn_sort.png delete mode 100644 app/src/main/res/drawable-xhdpi/btn_cab_done_default_transdroid2.9.png delete mode 100644 app/src/main/res/drawable-xhdpi/btn_cab_done_focused_transdroid2.9.png delete mode 100644 app/src/main/res/drawable-xhdpi/btn_cab_done_pressed_transdroid2.9.png create mode 100755 app/src/main/res/drawable-xhdpi/ic_action_copy.png create mode 100755 app/src/main/res/drawable-xhdpi/ic_action_download.png create mode 100755 app/src/main/res/drawable-xhdpi/ic_action_filter.png delete mode 100755 app/src/main/res/drawable-xhdpi/ic_action_info_dark.png delete mode 100755 app/src/main/res/drawable-xhdpi/ic_action_info_light.png delete mode 100755 app/src/main/res/drawable-xhdpi/ic_btn_sort.png delete mode 100755 app/src/main/res/drawable-xhdpi/ic_storage_white_24dp.png create mode 100755 app/src/main/res/drawable-xxhdpi/ic_action_copy.png create mode 100755 app/src/main/res/drawable-xxhdpi/ic_action_download.png create mode 100755 app/src/main/res/drawable-xxhdpi/ic_action_filter.png delete mode 100755 app/src/main/res/drawable-xxhdpi/ic_action_forcerecheck_dark.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_forcerecheck_light.png delete mode 100755 app/src/main/res/drawable-xxhdpi/ic_action_info_dark.png delete mode 100755 app/src/main/res/drawable-xxhdpi/ic_action_info_light.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_save_dark.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_save_light.png rename app/src/main/res/drawable-xxhdpi/{ic_btn_sort.png => ic_action_sort.png} (100%) delete mode 100755 app/src/main/res/drawable-xxhdpi/ic_insert_link_white_24dp.png delete mode 100755 app/src/main/res/drawable-xxxhdpi/ic_action_link.png delete mode 100755 app/src/main/res/drawable-xxxhdpi/ic_action_search.png delete mode 100755 app/src/main/res/drawable-xxxhdpi/ic_action_white.png delete mode 100755 app/src/main/res/drawable-xxxhdpi/ic_btn_sort.png delete mode 100644 app/src/main/res/drawable/btn_cab_done_transdroid2.xml rename app/src/main/res/menu/{fragment_details_cab.xml => fragment_details_cab_main.xml} (83%) create mode 100644 app/src/main/res/menu/fragment_details_cab_secondary.xml diff --git a/README.md b/README.md index f22712a4..f61b3336 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Please respect the coding standards for easier merging. master contains the curr Code structure ============== -Starting with version 2.3.0, Transdroid is developed in Android Studio, fully integrating with the Gradle build system. It is compiled against Android 4.4 (API level 19) and since version 2.2.0 supporting ICS (API level 15) and up only. To support lite (Transdrone, specially for the Play Store) and full (Transdroid) versions of the app, build flavours are defined in gradle, which contain version-specific resources. Dependencies are managed via Maven Central in the app's build.gradle file. +Starting with version 2.3.0, Transdroid is developed in Android Studio, fully integrating with the Gradle build system. It is (since version 2.5.0) compiled against Android 5.1 (API level 22) and (since version 2.2.0) supporting ICS (API level 15) and up only. To support lite (Transdrone, specially for the Play Store) and full (Transdroid) versions of the app, build flavours are defined in gradle, which contain version-specific resources. Dependencies are managed via JCentral in the app's build.gradle file. Developed By ============ diff --git a/app/build.gradle b/app/build.gradle index da7ead4b..cfafe69e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -36,12 +36,12 @@ dependencies { compile 'org.androidannotations:androidannotations-api:3.2' compile 'com.j256.ormlite:ormlite-core:4.48' compile 'com.j256.ormlite:ormlite-android:4.48' - compile 'de.keyboardsurfer.android.widget:crouton:1.8.5@aar' compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.3' compile 'com.android.support:appcompat-v7:22.0.0' compile 'com.android.support:support-annotations:20.0.0' compile 'com.getbase:floatingactionbutton:1.8.0' compile 'com.afollestad:material-dialogs:0.6.3.3' + compile 'com.nispok:snackbar:2.10.6' apt 'org.androidannotations:androidannotations:3.2' } diff --git a/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java b/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java index bd0cd4ab..94c90640 100644 --- a/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java @@ -24,6 +24,9 @@ import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.Toolbar; import android.widget.Toast; +import com.nispok.snackbar.Snackbar; +import com.nispok.snackbar.SnackbarManager; + import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Background; import org.androidannotations.annotations.Bean; @@ -74,8 +77,6 @@ import org.transdroid.daemon.task.StopTask; import java.util.ArrayList; import java.util.List; -import de.keyboardsurfer.android.widget.crouton.Crouton; - /** * An activity that holds a single torrents details fragment. It is used on devices (i.e. phones) where there is no room to show details in the {@link * TorrentsActivity} directly. Task execution, such as loading of more details and updating file priorities, is performed in this activity via @@ -144,12 +145,6 @@ public class DetailsActivity extends ActionBarActivity implements TorrentTasksEx } - @Override - protected void onDestroy() { - Crouton.cancelAllCroutons(); - super.onDestroy(); - } - @TargetApi(Build.VERSION_CODES.HONEYCOMB) @OptionsItem(android.R.id.home) protected void navigateUp() { @@ -333,7 +328,7 @@ public class DetailsActivity extends ActionBarActivity implements TorrentTasksEx // Refresh the screen as well refreshTorrent(); refreshTorrentDetails(torrent); - Crouton.showText(this, successMessage, NavigationHelper.CROUTON_INFO_STYLE); + SnackbarManager.show(Snackbar.with(this).text(successMessage)); } @UiThread @@ -353,7 +348,8 @@ public class DetailsActivity extends ActionBarActivity implements TorrentTasksEx log.i(this, result.getException().toString()); String error = getString(LocalTorrent.getResourceForDaemonException(result.getException())); fragmentDetails.updateIsLoading(false, isCritical ? error : null); - Crouton.showText(this, getString(LocalTorrent.getResourceForDaemonException(result.getException())), NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(getString(LocalTorrent.getResourceForDaemonException(result.getException()))) + .colorResource(R.color.crouton_error)); } @UiThread diff --git a/app/src/main/java/org/transdroid/core/gui/DetailsFragment.java b/app/src/main/java/org/transdroid/core/gui/DetailsFragment.java index f1c1278c..d80e4961 100644 --- a/app/src/main/java/org/transdroid/core/gui/DetailsFragment.java +++ b/app/src/main/java/org/transdroid/core/gui/DetailsFragment.java @@ -24,6 +24,7 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.ActionMenuView; import android.view.ActionMode; import android.view.Menu; @@ -34,6 +35,9 @@ import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; +import com.nispok.snackbar.Snackbar; +import com.nispok.snackbar.SnackbarManager; + import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Click; import org.androidannotations.annotations.EFragment; @@ -47,7 +51,6 @@ import org.transdroid.core.app.settings.SystemSettings_; import org.transdroid.core.gui.lists.DetailsAdapter; import org.transdroid.core.gui.lists.SimpleListItemAdapter; import org.transdroid.core.gui.navigation.Label; -import org.transdroid.core.gui.navigation.NavigationHelper; import org.transdroid.core.gui.navigation.NavigationHelper_; import org.transdroid.core.gui.navigation.RefreshableActivity; import org.transdroid.core.gui.navigation.SelectionManagerMode; @@ -67,8 +70,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import de.keyboardsurfer.android.widget.crouton.Crouton; - /** * Fragment that shows detailed statistics about some torrent. These come from some already fetched {@link Torrent} object, but it also retrieves * further detailed statistics. The actual execution of tasks is performed by the activity that contains this fragment, as per the {@link @@ -100,6 +101,8 @@ public class DetailsFragment extends Fragment implements OnTrackersUpdatedListen protected View detailsContainer; @ViewById(R.id.details_menu) protected ActionMenuView detailsMenu; + @ViewById(R.id.contextual_menu) + protected ActionMenuView contextualMenu; @ViewById protected SwipeRefreshLayout swipeRefreshLayout; @ViewById @@ -415,7 +418,7 @@ public class DetailsFragment extends Fragment implements OnTrackersUpdatedListen @OptionsItem(R.id.action_updatetrackers) protected void updateTrackers() { if (torrentDetails == null) { - Crouton.showText(getActivity(), R.string.error_stillloadingdetails, NavigationHelper.CROUTON_INFO_STYLE); + SnackbarManager.show(Snackbar.with(getActivity()).text(R.string.error_stillloadingdetails)); return; } new SetTrackersDialog().setOnTrackersUpdated(this).setCurrentTrackers(torrentDetails.getTrackersText()) @@ -473,10 +476,22 @@ public class DetailsFragment extends Fragment implements OnTrackersUpdatedListen SelectionManagerMode selectionManagerMode; @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { + public boolean onCreateActionMode(final ActionMode mode, Menu menu) { // Show contextual action bar to start/stop/remove/etc. torrents in batch mode - mode.getMenuInflater().inflate(R.menu.fragment_details_cab, menu); - selectionManagerMode = new SelectionManagerMode(detailsList, R.plurals.navigation_filesselected); + detailsMenu.setEnabled(false); + contextualMenu.setVisibility(View.VISIBLE); + contextualMenu.setOnMenuItemClickListener(new ActionMenuView.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + return onActionItemClicked(mode, menuItem); + } + }); + if (contextualMenu.getMenu().size() == 0) { + getActivity().getMenuInflater().inflate(R.menu.fragment_details_cab_main, contextualMenu.getMenu()); + } + Context themedContext = ((ActionBarActivity) getActivity()).getSupportActionBar().getThemedContext(); + mode.getMenuInflater().inflate(R.menu.fragment_details_cab_secondary, menu); + selectionManagerMode = new SelectionManagerMode(themedContext, detailsList, R.plurals.navigation_filesselected); selectionManagerMode.setOnlyCheckClass(TorrentFile.class); selectionManagerMode.onCreateActionMode(mode, menu); return true; @@ -484,19 +499,20 @@ public class DetailsFragment extends Fragment implements OnTrackersUpdatedListen @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + selectionManagerMode.onPrepareActionMode(mode, menu); // Pause autorefresh if (getActivity() != null && getActivity() instanceof TorrentsActivity) { ((TorrentsActivity) getActivity()).stopRefresh = true; ((TorrentsActivity) getActivity()).stopAutoRefresh(); } boolean filePaths = currentServerSettings != null && Daemon.supportsFilePaths(currentServerSettings.getType()); - menu.findItem(R.id.action_download).setVisible(filePaths); + contextualMenu.getMenu().findItem(R.id.action_download).setVisible(filePaths); boolean filePriorities = currentServerSettings != null && Daemon.supportsFilePrioritySetting(currentServerSettings.getType()); - menu.findItem(R.id.action_priority_off).setVisible(filePriorities); - menu.findItem(R.id.action_priority_low).setVisible(filePriorities); - menu.findItem(R.id.action_priority_normal).setVisible(filePriorities); - menu.findItem(R.id.action_priority_high).setVisible(filePriorities); - return selectionManagerMode.onPrepareActionMode(mode, menu); + contextualMenu.getMenu().findItem(R.id.action_priority_off).setVisible(filePriorities); + contextualMenu.getMenu().findItem(R.id.action_priority_low).setVisible(filePriorities); + contextualMenu.getMenu().findItem(R.id.action_priority_normal).setVisible(filePriorities); + contextualMenu.getMenu().findItem(R.id.action_priority_high).setVisible(filePriorities); + return true; } @SuppressLint("SdCardPath") @@ -569,7 +585,7 @@ public class DetailsFragment extends Fragment implements OnTrackersUpdatedListen } // No app is available that can handle FTP downloads - Crouton.showText(getActivity(), getString(R.string.error_noftpapp, url), NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(getActivity()).text(R.string.error_noftpapp).colorResource(R.color.crouton_error)); mode.finish(); return true; @@ -617,6 +633,8 @@ public class DetailsFragment extends Fragment implements OnTrackersUpdatedListen ((TorrentsActivity) getActivity()).startAutoRefresh(); } selectionManagerMode.onDestroyActionMode(mode); + contextualMenu.setVisibility(View.GONE); + detailsMenu.setEnabled(true); } }; diff --git a/app/src/main/java/org/transdroid/core/gui/ServerStatusView.java b/app/src/main/java/org/transdroid/core/gui/ServerStatusView.java index 4ae1dcec..f55fff18 100644 --- a/app/src/main/java/org/transdroid/core/gui/ServerStatusView.java +++ b/app/src/main/java/org/transdroid/core/gui/ServerStatusView.java @@ -21,6 +21,9 @@ import android.view.View; import android.widget.RelativeLayout; import android.widget.TextView; +import com.nispok.snackbar.Snackbar; +import com.nispok.snackbar.SnackbarManager; + import org.androidannotations.annotations.EViewGroup; import org.androidannotations.annotations.ViewById; import org.transdroid.R; @@ -32,8 +35,6 @@ import org.transdroid.daemon.util.FileSizeConverter; import java.util.List; -import de.keyboardsurfer.android.widget.crouton.Crouton; - @EViewGroup(R.layout.actionbar_serverstatus) public class ServerStatusView extends RelativeLayout implements OnRatesPickedListener { @@ -115,7 +116,7 @@ public class ServerStatusView extends RelativeLayout implements OnRatesPickedLis @Override public void onInvalidNumber() { - Crouton.showText(activity, R.string.error_notanumber, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(activity).text(R.string.error_notanumber).colorResource(R.color.crouton_error)); } } diff --git a/app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java b/app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java index e2423c5a..cc70e3a3 100644 --- a/app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java +++ b/app/src/main/java/org/transdroid/core/gui/TorrentTasksExecutor.java @@ -16,6 +16,9 @@ */ package org.transdroid.core.gui; +import android.support.v7.widget.ActionMenuView; +import android.support.v7.widget.Toolbar; + import org.transdroid.daemon.Priority; import org.transdroid.daemon.Torrent; import org.transdroid.daemon.TorrentFile; diff --git a/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java b/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java index f8fdc005..70fa8ddb 100644 --- a/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java @@ -26,9 +26,9 @@ import android.os.Build; import android.os.Bundle; import android.support.v4.view.MenuItemCompat; import android.support.v4.widget.DrawerLayout; -import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.widget.ActionMenuView; import android.support.v7.widget.SearchView; import android.support.v7.widget.Toolbar; import android.text.TextUtils; @@ -43,6 +43,8 @@ import android.widget.ListView; import com.getbase.floatingactionbutton.FloatingActionButton; import com.getbase.floatingactionbutton.FloatingActionsMenu; +import com.nispok.snackbar.Snackbar; +import com.nispok.snackbar.SnackbarManager; import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Background; @@ -135,8 +137,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import de.keyboardsurfer.android.widget.crouton.Crouton; - /** * Main activity that holds the fragment that shows the torrents list, presents a way to filter the list (via an action bar spinner or list side list) * and potentially shows a torrent details fragment too, if there is room. Task execution such as loading of and adding torrents is performs in this @@ -166,6 +166,8 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE protected Toolbar torrentsToolbar; @ViewById protected Toolbar actionsToolbar; + @ViewById(R.id.contextual_menu) + protected ActionMenuView contextualMenu; @ViewById protected FloatingActionsMenu addmenuButton; @ViewById @@ -404,12 +406,6 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE autoRefreshTask = null; } - @Override - protected void onDestroy() { - Crouton.cancelAllCroutons(); - super.onDestroy(); - } - @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); @@ -418,35 +414,35 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE if (actionsToolbar.getMenu().size() == 0) { actionsToolbar.inflateMenu(R.menu.activity_torrents_secondary); } - if (navigationHelper.enableSearchUi()) { - // Add an expandable SearchView to the action bar - MenuItem item = menu.findItem(R.id.action_search); - SearchView searchView = new SearchView(this); - searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); - searchView.setQueryRefinementEnabled(true); - searchView.setOnSearchClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - // Pause autorefresh - stopRefresh = true; - stopAutoRefresh(); - } - }); - MenuItemCompat.setOnActionExpandListener(item, new MenuItemCompat.OnActionExpandListener() { - @Override - public boolean onMenuItemActionExpand(MenuItem item) { - return true; - } + if (navigationHelper.enableSearchUi()) { + // Add an expandable SearchView to the action bar + MenuItem item = menu.findItem(R.id.action_search); + SearchView searchView = new SearchView(torrentsToolbar.getContext()); + searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); + searchView.setQueryRefinementEnabled(true); + searchView.setOnSearchClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + // Pause autorefresh + stopRefresh = true; + stopAutoRefresh(); + } + }); + MenuItemCompat.setOnActionExpandListener(item, new MenuItemCompat.OnActionExpandListener() { + @Override + public boolean onMenuItemActionExpand(MenuItem item) { + return true; + } - @Override - public boolean onMenuItemActionCollapse(MenuItem item) { - stopRefresh = false; - startAutoRefresh(); - return true; - } - }); - MenuItemCompat.setActionView(item, searchView); - searchMenu = item; + @Override + public boolean onMenuItemActionCollapse(MenuItem item) { + stopRefresh = false; + startAutoRefresh(); + return true; + } + }); + MenuItemCompat.setActionView(item, searchView); + searchMenu = item; } return true; } @@ -652,7 +648,7 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE return; } if (dataUri.getScheme() == null) { - Crouton.showText(this, R.string.error_invalid_url_form, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(R.string.error_invalid_url_form).colorResource(R.color.crouton_error)); return; } @@ -768,7 +764,7 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE protected void onBarcodeScanHandled(String barcode, String result) { log.d(this, "Scanned barcode " + barcode + " and got " + result); if (TextUtils.isEmpty(result)) { - Crouton.showText(this, R.string.error_noproductforcode, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(R.string.error_noproductforcode).colorResource(R.color.crouton_error)); } else if (result.startsWith("http") || result.startsWith("https")) { addTorrentByUrl(result, "QR code result"); // No torrent title known } else if (navigationHelper.enableSearchUi()) { @@ -1030,10 +1026,10 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE } catch (SecurityException e) { // No longer access to this file log.e(this, "No access given to " + contentUri.toString() + ": " + e.toString()); - Crouton.showText(this, R.string.error_torrentfile, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(R.string.error_torrentfile).colorResource(R.color.crouton_error)); } catch (FileNotFoundException e) { log.e(this, contentUri.toString() + " does not exist: " + e.toString()); - Crouton.showText(this, R.string.error_torrentfile, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(R.string.error_torrentfile).colorResource(R.color.crouton_error)); } } @@ -1045,7 +1041,7 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE addTorrentFromStream(input, title); } catch (Exception e) { log.e(this, "Can't download private site torrent " + url + " from " + source + ": " + e.toString()); - Crouton.showText(this, R.string.error_torrentfile, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(R.string.error_torrentfile).colorResource(R.color.crouton_error)); } } @@ -1073,14 +1069,14 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) { log.e(this, "Can't retrieve web torrent " + url + ": Unexpected HTTP response status code " + response.getStatusLine().toString()); - Crouton.showText(this, R.string.error_401, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(R.string.error_401).colorResource(R.color.crouton_error)); return; } InputStream input = response.getEntity().getContent(); addTorrentFromStream(input, title); } catch (Exception e) { log.e(this, "Can't retrieve web torrent " + url + ": " + e.toString()); - Crouton.showText(this, R.string.error_torrentfile, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(R.string.error_torrentfile).colorResource(R.color.crouton_error)); } } @@ -1106,7 +1102,7 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE } } catch (IOException e) { log.e(this, "Can't write input stream to " + tempFile.toString() + ": " + e.toString()); - Crouton.showText(this, R.string.error_torrentfile, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(R.string.error_torrentfile).colorResource(R.color.crouton_error)); } finally { try { if (input != null) { @@ -1114,7 +1110,7 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE } } catch (IOException e) { log.e(this, "Error closing the input stream " + tempFile.toString() + ": " + e.toString()); - Crouton.showText(this, R.string.error_torrentfile, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(R.string.error_torrentfile).colorResource(R.color.crouton_error)); } } } @@ -1251,7 +1247,7 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE protected void onTaskSucceeded(DaemonTaskSuccessResult result, String successMessage) { // Refresh the screen as well refreshScreen(); - Crouton.showText(this, successMessage, NavigationHelper.CROUTON_INFO_STYLE); + SnackbarManager.show(Snackbar.with(this).text(successMessage)); } @UiThread @@ -1259,7 +1255,7 @@ public class TorrentsActivity extends ActionBarActivity implements TorrentTasksE //noinspection ThrowableResultOfMethodCallIgnored log.i(this, result.getException().toString()); String error = getString(LocalTorrent.getResourceForDaemonException(result.getException())); - Crouton.showText(this, error, NavigationHelper.CROUTON_ERROR_STYLE); + SnackbarManager.show(Snackbar.with(this).text(error).colorResource(R.color.crouton_error)); fragmentTorrents.updateIsLoading(false); if (isCritical) { fragmentTorrents.updateError(error); diff --git a/app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java b/app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java index 9f1af8cb..e640890c 100644 --- a/app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java +++ b/app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java @@ -17,7 +17,11 @@ package org.transdroid.core.gui; import android.app.Fragment; +import android.content.Context; import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.ActionBarActivity; +import android.support.v7.widget.ActionMenuView; +import android.support.v7.widget.Toolbar; import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; @@ -27,6 +31,8 @@ import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; +import com.getbase.floatingactionbutton.FloatingActionsMenu; + import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Click; @@ -251,13 +257,33 @@ public class TorrentsFragment extends Fragment implements OnLabelPickedListener private MultiChoiceModeListener onTorrentsSelected = new MultiChoiceModeListener() { - SelectionManagerMode selectionManagerMode; + private SelectionManagerMode selectionManagerMode; + private ActionMenuView actionsMenu; + private Toolbar actionsToolbar; + private FloatingActionsMenu addmenuButton; @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - // Show contextual action bar to start/stop/remove/etc. torrents in batch mode - mode.getMenuInflater().inflate(R.menu.fragment_torrents_cab, menu); - selectionManagerMode = new SelectionManagerMode(torrentsList, R.plurals.navigation_torrentsselected); + public boolean onCreateActionMode(final ActionMode mode, Menu menu) { + // Show contextual action bars to start/stop/remove/etc. torrents in batch mode + if (actionsMenu == null) { + actionsMenu = ((TorrentsActivity) getActivity()).contextualMenu; + actionsToolbar = ((TorrentsActivity) getActivity()).actionsToolbar; + addmenuButton = ((TorrentsActivity) getActivity()).addmenuButton; + } + actionsToolbar.setEnabled(false); + actionsMenu.setVisibility(View.VISIBLE); + addmenuButton.setVisibility(View.GONE); + actionsMenu.setOnMenuItemClickListener(new ActionMenuView.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + return onActionItemClicked(mode, menuItem); + } + }); + if (actionsMenu.getMenu().size() == 0) { + getActivity().getMenuInflater().inflate(R.menu.fragment_torrents_cab, actionsMenu.getMenu()); + } + Context themedContext = ((ActionBarActivity) getActivity()).getSupportActionBar().getThemedContext(); + selectionManagerMode = new SelectionManagerMode(themedContext, torrentsList, R.plurals.navigation_torrentsselected); selectionManagerMode.onCreateActionMode(mode, menu); return true; } @@ -267,9 +293,9 @@ public class TorrentsFragment extends Fragment implements OnLabelPickedListener selectionManagerMode.onPrepareActionMode(mode, menu); // Hide/show options depending on the type of server we are connected to if (daemonType != null) { - menu.findItem(R.id.action_start).setVisible(Daemon.supportsStoppingStarting(daemonType)); - menu.findItem(R.id.action_stop).setVisible(Daemon.supportsStoppingStarting(daemonType)); - menu.findItem(R.id.action_setlabel).setVisible(Daemon.supportsSetLabel(daemonType)); + actionsMenu.getMenu().findItem(R.id.action_start).setVisible(Daemon.supportsStoppingStarting(daemonType)); + actionsMenu.getMenu().findItem(R.id.action_stop).setVisible(Daemon.supportsStoppingStarting(daemonType)); + actionsMenu.getMenu().findItem(R.id.action_setlabel).setVisible(Daemon.supportsSetLabel(daemonType)); } // Pause autorefresh if (getActivity() != null && getActivity() instanceof TorrentsActivity) { @@ -352,6 +378,9 @@ public class TorrentsFragment extends Fragment implements OnLabelPickedListener ((TorrentsActivity) getActivity()).startAutoRefresh(); } selectionManagerMode.onDestroyActionMode(mode); + actionsMenu.setVisibility(View.GONE); + actionsToolbar.setEnabled(true); + addmenuButton.setVisibility(View.VISIBLE); } }; diff --git a/app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java b/app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java index da1b00e7..cf468199 100644 --- a/app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java +++ b/app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java @@ -38,9 +38,6 @@ import org.transdroid.R; import java.io.IOException; -import de.keyboardsurfer.android.widget.crouton.Crouton; -import de.keyboardsurfer.android.widget.crouton.Style; - /** * Helper for activities to make navigation-related decisions, such as when a device can display a larger, tablet style layout or how to display * errors. @@ -50,14 +47,6 @@ import de.keyboardsurfer.android.widget.crouton.Style; @EBean public class NavigationHelper { - /** - * Use with {@link Crouton#showText(android.app.Activity, int, Style)} (and variants) to display error messages. - */ - public static Style CROUTON_ERROR_STYLE = new Style.Builder().setBackgroundColor(R.color.crouton_error).setTextSize(13).build(); - /** - * Use with {@link Crouton#showText(android.app.Activity, int, Style)} (and variants) to display info messages. - */ - public static Style CROUTON_INFO_STYLE = new Style.Builder().setBackgroundColor(R.color.crouton_info).setTextSize(13).build(); private static ImageLoader imageCache; @RootContext protected Context context; diff --git a/app/src/main/java/org/transdroid/core/gui/navigation/SelectionManagerMode.java b/app/src/main/java/org/transdroid/core/gui/navigation/SelectionManagerMode.java index 6520b4e2..38aae6ad 100644 --- a/app/src/main/java/org/transdroid/core/gui/navigation/SelectionManagerMode.java +++ b/app/src/main/java/org/transdroid/core/gui/navigation/SelectionManagerMode.java @@ -19,6 +19,7 @@ package org.transdroid.core.gui.navigation; import org.transdroid.core.gui.navigation.SelectionModificationSpinner.OnModificationActionSelectedListener; import org.transdroid.daemon.Finishable; +import android.content.Context; import android.util.SparseBooleanArray; import android.view.ActionMode; import android.view.Menu; @@ -35,18 +36,21 @@ import android.widget.ListView; */ public class SelectionManagerMode implements MultiChoiceModeListener, OnModificationActionSelectedListener { - private ListView managedList; - private int titleTemplateResource; + private final Context themedContext; + private final ListView managedList; + private final int titleTemplateResource; private Class onlyCheckClass = null; /** * Instantiates the helper by binding it to a specific {@link ListView} and providing the text resource to display * as title in the spinner. + * @param themedContext The context which is associated with the correct theme to apply when inflating views, i.e. the toolbar context * @param managedList The list to manage the selection for and execute selection action to * @param titleTemplateResource The string resource id to show as the spinners title; the number of selected items * will be supplied as numeric formatting argument */ - public SelectionManagerMode(ListView managedList, int titleTemplateResource) { + public SelectionManagerMode(Context themedContext, ListView managedList, int titleTemplateResource) { + this.themedContext = themedContext; this.managedList = managedList; this.titleTemplateResource = titleTemplateResource; } @@ -63,7 +67,7 @@ public class SelectionManagerMode implements MultiChoiceModeListener, OnModifica @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Allow modification of selection through a spinner - SelectionModificationSpinner selectionSpinner = new SelectionModificationSpinner(managedList.getContext()); + SelectionModificationSpinner selectionSpinner = new SelectionModificationSpinner(themedContext); selectionSpinner.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)); selectionSpinner.setOnModificationActionSelectedListener(this); @@ -85,7 +89,7 @@ public class SelectionManagerMode implements MultiChoiceModeListener, OnModifica .getCheckedItemPositions().keyAt(i))))) checkedCount++; } - ((SelectionModificationSpinner) mode.getCustomView()).updateTitle(managedList.getContext().getResources() + ((SelectionModificationSpinner) mode.getCustomView()).updateTitle(themedContext.getResources() .getQuantityString(titleTemplateResource, checkedCount, checkedCount)); } diff --git a/app/src/main/java/org/transdroid/core/gui/navigation/SetLabelDialog.java b/app/src/main/java/org/transdroid/core/gui/navigation/SetLabelDialog.java index 54f28962..01c07304 100644 --- a/app/src/main/java/org/transdroid/core/gui/navigation/SetLabelDialog.java +++ b/app/src/main/java/org/transdroid/core/gui/navigation/SetLabelDialog.java @@ -16,13 +16,6 @@ */ package org.transdroid.core.gui.navigation; -import java.security.InvalidParameterException; -import java.util.Iterator; -import java.util.List; - -import org.transdroid.R; -import org.transdroid.core.gui.lists.SimpleListItem; - import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; @@ -34,7 +27,16 @@ import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.EditText; import android.widget.ListView; -import de.keyboardsurfer.android.widget.crouton.Crouton; + +import com.nispok.snackbar.Snackbar; +import com.nispok.snackbar.SnackbarManager; + +import org.transdroid.R; +import org.transdroid.core.gui.lists.SimpleListItem; + +import java.security.InvalidParameterException; +import java.util.Iterator; +import java.util.List; /** * A dialog fragment that allows picking a label or entering a new label to set this new label to the torrent. @@ -60,16 +62,17 @@ public class SetLabelDialog extends DialogFragment { } /** - * Sets the list of currently known labels as are active on the server. These are offered to the user to pick a new - * label for the target torrents. + * Sets the list of currently known labels as are active on the server. These are offered to the user to pick a new label for the target + * torrents. * @param currentLabels The list of torrent labels * @return This dialog, for method chaining */ public SetLabelDialog setCurrentLabels(List