Browse Source

.editorconfig part 3: Entry rearrangement

pull/559/head
TacoTheDank 4 years ago
parent
commit
6dc1b85b2a
  1. 2
      app/src/main/AndroidManifest.xml
  2. 8
      app/src/main/java/org/transdroid/core/app/search/SearchHelper.java
  3. 43
      app/src/main/java/org/transdroid/core/app/search/SearchResult.java
  4. 56
      app/src/main/java/org/transdroid/core/app/settings/ApplicationSettings.java
  5. 2
      app/src/main/java/org/transdroid/core/app/settings/RssfeedSetting.java
  6. 9
      app/src/main/java/org/transdroid/core/app/settings/SettingsPersistence.java
  7. 3
      app/src/main/java/org/transdroid/core/app/settings/WebsearchSetting.java
  8. 3
      app/src/main/java/org/transdroid/core/gui/DetailsActivity.java
  9. 340
      app/src/main/java/org/transdroid/core/gui/DetailsFragment.java
  10. 26
      app/src/main/java/org/transdroid/core/gui/ServerPickerDialog.java
  11. 11
      app/src/main/java/org/transdroid/core/gui/ServerStatusView.java
  12. 69
      app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java
  13. 259
      app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java
  14. 67
      app/src/main/java/org/transdroid/core/gui/lists/LocalTorrent.java
  15. 4
      app/src/main/java/org/transdroid/core/gui/lists/PiecesMapView.java
  16. 12
      app/src/main/java/org/transdroid/core/gui/lists/SimpleListItemAdapter.java
  17. 3
      app/src/main/java/org/transdroid/core/gui/lists/TorrentFilePriorityLayout.java
  18. 37
      app/src/main/java/org/transdroid/core/gui/lists/TorrentProgressBar.java
  19. 3
      app/src/main/java/org/transdroid/core/gui/lists/TorrentStatusLayout.java
  20. 3
      app/src/main/java/org/transdroid/core/gui/lists/TorrentsAdapter.java
  21. 34
      app/src/main/java/org/transdroid/core/gui/log/ErrorLogEntry.java
  22. 56
      app/src/main/java/org/transdroid/core/gui/navigation/DialogHelper.java
  23. 6
      app/src/main/java/org/transdroid/core/gui/navigation/FilterListAdapter.java
  24. 86
      app/src/main/java/org/transdroid/core/gui/navigation/Label.java
  25. 132
      app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java
  26. 22
      app/src/main/java/org/transdroid/core/gui/navigation/SelectionModificationSpinner.java
  27. 26
      app/src/main/java/org/transdroid/core/gui/navigation/SetTransferRatesDialog.java
  28. 29
      app/src/main/java/org/transdroid/core/gui/navigation/StatusType.java
  29. 116
      app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java
  30. 8
      app/src/main/java/org/transdroid/core/gui/rss/RssItemsFragment.java
  31. 3
      app/src/main/java/org/transdroid/core/gui/rss/RssfeedsAdapter.java
  32. 3
      app/src/main/java/org/transdroid/core/gui/rss/RssitemsAdapter.java
  33. 39
      app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java
  34. 3
      app/src/main/java/org/transdroid/core/gui/search/SearchResultsAdapter.java
  35. 135
      app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java
  36. 3
      app/src/main/java/org/transdroid/core/gui/search/SearchSitesAdapter.java
  37. 50
      app/src/main/java/org/transdroid/core/gui/settings/HelpSettingsActivity.java
  38. 15
      app/src/main/java/org/transdroid/core/gui/settings/KeyBoundPreferencesActivity.java
  39. 17
      app/src/main/java/org/transdroid/core/gui/settings/RssfeedPreference.java
  40. 17
      app/src/main/java/org/transdroid/core/gui/settings/ServerPreference.java
  41. 4
      app/src/main/java/org/transdroid/core/gui/settings/ServerSettingsActivity.java
  42. 24
      app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java
  43. 17
      app/src/main/java/org/transdroid/core/gui/settings/WebsearchPreference.java
  44. 85
      app/src/main/java/org/transdroid/core/rssparser/Channel.java
  45. 92
      app/src/main/java/org/transdroid/core/rssparser/Item.java
  46. 17
      app/src/main/java/org/transdroid/core/seedbox/SeedboxPreference.java
  47. 3
      app/src/main/java/org/transdroid/core/seedbox/XirvikSharedSettingsActivity.java
  48. 12
      app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java
  49. 4
      app/src/main/java/org/transdroid/daemon/Daemon.java
  50. 20
      app/src/main/java/org/transdroid/daemon/DaemonException.java
  51. 11
      app/src/main/java/org/transdroid/daemon/DaemonMethod.java
  52. 19
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeRemoteRssChannel.java
  53. 20
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeRemoteRssItem.java
  54. 5
      app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcClient.java
  55. 33
      app/src/main/java/org/transdroid/daemon/Label.java
  56. 11
      app/src/main/java/org/transdroid/daemon/Priority.java
  57. 38
      app/src/main/java/org/transdroid/daemon/Tfb4rt/Tfb4rtAdapter.java
  58. 32
      app/src/main/java/org/transdroid/daemon/Torrent.java
  59. 19
      app/src/main/java/org/transdroid/daemon/TorrentDetails.java
  60. 80
      app/src/main/java/org/transdroid/daemon/TorrentFile.java
  61. 11
      app/src/main/java/org/transdroid/daemon/TorrentFilesSortBy.java
  62. 11
      app/src/main/java/org/transdroid/daemon/TorrentStatus.java
  63. 11
      app/src/main/java/org/transdroid/daemon/TorrentsSortBy.java
  64. 3
      app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java
  65. 20
      app/src/main/java/org/transdroid/daemon/Utorrent/data/UTorrentRemoteRssChannel.java
  66. 22
      app/src/main/java/org/transdroid/daemon/Utorrent/data/UTorrentRemoteRssItem.java
  67. 74
      app/src/main/java/org/transdroid/daemon/Vuze/VuzeXmlOverHttpClient.java
  68. 19
      app/src/main/java/org/transdroid/daemon/util/FileSizeConverter.java
  69. 8
      app/src/main/res/drawable-night/details_list_background.xml
  70. 8
      app/src/main/res/drawable/activatable_background.xml
  71. 8
      app/src/main/res/drawable/details_list_background.xml
  72. 8
      app/src/main/res/layout-land/dialog_color_picker.xml
  73. 2
      app/src/main/res/layout-w600dp/activity_search.xml
  74. 22
      app/src/main/res/layout-w600dp/activity_torrents.xml
  75. 30
      app/src/main/res/layout-w900dp/activity_torrents.xml
  76. 4
      app/src/main/res/layout/actionbar_addbutton.xml
  77. 4
      app/src/main/res/layout/actionbar_donebutton.xml
  78. 4
      app/src/main/res/layout/actionbar_serverselection.xml
  79. 18
      app/src/main/res/layout/actionbar_serverstatus.xml
  80. 2
      app/src/main/res/layout/activity_search.xml
  81. 14
      app/src/main/res/layout/activity_torrents.xml
  82. 2
      app/src/main/res/layout/activity_widgetconfig.xml
  83. 8
      app/src/main/res/layout/dialog_about.xml
  84. 8
      app/src/main/res/layout/dialog_changelog.xml
  85. 6
      app/src/main/res/layout/dialog_color_picker.xml
  86. 16
      app/src/main/res/layout/dialog_setlabel.xml
  87. 4
      app/src/main/res/layout/dialog_trackers.xml
  88. 8
      app/src/main/res/layout/fragment_details.xml
  89. 22
      app/src/main/res/layout/fragment_details_header.xml
  90. 4
      app/src/main/res/layout/fragment_remoterss.xml
  91. 2
      app/src/main/res/layout/fragment_rssfeeds.xml
  92. 2
      app/src/main/res/layout/fragment_rssitems.xml
  93. 2
      app/src/main/res/layout/fragment_searchresults.xml
  94. 8
      app/src/main/res/layout/fragment_torrents.xml
  95. 4
      app/src/main/res/layout/list_item_filter.xml
  96. 8
      app/src/main/res/layout/list_item_remoterssitem.xml
  97. 6
      app/src/main/res/layout/list_item_rssfeed.xml
  98. 4
      app/src/main/res/layout/list_item_rssitem.xml
  99. 10
      app/src/main/res/layout/list_item_searchresult.xml
  100. 4
      app/src/main/res/layout/list_item_searchsite.xml
  101. Some files were not shown because too many files have changed in this diff Show More

2
app/src/main/AndroidManifest.xml

@ -50,9 +50,9 @@
<application <application
android:name=".core.gui.TransdroidApp_" android:name=".core.gui.TransdroidApp_"
android:allowBackup="true" android:allowBackup="true"
android:banner="@drawable/banner"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:banner="@drawable/banner"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/Theme.AppCompat" android:theme="@style/Theme.AppCompat"
android:usesCleartextTraffic="true"> android:usesCleartextTraffic="true">

8
app/src/main/java/org/transdroid/core/app/search/SearchHelper.java

@ -53,10 +53,6 @@ public class SearchHelper {
@RootContext @RootContext
protected Context context; protected Context context;
public enum SearchSortOrder {
Combined, BySeeders
}
/** /**
* Return whether the Torrent Search package is installed and available to query against * Return whether the Torrent Search package is installed and available to query against
* *
@ -169,4 +165,8 @@ public class SearchHelper {
} }
} }
public enum SearchSortOrder {
Combined, BySeeders
}
} }

43
app/src/main/java/org/transdroid/core/app/search/SearchResult.java

@ -28,6 +28,15 @@ import java.util.Date;
*/ */
public class SearchResult implements Parcelable { public class SearchResult implements Parcelable {
public static final Parcelable.Creator<SearchResult> CREATOR = new Parcelable.Creator<SearchResult>() {
public SearchResult createFromParcel(Parcel in) {
return new SearchResult(in);
}
public SearchResult[] newArray(int size) {
return new SearchResult[size];
}
};
private final int id; private final int id;
private final String name; private final String name;
private final String torrentUrl; private final String torrentUrl;
@ -49,6 +58,18 @@ public class SearchResult implements Parcelable {
this.leechers = leechers; this.leechers = leechers;
} }
public SearchResult(Parcel in) {
id = in.readInt();
name = in.readString();
torrentUrl = in.readString();
detailsUrl = in.readString();
size = in.readString();
long addedOnIn = in.readLong();
addedOn = addedOnIn == -1 ? null : new Date(addedOnIn);
seeders = in.readString();
leechers = in.readString();
}
public int getId() { public int getId() {
return id; return id;
} }
@ -98,26 +119,4 @@ public class SearchResult implements Parcelable {
out.writeString(leechers); out.writeString(leechers);
} }
public static final Parcelable.Creator<SearchResult> CREATOR = new Parcelable.Creator<SearchResult>() {
public SearchResult createFromParcel(Parcel in) {
return new SearchResult(in);
}
public SearchResult[] newArray(int size) {
return new SearchResult[size];
}
};
public SearchResult(Parcel in) {
id = in.readInt();
name = in.readString();
torrentUrl = in.readString();
detailsUrl = in.readString();
size = in.readString();
long addedOnIn = in.readLong();
addedOn = addedOnIn == -1 ? null : new Date(addedOnIn);
seeders = in.readString();
leechers = in.readString();
}
} }

56
app/src/main/java/org/transdroid/core/app/settings/ApplicationSettings.java

