package com.dwdesign.tweetings.activity; import static com.dwdesign.tweetings.util.Utils.CUSTOM_TABS_ICON_NAME_MAP; import static com.dwdesign.tweetings.util.Utils.CUSTOM_TABS_TYPE_NAME_MAP; import static com.dwdesign.tweetings.util.Utils.buildArguments; import static com.dwdesign.tweetings.util.Utils.getAccountUsername; import static com.dwdesign.tweetings.util.Utils.getTabTypeName; import static com.dwdesign.tweetings.util.Utils.parseArguments; import static com.dwdesign.tweetings.util.Utils.parseString; import java.util.Arrays; import java.util.List; import java.util.Set; import com.dwdesign.tweetings.Constants; import com.dwdesign.tweetings.R; import com.dwdesign.tweetings.adapter.UserAutoCompleteAdapter; import com.dwdesign.tweetings.model.Account; import com.dwdesign.tweetings.util.ArrayUtils; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceScreen; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AutoCompleteTextView; import android.widget.Toast; @SuppressWarnings("deprecation") public class EditCustomTabActivity extends BasePreferenceActivity { private String mType, mName, mIcon, mText1, mText2; private long mAccountId; private Preference mTabTypePreference, mAccountPreference, mNamePreference, mTabIconPreference; private Text1Preference mText1Preference; private Text2Preference mText2Preference; private boolean mBackPressed = false, mHasUnsavedChanges = false; private final Handler mBackPressedHandler = new BackPressedHandler(this);; private static final int MESSAGE_ID_BACK_TIMEOUT = 0; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Intent intent = getIntent(); final String action = intent.getAction(); final Bundle extras = intent.getExtras(); if (!INTENT_ACTION_NEW_CUSTOM_TAB.equals(action) && !INTENT_ACTION_EDIT_CUSTOM_TAB.equals(action)) { finish(); return; } if (INTENT_ACTION_EDIT_CUSTOM_TAB.equals(action)) { setTitle(R.string.edit_tab); } if (savedInstanceState != null) { mName = savedInstanceState.getString(INTENT_KEY_NAME); mType = savedInstanceState.getString(INTENT_KEY_TYPE); mAccountId = savedInstanceState.getLong(INTENT_KEY_ACCOUNT_ID, -1); mText1 = savedInstanceState.getString(INTENT_KEY_TEXT1); mText2 = savedInstanceState.getString(INTENT_KEY_TEXT2); } else if (extras != null && INTENT_ACTION_EDIT_CUSTOM_TAB.equals(action)) { mType = extras.getString(INTENT_KEY_TYPE); mName = extras.getString(INTENT_KEY_NAME); mIcon = extras.getString(INTENT_KEY_ICON); final Bundle args = parseArguments(extras.getString(INTENT_KEY_ARGUMENTS)); if (args.containsKey(INTENT_KEY_ACCOUNT_ID)) { mAccountId = args.getLong(INTENT_KEY_ACCOUNT_ID, -1); } if (args.containsKey(INTENT_KEY_SCREEN_NAME)) { mText1 = args.getString(INTENT_KEY_SCREEN_NAME); } else if (args.containsKey(INTENT_KEY_QUERY)) { mText1 = args.getString(INTENT_KEY_QUERY); } if (args.containsKey(INTENT_KEY_LIST_NAME)) { mText2 = args.getString(INTENT_KEY_LIST_NAME); } } addPreferencesFromResource(R.xml.edit_tab); getSupportActionBar().setDisplayHomeAsUpEnabled(true); mText1Preference = new Text1Preference(this, R.string.unused); mText2Preference = new Text2Preference(this, R.string.unused); mTabIconPreference = new TabIconPreference(this); mNamePreference = new NamePreference(this); mAccountPreference = new AccountPreference(this); mTabTypePreference = new TabTypePreference(this); final PreferenceScreen screen = (PreferenceScreen) findPreference("edit_tab"); screen.addPreference(mNamePreference); screen.addPreference(mTabIconPreference); screen.addPreference(mTabTypePreference); screen.addPreference(mAccountPreference); screen.addPreference(mText1Preference); screen.addPreference(mText2Preference); } @Override public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.menu_edit_tab, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onKeyUp(final int keyCode, final KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_BACK: { if (!backPressed()) return true; break; } } return super.onKeyUp(keyCode, event); } @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { case MENU_HOME: { if (backPressed()) { finish(); } break; } case MENU_SAVE: { if (mName == null || mType == null) { Toast.makeText(this, R.string.invalid_settings, Toast.LENGTH_SHORT).show(); return false; } if (!AUTHORITY_DIRECT_MESSAGES.equals(mType) && mAccountId <= 0) { Toast.makeText(this, R.string.invalid_settings, Toast.LENGTH_SHORT).show(); return false; } final Bundle args = new Bundle(); args.putString(INTENT_KEY_SCREEN_NAME, mText1); if (AUTHORITY_LIST_TIMELINE.equals(mType) || AUTHORITY_LIST_MEMBERS.equals(mType) || AUTHORITY_LIST_SUBSCRIBERS.equals(mType)) { if (mText1 == null || mText1.length() == 0 || mText2 == null || mText2.length() == 0) { Toast.makeText(this, R.string.invalid_settings, Toast.LENGTH_SHORT).show(); return false; } args.putString(INTENT_KEY_LIST_NAME, mText2); } else if (AUTHORITY_SEARCH_TWEETS.equals(mType) || AUTHORITY_SEARCH_USERS.equals(mType)) { if (mText1 == null || mText1.length() == 0) { Toast.makeText(this, R.string.invalid_settings, Toast.LENGTH_SHORT).show(); return false; } args.remove(INTENT_KEY_SCREEN_NAME); args.putString(INTENT_KEY_QUERY, mText1); } else if (AUTHORITY_SAVED_SEARCHES.equals(mType)) { args.remove(INTENT_KEY_SCREEN_NAME); } args.putLong(INTENT_KEY_ACCOUNT_ID, mAccountId); final Intent intent = new Intent(); final Bundle extras = new Bundle(); extras.putString(INTENT_KEY_ARGUMENTS, buildArguments(args)); extras.putString(INTENT_KEY_NAME, mName); extras.putString(INTENT_KEY_TYPE, mType); extras.putString(INTENT_KEY_ICON, mIcon); intent.putExtras(extras); setResult(RESULT_OK, intent); finish(); break; } } return super.onOptionsItemSelected(item); } @Override protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { switch (requestCode) { case REQUEST_PICK_FILE: { if (resultCode == RESULT_OK) { final Uri uri = data != null ? data.getData() : null; if (uri != null) { mIcon = uri.getPath(); mTabIconPreference.setSummary(R.string.customize); mHasUnsavedChanges = true; } } break; } } super.onActivityResult(requestCode, resultCode, data); } @Override protected void onSaveInstanceState(final Bundle outState) { super.onSaveInstanceState(outState); outState.putString(INTENT_KEY_NAME, mName); outState.putString(INTENT_KEY_TYPE, mType); outState.putLong(INTENT_KEY_ACCOUNT_ID, mAccountId); outState.putString(INTENT_KEY_TEXT1, mText1); outState.putString(INTENT_KEY_TEXT2, mText2); } private boolean backPressed() { if (!mHasUnsavedChanges) return true; mBackPressedHandler.removeMessages(MESSAGE_ID_BACK_TIMEOUT); if (!mBackPressed) { Toast.makeText(this, R.string.unsaved_change_back_pressed, Toast.LENGTH_SHORT).show(); mBackPressed = true; mBackPressedHandler.sendEmptyMessageDelayed(MESSAGE_ID_BACK_TIMEOUT, 2000L); return false; } mBackPressed = false; return true; } private void setPreferencesByType(final String type) { if (type == null || mText1Preference == null || mText2Preference == null) return; mAccountPreference.setEnabled(true); mAccountPreference.setTitle(R.string.account); mText1Preference.setEnabled(true); mText1Preference.setTitle(R.string.screen_name); mText1Preference.setShouldCompleteUserName(true); mText2Preference.setEnabled(false); mText2Preference.setTitle(R.string.unused); if (AUTHORITY_LIST_TIMELINE.equals(type) || AUTHORITY_LIST_MEMBERS.equals(type) || AUTHORITY_LIST_SUBSCRIBERS.equals(type)) { mText2Preference.setEnabled(true); mText2Preference.setTitle(R.string.list_name); } else if (AUTHORITY_SEARCH_TWEETS.equals(type) || AUTHORITY_SEARCH_USERS.equals(type)) { mText1Preference.setTitle(R.string.keywords); mText1Preference.setShouldCompleteUserName(false); } else if (AUTHORITY_SAVED_SEARCHES.equals(type) || AUTHORITY_RETWEETED_TO_ME.equals(type) || AUTHORITY_DIRECT_MESSAGES.equals(type) || AUTHORITY_TRENDS.equals(type) || AUTHORITY_NEARBY.equals(type)) { mText1Preference.setEnabled(false); mText1Preference.setTitle(R.string.unused); mText1Preference.setShouldCompleteUserName(false); } } class AccountPreference extends Preference implements Constants, OnPreferenceClickListener, OnClickListener { private AlertDialog mDialog; private final Account[] mAccounts; private int mSelectedPos = -1; public AccountPreference(final Context context) { super(context); final List<Account> accounts = Account.getAccounts(getContext(), false); mAccounts = accounts.toArray(new Account[accounts.size()]); setTitle(R.string.account); if (mAccountId > 0) { setSummary(getAccountUsername(getContext(), mAccountId)); } setOnPreferenceClickListener(this); } @Override public void onClick(final DialogInterface dialog, final int which) { mAccountId = mAccounts[which].account_id; setSummary(mAccounts[which]); if (mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } mHasUnsavedChanges = true; } @Override public boolean onPreferenceClick(final Preference preference) { if (mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } if (mAccountId > 0) { final int length = mAccounts.length; for (int i = 0; i < length; i++) { if (mAccounts[i].account_id == mAccountId) { mSelectedPos = i; } } } final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle(getTitle()); builder.setSingleChoiceItems(mAccounts, mSelectedPos, this); mDialog = builder.show(); return true; } } abstract class AdditionalPreference extends Preference implements Constants, OnPreferenceClickListener, OnClickListener { private AlertDialog mDialog; private AutoCompleteTextView mEditText; public AdditionalPreference(final Context context, final int title) { super(context); setEnabled(false); setTitle(title); setOnPreferenceClickListener(this); } @Override public void onClick(final DialogInterface dialog, final int which) { switch (which) { case DialogInterface.BUTTON_POSITIVE: { final String text = parseString(mEditText.getText()); onTextSet(text); setSummary(text); break; } case DialogInterface.BUTTON_NEGATIVE: { break; } } } @Override public boolean onPreferenceClick(final Preference preference) { if (mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } final View view = LayoutInflater.from(getContext()).inflate(R.layout.auto_complete_textview_default_style, null); mEditText = (AutoCompleteTextView) view.findViewById(R.id.edit_text); mEditText.setAdapter(shouldCompleteUserName() ? new UserAutoCompleteAdapter(getContext()) : null); mEditText.setText(getTextToSet()); final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle(getTitle()); builder.setView(view); builder.setPositiveButton(android.R.string.ok, this); builder.setNegativeButton(android.R.string.cancel, this); mDialog = builder.show(); return true; } public abstract void onTextSet(String text); public abstract boolean shouldCompleteUserName(); abstract String getTextToSet(); } static class BackPressedHandler extends Handler { private final EditCustomTabActivity mActivity; public BackPressedHandler(final EditCustomTabActivity activity) { mActivity = activity; } @Override public void handleMessage(final Message msg) { mActivity.mBackPressed = false; } } class NamePreference extends Text2Preference { public NamePreference(final Context context) { super(context, R.string.name); setEnabled(true); setSummary(mName); } @Override public String getTextToSet() { return mName; } @Override public void onTextSet(final String text) { mName = text; mHasUnsavedChanges = true; } } class TabIconPreference extends Preference implements Constants, OnPreferenceClickListener, OnClickListener { private AlertDialog mDialog; private final String[] mKeys, mNames; private int mSelectedPos = -1; public TabIconPreference(final Context context) { super(context); final Set<String> keys = CUSTOM_TABS_ICON_NAME_MAP.keySet(); mKeys = keys.toArray(new String[keys.size()]); Arrays.sort(mKeys); final int length = mKeys.length; mNames = new String[length]; for (int i = 0; i < length; i++) { final String key = mKeys[i]; if (ICON_SPECIAL_TYPE_CUSTOMIZE.equals(key)) { mNames[i] = getString(R.string.customize); } else { mNames[i] = key.substring(0, 1).toUpperCase() + key.substring(1, key.length()); } } setTitle(R.string.icon); if (mIcon != null) { if (mIcon.contains("/")) { setSummary(R.string.customize); } else { final int idx = ArrayUtils.indexOf(mKeys, mIcon); if (idx >= 0) { setSummary(mNames[idx]); } } } setOnPreferenceClickListener(this); } @Override public void onClick(final DialogInterface dialog, final int which) { mSelectedPos = which; final String name = mNames[which]; final String key = mKeys[which]; if (ICON_SPECIAL_TYPE_CUSTOMIZE.equals(key)) { mIcon = null; final Intent intent = new Intent(INTENT_ACTION_PICK_FILE); final Bundle extras = new Bundle(); extras.putStringArray(INTENT_KEY_FILE_EXTENSIONS, new String[] { "jpg", "png", "bmp", "gif" }); intent.putExtras(extras); startActivityForResult(intent, REQUEST_PICK_FILE); } else { mIcon = key; mHasUnsavedChanges = true; setSummary(name); } if (mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } } @Override public boolean onPreferenceClick(final Preference preference) { if (mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle(getTitle()); builder.setSingleChoiceItems(mNames, mSelectedPos, this); mDialog = builder.show(); return true; } } class TabTypePreference extends Preference implements Constants, OnPreferenceClickListener, OnClickListener { private AlertDialog mDialog; private final String[] mKeys, mNames; private int mSelectedPos = -1; public TabTypePreference(final Context context) { super(context); final Set<String> keys = CUSTOM_TABS_TYPE_NAME_MAP.keySet(); mKeys = keys.toArray(new String[keys.size()]); Arrays.sort(mKeys); final int length = mKeys.length; mNames = new String[length]; for (int i = 0; i < length; i++) { final String key = mKeys[i]; mNames[i] = getTabTypeName(getContext(), key); } setTitle(R.string.tab_type); if (mType != null) { setSummary(getTabTypeName(getContext(), mType)); setPreferencesByType(mType); } setOnPreferenceClickListener(this); } @Override public void onClick(final DialogInterface dialog, final int which) { mType = mKeys[which]; setPreferencesByType(mType); final String name = mNames[which]; setSummary(name); if (mName == null || mName.length() == 0) { mName = name; mNamePreference.setSummary(name); } mHasUnsavedChanges = true; if (mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } } @Override public boolean onPreferenceClick(final Preference preference) { if (mDialog != null && mDialog.isShowing()) { mDialog.dismiss(); } final int length = mKeys.length; for (int i = 0; i < length; i++) { final String key = mKeys[i]; if (key.equals(mType)) { mSelectedPos = i; } } final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle(getTitle()); builder.setSingleChoiceItems(mNames, mSelectedPos, this); mDialog = builder.show(); return true; } } class Text1Preference extends AdditionalPreference { boolean mShouldCompleteUserName; public Text1Preference(final Context context, final int title) { super(context, title); setSummary(mText1); } @Override public String getTextToSet() { return mText1; } @Override public void onTextSet(final String text) { mText1 = text; mHasUnsavedChanges = true; } public void setShouldCompleteUserName(final boolean complete) { mShouldCompleteUserName = complete; } @Override public boolean shouldCompleteUserName() { return mShouldCompleteUserName; } } class Text2Preference extends AdditionalPreference { public Text2Preference(final Context context, final int title) { super(context, title); setSummary(mText2); } @Override public String getTextToSet() { return mText2; } @Override public void onTextSet(final String text) { mText2 = text; mHasUnsavedChanges = true; } @Override public final boolean shouldCompleteUserName() { return false; } } }