From ba4a1c032dbffde044b70c804f9d3c1f1ba7b939 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Wed, 25 Mar 2020 13:29:17 -0700 Subject: [PATCH] Add a download location preference. https://redmine.stoutner.com/issues/32 --- app/build.gradle | 2 +- .../activities/ImportExportActivity.java | 31 +++--- .../activities/MainWebViewActivity.java | 1 + .../privacybrowser/asynctasks/GetSource.java | 4 +- .../privacybrowser/asynctasks/GetUrlSize.java | 19 ++-- .../privacybrowser/asynctasks/SaveUrl.java | 5 +- .../privacybrowser/dialogs/OpenDialog.java | 23 ++--- .../privacybrowser/dialogs/SaveDialog.java | 17 ++-- .../dialogs/SaveLogcatDialog.java | 33 +++---- .../fragments/SettingsFragment.java | 99 +++++++++++++++++-- .../helpers/DownloadLocationHelper.java | 85 ++++++++++++++++ .../helpers/ImportExportDatabaseHelper.java | 38 +++++-- ...wnloads.xml => downloads_enabled_dark.xml} | 2 +- .../res/drawable/downloads_enabled_light.xml | 13 +++ .../res/drawable/downloads_ghosted_dark.xml | 13 +++ .../res/drawable/downloads_ghosted_light.xml | 13 +++ .../drawable/full_screen_disabled_dark.xml | 2 +- .../drawable/full_screen_disabled_light.xml | 2 +- .../res/drawable/full_screen_enabled_dark.xml | 2 +- .../drawable/full_screen_enabled_light.xml | 2 +- .../search_custom_url_enabled_dark.xml | 2 +- .../search_custom_url_enabled_light.xml | 2 +- .../search_custom_url_ghosted_dark.xml | 2 +- .../search_custom_url_ghosted_light.xml | 2 +- .../main/res/menu/webview_navigation_menu.xml | 2 +- app/src/main/res/values-de/strings.xml | 4 +- app/src/main/res/values-es/strings.xml | 14 +-- app/src/main/res/values-fr/strings.xml | 4 +- app/src/main/res/values-it/strings.xml | 4 +- app/src/main/res/values-ru/strings.xml | 4 +- app/src/main/res/values-tr/strings.xml | 4 +- app/src/main/res/values/attrs.xml | 3 +- app/src/main/res/values/strings.xml | 22 ++++- app/src/main/res/values/styles.xml | 16 +-- app/src/main/res/xml/preferences.xml | 17 +++- 35 files changed, 372 insertions(+), 136 deletions(-) create mode 100644 app/src/main/java/com/stoutner/privacybrowser/helpers/DownloadLocationHelper.java rename app/src/main/res/drawable/{downloads.xml => downloads_enabled_dark.xml} (91%) create mode 100644 app/src/main/res/drawable/downloads_enabled_light.xml create mode 100644 app/src/main/res/drawable/downloads_ghosted_dark.xml create mode 100644 app/src/main/res/drawable/downloads_ghosted_light.xml diff --git a/app/build.gradle b/app/build.gradle index 5c9bb272..769e71e4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -96,5 +96,5 @@ dependencies { implementation 'com.google.android.material:material:1.1.0' // Only compile Firebase ads for the free flavor. - freeImplementation 'com.google.firebase:firebase-ads:19.0.0' + freeImplementation 'com.google.firebase:firebase-ads:19.0.1' } \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java index df41cf31..3481f312 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/ImportExportActivity.java @@ -60,6 +60,7 @@ import com.google.android.material.textfield.TextInputLayout; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.dialogs.StoragePermissionDialog; +import com.stoutner.privacybrowser.helpers.DownloadLocationHelper; import com.stoutner.privacybrowser.helpers.FileNameHelper; import com.stoutner.privacybrowser.helpers.ImportExportDatabaseHelper; @@ -176,30 +177,24 @@ public class ImportExportActivity extends AppCompatActivity implements StoragePe openKeychainImportInstructionsTextView.setVisibility(View.GONE); importExportButton.setVisibility(View.GONE); - // Create strings for the default file paths. - String defaultFilePath; - String defaultPasswordEncryptionFilePath; - String defaultPgpFilePath; + // Instantiate the download location helper. + DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper(); - // Set the default file paths according to the storage permission status. - if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted. - // Set the default file paths to use the external public directory. - defaultFilePath = Environment.getExternalStorageDirectory() + "/" + getString(R.string.settings_pbs); - defaultPasswordEncryptionFilePath = defaultFilePath + ".aes"; - defaultPgpFilePath = defaultFilePath + ".pgp"; + // Get the default file path. + String defaultFilePath = downloadLocationHelper.getDownloadLocation(this) + "/" + getString(R.string.settings_pbs); - // Hide the storage permission text view. - storagePermissionTextView.setVisibility(View.GONE); - } else { // The storage permission has not been granted. - // Set the default file paths to use the external private directory. - defaultFilePath = getApplicationContext().getExternalFilesDir(null) + "/" + getString(R.string.settings_pbs); - defaultPasswordEncryptionFilePath = defaultFilePath + ".aes"; - defaultPgpFilePath = defaultFilePath + ".pgp"; - } + // Set the other default file paths. + String defaultPasswordEncryptionFilePath = defaultFilePath + ".aes"; + String defaultPgpFilePath = defaultFilePath + ".pgp"; // Set the default file path. fileNameEditText.setText(defaultFilePath); + // Hide the storage permission text view if the permission has already been granted. + if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { + storagePermissionTextView.setVisibility(View.GONE); + } + // Update the UI when the spinner changes. encryptionSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override diff --git a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java index 63c606cd..81a80cf2 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java @@ -1895,6 +1895,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook // Launch as a new task so that Download Manager and Privacy Browser show as separate windows in the recent tasks list. downloadManagerIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + // Make it so. startActivity(downloadManagerIntent); break; diff --git a/app/src/main/java/com/stoutner/privacybrowser/asynctasks/GetSource.java b/app/src/main/java/com/stoutner/privacybrowser/asynctasks/GetSource.java index 415f35bd..f5b4e54b 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/asynctasks/GetSource.java +++ b/app/src/main/java/com/stoutner/privacybrowser/asynctasks/GetSource.java @@ -491,8 +491,8 @@ public class GetSource extends AsyncTask // Disconnect HTTP URL connection. httpUrlConnection.disconnect(); } - } catch (IOException exception) { - exception.printStackTrace(); + } catch (Exception exception) { + // Do nothing. } // Return the response body string as the result. diff --git a/app/src/main/java/com/stoutner/privacybrowser/asynctasks/GetUrlSize.java b/app/src/main/java/com/stoutner/privacybrowser/asynctasks/GetUrlSize.java index b34f62e8..74968df9 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/asynctasks/GetUrlSize.java +++ b/app/src/main/java/com/stoutner/privacybrowser/asynctasks/GetUrlSize.java @@ -28,7 +28,6 @@ import android.widget.TextView; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.helpers.ProxyHelper; -import java.io.IOException; import java.lang.ref.WeakReference; import java.net.HttpURLConnection; import java.net.Proxy; @@ -81,10 +80,10 @@ public class GetUrlSize extends AsyncTask { Proxy proxy = proxyHelper.getCurrentProxy(context); // Open a connection to the URL. No data is actually sent at this point. - HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(proxy); + HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection(proxy); // Add the user agent to the header property. - httpURLConnection.setRequestProperty("User-Agent", userAgent); + httpUrlConnection.setRequestProperty("User-Agent", userAgent); // Add the cookies if they are enabled. if (cookiesEnabled) { @@ -94,7 +93,7 @@ public class GetUrlSize extends AsyncTask { // Only add the cookies if they are not null. if (cookiesString != null) { // Add the cookies to the header property. - httpURLConnection.setRequestProperty("Cookie", cookiesString); + httpUrlConnection.setRequestProperty("Cookie", cookiesString); } } @@ -103,19 +102,19 @@ public class GetUrlSize extends AsyncTask { // Exit if the task has been cancelled. if (isCancelled()) { // Disconnect the HTTP URL connection. - httpURLConnection.disconnect(); + httpUrlConnection.disconnect(); // Return the formatted file size string. return formattedFileSize; } // Get the status code. - int responseCode = httpURLConnection.getResponseCode(); + int responseCode = httpUrlConnection.getResponseCode(); // Exit if the task has been cancelled. if (isCancelled()) { // Disconnect the HTTP URL connection. - httpURLConnection.disconnect(); + httpUrlConnection.disconnect(); // Return the formatted file size string. return formattedFileSize; @@ -127,7 +126,7 @@ public class GetUrlSize extends AsyncTask { formattedFileSize = context.getString(R.string.invalid_url); } else { // The response code is not an error message. // Get the content length header. - String contentLengthString = httpURLConnection.getHeaderField("Content-Length"); + String contentLengthString = httpUrlConnection.getHeaderField("Content-Length"); // Define the file size long. long fileSize; @@ -143,9 +142,9 @@ public class GetUrlSize extends AsyncTask { } } finally { // Disconnect the HTTP URL connection. - httpURLConnection.disconnect(); + httpUrlConnection.disconnect(); } - } catch (IOException exception) { + } catch (Exception exception) { // Set the formatted file size to indicate a bad URL. formattedFileSize = context.getString(R.string.invalid_url); } diff --git a/app/src/main/java/com/stoutner/privacybrowser/asynctasks/SaveUrl.java b/app/src/main/java/com/stoutner/privacybrowser/asynctasks/SaveUrl.java index e6b81150..6b383f4e 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/asynctasks/SaveUrl.java +++ b/app/src/main/java/com/stoutner/privacybrowser/asynctasks/SaveUrl.java @@ -41,7 +41,6 @@ import com.stoutner.privacybrowser.views.NoSwipeViewPager; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; -import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.ref.WeakReference; @@ -214,7 +213,7 @@ public class SaveUrl extends AsyncTask { // Close the output stream. outputStream.close(); - // Define a media scanner intent, which adds items like pictures to Android's recent file list. + // Create a media scanner intent, which adds items like pictures to Android's recent file list. Intent mediaScannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); // Add the URI to the media scanner intent. @@ -226,7 +225,7 @@ public class SaveUrl extends AsyncTask { // Disconnect the HTTP URL connection. httpUrlConnection.disconnect(); } - } catch (IOException exception) { + } catch (Exception exception) { // Store the error in the save disposition string. saveDisposition = exception.toString(); } diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/OpenDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/OpenDialog.java index 2d6a7761..59aa177b 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/OpenDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/OpenDialog.java @@ -48,6 +48,7 @@ import androidx.preference.PreferenceManager; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; +import com.stoutner.privacybrowser.helpers.DownloadLocationHelper; import java.io.File; @@ -143,9 +144,6 @@ public class OpenDialog extends DialogFragment { TextView storagePermissionTextView = alertDialog.findViewById(R.id.storage_permission_textview); Button openButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); - // Create a string for the default file path. - String defaultFilePath; - // Update the status of the open button when the file name changes. fileNameEditText.addTextChangedListener(new TextWatcher() { @Override @@ -183,17 +181,11 @@ public class OpenDialog extends DialogFragment { } }); - // Set the default file path according to the storage permission state. - if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted. - // Set the default file path to use the external public directory. - defaultFilePath = Environment.getExternalStorageDirectory() + "/"; + // Instantiate the download location helper. + DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper(); - // Hide the storage permission text view. - storagePermissionTextView.setVisibility(View.GONE); - } else { // The storage permission has not been granted. - // Set the default file path to use the external private directory. - defaultFilePath = context.getExternalFilesDir(null) + "/"; - } + // Get the default file path. + String defaultFilePath = downloadLocationHelper.getDownloadLocation(context) + "/"; // Display the default file path. fileNameEditText.setText(defaultFilePath); @@ -201,6 +193,11 @@ public class OpenDialog extends DialogFragment { // Move the cursor to the end of the default file path. fileNameEditText.setSelection(defaultFilePath.length()); + // Hide the storage permission text view if the permission has already been granted. + if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { + storagePermissionTextView.setVisibility(View.GONE); + } + // Handle clicks on the browse button. browseButton.setOnClickListener((View view) -> { // Create the file picker intent. diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveDialog.java index d271b876..66282c86 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveDialog.java @@ -51,6 +51,7 @@ import androidx.preference.PreferenceManager; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; import com.stoutner.privacybrowser.asynctasks.GetUrlSize; +import com.stoutner.privacybrowser.helpers.DownloadLocationHelper; import java.io.File; @@ -319,19 +320,15 @@ public class SaveDialog extends DialogFragment { // Save the file name as the default file name. This must be final to be used in the lambda below. final String defaultFileName = fileName; - // Create a string for the default file path. - String defaultFilePath; + // Instantiate the download location helper. + DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper(); - // Set the default file path according to the storage permission state. - if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted. - // Set the default file path to use the external public directory. - defaultFilePath = Environment.getExternalStorageDirectory() + "/" + defaultFileName; + // Get the default file path. + String defaultFilePath = downloadLocationHelper.getDownloadLocation(context) + "/" + defaultFileName; - // Hide the storage permission text view. + // Hide the storage permission text view if the permission has already been granted. + if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { storagePermissionTextView.setVisibility(View.GONE); - } else { // The storage permission has not been granted. - // Set the default file path to use the external private directory. - defaultFilePath = context.getExternalFilesDir(null) + "/" + defaultFileName; } // Populate the edit texts. diff --git a/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveLogcatDialog.java b/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveLogcatDialog.java index dcd10f94..624e4553 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveLogcatDialog.java +++ b/app/src/main/java/com/stoutner/privacybrowser/dialogs/SaveLogcatDialog.java @@ -47,6 +47,7 @@ import androidx.core.content.ContextCompat; import androidx.fragment.app.DialogFragment; // The AndroidX dialog fragment is required or an error is produced on API <=22. It is also required for the browse button to work correctly. import com.stoutner.privacybrowser.R; +import com.stoutner.privacybrowser.helpers.DownloadLocationHelper; import java.io.File; @@ -83,11 +84,13 @@ public class SaveLogcatDialog extends DialogFragment { // Use an alert dialog builder to create the alert dialog. AlertDialog.Builder dialogBuilder; - // Get a handle for the activity. + // Get a handle for the activity and the context. Activity activity = getActivity(); + Context context = getContext(); - // Remove the incorrect lint warning below that the activity might be null. + // Remove the incorrect lint warnings. assert activity != null; + assert context != null; // Set the style according to the theme. if (darkTheme) { @@ -175,30 +178,20 @@ public class SaveLogcatDialog extends DialogFragment { } }); - // Create a string for the default file path. - String defaultFilePath; + // Instantiate the download location helper. + DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper(); - // Get a handle for the context. - Context context = getContext(); - - // Remove the incorrect lint warning below that context might be null. - assert context != null; + // Get the default file path. + String defaultFilePath = downloadLocationHelper.getDownloadLocation(context) + "/" + getString(R.string.privacy_browser_logcat_txt); - // Set the default file path according to the storage permission state. - if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted. - // Set the default file path to use the external public directory. - defaultFilePath = Environment.getExternalStorageDirectory() + "/" + getString(R.string.privacy_browser_logcat_txt); + // Display the default file path. + fileNameEditText.setText(defaultFilePath); - // Hide the storage permission text view. + // Hide the storage permission text view if the permission has already been granted. + if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { storagePermissionTextView.setVisibility(View.GONE); - } else { // The storage permission has not been granted. - // Set the default file path to use the external private directory. - defaultFilePath = context.getExternalFilesDir(null) + "/" + getString(R.string.privacy_browser_logcat_txt); } - // Display the default file path. - fileNameEditText.setText(defaultFilePath); - // Handle clicks on the browse button. browseButton.setOnClickListener((View view) -> { // Create the file picker intent. diff --git a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java index 1d4dd164..643051ab 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java +++ b/app/src/main/java/com/stoutner/privacybrowser/fragments/SettingsFragment.java @@ -24,6 +24,7 @@ import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.res.Resources; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -38,6 +39,7 @@ import androidx.preference.PreferenceFragmentCompat; import com.stoutner.privacybrowser.R; import com.stoutner.privacybrowser.activities.MainWebViewActivity; +import com.stoutner.privacybrowser.helpers.DownloadLocationHelper; import com.stoutner.privacybrowser.helpers.ProxyHelper; public class SettingsFragment extends PreferenceFragmentCompat { @@ -95,6 +97,8 @@ public class SettingsFragment extends PreferenceFragmentCompat { Preference clearFormDataPreference = findPreference("clear_form_data"); // The clear form data preference can be removed once the minimum API >= 26. Preference clearCachePreference = findPreference("clear_cache"); Preference homepagePreference = findPreference("homepage"); + Preference downloadLocationPreference = findPreference("download_location"); + Preference downloadCustomLocationPreference = findPreference("download_custom_location"); Preference fontSizePreference = findPreference("font_size"); Preference openIntentsInNewTabPreference = findPreference("open_intents_in_new_tab"); Preference swipeToRefreshPreference = findPreference("swipe_to_refresh"); @@ -138,6 +142,8 @@ public class SettingsFragment extends PreferenceFragmentCompat { assert clearFormDataPreference != null; assert clearCachePreference != null; assert homepagePreference != null; + assert downloadLocationPreference != null; + assert downloadCustomLocationPreference != null; assert fontSizePreference != null; assert openIntentsInNewTabPreference != null; assert swipeToRefreshPreference != null; @@ -152,8 +158,10 @@ public class SettingsFragment extends PreferenceFragmentCompat { hideAppBarPreference.setDependency("full_screen_browsing_mode"); // Get strings from the preferences. + String userAgentName = savedPreferences.getString("user_agent", getString(R.string.user_agent_default_value)); String searchString = savedPreferences.getString("search", getString(R.string.search_default_value)); String proxyString = savedPreferences.getString("proxy", getString(R.string.proxy_default_value)); + String downloadLocationString = savedPreferences.getString("download_location", getString(R.string.download_location_default_value)); // Get booleans that are used in multiple places from the preferences. boolean javaScriptEnabled = savedPreferences.getBoolean("javascript", false); @@ -190,10 +198,14 @@ public class SettingsFragment extends PreferenceFragmentCompat { // Only enable Fanboy's social blocking list preference if Fanboy's annoyance list is disabled. fanboySocialBlockingListPreference.setEnabled(!fanboyAnnoyanceListEnabled); + // Inflate a WebView to get the default user agent. LayoutInflater inflater = getActivity().getLayoutInflater(); + // `@SuppressLint("InflateParams")` removes the warning about using `null` as the `ViewGroup`, which in this case makes sense because the `bare_webview` will not be displayed. @SuppressLint("InflateParams") View bareWebViewLayout = inflater.inflate(R.layout.bare_webview, null, false); + + // Get a handle for a bare WebView. WebView bareWebView = bareWebViewLayout.findViewById(R.id.bare_webview); // Get the user agent arrays. @@ -201,9 +213,6 @@ public class SettingsFragment extends PreferenceFragmentCompat { String[] translatedUserAgentNamesArray = getResources().getStringArray(R.array.translated_user_agent_names); String[] userAgentDataArray = getResources().getStringArray(R.array.user_agent_data); - // Get the current user agent name from the preference. - String userAgentName = savedPreferences.getString("user_agent", getString(R.string.user_agent_default_value)); - // Get the array position of the user agent name. int userAgentArrayPosition = userAgentNamesArray.getPosition(userAgentName); @@ -229,10 +238,13 @@ public class SettingsFragment extends PreferenceFragmentCompat { userAgentPreference.setSummary(translatedUserAgentNamesArray[userAgentArrayPosition] + ":\n" + userAgentDataArray[userAgentArrayPosition]); } - // Set the summary text for the custom user agent preference and enable it if user agent preference is set to custom. + // Set the summary text for the custom user agent preference. customUserAgentPreference.setSummary(savedPreferences.getString("custom_user_agent", getString(R.string.custom_user_agent_default_value))); + + // Only enable the custom user agent preference if the user agent is set to `Custom`. customUserAgentPreference.setEnabled(userAgentPreference.getSummary().equals(getString(R.string.custom_user_agent))); + // Set the search URL as the summary text for the search preference when the preference screen is loaded. if (searchString.equals("Custom URL")) { // Use R.string.custom_url, which will be translated, instead of the array value, which will not. @@ -242,10 +254,13 @@ public class SettingsFragment extends PreferenceFragmentCompat { searchPreference.setSummary(searchString); } - // Set the summary text for `search_custom_url` (the default is `""`) and enable it if `search` is set to `Custom URL`. + // Set the summary text for the search custom URL (the default is `""`). searchCustomURLPreference.setSummary(savedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value))); + + // Only enable the search custom URL preference if the search is set to `Custom URL`. searchCustomURLPreference.setEnabled(searchString.equals("Custom URL")); + // Set the summary text for the proxy preference when the preference screen is loaded. switch (proxyString) { case ProxyHelper.NONE: @@ -269,11 +284,12 @@ public class SettingsFragment extends PreferenceFragmentCompat { break; } + // Set the summary text for the custom proxy URL. + proxyCustomUrlPreference.setSummary(savedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value))); + // Only enable the custom proxy URL if a custom proxy is selected. proxyCustomUrlPreference.setEnabled(proxyString.equals("Custom")); - // Set the summary text for the custom proxy URL. - proxyCustomUrlPreference.setSummary(savedPreferences.getString("proxy_custom_url", getString(R.string.proxy_custom_url_default_value))); // Set the status of the Clear and Exit preferences. clearCookiesPreference.setEnabled(!clearEverything); @@ -281,12 +297,31 @@ public class SettingsFragment extends PreferenceFragmentCompat { clearFormDataPreference.setEnabled(!clearEverything); // The form data line can be removed once the minimum API is >= 26. clearCachePreference.setEnabled(!clearEverything); + // Set the homepage URL as the summary text for the homepage preference. homepagePreference.setSummary(savedPreferences.getString("homepage", getString(R.string.homepage_default_value))); + + // Instantiate the download location helper. + DownloadLocationHelper downloadLocationHelper = new DownloadLocationHelper(); + + // Set the download location summary text. + downloadLocationPreference.setSummary(downloadLocationHelper.getDownloadLocation(context)); + + // Set the summary text for the download custom location (the default is `"`). + downloadCustomLocationPreference.setSummary(savedPreferences.getString("download_custom_location", getString(R.string.download_custom_location_default_value))); + + // Get the download location entry values string array. + String[] downloadLocationEntryValuesStringArray = context.getResources().getStringArray(R.array.download_location_entry_values); + + // Only enable the download custom location preference if the download location is set to `Custom`. + downloadCustomLocationPreference.setEnabled(downloadLocationString.equals(downloadLocationEntryValuesStringArray[3])); + + // Set the font size as the summary text for the preference. fontSizePreference.setSummary(savedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%"); + // Disable the JavaScript preference if Night Mode is enabled. JavaScript will be enabled for all web pages. javaScriptPreference.setEnabled(!nightMode); @@ -725,6 +760,21 @@ public class SettingsFragment extends PreferenceFragmentCompat { clearCachePreference.setIcon(R.drawable.cache_warning); } + // Set the download custom location icon. + if (downloadCustomLocationPreference.isEnabled()) { + if (darkTheme) { + downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_dark); + } else { + downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_light); + } + } else { + if (darkTheme) { + downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_dark); + } else { + downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_light); + } + } + // Set the open intents in new tab preference icon. if (savedPreferences.getBoolean("open_intents_in_new_tab", true)) { if (darkTheme) { @@ -1303,7 +1353,7 @@ public class SettingsFragment extends PreferenceFragmentCompat { // Store the new search string. String newSearchString = sharedPreferences.getString("search", getString(R.string.search_default_value)); - // Update `searchPreference` and `searchCustomURLPreference`. + // Update the search and search custom URL preferences. if (newSearchString.equals("Custom URL")) { // `Custom URL` is selected. // Set the summary text to `R.string.custom_url`, which is translated. searchPreference.setSummary(R.string.custom_url); @@ -1334,7 +1384,7 @@ public class SettingsFragment extends PreferenceFragmentCompat { break; case "search_custom_url": - // Set the new custom search URL as the summary text for `search_custom_url`. The default is `""`. + // Set the new search custom URL as the summary text for the preference. searchCustomURLPreference.setSummary(sharedPreferences.getString("search_custom_url", getString(R.string.search_custom_url_default_value))); break; @@ -1595,6 +1645,37 @@ public class SettingsFragment extends PreferenceFragmentCompat { homepagePreference.setSummary(sharedPreferences.getString("homepage", getString(R.string.homepage_default_value))); break; + case "download_location": + // Get the new download location. + String newDownloadLocationString = sharedPreferences.getString("download_location", getString(R.string.download_location_default_value)); + + // Update the download location summary text. + downloadLocationPreference.setSummary(downloadLocationHelper.getDownloadLocation(context)); + + // Update the status of the download custom location preference. + downloadCustomLocationPreference.setEnabled(newDownloadLocationString.equals(downloadLocationEntryValuesStringArray[3])); + + // Update the download custom location icon. + if (downloadCustomLocationPreference.isEnabled()) { + if (darkTheme) { + downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_dark); + } else { + downloadCustomLocationPreference.setIcon(R.drawable.downloads_enabled_light); + } + } else { + if (darkTheme) { + downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_dark); + } else { + downloadCustomLocationPreference.setIcon(R.drawable.downloads_ghosted_light); + } + } + break; + + case "download_custom_location": + // Set the new download custom location as the summary text for the preference. + downloadCustomLocationPreference.setSummary(sharedPreferences.getString("download_custom_location", getString(R.string.download_custom_location_default_value))); + break; + case "font_size": // Update the font size summary text. fontSizePreference.setSummary(sharedPreferences.getString("font_size", getString(R.string.font_size_default_value)) + "%"); diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/DownloadLocationHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/DownloadLocationHelper.java new file mode 100644 index 00000000..f23aaea2 --- /dev/null +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/DownloadLocationHelper.java @@ -0,0 +1,85 @@ +/* + * Copyright © 2020 Soren Stoutner . + * + * This file is part of Privacy Browser . + * + * Privacy Browser is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Privacy Browser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Privacy Browser. If not, see . + */ + +package com.stoutner.privacybrowser.helpers; + +import android.Manifest; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.os.Environment; + +import androidx.core.content.ContextCompat; +import androidx.preference.PreferenceManager; + +import com.stoutner.privacybrowser.R; + +import java.io.File; + +public class DownloadLocationHelper { + public String getDownloadLocation(Context context) { + // Get the download location entry values string array. + String[] downloadLocationEntryValuesStringArray = context.getResources().getStringArray(R.array.download_location_entry_values); + + // Get the two standard download directories. + File publicDownloadDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); + File publicAppFilesDirectory = context.getExternalFilesDir(null); + + // Remove the incorrect lint warning below that the public app files directory might be null. + assert publicAppFilesDirectory != null; + + // Convert the download directories to strings. + String publicDownloadDirectoryString = publicDownloadDirectory.toString(); + String publicAppFilesDirectoryString = publicAppFilesDirectory.toString(); + + // Get a handle for the shared preferences. + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + + // Get the download location strings from the preferences. + String downloadLocationString = sharedPreferences.getString("download_location", context.getString(R.string.download_location_default_value)); + String downloadCustomLocationString = sharedPreferences.getString("download_custom_location", context.getString(R.string.download_custom_location_default_value)); + + // Define a string for the default file path. + String defaultFilePath; + + // Set the default file path according to the download location. + if (downloadLocationString.equals(downloadLocationEntryValuesStringArray[0])) { // the download location is set to auto. + // Set the download location summary text according to the storage permission status. + if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // The storage permission has been granted. + // Use the public download directory. + defaultFilePath = publicDownloadDirectoryString; + } else { // The storage permission has not been granted. + // Use the public app files directory. + defaultFilePath = publicAppFilesDirectoryString; + } + } else if (downloadLocationString.equals(downloadLocationEntryValuesStringArray[1])) { // The download location is set to the app directory. + // Use the public app files directory. + defaultFilePath = publicAppFilesDirectoryString; + } else if (downloadLocationString.equals(downloadLocationEntryValuesStringArray[2])) { // The download location is set to the public directory. + // Use the public download directory. + defaultFilePath = publicDownloadDirectoryString; + } else { // The download location is set to custom. + // Use the download custom location. + defaultFilePath = downloadCustomLocationString; + } + + // Return the default file path. + return defaultFilePath; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacybrowser/helpers/ImportExportDatabaseHelper.java b/app/src/main/java/com/stoutner/privacybrowser/helpers/ImportExportDatabaseHelper.java index 50a5ad23..74b4e510 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/helpers/ImportExportDatabaseHelper.java +++ b/app/src/main/java/com/stoutner/privacybrowser/helpers/ImportExportDatabaseHelper.java @@ -76,6 +76,8 @@ public class ImportExportDatabaseHelper { private static final String CLEAR_FORM_DATA = "clear_form_data"; private static final String CLEAR_CACHE = "clear_cache"; private static final String HOMEPAGE = "homepage"; + private static final String DOWNLOAD_LOCATION = "download_location"; + private static final String DOWNLOAD_CUSTOM_LOCATION = "download_custom_location"; private static final String FONT_SIZE = "font_size"; private static final String OPEN_INTENTS_IN_NEW_TAB = "open_intents_in_new_tab"; private static final String SWIPE_TO_REFRESH = "swipe_to_refresh"; @@ -229,6 +231,8 @@ public class ImportExportDatabaseHelper { CLEAR_FORM_DATA + " BOOLEAN, " + CLEAR_CACHE + " BOOLEAN, " + HOMEPAGE + " TEXT, " + + DOWNLOAD_LOCATION + " TEXT, " + + DOWNLOAD_CUSTOM_LOCATION + " TEXT, " + FONT_SIZE + " TEXT, " + OPEN_INTENTS_IN_NEW_TAB + " BOOLEAN, " + SWIPE_TO_REFRESH + " BOOLEAN, " + @@ -279,6 +283,8 @@ public class ImportExportDatabaseHelper { preferencesContentValues.put(CLEAR_FORM_DATA, sharedPreferences.getBoolean(CLEAR_FORM_DATA, true)); // Clear form data can be removed once the minimum API >= 26. preferencesContentValues.put(CLEAR_CACHE, sharedPreferences.getBoolean(CLEAR_CACHE, true)); preferencesContentValues.put(HOMEPAGE, sharedPreferences.getString(HOMEPAGE, context.getString(R.string.homepage_default_value))); + preferencesContentValues.put(DOWNLOAD_LOCATION, sharedPreferences.getString(DOWNLOAD_LOCATION, context.getString(R.string.download_location_default_value))); + preferencesContentValues.put(DOWNLOAD_CUSTOM_LOCATION, sharedPreferences.getString(DOWNLOAD_CUSTOM_LOCATION, context.getString(R.string.download_custom_location_default_value))); preferencesContentValues.put(FONT_SIZE, sharedPreferences.getString(FONT_SIZE, context.getString(R.string.font_size_default_value))); preferencesContentValues.put(OPEN_INTENTS_IN_NEW_TAB, sharedPreferences.getBoolean(OPEN_INTENTS_IN_NEW_TAB, true)); preferencesContentValues.put(SWIPE_TO_REFRESH, sharedPreferences.getBoolean(SWIPE_TO_REFRESH, true)); @@ -392,7 +398,7 @@ public class ImportExportDatabaseHelper { // Create the new font size column. importDatabase.execSQL("ALTER TABLE " + PREFERENCES_TABLE + " ADD COLUMN " + FONT_SIZE + " TEXT"); - // Place the font size string in the new column. + // Populate the preferences table with the current font size value. importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + FONT_SIZE + " = '" + fontSize + "'"); // Upgrade from schema version 3. @@ -411,7 +417,7 @@ public class ImportExportDatabaseHelper { boolean hideAppBar = sharedPreferences.getBoolean(HIDE_APP_BAR, true); boolean scrollAppBar = sharedPreferences.getBoolean(SCROLL_APP_BAR, true); - // Populate the database with the current values. + // Populate the preferences table with the current app bar values. if (hideAppBar) { importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + HIDE_APP_BAR + " = " + 1); } else { @@ -432,7 +438,7 @@ public class ImportExportDatabaseHelper { // Get the current open intents in new tab preference. boolean openIntentsInNewTab = sharedPreferences.getBoolean(OPEN_INTENTS_IN_NEW_TAB, true); - // Populate the database with the current value. + // Populate the preferences table with the current open intents value. if (openIntentsInNewTab) { importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + OPEN_INTENTS_IN_NEW_TAB + " = " + 1); } else { @@ -456,28 +462,28 @@ public class ImportExportDatabaseHelper { boolean twitterAmpRedirects = sharedPreferences.getBoolean(TWITTER_AMP_REDIRECTS, true); boolean wideViewport = sharedPreferences.getBoolean(WIDE_VIEWPORT, true); - // Populate the database with the current Google Analytics value. + // Populate the preferences with the current Google Analytics value. if (googleAnalytics) { importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + GOOGLE_ANALYTICS + " = " + 1); } else { importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + GOOGLE_ANALYTICS + " = " + 0); } - // Populate the database with the current Facebook Click IDs value. + // Populate the preferences with the current Facebook Click IDs value. if (facebookClickIds) { importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + FACEBOOK_CLICK_IDS + " = " + 1); } else { importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + FACEBOOK_CLICK_IDS + " = " + 0); } - // Populate the database with the current Twitter AMP redirects value. + // Populate the preferences table with the current Twitter AMP redirects value. if (twitterAmpRedirects) { importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + TWITTER_AMP_REDIRECTS + " = " + 1); } else { importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + TWITTER_AMP_REDIRECTS + " = " + 0); } - // Populate the database with the current wide viewport value. + // Populate the preferences table with the current wide viewport value. if (wideViewport) { importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + WIDE_VIEWPORT + " = " + 1); } else { @@ -495,7 +501,7 @@ public class ImportExportDatabaseHelper { // Get the current preference values. boolean ultraList = sharedPreferences.getBoolean(ULTRALIST, true); - // Populate the tables with the current UltraList value. + // Populate the preferences tables with the current UltraList value. if (ultraList) { importDatabase.execSQL("UPDATE " + DomainsDatabaseHelper.DOMAINS_TABLE + " SET " + DomainsDatabaseHelper.ULTRALIST + " = " + 1); importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + ULTRALIST + " = " + 1); @@ -517,13 +523,23 @@ public class ImportExportDatabaseHelper { // SQL escape the proxy custom URL string. proxyCustomUrl = DatabaseUtils.sqlEscapeString(proxyCustomUrl); - // Populate the table with the current proxy values. + // Populate the preferences table with the current proxy values. importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + PROXY + " = '" + proxy + "'"); importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + PROXY_CUSTOM_URL + " = '" + proxyCustomUrl + "'"); // Upgrade from schema version 9. case 9: - // `download_with_external_app` was removed the the Preferences table in schema version 10, but there is no need to make any modifications to the database. + // Add the download location columns to the preferences table. + importDatabase.execSQL("ALTER TABLE " + PREFERENCES_TABLE + " ADD COLUMN " + DOWNLOAD_LOCATION + " TEXT"); + importDatabase.execSQL("ALTER TABLE " + PREFERENCES_TABLE + " ADD COLUMN " + DOWNLOAD_CUSTOM_LOCATION + " TEXT"); + + // Get the current download location values. + String downloadLocation = sharedPreferences.getString(DOWNLOAD_LOCATION, context.getString(R.string.download_location_default_value)); + String downloadCustomLocation = sharedPreferences.getString(DOWNLOAD_CUSTOM_LOCATION, context.getString(R.string.download_custom_location_default_value)); + + // Populate the preferences table with the current download location values. + importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + DOWNLOAD_LOCATION + " = '" + downloadLocation + "'"); + importDatabase.execSQL("UPDATE " + PREFERENCES_TABLE + " SET " + DOWNLOAD_CUSTOM_LOCATION + " = '" + downloadCustomLocation + "'"); } } @@ -672,6 +688,8 @@ public class ImportExportDatabaseHelper { .putBoolean(CLEAR_FORM_DATA, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndex(CLEAR_FORM_DATA)) == 1) .putBoolean(CLEAR_CACHE, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndex(CLEAR_CACHE)) == 1) .putString(HOMEPAGE, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndex(HOMEPAGE))) + .putString(DOWNLOAD_LOCATION, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndex(DOWNLOAD_LOCATION))) + .putString(DOWNLOAD_CUSTOM_LOCATION, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndex(DOWNLOAD_CUSTOM_LOCATION))) .putString(FONT_SIZE, importPreferencesCursor.getString(importPreferencesCursor.getColumnIndex(FONT_SIZE))) .putBoolean(OPEN_INTENTS_IN_NEW_TAB, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndex(OPEN_INTENTS_IN_NEW_TAB)) == 1) .putBoolean(SWIPE_TO_REFRESH, importPreferencesCursor.getInt(importPreferencesCursor.getColumnIndex(SWIPE_TO_REFRESH)) == 1) diff --git a/app/src/main/res/drawable/downloads.xml b/app/src/main/res/drawable/downloads_enabled_dark.xml similarity index 91% rename from app/src/main/res/drawable/downloads.xml rename to app/src/main/res/drawable/downloads_enabled_dark.xml index 4bbd96ee..f3622528 100644 --- a/app/src/main/res/drawable/downloads.xml +++ b/app/src/main/res/drawable/downloads_enabled_dark.xml @@ -8,6 +8,6 @@ \ No newline at end of file diff --git a/app/src/main/res/drawable/downloads_enabled_light.xml b/app/src/main/res/drawable/downloads_enabled_light.xml new file mode 100644 index 00000000..34e0fc7e --- /dev/null +++ b/app/src/main/res/drawable/downloads_enabled_light.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/downloads_ghosted_dark.xml b/app/src/main/res/drawable/downloads_ghosted_dark.xml new file mode 100644 index 00000000..c857a820 --- /dev/null +++ b/app/src/main/res/drawable/downloads_ghosted_dark.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/downloads_ghosted_light.xml b/app/src/main/res/drawable/downloads_ghosted_light.xml new file mode 100644 index 00000000..bfcd415d --- /dev/null +++ b/app/src/main/res/drawable/downloads_ghosted_light.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/full_screen_disabled_dark.xml b/app/src/main/res/drawable/full_screen_disabled_dark.xml index 72379619..f01cb256 100644 --- a/app/src/main/res/drawable/full_screen_disabled_dark.xml +++ b/app/src/main/res/drawable/full_screen_disabled_dark.xml @@ -1,4 +1,4 @@ - + + + + + + + + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 1cb4588b..6c247979 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -193,7 +193,7 @@ Vorheriges Nächstes - + Dateiname Archiv speichern Grafik speichern @@ -533,8 +533,8 @@ Yahoo - JavaScript aktiviert Eigene - Suchmaschinen-URL Eigene URL + Suchmaschinen-URL Proxy Keiner Tor diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 088dd617..e75f0343 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -189,7 +189,7 @@ Anterior Siguiente - + Nombre de archivo Guardar archivo Guardar imagen @@ -530,13 +530,8 @@ Yahoo - Javascript habilitado Personalizado - Ninguno - conectar directamente a Internet. - Tor - conectar a través de socks://localhost:9050. - Tor - conectar a través de http://localhost:8118. - I2P - conectar a través de http://localhost:4444. - URL personalizado de búsqueda URL personalizado - URL personalizada del proxy + URL personalizado de búsqueda Proxy Ninguno Tor @@ -548,7 +543,12 @@ I2P Personalizado + Ninguno - conectar directamente a Internet. + Tor - conectar a través de socks://localhost:9050. + Tor - conectar a través de http://localhost:8118. + I2P - conectar a través de http://localhost:4444. Proxy personalizado + URL personalizada del proxy Pantalla completa Navegación de pantalla completa Doble toque para alternar a modo de navegación de pantalla completa. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 4a227f10..3af69bde 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -189,7 +189,7 @@ Précédent Suivant - + Nom du fichier Enregistrer l\'archive Sauvegarder en tant qu\'image @@ -523,8 +523,8 @@ Yahoo - JavaScript activé Personnalisée - URL de recherche personnalisée URL personnalisée + URL de recherche personnalisée Proxy Aucun Tor diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 45e6df92..a567b71e 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -189,7 +189,7 @@ Precedente Successivo - + Nome File Salva Archivio Salva Immagine @@ -530,8 +530,8 @@ Yahoo - JavaScript abilitato Personalizzata - Ricerca personalizzata URL Personalizzata + Ricerca personalizzata Proxy Nessuno Tor diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index b3aeea43..4c5e3485 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -186,7 +186,7 @@ Предыдущий Следующий - + Имя файла Сохранить архив Сохранить изображение @@ -524,8 +524,8 @@ Yahoo - JavaScript включен Настраиваемый - Настраиваемый URL поиска Настраиваемый URL + Настраиваемый URL поиска Прокси Нет Tor diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index c1ac660a..689cc1ef 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -182,7 +182,7 @@ Önceki Sonraki - + Dosya adı Resmi kaydet Websayfası.png @@ -503,8 +503,8 @@ Yahoo - JavaScript etkin Özel sayfa - Özel sayfa ara Özel sayfa + Özel sayfa ara Tam Ekran Tam ekran modu Tam ekran moduna geçmek için çift dokun. diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 3632b7cc..30cc9844 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -1,7 +1,7 @@ - Favorite Icon URL or Search Terms @@ -196,7 +194,7 @@ Previous Next - + Save Dialog File name Save Archive @@ -581,8 +579,8 @@ https://search.yahoo.com/mobile/s?p= Custom URL - Search custom URL Custom URL + Search custom URL Proxy None Tor @@ -624,6 +622,20 @@ Clears WebView’s cache. General Homepage + Download location + + Auto + App directory + Public directory + Custom + + + Auto + App + Public + Custom + + Download custom location Font size Open intents in new tab Intents are links sent from other apps. @@ -650,6 +662,8 @@ None http://localhost:8118 https://www.startpage.com/ + Auto + 100 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index cd849e2b..2cdc1eec 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -87,10 +87,11 @@ @color/blue_700 @color/blue_900 @color/blue_700 - @drawable/user_agent_light - @drawable/search_enabled_light - @drawable/home_enabled_light + @drawable/downloads_enabled_light @drawable/font_size_light + @drawable/home_enabled_light + @drawable/search_enabled_light + @drawable/user_agent_light @@ -180,14 +181,15 @@ diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index dafe62e6..3234462a 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -1,7 +1,7 @@