@ -60,9 +60,9 @@ public class ApplicationSettings {
@RootContext @RootContext
protected Context context; protected Context context;
private SharedPreferences prefs;
@Bean @Bean
protected SearchHelper searchHelper; protected SearchHelper searchHelper;
private SharedPreferences prefs;
protected ApplicationSettings(Context context) { protected ApplicationSettings(Context context) {
prefs = PreferenceManager.getDefaultSharedPreferences(context); prefs = PreferenceManager.getDefaultSharedPreferences(context);
@ -348,6 +348,15 @@ public class ApplicationSettings {
return getServerSetting(last); return getServerSetting(last);
} }
/**
* Registers some server as being the last used by the user
*
* @param server The settings of the server that the user last used
*/
public void setLastUsedServer(ServerSetting server) {
setLastUsedServerKey(server.getOrder());
}
/** /**
* Returns the order number/unique key of the server that the used last used; use with getServerSettings(int) or * Returns the order number/unique key of the server that the used last used; use with getServerSettings(int) or
* call getLastUsedServer directly. WARNING: the returned integer may no longer refer to a known server settings * call getLastUsedServer directly. WARNING: the returned integer may no longer refer to a known server settings
@ -359,15 +368,6 @@ public class ApplicationSettings {
return prefs.getInt("system_lastusedserver", -1); return prefs.getInt("system_lastusedserver", -1);
} }
/**
* Registers some server as being the last used by the user
*
* @param server The settings of the server that the user last used
*/
public void setLastUsedServer(ServerSetting server) {
setLastUsedServerKey(server.getOrder());
}
/** /**
* Registers the order number/unique key of some server as being last used by the user * Registers the order number/unique key of some server as being last used by the user
* *
@ -590,6 +590,15 @@ public class ApplicationSettings {
.getStatus(prefs.getInt("system_lastusedsortorder", TorrentsSortBy.Alphanumeric.getCode())); .getStatus(prefs.getInt("system_lastusedsortorder", TorrentsSortBy.Alphanumeric.getCode()));
} }
/**
* Returns the search sort order property that the user last used.
*
* @return The last used sort order enumeration value
*/
public SearchSortOrder getLastUsedSearchSortOrder() {
return SearchSortOrder.values()[(prefs.getInt("system_lastusedsearchsortorder", SearchSortOrder.BySeeders.ordinal()))];
}
/** /**
* Registers the search list sort order as being last used by the user * Registers the search list sort order as being last used by the user
* *
@ -601,15 +610,6 @@ public class ApplicationSettings {
edit.apply(); edit.apply();
} }
/**
* Returns the search sort order property that the user last used.
*
* @return The last used sort order enumeration value
*/
public SearchSortOrder getLastUsedSearchSortOrder() {
return SearchSortOrder.values()[(prefs.getInt("system_lastusedsearchsortorder", SearchSortOrder.BySeeders.ordinal()))];
}
/** /**
* Returns the sort order direction that the user last used. Use together with {@link #getLastUsedSortOrder()} to * Returns the sort order direction that the user last used. Use together with {@link #getLastUsedSortOrder()} to
* get the full last used sort settings. * get the full last used sort settings.
@ -686,6 +686,15 @@ public class ApplicationSettings {
return null; return null;
} }
/**
* Registers the unique key of some web search or in-app search site as being last used by the user
*
* @param site The site settings to register as being last used
*/
public void setLastUsedSearchSite(SearchSetting site) {
prefs.edit().putString("header_setsearchsite", site.getKey()).apply();
}
/** /**
* Returns the unique key of the site that the used last used or selected as default form the main settings; use * Returns the unique key of the site that the used last used or selected as default form the main settings; use
* with getLastUsedSearchSite directly. WARNING: the returned string may no longer refer to a known web search site * with getLastUsedSearchSite directly. WARNING: the returned string may no longer refer to a known web search site
@ -698,15 +707,6 @@ public class ApplicationSettings {
return prefs.getString("header_setsearchsite", null); return prefs.getString("header_setsearchsite", null);
} }
/**
* Registers the unique key of some web search or in-app search site as being last used by the user
*
* @param site The site settings to register as being last used
*/
public void setLastUsedSearchSite(SearchSetting site) {
prefs.edit().putString("header_setsearchsite", site.getKey()).apply();
}
/** /**
* Returns the statistics of this server as it was last seen by the background server checker service. * Returns the statistics of this server as it was last seen by the background server checker service.
* *

2
app/src/main/java/org/transdroid/core/app/settings/RssfeedSetting.java

@ -39,8 +39,8 @@ public class RssfeedSetting implements SimpleListItem {
private final boolean alarm; private final boolean alarm;
private final String excludeFilter; private final String excludeFilter;
private final String includeFilter; private final String includeFilter;
private Date lastViewed;
private final String lastViewedItemUrl; private final String lastViewedItemUrl;
private Date lastViewed;
public RssfeedSetting(int order, String name, String baseUrl, boolean needsAuth, boolean alarm, String excludeFilter, String includeFilter, Date lastViewed, public RssfeedSetting(int order, String name, String baseUrl, boolean needsAuth, boolean alarm, String excludeFilter, String includeFilter, Date lastViewed,
String lastViewedItemUrl) { String lastViewedItemUrl) {

9
app/src/main/java/org/transdroid/core/app/settings/SettingsPersistence.java

@ -44,15 +44,14 @@ import java.io.OutputStream;
@EBean(scope = Scope.Singleton) @EBean(scope = Scope.Singleton)
public class SettingsPersistence { public class SettingsPersistence {
@Bean
protected ApplicationSettings applicationSettings;
@Bean
protected SystemSettings systemSettings;
public static final String DEFAULT_SETTINGS_DIR = Environment.getExternalStorageDirectory().toString() public static final String DEFAULT_SETTINGS_DIR = Environment.getExternalStorageDirectory().toString()
+ "/Transdroid/"; + "/Transdroid/";
public static final String DEFAULT_SETTINGS_FILENAME = "settings.json"; public static final String DEFAULT_SETTINGS_FILENAME = "settings.json";
public static final File DEFAULT_SETTINGS_FILE = new File(DEFAULT_SETTINGS_DIR + DEFAULT_SETTINGS_FILENAME); public static final File DEFAULT_SETTINGS_FILE = new File(DEFAULT_SETTINGS_DIR + DEFAULT_SETTINGS_FILENAME);
@Bean
protected ApplicationSettings applicationSettings;
@Bean
protected SystemSettings systemSettings;
/** /**
* Reads the server, web searches, RSS feed, background service and system settings from a JSON-encoded String, such as when read via a QR code. * Reads the server, web searches, RSS feed, background service and system settings from a JSON-encoded String, such as when read via a QR code.

3
app/src/main/java/org/transdroid/core/app/settings/WebsearchSetting.java

@ -29,9 +29,8 @@ import org.transdroid.core.gui.search.SearchSetting;
*/ */
public class WebsearchSetting implements SimpleListItem, SearchSetting { public class WebsearchSetting implements SimpleListItem, SearchSetting {
private static final String DEFAULT_NAME = "Default";
public static final String KEY_PREFIX = "websearch_"; public static final String KEY_PREFIX = "websearch_";
private static final String DEFAULT_NAME = "Default";
private final int order; private final int order;
private final String name; private final String name;
private final String baseUrl; private final String baseUrl;

3
app/src/main/java/org/transdroid/core/gui/DetailsActivity.java

@ -106,13 +106,12 @@ public class DetailsActivity extends AppCompatActivity implements TorrentTasksEx
protected ConnectivityHelper connectivityHelper; protected ConnectivityHelper connectivityHelper;
@Bean @Bean
protected ApplicationSettings applicationSettings; protected ApplicationSettings applicationSettings;
private IDaemonAdapter currentConnection = null;
// Details view components // Details view components
@ViewById @ViewById
protected Toolbar selectionToolbar; protected Toolbar selectionToolbar;
@FragmentById(R.id.torrentdetails_fragment) @FragmentById(R.id.torrentdetails_fragment)
protected DetailsFragment fragmentDetails; protected DetailsFragment fragmentDetails;
private IDaemonAdapter currentConnection = null;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {

340
app/src/main/java/org/transdroid/core/gui/DetailsFragment.java

@ -96,8 +96,6 @@ public class DetailsFragment extends Fragment implements OnTrackersUpdatedListen
protected boolean isLoadingTorrent = false; protected boolean isLoadingTorrent = false;
@InstanceState @InstanceState
protected boolean hasCriticalError = false; protected boolean hasCriticalError = false;
private ServerSetting currentServerSettings = null;
// Views // Views
@ViewById @ViewById
protected View detailsContainer; protected View detailsContainer;
@ -113,6 +111,175 @@ public class DetailsFragment extends Fragment implements OnTrackersUpdatedListen
protected TextView emptyText, errorText; protected TextView emptyText, errorText;
@ViewById @ViewById
protected ProgressBar loadingProgress; protected ProgressBar loadingProgress;
private ServerSetting currentServerSettings = null;
private MultiChoiceModeListener onDetailsSelected = new MultiChoiceModeListener() {
SelectionManagerMode selectionManagerMode;
@Override
public boolean onCreateActionMode(final ActionMode mode, Menu menu) {
// Show contextual action bar to start/stop/remove/etc. torrents in batch mode
detailsMenu.setEnabled(false);
contextualMenu.setVisibility(View.VISIBLE);
contextualMenu.setOnMenuItemClickListener(new ActionMenuView.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
return onActionItemClicked(mode, menuItem);
}
});
contextualMenu.getMenu().clear();
getActivity().getMenuInflater().inflate(R.menu.fragment_details_cab_main, contextualMenu.getMenu());
Context themedContext = ((AppCompatActivity) 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;
}
@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());
contextualMenu.getMenu().findItem(R.id.action_download).setVisible(filePaths);
boolean filePriorities = currentServerSettings != null && Daemon.supportsFilePrioritySetting(currentServerSettings.getType());
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")
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Get checked torrents
List<TorrentFile> checked = new ArrayList<>();
for (int i = 0; i < detailsList.getCheckedItemPositions().size(); i++) {
if (detailsList.getCheckedItemPositions().valueAt(i) && i < detailsList.getAdapter().getCount() &&
detailsList.getAdapter().getItem(detailsList.getCheckedItemPositions().keyAt(i)) instanceof TorrentFile) {
checked.add((TorrentFile) detailsList.getAdapter().getItem(detailsList.getCheckedItemPositions().keyAt(i)));
}
}
int itemId = item.getItemId();
if (itemId == R.id.action_download) {
if (checked.size() < 1 || currentServerSettings == null) {
return true;
}
String urlBase = currentServerSettings.getFtpUrl();
if (urlBase == null || urlBase.equals("")) {
urlBase = "ftp://" + currentServerSettings.getAddress() + "/";
}
// Try using AndFTP intents
Intent andftpStart = new Intent(Intent.ACTION_PICK);
andftpStart.setDataAndType(Uri.parse(urlBase), "vnd.android.cursor.dir/lysesoft.andftp.uri");
andftpStart.putExtra("command_type", "download");
andftpStart.putExtra("ftp_pasv", "true");
if (Uri.parse(urlBase).getUserInfo() != null) {
andftpStart.putExtra("ftp_username", Uri.parse(urlBase).getUserInfo());
} else {
andftpStart.putExtra("ftp_username", currentServerSettings.getUsername());
}
if (currentServerSettings.getFtpPassword() != null && !currentServerSettings.getFtpPassword().equals("")) {
andftpStart.putExtra("ftp_password", currentServerSettings.getFtpPassword());
} else {
andftpStart.putExtra("ftp_password", currentServerSettings.getPassword());
}
// Note: AndFTP doesn't understand the directory that Environment.getExternalStoragePublicDirectory()
// uses :(
andftpStart.putExtra("local_folder", "/sdcard/Download");
for (int f = 0; f < checked.size(); f++) {
String file = checked.get(f).getRelativePath();
if (file != null) {
// If the file is directly in the root, AndFTP fails if we supply the proper path (like
// /file.pdf)
// Work around this bug by removing the leading / if no further directories are used in the path
if (file.startsWith("/") && file.indexOf("/", 1) < 0) {
file = file.substring(1);
}
andftpStart.putExtra("remote_file" + (f + 1), file);
}
}
if (andftpStart.resolveActivity(getActivity().getPackageManager()) != null) {
startActivity(andftpStart);
mode.finish();
return true;
}
// Try using a VIEW intent given an ftp:// scheme URI
String url = urlBase + checked.get(0).getRelativePath();
Intent simpleStart = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (simpleStart.resolveActivity(getActivity().getPackageManager()) != null) {
startActivity(simpleStart);
mode.finish();
return true;
}
// No app is available that can handle FTP downloads
SnackbarManager.show(Snackbar.with(getActivity()).text(getString(R.string.error_noftpapp, url)).type(SnackbarType.MULTI_LINE)
.colorResource(R.color.red));
mode.finish();
return true;
} else if (itemId == R.id.action_copytoclipboard) {
StringBuilder names = new StringBuilder();
for (int f = 0; f < checked.size(); f++) {
if (f != 0) {
names.append("\n");
}
names.append(checked.get(f).getName());
}
ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
clipboardManager.setPrimaryClip(ClipData.newPlainText("Transdroid", names.toString()));
mode.finish();
return true;
} else {
Priority priority = Priority.Off;
if (itemId == R.id.action_priority_low) {
priority = Priority.Low;
}
if (itemId == R.id.action_priority_normal) {
priority = Priority.Normal;
}
if (itemId == R.id.action_priority_high) {
priority = Priority.High;
}
if (getTasksExecutor() != null)
getTasksExecutor().updatePriority(torrent, checked, priority);
mode.finish();
return true;
}
}
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
selectionManagerMode.onItemCheckedStateChanged(mode, position, id, checked);
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// Resume autorefresh
if (getActivity() != null && getActivity() instanceof TorrentsActivity) {
((TorrentsActivity) getActivity()).stopRefresh = false;
((TorrentsActivity) getActivity()).startAutoRefresh();
}
selectionManagerMode.onDestroyActionMode(mode);
contextualMenu.setVisibility(View.GONE);
detailsMenu.setEnabled(true);
}
};
@AfterViews @AfterViews
protected void init() { protected void init() {
@ -516,175 +683,6 @@ public class DetailsFragment extends Fragment implements OnTrackersUpdatedListen
} }
} }
private MultiChoiceModeListener onDetailsSelected = new MultiChoiceModeListener() {
SelectionManagerMode selectionManagerMode;
@Override
public boolean onCreateActionMode(final ActionMode mode, Menu menu) {
// Show contextual action bar to start/stop/remove/etc. torrents in batch mode
detailsMenu.setEnabled(false);
contextualMenu.setVisibility(View.VISIBLE);
contextualMenu.setOnMenuItemClickListener(new ActionMenuView.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
return onActionItemClicked(mode, menuItem);
}
});
contextualMenu.getMenu().clear();
getActivity().getMenuInflater().inflate(R.menu.fragment_details_cab_main, contextualMenu.getMenu());
Context themedContext = ((AppCompatActivity) 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;
}
@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());
contextualMenu.getMenu().findItem(R.id.action_download).setVisible(filePaths);
boolean filePriorities = currentServerSettings != null && Daemon.supportsFilePrioritySetting(currentServerSettings.getType());
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")
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Get checked torrents
List<TorrentFile> checked = new ArrayList<>();
for (int i = 0; i < detailsList.getCheckedItemPositions().size(); i++) {
if (detailsList.getCheckedItemPositions().valueAt(i) && i < detailsList.getAdapter().getCount() &&
detailsList.getAdapter().getItem(detailsList.getCheckedItemPositions().keyAt(i)) instanceof TorrentFile) {
checked.add((TorrentFile) detailsList.getAdapter().getItem(detailsList.getCheckedItemPositions().keyAt(i)));
}
}
int itemId = item.getItemId();
if (itemId == R.id.action_download) {
if (checked.size() < 1 || currentServerSettings == null) {
return true;
}
String urlBase = currentServerSettings.getFtpUrl();
if (urlBase == null || urlBase.equals("")) {
urlBase = "ftp://" + currentServerSettings.getAddress() + "/";
}
// Try using AndFTP intents
Intent andftpStart = new Intent(Intent.ACTION_PICK);
andftpStart.setDataAndType(Uri.parse(urlBase), "vnd.android.cursor.dir/lysesoft.andftp.uri");
andftpStart.putExtra("command_type", "download");
andftpStart.putExtra("ftp_pasv", "true");
if (Uri.parse(urlBase).getUserInfo() != null) {
andftpStart.putExtra("ftp_username", Uri.parse(urlBase).getUserInfo());
} else {
andftpStart.putExtra("ftp_username", currentServerSettings.getUsername());
}
if (currentServerSettings.getFtpPassword() != null && !currentServerSettings.getFtpPassword().equals("")) {
andftpStart.putExtra("ftp_password", currentServerSettings.getFtpPassword());
} else {
andftpStart.putExtra("ftp_password", currentServerSettings.getPassword());
}
// Note: AndFTP doesn't understand the directory that Environment.getExternalStoragePublicDirectory()
// uses :(
andftpStart.putExtra("local_folder", "/sdcard/Download");
for (int f = 0; f < checked.size(); f++) {
String file = checked.get(f).getRelativePath();
if (file != null) {
// If the file is directly in the root, AndFTP fails if we supply the proper path (like
// /file.pdf)
// Work around this bug by removing the leading / if no further directories are used in the path
if (file.startsWith("/") && file.indexOf("/", 1) < 0) {
file = file.substring(1);
}
andftpStart.putExtra("remote_file" + (f + 1), file);
}
}
if (andftpStart.resolveActivity(getActivity().getPackageManager()) != null) {
startActivity(andftpStart);
mode.finish();
return true;
}
// Try using a VIEW intent given an ftp:// scheme URI
String url = urlBase + checked.get(0).getRelativePath();
Intent simpleStart = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (simpleStart.resolveActivity(getActivity().getPackageManager()) != null) {
startActivity(simpleStart);
mode.finish();
return true;
}
// No app is available that can handle FTP downloads
SnackbarManager.show(Snackbar.with(getActivity()).text(getString(R.string.error_noftpapp, url)).type(SnackbarType.MULTI_LINE)
.colorResource(R.color.red));
mode.finish();
return true;
} else if (itemId == R.id.action_copytoclipboard) {
StringBuilder names = new StringBuilder();
for (int f = 0; f < checked.size(); f++) {
if (f != 0) {
names.append("\n");
}
names.append(checked.get(f).getName());
}
ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
clipboardManager.setPrimaryClip(ClipData.newPlainText("Transdroid", names.toString()));
mode.finish();
return true;
} else {
Priority priority = Priority.Off;
if (itemId == R.id.action_priority_low) {
priority = Priority.Low;
}
if (itemId == R.id.action_priority_normal) {
priority = Priority.Normal;
}
if (itemId == R.id.action_priority_high) {
priority = Priority.High;
}
if (getTasksExecutor() != null)
getTasksExecutor().updatePriority(torrent, checked, priority);
mode.finish();
return true;
}
}
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
selectionManagerMode.onItemCheckedStateChanged(mode, position, id, checked);
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// Resume autorefresh
if (getActivity() != null && getActivity() instanceof TorrentsActivity) {
((TorrentsActivity) getActivity()).stopRefresh = false;
((TorrentsActivity) getActivity()).startAutoRefresh();
}
selectionManagerMode.onDestroyActionMode(mode);
contextualMenu.setVisibility(View.GONE);
detailsMenu.setEnabled(true);
}
};
/** /**
* Returns the object responsible for executing torrent tasks against a connected server * Returns the object responsible for executing torrent tasks against a connected server
* *

26
app/src/main/java/org/transdroid/core/gui/ServerPickerDialog.java

@ -30,19 +30,6 @@ import java.util.List;
public class ServerPickerDialog extends DialogFragment { public class ServerPickerDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String[] serverNames = getArguments().getStringArray("serverNames");
return new AlertDialog.Builder(getActivity()).setTitle(R.string.navigation_pickserver)
.setItems(serverNames, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (getActivity() != null && getActivity() instanceof TorrentsActivity)
((TorrentsActivity) getActivity()).switchServerAndAddFromIntent(which);
}
}).create();
}
/** /**
* Opens a dialog that allows the selection of a configured server (manual or seedbox). The calling activity will * Opens a dialog that allows the selection of a configured server (manual or seedbox). The calling activity will
* receive a callback on its switchServerAndAddFromIntent(int) method. * receive a callback on its switchServerAndAddFromIntent(int) method.
@ -63,4 +50,17 @@ public class ServerPickerDialog extends DialogFragment {
dialog.show(activity.getFragmentManager(), "serverpicker"); dialog.show(activity.getFragmentManager(), "serverpicker");
} }
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String[] serverNames = getArguments().getStringArray("serverNames");
return new AlertDialog.Builder(getActivity()).setTitle(R.string.navigation_pickserver)
.setItems(serverNames, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (getActivity() != null && getActivity() instanceof TorrentsActivity)
((TorrentsActivity) getActivity()).switchServerAndAddFromIntent(which);
}
}).create();
}
} }

11
app/src/main/java/org/transdroid/core/gui/ServerStatusView.java

@ -42,6 +42,11 @@ public class ServerStatusView extends RelativeLayout implements OnRatesPickedLis
@ViewById @ViewById
protected View speedswrapperLayout; protected View speedswrapperLayout;
private TorrentsActivity activity; private TorrentsActivity activity;
private OnClickListener onStartDownPickerClicked = new OnClickListener() {
public void onClick(View v) {
SetTransferRatesDialog.show(getContext(), ServerStatusView.this);
}
};
public ServerStatusView(Context context) { public ServerStatusView(Context context) {
super(context); super(context);
@ -100,12 +105,6 @@ public class ServerStatusView extends RelativeLayout implements OnRatesPickedLis
} }
private OnClickListener onStartDownPickerClicked = new OnClickListener() {
public void onClick(View v) {
SetTransferRatesDialog.show(getContext(), ServerStatusView.this);
}
};
@Override @Override
public void onRatesPicked(int maxDownloadSpeed, int maxUploadSpeed) { public void onRatesPicked(int maxDownloadSpeed, int maxUploadSpeed) {
activity.updateMaxSpeeds(maxDownloadSpeed, maxUploadSpeed); activity.updateMaxSpeeds(maxDownloadSpeed, maxUploadSpeed);

69
app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java

@ -188,12 +188,6 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE
protected ListView filtersList; protected ListView filtersList;
@ViewById @ViewById
protected SearchView filterSearch; protected SearchView filterSearch;
private ListView navigationList;
private FilterListAdapter navigationListAdapter;
private ServerSelectionView serverSelectionView;
private ServerStatusView serverStatusView;
private ActionBarDrawerToggle drawerToggle;
// Settings // Settings
@Bean @Bean
protected ApplicationSettings applicationSettings; protected ApplicationSettings applicationSettings;
@ -214,6 +208,11 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE
protected DetailsFragment fragmentDetails; protected DetailsFragment fragmentDetails;
@InstanceState @InstanceState
boolean firstStart = true; boolean firstStart = true;
private ListView navigationList;
private FilterListAdapter navigationListAdapter;
private ServerSelectionView serverSelectionView;
private ServerStatusView serverStatusView;
private ActionBarDrawerToggle drawerToggle;
private MenuItem searchMenu = null; private MenuItem searchMenu = null;
private IDaemonAdapter currentConnection = null; private IDaemonAdapter currentConnection = null;
@ -222,6 +221,34 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE
private String awaitingAddLocalFile; private String awaitingAddLocalFile;
private String awaitingAddTitle; private String awaitingAddTitle;
/**
* Handles item selections on the dedicated list of filter items
*/
private OnItemClickListener onFilterListItemClicked = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
navigationList.setItemChecked(position, true);
Object item = navigationList.getAdapter().getItem(position);
if (item instanceof SimpleListItem) {
filterSelected((SimpleListItem) item, false);
}
if (drawerLayout != null)
drawerLayout.closeDrawer(drawerContainer);
}
};
private SearchView.OnQueryTextListener filterQueryTextChanged = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// Redirect to filter method which will directly apply it
filterTorrents(newText);
return true;
}
};
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -524,22 +551,6 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE
return drawerToggle != null && drawerToggle.onOptionsItemSelected(item); return drawerToggle != null && drawerToggle.onOptionsItemSelected(item);
} }
/**
* Handles item selections on the dedicated list of filter items
*/
private OnItemClickListener onFilterListItemClicked = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
navigationList.setItemChecked(position, true);
Object item = navigationList.getAdapter().getItem(position);
if (item instanceof SimpleListItem) {
filterSelected((SimpleListItem) item, false);
}
if (drawerLayout != null)
drawerLayout.closeDrawer(drawerContainer);
}
};
/** /**
* A new filter was selected; update the view over the current data * A new filter was selected; update the view over the current data
* *
@ -876,20 +887,6 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE
fragmentTorrents.sortBy(TorrentsSortBy.Size); fragmentTorrents.sortBy(TorrentsSortBy.Size);
} }
private SearchView.OnQueryTextListener filterQueryTextChanged = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// Redirect to filter method which will directly apply it
filterTorrents(newText);
return true;
}
};
/** /**
* Redirect the newly entered list filter to the torrents fragment. * Redirect the newly entered list filter to the torrents fragment.
* *

259
app/src/main/java/org/transdroid/core/gui/TorrentsFragment.java

@ -71,13 +71,13 @@ import java.util.Locale;
@EFragment(R.layout.fragment_torrents) @EFragment(R.layout.fragment_torrents)
public class TorrentsFragment extends Fragment implements OnLabelPickedListener { public class TorrentsFragment extends Fragment implements OnLabelPickedListener {
// HACK Working around #391 while hopefully we rework the UI in the future to persist the list in db or something
protected static ArrayList<Torrent> torrents = null;
// Local data // Local data
@Bean @Bean
protected ApplicationSettings applicationSettings; protected ApplicationSettings applicationSettings;
@Bean @Bean
protected SystemSettings systemSettings; protected SystemSettings systemSettings;
// HACK Working around #391 while hopefully we rework the UI in the future to persist the list in db or something
protected static ArrayList<Torrent> torrents = null;
@InstanceState @InstanceState
protected ArrayList<Torrent> lastMultiSelectedTorrents; protected ArrayList<Torrent> lastMultiSelectedTorrents;
@InstanceState @InstanceState
@ -112,6 +112,133 @@ public class TorrentsFragment extends Fragment implements OnLabelPickedListener
protected TextView errorText; protected TextView errorText;
@ViewById @ViewById
protected ProgressBar loadingProgress; protected ProgressBar loadingProgress;
private MultiChoiceModeListener onTorrentsSelected = new MultiChoiceModeListener() {
private SelectionManagerMode selectionManagerMode;
private ActionMenuView actionsMenu;
private Toolbar actionsToolbar;
private FloatingActionsMenu addmenuButton;
@Override
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);
}
});
actionsMenu.getMenu().clear();
getActivity().getMenuInflater().inflate(R.menu.fragment_torrents_cab, actionsMenu.getMenu());
Context themedContext = ((AppCompatActivity) getActivity()).getSupportActionBar().getThemedContext();
selectionManagerMode = new SelectionManagerMode(themedContext, torrentsList, R.plurals.navigation_torrentsselected);
selectionManagerMode.onCreateActionMode(mode, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
selectionManagerMode.onPrepareActionMode(mode, menu);
// Hide/show options depending on the type of server we are connected to
if (daemonType != null) {
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) {
((TorrentsActivity) getActivity()).stopRefresh = true;
((TorrentsActivity) getActivity()).stopAutoRefresh();
}
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Get checked torrents
ArrayList<Torrent> checked = new ArrayList<>();
for (int i = 0; i < torrentsList.getCheckedItemPositions().size(); i++) {
if (torrentsList.getCheckedItemPositions().valueAt(i) && i < torrentsList.getAdapter().getCount()) {
checked.add((Torrent) torrentsList.getAdapter().getItem(torrentsList.getCheckedItemPositions().keyAt(i)));
}
}
int itemId = item.getItemId();
if (itemId == R.id.action_resume) {
for (Torrent torrent : checked) {
getTasksExecutor().resumeTorrent(torrent);
}
mode.finish();
return true;
} else if (itemId == R.id.action_pause) {
for (Torrent torrent : checked) {
getTasksExecutor().pauseTorrent(torrent);
}
mode.finish();
return true;
} else if (itemId == R.id.action_start) {
for (Torrent torrent : checked) {
getTasksExecutor().startTorrent(torrent, false);
}
mode.finish();
return true;
} else if (itemId == R.id.action_stop) {
for (Torrent torrent : checked) {
getTasksExecutor().stopTorrent(torrent);
}
mode.finish();
return true;
} else if (itemId == R.id.action_remove_default) {
for (Torrent torrent : checked) {
getTasksExecutor().removeTorrent(torrent, false);
}
mode.finish();
return true;
} else if (itemId == R.id.action_remove_withdata) {
for (Torrent torrent : checked) {
getTasksExecutor().removeTorrent(torrent, true);
}
mode.finish();
return true;
} else if (itemId == R.id.action_setlabel) {
lastMultiSelectedTorrents = checked;
if (currentLabels != null) {
SetLabelDialog.show(getActivity(), TorrentsFragment.this, currentLabels);
}
mode.finish();
return true;
} else {
return false;
}
}
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
selectionManagerMode.onItemCheckedStateChanged(mode, position, id, checked);
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// Resume autorefresh
if (getActivity() != null && getActivity() instanceof TorrentsActivity) {
((TorrentsActivity) getActivity()).stopRefresh = false;
((TorrentsActivity) getActivity()).startAutoRefresh();
}
selectionManagerMode.onDestroyActionMode(mode);
actionsMenu.setVisibility(View.GONE);
actionsToolbar.setEnabled(true);
addmenuButton.setVisibility(View.VISIBLE);
}
};
@AfterViews @AfterViews
protected void init() { protected void init() {
@ -272,134 +399,6 @@ public class TorrentsFragment extends Fragment implements OnLabelPickedListener
updateViewVisibility(); updateViewVisibility();
} }
private MultiChoiceModeListener onTorrentsSelected = new MultiChoiceModeListener() {
private SelectionManagerMode selectionManagerMode;
private ActionMenuView actionsMenu;
private Toolbar actionsToolbar;
private FloatingActionsMenu addmenuButton;
@Override
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);
}
});
actionsMenu.getMenu().clear();
getActivity().getMenuInflater().inflate(R.menu.fragment_torrents_cab, actionsMenu.getMenu());
Context themedContext = ((AppCompatActivity) getActivity()).getSupportActionBar().getThemedContext();
selectionManagerMode = new SelectionManagerMode(themedContext, torrentsList, R.plurals.navigation_torrentsselected);
selectionManagerMode.onCreateActionMode(mode, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
selectionManagerMode.onPrepareActionMode(mode, menu);
// Hide/show options depending on the type of server we are connected to
if (daemonType != null) {
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) {
((TorrentsActivity) getActivity()).stopRefresh = true;
((TorrentsActivity) getActivity()).stopAutoRefresh();
}
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Get checked torrents
ArrayList<Torrent> checked = new ArrayList<>();
for (int i = 0; i < torrentsList.getCheckedItemPositions().size(); i++) {
if (torrentsList.getCheckedItemPositions().valueAt(i) && i < torrentsList.getAdapter().getCount()) {
checked.add((Torrent) torrentsList.getAdapter().getItem(torrentsList.getCheckedItemPositions().keyAt(i)));
}
}
int itemId = item.getItemId();
if (itemId == R.id.action_resume) {
for (Torrent torrent : checked) {
getTasksExecutor().resumeTorrent(torrent);
}
mode.finish();
return true;
} else if (itemId == R.id.action_pause) {
for (Torrent torrent : checked) {
getTasksExecutor().pauseTorrent(torrent);
}
mode.finish();
return true;
} else if (itemId == R.id.action_start) {
for (Torrent torrent : checked) {
getTasksExecutor().startTorrent(torrent, false);
}
mode.finish();
return true;
} else if (itemId == R.id.action_stop) {
for (Torrent torrent : checked) {
getTasksExecutor().stopTorrent(torrent);
}
mode.finish();
return true;
} else if (itemId == R.id.action_remove_default) {
for (Torrent torrent : checked) {
getTasksExecutor().removeTorrent(torrent, false);
}
mode.finish();
return true;
} else if (itemId == R.id.action_remove_withdata) {
for (Torrent torrent : checked) {
getTasksExecutor().removeTorrent(torrent, true);
}
mode.finish();
return true;
} else if (itemId == R.id.action_setlabel) {
lastMultiSelectedTorrents = checked;
if (currentLabels != null) {
SetLabelDialog.show(getActivity(), TorrentsFragment.this, currentLabels);
}
mode.finish();
return true;
} else {
return false;
}
}
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
selectionManagerMode.onItemCheckedStateChanged(mode, position, id, checked);
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// Resume autorefresh
if (getActivity() != null && getActivity() instanceof TorrentsActivity) {
((TorrentsActivity) getActivity()).stopRefresh = false;
((TorrentsActivity) getActivity()).startAutoRefresh();
}
selectionManagerMode.onDestroyActionMode(mode);
actionsMenu.setVisibility(View.GONE);
actionsToolbar.setEnabled(true);
addmenuButton.setVisibility(View.VISIBLE);
}
};
@Click @Click
protected void emptyTextClicked() { protected void emptyTextClicked() {
// Refresh the activity (that contains this fragment) when the empty view gear is clicked // Refresh the activity (that contains this fragment) when the empty view gear is clicked

67
app/src/main/java/org/transdroid/core/gui/lists/LocalTorrent.java

@ -35,6 +35,14 @@ import java.util.Locale;
*/ */
public class LocalTorrent { public class LocalTorrent {
private static final String DECIMAL_FORMATTER = "%.1f";
private static final String DECIMAL_FORMATTER_2 = "%.2f";
private final Torrent t;
private LocalTorrent(Torrent torrent) {
this.t = torrent;
}
/** /**
* Creates the LocalTorrent object so that the translatable/formattable version of a Torrent can be used. * Creates the LocalTorrent object so that the translatable/formattable version of a Torrent can be used.
* *
@ -45,14 +53,32 @@ public class LocalTorrent {
return new LocalTorrent(torrent); return new LocalTorrent(torrent);
} }
private final Torrent t; /**
* Convert a DaemonException to a translatable human-readable error message
private LocalTorrent(Torrent torrent) { *
this.t = torrent; * @param e The exception that was thrown by the server
* @return A string resource ID to show to the user
*/
public static int getResourceForDaemonException(DaemonException e) {
switch (e.getType()) {
case MethodUnsupported:
return R.string.error_unsupported;
case ConnectionError:
return R.string.error_httperror;
case UnexpectedResponse:
return R.string.error_jsonresponseerror;
case ParsingFailed:
return R.string.error_jsonrequesterror;
case NotConnected:
return R.string.error_daemonnotconnected;
case AuthenticationFailure:
return R.string.error_401;
case FileAccessError:
return R.string.error_torrentfile;
default:
return R.string.error_httperror;
}
} }
private static final String DECIMAL_FORMATTER = "%.1f";
private static final String DECIMAL_FORMATTER_2 = "%.2f";
/** /**
* Builds a string showing the upload/download seed ratio. If not downloading, it will base the ratio on the total * Builds a string showing the upload/download seed ratio. If not downloading, it will base the ratio on the total
@ -230,31 +256,4 @@ public class LocalTorrent {
TimespanConverter.getTime(t.getEta(), inDays)); TimespanConverter.getTime(t.getEta(), inDays));
} }
/**
* Convert a DaemonException to a translatable human-readable error message
*
* @param e The exception that was thrown by the server
* @return A string resource ID to show to the user
*/
public static int getResourceForDaemonException(DaemonException e) {
switch (e.getType()) {
case MethodUnsupported:
return R.string.error_unsupported;
case ConnectionError:
return R.string.error_httperror;
case UnexpectedResponse:
return R.string.error_jsonresponseerror;
case ParsingFailed:
return R.string.error_jsonrequesterror;
case NotConnected:
return R.string.error_daemonnotconnected;
case AuthenticationFailure:
return R.string.error_401;
case FileAccessError:
return R.string.error_torrentfile;
default:
return R.string.error_httperror;
}
}
} }

