package com.ubergeek42.WeechatAndroid;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.preference.ClearCertPreference;
import android.support.v7.preference.DialogPreference;
import android.support.v7.preference.EditTextPreferenceFix;
import android.support.v7.preference.FilePreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.RingtonePreferenceFix;
import android.support.v7.preference.ThemePreference;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.support.v7.preference.FontPreference;
import android.widget.Toast;
import com.ubergeek42.WeechatAndroid.utils.Utils;
import static com.ubergeek42.WeechatAndroid.utils.Constants.*;
public class PreferencesActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
final static private String KEY = "key";
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.preferences);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) actionBar.setDisplayHomeAsUpEnabled(true);
// this is exactly the place for the following statement. why? no idea.
if (savedInstanceState != null)
return;
Fragment p = getSupportFragmentManager().findFragmentByTag(null);
if (p == null) p = new PreferencesFragment();
String key = getIntent().getStringExtra(KEY);
if (key != null) {
Bundle args = new Bundle();
args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, key);
p.setArguments(args);
}
getSupportFragmentManager().beginTransaction()
.add(R.id.preferences, p, null)
.commit();
}
@Override public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat, PreferenceScreen preferenceScreen) {
Intent intent = new Intent(PreferencesActivity.this, PreferencesActivity.class);
intent.putExtra(KEY, preferenceScreen.getKey());
startActivity(intent);
return true;
}
@Override public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
////////////////////////////////////////////////////////////////////////////////////////////////
public static class PreferencesFragment extends PreferenceFragmentCompat implements DialogPreference.TargetFragment, Preference.OnPreferenceChangeListener {
private static final String FRAGMENT_DIALOG_TAG = "android.support.v7.preference.PreferenceFragment.DIALOG";
private String key;
private Preference sslGroup = null;
private Preference sshGroup = null;
private Preference wsPath = null;
@Override public void onDisplayPreferenceDialog(Preference preference) {
final DialogFragment f;
if (preference instanceof FontPreference)
f = FontPreference.FontPreferenceFragment.newInstance(preference.getKey());
else if (preference instanceof ThemePreference)
f = ThemePreference.ThemePreferenceFragment.newInstance(preference.getKey());
else if (preference instanceof FilePreference)
f = FilePreference.FilePreferenceFragment.newInstance(preference.getKey(), PREF_SSH_KEY.equals(preference.getKey()) ? 1 : 2);
else if (preference instanceof EditTextPreferenceFix)
f = EditTextPreferenceFix.EditTextPreferenceFixFragment.newInstance(preference.getKey());
else if (preference instanceof ClearCertPreference)
f = ClearCertPreference.ClearCertPreferenceFragment.newInstance(preference.getKey());
else if (preference instanceof RingtonePreferenceFix) {
Intent intent = ((RingtonePreferenceFix) preference).makeRingtoneRequestIntent();
startActivityForResult(intent, 0);
return;
} else {
super.onDisplayPreferenceDialog(preference);
return;
}
f.setTargetFragment(this, 0);
f.show(getFragmentManager(), FRAGMENT_DIALOG_TAG);
}
// this makes fragment display preferences. key is the key of the preference screen
// that this fragment is supposed to display. the key is set in activity's onCreate
@Override public void onCreatePreferences(Bundle bundle, String key) {
setPreferencesFromResource(R.xml.preferences, this.key = key);
String[] listenTo = {};
if (PREF_CONNECTION_GROUP.equals(key)) {
sslGroup = findPreference(PREF_SSL_GROUP);
sshGroup = findPreference(PREF_SSH_GROUP);
wsPath = findPreference(PREF_WS_PATH);
showHideStuff(getPreferenceScreen().getSharedPreferences().getString(PREF_CONNECTION_TYPE, PREF_CONNECTION_TYPE_D));
listenTo = new String[] {PREF_CONNECTION_TYPE, PREF_HOST, PREF_PORT};
} else if (PREF_SSH_GROUP.equals(key))
listenTo = new String[] {PREF_SSH_HOST, PREF_SSH_PORT};
else if (PREF_PING_GROUP.equals(key))
listenTo = new String[] {PREF_PING_IDLE, PREF_PING_TIMEOUT};
else if (PREF_LOOKFEEL_GROUP.equals(key))
listenTo = new String[] {PREF_TEXT_SIZE, PREF_MAX_WIDTH, PREF_TIMESTAMP_FORMAT};
for (String p : listenTo)
findPreference(p).setOnPreferenceChangeListener(this);
}
// this only sets the title of the action bar
@Override public void onActivityCreated(Bundle savedInstanceState) {
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if (actionBar != null)
actionBar.setTitle((key == null) ? getString(R.string.preferences) : findPreference(key).getTitle());
super.onActivityCreated(savedInstanceState);
}
// this is required for RingtonePreferenceFix, which requires an activity to operate
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case 0: ((RingtonePreferenceFix) findPreference(PREF_NOTIFICATION_SOUND)).onActivityResult(data); break;
case 1: ((FilePreference) findPreference(PREF_SSH_KEY)).onActivityResult(data); break;
case 2: ((FilePreference) findPreference(PREF_SSH_KNOWN_HOSTS)).onActivityResult(data); break;
}
}
}
@Override public boolean onPreferenceChange(Preference preference, Object o) {
String key = preference.getKey();
boolean valid = true;
int toast = -1;
if (Utils.isAnyOf(key, PREF_HOST, PREF_SSH_HOST)) {
valid = !((String) o).contains(" ");
toast = R.string.pref_hostname_invalid;
} else if (Utils.isAnyOf(key, PREF_TEXT_SIZE, PREF_MAX_WIDTH, PREF_PORT, PREF_SSH_PORT, PREF_PING_IDLE, PREF_PING_TIMEOUT)) {
valid = Utils.isAllDigits((String) o);
toast = R.string.pref_number_invalid;
} else if (PREF_TIMESTAMP_FORMAT.equals(key)) {
valid = Utils.isValidTimestampFormat((String) o);
toast = R.string.pref_timestamp_invalid;
} else if (PREF_CONNECTION_TYPE.equals(key))
showHideStuff((String) o);
if (!valid)
Toast.makeText(getContext(), toast, Toast.LENGTH_SHORT).show();
return valid;
}
// this hides and shows stunnel / ssh preference screens
// must not be called when the settings do not exist in the tree
private void showHideStuff(String type) {
if (Utils.isAnyOf(type, PREF_TYPE_SSL, PREF_TYPE_WEBSOCKET_SSL)) getPreferenceScreen().addPreference(sslGroup);
else getPreferenceScreen().removePreference(sslGroup);
if (PREF_TYPE_SSH.equals(type)) getPreferenceScreen().addPreference(sshGroup);
else getPreferenceScreen().removePreference(sshGroup);
if (Utils.isAnyOf(type, PREF_TYPE_WEBSOCKET, PREF_TYPE_WEBSOCKET_SSL)) getPreferenceScreen().addPreference(wsPath);
else getPreferenceScreen().removePreference(wsPath);
}
}
}