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.
296 lines
11 KiB
296 lines
11 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.widget; |
|
|
|
import android.annotation.SuppressLint; |
|
import android.annotation.TargetApi; |
|
import android.appwidget.AppWidgetManager; |
|
import android.content.Intent; |
|
import android.os.Build; |
|
import android.os.Bundle; |
|
import androidx.appcompat.app.ActionBar; |
|
import androidx.appcompat.app.AppCompatActivity; |
|
import android.view.View; |
|
import android.view.View.OnClickListener; |
|
import android.widget.CheckBox; |
|
import android.widget.CompoundButton; |
|
import android.widget.CompoundButton.OnCheckedChangeListener; |
|
import android.widget.ListView; |
|
import android.widget.Spinner; |
|
import android.widget.TextView; |
|
|
|
import org.androidannotations.annotations.AfterViews; |
|
import org.androidannotations.annotations.Background; |
|
import org.androidannotations.annotations.Bean; |
|
import org.androidannotations.annotations.EActivity; |
|
import org.androidannotations.annotations.ItemSelect; |
|
import org.androidannotations.annotations.UiThread; |
|
import org.androidannotations.annotations.ViewById; |
|
import org.transdroid.R; |
|
import org.transdroid.core.app.settings.ApplicationSettings; |
|
import org.transdroid.core.app.settings.ServerSetting; |
|
import org.transdroid.core.app.settings.SystemSettings; |
|
import org.transdroid.core.gui.lists.SimpleListItemSpinnerAdapter; |
|
import org.transdroid.core.gui.lists.SortByListItem; |
|
import org.transdroid.core.gui.log.Log; |
|
import org.transdroid.core.gui.navigation.StatusType; |
|
import org.transdroid.core.gui.navigation.StatusType.StatusTypeFilter; |
|
import org.transdroid.core.service.ConnectivityHelper; |
|
import org.transdroid.daemon.Daemon; |
|
import org.transdroid.daemon.IDaemonAdapter; |
|
import org.transdroid.daemon.Label; |
|
import org.transdroid.daemon.Torrent; |
|
import org.transdroid.daemon.TorrentsComparator; |
|
import org.transdroid.daemon.TorrentsSortBy; |
|
import org.transdroid.daemon.task.DaemonTaskResult; |
|
import org.transdroid.daemon.task.RetrieveTask; |
|
import org.transdroid.daemon.task.RetrieveTaskSuccessResult; |
|
import org.transdroid.daemon.util.FileSizeConverter; |
|
|
|
import java.util.ArrayList; |
|
import java.util.Collections; |
|
import java.util.List; |
|
|
|
@TargetApi(Build.VERSION_CODES.HONEYCOMB) |
|
@EActivity(resName = "activity_widgetconfig") |
|
public class ListWidgetConfigActivity extends AppCompatActivity { |
|
|
|
// Views and adapters |
|
@ViewById |
|
protected Spinner serverSpinner, filterSpinner, sortSpinner; |
|
@ViewById |
|
protected CheckBox reverseorderCheckBox, showstatusCheckBox; |
|
@ViewById |
|
protected TextView filterText, serverText, errorText; |
|
@ViewById |
|
protected TextView downcountText, upcountText, downcountSign, upcountSign, downspeedText, upspeedText; |
|
@ViewById |
|
protected ListView torrentsList; |
|
@ViewById |
|
protected View navigationView, serverstatusView; |
|
// Settings and helpers |
|
@Bean |
|
protected Log log; |
|
@Bean |
|
protected ConnectivityHelper connectivityHelper; |
|
@Bean |
|
protected ApplicationSettings applicationSettings; |
|
@Bean |
|
protected SystemSettings systemSettings; |
|
protected OnCheckedChangeListener reverseorderCheckedChanged = new OnCheckedChangeListener() { |
|
@Override |
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { |
|
filterTorrents(); |
|
} |
|
}; |
|
protected OnCheckedChangeListener showstatusCheckChanged = new OnCheckedChangeListener() { |
|
@Override |
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { |
|
navigationView.setVisibility(showstatusCheckBox.isChecked() ? View.GONE : View.VISIBLE); |
|
serverstatusView.setVisibility(showstatusCheckBox.isChecked() ? View.VISIBLE : View.GONE); |
|
} |
|
}; |
|
private List<Torrent> previewTorrents = null; |
|
private int appWidgetId; |
|
private OnClickListener doneClicked = new OnClickListener() { |
|
@Override |
|
public void onClick(View v) { |
|
|
|
// All spinner have to be initialised already |
|
if (serverSpinner.getSelectedItem() == null) { |
|
return; |
|
} |
|
if (filterSpinner.getSelectedItem() == null) { |
|
return; |
|
} |
|
if (sortSpinner.getSelectedItem() == null) { |
|
return; |
|
} |
|
|
|
// Store these user preferences |
|
int server = ((ServerSetting) serverSpinner.getSelectedItem()).getOrder(); |
|
StatusType statusType = ((StatusTypeFilter) filterSpinner.getSelectedItem()).getStatusType(); |
|
TorrentsSortBy sortBy = ((SortByListItem) sortSpinner.getSelectedItem()).getSortBy(); |
|
boolean reverseSort = reverseorderCheckBox.isChecked(); |
|
boolean showstatus = showstatusCheckBox.isChecked(); |
|
ListWidgetConfig config = new ListWidgetConfig(server, statusType, sortBy, reverseSort, showstatus); |
|
applicationSettings.setWidgetConfig(appWidgetId, config); |
|
|
|
// Return the widget configuration result |
|
AppWidgetManager manager = AppWidgetManager.getInstance(ListWidgetConfigActivity.this); |
|
manager.updateAppWidget(appWidgetId, ListWidgetProvider.buildRemoteViews(getApplicationContext(), appWidgetId, config)); |
|
manager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.torrents_list); |
|
setResult(RESULT_OK, new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)); |
|
finish(); |
|
|
|
} |
|
}; |
|
|
|
@Override |
|
protected void onCreate(Bundle savedInstanceState) { |
|
|
|
super.onCreate(savedInstanceState); |
|
if (getIntent() == null || getIntent().getExtras() == null || |
|
!getIntent().hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) { |
|
// Invalid configuration; return canceled result |
|
setResult(RESULT_CANCELED, new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)); |
|
finish(); |
|
} |
|
|
|
// Get the appwidget ID we are configuring |
|
appWidgetId = getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); |
|
// Set preliminary canceled result and continue with the initialisation |
|
setResult(RESULT_CANCELED, new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)); |
|
|
|
} |
|
|
|
@AfterViews |
|
protected void init() { |
|
|
|
// Populate the selection spinners with custom array adapters |
|
List<SortByListItem> sortOrders = new ArrayList<>(); |
|
for (TorrentsSortBy order : TorrentsSortBy.values()) { |
|
sortOrders.add(new SortByListItem(this, order)); |
|
} |
|
serverSpinner.setAdapter(new SimpleListItemSpinnerAdapter<>(this, 0, applicationSettings.getAllServerSettings())); |
|
filterSpinner.setAdapter(new SimpleListItemSpinnerAdapter<>(this, 0, StatusType.getAllStatusTypes(this))); |
|
sortSpinner.setAdapter(new SimpleListItemSpinnerAdapter<>(this, 0, sortOrders)); |
|
reverseorderCheckBox.setOnCheckedChangeListener(reverseorderCheckedChanged); |
|
showstatusCheckBox.setOnCheckedChangeListener(showstatusCheckChanged); |
|
torrentsList.setEmptyView(errorText); |
|
|
|
// Set up action bar with a done button |
|
// Inspired by NoNonsenseNotes's ListWidgetConfig.java (Apache License, Version 2.0) |
|
if (getSupportActionBar() != null) { |
|
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, |
|
ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE); |
|
@SuppressLint("InflateParams") // Uses local activity theme correctly, so missing the inflation parent is okay |
|
View doneButtonFrame = getLayoutInflater().inflate(R.layout.actionbar_donebutton, null); |
|
doneButtonFrame.findViewById(R.id.actionbar_done).setOnClickListener(doneClicked); |
|
getSupportActionBar().setCustomView(doneButtonFrame); |
|
} |
|
|
|
} |
|
|
|
@ItemSelect |
|
protected void serverSpinnerItemSelected(boolean selected, ServerSetting server) { |
|
serverText.setText(server.getName()); |
|
loadTorrents(); |
|
} |
|
|
|
@ItemSelect |
|
protected void filterSpinnerItemSelected(boolean selected, StatusTypeFilter statusTypeFilter) { |
|
filterText.setText(statusTypeFilter.getName()); |
|
filterTorrents(); |
|
} |
|
|
|
@ItemSelect |
|
protected void sortSpinnerItemSelected(boolean selected, SortByListItem sortByListItem) { |
|
filterTorrents(); |
|
} |
|
|
|
@Background |
|
protected void loadTorrents() { |
|
|
|
if (serverSpinner.getSelectedItem() == null) { |
|
return; |
|
} |
|
|
|
// Create a connection object and retrieve the live torrents |
|
IDaemonAdapter connection = |
|
((ServerSetting) serverSpinner.getSelectedItem()).createServerAdapter(connectivityHelper.getConnectedNetworkName(), this); |
|
DaemonTaskResult result = RetrieveTask.create(connection).execute(log); |
|
if (result instanceof RetrieveTaskSuccessResult) { |
|
// Success; show the active torrents in the widget preview |
|
onTorrentsRetrieved(((RetrieveTaskSuccessResult) result).getTorrents(), ((RetrieveTaskSuccessResult) result).getLabels()); |
|
} else { |
|
// Can't connect right now; provide a nice error message |
|
showError(false); |
|
} |
|
|
|
} |
|
|
|
@UiThread |
|
protected void onTorrentsRetrieved(List<Torrent> torrents, List<Label> labels) { |
|
previewTorrents = torrents; |
|
filterTorrents(); |
|
} |
|
|
|
protected void filterTorrents() { |
|
|
|
// All spinners have to be initialised already |
|
if (serverSpinner.getSelectedItem() == null) { |
|
return; |
|
} |
|
if (filterSpinner.getSelectedItem() == null) { |
|
return; |
|
} |
|
if (sortSpinner.getSelectedItem() == null) { |
|
return; |
|
} |
|
if (previewTorrents == null) { |
|
return; |
|
} |
|
|
|
// Get the already loaded torrents and filter and sort them |
|
ArrayList<Torrent> filteredTorrents = new ArrayList<>(previewTorrents.size()); |
|
StatusTypeFilter statusTypeFilter = (StatusTypeFilter) filterSpinner.getSelectedItem(); |
|
boolean dormantAsInactive = systemSettings.treatDormantAsInactive(); |
|
for (Torrent torrent : previewTorrents) { |
|
if (statusTypeFilter.matches(torrent, dormantAsInactive)) { |
|
filteredTorrents.add(torrent); |
|
} |
|
} |
|
if (filteredTorrents.size() == 0) { |
|
showError(true); |
|
return; |
|
} |
|
TorrentsSortBy sortBy = ((SortByListItem) sortSpinner.getSelectedItem()).getSortBy(); |
|
Daemon serverType = filteredTorrents.get(0).getDaemon(); |
|
Collections.sort(filteredTorrents, new TorrentsComparator(serverType, sortBy, reverseorderCheckBox.isChecked())); |
|
|
|
// Update the server status count and speeds |
|
int downcount = 0, upcount = 0, downspeed = 0, upspeed = 0; |
|
for (Torrent torrent : previewTorrents) { |
|
if (torrent.isDownloading(dormantAsInactive)) { |
|
downcount++; |
|
upcount++; |
|
} else if (torrent.isSeeding(dormantAsInactive)) { |
|
upcount++; |
|
} |
|
downspeed += torrent.getRateDownload(); |
|
upspeed += torrent.getRateUpload(); |
|
} |
|
downcountText.setText(Integer.toString(downcount)); |
|
upcountText.setText(Integer.toString(upcount)); |
|
downspeedText.setText(FileSizeConverter.getSize(downspeed) + "/s"); |
|
upspeedText.setText(FileSizeConverter.getSize(upspeed) + "/s"); |
|
|
|
// Finally update the widget preview with the live, filtered and sorted torrents list |
|
torrentsList.setAdapter(new ListWidgetPreviewAdapter(this, 0, filteredTorrents)); |
|
torrentsList.setVisibility(View.VISIBLE); |
|
errorText.setVisibility(View.GONE); |
|
} |
|
|
|
@UiThread |
|
protected void showError(boolean emptyResults) { |
|
torrentsList.setVisibility(View.GONE); |
|
errorText.setVisibility(View.VISIBLE); |
|
errorText.setText(emptyResults ? R.string.navigation_emptytorrents : R.string.error_httperror); |
|
} |
|
|
|
}
|
|
|