From 07fc1167dc297bbd18c40f33957018b517597422 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Sun, 6 Aug 2017 19:36:29 +0800 Subject: [PATCH] fixed dialog fragment target w/child fragment manager crashes --- .../preference/ColorPickerPreference.java | 168 -------------- .../KeyboardShortcutPreference.java | 219 ------------------ .../preference/MultiSelectListPreference.java | 2 +- .../NotificationTypePreference.java | 3 +- .../preference/SeekBarDialogPreference.java | 2 +- .../SettingsImportExportPreference.java | 2 +- .../preference/ThemeBackgroundPreference.java | 2 +- ...ExtraFeaturesIntroductionDialogFragment.kt | 14 +- .../fragment/SetUserNicknameDialogFragment.kt | 11 +- .../filter/FiltersSubscriptionsFragment.kt | 6 +- .../fragment/statuses/UserTimelineFragment.kt | 2 +- .../preference/ColorPickerPreference.kt | 147 ++++++++++++ .../preference/KeyboardShortcutPreference.kt | 172 ++++++++++++++ .../RandomizeAccountNamePreference.kt | 2 +- .../preference/ThemedEditTextPreference.kt | 3 +- .../org/mariotaku/twidere/util/MenuUtils.kt | 4 +- 16 files changed, 355 insertions(+), 404 deletions(-) delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/preference/ColorPickerPreference.java delete mode 100644 twidere/src/main/java/org/mariotaku/twidere/preference/KeyboardShortcutPreference.java create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/preference/ColorPickerPreference.kt create mode 100644 twidere/src/main/kotlin/org/mariotaku/twidere/preference/KeyboardShortcutPreference.kt diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/ColorPickerPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/ColorPickerPreference.java deleted file mode 100644 index e233179e1..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/ColorPickerPreference.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2014 Mariotaku Lee - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package org.mariotaku.twidere.preference; - -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.res.TypedArray; -import android.graphics.Color; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; -import android.support.v7.app.AlertDialog; -import android.support.v7.preference.DialogPreference; -import android.support.v7.preference.PreferenceDialogFragmentCompat; -import android.support.v7.preference.PreferenceFragmentCompat; -import android.support.v7.preference.PreferenceViewHolder; -import android.util.AttributeSet; -import android.util.Log; -import android.view.View; -import android.widget.ImageView; - -import org.mariotaku.twidere.R; -import org.mariotaku.twidere.extension.DialogExtensionsKt; -import org.mariotaku.twidere.preference.iface.IDialogPreference; -import org.mariotaku.twidere.util.TwidereColorUtils; - -import me.uucky.colorpicker.ColorPickerDialog; - -import static org.mariotaku.twidere.Constants.PRESET_COLORS; -import static org.mariotaku.twidere.TwidereConstants.LOGTAG; - -public class ColorPickerPreference extends DialogPreference implements - IDialogPreference { - - private int mDefaultValue = Color.WHITE; - private boolean mAlphaSliderEnabled = false; - - public ColorPickerPreference(final Context context, final AttributeSet attrs) { - this(context, attrs, R.attr.dialogPreferenceStyle); - } - - public ColorPickerPreference(final Context context, final AttributeSet attrs, final int defStyle) { - super(context, attrs, defStyle); - setWidgetLayoutResource(R.layout.preference_widget_color_picker); - - final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ColorPickerPreferences); - mAlphaSliderEnabled = a.getBoolean(R.styleable.ColorPickerPreferences_alphaSlider, false); - setDefaultValue(a.getColor(R.styleable.ColorPickerPreferences_defaultColor, 0)); - a.recycle(); - } - - @Override - public void setDefaultValue(final Object value) { - if (!(value instanceof Integer)) return; - mDefaultValue = (Integer) value; - } - - @Override - protected void onSetInitialValue(final boolean restoreValue, final Object defaultValue) { - if (isPersistent() && defaultValue instanceof Integer) { - persistInt(restoreValue ? getValue() : (Integer) defaultValue); - } - } - - private int getValue() { - try { - if (isPersistent()) return getPersistedInt(mDefaultValue); - } catch (final ClassCastException e) { - Log.w(LOGTAG, e); - } - return mDefaultValue; - } - - @Override - public void displayDialog(PreferenceFragmentCompat fragment) { - ColorPickerPreferenceDialogFragment df = ColorPickerPreferenceDialogFragment.newInstance(getKey()); - df.setTargetFragment(fragment, 0); - df.show(fragment.getFragmentManager(), getKey()); - } - - @Override - public void onBindViewHolder(PreferenceViewHolder holder) { - super.onBindViewHolder(holder); - final ImageView imageView = (ImageView) holder.findViewById(R.id.color); - imageView.setImageBitmap(TwidereColorUtils.getColorPreviewBitmap(getContext(), getValue(), false)); - } - - public boolean isAlphaSliderEnabled() { - return mAlphaSliderEnabled; - } - - public static final class ColorPickerPreferenceDialogFragment extends PreferenceDialogFragmentCompat - implements DialogInterface.OnShowListener, DialogInterface.OnClickListener { - - private ColorPickerDialog.Controller mController; - - - public static ColorPickerPreferenceDialogFragment newInstance(String key) { - final ColorPickerPreferenceDialogFragment df = new ColorPickerPreferenceDialogFragment(); - final Bundle args = new Bundle(); - args.putString(ARG_KEY, key); - df.setArguments(args); - return df; - } - - @NonNull - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final ColorPickerPreference preference = (ColorPickerPreference) getPreference(); - final Context context = getContext(); - final AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(preference.getDialogTitle()); - builder.setView(R.layout.cp__dialog_color_picker); - builder.setPositiveButton(android.R.string.ok, this); - builder.setNegativeButton(android.R.string.cancel, this); - Dialog dialog = builder.create(); - dialog.setOnShowListener(this); - return dialog; - } - - @Override - public void onDialogClosed(boolean positive) { - final ColorPickerPreference preference = (ColorPickerPreference) getPreference(); - if (mController == null) return; - final int color = mController.getColor(); - if (preference.isPersistent()) { - preference.persistInt(color); - } - preference.callChangeListener(color); - preference.notifyChanged(); - } - - @Override - public void onShow(DialogInterface dialog) { - final ColorPickerPreference preference = (ColorPickerPreference) getPreference(); - final AlertDialog alertDialog = (AlertDialog) dialog; - DialogExtensionsKt.applyTheme(alertDialog); - final View windowView = alertDialog.getWindow().getDecorView(); - if (windowView == null) return; - mController = new ColorPickerDialog.Controller(getContext(), windowView); - mController.setAlphaEnabled(preference.isAlphaSliderEnabled()); - for (int presetColor : PRESET_COLORS) { - mController.addColor(ContextCompat.getColor(getContext(), presetColor)); - } - mController.setInitialColor(preference.getValue()); - } - - } - -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/KeyboardShortcutPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/KeyboardShortcutPreference.java deleted file mode 100644 index c132d050f..000000000 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/KeyboardShortcutPreference.java +++ /dev/null @@ -1,219 +0,0 @@ -package org.mariotaku.twidere.preference; - -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.content.res.TypedArray; -import android.os.Bundle; -import android.support.v7.app.AlertDialog; -import android.support.v7.preference.DialogPreference; -import android.support.v7.preference.PreferenceFragmentCompat; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; -import android.view.KeyEvent; -import android.view.View; -import android.widget.TextView; - -import org.mariotaku.twidere.R; -import org.mariotaku.twidere.fragment.ThemedPreferenceDialogFragmentCompat; -import org.mariotaku.twidere.preference.iface.IDialogPreference; -import org.mariotaku.twidere.util.KeyboardShortcutsHandler; -import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutSpec; -import org.mariotaku.twidere.util.dagger.GeneralComponent; - -import javax.inject.Inject; - -import static org.mariotaku.twidere.TwidereConstants.LOGTAG; - -/** - * Created by mariotaku on 16/3/15. - */ -public class KeyboardShortcutPreference extends DialogPreference implements IDialogPreference { - - private SharedPreferences.OnSharedPreferenceChangeListener mPreferencesChangeListener; - - private String mContextTag, mAction; - - @Inject - KeyboardShortcutsHandler mKeyboardShortcutsHandler; - - public KeyboardShortcutPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(context, attrs); - } - - public KeyboardShortcutPreference(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(context, attrs); - } - - public KeyboardShortcutPreference(Context context, AttributeSet attrs) { - super(context, attrs); - init(context, attrs); - } - - private void init(Context context, AttributeSet set) { - GeneralComponent.Companion.get(context).inject(this); - TypedArray a = context.obtainStyledAttributes(set, R.styleable.KeyboardShortcutPreference); - mContextTag = a.getString(R.styleable.KeyboardShortcutPreference_android_tag); - mAction = a.getString(R.styleable.KeyboardShortcutPreference_android_action); - a.recycle(); - - if (TextUtils.isEmpty(mAction)) { - throw new IllegalArgumentException("android:action required"); - } - setKey(mAction); - - setDialogLayoutResource(R.layout.dialog_keyboard_shortcut_input); - setPersistent(false); - setDialogTitle(KeyboardShortcutsHandler.getActionLabel(context, mAction)); - setTitle(KeyboardShortcutsHandler.getActionLabel(context, mAction)); - mPreferencesChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { - updateSummary(); - } - }; - updateSummary(); - } - - @Override - protected void onPrepareForRemoval() { - mKeyboardShortcutsHandler.unregisterOnSharedPreferenceChangeListener(mPreferencesChangeListener); - super.onPrepareForRemoval(); - } - - @Override - public void onAttached() { - super.onAttached(); - mKeyboardShortcutsHandler.registerOnSharedPreferenceChangeListener(mPreferencesChangeListener); - } - - private void updateSummary() { - final KeyboardShortcutSpec spec = mKeyboardShortcutsHandler.findKey(mAction); - setSummary(spec != null ? spec.toKeyString() : null); - } - - @Override - public void displayDialog(PreferenceFragmentCompat fragment) { - KeyboardShortcutDialogFragment df = KeyboardShortcutDialogFragment.newInstance(mAction); - df.setTargetFragment(fragment, 0); - df.show(fragment.getFragmentManager(), mAction); - } - - public String getAction() { - return mAction; - } - - private String getContextTag() { - return mContextTag; - } - - public KeyboardShortcutsHandler getKeyboardShortcutsHandler() { - return mKeyboardShortcutsHandler; - } - - public static class KeyboardShortcutDialogFragment extends ThemedPreferenceDialogFragmentCompat - implements DialogInterface.OnKeyListener { - - private TextView mKeysLabel; - private TextView mConflictLabel; - - private KeyboardShortcutSpec mKeySpec; - private int mModifierStates; - - public static KeyboardShortcutDialogFragment newInstance(String key) { - final KeyboardShortcutDialogFragment df = new KeyboardShortcutDialogFragment(); - final Bundle args = new Bundle(); - args.putString(ARG_KEY, key); - df.setArguments(args); - return df; - } - - - @Override - public void onDialogClosed(boolean positiveResult) { - - } - - @Override - protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { - builder.setPositiveButton(android.R.string.ok, this); - builder.setNegativeButton(android.R.string.cancel, this); - builder.setNeutralButton(R.string.action_clear, this); - builder.setOnKeyListener(this); - } - - @Override - public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { - if (event.getAction() == KeyEvent.ACTION_DOWN) { - if (KeyEvent.isModifierKey(keyCode)) { - mModifierStates |= KeyboardShortcutsHandler.getMetaStateForKeyCode(keyCode); - } - } else if (event.getAction() != KeyEvent.ACTION_UP) { - return false; - } - if (KeyEvent.isModifierKey(keyCode)) { - mModifierStates &= ~KeyboardShortcutsHandler.getMetaStateForKeyCode(keyCode); - } - final KeyboardShortcutPreference preference = (KeyboardShortcutPreference) getPreference(); - final String action = preference.getAction(); - final String contextTag = preference.getContextTag(); - final KeyboardShortcutsHandler handler = preference.getKeyboardShortcutsHandler(); - - final KeyboardShortcutSpec spec = KeyboardShortcutsHandler.getKeyboardShortcutSpec(contextTag, - keyCode, event, KeyEvent.normalizeMetaState(mModifierStates | event.getMetaState())); - if (spec == null || !spec.isValid()) { - Log.d(LOGTAG, String.format("Invalid key %s", event), new Exception()); - return false; - } - mKeySpec = spec; - mKeysLabel.setText(spec.toKeyString()); - final String oldAction = handler.findAction(spec); - final Context context = getContext(); - if (action.equals(oldAction) || TextUtils.isEmpty(oldAction)) { - mConflictLabel.setVisibility(View.GONE); - if (dialog instanceof AlertDialog) { - ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setText((android.R.string.ok)); - } - } else { - mConflictLabel.setVisibility(View.VISIBLE); - final String label = KeyboardShortcutsHandler.getActionLabel(context, oldAction); - mConflictLabel.setText(context.getString(R.string.conflicts_with_name, label)); - if (dialog instanceof AlertDialog) { - ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setText((R.string.overwrite)); - } - } - return true; - } - - @Override - protected void onBindDialogView(View view) { - super.onBindDialogView(view); - mKeysLabel = (TextView) view.findViewById(R.id.keys_label); - mConflictLabel = (TextView) view.findViewById(R.id.conflict_label); - mConflictLabel.setVisibility(View.GONE); - } - - - @Override - public void onClick(DialogInterface dialog, int which) { - final KeyboardShortcutPreference preference = (KeyboardShortcutPreference) getPreference(); - final String action = preference.getAction(); - final KeyboardShortcutsHandler handler = preference.getKeyboardShortcutsHandler(); - switch (which) { - case DialogInterface.BUTTON_POSITIVE: { - if (mKeySpec == null) return; - handler.register(mKeySpec, action); - break; - } - case DialogInterface.BUTTON_NEUTRAL: { - handler.unregister(action); - break; - } - } - } - - } -} diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/MultiSelectListPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/MultiSelectListPreference.java index b5d972d01..dbcff978b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/MultiSelectListPreference.java +++ b/twidere/src/main/java/org/mariotaku/twidere/preference/MultiSelectListPreference.java @@ -53,7 +53,7 @@ abstract class MultiSelectListPreference extends DialogPreference implements IDi @Override - public void displayDialog(PreferenceFragmentCompat fragment) { + public void displayDialog(@NonNull PreferenceFragmentCompat fragment) { final MultiSelectListDialogFragment df = MultiSelectListDialogFragment.newInstance(getKey()); df.setTargetFragment(fragment, 0); df.show(fragment.getFragmentManager(), getKey()); diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/NotificationTypePreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/NotificationTypePreference.java index 9f5f6dded..139d1203b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/NotificationTypePreference.java +++ b/twidere/src/main/java/org/mariotaku/twidere/preference/NotificationTypePreference.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.res.TypedArray; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v7.app.AlertDialog; import android.support.v7.preference.DialogPreference; import android.support.v7.preference.PreferenceDialogFragmentCompat; @@ -94,7 +95,7 @@ public class NotificationTypePreference extends DialogPreference implements } @Override - public void displayDialog(PreferenceFragmentCompat fragment) { + public void displayDialog(@NonNull PreferenceFragmentCompat fragment) { final NotificationTypeDialogFragment df = NotificationTypeDialogFragment.newInstance(getKey()); df.setTargetFragment(fragment, 0); df.show(fragment.getFragmentManager(), getKey()); diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/SeekBarDialogPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/SeekBarDialogPreference.java index 807e5829d..6bd3ca1ba 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/SeekBarDialogPreference.java +++ b/twidere/src/main/java/org/mariotaku/twidere/preference/SeekBarDialogPreference.java @@ -185,7 +185,7 @@ public class SeekBarDialogPreference extends DialogPreference implements IDialog } @Override - public void displayDialog(PreferenceFragmentCompat fragment) { + public void displayDialog(@NonNull PreferenceFragmentCompat fragment) { SeekBarDialogPreferenceFragment df = SeekBarDialogPreferenceFragment.newInstance(getKey()); df.setTargetFragment(fragment, 0); df.show(fragment.getFragmentManager(), getKey()); diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/SettingsImportExportPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/SettingsImportExportPreference.java index 08de343b1..f23519413 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/SettingsImportExportPreference.java +++ b/twidere/src/main/java/org/mariotaku/twidere/preference/SettingsImportExportPreference.java @@ -50,7 +50,7 @@ public class SettingsImportExportPreference extends DialogPreference implements } @Override - public void displayDialog(PreferenceFragmentCompat fragment) { + public void displayDialog(@NonNull PreferenceFragmentCompat fragment) { ImportExportDialogFragment df = ImportExportDialogFragment.newInstance(getKey()); df.setTargetFragment(fragment, 0); df.show(fragment.getFragmentManager(), getKey()); diff --git a/twidere/src/main/java/org/mariotaku/twidere/preference/ThemeBackgroundPreference.java b/twidere/src/main/java/org/mariotaku/twidere/preference/ThemeBackgroundPreference.java index 7842e9642..c331a1ee5 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/preference/ThemeBackgroundPreference.java +++ b/twidere/src/main/java/org/mariotaku/twidere/preference/ThemeBackgroundPreference.java @@ -98,7 +98,7 @@ public class ThemeBackgroundPreference extends DialogPreference implements Const } @Override - public void displayDialog(PreferenceFragmentCompat fragment) { + public void displayDialog(@NonNull PreferenceFragmentCompat fragment) { InternalDialogFragment df = InternalDialogFragment.newInstance(getKey()); df.setTargetFragment(fragment, 0); df.show(fragment.getFragmentManager(), getKey()); diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ExtraFeaturesIntroductionDialogFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ExtraFeaturesIntroductionDialogFragment.kt index 64a181042..683941f5e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ExtraFeaturesIntroductionDialogFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ExtraFeaturesIntroductionDialogFragment.kt @@ -102,14 +102,24 @@ class ExtraFeaturesIntroductionDialogFragment : BaseDialogFragment() { companion object { const val EXTRA_FEATURE = "feature" const val EXTRA_SOURCE = "source" - fun show(fm: FragmentManager, feature: String, source: String? = null, requestCode: Int = 0): ExtraFeaturesIntroductionDialogFragment { + + const val FRAGMENT_TAG = "extra_features_introduction" + + fun create(feature: String, source: String? = null, requestCode: Int = 0): + ExtraFeaturesIntroductionDialogFragment { val df = ExtraFeaturesIntroductionDialogFragment() df.arguments = Bundle { this[EXTRA_FEATURE] = feature this[EXTRA_SOURCE] = source this[EXTRA_REQUEST_CODE] = requestCode } - df.show(fm, "extra_features_introduction") + return df + } + + fun show(fm: FragmentManager, feature: String, source: String? = null, requestCode: Int = 0): + ExtraFeaturesIntroductionDialogFragment { + val df = create(feature, source, requestCode) + df.show(fm, FRAGMENT_TAG) return df } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/SetUserNicknameDialogFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/SetUserNicknameDialogFragment.kt index ccff8b8a5..490ec31e1 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/SetUserNicknameDialogFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/SetUserNicknameDialogFragment.kt @@ -72,15 +72,20 @@ class SetUserNicknameDialogFragment : BaseDialogFragment(), OnClickListener { companion object { - private val FRAGMENT_TAG_SET_USER_NICKNAME = "set_user_nickname" + const val FRAGMENT_TAG = "set_user_nickname" - fun show(fm: FragmentManager, userKey: UserKey, nickname: String?): SetUserNicknameDialogFragment { + fun create(userKey: UserKey, nickname: String?): SetUserNicknameDialogFragment { val f = SetUserNicknameDialogFragment() val args = Bundle() args.putParcelable(EXTRA_USER_KEY, userKey) args.putString(EXTRA_NAME, nickname) f.arguments = args - f.show(fm, FRAGMENT_TAG_SET_USER_NICKNAME) + return f + } + + fun show(fm: FragmentManager, userKey: UserKey, nickname: String?): SetUserNicknameDialogFragment { + val f = create(userKey, nickname) + f.show(fm, FRAGMENT_TAG) return f } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt index 6aa60bc8f..f8f61320a 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt @@ -79,18 +79,20 @@ class FiltersSubscriptionsFragment : BaseFragment(), LoaderManager.LoaderCallbac when (arguments?.getString(EXTRA_ACTION)) { ACTION_ADD_URL_SUBSCRIPTION -> { if (!extraFeaturesService.isEnabled(ExtraFeaturesService.FEATURE_FILTERS_SUBSCRIPTION)) { - val df = ExtraFeaturesIntroductionDialogFragment.show(childFragmentManager, + val df = ExtraFeaturesIntroductionDialogFragment.create( ExtraFeaturesService.FEATURE_FILTERS_SUBSCRIPTION) df.setTargetFragment(this, REQUEST_ADD_URL_SUBSCRIPTION_PURCHASE) + df.show(fragmentManager, ExtraFeaturesIntroductionDialogFragment.FRAGMENT_TAG) } else { showAddUrlSubscription() } } else -> { if (!extraFeaturesService.isEnabled(ExtraFeaturesService.FEATURE_FILTERS_SUBSCRIPTION)) { - val df = ExtraFeaturesIntroductionDialogFragment.show(childFragmentManager, + val df = ExtraFeaturesIntroductionDialogFragment.create( ExtraFeaturesService.FEATURE_FILTERS_SUBSCRIPTION) df.setTargetFragment(this, REQUEST_PURCHASE_EXTRA_FEATURES) + df.show(fragmentManager, ExtraFeaturesIntroductionDialogFragment.FRAGMENT_TAG) } } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/statuses/UserTimelineFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/statuses/UserTimelineFragment.kt index bbb38580b..23b05b45e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/statuses/UserTimelineFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/statuses/UserTimelineFragment.kt @@ -127,7 +127,7 @@ class UserTimelineFragment : ParcelableStatusesFragment() { override fun onFilterClick(holder: TimelineFilterHeaderViewHolder) { val df = UserTimelineFilterDialogFragment() df.setTargetFragment(this, REQUEST_SET_TIMELINE_FILTER) - df.show(childFragmentManager, "set_timeline_filter") + df.show(fragmentManager, "set_timeline_filter") } @Subscribe diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ColorPickerPreference.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ColorPickerPreference.kt new file mode 100644 index 000000000..404792984 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ColorPickerPreference.kt @@ -0,0 +1,147 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2014 Mariotaku Lee + * + * This program 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. + * + * This program 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 this program. If not, see . + */ + +package org.mariotaku.twidere.preference + +import android.app.Dialog +import android.content.Context +import android.content.DialogInterface +import android.graphics.Color +import android.os.Bundle +import android.support.v4.content.ContextCompat +import android.support.v7.app.AlertDialog +import android.support.v7.preference.DialogPreference +import android.support.v7.preference.PreferenceDialogFragmentCompat +import android.support.v7.preference.PreferenceFragmentCompat +import android.support.v7.preference.PreferenceViewHolder +import android.util.AttributeSet +import android.util.Log +import android.widget.ImageView +import me.uucky.colorpicker.ColorPickerDialog +import org.mariotaku.twidere.Constants.PRESET_COLORS +import org.mariotaku.twidere.R +import org.mariotaku.twidere.TwidereConstants.LOGTAG +import org.mariotaku.twidere.extension.applyTheme +import org.mariotaku.twidere.preference.iface.IDialogPreference +import org.mariotaku.twidere.util.TwidereColorUtils + +class ColorPickerPreference(context: Context, attrs: AttributeSet? = null) : + DialogPreference(context, attrs, R.attr.dialogPreferenceStyle), IDialogPreference { + + var defaultValue: Int = Color.WHITE + var isAlphaSliderEnabled: Boolean + + private val value: Int + get() { + try { + if (isPersistent) return getPersistedInt(defaultValue) + } catch (e: ClassCastException) { + Log.w(LOGTAG, e) + } + + return defaultValue + } + + init { + widgetLayoutResource = R.layout.preference_widget_color_picker + + val a = context.obtainStyledAttributes(attrs, R.styleable.ColorPickerPreferences) + isAlphaSliderEnabled = a.getBoolean(R.styleable.ColorPickerPreferences_alphaSlider, false) + setDefaultValue(a.getColor(R.styleable.ColorPickerPreferences_defaultColor, 0)) + a.recycle() + } + + override fun setDefaultValue(value: Any) { + if (value !is Int) return + defaultValue = value + } + + override fun onSetInitialValue(restoreValue: Boolean, defaultValue: Any?) { + if (isPersistent && defaultValue is Int) { + persistInt(if (restoreValue) value else defaultValue) + } + } + + override fun displayDialog(fragment: PreferenceFragmentCompat) { + val df = ColorPickerPreferenceDialogFragment.newInstance(key) + df.setTargetFragment(fragment, 0) + df.show(fragment.fragmentManager, key) + } + + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + val imageView = holder.findViewById(R.id.color) as ImageView + imageView.setImageBitmap(TwidereColorUtils.getColorPreviewBitmap(context, value, false)) + } + + class ColorPickerPreferenceDialogFragment : PreferenceDialogFragmentCompat(), DialogInterface.OnShowListener, DialogInterface.OnClickListener { + + private lateinit var controller: ColorPickerDialog.Controller + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val preference = preference as ColorPickerPreference + val context = context + val builder = AlertDialog.Builder(context) + builder.setTitle(preference.dialogTitle) + builder.setView(R.layout.cp__dialog_color_picker) + builder.setPositiveButton(android.R.string.ok, this) + builder.setNegativeButton(android.R.string.cancel, this) + val dialog = builder.create() + dialog.setOnShowListener(this) + return dialog + } + + override fun onDialogClosed(positive: Boolean) { + val preference = preference as ColorPickerPreference + val color = controller.color + if (preference.isPersistent) { + preference.persistInt(color) + } + preference.callChangeListener(color) + preference.notifyChanged() + } + + override fun onShow(dialog: DialogInterface) { + val preference = preference as ColorPickerPreference + val alertDialog = dialog as AlertDialog + alertDialog.applyTheme() + val windowView = alertDialog.window!!.decorView ?: return + controller = ColorPickerDialog.Controller(context, windowView) + controller.setAlphaEnabled(preference.isAlphaSliderEnabled) + for (presetColor in PRESET_COLORS) { + controller.addColor(ContextCompat.getColor(context, presetColor)) + } + controller.setInitialColor(preference.value) + } + + companion object { + + + fun newInstance(key: String): ColorPickerPreferenceDialogFragment { + val df = ColorPickerPreferenceDialogFragment() + val args = Bundle() + args.putString(PreferenceDialogFragmentCompat.ARG_KEY, key) + df.arguments = args + return df + } + } + + } + +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/KeyboardShortcutPreference.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/KeyboardShortcutPreference.kt new file mode 100644 index 000000000..42935a62d --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/KeyboardShortcutPreference.kt @@ -0,0 +1,172 @@ +package org.mariotaku.twidere.preference + +import android.content.Context +import android.content.DialogInterface +import android.content.SharedPreferences +import android.os.Bundle +import android.support.v7.app.AlertDialog +import android.support.v7.preference.DialogPreference +import android.support.v7.preference.PreferenceDialogFragmentCompat +import android.support.v7.preference.PreferenceFragmentCompat +import android.text.TextUtils +import android.util.AttributeSet +import android.util.Log +import android.view.KeyEvent +import android.view.View +import android.widget.TextView +import org.mariotaku.twidere.R +import org.mariotaku.twidere.TwidereConstants.LOGTAG +import org.mariotaku.twidere.fragment.ThemedPreferenceDialogFragmentCompat +import org.mariotaku.twidere.preference.iface.IDialogPreference +import org.mariotaku.twidere.util.KeyboardShortcutsHandler +import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutSpec +import org.mariotaku.twidere.util.dagger.GeneralComponent +import javax.inject.Inject + +/** + * Created by mariotaku on 16/3/15. + */ +class KeyboardShortcutPreference(context: Context, attrs: AttributeSet? = null) : + DialogPreference(context, attrs), IDialogPreference { + + private val preferencesChangeListener: SharedPreferences.OnSharedPreferenceChangeListener + + val contextTag: String + val action: String + + @Inject + lateinit var keyboardShortcutsHandler: KeyboardShortcutsHandler + + init { + GeneralComponent.get(context).inject(this) + val a = context.obtainStyledAttributes(attrs, R.styleable.KeyboardShortcutPreference) + contextTag = a.getString(R.styleable.KeyboardShortcutPreference_android_tag) + action = a.getString(R.styleable.KeyboardShortcutPreference_android_action) + .takeUnless(String::isNullOrEmpty) ?: throw IllegalArgumentException("android:action required") + a.recycle() + + key = action + + dialogLayoutResource = R.layout.dialog_keyboard_shortcut_input + isPersistent = false + dialogTitle = KeyboardShortcutsHandler.getActionLabel(context, action) + title = KeyboardShortcutsHandler.getActionLabel(context, action) + preferencesChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { preferences, key -> updateSummary() } + updateSummary() + } + + override fun onPrepareForRemoval() { + keyboardShortcutsHandler.unregisterOnSharedPreferenceChangeListener(preferencesChangeListener) + super.onPrepareForRemoval() + } + + override fun onAttached() { + super.onAttached() + keyboardShortcutsHandler.registerOnSharedPreferenceChangeListener(preferencesChangeListener) + } + + private fun updateSummary() { + val spec = keyboardShortcutsHandler.findKey(action) + summary = spec?.toKeyString() + } + + override fun displayDialog(fragment: PreferenceFragmentCompat) { + val df = KeyboardShortcutDialogFragment.newInstance(action) + df.setTargetFragment(fragment, 0) + df.show(fragment.fragmentManager, action) + } + + class KeyboardShortcutDialogFragment : ThemedPreferenceDialogFragmentCompat(), DialogInterface.OnKeyListener { + + private lateinit var keysLabel: TextView + private lateinit var conflictLabel: TextView + + private var keySpec: KeyboardShortcutSpec? = null + private var modifierStates: Int = 0 + + + override fun onDialogClosed(positiveResult: Boolean) { + + } + + override fun onPrepareDialogBuilder(builder: AlertDialog.Builder?) { + builder!!.setPositiveButton(android.R.string.ok, this) + builder.setNegativeButton(android.R.string.cancel, this) + builder.setNeutralButton(R.string.action_clear, this) + builder.setOnKeyListener(this) + } + + override fun onKey(dialog: DialogInterface, keyCode: Int, event: KeyEvent): Boolean { + if (event.action == KeyEvent.ACTION_DOWN) { + if (KeyEvent.isModifierKey(keyCode)) { + modifierStates = modifierStates or KeyboardShortcutsHandler.getMetaStateForKeyCode(keyCode) + } + } else if (event.action != KeyEvent.ACTION_UP) { + return false + } + if (KeyEvent.isModifierKey(keyCode)) { + modifierStates = modifierStates and KeyboardShortcutsHandler.getMetaStateForKeyCode(keyCode).inv() + } + val preference = preference as KeyboardShortcutPreference + val action = preference.action + val contextTag = preference.contextTag + val handler = preference.keyboardShortcutsHandler + + val spec = KeyboardShortcutsHandler.getKeyboardShortcutSpec(contextTag, + keyCode, event, KeyEvent.normalizeMetaState(modifierStates or event.metaState)) + if (spec == null || !spec.isValid) { + Log.d(LOGTAG, String.format("Invalid key %s", event), Exception()) + return false + } + keySpec = spec + keysLabel.text = spec.toKeyString() + val oldAction = handler.findAction(spec) + val context = context + if (action == oldAction || TextUtils.isEmpty(oldAction)) { + conflictLabel.visibility = View.GONE + (dialog as? AlertDialog)?.getButton(DialogInterface.BUTTON_POSITIVE)?.setText(android.R.string.ok) + } else { + conflictLabel.visibility = View.VISIBLE + val label = KeyboardShortcutsHandler.getActionLabel(context, oldAction) + conflictLabel.text = context.getString(R.string.conflicts_with_name, label) + (dialog as? AlertDialog)?.getButton(DialogInterface.BUTTON_POSITIVE)?.setText(R.string.overwrite) + } + return true + } + + override fun onBindDialogView(view: View) { + super.onBindDialogView(view) + keysLabel = view.findViewById(R.id.keys_label) + conflictLabel = view.findViewById(R.id.conflict_label) + conflictLabel.visibility = View.GONE + } + + + override fun onClick(dialog: DialogInterface?, which: Int) { + val preference = preference as KeyboardShortcutPreference + val action = preference.action + val handler = preference.keyboardShortcutsHandler + when (which) { + DialogInterface.BUTTON_POSITIVE -> { + if (keySpec == null) return + handler.register(keySpec, action) + } + DialogInterface.BUTTON_NEUTRAL -> { + handler.unregister(action) + } + } + } + + companion object { + + fun newInstance(key: String): KeyboardShortcutDialogFragment { + val df = KeyboardShortcutDialogFragment() + val args = Bundle() + args.putString(PreferenceDialogFragmentCompat.ARG_KEY, key) + df.arguments = args + return df + } + } + + } +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/RandomizeAccountNamePreference.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/RandomizeAccountNamePreference.kt index 215b25673..564fd3639 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/RandomizeAccountNamePreference.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/RandomizeAccountNamePreference.kt @@ -58,7 +58,7 @@ class RandomizeAccountNamePreference @JvmOverloads constructor( override fun displayDialog(fragment: PreferenceFragmentCompat) { val df = RenameAccountsConfirmDialogFragment.newInstance(key, getPersistedBoolean(false)) df.setTargetFragment(fragment, 0) - df.show(fragment.childFragmentManager, key) + df.show(fragment.fragmentManager, key) } class RenameAccountsConfirmDialogFragment : PreferenceDialogFragmentCompat() { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ThemedEditTextPreference.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ThemedEditTextPreference.kt index 544682caf..1bf5ef0d1 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ThemedEditTextPreference.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ThemedEditTextPreference.kt @@ -30,7 +30,8 @@ import org.mariotaku.twidere.preference.iface.IDialogPreference /** * Created by mariotaku on 16/3/15. */ -class ThemedEditTextPreference(context: Context, attrs: AttributeSet? = null) : EditTextPreference(context, attrs), IDialogPreference { +class ThemedEditTextPreference(context: Context, attrs: AttributeSet? = null) : + EditTextPreference(context, attrs), IDialogPreference { override fun displayDialog(fragment: PreferenceFragmentCompat) { val df = ThemedEditTextPreferenceDialogFragmentCompat.newInstance(key) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/MenuUtils.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/MenuUtils.kt index 9d8d9b20f..bf9622cb4 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/MenuUtils.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/MenuUtils.kt @@ -311,11 +311,11 @@ object MenuUtils { } R.id.set_nickname -> { val nick = colorNameManager.getUserNickname(status.user_key) - val df = SetUserNicknameDialogFragment.show(fm, - status.user_key, nick) + val df = SetUserNicknameDialogFragment.create(status.user_key, nick) if (fragment != null) { df.setTargetFragment(fragment, REQUEST_SET_NICKNAME) } + df.show(fm, SetUserNicknameDialogFragment.FRAGMENT_TAG) } R.id.open_with_account -> { val intent = Intent(INTENT_ACTION_SELECT_ACCOUNT)