Lightning browser with I2P configuration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

534 lines
21 KiB

/*
* Copyright 2014 A.C.R. Development
*/
package org.purplei2p.lightning.settings.fragment;
import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.URLUtil;
import android.widget.EditText;
import java.util.List;
import javax.inject.Inject;
import org.purplei2p.lightning.R;
import org.purplei2p.lightning.BrowserApp;
import org.purplei2p.lightning.constant.Constants;
import org.purplei2p.lightning.dialog.BrowserDialog;
import org.purplei2p.lightning.search.SearchEngineProvider;
import org.purplei2p.lightning.search.engine.BaseSearchEngine;
import org.purplei2p.lightning.search.engine.CustomSearch;
import org.purplei2p.lightning.utils.FileUtils;
import org.purplei2p.lightning.utils.ProxyUtils;
import org.purplei2p.lightning.utils.ThemeUtils;
import org.purplei2p.lightning.utils.Utils;
public class GeneralSettingsFragment extends LightningPreferenceFragment implements Preference.OnPreferenceClickListener, Preference.OnPreferenceChangeListener {
private static final String SETTINGS_PROXY = "proxy";
private static final String SETTINGS_IMAGES = "cb_images";
private static final String SETTINGS_JAVASCRIPT = "cb_javascript";
private static final String SETTINGS_COLORMODE = "cb_colormode";
private static final String SETTINGS_USERAGENT = "agent";
private static final String SETTINGS_DOWNLOAD = "download";
private static final String SETTINGS_HOME = "home";
private static final String SETTINGS_SEARCHENGINE = "search";
private Activity mActivity;
private static final int API = android.os.Build.VERSION.SDK_INT;
private CharSequence[] mProxyChoices;
private Preference proxy, useragent, downloadloc, home, searchengine;
private String mDownloadLocation;
private int mAgentChoice;
private String mHomepage;
@Inject SearchEngineProvider mSearchEngineProvider;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preference_general);
BrowserApp.getAppComponent().inject(this);
mActivity = getActivity();
initPrefs();
}
private void initPrefs() {
proxy = findPreference(SETTINGS_PROXY);
useragent = findPreference(SETTINGS_USERAGENT);
downloadloc = findPreference(SETTINGS_DOWNLOAD);
home = findPreference(SETTINGS_HOME);
searchengine = findPreference(SETTINGS_SEARCHENGINE);
CheckBoxPreference cbImages = (CheckBoxPreference) findPreference(SETTINGS_IMAGES);
CheckBoxPreference cbJsScript = (CheckBoxPreference) findPreference(SETTINGS_JAVASCRIPT);
CheckBoxPreference cbColorMode = (CheckBoxPreference) findPreference(SETTINGS_COLORMODE);
proxy.setOnPreferenceClickListener(this);
useragent.setOnPreferenceClickListener(this);
downloadloc.setOnPreferenceClickListener(this);
home.setOnPreferenceClickListener(this);
searchengine.setOnPreferenceClickListener(this);
cbImages.setOnPreferenceChangeListener(this);
cbJsScript.setOnPreferenceChangeListener(this);
cbColorMode.setOnPreferenceChangeListener(this);
mAgentChoice = mPreferenceManager.getUserAgentChoice();
mHomepage = mPreferenceManager.getHomepage();
mDownloadLocation = mPreferenceManager.getDownloadDirectory();
mProxyChoices = getResources().getStringArray(R.array.proxy_choices_array);
int choice = mPreferenceManager.getProxyChoice();
if (choice == Constants.PROXY_MANUAL) {
proxy.setSummary(mPreferenceManager.getProxyHost() + ':' + mPreferenceManager.getProxyPort());
} else {
proxy.setSummary(mProxyChoices[choice]);
}
BaseSearchEngine currentSearchEngine = mSearchEngineProvider.getCurrentSearchEngine();
setSearchEngineSummary(currentSearchEngine);
downloadloc.setSummary(mDownloadLocation);
if (mHomepage.contains(Constants.SCHEME_HOMEPAGE)) {
home.setSummary(getResources().getString(R.string.action_homepage));
} else if (mHomepage.contains(Constants.SCHEME_BLANK)) {
home.setSummary(getResources().getString(R.string.action_blank));
} else if (mHomepage.contains(Constants.SCHEME_BOOKMARKS)) {
home.setSummary(getResources().getString(R.string.action_bookmarks));
} else {
home.setSummary(mHomepage);
}
switch (mAgentChoice) {
case 1:
useragent.setSummary(getResources().getString(R.string.agent_default));
break;
case 2:
useragent.setSummary(getResources().getString(R.string.agent_desktop));
break;
case 3:
useragent.setSummary(getResources().getString(R.string.agent_mobile));
break;
case 4:
useragent.setSummary(getResources().getString(R.string.agent_custom));
}
boolean imagesBool = mPreferenceManager.getBlockImagesEnabled();
boolean enableJSBool = mPreferenceManager.getJavaScriptEnabled();
cbImages.setChecked(imagesBool);
cbJsScript.setChecked(enableJSBool);
cbColorMode.setChecked(mPreferenceManager.getColorModeEnabled());
}
private void showUrlPicker(@NonNull final CustomSearch customSearch) {
BrowserDialog.showEditText(mActivity,
R.string.search_engine_custom,
R.string.search_engine_custom,
mPreferenceManager.getSearchUrl(),
R.string.action_ok,
new BrowserDialog.EditorListener() {
@Override
public void onClick(String text) {
mPreferenceManager.setSearchUrl(text);
setSearchEngineSummary(customSearch);
}
});
}
private void proxyChoicePicker() {
AlertDialog.Builder picker = new AlertDialog.Builder(mActivity);
picker.setTitle(R.string.http_proxy);
picker.setSingleChoiceItems(mProxyChoices, mPreferenceManager.getProxyChoice(),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
setProxyChoice(which);
}
});
picker.setPositiveButton(R.string.action_ok, null);
Dialog dialog = picker.show();
BrowserDialog.setDialogSize(mActivity, dialog);
}
private void setProxyChoice(@Constants.Proxy int choice) {
switch (choice) {
case Constants.PROXY_I2P:
choice = ProxyUtils.setProxyChoice(choice, mActivity);
break;
case Constants.PROXY_MANUAL:
manualProxyPicker();
break;
case Constants.NO_PROXY:
break;
}
mPreferenceManager.setProxyChoice(choice);
if (choice < mProxyChoices.length)
proxy.setSummary(mProxyChoices[choice]);
}
private void manualProxyPicker() {
View v = mActivity.getLayoutInflater().inflate(R.layout.dialog_manual_proxy, null);
final EditText eProxyHost = v.findViewById(R.id.proxyHost);
final EditText eProxyPort = v.findViewById(R.id.proxyPort);
// Limit the number of characters since the port needs to be of type int
// Use input filters to limite the EditText length and determine the max
// length by using length of integer MAX_VALUE
int maxCharacters = Integer.toString(Integer.MAX_VALUE).length();
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(maxCharacters - 1);
eProxyPort.setFilters(filterArray);
eProxyHost.setText(mPreferenceManager.getProxyHost());
eProxyPort.setText(Integer.toString(mPreferenceManager.getProxyPort()));
Dialog dialog = new AlertDialog.Builder(mActivity)
.setTitle(R.string.manual_proxy)
.setView(v)
.setPositiveButton(R.string.action_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
String proxyHost = eProxyHost.getText().toString();
int proxyPort;
try {
// Try/Catch in case the user types an empty string or a number
// larger than max integer
proxyPort = Integer.parseInt(eProxyPort.getText().toString());
} catch (NumberFormatException ignored) {
proxyPort = mPreferenceManager.getProxyPort();
}
mPreferenceManager.setProxyHost(proxyHost);
mPreferenceManager.setProxyPort(proxyPort);
proxy.setSummary(proxyHost + ':' + proxyPort);
}
}).show();
BrowserDialog.setDialogSize(mActivity, dialog);
}
@NonNull
private CharSequence[] convertSearchEngineToString(@NonNull List<BaseSearchEngine> searchEngines) {
CharSequence[] titles = new CharSequence[searchEngines.size()];
for (int n = 0; n < searchEngines.size(); n++) {
titles[n] = getString(searchEngines.get(n).getTitleRes());
}
return titles;
}
private void searchDialog() {
AlertDialog.Builder picker = new AlertDialog.Builder(mActivity);
picker.setTitle(getResources().getString(R.string.title_search_engine));
final List<BaseSearchEngine> searchEngineList = mSearchEngineProvider.getAllSearchEngines();
CharSequence[] chars = convertSearchEngineToString(searchEngineList);
int n = mPreferenceManager.getSearchChoice();
picker.setSingleChoiceItems(chars, n, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
BaseSearchEngine searchEngine = searchEngineList.get(which);
// Store the search engine preference
int preferencesIndex = mSearchEngineProvider.mapSearchEngineToPreferenceIndex(searchEngine);
mPreferenceManager.setSearchChoice(preferencesIndex);
if (searchEngine instanceof CustomSearch) {
// Show the URL picker
showUrlPicker((CustomSearch) searchEngine);
} else {
// Set the new search engine summary
setSearchEngineSummary(searchEngine);
}
}
});
picker.setPositiveButton(R.string.action_ok, null);
Dialog dialog = picker.show();
BrowserDialog.setDialogSize(mActivity, dialog);
}
private void homepageDialog() {
AlertDialog.Builder picker = new AlertDialog.Builder(mActivity);
picker.setTitle(R.string.home);
mHomepage = mPreferenceManager.getHomepage();
int n;
switch (mHomepage) {
case Constants.SCHEME_HOMEPAGE:
n = 0;
break;
case Constants.SCHEME_BLANK:
n = 1;
break;
case Constants.SCHEME_BOOKMARKS:
n = 2;
break;
default:
n = 3;
break;
}
picker.setSingleChoiceItems(R.array.homepage, n,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
mPreferenceManager.setHomepage(Constants.SCHEME_HOMEPAGE);
home.setSummary(getResources().getString(R.string.action_homepage));
break;
case 1:
mPreferenceManager.setHomepage(Constants.SCHEME_BLANK);
home.setSummary(getResources().getString(R.string.action_blank));
break;
case 2:
mPreferenceManager.setHomepage(Constants.SCHEME_BOOKMARKS);
home.setSummary(getResources().getString(R.string.action_bookmarks));
break;
case 3:
homePicker();
break;
}
}
});
picker.setPositiveButton(getResources().getString(R.string.action_ok), null);
Dialog dialog = picker.show();
BrowserDialog.setDialogSize(mActivity, dialog);
}
private void homePicker() {
String currentHomepage;
mHomepage = mPreferenceManager.getHomepage();
if (!URLUtil.isAboutUrl(mHomepage)) {
currentHomepage = mHomepage;
} else {
currentHomepage = "http://i2pd.i2p";
}
BrowserDialog.showEditText(mActivity,
R.string.title_custom_homepage,
R.string.title_custom_homepage,
currentHomepage,
R.string.action_ok,
new BrowserDialog.EditorListener() {
@Override
public void onClick(String text) {
mPreferenceManager.setHomepage(text);
home.setSummary(text);
}
});
}
private void downloadLocDialog() {
AlertDialog.Builder picker = new AlertDialog.Builder(mActivity);
picker.setTitle(getResources().getString(R.string.title_download_location));
mDownloadLocation = mPreferenceManager.getDownloadDirectory();
int n;
if (mDownloadLocation.contains(Environment.DIRECTORY_DOWNLOADS)) {
n = 0;
} else {
n = 1;
}
picker.setSingleChoiceItems(R.array.download_folder, n,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
mPreferenceManager.setDownloadDirectory(FileUtils.DEFAULT_DOWNLOAD_PATH);
downloadloc.setSummary(FileUtils.DEFAULT_DOWNLOAD_PATH);
break;
case 1:
downPicker();
break;
}
}
});
picker.setPositiveButton(getResources().getString(R.string.action_ok), null);
Dialog dialog = picker.show();
BrowserDialog.setDialogSize(mActivity, dialog);
}
private void agentDialog() {
AlertDialog.Builder agentPicker = new AlertDialog.Builder(mActivity);
agentPicker.setTitle(getResources().getString(R.string.title_user_agent));
mAgentChoice = mPreferenceManager.getUserAgentChoice();
agentPicker.setSingleChoiceItems(R.array.user_agent, mAgentChoice - 1,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mPreferenceManager.setUserAgentChoice(which + 1);
switch (which) {
case 0:
useragent.setSummary(getResources().getString(R.string.agent_default));
break;
case 1:
useragent.setSummary(getResources().getString(R.string.agent_desktop));
break;
case 2:
useragent.setSummary(getResources().getString(R.string.agent_mobile));
break;
case 3:
useragent.setSummary(getResources().getString(R.string.agent_custom));
agentPicker();
break;
}
}
});
agentPicker.setPositiveButton(getResources().getString(R.string.action_ok), null);
Dialog dialog = agentPicker.show();
BrowserDialog.setDialogSize(mActivity, dialog);
}
private void agentPicker() {
BrowserDialog.showEditText(mActivity,
R.string.title_user_agent,
R.string.title_user_agent,
mPreferenceManager.getUserAgentString(""),
R.string.action_ok,
new BrowserDialog.EditorListener() {
@Override
public void onClick(String text) {
mPreferenceManager.setUserAgentString(text);
useragent.setSummary(mActivity.getString(R.string.agent_custom));
}
});
}
private void downPicker() {
View dialogView = LayoutInflater.from(mActivity).inflate(R.layout.dialog_edit_text, null);
final EditText getDownload = dialogView.findViewById(R.id.dialog_edit_text);
final int errorColor = ContextCompat.getColor(mActivity, R.color.error_red);
final int regularColor = ThemeUtils.getTextColor(mActivity);
getDownload.setTextColor(regularColor);
getDownload.addTextChangedListener(new DownloadLocationTextWatcher(getDownload, errorColor, regularColor));
getDownload.setText(mPreferenceManager.getDownloadDirectory());
AlertDialog.Builder downLocationPicker = new AlertDialog.Builder(mActivity)
.setTitle(R.string.title_download_location)
.setView(dialogView)
.setPositiveButton(R.string.action_ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String text = getDownload.getText().toString();
text = FileUtils.addNecessarySlashes(text);
mPreferenceManager.setDownloadDirectory(text);
downloadloc.setSummary(text);
}
});
Dialog dialog = downLocationPicker.show();
BrowserDialog.setDialogSize(mActivity, dialog);
}
private void setSearchEngineSummary(BaseSearchEngine baseSearchEngine) {
if (baseSearchEngine instanceof CustomSearch) {
searchengine.setSummary(mPreferenceManager.getSearchUrl());
} else {
searchengine.setSummary(getString(baseSearchEngine.getTitleRes()));
}
}
@Override
public boolean onPreferenceClick(@NonNull Preference preference) {
switch (preference.getKey()) {
case SETTINGS_PROXY:
proxyChoicePicker();
return true;
case SETTINGS_USERAGENT:
agentDialog();
return true;
case SETTINGS_DOWNLOAD:
downloadLocDialog();
return true;
case SETTINGS_HOME:
homepageDialog();
return true;
case SETTINGS_SEARCHENGINE:
searchDialog();
return true;
default:
return false;
}
}
@Override
public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) {
boolean checked = false;
if (newValue instanceof Boolean) {
checked = Boolean.TRUE.equals(newValue);
}
switch (preference.getKey()) {
case SETTINGS_IMAGES:
mPreferenceManager.setBlockImagesEnabled(checked);
return true;
case SETTINGS_JAVASCRIPT:
mPreferenceManager.setJavaScriptEnabled(checked);
return true;
case SETTINGS_COLORMODE:
mPreferenceManager.setColorModeEnabled(checked);
return true;
default:
return false;
}
}
private static class DownloadLocationTextWatcher implements TextWatcher {
@NonNull private final EditText getDownload;
private final int errorColor;
private final int regularColor;
public DownloadLocationTextWatcher(@NonNull EditText getDownload, int errorColor, int regularColor) {
this.getDownload = getDownload;
this.errorColor = errorColor;
this.regularColor = regularColor;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(@NonNull Editable s) {
if (!FileUtils.isWriteAccessAvailable(s.toString())) {
this.getDownload.setTextColor(this.errorColor);
} else {
this.getDownload.setTextColor(this.regularColor);
}
}
}
}