You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
345 lines
13 KiB
345 lines
13 KiB
/* |
|
* Copyright 2010-2018 Eric Kok et al. |
|
* |
|
* Transdroid is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation, either version 3 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* Transdroid is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>. |
|
*/ |
|
package org.transdroid.core.gui.search; |
|
|
|
import android.annotation.TargetApi; |
|
import android.app.SearchManager; |
|
import android.content.Intent; |
|
import android.net.Uri; |
|
import android.os.Build; |
|
import android.os.Bundle; |
|
import android.provider.SearchRecentSuggestions; |
|
|
|
import androidx.core.view.MenuItemCompat; |
|
import androidx.appcompat.app.AppCompatActivity; |
|
import androidx.appcompat.widget.Toolbar; |
|
|
|
import android.view.Menu; |
|
import android.view.MenuItem; |
|
import android.view.View; |
|
import android.widget.AdapterView; |
|
import android.widget.AdapterView.OnItemClickListener; |
|
import android.widget.ListView; |
|
import android.widget.SearchView; |
|
import android.widget.Spinner; |
|
import android.widget.TextView; |
|
|
|
import org.androidannotations.annotations.AfterViews; |
|
import org.androidannotations.annotations.Bean; |
|
import org.androidannotations.annotations.EActivity; |
|
import org.androidannotations.annotations.FragmentById; |
|
import org.androidannotations.annotations.OptionsItem; |
|
import org.androidannotations.annotations.SystemService; |
|
import org.androidannotations.annotations.ViewById; |
|
import org.transdroid.R; |
|
import org.transdroid.core.app.search.SearchHelper; |
|
import org.transdroid.core.app.search.SearchHelper.SearchSortOrder; |
|
import org.transdroid.core.app.search.SearchSite; |
|
import org.transdroid.core.app.settings.ApplicationSettings; |
|
import org.transdroid.core.app.settings.SettingsUtils; |
|
import org.transdroid.core.app.settings.WebsearchSetting; |
|
import org.transdroid.core.gui.TorrentsActivity_; |
|
import org.transdroid.core.gui.navigation.NavigationHelper; |
|
|
|
import java.util.List; |
|
|
|
/** |
|
* An activity that shows search results to the user (after a query was supplied by the standard Android search manager) and either shows the list of |
|
* search sites on the left (e.g. on tablets) or allows switching between search sites via the action bar spinner. |
|
* |
|
* @author Eric Kok |
|
*/ |
|
@EActivity(R.layout.activity_search) |
|
public class SearchActivity extends AppCompatActivity { |
|
|
|
@ViewById |
|
protected Toolbar searchToolbar; |
|
@ViewById |
|
protected Spinner sitesSpinner; |
|
@FragmentById(R.id.searchresults_fragment) |
|
protected SearchResultsFragment fragmentResults; |
|
@ViewById |
|
protected ListView searchsitesList; |
|
@ViewById |
|
protected TextView installmoduleText; |
|
@Bean |
|
protected ApplicationSettings applicationSettings; |
|
@Bean |
|
protected SearchHelper searchHelper; |
|
@SystemService |
|
protected SearchManager searchManager; |
|
private MenuItem searchMenu = null; |
|
private SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, SearchHistoryProvider.AUTHORITY, SearchHistoryProvider.MODE); |
|
|
|
private List<SearchSetting> searchSites; |
|
private SearchSetting lastUsedSite; |
|
private String lastUsedQuery; |
|
|
|
@Override |
|
public void onCreate(Bundle savedInstanceState) { |
|
SettingsUtils.applyDayNightTheme(this); |
|
super.onCreate(savedInstanceState); |
|
} |
|
|
|
@AfterViews |
|
protected void init() { |
|
|
|
searchToolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_material); |
|
searchToolbar.setNavigationOnClickListener(new View.OnClickListener() { |
|
@Override |
|
public void onClick(View v) { |
|
TorrentsActivity_.intent(SearchActivity.this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start(); |
|
} |
|
}); |
|
setSupportActionBar(searchToolbar); |
|
|
|
// Get the user query, as coming from the standard SearchManager |
|
handleIntent(getIntent()); |
|
|
|
if (!searchHelper.isTorrentSearchInstalled()) { |
|
// The module install text will be shown instead (in onPrepareOptionsMenu) |
|
return; |
|
} |
|
|
|
// Load sites and find the last used (or set as default) search site |
|
searchSites = applicationSettings.getSearchSettings(); |
|
lastUsedSite = applicationSettings.getLastUsedSearchSite(); |
|
int lastUsedPosition = -1; |
|
if (lastUsedSite != null) { |
|
for (int i = 0; i < searchSites.size(); i++) { |
|
if (searchSites.get(i).getKey().equals(lastUsedSite.getKey())) { |
|
lastUsedPosition = i; |
|
break; |
|
} |
|
} |
|
} |
|
|
|
// Allow site selection via list (on large screens) or action bar spinner |
|
if (searchsitesList != null) { |
|
// The current layout has a dedicated list view to select the search site |
|
SearchSitesAdapter searchSitesAdapter = SearchSitesAdapter_.getInstance_(this); |
|
searchSitesAdapter.update(searchSites); |
|
searchsitesList.setAdapter(searchSitesAdapter); |
|
searchsitesList.setOnItemClickListener(onSearchSiteClicked); |
|
// Select the last used site and start the search |
|
if (lastUsedPosition >= 0) { |
|
searchsitesList.setItemChecked(lastUsedPosition, true); |
|
lastUsedSite = searchSites.get(lastUsedPosition); |
|
refreshSearch(); |
|
} else { |
|
fragmentResults.clearResults(); |
|
} |
|
} else { |
|
// Use the action bar spinner to select sites |
|
if (getSupportActionBar() != null) |
|
getSupportActionBar().setTitle(""); |
|
sitesSpinner.setVisibility(View.VISIBLE); |
|
sitesSpinner.setAdapter(new SearchSettingsDropDownAdapter(searchToolbar.getContext(), searchSites)); |
|
sitesSpinner.setOnItemSelectedListener(onSearchSiteSelected); |
|
// Select the last used site; this also starts the search! |
|
if (lastUsedPosition >= 0) { |
|
sitesSpinner.setSelection(lastUsedPosition); |
|
lastUsedSite = searchSites.get(lastUsedPosition); |
|
refreshSearch(); |
|
} else { |
|
fragmentResults.clearResults(); |
|
} |
|
} |
|
invalidateOptionsMenu(); |
|
|
|
} |
|
|
|
@Override |
|
public boolean onCreateOptionsMenu(Menu menu) { |
|
super.onCreateOptionsMenu(menu); |
|
// Manually insert the actions into the main torrent and secondary actions toolbars |
|
searchToolbar.inflateMenu(R.menu.activity_search); |
|
// Add an expandable SearchView to the action bar |
|
MenuItem item = menu.findItem(R.id.action_search); |
|
final SearchView searchView = new SearchView(searchToolbar.getContext()); |
|
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); |
|
searchView.setQueryRefinementEnabled(true); |
|
searchView.setIconified(false); |
|
searchView.setIconifiedByDefault(false); |
|
MenuItemCompat.setActionView(item, searchView); |
|
searchMenu = item; |
|
final MenuItem sortBySeeders = menu.findItem(R.id.action_sort_seeders); |
|
final MenuItem sortByAdded = menu.findItem(R.id.action_sort_added); |
|
final SearchSortOrder sortOrder = applicationSettings.getLastUsedSearchSortOrder(); |
|
if (sortOrder == SearchSortOrder.BySeeders) { |
|
sortBySeeders.setChecked(true); |
|
} else { |
|
sortByAdded.setChecked(true); |
|
} |
|
return true; |
|
} |
|
|
|
@Override |
|
public boolean onPrepareOptionsMenu(Menu menu) { |
|
super.onPrepareOptionsMenu(menu); |
|
|
|
boolean searchInstalled = searchHelper.isTorrentSearchInstalled(); |
|
searchToolbar.getMenu().findItem(R.id.action_search).setVisible(searchInstalled); |
|
searchToolbar.getMenu().findItem(R.id.action_refresh).setVisible(searchInstalled); |
|
searchToolbar.getMenu().findItem(R.id.action_downloadsearch).setVisible(!searchInstalled); |
|
if (searchsitesList != null) { |
|
searchsitesList.setVisibility(searchInstalled ? View.VISIBLE : View.GONE); |
|
} |
|
if (searchInstalled) { |
|
getFragmentManager().beginTransaction().show(fragmentResults).commit(); |
|
} else { |
|
getFragmentManager().beginTransaction().hide(fragmentResults).commit(); |
|
} |
|
installmoduleText.setVisibility(searchInstalled ? View.GONE : View.VISIBLE); |
|
|
|
return true; |
|
} |
|
|
|
@Override |
|
protected void onNewIntent(Intent intent) { |
|
handleIntent(intent); |
|
refreshSearch(); |
|
} |
|
|
|
private void handleIntent(Intent intent) { |
|
|
|
lastUsedQuery = parseQuery(intent); |
|
|
|
// Is this actually a full HTTP URL? Then redirect this request to add the URL directly |
|
if (lastUsedQuery != null && (lastUsedQuery.startsWith("http") || lastUsedQuery.startsWith("https") || |
|
lastUsedQuery.startsWith("magnet") || lastUsedQuery.startsWith("file"))) { |
|
// Don't broadcast this intent; we can safely assume this is intended for Transdroid only |
|
Intent i = TorrentsActivity_.intent(this).get(); |
|
i.setData(Uri.parse(lastUsedQuery)); |
|
startActivity(i); |
|
finish(); |
|
} |
|
|
|
} |
|
|
|
@Override |
|
public boolean onSearchRequested() { |
|
if (searchMenu != null) { |
|
searchMenu.expandActionView(); |
|
} |
|
return true; |
|
} |
|
|
|
private OnItemClickListener onSearchSiteClicked = new OnItemClickListener() { |
|
|
|
@Override |
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
|
lastUsedSite = searchSites.get(position); |
|
refreshSearch(); |
|
} |
|
}; |
|
private AdapterView.OnItemSelectedListener onSearchSiteSelected = new AdapterView.OnItemSelectedListener() { |
|
@Override |
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { |
|
lastUsedSite = searchSites.get(position); |
|
refreshSearch(); |
|
} |
|
|
|
@Override |
|
public void onNothingSelected(AdapterView<?> parent) { |
|
} |
|
}; |
|
|
|
/** |
|
* Extracts the query string from the search {@link Intent} |
|
* |
|
* @return The query string that was entered by the user |
|
*/ |
|
private String parseQuery(Intent intent) { |
|
|
|
String query = null; |
|
if (intent.getAction().equals(Intent.ACTION_SEARCH)) { |
|
query = intent.getStringExtra(SearchManager.QUERY).trim(); |
|
} else if (intent.getAction().equals(Intent.ACTION_SEND)) { |
|
query = SendIntentHelper.cleanUpText(intent).trim(); |
|
} |
|
if (query != null && query.length() > 0) { |
|
|
|
// Remember this search query to later show as a suggestion |
|
suggestions.saveRecentQuery(query, null); |
|
return query; |
|
|
|
} |
|
return null; |
|
|
|
} |
|
|
|
@TargetApi(Build.VERSION_CODES.HONEYCOMB) |
|
@OptionsItem(android.R.id.home) |
|
protected void navigateUp() { |
|
TorrentsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start(); |
|
} |
|
|
|
@OptionsItem(R.id.action_refresh) |
|
protected void refreshSearch() { |
|
|
|
if (searchMenu != null) { |
|
// Close the search view in the action bar |
|
searchMenu.collapseActionView(); |
|
} |
|
|
|
if (lastUsedSite instanceof WebsearchSetting) { |
|
|
|
// Start a browser page directly to the requested search results |
|
WebsearchSetting websearch = (WebsearchSetting) lastUsedSite; |
|
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(websearch.getBaseUrl().replace("%s", lastUsedQuery)))); |
|
finish(); |
|
|
|
} else if (lastUsedSite instanceof SearchSite) { |
|
|
|
// Save the search site currently used to search for future usage |
|
applicationSettings.setLastUsedSearchSite(lastUsedSite); |
|
// Update the activity title (only shown on large devices) |
|
if (sitesSpinner == null && getSupportActionBar() != null) |
|
getSupportActionBar() |
|
.setTitle(NavigationHelper.buildCondensedFontString(getString(R.string.search_queryonsite, lastUsedQuery, lastUsedSite.getName()))); |
|
// Ask the results fragment to start a search for the specified query |
|
fragmentResults.startSearch(lastUsedQuery, (SearchSite) lastUsedSite, applicationSettings.getLastUsedSearchSortOrder()); |
|
|
|
} |
|
} |
|
|
|
@OptionsItem(R.id.action_downloadsearch) |
|
protected void downloadSearchModule() { |
|
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.transdroid.org/latest-search"))); |
|
} |
|
|
|
@OptionsItem(R.id.action_sort_added) |
|
protected void sortByDateAdded() { |
|
if (applicationSettings.getLastUsedSearchSortOrder() == SearchSortOrder.Combined) { |
|
return; |
|
} |
|
invalidateOptionsMenu(); |
|
applicationSettings.setLastUsedSearchSortOrder(SearchSortOrder.Combined); |
|
refreshSearch(); |
|
} |
|
|
|
@OptionsItem(R.id.action_sort_seeders) |
|
protected void sortBySeeders() { |
|
if (applicationSettings.getLastUsedSearchSortOrder() == SearchSortOrder.BySeeders) { |
|
return; |
|
} |
|
invalidateOptionsMenu(); |
|
applicationSettings.setLastUsedSearchSortOrder(SearchSortOrder.BySeeders); |
|
refreshSearch(); |
|
} |
|
}
|
|
|