4
app/src/main/java/org/transdroid/core/gui/lists/PiecesMapView.java

@ -15,12 +15,10 @@ class PiecesMapView extends View {
private final float scale = getContext().getResources().getDisplayMetrics().density; private final float scale = getContext().getResources().getDisplayMetrics().density;
private final int MINIMUM_HEIGHT = (int) (25 * scale); private final int MINIMUM_HEIGHT = (int) (25 * scale);
private final int MINIMUM_PIECE_WIDTH = (int) (2 * scale); private final int MINIMUM_PIECE_WIDTH = (int) (2 * scale);
private ArrayList<Integer> pieces = null;
private final Paint downloadingPaint = new Paint(); private final Paint downloadingPaint = new Paint();
private final Paint donePaint = new Paint(); private final Paint donePaint = new Paint();
private final Paint partialDonePaint = new Paint(); private final Paint partialDonePaint = new Paint();
private ArrayList<Integer> pieces = null;
public PiecesMapView(Context context) { public PiecesMapView(Context context) {
super(context); super(context);

12
app/src/main/java/org/transdroid/core/gui/lists/SimpleListItemAdapter.java

@ -84,6 +84,12 @@ public class SimpleListItemAdapter extends BaseAdapter {
*/ */
public static class SimpleStringItem implements SimpleListItem { public static class SimpleStringItem implements SimpleListItem {
private final String string;
public SimpleStringItem(String string) {
this.string = string;
}
/** /**
* Wraps a simple string of strings into a list of SimpleStringItem to add as data to a * Wraps a simple string of strings into a list of SimpleStringItem to add as data to a
* {@link SimpleListItemAdapter} * {@link SimpleListItemAdapter}
@ -101,12 +107,6 @@ public class SimpleListItemAdapter extends BaseAdapter {
return errors; return errors;
} }
private final String string;
public SimpleStringItem(String string) {
this.string = string;
}
@Override @Override
public String getName() { public String getName() {
return this.string; return this.string;

3
app/src/main/java/org/transdroid/core/gui/lists/TorrentFilePriorityLayout.java

@ -37,13 +37,12 @@ public class TorrentFilePriorityLayout extends RelativeLayout {
private final float scale = getContext().getResources().getDisplayMetrics().density; private final float scale = getContext().getResources().getDisplayMetrics().density;
private final int WIDTH = (int) (6 * scale + 0.5f); private final int WIDTH = (int) (6 * scale + 0.5f);
private Priority priority = null;
private final Paint offPaint = new Paint(); private final Paint offPaint = new Paint();
private final Paint lowPaint = new Paint(); private final Paint lowPaint = new Paint();
private final Paint highPaint = new Paint(); private final Paint highPaint = new Paint();
private final Paint normalPaint = new Paint(); private final Paint normalPaint = new Paint();
private final RectF fullRect = new RectF(); private final RectF fullRect = new RectF();
private Priority priority = null;
public TorrentFilePriorityLayout(Context context) { public TorrentFilePriorityLayout(Context context) {
super(context); super(context);

37
app/src/main/java/org/transdroid/core/gui/lists/TorrentProgressBar.java

@ -35,10 +35,6 @@ public class TorrentProgressBar extends View {
private final float scale = getContext().getResources().getDisplayMetrics().density; private final float scale = getContext().getResources().getDisplayMetrics().density;
private final int MINIMUM_HEIGHT = (int) (3 * scale + 0.5f); private final int MINIMUM_HEIGHT = (int) (3 * scale + 0.5f);
private int progress;
private boolean isActive;
private boolean isError;
private final Paint notdonePaint = new Paint(); private final Paint notdonePaint = new Paint();
private final Paint inactiveDonePaint = new Paint(); private final Paint inactiveDonePaint = new Paint();
private final Paint inactivePaint = new Paint(); private final Paint inactivePaint = new Paint();
@ -47,21 +43,9 @@ public class TorrentProgressBar extends View {
private final Paint errorPaint = new Paint(); private final Paint errorPaint = new Paint();
private final RectF fullRect = new RectF(); private final RectF fullRect = new RectF();
private final RectF progressRect = new RectF(); private final RectF progressRect = new RectF();
private int progress;
public void setProgress(int progress) { private boolean isActive;
this.progress = progress; private boolean isError;
this.invalidate();
}
public void setActive(boolean isActive) {
this.isActive = isActive;
this.invalidate();
}
public void setError(boolean isError) {
this.isError = isError;
this.invalidate();
}
public TorrentProgressBar(Context context) { public TorrentProgressBar(Context context) {
super(context); super(context);
@ -81,6 +65,21 @@ public class TorrentProgressBar extends View {
a.recycle(); a.recycle();
} }
public void setProgress(int progress) {
this.progress = progress;
this.invalidate();
}
public void setActive(boolean isActive) {
this.isActive = isActive;
this.invalidate();
}
public void setError(boolean isError) {
this.isError = isError;
this.invalidate();
}
private void initPaints() { private void initPaints() {
notdonePaint.setColor(getResources().getColor(R.color.torrent_background)); notdonePaint.setColor(getResources().getColor(R.color.torrent_background));
inactiveDonePaint.setColor(getResources().getColor(R.color.torrent_paused)); inactiveDonePaint.setColor(getResources().getColor(R.color.torrent_paused));

3
app/src/main/java/org/transdroid/core/gui/lists/TorrentStatusLayout.java

@ -37,14 +37,13 @@ public class TorrentStatusLayout extends RelativeLayout {
private final float scale = getContext().getResources().getDisplayMetrics().density; private final float scale = getContext().getResources().getDisplayMetrics().density;
private final int WIDTH = (int) (6 * scale + 0.5f); private final int WIDTH = (int) (6 * scale + 0.5f);
private TorrentStatus status = null;
private final Paint pausedPaint = new Paint(); private final Paint pausedPaint = new Paint();
private final Paint otherPaint = new Paint(); private final Paint otherPaint = new Paint();
private final Paint downloadingPaint = new Paint(); private final Paint downloadingPaint = new Paint();
private final Paint seedingPaint = new Paint(); private final Paint seedingPaint = new Paint();
private final Paint errorPaint = new Paint(); private final Paint errorPaint = new Paint();
private final RectF fullRect = new RectF(); private final RectF fullRect = new RectF();
private TorrentStatus status = null;
public TorrentStatusLayout(Context context) { public TorrentStatusLayout(Context context) {
super(context); super(context);

3
app/src/main/java/org/transdroid/core/gui/lists/TorrentsAdapter.java

@ -35,10 +35,9 @@ import java.util.ArrayList;
@EBean @EBean
public class TorrentsAdapter extends BaseAdapter { public class TorrentsAdapter extends BaseAdapter {
private ArrayList<Torrent> torrents = null;
@RootContext @RootContext
protected Context context; protected Context context;
private ArrayList<Torrent> torrents = null;
/** /**
* Allows updating the full internal list of torrents at once, replacing the old list * Allows updating the full internal list of torrents at once, replacing the old list

34
app/src/main/java/org/transdroid/core/gui/log/ErrorLogEntry.java

@ -34,7 +34,15 @@ public class ErrorLogEntry implements Parcelable {
public static final String ID = "logId"; public static final String ID = "logId";
public static final String DATEANDTIME = "dateAndTime"; public static final String DATEANDTIME = "dateAndTime";
public static final Parcelable.Creator<ErrorLogEntry> CREATOR = new Parcelable.Creator<ErrorLogEntry>() {
public ErrorLogEntry createFromParcel(Parcel in) {
return new ErrorLogEntry(in);
}
public ErrorLogEntry[] newArray(int size) {
return new ErrorLogEntry[size];
}
};
@DatabaseField(id = true, columnName = ID) @DatabaseField(id = true, columnName = ID)
private Integer logId; private Integer logId;
@DatabaseField(columnName = DATEANDTIME) @DatabaseField(columnName = DATEANDTIME)
@ -56,6 +64,14 @@ public class ErrorLogEntry implements Parcelable {
this.message = message; this.message = message;
} }
private ErrorLogEntry(Parcel in) {
logId = in.readInt();
dateAndTime = new Date(in.readLong());
priority = in.readInt();
tag = in.readString();
message = in.readString();
}
public Integer getLogId() { public Integer getLogId() {
return logId; return logId;
} }
@ -88,22 +104,4 @@ public class ErrorLogEntry implements Parcelable {
out.writeString(message); out.writeString(message);
} }
public static final Parcelable.Creator<ErrorLogEntry> CREATOR = new Parcelable.Creator<ErrorLogEntry>() {
public ErrorLogEntry createFromParcel(Parcel in) {
return new ErrorLogEntry(in);
}
public ErrorLogEntry[] newArray(int size) {
return new ErrorLogEntry[size];
}
};
private ErrorLogEntry(Parcel in) {
logId = in.readInt();
dateAndTime = new Date(in.readLong());
priority = in.readInt();
tag = in.readString();
message = in.readString();
}
} }

56
app/src/main/java/org/transdroid/core/gui/navigation/DialogHelper.java

@ -45,6 +45,27 @@ public class DialogHelper extends Activity {
@Extra @Extra
protected DialogSpecification dialog; protected DialogSpecification dialog;
/**
* Call this from {@link Activity#onCreateDialog(int)}, supplying an instance of the {@link DialogSpecification}
* that should be shown to the user.
*
* @param context The activity that calls this method and which will own the constructed dialog
* @param dialog An instance of the specification for the dialog that needs to be shown
* @return Either an instance of a {@link Dialog} that the activity should further control or null if the dialog
* will instead be opened as a full screen activity
*/
public static Dialog showDialog(Context context, DialogSpecification dialog) {
// If the device is large (i.e. a tablet) then return a dialog to show
if (!NavigationHelper_.getInstance_(context).isSmallScreen())
return new PopupDialog(context, dialog);
// This is a small device; create a full screen dialog (which is just an activity)
DialogHelper_.intent(context).dialog(dialog).start();
return null;
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -70,24 +91,16 @@ public class DialogHelper extends Activity {
} }
/** /**
* Call this from {@link Activity#onCreateDialog(int)}, supplying an instance of the {@link DialogSpecification} * Specification for some dialog that can be show to the user, consisting of a custom layout and possibly an action
* that should be shown to the user. * bar menu. Warning: the action bar, and thus the menu options, is only shown when the dialog is presented as full
* * screen activity. Use only for unimportant actions.
* @param context The activity that calls this method and which will own the constructed dialog
* @param dialog An instance of the specification for the dialog that needs to be shown
* @return Either an instance of a {@link Dialog} that the activity should further control or null if the dialog
* will instead be opened as a full screen activity
*/ */
public static Dialog showDialog(Context context, DialogSpecification dialog) { public interface DialogSpecification extends Serializable {
int getDialogLayoutId();
// If the device is large (i.e. a tablet) then return a dialog to show
if (!NavigationHelper_.getInstance_(context).isSmallScreen())
return new PopupDialog(context, dialog);
// This is a small device; create a full screen dialog (which is just an activity) int getDialogMenuId();
DialogHelper_.intent(context).dialog(dialog).start();
return null;
boolean onMenuItemSelected(Activity ownerActivity, int selectedItemId);
} }
/** /**
@ -101,17 +114,4 @@ public class DialogHelper extends Activity {
} }
} }
/**
* Specification for some dialog that can be show to the user, consisting of a custom layout and possibly an action
* bar menu. Warning: the action bar, and thus the menu options, is only shown when the dialog is presented as full
* screen activity. Use only for unimportant actions.
*/
public interface DialogSpecification extends Serializable {
int getDialogLayoutId();
int getDialogMenuId();
boolean onMenuItemSelected(Activity ownerActivity, int selectedItemId);
}
} }

6
app/src/main/java/org/transdroid/core/gui/navigation/FilterListAdapter.java

@ -41,12 +41,12 @@ public class FilterListAdapter extends MergeAdapter {
@RootContext @RootContext
protected Context context; protected Context context;
private FilterListItemAdapter serverItems = null;
private FilterListItemAdapter statusTypeItems = null;
private FilterListItemAdapter labelItems = null;
protected ViewHolderAdapter statusTypeSeparator; protected ViewHolderAdapter statusTypeSeparator;
protected ViewHolderAdapter labelSeperator; protected ViewHolderAdapter labelSeperator;
protected ViewHolderAdapter serverSeparator; protected ViewHolderAdapter serverSeparator;
private FilterListItemAdapter serverItems = null;
private FilterListItemAdapter statusTypeItems = null;
private FilterListItemAdapter labelItems = null;
/** /**
* Update the list of available servers * Update the list of available servers

86
app/src/main/java/org/transdroid/core/gui/navigation/Label.java

@ -34,8 +34,16 @@ import java.util.List;
*/ */
public class Label implements SimpleListItem, NavigationFilter, Comparable<Label> { public class Label implements SimpleListItem, NavigationFilter, Comparable<Label> {
private static String unnamedLabelText = null; public static final Parcelable.Creator<Label> CREATOR = new Parcelable.Creator<Label>() {
public Label createFromParcel(Parcel in) {
return new Label(in);
}
public Label[] newArray(int size) {
return new Label[size];
}
};
private static String unnamedLabelText = null;
private final boolean isEmptyLabel; private final boolean isEmptyLabel;
private final String name; private final String name;
private final int count; private final int count;
@ -50,6 +58,39 @@ public class Label implements SimpleListItem, NavigationFilter, Comparable<Label
this(daemonLabel.getName(), daemonLabel.getCount(), false); this(daemonLabel.getName(), daemonLabel.getCount(), false);
} }
private Label(Parcel in) {
this.name = in.readString();
this.count = in.readInt();
this.isEmptyLabel = in.readInt() == 1;
}
/**
* Converts a list of labels as retrieved from a server daemon into a list of labels that can be used in the UI as navigation filters.
*
* @param daemonLabels The raw list of labels as received from the server daemon adapter
* @param unnamedLabel The text to show for the empty label (i.e. the unnamed label)
* @return A label items that can be used in a filter list such as the action bar spinner
*/
public static ArrayList<Label> convertToNavigationLabels(List<org.transdroid.daemon.Label> daemonLabels, String unnamedLabel) {
if (daemonLabels == null) {
return null;
}
ArrayList<Label> localLabels = new ArrayList<>();
unnamedLabelText = unnamedLabel;
for (org.transdroid.daemon.Label label : daemonLabels) {
if (label != null && !TextUtils.isEmpty(label.getName())) {
localLabels.add(new Label(label));
}
}
Collections.sort(localLabels);
// force unlabelled to be at the top
localLabels.add(0, new Label(unnamedLabel, -1, true));
return localLabels;
}
@Override @Override
public String getName() { public String getName() {
if (TextUtils.isEmpty(this.name)) { if (TextUtils.isEmpty(this.name)) {
@ -91,49 +132,6 @@ public class Label implements SimpleListItem, NavigationFilter, Comparable<Label
return this.name.compareTo(another.getName()); return this.name.compareTo(another.getName());
} }
/**
* Converts a list of labels as retrieved from a server daemon into a list of labels that can be used in the UI as navigation filters.
*
* @param daemonLabels The raw list of labels as received from the server daemon adapter
* @param unnamedLabel The text to show for the empty label (i.e. the unnamed label)
* @return A label items that can be used in a filter list such as the action bar spinner
*/
public static ArrayList<Label> convertToNavigationLabels(List<org.transdroid.daemon.Label> daemonLabels, String unnamedLabel) {
if (daemonLabels == null) {
return null;
}
ArrayList<Label> localLabels = new ArrayList<>();
unnamedLabelText = unnamedLabel;
for (org.transdroid.daemon.Label label : daemonLabels) {
if (label != null && !TextUtils.isEmpty(label.getName())) {
localLabels.add(new Label(label));
}
}
Collections.sort(localLabels);
// force unlabelled to be at the top
localLabels.add(0, new Label(unnamedLabel, -1, true));
return localLabels;
}
private Label(Parcel in) {
this.name = in.readString();
this.count = in.readInt();
this.isEmptyLabel = in.readInt() == 1;
}
public static final Parcelable.Creator<Label> CREATOR = new Parcelable.Creator<Label>() {
public Label createFromParcel(Parcel in) {
return new Label(in);
}
public Label[] newArray(int size) {
return new Label[size];
}
};
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;

132
app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java

@ -70,6 +70,72 @@ public class NavigationHelper {
@RootContext @RootContext
protected Context context; protected Context context;
/**
* Converts a string into a {@link Spannable} that displays the string in the Roboto Condensed font
*
* @param string A plain text {@link String}
* @return A {@link Spannable} that can be applied to supporting views (such as the action bar title) so that the input string will be displayed
* using the Roboto Condensed font (if the OS has this)
*/
public static SpannableString buildCondensedFontString(String string) {
if (string == null) {
return null;
}
SpannableString s = new SpannableString(string);
s.setSpan(new TypefaceSpan("sans-serif-condensed"), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return s;
}
/**
* Analyses a torrent http or magnet URI and tries to come up with a reasonable human-readable name.
*
* @param rawTorrentUri The raw http:// or magnet: link to the torrent
* @return A best-guess, reasonably long name for the linked torrent
*/
public static String extractNameFromUri(Uri rawTorrentUri) {
if (rawTorrentUri.getScheme() == null) {
// Probably an incorrect URI; just return the whole thing
return rawTorrentUri.toString();
}
if (rawTorrentUri.getScheme().equals("magnet")) {
// Magnet links might have a dn (display name) parameter
String dn = getQueryParameter(rawTorrentUri, "dn");
if (dn != null && !dn.equals("")) {
return dn;
}
// If not, try to return the hash that is specified as xt (exact topci)
String xt = getQueryParameter(rawTorrentUri, "xt");
if (xt != null && !xt.equals("")) {
return xt;
}
}
if (rawTorrentUri.isHierarchical()) {
String path = rawTorrentUri.getPath();
if (path != null) {
if (path.contains("/")) {
path = path.substring(path.lastIndexOf("/"));
}
return path;
}
}
// No idea what to do with this; return as is
return rawTorrentUri.toString();
}
private static String getQueryParameter(Uri uri, String parameter) {
int start = uri.toString().indexOf(parameter + "=");
if (start >= 0) {
int begin = start + (parameter + "=").length();
int end = uri.toString().indexOf("&", begin);
return uri.toString().substring(begin, end >= 0 ? end : uri.toString().length());
}
return null;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public boolean checkTorrentReadPermission(final Activity activity) { public boolean checkTorrentReadPermission(final Activity activity) {
return Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT || return Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT ||
@ -140,72 +206,6 @@ public class NavigationHelper {
return null; return null;
} }
/**
* Converts a string into a {@link Spannable} that displays the string in the Roboto Condensed font
*
* @param string A plain text {@link String}
* @return A {@link Spannable} that can be applied to supporting views (such as the action bar title) so that the input string will be displayed
* using the Roboto Condensed font (if the OS has this)
*/
public static SpannableString buildCondensedFontString(String string) {
if (string == null) {
return null;
}
SpannableString s = new SpannableString(string);
s.setSpan(new TypefaceSpan("sans-serif-condensed"), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return s;
}
/**
* Analyses a torrent http or magnet URI and tries to come up with a reasonable human-readable name.
*
* @param rawTorrentUri The raw http:// or magnet: link to the torrent
* @return A best-guess, reasonably long name for the linked torrent
*/
public static String extractNameFromUri(Uri rawTorrentUri) {
if (rawTorrentUri.getScheme() == null) {
// Probably an incorrect URI; just return the whole thing
return rawTorrentUri.toString();
}
if (rawTorrentUri.getScheme().equals("magnet")) {
// Magnet links might have a dn (display name) parameter
String dn = getQueryParameter(rawTorrentUri, "dn");
if (dn != null && !dn.equals("")) {
return dn;
}
// If not, try to return the hash that is specified as xt (exact topci)
String xt = getQueryParameter(rawTorrentUri, "xt");
if (xt != null && !xt.equals("")) {
return xt;
}
}
if (rawTorrentUri.isHierarchical()) {
String path = rawTorrentUri.getPath();
if (path != null) {
if (path.contains("/")) {
path = path.substring(path.lastIndexOf("/"));
}
return path;
}
}
// No idea what to do with this; return as is
return rawTorrentUri.toString();
}
private static String getQueryParameter(Uri uri, String parameter) {
int start = uri.toString().indexOf(parameter + "=");
if (start >= 0) {
int begin = start + (parameter + "=").length();
int end = uri.toString().indexOf("&", begin);
return uri.toString().substring(begin, end >= 0 ? end : uri.toString().length());
}
return null;
}
/** /**
* Returns (and initialises, if needed) an image cache that uses memory and (1MB) local storage. * Returns (and initialises, if needed) an image cache that uses memory and (1MB) local storage.
* *

22
app/src/main/java/org/transdroid/core/gui/navigation/SelectionModificationSpinner.java

@ -79,6 +79,17 @@ public class SelectionModificationSpinner extends Spinner {
super.setSelection(position); super.setSelection(position);
} }
/**
* Interface to implement if an interface want to respond to selection modification actions.
*/
public interface OnModificationActionSelectedListener {
public void selectAll();
public void selectFinished();
public void invertSelection();
}
/** /**
* Local adapter that holds the actions which can be performed and a title text view that always shows instead of a * Local adapter that holds the actions which can be performed and a title text view that always shows instead of a
* list item as in a normal spinner. * list item as in a normal spinner.
@ -109,15 +120,4 @@ public class SelectionModificationSpinner extends Spinner {
} }
/**
* Interface to implement if an interface want to respond to selection modification actions.
*/
public interface OnModificationActionSelectedListener {
public void selectAll();
public void selectFinished();
public void invertSelection();
}
} }

26
app/src/main/java/org/transdroid/core/gui/navigation/SetTransferRatesDialog.java

@ -30,6 +30,19 @@ import org.transdroid.core.app.settings.SettingsUtils;
public class SetTransferRatesDialog { public class SetTransferRatesDialog {
private static OnClickListener onNumberClicked = new OnClickListener() {
@Override
public void onClick(View v) {
// Append the text contents of the button itself as text to the current number (as reference in the view's
// tag)
TextView numberView = (TextView) v.getTag();
if (numberView.getText().toString().equals(v.getContext().getString(R.string.status_maxspeed_novalue))) {
numberView.setText("");
}
numberView.setText(numberView.getText().toString() + ((Button) v).getText().toString());
}
};
/** /**
* A dialog fragment that allow picking of maximum download and upload transfer rates as well as the resetting of these values. * A dialog fragment that allow picking of maximum download and upload transfer rates as well as the resetting of these values.
* *
@ -88,19 +101,6 @@ public class SetTransferRatesDialog {
} }
} }
private static OnClickListener onNumberClicked = new OnClickListener() {
@Override
public void onClick(View v) {
// Append the text contents of the button itself as text to the current number (as reference in the view's
// tag)
TextView numberView = (TextView) v.getTag();
if (numberView.getText().toString().equals(v.getContext().getString(R.string.status_maxspeed_novalue))) {
numberView.setText("");
}
numberView.setText(numberView.getText().toString() + ((Button) v).getText().toString());
}
};
/** /**
* Listener interface to the user having picked or wanting to resets the current maximum transfer speeds; * Listener interface to the user having picked or wanting to resets the current maximum transfer speeds;
*/ */

29
app/src/main/java/org/transdroid/core/gui/navigation/StatusType.java

@ -92,6 +92,15 @@ public enum StatusType {
public static class StatusTypeFilter implements SimpleListItem, NavigationFilter { public static class StatusTypeFilter implements SimpleListItem, NavigationFilter {
public static final Parcelable.Creator<StatusTypeFilter> CREATOR = new Parcelable.Creator<StatusTypeFilter>() {
public StatusTypeFilter createFromParcel(Parcel in) {
return new StatusTypeFilter(in);
}
public StatusTypeFilter[] newArray(int size) {
return new StatusTypeFilter[size];
}
};
private final StatusType statusType; private final StatusType statusType;
private final String name; private final String name;
@ -100,6 +109,11 @@ public enum StatusType {
this.name = name; this.name = name;
} }
private StatusTypeFilter(Parcel in) {
this.statusType = StatusType.valueOf(in.readString());
this.name = in.readString();
}
public StatusType getStatusType() { public StatusType getStatusType() {
return statusType; return statusType;
} }
@ -139,21 +153,6 @@ public enum StatusType {
} }
} }
private StatusTypeFilter(Parcel in) {
this.statusType = StatusType.valueOf(in.readString());
this.name = in.readString();
}
public static final Parcelable.Creator<StatusTypeFilter> CREATOR = new Parcelable.Creator<StatusTypeFilter>() {
public StatusTypeFilter createFromParcel(Parcel in) {
return new StatusTypeFilter(in);
}
public StatusTypeFilter[] newArray(int size) {
return new StatusTypeFilter[size];
}
};
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;

116
app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java

@ -79,15 +79,13 @@ import java.util.List;
@EActivity(R.layout.activity_rssfeeds) @EActivity(R.layout.activity_rssfeeds)
public class RssFeedsActivity extends AppCompatActivity { public class RssFeedsActivity extends AppCompatActivity {
protected static final int RSS_FEEDS_LOCAL = 0;
protected static final int RSS_FEEDS_REMOTE = 1;
// Settings and local data // Settings and local data
@Bean @Bean
protected Log log; protected Log log;
@Bean @Bean
protected ApplicationSettings applicationSettings; protected ApplicationSettings applicationSettings;
protected static final int RSS_FEEDS_LOCAL = 0;
protected static final int RSS_FEEDS_REMOTE = 1;
@FragmentById(R.id.rssfeeds_fragment) @FragmentById(R.id.rssfeeds_fragment)
protected RssFeedsFragment fragmentLocalFeeds; protected RssFeedsFragment fragmentLocalFeeds;
@FragmentById(R.id.rssitems_fragment) @FragmentById(R.id.rssitems_fragment)
@ -112,61 +110,6 @@ public class RssFeedsActivity extends AppCompatActivity {
@Bean @Bean
protected ConnectivityHelper connectivityHelper; protected ConnectivityHelper connectivityHelper;
protected class LayoutPagerAdapter extends PagerAdapter {
boolean hasRemoteRss;
String serverName;
public LayoutPagerAdapter(boolean hasRemoteRss, String name) {
super();
this.hasRemoteRss = hasRemoteRss;
this.serverName = (name.length() > 0 ? name : getString(R.string.navigation_rss_tabs_remote));
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
int resId = 0;
if (position == RSS_FEEDS_LOCAL) {
resId = R.id.layout_rssfeeds_local;
} else if (position == RSS_FEEDS_REMOTE) {
resId = R.id.layout_rss_feeds_remote;
}
return findViewById(resId);
}
@Override
public int getCount() {
return (this.hasRemoteRss ? 2 : 1);
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
return (view == o);
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((View) object);
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case RSS_FEEDS_LOCAL:
return getString(R.string.navigation_rss_tabs_local);
case RSS_FEEDS_REMOTE:
return this.serverName;
}
return super.getPageTitle(position);
}
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
SettingsUtils.applyDayNightTheme(this); SettingsUtils.applyDayNightTheme(this);
@ -384,7 +327,6 @@ public class RssFeedsActivity extends AppCompatActivity {
SnackbarManager.show(Snackbar.with(this).text(error).colorResource(R.color.red).type(SnackbarType.MULTI_LINE)); SnackbarManager.show(Snackbar.with(this).text(error).colorResource(R.color.red).type(SnackbarType.MULTI_LINE));
} }
public void onFeedSelected(int position) { public void onFeedSelected(int position) {
selectedFilter = position; selectedFilter = position;
@ -442,4 +384,58 @@ public class RssFeedsActivity extends AppCompatActivity {
fragmentRemoteFeeds.updateChannelFilters(feedLabels); fragmentRemoteFeeds.updateChannelFilters(feedLabels);
} }
protected class LayoutPagerAdapter extends PagerAdapter {
boolean hasRemoteRss;
String serverName;
public LayoutPagerAdapter(boolean hasRemoteRss, String name) {
super();
this.hasRemoteRss = hasRemoteRss;
this.serverName = (name.length() > 0 ? name : getString(R.string.navigation_rss_tabs_remote));
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
int resId = 0;
if (position == RSS_FEEDS_LOCAL) {
resId = R.id.layout_rssfeeds_local;
} else if (position == RSS_FEEDS_REMOTE) {
resId = R.id.layout_rss_feeds_remote;
}
return findViewById(resId);
}
@Override
public int getCount() {
return (this.hasRemoteRss ? 2 : 1);
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
return (view == o);
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((View) object);
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case RSS_FEEDS_LOCAL:
return getString(R.string.navigation_rss_tabs_local);
case RSS_FEEDS_REMOTE:
return this.serverName;
}
return super.getPageTitle(position);
}
}
} }

8
app/src/main/java/org/transdroid/core/gui/rss/RssItemsFragment.java

@ -77,6 +77,10 @@ public class RssItemsFragment extends Fragment {
// Views // Views
@ViewById(R.id.rssitems_list) @ViewById(R.id.rssitems_list)
protected ListView rssItemsList; protected ListView rssItemsList;
@Bean
protected RssitemsAdapter rssitemsAdapter;
@ViewById
protected TextView emptyText;
private MultiChoiceModeListener onItemsSelected = new MultiChoiceModeListener() { private MultiChoiceModeListener onItemsSelected = new MultiChoiceModeListener() {
SelectionManagerMode selectionManagerMode; SelectionManagerMode selectionManagerMode;
@ -182,10 +186,6 @@ public class RssItemsFragment extends Fragment {
} }
}; };
@Bean
protected RssitemsAdapter rssitemsAdapter;
@ViewById
protected TextView emptyText;
@AfterViews @AfterViews
protected void init() { protected void init() {

3
app/src/main/java/org/transdroid/core/gui/rss/RssfeedsAdapter.java

@ -35,10 +35,9 @@ import java.util.List;
@EBean @EBean
public class RssfeedsAdapter extends BaseAdapter { public class RssfeedsAdapter extends BaseAdapter {
private List<RssfeedLoader> loaders = null;
@RootContext @RootContext
protected Context context; protected Context context;
private List<RssfeedLoader> loaders = null;
/** /**
* Allows updating the full internal list of feed loaders at once, replacing the old list * Allows updating the full internal list of feed loaders at once, replacing the old list

3
app/src/main/java/org/transdroid/core/gui/rss/RssitemsAdapter.java

@ -34,10 +34,9 @@ import org.transdroid.core.rssparser.Item;
@EBean @EBean
public class RssitemsAdapter extends BaseAdapter { public class RssitemsAdapter extends BaseAdapter {
private Channel rssfeed = null;
@RootContext @RootContext
protected Context context; protected Context context;
private Channel rssfeed = null;
/** /**
* Allows updating the full RSS feed (channel and contained items), replacing the old data * Allows updating the full RSS feed (channel and contained items), replacing the old data

39
app/src/main/java/org/transdroid/core/gui/search/SearchActivity.java

@ -87,6 +87,25 @@ public class SearchActivity extends AppCompatActivity {
private List<SearchSetting> searchSites; private List<SearchSetting> searchSites;
private SearchSetting lastUsedSite; private SearchSetting lastUsedSite;
private String lastUsedQuery; private String lastUsedQuery;
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) {
}
};
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -238,26 +257,6 @@ public class SearchActivity extends AppCompatActivity {
return true; 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} * Extracts the query string from the search {@link Intent}
* *

3
app/src/main/java/org/transdroid/core/gui/search/SearchResultsAdapter.java

@ -35,10 +35,9 @@ import java.util.List;
@EBean @EBean
public class SearchResultsAdapter extends BaseAdapter { public class SearchResultsAdapter extends BaseAdapter {
private List<SearchResult> results = null;
@RootContext @RootContext
protected Context context; protected Context context;
private List<SearchResult> results = null;
/** /**
* Allows updating the search results, replacing the old data * Allows updating the search results, replacing the old data

135
app/src/main/java/org/transdroid/core/gui/search/SearchResultsFragment.java

@ -80,74 +80,6 @@ public class SearchResultsFragment extends Fragment {
protected TextView emptyText; protected TextView emptyText;
@ViewById @ViewById
protected ProgressBar loadingProgress; protected ProgressBar loadingProgress;
@AfterViews
protected void init() {
// On large screens where this fragment is shown next to the sites list; we show a continues grey vertical line
// to separate the lists visually
if (!NavigationHelper_.getInstance_(getActivity()).isSmallScreen()) {
resultsList.setBackgroundResource(R.drawable.details_list_background);
}
// Set up the list adapter, which allows multi-select
resultsList.setAdapter(resultsAdapter);
resultsList.setMultiChoiceModeListener(onItemsSelected);
if (results != null) {
showResults();
}
}
public void startSearch(String query, SearchSite site, SearchSortOrder sortBy) {
loadingProgress.setVisibility(View.VISIBLE);
resultsList.setVisibility(View.GONE);
emptyText.setVisibility(View.GONE);
performSearch(query, site, sortBy);
}
@Background
protected void performSearch(String query, SearchSite site, SearchSortOrder sortBy) {
results = searchHelper.search(query, site, sortBy);
resultsSource = site.isPrivate() ? site.getKey() : null;
showResults();
}
@UiThread
protected void showResults() {
loadingProgress.setVisibility(View.GONE);
if (results == null || results.size() == 0) {
resultsList.setVisibility(View.GONE);
emptyText.setVisibility(View.VISIBLE);
return;
}
resultsAdapter.update(results);
resultsList.setVisibility(View.VISIBLE);
emptyText.setVisibility(View.GONE);
}
public void clearResults() {
loadingProgress.setVisibility(View.GONE);
resultsList.setVisibility(View.GONE);
emptyText.setVisibility(View.VISIBLE);
}
@ItemClick(R.id.searchresults_list)
protected void onItemClicked(SearchResult item) {
if (item.getTorrentUrl() == null) {
SnackbarManager.show(Snackbar.with(getActivity()).text(R.string.error_notorrentfile).colorResource(R.color.red));
return;
}
// Don't broadcast this intent; we can safely assume this is intended for Transdroid only
Intent i = TorrentsActivity_.intent(getActivity()).get();
i.setData(Uri.parse(item.getTorrentUrl()));
i.putExtra("TORRENT_TITLE", item.getName());
if (resultsSource != null) {
i.putExtra("PRIVATE_SOURCE", resultsSource);
}
startActivity(i);
}
private MultiChoiceModeListener onItemsSelected = new MultiChoiceModeListener() { private MultiChoiceModeListener onItemsSelected = new MultiChoiceModeListener() {
SelectionManagerMode selectionManagerMode; SelectionManagerMode selectionManagerMode;
@ -225,4 +157,71 @@ public class SearchResultsFragment extends Fragment {
}; };
@AfterViews
protected void init() {
// On large screens where this fragment is shown next to the sites list; we show a continues grey vertical line
// to separate the lists visually
if (!NavigationHelper_.getInstance_(getActivity()).isSmallScreen()) {
resultsList.setBackgroundResource(R.drawable.details_list_background);
}
// Set up the list adapter, which allows multi-select
resultsList.setAdapter(resultsAdapter);
resultsList.setMultiChoiceModeListener(onItemsSelected);
if (results != null) {
showResults();
}
}
public void startSearch(String query, SearchSite site, SearchSortOrder sortBy) {
loadingProgress.setVisibility(View.VISIBLE);
resultsList.setVisibility(View.GONE);
emptyText.setVisibility(View.GONE);
performSearch(query, site, sortBy);
}
@Background
protected void performSearch(String query, SearchSite site, SearchSortOrder sortBy) {
results = searchHelper.search(query, site, sortBy);
resultsSource = site.isPrivate() ? site.getKey() : null;
showResults();
}
@UiThread
protected void showResults() {
loadingProgress.setVisibility(View.GONE);
if (results == null || results.size() == 0) {
resultsList.setVisibility(View.GONE);
emptyText.setVisibility(View.VISIBLE);
return;
}
resultsAdapter.update(results);
resultsList.setVisibility(View.VISIBLE);
emptyText.setVisibility(View.GONE);
}
public void clearResults() {
loadingProgress.setVisibility(View.GONE);
resultsList.setVisibility(View.GONE);
emptyText.setVisibility(View.VISIBLE);
}
@ItemClick(R.id.searchresults_list)
protected void onItemClicked(SearchResult item) {
if (item.getTorrentUrl() == null) {
SnackbarManager.show(Snackbar.with(getActivity()).text(R.string.error_notorrentfile).colorResource(R.color.red));
return;
}
// Don't broadcast this intent; we can safely assume this is intended for Transdroid only
Intent i = TorrentsActivity_.intent(getActivity()).get();
i.setData(Uri.parse(item.getTorrentUrl()));
i.putExtra("TORRENT_TITLE", item.getName());
if (resultsSource != null) {
i.putExtra("PRIVATE_SOURCE", resultsSource);
}
startActivity(i);
}
} }

3
app/src/main/java/org/transdroid/core/gui/search/SearchSitesAdapter.java

@ -36,10 +36,9 @@ import java.util.List;
@EBean @EBean
public class SearchSitesAdapter extends BaseAdapter { public class SearchSitesAdapter extends BaseAdapter {
private List<SearchSetting> sites = null;
@RootContext @RootContext
protected Context context; protected Context context;
private List<SearchSetting> sites = null;
/** /**
* Allows updating the full internal list of sites at once, replacing the old list * Allows updating the full internal list of sites at once, replacing the old list

50
app/src/main/java/org/transdroid/core/gui/settings/HelpSettingsActivity.java

@ -51,30 +51,6 @@ public class HelpSettingsActivity extends PreferenceCompatActivity {
protected ErrorLogSender errorLogSender; protected ErrorLogSender errorLogSender;
@Bean @Bean
protected SettingsPersistence settingsPersistence; protected SettingsPersistence settingsPersistence;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Just load the system-related preferences from XML
addPreferencesFromResource(R.xml.pref_help);
// Handle outgoing links and preference changes
findPreference("system_sendlog").setOnPreferenceClickListener(onSendLogClick);
findPreference("system_installhelp").setOnPreferenceClickListener(onInstallHelpClick);
findPreference("system_changelog").setOnPreferenceClickListener(onChangeLogClick);
findPreference("system_about").setTitle(getString(R.string.pref_about, getString(R.string.app_name)));
findPreference("system_about").setOnPreferenceClickListener(onAboutClick);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@OptionsItem(android.R.id.home)
protected void navigateUp() {
MainSettingsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start();
}
private OnPreferenceClickListener onSendLogClick = new OnPreferenceClickListener() { private OnPreferenceClickListener onSendLogClick = new OnPreferenceClickListener() {
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
@ -82,7 +58,6 @@ public class HelpSettingsActivity extends PreferenceCompatActivity {
return true; return true;
} }
}; };
private OnPreferenceClickListener onInstallHelpClick = new OnPreferenceClickListener() { private OnPreferenceClickListener onInstallHelpClick = new OnPreferenceClickListener() {
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {
@ -90,7 +65,6 @@ public class HelpSettingsActivity extends PreferenceCompatActivity {
return true; return true;
} }
}; };
private OnPreferenceClickListener onChangeLogClick = new OnPreferenceClickListener() { private OnPreferenceClickListener onChangeLogClick = new OnPreferenceClickListener() {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
@ -99,7 +73,6 @@ public class HelpSettingsActivity extends PreferenceCompatActivity {
return true; return true;
} }
}; };
private OnPreferenceClickListener onAboutClick = new OnPreferenceClickListener() { private OnPreferenceClickListener onAboutClick = new OnPreferenceClickListener() {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
@ -109,6 +82,29 @@ public class HelpSettingsActivity extends PreferenceCompatActivity {
} }
}; };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Just load the system-related preferences from XML
addPreferencesFromResource(R.xml.pref_help);
// Handle outgoing links and preference changes
findPreference("system_sendlog").setOnPreferenceClickListener(onSendLogClick);
findPreference("system_installhelp").setOnPreferenceClickListener(onInstallHelpClick);
findPreference("system_changelog").setOnPreferenceClickListener(onChangeLogClick);
findPreference("system_about").setTitle(getString(R.string.pref_about, getString(R.string.app_name)));
findPreference("system_about").setOnPreferenceClickListener(onAboutClick);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@OptionsItem(android.R.id.home)
protected void navigateUp() {
MainSettingsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start();
}
protected Dialog onCreateDialog(int id) { protected Dialog onCreateDialog(int id) {
switch (id) { switch (id) {
case DIALOG_CHANGELOG: case DIALOG_CHANGELOG:

15
app/src/main/java/org/transdroid/core/gui/settings/KeyBoundPreferencesActivity.java

@ -51,6 +51,13 @@ public abstract class KeyBoundPreferencesActivity extends PreferenceCompatActivi
private SharedPreferences sharedPrefs; private SharedPreferences sharedPrefs;
private Map<String, String> originalSummaries = new HashMap<>(); private Map<String, String> originalSummaries = new HashMap<>();
private OnSharedPreferenceChangeListener onPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
showValueOnSummary(key);
onPreferencesChanged();
}
};
/** /**
* Should be called during the activity {@link #onCreate(android.os.Bundle)} (but after super.onCreate(Bundle)) to * Should be called during the activity {@link #onCreate(android.os.Bundle)} (but after super.onCreate(Bundle)) to
@ -88,14 +95,6 @@ public abstract class KeyBoundPreferencesActivity extends PreferenceCompatActivi
onPreferenceChangeListener); onPreferenceChangeListener);
} }
private OnSharedPreferenceChangeListener onPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
showValueOnSummary(key);
onPreferencesChanged();
}
};
/** /**
* Key-bound preference activities may override this method if they want to react to preference changes. * Key-bound preference activities may override this method if they want to react to preference changes.
*/ */

17
app/src/main/java/org/transdroid/core/gui/settings/RssfeedPreference.java

@ -33,6 +33,14 @@ public class RssfeedPreference extends Preference {
private RssfeedSetting rssfeedSetting; private RssfeedSetting rssfeedSetting;
private OnRssfeedClickedListener onRssfeedClickedListener = null; private OnRssfeedClickedListener onRssfeedClickedListener = null;
private OnPreferenceClickListener onPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onRssfeedClickedListener != null)
onRssfeedClickedListener.onRssfeedClicked(rssfeedSetting);
return true;
}
};
public RssfeedPreference(Context context) { public RssfeedPreference(Context context) {
super(context); super(context);
@ -65,15 +73,6 @@ public class RssfeedPreference extends Preference {
return this; return this;
} }
private OnPreferenceClickListener onPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onRssfeedClickedListener != null)
onRssfeedClickedListener.onRssfeedClicked(rssfeedSetting);
return true;
}
};
public interface OnRssfeedClickedListener { public interface OnRssfeedClickedListener {
void onRssfeedClicked(RssfeedSetting rssfeedSetting); void onRssfeedClicked(RssfeedSetting rssfeedSetting);
} }

17
app/src/main/java/org/transdroid/core/gui/settings/ServerPreference.java

@ -33,6 +33,14 @@ public class ServerPreference extends Preference {
protected ServerSetting serverSetting; protected ServerSetting serverSetting;
private OnServerClickedListener onServerClickedListener = null; private OnServerClickedListener onServerClickedListener = null;
private OnPreferenceClickListener onPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onServerClickedListener != null)
onServerClickedListener.onServerClicked(serverSetting);
return true;
}
};
public ServerPreference(Context context) { public ServerPreference(Context context) {
super(context); super(context);
@ -65,15 +73,6 @@ public class ServerPreference extends Preference {
return this; return this;
} }
private OnPreferenceClickListener onPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onServerClickedListener != null)
onServerClickedListener.onServerClicked(serverSetting);
return true;
}
};
public interface OnServerClickedListener { public interface OnServerClickedListener {
public void onServerClicked(ServerSetting serverSetting); public void onServerClicked(ServerSetting serverSetting);
} }

4
app/src/main/java/org/transdroid/core/gui/settings/ServerSettingsActivity.java

@ -49,11 +49,9 @@ import org.transdroid.daemon.Daemon;
@OptionsMenu(R.menu.activity_deleteableprefs) @OptionsMenu(R.menu.activity_deleteableprefs)
public class ServerSettingsActivity extends KeyBoundPreferencesActivity { public class ServerSettingsActivity extends KeyBoundPreferencesActivity {
private static final int DIALOG_CONFIRMREMOVE = 0;
@Bean @Bean
protected ConnectivityHelper connectivityHelper; protected ConnectivityHelper connectivityHelper;
private static final int DIALOG_CONFIRMREMOVE = 0;
private EditTextPreference extraPass, folder, downloadDir, excludeFilter, includeFilter, localNetworkPreference; private EditTextPreference extraPass, folder, downloadDir, excludeFilter, includeFilter, localNetworkPreference;
@Override @Override

24
app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java

@ -58,6 +58,17 @@ import java.io.OutputStream;
public class SystemSettingsActivity extends PreferenceCompatActivity { public class SystemSettingsActivity extends PreferenceCompatActivity {
protected static final int DIALOG_IMPORTSETTINGS = 0; protected static final int DIALOG_IMPORTSETTINGS = 0;
protected static final int DIALOG_EXPORTSETTINGS = 1;
protected static final int ACTIVITY_IMPORT_SETTINGS = 1;
protected static final int ACTIVITY_EXPORT_SETTINGS = 2;
@Bean
protected NavigationHelper navigationHelper;
@Bean
protected ApplicationSettings applicationSettings;
@Bean
protected ErrorLogSender errorLogSender;
@Bean
protected SettingsPersistence settingsPersistence;
private OnPreferenceClickListener onImportSettingsClick = new OnPreferenceClickListener() { private OnPreferenceClickListener onImportSettingsClick = new OnPreferenceClickListener() {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
@ -66,7 +77,6 @@ public class SystemSettingsActivity extends PreferenceCompatActivity {
return true; return true;
} }
}; };
protected static final int DIALOG_EXPORTSETTINGS = 1;
private OnPreferenceClickListener onExportSettingsClick = new OnPreferenceClickListener() { private OnPreferenceClickListener onExportSettingsClick = new OnPreferenceClickListener() {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
@ -75,18 +85,6 @@ public class SystemSettingsActivity extends PreferenceCompatActivity {
return true; return true;
} }
}; };
protected static final int ACTIVITY_IMPORT_SETTINGS = 1;
protected static final int ACTIVITY_EXPORT_SETTINGS = 2;
@Bean
protected NavigationHelper navigationHelper;
@Bean
protected ApplicationSettings applicationSettings;
@Bean
protected ErrorLogSender errorLogSender;
@Bean
protected SettingsPersistence settingsPersistence;
private OnPreferenceClickListener onCheckUpdatesClick = new OnPreferenceClickListener() { private OnPreferenceClickListener onCheckUpdatesClick = new OnPreferenceClickListener() {
@Override @Override
public boolean onPreferenceClick(Preference preference) { public boolean onPreferenceClick(Preference preference) {

17
app/src/main/java/org/transdroid/core/gui/settings/WebsearchPreference.java

@ -33,6 +33,14 @@ public class WebsearchPreference extends Preference {
private WebsearchSetting websearchSetting; private WebsearchSetting websearchSetting;
private OnWebsearchClickedListener onWebsearchClickedListener = null; private OnWebsearchClickedListener onWebsearchClickedListener = null;
private OnPreferenceClickListener onPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onWebsearchClickedListener != null)
onWebsearchClickedListener.onWebsearchClicked(websearchSetting);
return true;
}
};
public WebsearchPreference(Context context) { public WebsearchPreference(Context context) {
super(context); super(context);
@ -65,15 +73,6 @@ public class WebsearchPreference extends Preference {
return this; return this;
} }
private OnPreferenceClickListener onPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onWebsearchClickedListener != null)
onWebsearchClickedListener.onWebsearchClicked(websearchSetting);
return true;
}
};
public interface OnWebsearchClickedListener { public interface OnWebsearchClickedListener {
void onWebsearchClicked(WebsearchSetting serverSetting); void onWebsearchClicked(WebsearchSetting serverSetting);
} }

85
app/src/main/java/org/transdroid/core/rssparser/Channel.java

@ -13,6 +13,15 @@ import java.util.List;
public class Channel implements Parcelable { public class Channel implements Parcelable {
public static final Parcelable.Creator<Channel> CREATOR = new Parcelable.Creator<Channel>() {
public Channel createFromParcel(Parcel in) {
return new Channel(in);
}
public Channel[] newArray(int size) {
return new Channel[size];
}
};
private int id; private int id;
private String title; private String title;
private String link; private String link;
@ -28,56 +37,67 @@ public class Channel implements Parcelable {
this.items = new ArrayList<>(); this.items = new ArrayList<>();
} }
public void setId(int id) { private Channel(Parcel in) {
this.id = id; this();
id = in.readInt();
title = in.readString();
link = in.readString();
description = in.readString();
long pubDateIn = in.readLong();
pubDate = pubDateIn == -1 ? null : new Date(pubDateIn);
lastBuildDate = in.readLong();
categories = new ArrayList<>();
in.readTypedList(items, Item.CREATOR);
in.readStringList(categories);
image = in.readString();
} }
public int getId() { public int getId() {
return id; return id;
} }
public void setTitle(String title) { public void setId(int id) {
this.title = title; this.id = id;
} }
public String getTitle() { public String getTitle() {
return title; return title;
} }
public void setLink(String link) { public void setTitle(String title) {
this.link = link; this.title = title;
} }
public String getLink() { public String getLink() {
return link; return link;
} }
public void setDescription(String description) { public void setLink(String link) {
this.description = description; this.link = link;
} }
public String getDescription() { public String getDescription() {
return description; return description;
} }
public void setPubDate(Date date) { public void setDescription(String description) {
this.pubDate = date; this.description = description;
} }
public Date getPubDate() { public Date getPubDate() {
return pubDate; return pubDate;
} }
public void setLastBuildDate(long lastBuildDate) { public void setPubDate(Date date) {
this.lastBuildDate = lastBuildDate; this.pubDate = date;
} }
public long getLastBuildDate() { public long getLastBuildDate() {
return lastBuildDate; return lastBuildDate;
} }
public void setCategories(List<String> categories) { public void setLastBuildDate(long lastBuildDate) {
this.categories = categories; this.lastBuildDate = lastBuildDate;
} }
public void addCategory(String category) { public void addCategory(String category) {
@ -88,8 +108,8 @@ public class Channel implements Parcelable {
return categories; return categories;
} }
public void setItems(List<Item> items) { public void setCategories(List<String> categories) {
this.items = items; this.categories = categories;
} }
public void addItem(Item item) { public void addItem(Item item) {
@ -100,14 +120,18 @@ public class Channel implements Parcelable {
return items; return items;
} }
public void setImage(String image) { public void setItems(List<Item> items) {
this.image = image; this.items = items;
} }
public String getImage() { public String getImage() {
return image; return image;
} }
public void setImage(String image) {
this.image = image;
}
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;
@ -126,29 +150,4 @@ public class Channel implements Parcelable {
out.writeString(image); out.writeString(image);
} }
public static final Parcelable.Creator<Channel> CREATOR = new Parcelable.Creator<Channel>() {
public Channel createFromParcel(Parcel in) {
return new Channel(in);
}
public Channel[] newArray(int size) {
return new Channel[size];
}
};
private Channel(Parcel in) {
this();
id = in.readInt();
title = in.readString();
link = in.readString();
description = in.readString();
long pubDateIn = in.readLong();
pubDate = pubDateIn == -1 ? null : new Date(pubDateIn);
lastBuildDate = in.readLong();
categories = new ArrayList<>();
in.readTypedList(items, Item.CREATOR);
in.readStringList(categories);
image = in.readString();
}
} }

92
app/src/main/java/org/transdroid/core/rssparser/Item.java

@ -12,6 +12,15 @@ import java.util.Date;
public class Item implements Parcelable { public class Item implements Parcelable {
public static final Parcelable.Creator<Item> CREATOR = new Parcelable.Creator<Item>() {
public Item createFromParcel(Parcel in) {
return new Item(in);
}
public Item[] newArray(int size) {
return new Item[size];
}
};
private int id; private int id;
private String title; private String title;
private String link; private String link;
@ -20,76 +29,91 @@ public class Item implements Parcelable {
private String enclosureUrl; private String enclosureUrl;
private String enclosureType; private String enclosureType;
private long enclosureLength; private long enclosureLength;
/** /**
* isNew is not parsed from the RSS feed but may be set using {@link #setIsNew(boolean)} manually * isNew is not parsed from the RSS feed but may be set using {@link #setIsNew(boolean)} manually
*/ */
private boolean isNew; private boolean isNew;
public void setId(int id) { public Item() {
this.id = id; }
private Item(Parcel in) {
id = in.readInt();
title = in.readString();
link = in.readString();
description = in.readString();
long pubDateIn = in.readLong();
pubDate = pubDateIn == -1 ? null : new Date(pubDateIn);
enclosureUrl = in.readString();
enclosureType = in.readString();
enclosureLength = in.readLong();
isNew = in.readInt() == 1;
} }
public int getId() { public int getId() {
return id; return id;
} }
public void setTitle(String title) { public void setId(int id) {
this.title = title; this.id = id;
} }
public String getTitle() { public String getTitle() {
return this.title; return this.title;
} }
public void setDescription(String description) { public void setTitle(String title) {
this.description = description; this.title = title;
} }
public String getDescription() { public String getDescription() {
return this.description; return this.description;
} }
public void setLink(String link) { public void setDescription(String description) {
this.link = link; this.description = description;
} }
public String getLink() { public String getLink() {
return this.link; return this.link;
} }
public void setPubdate(Date pubdate) { public void setLink(String link) {
this.pubDate = pubdate; this.link = link;
} }
public Date getPubdate() { public Date getPubdate() {
return this.pubDate; return this.pubDate;
} }
public void setEnclosureUrl(String enclosureUrl) { public void setPubdate(Date pubdate) {
this.enclosureUrl = enclosureUrl; this.pubDate = pubdate;
}
public void setEnclosureLength(long enclosureLength) {
this.enclosureLength = enclosureLength;
}
public void setEnclosureType(String enclosureType) {
this.enclosureType = enclosureType;
} }
public String getEnclosureUrl() { public String getEnclosureUrl() {
return this.enclosureUrl; return this.enclosureUrl;
} }
public void setEnclosureUrl(String enclosureUrl) {
this.enclosureUrl = enclosureUrl;
}
public String getEnclosureType() { public String getEnclosureType() {
return this.enclosureType; return this.enclosureType;
} }
public void setEnclosureType(String enclosureType) {
this.enclosureType = enclosureType;
}
public long getEnclosureLength() { public long getEnclosureLength() {
return this.enclosureLength; return this.enclosureLength;
} }
public void setEnclosureLength(long enclosureLength) {
this.enclosureLength = enclosureLength;
}
public void setIsNew(boolean isNew) { public void setIsNew(boolean isNew) {
this.isNew = isNew; this.isNew = isNew;
} }
@ -140,30 +164,4 @@ public class Item implements Parcelable {
out.writeInt(isNew ? 1 : 0); out.writeInt(isNew ? 1 : 0);
} }
public static final Parcelable.Creator<Item> CREATOR = new Parcelable.Creator<Item>() {
public Item createFromParcel(Parcel in) {
return new Item(in);
}
public Item[] newArray(int size) {
return new Item[size];
}
};
public Item() {
}
private Item(Parcel in) {
id = in.readInt();
title = in.readString();
link = in.readString();
description = in.readString();
long pubDateIn = in.readLong();
pubDate = pubDateIn == -1 ? null : new Date(pubDateIn);
enclosureUrl = in.readString();
enclosureType = in.readString();
enclosureLength = in.readLong();
isNew = in.readInt() == 1;
}
} }

17
app/src/main/java/org/transdroid/core/seedbox/SeedboxPreference.java

@ -33,6 +33,14 @@ public class SeedboxPreference extends ServerPreference {
private SeedboxProvider provider = null; private SeedboxProvider provider = null;
private OnSeedboxClickedListener onSeedboxClickedListener = null; private OnSeedboxClickedListener onSeedboxClickedListener = null;
private int onSeedboxClickedListenerOffset = 0; private int onSeedboxClickedListenerOffset = 0;
private OnPreferenceClickListener onSeedboxPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onSeedboxClickedListener != null)
onSeedboxClickedListener.onSeedboxClicked(serverSetting, provider, onSeedboxClickedListenerOffset);
return true;
}
};
public SeedboxPreference(Context context) { public SeedboxPreference(Context context) {
super(context); super(context);
@ -74,15 +82,6 @@ public class SeedboxPreference extends ServerPreference {
return provider; return provider;
} }
private OnPreferenceClickListener onSeedboxPreferenceClicked = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (onSeedboxClickedListener != null)
onSeedboxClickedListener.onSeedboxClicked(serverSetting, provider, onSeedboxClickedListenerOffset);
return true;
}
};
/** /**
* Set a listener that will be notified of click events on this preference * Set a listener that will be notified of click events on this preference
* *

3
app/src/main/java/org/transdroid/core/seedbox/XirvikSharedSettingsActivity.java

@ -55,10 +55,9 @@ import java.io.InputStream;
@OptionsMenu(resName = "activity_deleteableprefs") @OptionsMenu(resName = "activity_deleteableprefs")
public class XirvikSharedSettingsActivity extends KeyBoundPreferencesActivity { public class XirvikSharedSettingsActivity extends KeyBoundPreferencesActivity {
private EditTextPreference excludeFilter, includeFilter;
@Bean @Bean
protected Log log; protected Log log;
private EditTextPreference excludeFilter, includeFilter;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {

12
app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java

@ -92,12 +92,6 @@ public class ListWidgetConfigActivity extends AppCompatActivity {
protected ApplicationSettings applicationSettings; protected ApplicationSettings applicationSettings;
@Bean @Bean
protected SystemSettings systemSettings; protected SystemSettings systemSettings;
protected OnCheckedChangeListener reverseorderCheckedChanged = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
filterTorrents();
}
};
protected OnCheckedChangeListener showstatusCheckChanged = new OnCheckedChangeListener() { protected OnCheckedChangeListener showstatusCheckChanged = new OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@ -106,6 +100,12 @@ public class ListWidgetConfigActivity extends AppCompatActivity {
} }
}; };
private List<Torrent> previewTorrents = null; private List<Torrent> previewTorrents = null;
protected OnCheckedChangeListener reverseorderCheckedChanged = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
filterTorrents();
}
};
private int appWidgetId; private int appWidgetId;
private OnClickListener doneClicked = new OnClickListener() { private OnClickListener doneClicked = new OnClickListener() {
@Override @Override

4
app/src/main/java/org/transdroid/daemon/Daemon.java

@ -137,8 +137,6 @@ public enum Daemon {
} }
}; };
public abstract IDaemonAdapter createAdapter(DaemonSettings settings);
/** /**
* Returns the code as used in preferences matching the given daemon type * Returns the code as used in preferences matching the given daemon type
* *
@ -429,4 +427,6 @@ public enum Daemon {
return type == uTorrent || type == DelugeRpc || type == Deluge2Rpc; return type == uTorrent || type == DelugeRpc || type == Deluge2Rpc;
} }
public abstract IDaemonAdapter createAdapter(DaemonSettings settings);
} }

20
app/src/main/java/org/transdroid/daemon/DaemonException.java

@ -34,16 +34,6 @@ public class DaemonException extends Exception {
private ExceptionType internalException; private ExceptionType internalException;
public enum ExceptionType {
MethodUnsupported,
ConnectionError,
UnexpectedResponse,
ParsingFailed,
AuthenticationFailure,
NotConnected,
FileAccessError
}
public DaemonException(ExceptionType internalException, String message) { public DaemonException(ExceptionType internalException, String message) {
super(message); super(message);
this.internalException = internalException; this.internalException = internalException;
@ -59,4 +49,14 @@ public class DaemonException extends Exception {
return internalException.toString() + " exception: " + getMessage(); return internalException.toString() + " exception: " + getMessage();
} }
public enum ExceptionType {
MethodUnsupported,
ConnectionError,
UnexpectedResponse,
ParsingFailed,
AuthenticationFailure,
NotConnected,
FileAccessError
}
} }

11
app/src/main/java/org/transdroid/daemon/DaemonMethod.java

@ -48,7 +48,6 @@ public enum DaemonMethod {
ToggleSequentialDownload(23), ToggleSequentialDownload(23),
ToggleFirstLastPieceDownload(24); ToggleFirstLastPieceDownload(24);
private int code;
private static final Map<Integer, DaemonMethod> lookup = new HashMap<>(); private static final Map<Integer, DaemonMethod> lookup = new HashMap<>();
static { static {
@ -56,16 +55,18 @@ public enum DaemonMethod {
lookup.put(s.getCode(), s); lookup.put(s.getCode(), s);
} }
private int code;
DaemonMethod(int code) { DaemonMethod(int code) {
this.code = code; this.code = code;
} }
public int getCode() {
return code;
}
public static DaemonMethod getStatus(int code) { public static DaemonMethod getStatus(int code) {
return lookup.get(code); return lookup.get(code);
} }
public int getCode() {
return code;
}
} }

19
app/src/main/java/org/transdroid/daemon/Deluge/DelugeRemoteRssChannel.java

@ -16,6 +16,15 @@ import java.util.List;
*/ */
class DelugeRemoteRssChannel extends RemoteRssChannel { class DelugeRemoteRssChannel extends RemoteRssChannel {
public static final Parcelable.Creator<DelugeRemoteRssChannel> CREATOR = new Parcelable.Creator<DelugeRemoteRssChannel>() {
public DelugeRemoteRssChannel createFromParcel(Parcel in) {
return new DelugeRemoteRssChannel(in);
}
public DelugeRemoteRssChannel[] newArray(int size) {
return new DelugeRemoteRssChannel[size];
}
};
private final String label; private final String label;
private final String downloadLocation; private final String downloadLocation;
private final String moveCompleted; private final String moveCompleted;
@ -73,14 +82,4 @@ class DelugeRemoteRssChannel extends RemoteRssChannel {
public String getMoveCompleted() { public String getMoveCompleted() {
return moveCompleted; return moveCompleted;
} }
public static final Parcelable.Creator<DelugeRemoteRssChannel> CREATOR = new Parcelable.Creator<DelugeRemoteRssChannel>() {
public DelugeRemoteRssChannel createFromParcel(Parcel in) {
return new DelugeRemoteRssChannel(in);
}
public DelugeRemoteRssChannel[] newArray(int size) {
return new DelugeRemoteRssChannel[size];
}
};
} }

20
app/src/main/java/org/transdroid/daemon/Deluge/DelugeRemoteRssItem.java

@ -13,6 +13,16 @@ import java.util.Date;
* @author alonalbert * @author alonalbert
*/ */
class DelugeRemoteRssItem extends RemoteRssItem { class DelugeRemoteRssItem extends RemoteRssItem {
public static final Parcelable.Creator<DelugeRemoteRssItem> CREATOR = new Parcelable.Creator<DelugeRemoteRssItem>() {
public DelugeRemoteRssItem createFromParcel(Parcel in) {
return new DelugeRemoteRssItem(in);
}
public DelugeRemoteRssItem[] newArray(int size) {
return new DelugeRemoteRssItem[size];
}
};
DelugeRemoteRssItem(String title, String link, String sourceName, Date timestamp) { DelugeRemoteRssItem(String title, String link, String sourceName, Date timestamp) {
this.title = title; this.title = title;
this.link = link; this.link = link;
@ -34,14 +44,4 @@ class DelugeRemoteRssItem extends RemoteRssItem {
dest.writeString(sourceName); dest.writeString(sourceName);
dest.writeSerializable(timestamp); dest.writeSerializable(timestamp);
} }
public static final Parcelable.Creator<DelugeRemoteRssItem> CREATOR = new Parcelable.Creator<DelugeRemoteRssItem>() {
public DelugeRemoteRssItem createFromParcel(Parcel in) {
return new DelugeRemoteRssItem(in);
}
public DelugeRemoteRssItem[] newArray(int size) {
return new DelugeRemoteRssItem[size];
}
};
} }

5
app/src/main/java/org/transdroid/daemon/Deluge/DelugeRpcClient.java

@ -52,10 +52,9 @@ class DelugeRpcClient implements Closeable {
private static final int RPC_ERROR = 2; private static final int RPC_ERROR = 2;
private static final byte V2_PROTOCOL_VERSION = 1; private static final byte V2_PROTOCOL_VERSION = 1;
private static final int V2_HEADER_SIZE = 5; private static final int V2_HEADER_SIZE = 5;
private Socket socket;
private final boolean isVersion2;
private static AtomicInteger requestId = new AtomicInteger(); private static AtomicInteger requestId = new AtomicInteger();
private final boolean isVersion2;
private Socket socket;
DelugeRpcClient(boolean isVersion2) { DelugeRpcClient(boolean isVersion2) {
this.isVersion2 = isVersion2; this.isVersion2 = isVersion2;

33
app/src/main/java/org/transdroid/daemon/Label.java

@ -28,16 +28,17 @@ import android.os.Parcelable;
*/ */
public final class Label implements Parcelable, Comparable<Label> { public final class Label implements Parcelable, Comparable<Label> {
final private String name; public static final Parcelable.Creator<Label> CREATOR = new Parcelable.Creator<Label>() {
final private int count; public Label createFromParcel(Parcel in) {
return new Label(in);
public String getName() {
return name;
} }
public int getCount() { public Label[] newArray(int size) {
return count; return new Label[size];
} }
};
final private String name;
final private int count;
private Label(Parcel in) { private Label(Parcel in) {
this.name = in.readString(); this.name = in.readString();
@ -49,6 +50,14 @@ public final class Label implements Parcelable, Comparable<Label> {
this.count = count; this.count = count;
} }
public String getName() {
return name;
}
public int getCount() {
return count;
}
@Override @Override
public String toString() { public String toString() {
return name;//+"("+String.valueOf(count)+")"; return name;//+"("+String.valueOf(count)+")";
@ -60,16 +69,6 @@ public final class Label implements Parcelable, Comparable<Label> {
return name.compareTo(another.getName()); return name.compareTo(another.getName());
} }
public static final Parcelable.Creator<Label> CREATOR = new Parcelable.Creator<Label>() {
public Label createFromParcel(Parcel in) {
return new Label(in);
}
public Label[] newArray(int size) {
return new Label[size];
}
};
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;

11
app/src/main/java/org/transdroid/daemon/Priority.java

@ -33,7 +33,6 @@ public enum Priority {
Normal(2), Normal(2),
High(3); High(3);
private int code;
private static final Map<Integer, Priority> lookup = new HashMap<Integer, Priority>(); private static final Map<Integer, Priority> lookup = new HashMap<Integer, Priority>();
static { static {
@ -41,18 +40,20 @@ public enum Priority {
lookup.put(s.getCode(), s); lookup.put(s.getCode(), s);
} }
private int code;
Priority(int code) { Priority(int code) {
this.code = code; this.code = code;
} }
public int getCode() {
return code;
}
public static Priority getPriority(int code) { public static Priority getPriority(int code) {
return lookup.get(code); return lookup.get(code);
} }
public int getCode() {
return code;
}
public int comparePriorityTo(Priority another) { public int comparePriorityTo(Priority another) {
return new Integer(this.getCode()).compareTo(new Integer(another.getCode())); return new Integer(this.getCode()).compareTo(new Integer(another.getCode()));
} }

38
app/src/main/java/org/transdroid/daemon/Tfb4rt/Tfb4rtAdapter.java

@ -81,6 +81,25 @@ public class Tfb4rtAdapter implements IDaemonAdapter {
this.settings = settings; this.settings = settings;
} }
/**
* Calculate the MD5 hash of a password to use with the Torrentflux-b4rt dispatcher requests.
*
* @param pass The plain text password
* @return A hex-formatted MD5-hashed string of the password
*/
public static String md5Pass(String pass) {
try {
MessageDigest m = MessageDigest.getInstance("MD5");
byte[] data = pass.getBytes();
m.update(data, 0, data.length);
BigInteger i = new BigInteger(1, m.digest());
return String.format("%1$032X", i);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
@Override @Override
public DaemonTaskResult executeTask(Log log, DaemonTask task) { public DaemonTaskResult executeTask(Log log, DaemonTask task) {
@ -282,25 +301,6 @@ public class Tfb4rtAdapter implements IDaemonAdapter {
+ md5Pass((settings.getPassword() == null ? "" : settings.getPassword())); + md5Pass((settings.getPassword() == null ? "" : settings.getPassword()));
} }
/**
* Calculate the MD5 hash of a password to use with the Torrentflux-b4rt dispatcher requests.
*
* @param pass The plain text password
* @return A hex-formatted MD5-hashed string of the password
*/
public static String md5Pass(String pass) {
try {
MessageDigest m = MessageDigest.getInstance("MD5");
byte[] data = pass.getBytes();
m.update(data, 0, data.length);
BigInteger i = new BigInteger(1, m.digest());
return String.format("%1$032X", i);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
@Override @Override
public Daemon getType() { public Daemon getType() {
return settings.getType(); return settings.getType();

32
app/src/main/java/org/transdroid/daemon/Torrent.java

@ -30,12 +30,18 @@ import java.util.Date;
*/ */
public final class Torrent implements Parcelable, Comparable<Torrent>, Finishable { public final class Torrent implements Parcelable, Comparable<Torrent>, Finishable {
public static final Parcelable.Creator<Torrent> CREATOR = new Parcelable.Creator<Torrent>() {
public Torrent createFromParcel(Parcel in) {
return new Torrent(in);
}
public Torrent[] newArray(int size) {
return new Torrent[size];
}
};
final private long id; final private long id;
final private String hash; final private String hash;
final private String name; final private String name;
private TorrentStatus statusCode;
private String locationDir;
final private int rateDownload; final private int rateDownload;
final private int rateUpload; final private int rateUpload;
final private int seedersConnected; final private int seedersConnected;
@ -43,20 +49,20 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
final private int leechersConnected; final private int leechersConnected;
final private int leechersKnown; final private int leechersKnown;
final private int eta; final private int eta;
final private long downloadedEver; final private long downloadedEver;
final private long uploadedEver; final private long uploadedEver;
final private long totalSize; final private long totalSize;
final private float partDone; final private float partDone;
final private float available; final private float available;
private String label;
private boolean sequentialDownload;
private boolean firstLastPieceDownload;
final private Date dateAdded; final private Date dateAdded;
final private Date dateDone; final private Date dateDone;
final private String error; final private String error;
final private Daemon daemon; final private Daemon daemon;
private TorrentStatus statusCode;
private String locationDir;
private String label;
private boolean sequentialDownload;
private boolean firstLastPieceDownload;
private Torrent(Parcel in) { private Torrent(Parcel in) {
this.id = in.readLong(); this.id = in.readLong();
@ -394,16 +400,6 @@ public final class Torrent implements Parcelable, Comparable<Torrent>, Finishabl
return name.compareTo(another.getName()); return name.compareTo(another.getName());
} }
public static final Parcelable.Creator<Torrent> CREATOR = new Parcelable.Creator<Torrent>() {
public Torrent createFromParcel(Parcel in) {
return new Torrent(in);
}
public Torrent[] newArray(int size) {
return new Torrent[size];
}
};
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;

19
app/src/main/java/org/transdroid/daemon/TorrentDetails.java

@ -30,6 +30,15 @@ import java.util.List;
*/ */
public final class TorrentDetails implements Parcelable { public final class TorrentDetails implements Parcelable {
public static final Parcelable.Creator<TorrentDetails> CREATOR = new Parcelable.Creator<TorrentDetails>() {
public TorrentDetails createFromParcel(Parcel in) {
return new TorrentDetails(in);
}
public TorrentDetails[] newArray(int size) {
return new TorrentDetails[size];
}
};
private final List<String> trackers; private final List<String> trackers;
private final List<String> errors; private final List<String> errors;
private final List<Integer> pieces; private final List<Integer> pieces;
@ -97,16 +106,6 @@ public final class TorrentDetails implements Parcelable {
return this.pieces; return this.pieces;
} }
public static final Parcelable.Creator<TorrentDetails> CREATOR = new Parcelable.Creator<TorrentDetails>() {
public TorrentDetails createFromParcel(Parcel in) {
return new TorrentDetails(in);
}
public TorrentDetails[] newArray(int size) {
return new TorrentDetails[size];
}
};
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;

80
app/src/main/java/org/transdroid/daemon/TorrentFile.java

@ -32,6 +32,16 @@ import java.util.Map;
*/ */
public final class TorrentFile implements Parcelable, Comparable<TorrentFile>, Finishable { public final class TorrentFile implements Parcelable, Comparable<TorrentFile>, Finishable {
public static final Parcelable.Creator<TorrentFile> CREATOR = new Parcelable.Creator<TorrentFile>() {
public TorrentFile createFromParcel(Parcel in) {
return new TorrentFile(in);
}
public TorrentFile[] newArray(int size) {
return new TorrentFile[size];
}
};
private static final Map<String, String> mimeTypes = fillMimeTypes();
private final String key; private final String key;
private final String name; private final String name;
private final String relativePath; private final String relativePath;
@ -60,6 +70,35 @@ public final class TorrentFile implements Parcelable, Comparable<TorrentFile>, F
this.priority = Priority.getPriority(in.readInt()); this.priority = Priority.getPriority(in.readInt());
} }
private static Map<String, String> fillMimeTypes() {
// Full mime type support list is in http://code.google.com/p/android-vlc-remote/source/browse/trunk/AndroidManifest.xml
// We use a selection of the most popular/obvious ones
HashMap<String, String> types = new HashMap<String, String>();
// Application
types.put("m4a", "application/x-extension-m4a");
types.put("flac", "application/x-flac");
types.put("mkv", "application/x-matroska");
types.put("ogg", "application/x-ogg");
// Audio
types.put("m3u", "audio/mpegurl");
types.put("mp3", "audio/mpeg");
types.put("mpa", "audio/mpeg");
types.put("mpc", "audio/x-musepack");
types.put("wav", "audio/x-wav");
types.put("wma", "audio/x-ms-wma");
// Video
types.put("3gp", "video/3gpp");
types.put("avi", "video/x-avi");
types.put("flv", "video/x-flv");
types.put("mov", "video/quicktime");
types.put("mp4", "video/mp4");
types.put("mpg", "video/mpeg");
types.put("mpeg", "video/mpeg");
types.put("vob", "video/mpeg");
types.put("wmv", "video/x-ms-wmv");
return types;
}
public String getKey() { public String getKey() {
return this.key; return this.key;
} }
@ -178,47 +217,6 @@ public final class TorrentFile implements Parcelable, Comparable<TorrentFile>, F
return name.compareTo(another.getName()); return name.compareTo(another.getName());
} }
private static final Map<String, String> mimeTypes = fillMimeTypes();
private static Map<String, String> fillMimeTypes() {
// Full mime type support list is in http://code.google.com/p/android-vlc-remote/source/browse/trunk/AndroidManifest.xml
// We use a selection of the most popular/obvious ones
HashMap<String, String> types = new HashMap<String, String>();
// Application
types.put("m4a", "application/x-extension-m4a");
types.put("flac", "application/x-flac");
types.put("mkv", "application/x-matroska");
types.put("ogg", "application/x-ogg");
// Audio
types.put("m3u", "audio/mpegurl");
types.put("mp3", "audio/mpeg");
types.put("mpa", "audio/mpeg");
types.put("mpc", "audio/x-musepack");
types.put("wav", "audio/x-wav");
types.put("wma", "audio/x-ms-wma");
// Video
types.put("3gp", "video/3gpp");
types.put("avi", "video/x-avi");
types.put("flv", "video/x-flv");
types.put("mov", "video/quicktime");
types.put("mp4", "video/mp4");
types.put("mpg", "video/mpeg");
types.put("mpeg", "video/mpeg");
types.put("vob", "video/mpeg");
types.put("wmv", "video/x-ms-wmv");
return types;
}
public static final Parcelable.Creator<TorrentFile> CREATOR = new Parcelable.Creator<TorrentFile>() {
public TorrentFile createFromParcel(Parcel in) {
return new TorrentFile(in);
}
public TorrentFile[] newArray(int size) {
return new TorrentFile[size];
}
};
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;

11
app/src/main/java/org/transdroid/daemon/TorrentFilesSortBy.java

@ -26,7 +26,6 @@ public enum TorrentFilesSortBy {
PartDone(2), PartDone(2),
TotalSize(3); TotalSize(3);
private int code;
private static final Map<Integer, TorrentFilesSortBy> lookup = new HashMap<Integer, TorrentFilesSortBy>(); private static final Map<Integer, TorrentFilesSortBy> lookup = new HashMap<Integer, TorrentFilesSortBy>();
static { static {
@ -34,16 +33,18 @@ public enum TorrentFilesSortBy {
lookup.put(s.getCode(), s); lookup.put(s.getCode(), s);
} }
private int code;
TorrentFilesSortBy(int code) { TorrentFilesSortBy(int code) {
this.code = code; this.code = code;
} }
public int getCode() {
return code;
}
public static TorrentFilesSortBy getStatus(int code) { public static TorrentFilesSortBy getStatus(int code) {
return lookup.get(code); return lookup.get(code);
} }
public int getCode() {
return code;
}
} }

11
app/src/main/java/org/transdroid/daemon/TorrentStatus.java

@ -31,7 +31,6 @@ public enum TorrentStatus {
Error(64), Error(64),
Unknown(0); Unknown(0);
private int code;
private static final Map<Integer, TorrentStatus> lookup = new HashMap<Integer, TorrentStatus>(); private static final Map<Integer, TorrentStatus> lookup = new HashMap<Integer, TorrentStatus>();
static { static {
@ -39,18 +38,20 @@ public enum TorrentStatus {
lookup.put(s.getCode(), s); lookup.put(s.getCode(), s);
} }
private int code;
TorrentStatus(int code) { TorrentStatus(int code) {
this.code = code; this.code = code;
} }
public int getCode() {
return code;
}
public static TorrentStatus getStatus(int code) { public static TorrentStatus getStatus(int code) {
return lookup.get(code); return lookup.get(code);
} }
public int getCode() {
return code;
}
public int compareStatusCodeTo(TorrentStatus another) { public int compareStatusCodeTo(TorrentStatus another) {
return new Integer(this.getCode()).compareTo(new Integer(another.getCode())); return new Integer(this.getCode()).compareTo(new Integer(another.getCode()));
} }

11
app/src/main/java/org/transdroid/daemon/TorrentsSortBy.java

@ -32,7 +32,6 @@ public enum TorrentsSortBy {
Percent(8), Percent(8),
Size(9); Size(9);
private int code;
private static final Map<Integer, TorrentsSortBy> lookup = new HashMap<Integer, TorrentsSortBy>(); private static final Map<Integer, TorrentsSortBy> lookup = new HashMap<Integer, TorrentsSortBy>();
static { static {
@ -40,16 +39,18 @@ public enum TorrentsSortBy {
lookup.put(s.getCode(), s); lookup.put(s.getCode(), s);
} }
private int code;
TorrentsSortBy(int code) { TorrentsSortBy(int code) {
this.code = code; this.code = code;
} }
public int getCode() {
return code;
}
public static TorrentsSortBy getStatus(int code) { public static TorrentsSortBy getStatus(int code) {
return lookup.get(code); return lookup.get(code);
} }
public int getCode() {
return code;
}
} }

3
app/src/main/java/org/transdroid/daemon/Utorrent/UtorrentAdapter.java

@ -117,11 +117,10 @@ public class UtorrentAdapter implements IDaemonAdapter, RemoteRssSupplier {
private static final int RPC_FILEDOWNLOADED_IDX = 2; private static final int RPC_FILEDOWNLOADED_IDX = 2;
private static final int RPC_FILEPRIORITY_IDX = 3; private static final int RPC_FILEPRIORITY_IDX = 3;
private static String authtoken; private static String authtoken;
private static ArrayList<RemoteRssChannel> remoteRssChannels = new ArrayList<>();
private DaemonSettings settings; private DaemonSettings settings;
private DefaultHttpClient httpclient; private DefaultHttpClient httpclient;
private static ArrayList<RemoteRssChannel> remoteRssChannels = new ArrayList<>();
/** /**
* Initialises an adapter that provides operations to the uTorrent web daemon * Initialises an adapter that provides operations to the uTorrent web daemon

20
app/src/main/java/org/transdroid/daemon/Utorrent/data/UTorrentRemoteRssChannel.java

@ -16,6 +16,16 @@ import java.util.ArrayList;
* @author Twig * @author Twig
*/ */
public class UTorrentRemoteRssChannel extends RemoteRssChannel { public class UTorrentRemoteRssChannel extends RemoteRssChannel {
public static final Parcelable.Creator<UTorrentRemoteRssChannel> CREATOR = new Parcelable.Creator<UTorrentRemoteRssChannel>() {
public UTorrentRemoteRssChannel createFromParcel(Parcel in) {
return new UTorrentRemoteRssChannel(in);
}
public UTorrentRemoteRssChannel[] newArray(int size) {
return new UTorrentRemoteRssChannel[size];
}
};
public UTorrentRemoteRssChannel(JSONArray json) throws JSONException { public UTorrentRemoteRssChannel(JSONArray json) throws JSONException {
// boolean enabled = json.getBoolean(1); // boolean enabled = json.getBoolean(1);
boolean isCustomAlias = !json.getBoolean(2); boolean isCustomAlias = !json.getBoolean(2);
@ -61,14 +71,4 @@ public class UTorrentRemoteRssChannel extends RemoteRssChannel {
dest.writeLong(lastUpdated); dest.writeLong(lastUpdated);
dest.writeList(items); dest.writeList(items);
} }
public static final Parcelable.Creator<UTorrentRemoteRssChannel> CREATOR = new Parcelable.Creator<UTorrentRemoteRssChannel>() {
public UTorrentRemoteRssChannel createFromParcel(Parcel in) {
return new UTorrentRemoteRssChannel(in);
}
public UTorrentRemoteRssChannel[] newArray(int size) {
return new UTorrentRemoteRssChannel[size];
}
};
} }

22
app/src/main/java/org/transdroid/daemon/Utorrent/data/UTorrentRemoteRssItem.java

@ -20,6 +20,17 @@ public class UTorrentRemoteRssItem extends RemoteRssItem {
// public int season; // public int season;
// public int episode; // public int episode;
public static final Parcelable.Creator<UTorrentRemoteRssItem> CREATOR = new Parcelable.Creator<UTorrentRemoteRssItem>() {
public UTorrentRemoteRssItem createFromParcel(Parcel in) {
return new UTorrentRemoteRssItem(in);
}
public UTorrentRemoteRssItem[] newArray(int size) {
return new UTorrentRemoteRssItem[size];
}
};
public UTorrentRemoteRssItem(JSONArray json) throws JSONException { public UTorrentRemoteRssItem(JSONArray json) throws JSONException {
// name = json.getString(0); // clean name // name = json.getString(0); // clean name
title = json.getString(1); // filename title = json.getString(1); // filename
@ -33,17 +44,6 @@ public class UTorrentRemoteRssItem extends RemoteRssItem {
// episode = json.getInt(7); // episode = json.getInt(7);
} }
public static final Parcelable.Creator<UTorrentRemoteRssItem> CREATOR = new Parcelable.Creator<UTorrentRemoteRssItem>() {
public UTorrentRemoteRssItem createFromParcel(Parcel in) {
return new UTorrentRemoteRssItem(in);
}
public UTorrentRemoteRssItem[] newArray(int size) {
return new UTorrentRemoteRssItem[size];
}
};
public UTorrentRemoteRssItem(Parcel in) { public UTorrentRemoteRssItem(Parcel in) {
// name = in.readString(); // name = in.readString();
title = in.readString(); title = in.readString();

74
app/src/main/java/org/transdroid/daemon/Vuze/VuzeXmlOverHttpClient.java

@ -153,6 +153,43 @@ public class VuzeXmlOverHttpClient {
this(settings, URI.create(url)); this(settings, URI.create(url));
} }
static Object deserialize(String rawText) {
// Null?
if (rawText == null || rawText.equals("null")) {
return null;
}
/* For now cast all integers as Long; this prevents casting problems later on when
* we know it's a long but the value was small so it is casted to an Integer here
// Integer?
try {
Integer integernum = Integer.parseInt(rawText);
return integernum;
} catch (NumberFormatException e) {
// Just continue trying the next type
}*/
// Long?
try {
Long longnum = Long.parseLong(rawText);
return longnum;
} catch (NumberFormatException e) {
// Just continue trying the next type
}
// Double?
try {
Double doublenum = Double.parseDouble(rawText);
return doublenum;
} catch (NumberFormatException e) {
// Just continue trying the next type
}
// String otherwise
return rawText;
}
protected Map<String, Object> callXMLRPC(Long object, String method, Object[] params, Long connectionID, boolean paramsAreVuzeObjects) throws DaemonException { protected Map<String, Object> callXMLRPC(Long object, String method, Object[] params, Long connectionID, boolean paramsAreVuzeObjects) throws DaemonException {
try { try {
@ -338,41 +375,4 @@ public class VuzeXmlOverHttpClient {
return value.toString(); return value.toString();
} }
static Object deserialize(String rawText) {
// Null?
if (rawText == null || rawText.equals("null")) {
return null;
}
/* For now cast all integers as Long; this prevents casting problems later on when
* we know it's a long but the value was small so it is casted to an Integer here
// Integer?
try {
Integer integernum = Integer.parseInt(rawText);
return integernum;
} catch (NumberFormatException e) {
// Just continue trying the next type
}*/
// Long?
try {
Long longnum = Long.parseLong(rawText);
return longnum;
} catch (NumberFormatException e) {
// Just continue trying the next type
}
// Double?
try {
Double doublenum = Double.parseDouble(rawText);
return doublenum;
} catch (NumberFormatException e) {
// Just continue trying the next type
}
// String otherwise
return rawText;
}
} }

19
app/src/main/java/org/transdroid/daemon/util/FileSizeConverter.java

@ -28,16 +28,6 @@ public class FileSizeConverter {
private static final String DECIMAL_FORMATTER = "%.1f"; private static final String DECIMAL_FORMATTER = "%.1f";
private static final String DECIMAL_FORMATTER_GB = "%.2f"; private static final String DECIMAL_FORMATTER_GB = "%.2f";
/**
* A quantity in which to express a file size.
*
* @author erickok
*/
public enum SizeUnit {
B, KB, MB, GB
}
private static int INC_SIZE = 1024; private static int INC_SIZE = 1024;
/** /**
@ -118,4 +108,13 @@ public class FileSizeConverter {
} }
} }
/**
* A quantity in which to express a file size.
*
* @author erickok
*/
public enum SizeUnit {
B, KB, MB, GB
}
} }

8
app/src/main/res/drawable-night/details_list_background.xml

@ -16,9 +16,9 @@
--> -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item <item
android:left="2dp" android:drawable="@color/transdroid_divider"
android:drawable="@color/transdroid_divider" /> android:left="2dp" />
<item <item
android:left="4dp" android:drawable="@color/transdroid_background"
android:drawable="@color/transdroid_background" /> android:left="4dp" />
</layer-list> </layer-list>

8
app/src/main/res/drawable/activatable_background.xml

@ -15,9 +15,9 @@
--> -->
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_shortAnimTime"> <selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_shortAnimTime">
<item android:state_pressed="false" android:state_selected="true" android:drawable="@drawable/list_focused" /> <item android:drawable="@drawable/list_focused" android:state_pressed="false" android:state_selected="true" />
<item android:state_pressed="false" android:state_focused="true" android:drawable="@drawable/list_focused" /> <item android:drawable="@drawable/list_focused" android:state_focused="true" android:state_pressed="false" />
<item android:state_pressed="true" android:drawable="@drawable/list_pressed" /> <item android:drawable="@drawable/list_pressed" android:state_pressed="true" />
<item android:state_activated="true" android:drawable="@drawable/list_focused" /> <item android:drawable="@drawable/list_focused" android:state_activated="true" />
<item android:drawable="@android:color/transparent" /> <item android:drawable="@android:color/transparent" />
</selector> </selector>

8
app/src/main/res/drawable/details_list_background.xml

@ -16,9 +16,9 @@
--> -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item <item
android:left="2dp" android:drawable="@color/transdroid_divider"
android:drawable="@color/transdroid_divider" /> android:left="2dp" />
<item <item
android:left="4dp" android:drawable="@color/transdroid_background"
android:drawable="@color/transdroid_background" /> android:left="4dp" />
</layer-list> </layer-list>

8
app/src/main/res/layout-land/dialog_color_picker.xml

@ -41,18 +41,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="HEX" android:hint="HEX"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:inputType="textCapCharacters"
android:maxLength="7" android:maxLength="7"
android:singleLine="true" android:singleLine="true"
android:inputType="textCapCharacters"
android:visibility="gone"></EditText> android:visibility="gone"></EditText>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="6dp" android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:layout_marginRight="6dp"
android:layout_marginBottom="5dp"
android:gravity="center" android:gravity="center"
android:text="@string/press_color_to_apply" android:text="@string/press_color_to_apply"
android:textAppearance="?android:attr/textAppearanceSmall" /> android:textAppearance="?android:attr/textAppearanceSmall" />
@ -66,8 +66,8 @@
<TextView <TextView
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:gravity="center" android:gravity="center"
android:text="↓" android:text="↓"
android:textSize="20sp" /> android:textSize="20sp" />

2
app/src/main/res/layout-w600dp/activity_search.xml

@ -57,8 +57,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:drawablePadding="8dip"
android:drawableTop="?attr/loading_progress" android:drawableTop="?attr/loading_progress"
android:drawablePadding="8dip"
android:gravity="center" android:gravity="center"
android:maxWidth="400dip" android:maxWidth="400dip"
android:padding="@dimen/margin_default" android:padding="@dimen/margin_default"

22
app/src/main/res/layout-w600dp/activity_torrents.xml

@ -16,8 +16,8 @@
--> -->
<!-- This layout is for 7" and 10" tablets in portrait and shows torrents and filters. --> <!-- This layout is for 7" and 10" tablets in portrait and shows torrents and filters. -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
@ -62,24 +62,24 @@
android:layout_width="@dimen/ui_filters_list" android:layout_width="@dimen/ui_filters_list"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_above="@id/actions_toolbar" android:layout_above="@id/actions_toolbar"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_marginBottom="5dp" android:layout_alignParentLeft="true"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp" android:layout_marginEnd="5dp"
android:layout_marginRight="5dp" android:layout_marginRight="5dp"
android:layout_marginTop="5dp" android:layout_marginBottom="5dp"
app:searchIcon="@drawable/ic_action_filter" app:iconifiedByDefault="false"
app:queryHint="@string/action_filter" app:queryHint="@string/action_filter"
app:iconifiedByDefault="false" /> app:searchIcon="@drawable/ic_action_filter" />
<ListView <ListView
android:id="@+id/filters_list" android:id="@+id/filters_list"
android:layout_width="@dimen/ui_filters_list" android:layout_width="@dimen/ui_filters_list"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_above="@id/filter_search" android:layout_above="@id/filter_search"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/torrents_toolbar" android:layout_below="@id/torrents_toolbar"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:choiceMode="singleChoice" android:choiceMode="singleChoice"
tools:listitem="@layout/list_item_filter" /> tools:listitem="@layout/list_item_filter" />
@ -107,11 +107,11 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignEnd="@+id/torrents_fragment" android:layout_alignEnd="@+id/torrents_fragment"
android:layout_alignParentBottom="true"
android:layout_alignRight="@+id/torrents_fragment" android:layout_alignRight="@+id/torrents_fragment"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_marginBottom="20dp"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:layout_marginRight="10dp" /> android:layout_marginRight="10dp"
android:layout_marginBottom="20dp" />
</RelativeLayout> </RelativeLayout>

30
app/src/main/res/layout-w900dp/activity_torrents.xml

@ -35,22 +35,22 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignEnd="@id/filters_list" android:layout_alignEnd="@id/filters_list"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@id/filters_list" android:layout_alignRight="@id/filters_list"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:minHeight="?attr/actionBarSize" /> android:minHeight="?attr/actionBarSize" />
<androidx.appcompat.widget.SearchView <androidx.appcompat.widget.SearchView
android:id="@+id/filter_search" android:id="@+id/filter_search"
android:layout_width="@dimen/ui_filters_list" android:layout_width="@dimen/ui_filters_list"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_marginBottom="5dp" android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp" android:layout_marginEnd="5dp"
android:layout_marginRight="5dp" android:layout_marginRight="5dp"
android:layout_marginTop="5dp" android:layout_marginBottom="5dp"
app:iconifiedByDefault="false" app:iconifiedByDefault="false"
app:queryHint="@string/action_filter" app:queryHint="@string/action_filter"
app:searchIcon="@drawable/ic_action_filter" /> app:searchIcon="@drawable/ic_action_filter" />
@ -60,9 +60,9 @@
android:layout_width="@dimen/ui_filters_list" android:layout_width="@dimen/ui_filters_list"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_above="@id/filter_search" android:layout_above="@id/filter_search"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/selection_toolbar" android:layout_below="@id/selection_toolbar"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:choiceMode="singleChoice" android:choiceMode="singleChoice"
tools:listitem="@layout/list_item_filter" /> tools:listitem="@layout/list_item_filter" />
@ -84,8 +84,8 @@
style="@style/DefaultToolbar" style="@style/DefaultToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toLeftOf="@id/fragments_divider"
android:layout_toStartOf="@id/fragments_divider" android:layout_toStartOf="@id/fragments_divider"
android:layout_toLeftOf="@id/fragments_divider"
android:minHeight="?attr/actionBarSize" /> android:minHeight="?attr/actionBarSize" />
<androidx.appcompat.widget.ActionMenuView <androidx.appcompat.widget.ActionMenuView
@ -93,9 +93,9 @@
style="@style/SplitToolbar" style="@style/SplitToolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toLeftOf="@id/fragments_divider"
android:layout_toStartOf="@id/fragments_divider"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_toStartOf="@id/fragments_divider"
android:layout_toLeftOf="@id/fragments_divider"
android:minHeight="?attr/actionBarSize" android:minHeight="?attr/actionBarSize"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible" /> tools:visibility="visible" />
@ -115,8 +115,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@id/torrents_toolbar" android:layout_below="@id/torrents_toolbar"
android:layout_toLeftOf="@id/fragments_divider"
android:layout_toStartOf="@id/fragments_divider" android:layout_toStartOf="@id/fragments_divider"
android:layout_toLeftOf="@id/fragments_divider"
tools:layout="@layout/fragment_torrents" /> tools:layout="@layout/fragment_torrents" />
<fragment <fragment
@ -135,11 +135,11 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_marginBottom="20dp"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:layout_marginRight="10dp" android:layout_marginRight="10dp"
android:layout_toLeftOf="@id/fragments_divider" android:layout_marginBottom="20dp"
android:layout_toStartOf="@id/fragments_divider" /> android:layout_toStartOf="@id/fragments_divider"
android:layout_toLeftOf="@id/fragments_divider" />
</RelativeLayout> </RelativeLayout>

4
app/src/main/res/layout/actionbar_addbutton.xml

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<com.getbase.floatingactionbutton.FloatingActionsMenu android:id="@+id/addmenu_button" <com.getbase.floatingactionbutton.FloatingActionsMenu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/addmenu_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:fab_addButtonColorNormal="@color/green" app:fab_addButtonColorNormal="@color/green"

4
app/src/main/res/layout/actionbar_donebutton.xml

@ -15,9 +15,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
--> -->
<FrameLayout android:id="@+id/actionbar_done" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/actionbar_done"
style="?android:actionButtonStyle" style="?android:actionButtonStyle"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1"> android:layout_weight="1">

4
app/src/main/res/layout/actionbar_serverselection.xml

@ -16,8 +16,8 @@
--> -->
<merge xmlns:android="http://schemas.android.com/apk/res/android" <merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:layout_width="match_parent" tools:layout_height="?android:attr/actionBarSize"
tools:layout_height="?android:attr/actionBarSize"> tools:layout_width="match_parent">
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"

18
app/src/main/res/layout/actionbar_serverstatus.xml

@ -18,8 +18,8 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize" android:layout_height="?android:attr/actionBarSize"
tools:background="@android:color/white" android:orientation="horizontal"
android:orientation="horizontal"> tools:background="@android:color/white">
<View <View
android:layout_width="0dp" android:layout_width="0dp"
@ -50,8 +50,8 @@
android:id="@+id/downcount_sign" android:id="@+id/downcount_sign"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="@id/downcount_text"
android:layout_toEndOf="@id/downcount_text" android:layout_toEndOf="@id/downcount_text"
android:layout_toRightOf="@id/downcount_text"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:text="↓" android:text="↓"
android:textColor="?attr/text_actionbar" android:textColor="?attr/text_actionbar"
@ -64,8 +64,8 @@
android:id="@+id/upcount_text" android:id="@+id/upcount_text"
android:layout_width="@dimen/ui_serverstatus_width" android:layout_width="@dimen/ui_serverstatus_width"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="@id/downcount_sign"
android:layout_toEndOf="@id/downcount_sign" android:layout_toEndOf="@id/downcount_sign"
android:layout_toRightOf="@id/downcount_sign"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:gravity="end" android:gravity="end"
android:textColor="?attr/text_actionbar" android:textColor="?attr/text_actionbar"
@ -76,8 +76,8 @@
android:id="@+id/upcount_sign" android:id="@+id/upcount_sign"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_toRightOf="@id/upcount_text"
android:layout_toEndOf="@id/upcount_text" android:layout_toEndOf="@id/upcount_text"
android:layout_toRightOf="@id/upcount_text"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:text="↑" android:text="↑"
android:textColor="?attr/text_actionbar" android:textColor="?attr/text_actionbar"
@ -90,9 +90,9 @@
android:id="@+id/downspeed_text" android:id="@+id/downspeed_text"
android:layout_width="@dimen/ui_serverstatus_width" android:layout_width="@dimen/ui_serverstatus_width"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/downcount_text"
android:layout_alignLeft="@id/downcount_text" android:layout_alignLeft="@id/downcount_text"
android:layout_alignRight="@id/downcount_sign" android:layout_alignRight="@id/downcount_sign"
android:layout_below="@id/downcount_text"
android:layout_marginTop="-4dip" android:layout_marginTop="-4dip"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:gravity="end" android:gravity="end"
@ -104,11 +104,11 @@
android:id="@+id/upspeed_text" android:id="@+id/upspeed_text"
android:layout_width="@dimen/ui_serverstatus_width" android:layout_width="@dimen/ui_serverstatus_width"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignLeft="@id/upcount_text" android:layout_below="@id/upcount_text"
android:layout_alignStart="@id/upcount_text" android:layout_alignStart="@id/upcount_text"
android:layout_alignRight="@id/upcount_sign" android:layout_alignLeft="@id/upcount_text"
android:layout_alignEnd="@id/upcount_sign" android:layout_alignEnd="@id/upcount_sign"
android:layout_below="@id/upcount_text" android:layout_alignRight="@id/upcount_sign"
android:layout_marginTop="-4dip" android:layout_marginTop="-4dip"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:gravity="end" android:gravity="end"

2
app/src/main/res/layout/activity_search.xml

@ -51,8 +51,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:drawablePadding="8dip"
android:drawableTop="?attr/loading_progress" android:drawableTop="?attr/loading_progress"
android:drawablePadding="8dip"
android:gravity="center" android:gravity="center"
android:maxWidth="400dip" android:maxWidth="400dip"
android:padding="@dimen/margin_default" android:padding="@dimen/margin_default"

14
app/src/main/res/layout/activity_torrents.xml

@ -15,10 +15,10 @@
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
--> -->
<!-- This layout is for phones in portrait and shows the torrents list with the filters as navigation drawer. --> <!-- This layout is for phones in portrait and shows the torrents list with the filters as navigation drawer. -->
<androidx.drawerlayout.widget.DrawerLayout android:id="@+id/drawer_layout" <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".core.gui.TorrentsActivity_"> tools:context=".core.gui.TorrentsActivity_">
@ -77,13 +77,13 @@
layout="@layout/actionbar_addbutton" layout="@layout/actionbar_addbutton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_marginBottom="16dp"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:layout_marginRight="10dp" /> android:layout_marginRight="10dp"
android:layout_marginBottom="16dp" />
</RelativeLayout> </RelativeLayout>
@ -109,10 +109,10 @@
android:id="@+id/filter_search" android:id="@+id/filter_search"
android:layout_width="@dimen/ui_filters_list" android:layout_width="@dimen/ui_filters_list"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="5dp" android:layout_marginTop="5dp"
android:layout_marginEnd="5dp" android:layout_marginEnd="5dp"
android:layout_marginRight="10dp" android:layout_marginRight="10dp"
android:layout_marginTop="5dp" android:layout_marginBottom="5dp"
app:iconifiedByDefault="false" app:iconifiedByDefault="false"
app:queryHint="@string/action_filter" app:queryHint="@string/action_filter"
app:searchIcon="@drawable/ic_action_filter" /> app:searchIcon="@drawable/ic_action_filter" />

2
app/src/main/res/layout/activity_widgetconfig.xml

@ -103,8 +103,8 @@
android:id="@+id/darktheme_check_box" android:id="@+id/darktheme_check_box"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_half"
android:layout_marginTop="@dimen/margin_half" android:layout_marginTop="@dimen/margin_half"
android:layout_marginBottom="@dimen/margin_half"
android:text="@string/widget_usedarktheme" /> android:text="@string/widget_usedarktheme" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

8
app/src/main/res/layout/dialog_about.xml

@ -29,8 +29,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/margin_half"
android:layout_marginTop="@dimen/margin_half" android:layout_marginTop="@dimen/margin_half"
android:layout_marginBottom="@dimen/margin_half"
android:drawableLeft="@drawable/ic_launcher" android:drawableLeft="@drawable/ic_launcher"
android:drawablePadding="@dimen/margin_half" android:drawablePadding="@dimen/margin_half"
android:fontFamily="sans-serif-condensed" android:fontFamily="sans-serif-condensed"
@ -61,8 +61,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/margin_default"
android:layout_marginTop="4dip" android:layout_marginTop="4dip"
android:layout_marginBottom="@dimen/margin_default"
android:gravity="center" android:gravity="center"
android:text="@string/system_license" /> android:text="@string/system_license" />
@ -80,8 +80,8 @@
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/margin_default" android:layout_marginBottom="@dimen/margin_default"
android:fontFamily="monospace" android:fontFamily="monospace"
android:textSize="12sp" android:text="@string/system_libraries"
android:text="@string/system_libraries" /> android:textSize="12sp" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

8
app/src/main/res/layout/dialog_changelog.xml

@ -17,14 +17,14 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:padding="@dimen/margin_default"
android:fillViewport="true" android:fillViewport="true"
android:orientation="vertical"> android:orientation="vertical"
android:padding="@dimen/margin_default">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/system_changelog" android:autoLink="web"
android:autoLink="web" /> android:text="@string/system_changelog" />
</ScrollView> </ScrollView>

6
app/src/main/res/layout/dialog_color_picker.xml

@ -33,9 +33,9 @@
android:id="@+id/text_hex_wrapper" android:id="@+id/text_hex_wrapper"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="6dp" android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"> android:layout_marginRight="6dp"
android:layout_marginBottom="5dp">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -51,9 +51,9 @@
android:layout_weight="1" android:layout_weight="1"
android:hint="HEX" android:hint="HEX"
android:imeOptions="actionDone" android:imeOptions="actionDone"
android:inputType="textCapCharacters"
android:maxLength="7" android:maxLength="7"
android:singleLine="true" android:singleLine="true"
android:inputType="textCapCharacters"
android:visibility="gone"></EditText> android:visibility="gone"></EditText>
</LinearLayout> </LinearLayout>

16
app/src/main/res/layout/dialog_setlabel.xml

@ -18,16 +18,16 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:padding="@dimen/margin_default" android:orientation="vertical"
android:orientation="vertical"> android:padding="@dimen/margin_default">
<TextView <TextView
android:id="@+id/pick_label" android:id="@+id/pick_label"
style="@style/SectionHeader"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/status_label_pick"
android:layout_marginBottom="@dimen/margin_half" android:layout_marginBottom="@dimen/margin_half"
style="@style/SectionHeader" /> android:text="@string/status_label_pick" />
<ListView <ListView
android:id="@+id/labels_list" android:id="@+id/labels_list"
@ -37,19 +37,19 @@
tools:listitem="@layout/list_item_simple" /> tools:listitem="@layout/list_item_simple" />
<TextView <TextView
style="@style/SectionHeader"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_default" android:layout_marginTop="@dimen/margin_default"
android:text="@string/status_label_new"
android:layout_marginBottom="@dimen/margin_half" android:layout_marginBottom="@dimen/margin_half"
style="@style/SectionHeader" /> android:text="@string/status_label_new" />
<EditText <EditText
android:id="@+id/newlabel_edit" android:id="@+id/newlabel_edit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:singleLine="true" android:hint="@string/status_label_hint"
android:inputType="textFilter" android:inputType="textFilter"
android:hint="@string/status_label_hint" /> android:singleLine="true" />
</LinearLayout> </LinearLayout>

4
app/src/main/res/layout/dialog_trackers.xml

@ -23,7 +23,7 @@
android:id="@+id/trackers_edit" android:id="@+id/trackers_edit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:minLines="5" android:inputType="textUri|textMultiLine"
android:inputType="textUri|textMultiLine" /> android:minLines="5" />
</FrameLayout> </FrameLayout>

8
app/src/main/res/layout/fragment_details.xml

@ -14,9 +14,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Transdroid. If not, see <http://www.gnu.org/licenses/>. along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
--> -->
<RelativeLayout xmlns:tools="http://schemas.android.com/tools" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/details_container" android:id="@+id/details_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".core.gui.DetailsActivity_"> tools:context=".core.gui.DetailsActivity_">
@ -72,8 +72,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:drawablePadding="8dip"
android:drawableTop="?attr/loading_progress" android:drawableTop="?attr/loading_progress"
android:drawablePadding="8dip"
android:gravity="center" android:gravity="center"
android:padding="@dimen/margin_default" android:padding="@dimen/margin_default"
android:text="@string/navigation_emptydetails" android:text="@string/navigation_emptydetails"
@ -85,8 +85,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:drawablePadding="8dip"
android:drawableTop="?attr/loading_progress" android:drawableTop="?attr/loading_progress"
android:drawablePadding="8dip"
android:gravity="center" android:gravity="center"
android:maxWidth="400dip" android:maxWidth="400dip"
android:padding="@dimen/margin_default" android:padding="@dimen/margin_default"

22
app/src/main/res/layout/fragment_details_header.xml

@ -17,23 +17,23 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginBottom="@dimen/margin_default" android:layout_marginTop="@dimen/margin_default"
android:layout_marginTop="@dimen/margin_default"> android:layout_marginBottom="@dimen/margin_default">
<LinearLayout <LinearLayout
android:id="@+id/date_label_wrapper" android:id="@+id/date_label_wrapper"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="@dimen/margin_default" android:layout_marginLeft="@dimen/margin_default"
android:layout_marginRight="@dimen/margin_default"> android:layout_marginRight="@dimen/margin_default"
android:orientation="horizontal">
<TextView <TextView
android:id="@+id/dateadded_text" android:id="@+id/dateadded_text"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.5"
android:layout_marginRight="@dimen/margin_half" android:layout_marginRight="@dimen/margin_half"
android:layout_weight="0.5"
android:textIsSelectable="false" /> android:textIsSelectable="false" />
<TextView <TextView
@ -41,10 +41,10 @@
style="@style/LabelTextView" style="@style/LabelTextView"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.5"
android:layout_marginLeft="@dimen/margin_half" android:layout_marginLeft="@dimen/margin_half"
android:textIsSelectable="true" android:layout_weight="0.5"
android:gravity="right" android:gravity="right"
android:textIsSelectable="true"
android:visibility="invisible" /> android:visibility="invisible" />
</LinearLayout> </LinearLayout>
@ -54,8 +54,8 @@
android:layout_height="@dimen/ui_details_seperator" android:layout_height="@dimen/ui_details_seperator"
android:layout_below="@id/date_label_wrapper" android:layout_below="@id/date_label_wrapper"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_marginBottom="@dimen/margin_half"
android:layout_marginTop="@dimen/margin_default" android:layout_marginTop="@dimen/margin_default"
android:layout_marginBottom="@dimen/margin_half"
android:background="@color/green" android:background="@color/green"
android:textSize="@dimen/text_enlargednumbers" /> android:textSize="@dimen/text_enlargednumbers" />
@ -98,8 +98,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/ratio_text" android:layout_below="@id/ratio_text"
android:layout_marginBottom="4dip"
android:layout_marginLeft="@dimen/margin_half" android:layout_marginLeft="@dimen/margin_half"
android:layout_marginBottom="4dip"
android:layout_toRightOf="@id/separator" android:layout_toRightOf="@id/separator"
android:fontFamily="sans-serif-light" android:fontFamily="sans-serif-light"
android:textColor="?attr/text_bright" android:textColor="?attr/text_bright"
@ -178,10 +178,10 @@
android:layout_below="@id/separator" android:layout_below="@id/separator"
android:layout_marginBottom="@dimen/margin_half" android:layout_marginBottom="@dimen/margin_half"
android:orientation="vertical" android:orientation="vertical"
android:paddingBottom="@dimen/margin_half"
android:paddingLeft="@dimen/margin_default" android:paddingLeft="@dimen/margin_default"
android:paddingTop="@dimen/margin_half"
android:paddingRight="@dimen/margin_default" android:paddingRight="@dimen/margin_default"
android:paddingTop="@dimen/margin_half"> android:paddingBottom="@dimen/margin_half">
<TextView <TextView
android:id="@+id/status_text" android:id="@+id/status_text"

4
app/src/main/res/layout/fragment_remoterss.xml

@ -27,11 +27,11 @@
android:spinnerMode="dialog" /> android:spinnerMode="dialog" />
<TextView <TextView
android:id="@+id/remoterss_status_message"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:text="@string/remoterss_loading"
android:gravity="center" android:gravity="center"
android:id="@+id/remoterss_status_message" /> android:text="@string/remoterss_loading" />
<ListView <ListView
android:id="@+id/torrents_list" android:id="@+id/torrents_list"

2
app/src/main/res/layout/fragment_rssfeeds.xml

@ -31,8 +31,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:drawablePadding="8dip"
android:drawableTop="?attr/loading_progress" android:drawableTop="?attr/loading_progress"
android:drawablePadding="8dip"
android:gravity="center" android:gravity="center"
android:maxWidth="400dip" android:maxWidth="400dip"
android:padding="@dimen/margin_default" android:padding="@dimen/margin_default"

2
app/src/main/res/layout/fragment_rssitems.xml

@ -30,8 +30,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:drawablePadding="8dip"
android:drawableTop="?attr/loading_progress" android:drawableTop="?attr/loading_progress"
android:drawablePadding="8dip"
android:gravity="center" android:gravity="center"
android:maxWidth="400dip" android:maxWidth="400dip"
android:padding="@dimen/margin_default" android:padding="@dimen/margin_default"

2
app/src/main/res/layout/fragment_searchresults.xml

@ -42,8 +42,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:drawablePadding="8dip"
android:drawableTop="?attr/loading_progress" android:drawableTop="?attr/loading_progress"
android:drawablePadding="8dip"
android:gravity="center" android:gravity="center"
android:maxWidth="400dip" android:maxWidth="400dip"
android:padding="@dimen/margin_default" android:padding="@dimen/margin_default"

8
app/src/main/res/layout/fragment_torrents.xml

@ -28,9 +28,9 @@
android:id="@+id/torrents_list" android:id="@+id/torrents_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:choiceMode="multipleChoiceModal"
android:clipToPadding="false" android:clipToPadding="false"
android:paddingBottom="35dp" android:paddingBottom="35dp"
android:choiceMode="multipleChoiceModal"
android:visibility="gone" android:visibility="gone"
tools:listitem="@layout/list_item_torrent" tools:listitem="@layout/list_item_torrent"
tools:visibility="visible" /> tools:visibility="visible" />
@ -53,8 +53,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:drawablePadding="8dip"
android:drawableTop="?attr/loading_progress" android:drawableTop="?attr/loading_progress"
android:drawablePadding="8dip"
android:gravity="center" android:gravity="center"
android:maxWidth="400dip" android:maxWidth="400dip"
android:padding="@dimen/margin_default" android:padding="@dimen/margin_default"
@ -67,8 +67,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:drawablePadding="8dip"
android:drawableTop="?attr/loading_progress" android:drawableTop="?attr/loading_progress"
android:drawablePadding="8dip"
android:gravity="center" android:gravity="center"
android:maxWidth="400dip" android:maxWidth="400dip"
android:padding="@dimen/margin_default" android:padding="@dimen/margin_default"
@ -80,8 +80,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:drawablePadding="8dip"
android:drawableTop="?attr/loading_progress" android:drawableTop="?attr/loading_progress"
android:drawablePadding="8dip"
android:gravity="center" android:gravity="center"
android:maxWidth="400dip" android:maxWidth="400dip"
android:padding="@dimen/margin_default" android:padding="@dimen/margin_default"

4
app/src/main/res/layout/list_item_filter.xml

@ -18,10 +18,10 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/activatable_background" android:background="?attr/activatable_background"
android:paddingBottom="@dimen/margin_half"
android:paddingLeft="@dimen/margin_default" android:paddingLeft="@dimen/margin_default"
android:paddingTop="@dimen/margin_half"
android:paddingRight="@dimen/margin_default" android:paddingRight="@dimen/margin_default"
android:paddingTop="@dimen/margin_half"> android:paddingBottom="@dimen/margin_half">
<TextView <TextView
android:id="@+id/item_text" android:id="@+id/item_text"

8
app/src/main/res/layout/list_item_remoterssitem.xml

@ -19,10 +19,10 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/activatable_background" android:background="?attr/activatable_background"
android:paddingBottom="@dimen/margin_default"
android:paddingLeft="@dimen/margin_default" android:paddingLeft="@dimen/margin_default"
android:paddingTop="@dimen/margin_default"
android:paddingRight="@dimen/margin_default" android:paddingRight="@dimen/margin_default"
android:paddingTop="@dimen/margin_default"> android:paddingBottom="@dimen/margin_default">
<TextView <TextView
android:id="@+id/label_text" android:id="@+id/label_text"
@ -37,12 +37,12 @@
android:id="@+id/name_text" android:id="@+id/name_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/label_text"
android:fontFamily="sans-serif-condensed" android:fontFamily="sans-serif-condensed"
android:textColor="?attr/text_bright" android:textColor="?attr/text_bright"
android:textIsSelectable="false" android:textIsSelectable="false"
android:textSize="@dimen/text_enlarged" android:textSize="@dimen/text_enlarged"
tools:text="Title for torrent" tools:text="Title for torrent" />
android:layout_below="@+id/label_text" />
<TextView <TextView
android:id="@+id/date_text" android:id="@+id/date_text"

6
app/src/main/res/layout/list_item_rssfeed.xml

@ -26,11 +26,11 @@
android:id="@+id/favicon_image" android:id="@+id/favicon_image"
android:layout_width="24dip" android:layout_width="24dip"
android:layout_height="24dip" android:layout_height="24dip"
android:layout_marginRight="@dimen/margin_default"
android:layout_marginEnd="@dimen/margin_default" android:layout_marginEnd="@dimen/margin_default"
android:layout_marginRight="@dimen/margin_default"
android:scaleType="centerCrop" android:scaleType="centerCrop"
tools:src="@drawable/ic_launcher" tools:ignore="contentDescription"
tools:ignore="contentDescription" /> tools:src="@drawable/ic_launcher" />
<TextView <TextView
android:id="@+id/name_text" android:id="@+id/name_text"

4
app/src/main/res/layout/list_item_rssitem.xml

@ -19,10 +19,10 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/activatable_background" android:background="?attr/activatable_background"
android:paddingBottom="@dimen/margin_default"
android:paddingLeft="@dimen/margin_default" android:paddingLeft="@dimen/margin_default"
android:paddingTop="@dimen/margin_default"
android:paddingRight="@dimen/margin_default" android:paddingRight="@dimen/margin_default"
android:paddingTop="@dimen/margin_default"> android:paddingBottom="@dimen/margin_default">
<TextView <TextView
android:id="@+id/name_text" android:id="@+id/name_text"

10
app/src/main/res/layout/list_item_searchresult.xml

@ -19,10 +19,10 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/activatable_background" android:background="?attr/activatable_background"
android:paddingBottom="@dimen/margin_half"
android:paddingLeft="@dimen/margin_default" android:paddingLeft="@dimen/margin_default"
android:paddingTop="@dimen/margin_half"
android:paddingRight="@dimen/margin_default" android:paddingRight="@dimen/margin_default"
android:paddingTop="@dimen/margin_half"> android:paddingBottom="@dimen/margin_half">
<TextView <TextView
android:id="@+id/name_text" android:id="@+id/name_text"
@ -38,9 +38,9 @@
android:id="@+id/leechers_text" android:id="@+id/leechers_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/name_text"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_below="@id/name_text"
android:layout_marginTop="4dip" android:layout_marginTop="4dip"
android:textIsSelectable="false" android:textIsSelectable="false"
android:textSize="@dimen/text_small" android:textSize="@dimen/text_small"
@ -53,8 +53,8 @@
android:layout_alignBaseline="@id/leechers_text" android:layout_alignBaseline="@id/leechers_text"
android:layout_marginEnd="@dimen/margin_default" android:layout_marginEnd="@dimen/margin_default"
android:layout_marginRight="@dimen/margin_default" android:layout_marginRight="@dimen/margin_default"
android:layout_toLeftOf="@id/leechers_text"
android:layout_toStartOf="@id/leechers_text" android:layout_toStartOf="@id/leechers_text"
android:layout_toLeftOf="@id/leechers_text"
android:textIsSelectable="false" android:textIsSelectable="false"
android:textSize="@dimen/text_small" android:textSize="@dimen/text_small"
tools:text="@string/search_leechers" /> tools:text="@string/search_leechers" />
@ -73,8 +73,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignBaseline="@id/leechers_text" android:layout_alignBaseline="@id/leechers_text"
android:layout_marginLeft="@dimen/margin_default"
android:layout_marginStart="@dimen/margin_default" android:layout_marginStart="@dimen/margin_default"
android:layout_marginLeft="@dimen/margin_default"
android:layout_toEndOf="@id/size_text" android:layout_toEndOf="@id/size_text"
android:layout_toRightOf="@id/size_text" android:layout_toRightOf="@id/size_text"
android:textIsSelectable="false" android:textIsSelectable="false"

4
app/src/main/res/layout/list_item_searchsite.xml

@ -20,10 +20,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/activatable_background" android:background="?attr/activatable_background"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingBottom="@dimen/margin_half"
android:paddingLeft="@dimen/margin_default" android:paddingLeft="@dimen/margin_default"
android:paddingTop="@dimen/margin_half"
android:paddingRight="@dimen/margin_default" android:paddingRight="@dimen/margin_default"
android:paddingTop="@dimen/margin_half"> android:paddingBottom="@dimen/margin_half">
<ImageView <ImageView
android:id="@+id/favicon_image" android:id="@+id/favicon_image"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save