aboutsummaryrefslogtreecommitdiff
path: root/WordPress/src/main/java/org/wordpress/android/ui/prefs/SiteSettingsFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'WordPress/src/main/java/org/wordpress/android/ui/prefs/SiteSettingsFragment.java')
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/prefs/SiteSettingsFragment.java1392
1 files changed, 1392 insertions, 0 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/SiteSettingsFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/prefs/SiteSettingsFragment.java
new file mode 100644
index 000000000..13fc10c5b
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/SiteSettingsFragment.java
@@ -0,0 +1,1392 @@
+package org.wordpress.android.ui.prefs;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.support.annotation.NonNull;
+import android.support.design.widget.Snackbar;
+import android.support.v7.widget.LinearLayoutManager;
+import android.text.TextUtils;
+import android.util.Pair;
+import android.util.SparseBooleanArray;
+import android.view.ActionMode;
+import android.view.ContextThemeWrapper;
+import android.view.HapticFeedbackConstants;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.NumberPicker.Formatter;
+import android.widget.TextView;
+
+import com.android.volley.VolleyError;
+import com.wordpress.rest.RestRequest;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.wordpress.android.R;
+import org.wordpress.android.WordPress;
+import org.wordpress.android.analytics.AnalyticsTracker;
+import org.wordpress.android.models.AccountHelper;
+import org.wordpress.android.models.Blog;
+import org.wordpress.android.ui.WPWebViewActivity;
+import org.wordpress.android.ui.stats.StatsWidgetProvider;
+import org.wordpress.android.ui.stats.datasets.StatsTable;
+import org.wordpress.android.util.AnalyticsUtils;
+import org.wordpress.android.util.AppLog;
+import org.wordpress.android.util.CoreEvents;
+import org.wordpress.android.util.HelpshiftHelper;
+import org.wordpress.android.util.NetworkUtils;
+import org.wordpress.android.util.StringUtils;
+import org.wordpress.android.util.ToastUtils;
+import org.wordpress.android.util.UrlUtils;
+import org.wordpress.android.util.WPActivityUtils;
+import org.wordpress.android.util.WPPrefUtils;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import de.greenrobot.event.EventBus;
+
+/**
+ * Allows interfacing with WordPress site settings. Works with WP.com and WP.org v4.5+ (pending).
+ *
+ * Settings are synced automatically when local changes are made.
+ */
+
+public class SiteSettingsFragment extends PreferenceFragment
+ implements Preference.OnPreferenceChangeListener,
+ Preference.OnPreferenceClickListener,
+ AdapterView.OnItemLongClickListener,
+ ViewGroup.OnHierarchyChangeListener,
+ Dialog.OnDismissListener,
+ SiteSettingsInterface.SiteSettingsListener {
+
+ /**
+ * Use this argument to pass the {@link Integer} local blog ID to this fragment.
+ */
+ public static final String ARG_LOCAL_BLOG_ID = "local_blog_id";
+
+ /**
+ * When the user removes a site (by selecting Delete Site) the parent {@link Activity} result
+ * is set to this value and {@link Activity#finish()} is invoked.
+ */
+ public static final int RESULT_BLOG_REMOVED = Activity.RESULT_FIRST_USER;
+
+ /**
+ * Provides the regex to identify domain HTTP(S) protocol and/or 'www' sub-domain.
+ *
+ * Used to format user-facing {@link String}'s in certain preferences.
+ */
+ public static final String ADDRESS_FORMAT_REGEX = "^(https?://(w{3})?|www\\.)";
+
+ /**
+ * url that points to wordpress.com purchases
+ */
+ public static final String WORDPRESS_PURCHASES_URL = "https://wordpress.com/purchases";
+
+ /**
+ * Used to move the Uncategorized category to the beginning of the category list.
+ */
+ private static final int UNCATEGORIZED_CATEGORY_ID = 1;
+
+ /**
+ * Request code used when creating the {@link RelatedPostsDialog}.
+ */
+ private static final int RELATED_POSTS_REQUEST_CODE = 1;
+ private static final int THREADING_REQUEST_CODE = 2;
+ private static final int PAGING_REQUEST_CODE = 3;
+ private static final int CLOSE_AFTER_REQUEST_CODE = 4;
+ private static final int MULTIPLE_LINKS_REQUEST_CODE = 5;
+ private static final int DELETE_SITE_REQUEST_CODE = 6;
+ private static final String DELETE_SITE_TAG = "delete-site";
+ private static final String PURCHASE_ORIGINAL_RESPONSE_KEY = "originalResponse";
+ private static final String PURCHASE_ACTIVE_KEY = "active";
+ private static final String ANALYTICS_ERROR_PROPERTY_KEY = "error";
+
+ private static final long FETCH_DELAY = 1000;
+
+ // Reference to blog obtained from passed ID (ARG_LOCAL_BLOG_ID)
+ private Blog mBlog;
+
+ // Can interface with WP.com or WP.org
+ private SiteSettingsInterface mSiteSettings;
+
+ // Reference to the list of items being edited in the current list editor
+ private List<String> mEditingList;
+
+ // Used to ensure that settings are only fetched once throughout the lifecycle of the fragment
+ private boolean mShouldFetch;
+
+ // General settings
+ private EditTextPreference mTitlePref;
+ private EditTextPreference mTaglinePref;
+ private EditTextPreference mAddressPref;
+ private DetailListPreference mPrivacyPref;
+ private DetailListPreference mLanguagePref;
+
+ // Account settings (NOTE: only for WP.org)
+ private EditTextPreference mUsernamePref;
+ private EditTextPreference mPasswordPref;
+
+ // Writing settings
+ private WPSwitchPreference mLocationPref;
+ private DetailListPreference mCategoryPref;
+ private DetailListPreference mFormatPref;
+ private Preference mRelatedPostsPref;
+
+ // Discussion settings preview
+ private WPSwitchPreference mAllowCommentsPref;
+ private WPSwitchPreference mSendPingbacksPref;
+ private WPSwitchPreference mReceivePingbacksPref;
+
+ // Discussion settings -> Defaults for New Posts
+ private WPSwitchPreference mAllowCommentsNested;
+ private WPSwitchPreference mSendPingbacksNested;
+ private WPSwitchPreference mReceivePingbacksNested;
+ private PreferenceScreen mMorePreference;
+
+ // Discussion settings -> Comments
+ private WPSwitchPreference mIdentityRequiredPreference;
+ private WPSwitchPreference mUserAccountRequiredPref;
+ private Preference mCloseAfterPref;
+ private DetailListPreference mSortByPref;
+ private Preference mThreadingPref;
+ private Preference mPagingPref;
+ private DetailListPreference mWhitelistPref;
+ private Preference mMultipleLinksPref;
+ private Preference mModerationHoldPref;
+ private Preference mBlacklistPref;
+
+ // This Device settings
+ private DetailListPreference mImageWidthPref;
+ private WPSwitchPreference mUploadAndLinkPref;
+
+ // Advanced settings
+ private Preference mStartOverPref;
+ private Preference mExportSitePref;
+ private Preference mDeleteSitePref;
+
+ private boolean mEditingEnabled = true;
+
+ // Reference to the state of the fragment
+ private boolean mIsFragmentPaused = false;
+
+ // Hold for Moderation and Blacklist settings
+ private Dialog mDialog;
+ private ActionMode mActionMode;
+ private MultiSelectRecyclerViewAdapter mAdapter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Activity activity = getActivity();
+
+ // make sure we have local site data and a network connection, otherwise finish activity
+ mBlog = WordPress.getBlog(getArguments().getInt(ARG_LOCAL_BLOG_ID, -1));
+ if (mBlog == null || !NetworkUtils.checkConnection(activity)) {
+ getActivity().finish();
+ return;
+ }
+
+ // track successful settings screen access
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_ACCESSED);
+
+ // setup state to fetch remote settings
+ mShouldFetch = true;
+
+ // initialize the appropriate settings interface (WP.com or WP.org)
+ mSiteSettings = SiteSettingsInterface.getInterface(activity, mBlog, this);
+
+ setRetainInstance(true);
+ addPreferencesFromResource(R.xml.site_settings);
+
+ // toggle which preferences are shown and set references
+ initPreferences();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ WordPress.wpDB.saveBlog(mBlog);
+ mIsFragmentPaused = true;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ // Fragment#onResume() is called after FragmentActivity#onPostResume().
+ // The latter is the most secure way of keeping track of the activity's state, and avoid calls to commitAllowingStateLoss.
+ mIsFragmentPaused = false;
+
+ // always load cached settings
+ mSiteSettings.init(false);
+
+ if (mShouldFetch) {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ // initialize settings with locally cached values, fetch remote on first pass
+ mSiteSettings.init(true);
+ }
+ }, FETCH_DELAY);
+ // stop future calls from fetching remote settings
+ mShouldFetch = false;
+ }
+ }
+
+ @Override
+ public void onDestroyView() {
+ removeMoreScreenToolbar();
+ super.onDestroyView();
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (data != null) {
+ switch (requestCode) {
+ case RELATED_POSTS_REQUEST_CODE:
+ // data is null if user cancelled editing Related Posts settings
+ mSiteSettings.setShowRelatedPosts(data.getBooleanExtra(
+ RelatedPostsDialog.SHOW_RELATED_POSTS_KEY, false));
+ mSiteSettings.setShowRelatedPostHeader(data.getBooleanExtra(
+ RelatedPostsDialog.SHOW_HEADER_KEY, false));
+ mSiteSettings.setShowRelatedPostImages(data.getBooleanExtra(
+ RelatedPostsDialog.SHOW_IMAGES_KEY, false));
+ onPreferenceChange(mRelatedPostsPref, mSiteSettings.getRelatedPostsDescription());
+ break;
+ case THREADING_REQUEST_CODE:
+ int levels = data.getIntExtra(NumberPickerDialog.CUR_VALUE_KEY, -1);
+ mSiteSettings.setShouldThreadComments(levels > 1 && data.getBooleanExtra
+ (NumberPickerDialog.SWITCH_ENABLED_KEY, false));
+ onPreferenceChange(mThreadingPref, levels);
+ break;
+ case PAGING_REQUEST_CODE:
+ mSiteSettings.setShouldPageComments(data.getBooleanExtra
+ (NumberPickerDialog.SWITCH_ENABLED_KEY, false));
+ onPreferenceChange(mPagingPref, data.getIntExtra(
+ NumberPickerDialog.CUR_VALUE_KEY, -1));
+ break;
+ case CLOSE_AFTER_REQUEST_CODE:
+ mSiteSettings.setShouldCloseAfter(data.getBooleanExtra
+ (NumberPickerDialog.SWITCH_ENABLED_KEY, false));
+ onPreferenceChange(mCloseAfterPref, data.getIntExtra(
+ NumberPickerDialog.CUR_VALUE_KEY, -1));
+ break;
+ case MULTIPLE_LINKS_REQUEST_CODE:
+ int numLinks = data.getIntExtra(NumberPickerDialog.CUR_VALUE_KEY, -1);
+ if (numLinks < 0 || numLinks == mSiteSettings.getMultipleLinks()) return;
+ onPreferenceChange(mMultipleLinksPref, numLinks);
+ break;
+ }
+ } else {
+ switch (requestCode) {
+ case DELETE_SITE_REQUEST_CODE:
+ deleteSite();
+ break;
+ }
+ }
+
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ ViewGroup container,
+ Bundle savedInstanceState) {
+ // use a wrapper to apply the Calypso theme
+ Context themer = new ContextThemeWrapper(getActivity(), R.style.Calypso_SiteSettingsTheme);
+ LayoutInflater localInflater = inflater.cloneInContext(themer);
+ View view = super.onCreateView(localInflater, container, savedInstanceState);
+
+ if (view != null) {
+ setupPreferenceList((ListView) view.findViewById(android.R.id.list), getResources());
+ }
+
+ return view;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ removeMoreScreenToolbar();
+ super.onSaveInstanceState(outState);
+ setupMorePreferenceScreen();
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ if (savedInstanceState != null) setupMorePreferenceScreen();
+ }
+
+ @Override
+ public void onChildViewAdded(View parent, View child) {
+ if (child.getId() == android.R.id.title && child instanceof TextView) {
+ // style preference category title views
+ TextView title = (TextView) child;
+ WPPrefUtils.layoutAsBody2(title);
+ } else {
+ // style preference title views
+ TextView title = (TextView) child.findViewById(android.R.id.title);
+ if (title != null) WPPrefUtils.layoutAsSubhead(title);
+ }
+ }
+
+ @Override
+ public void onChildViewRemoved(View parent, View child) {
+ // NOP
+ }
+
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
+ super.onPreferenceTreeClick(screen, preference);
+
+ // More preference selected, style the Discussion screen
+ if (preference == mMorePreference) {
+ // track user accessing the full Discussion settings screen
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_ACCESSED_MORE_SETTINGS);
+
+ return setupMorePreferenceScreen();
+ } else if (preference == findPreference(getString(R.string.pref_key_site_start_over_screen))) {
+ Dialog dialog = ((PreferenceScreen) preference).getDialog();
+ if (dialog == null) return false;
+
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_START_OVER_ACCESSED);
+
+ setupPreferenceList((ListView) dialog.findViewById(android.R.id.list), getResources());
+ String title = getString(R.string.start_over);
+ WPActivityUtils.addToolbarToDialog(this, dialog, title);
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ if (preference == mRelatedPostsPref) {
+ showRelatedPostsDialog();
+ } else if (preference == mMultipleLinksPref) {
+ showMultipleLinksDialog();
+ } else if (preference == mModerationHoldPref) {
+ mEditingList = mSiteSettings.getModerationKeys();
+ showListEditorDialog(R.string.site_settings_moderation_hold_title,
+ R.string.site_settings_hold_for_moderation_description);
+ } else if (preference == mBlacklistPref) {
+ mEditingList = mSiteSettings.getBlacklistKeys();
+ showListEditorDialog(R.string.site_settings_blacklist_title,
+ R.string.site_settings_blacklist_description);
+ } else if (preference == mStartOverPref) {
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_START_OVER_CONTACT_SUPPORT_CLICKED);
+ HelpshiftHelper.getInstance().showConversation(getActivity(), HelpshiftHelper.Tag.ORIGIN_START_OVER);
+ } else if (preference == mCloseAfterPref) {
+ showCloseAfterDialog();
+ } else if (preference == mPagingPref) {
+ showPagingDialog();
+ } else if (preference == mThreadingPref) {
+ showThreadingDialog();
+ } else if (preference == mCategoryPref || preference == mFormatPref) {
+ return !shouldShowListPreference((DetailListPreference) preference);
+ } else if (preference == mExportSitePref) {
+ showExportContentDialog();
+ } else if (preference == mDeleteSitePref) {
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_ACCESSED);
+ requestPurchasesForDeletionCheck();
+ } else {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (newValue == null || !mEditingEnabled) return false;
+
+ if (preference == mTitlePref) {
+ mSiteSettings.setTitle(newValue.toString());
+ changeEditTextPreferenceValue(mTitlePref, mSiteSettings.getTitle());
+ } else if (preference == mTaglinePref) {
+ mSiteSettings.setTagline(newValue.toString());
+ changeEditTextPreferenceValue(mTaglinePref, mSiteSettings.getTagline());
+ } else if (preference == mAddressPref) {
+ mSiteSettings.setAddress(newValue.toString());
+ changeEditTextPreferenceValue(mAddressPref, mSiteSettings.getAddress());
+ } else if (preference == mLanguagePref) {
+ if (!mSiteSettings.setLanguageCode(newValue.toString())) {
+ AppLog.w(AppLog.T.SETTINGS, "Unknown language code " + newValue.toString() + " selected in Site Settings.");
+ ToastUtils.showToast(getActivity(), R.string.site_settings_unknown_language_code_error);
+ }
+ changeLanguageValue(mSiteSettings.getLanguageCode());
+ } else if (preference == mPrivacyPref) {
+ mSiteSettings.setPrivacy(Integer.parseInt(newValue.toString()));
+ setDetailListPreferenceValue(mPrivacyPref,
+ String.valueOf(mSiteSettings.getPrivacy()),
+ mSiteSettings.getPrivacyDescription());
+ } else if (preference == mAllowCommentsPref || preference == mAllowCommentsNested) {
+ setAllowComments((Boolean) newValue);
+ } else if (preference == mSendPingbacksPref || preference == mSendPingbacksNested) {
+ setSendPingbacks((Boolean) newValue);
+ } else if (preference == mReceivePingbacksPref || preference == mReceivePingbacksNested) {
+ setReceivePingbacks((Boolean) newValue);
+ } else if (preference == mCloseAfterPref) {
+ mSiteSettings.setCloseAfter(Integer.parseInt(newValue.toString()));
+ mCloseAfterPref.setSummary(mSiteSettings.getCloseAfterDescription());
+ } else if (preference == mSortByPref) {
+ mSiteSettings.setCommentSorting(Integer.parseInt(newValue.toString()));
+ setDetailListPreferenceValue(mSortByPref,
+ newValue.toString(),
+ mSiteSettings.getSortingDescription());
+ } else if (preference == mThreadingPref) {
+ mSiteSettings.setThreadingLevels(Integer.parseInt(newValue.toString()));
+ mThreadingPref.setSummary(mSiteSettings.getThreadingDescription());
+ } else if (preference == mPagingPref) {
+ mSiteSettings.setPagingCount(Integer.parseInt(newValue.toString()));
+ mPagingPref.setSummary(mSiteSettings.getPagingDescription());
+ } else if (preference == mIdentityRequiredPreference) {
+ mSiteSettings.setIdentityRequired((Boolean) newValue);
+ } else if (preference == mUserAccountRequiredPref) {
+ mSiteSettings.setUserAccountRequired((Boolean) newValue);
+ } else if (preference == mWhitelistPref) {
+ updateWhitelistSettings(Integer.parseInt(newValue.toString()));
+ } else if (preference == mMultipleLinksPref) {
+ mSiteSettings.setMultipleLinks(Integer.parseInt(newValue.toString()));
+ String s = StringUtils.getQuantityString(getActivity(), R.string.site_settings_multiple_links_summary_zero,
+ R.string.site_settings_multiple_links_summary_one,
+ R.string.site_settings_multiple_links_summary_other, mSiteSettings.getMultipleLinks());
+ mMultipleLinksPref.setSummary(s);
+ } else if (preference == mUsernamePref) {
+ mSiteSettings.setUsername(newValue.toString());
+ changeEditTextPreferenceValue(mUsernamePref, mSiteSettings.getUsername());
+ } else if (preference == mPasswordPref) {
+ mSiteSettings.setPassword(newValue.toString());
+ changeEditTextPreferenceValue(mPasswordPref, mSiteSettings.getPassword());
+ } else if (preference == mLocationPref) {
+ mSiteSettings.setLocation((Boolean) newValue);
+ } else if (preference == mCategoryPref) {
+ mSiteSettings.setDefaultCategory(Integer.parseInt(newValue.toString()));
+ setDetailListPreferenceValue(mCategoryPref,
+ newValue.toString(),
+ mSiteSettings.getDefaultCategoryForDisplay());
+ } else if (preference == mFormatPref) {
+ mSiteSettings.setDefaultFormat(newValue.toString());
+ setDetailListPreferenceValue(mFormatPref,
+ newValue.toString(),
+ mSiteSettings.getDefaultPostFormatDisplay());
+ } else if (preference == mImageWidthPref) {
+ mBlog.setMaxImageWidth(newValue.toString());
+ setDetailListPreferenceValue(mImageWidthPref,
+ mBlog.getMaxImageWidth(),
+ mBlog.getMaxImageWidth());
+ } else if (preference == mUploadAndLinkPref) {
+ mBlog.setFullSizeImage(Boolean.valueOf(newValue.toString()));
+ } else if (preference == mRelatedPostsPref) {
+ mRelatedPostsPref.setSummary(newValue.toString());
+ } else if (preference == mModerationHoldPref) {
+ mModerationHoldPref.setSummary(mSiteSettings.getModerationHoldDescription());
+ } else if (preference == mBlacklistPref) {
+ mBlacklistPref.setSummary(mSiteSettings.getBlacklistDescription());
+ } else {
+ return false;
+ }
+
+ mSiteSettings.saveSettings();
+
+ return true;
+ }
+
+ @Override
+ public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+ ListView listView = (ListView) parent;
+ ListAdapter listAdapter = listView.getAdapter();
+ Object obj = listAdapter.getItem(position);
+
+ if (obj != null) {
+ if (obj instanceof View.OnLongClickListener) {
+ View.OnLongClickListener longListener = (View.OnLongClickListener) obj;
+ return longListener.onLongClick(view);
+ } else if (obj instanceof PreferenceHint) {
+ PreferenceHint hintObj = (PreferenceHint) obj;
+ if (hintObj.hasHint()) {
+ HashMap<String, Object> properties = new HashMap<>();
+ properties.put("hint_shown", hintObj.getHint());
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_HINT_TOAST_SHOWN, properties);
+ ToastUtils.showToast(getActivity(), hintObj.getHint(), ToastUtils.Duration.SHORT);
+ }
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ if (mEditingList == mSiteSettings.getModerationKeys()) {
+ onPreferenceChange(mModerationHoldPref, mEditingList.size());
+ } else if (mEditingList == mSiteSettings.getBlacklistKeys()) {
+ onPreferenceChange(mBlacklistPref, mEditingList.size());
+ }
+ mEditingList = null;
+ }
+
+ @Override
+ public void onSettingsUpdated(Exception error) {
+ if (error != null) {
+ ToastUtils.showToast(getActivity(), R.string.error_fetch_remote_site_settings);
+ getActivity().finish();
+ return;
+ }
+
+ if (isAdded()) setPreferencesFromSiteSettings();
+ }
+
+ @Override
+ public void onSettingsSaved(Exception error) {
+ if (error != null) {
+ ToastUtils.showToast(WordPress.getContext(), R.string.error_post_remote_site_settings);
+ return;
+ }
+ mBlog.setBlogName(mSiteSettings.getTitle());
+ WordPress.wpDB.saveBlog(mBlog);
+
+ // update the global current Blog so WordPress.getCurrentBlog() callers will get the updated object
+ WordPress.setCurrentBlog(mBlog.getLocalTableBlogId());
+
+ EventBus.getDefault().post(new CoreEvents.BlogListChanged());
+ }
+
+ @Override
+ public void onCredentialsValidated(Exception error) {
+ if (error != null) {
+ ToastUtils.showToast(WordPress.getContext(), R.string.username_or_password_incorrect);
+ }
+ }
+
+ private void setupPreferenceList(ListView prefList, Resources res) {
+ if (prefList == null || res == null) return;
+
+ // customize list dividers
+ //noinspection deprecation
+ prefList.setDivider(res.getDrawable(R.drawable.preferences_divider));
+ prefList.setDividerHeight(res.getDimensionPixelSize(R.dimen.site_settings_divider_height));
+ // handle long clicks on preferences to display hints
+ prefList.setOnItemLongClickListener(this);
+ // required to customize (Calypso) preference views
+ prefList.setOnHierarchyChangeListener(this);
+ // remove footer divider bar
+ prefList.setFooterDividersEnabled(false);
+ //noinspection deprecation
+ prefList.setOverscrollFooter(res.getDrawable(R.color.transparent));
+ }
+
+ /**
+ * Helper method to retrieve {@link Preference} references and initialize any data.
+ */
+ private void initPreferences() {
+ mTitlePref = (EditTextPreference) getChangePref(R.string.pref_key_site_title);
+ mTaglinePref = (EditTextPreference) getChangePref(R.string.pref_key_site_tagline);
+ mAddressPref = (EditTextPreference) getChangePref(R.string.pref_key_site_address);
+ mPrivacyPref = (DetailListPreference) getChangePref(R.string.pref_key_site_visibility);
+ mLanguagePref = (DetailListPreference) getChangePref(R.string.pref_key_site_language);
+ mUsernamePref = (EditTextPreference) getChangePref(R.string.pref_key_site_username);
+ mPasswordPref = (EditTextPreference) getChangePref(R.string.pref_key_site_password);
+ mLocationPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_location);
+ mCategoryPref = (DetailListPreference) getChangePref(R.string.pref_key_site_category);
+ mFormatPref = (DetailListPreference) getChangePref(R.string.pref_key_site_format);
+ mAllowCommentsPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_allow_comments);
+ mAllowCommentsNested = (WPSwitchPreference) getChangePref(R.string.pref_key_site_allow_comments_nested);
+ mSendPingbacksPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_send_pingbacks);
+ mSendPingbacksNested = (WPSwitchPreference) getChangePref(R.string.pref_key_site_send_pingbacks_nested);
+ mReceivePingbacksPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_receive_pingbacks);
+ mReceivePingbacksNested = (WPSwitchPreference) getChangePref(R.string.pref_key_site_receive_pingbacks_nested);
+ mIdentityRequiredPreference = (WPSwitchPreference) getChangePref(R.string.pref_key_site_identity_required);
+ mUserAccountRequiredPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_user_account_required);
+ mSortByPref = (DetailListPreference) getChangePref(R.string.pref_key_site_sort_by);
+ mWhitelistPref = (DetailListPreference) getChangePref(R.string.pref_key_site_whitelist);
+ mMorePreference = (PreferenceScreen) getClickPref(R.string.pref_key_site_more_discussion);
+ mRelatedPostsPref = getClickPref(R.string.pref_key_site_related_posts);
+ mCloseAfterPref = getClickPref(R.string.pref_key_site_close_after);
+ mPagingPref = getClickPref(R.string.pref_key_site_paging);
+ mThreadingPref = getClickPref(R.string.pref_key_site_threading);
+ mMultipleLinksPref = getClickPref(R.string.pref_key_site_multiple_links);
+ mModerationHoldPref = getClickPref(R.string.pref_key_site_moderation_hold);
+ mBlacklistPref = getClickPref(R.string.pref_key_site_blacklist);
+ mImageWidthPref = (DetailListPreference) getChangePref(R.string.pref_key_site_image_width);
+ mUploadAndLinkPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_upload_and_link_image);
+ mStartOverPref = getClickPref(R.string.pref_key_site_start_over);
+ mExportSitePref = getClickPref(R.string.pref_key_site_export_site);
+ mDeleteSitePref = getClickPref(R.string.pref_key_site_delete_site);
+
+ sortLanguages();
+
+ // .com sites hide the Account category, self-hosted sites hide the Related Posts preference
+ if (mBlog.isDotcomFlag()) {
+ removeSelfHostedOnlyPreferences();
+ } else {
+ removeDotComOnlyPreferences();
+ }
+
+ // hide all options except for Delete site and Enable Location if user is not admin
+ if (!mBlog.isAdmin()) hideAdminRequiredPreferences();
+ }
+
+ public void setEditingEnabled(boolean enabled) {
+ // excludes mAddressPref, mMorePreference
+ final Preference[] editablePreference = {
+ mTitlePref , mTaglinePref, mPrivacyPref, mLanguagePref, mUsernamePref,
+ mPasswordPref, mLocationPref, mCategoryPref, mFormatPref, mAllowCommentsPref,
+ mAllowCommentsNested, mSendPingbacksPref, mSendPingbacksNested, mReceivePingbacksPref,
+ mReceivePingbacksNested, mIdentityRequiredPreference, mUserAccountRequiredPref,
+ mSortByPref, mWhitelistPref, mRelatedPostsPref, mCloseAfterPref, mPagingPref,
+ mThreadingPref, mMultipleLinksPref, mModerationHoldPref, mBlacklistPref,
+ mImageWidthPref, mUploadAndLinkPref, mDeleteSitePref
+ };
+
+ for(Preference preference : editablePreference) {
+ if(preference!=null) preference.setEnabled(enabled);
+ }
+
+ mEditingEnabled = enabled;
+ }
+
+ private void showRelatedPostsDialog() {
+ DialogFragment relatedPosts = new RelatedPostsDialog();
+ Bundle args = new Bundle();
+ args.putBoolean(RelatedPostsDialog.SHOW_RELATED_POSTS_KEY, mSiteSettings.getShowRelatedPosts());
+ args.putBoolean(RelatedPostsDialog.SHOW_HEADER_KEY, mSiteSettings.getShowRelatedPostHeader());
+ args.putBoolean(RelatedPostsDialog.SHOW_IMAGES_KEY, mSiteSettings.getShowRelatedPostImages());
+ relatedPosts.setArguments(args);
+ relatedPosts.setTargetFragment(this, RELATED_POSTS_REQUEST_CODE);
+ relatedPosts.show(getFragmentManager(), "related-posts");
+ }
+
+ private void showNumberPickerDialog(Bundle args, int requestCode, String tag) {
+ showNumberPickerDialog(args, requestCode, tag, null);
+ }
+
+ private void showNumberPickerDialog(Bundle args, int requestCode, String tag, Formatter format) {
+ NumberPickerDialog dialog = new NumberPickerDialog();
+ dialog.setNumberFormat(format);
+ dialog.setArguments(args);
+ dialog.setTargetFragment(this, requestCode);
+ dialog.show(getFragmentManager(), tag);
+ }
+
+ private void showPagingDialog() {
+ Bundle args = new Bundle();
+ args.putBoolean(NumberPickerDialog.SHOW_SWITCH_KEY, true);
+ args.putBoolean(NumberPickerDialog.SWITCH_ENABLED_KEY, mSiteSettings.getShouldPageComments());
+ args.putString(NumberPickerDialog.SWITCH_TITLE_KEY, getString(R.string.site_settings_paging_title));
+ args.putString(NumberPickerDialog.SWITCH_DESC_KEY, getString(R.string.site_settings_paging_dialog_description));
+ args.putString(NumberPickerDialog.TITLE_KEY, getString(R.string.site_settings_paging_title));
+ args.putString(NumberPickerDialog.HEADER_TEXT_KEY, getString(R.string.site_settings_paging_dialog_header));
+ args.putInt(NumberPickerDialog.MIN_VALUE_KEY, 1);
+ args.putInt(NumberPickerDialog.MAX_VALUE_KEY, getResources().getInteger(R.integer.paging_limit));
+ args.putInt(NumberPickerDialog.CUR_VALUE_KEY, mSiteSettings.getPagingCount());
+ showNumberPickerDialog(args, PAGING_REQUEST_CODE, "paging-dialog");
+ }
+
+ private void showThreadingDialog() {
+ Bundle args = new Bundle();
+ args.putBoolean(NumberPickerDialog.SHOW_SWITCH_KEY, true);
+ args.putBoolean(NumberPickerDialog.SWITCH_ENABLED_KEY, mSiteSettings.getShouldThreadComments());
+ args.putString(NumberPickerDialog.SWITCH_TITLE_KEY, getString(R.string.site_settings_threading_title));
+ args.putString(NumberPickerDialog.SWITCH_DESC_KEY, getString(R.string.site_settings_threading_dialog_description));
+ args.putString(NumberPickerDialog.TITLE_KEY, getString(R.string.site_settings_threading_title));
+ args.putString(NumberPickerDialog.HEADER_TEXT_KEY, getString(R.string.site_settings_threading_dialog_header));
+ args.putInt(NumberPickerDialog.MIN_VALUE_KEY, 2);
+ args.putInt(NumberPickerDialog.MAX_VALUE_KEY, getResources().getInteger(R.integer.threading_limit));
+ args.putInt(NumberPickerDialog.CUR_VALUE_KEY, mSiteSettings.getThreadingLevels());
+ showNumberPickerDialog(args, THREADING_REQUEST_CODE, "threading-dialog", new Formatter() {
+ @Override
+ public String format(int value) {
+ return mSiteSettings.getThreadingDescriptionForLevel(value);
+ }
+ });
+ }
+
+ private void showExportContentDialog() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.export_your_content);
+ String email = AccountHelper.getDefaultAccount().getEmail();
+ builder.setMessage(getString(R.string.export_your_content_message, email));
+ builder.setPositiveButton(R.string.site_settings_export_content_title, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_EXPORT_SITE_REQUESTED);
+ exportSite();
+ }
+ });
+ builder.setNegativeButton(R.string.cancel, null);
+
+ builder.show();
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_EXPORT_SITE_ACCESSED);
+ }
+
+ private void dismissProgressDialog(ProgressDialog progressDialog) {
+ if (progressDialog != null && progressDialog.isShowing()) {
+ try {
+ progressDialog.dismiss();
+ } catch (IllegalArgumentException e) {
+ // dialog doesn't exist
+ }
+ }
+ }
+
+ private void requestPurchasesForDeletionCheck() {
+ final Blog currentBlog = WordPress.getCurrentBlog();
+ final ProgressDialog progressDialog = ProgressDialog.show(getActivity(), "", getString(R.string.checking_purchases), true, false);
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_PURCHASES_REQUESTED);
+ WordPress.getRestClientUtils().getSitePurchases(currentBlog.getDotComBlogId(), new RestRequest.Listener() {
+ @Override
+ public void onResponse(JSONObject response) {
+ dismissProgressDialog(progressDialog);
+ if (isAdded()) {
+ showPurchasesOrDeleteSiteDialog(response, currentBlog);
+ }
+ }
+ }, new RestRequest.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ dismissProgressDialog(progressDialog);
+ if (isAdded()) {
+ ToastUtils.showToast(getActivity(), getString(R.string.purchases_request_error));
+ AppLog.e(AppLog.T.API, "Error occurred while requesting purchases for deletion check: " + error.toString());
+ }
+ }
+ });
+ }
+
+ private void showPurchasesOrDeleteSiteDialog(JSONObject response, final Blog currentBlog) {
+ try {
+ JSONArray purchases = response.getJSONArray(PURCHASE_ORIGINAL_RESPONSE_KEY);
+ if (hasActivePurchases(purchases)) {
+ showPurchasesDialog(currentBlog);
+ } else {
+ showDeleteSiteDialog();
+ }
+ } catch (JSONException e) {
+ AppLog.e(AppLog.T.API, "Error occurred while trying to delete site: " + e.toString());
+ }
+ }
+
+ private void showPurchasesDialog(final Blog currentBlog) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.premium_upgrades_title);
+ builder.setMessage(R.string.premium_upgrades_message);
+ builder.setPositiveButton(R.string.show_purchases, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_PURCHASES_SHOW_CLICKED);
+ WPWebViewActivity.openUrlByUsingWPCOMCredentials(getActivity(), WORDPRESS_PURCHASES_URL, AccountHelper.getCurrentUsernameForBlog(currentBlog));
+ }
+ });
+ builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ });
+ builder.show();
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_PURCHASES_SHOWN);
+ }
+
+ private boolean hasActivePurchases(JSONArray purchases) throws JSONException {
+ for (int i = 0; i < purchases.length(); i++) {
+ JSONObject purchase = purchases.getJSONObject(i);
+ int active = purchase.getInt(PURCHASE_ACTIVE_KEY);
+
+ if (active == 1) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private void showDeleteSiteDialog() {
+ if (mIsFragmentPaused) return; // Do not show the DeleteSiteDialogFragment if the fragment was paused.
+ // DialogFragment internally uses commit(), and not commitAllowingStateLoss, crashing the app in case like that.
+ Bundle args = new Bundle();
+ args.putString(DeleteSiteDialogFragment.SITE_DOMAIN_KEY, UrlUtils.getHost(mBlog.getHomeURL()));
+ DeleteSiteDialogFragment deleteSiteDialogFragment = new DeleteSiteDialogFragment();
+ deleteSiteDialogFragment.setArguments(args);
+ deleteSiteDialogFragment.setTargetFragment(this, DELETE_SITE_REQUEST_CODE);
+ deleteSiteDialogFragment.show(getFragmentManager(), DELETE_SITE_TAG);
+ }
+
+ private void showCloseAfterDialog() {
+ Bundle args = new Bundle();
+ args.putBoolean(NumberPickerDialog.SHOW_SWITCH_KEY, true);
+ args.putBoolean(NumberPickerDialog.SWITCH_ENABLED_KEY, mSiteSettings.getShouldCloseAfter());
+ args.putString(NumberPickerDialog.SWITCH_TITLE_KEY, getString(R.string.site_settings_close_after_dialog_switch_text));
+ args.putString(NumberPickerDialog.SWITCH_DESC_KEY, getString(R.string.site_settings_close_after_dialog_description));
+ args.putString(NumberPickerDialog.TITLE_KEY, getString(R.string.site_settings_close_after_dialog_title));
+ args.putString(NumberPickerDialog.HEADER_TEXT_KEY, getString(R.string.site_settings_close_after_dialog_header));
+ args.putInt(NumberPickerDialog.MIN_VALUE_KEY, 1);
+ args.putInt(NumberPickerDialog.MAX_VALUE_KEY, getResources().getInteger(R.integer.close_after_limit));
+ args.putInt(NumberPickerDialog.CUR_VALUE_KEY, mSiteSettings.getCloseAfter());
+ showNumberPickerDialog(args, CLOSE_AFTER_REQUEST_CODE, "close-after-dialog");
+ }
+
+ private void showMultipleLinksDialog() {
+ Bundle args = new Bundle();
+ args.putBoolean(NumberPickerDialog.SHOW_SWITCH_KEY, false);
+ args.putString(NumberPickerDialog.TITLE_KEY, getString(R.string.site_settings_multiple_links_title));
+ args.putInt(NumberPickerDialog.MIN_VALUE_KEY, 0);
+ args.putInt(NumberPickerDialog.MAX_VALUE_KEY, getResources().getInteger(R.integer.max_links_limit));
+ args.putInt(NumberPickerDialog.CUR_VALUE_KEY, mSiteSettings.getMultipleLinks());
+ showNumberPickerDialog(args, MULTIPLE_LINKS_REQUEST_CODE, "multiple-links-dialog");
+ }
+
+ private void setPreferencesFromSiteSettings() {
+ mLocationPref.setChecked(mSiteSettings.getLocation());
+ changeEditTextPreferenceValue(mTitlePref, mSiteSettings.getTitle());
+ changeEditTextPreferenceValue(mTaglinePref, mSiteSettings.getTagline());
+ changeEditTextPreferenceValue(mAddressPref, mSiteSettings.getAddress());
+ changeEditTextPreferenceValue(mUsernamePref, mSiteSettings.getUsername());
+ changeEditTextPreferenceValue(mPasswordPref, mSiteSettings.getPassword());
+ changeLanguageValue(mSiteSettings.getLanguageCode());
+ setDetailListPreferenceValue(mPrivacyPref,
+ String.valueOf(mSiteSettings.getPrivacy()),
+ mSiteSettings.getPrivacyDescription());
+ setDetailListPreferenceValue(mImageWidthPref,
+ mBlog.getMaxImageWidth(),
+ mBlog.getMaxImageWidth());
+ setCategories();
+ setPostFormats();
+ setAllowComments(mSiteSettings.getAllowComments());
+ setSendPingbacks(mSiteSettings.getSendPingbacks());
+ setReceivePingbacks(mSiteSettings.getReceivePingbacks());
+ setDetailListPreferenceValue(mSortByPref,
+ String.valueOf(mSiteSettings.getCommentSorting()),
+ mSiteSettings.getSortingDescription());
+ int approval = mSiteSettings.getManualApproval() ?
+ mSiteSettings.getUseCommentWhitelist() ? 0
+ : -1 : 1;
+ setDetailListPreferenceValue(mWhitelistPref, String.valueOf(approval), getWhitelistSummary(approval));
+ String s = StringUtils.getQuantityString(getActivity(), R.string.site_settings_multiple_links_summary_zero,
+ R.string.site_settings_multiple_links_summary_one,
+ R.string.site_settings_multiple_links_summary_other, mSiteSettings.getMultipleLinks());
+ mMultipleLinksPref.setSummary(s);
+ mUploadAndLinkPref.setChecked(mBlog.isFullSizeImage());
+ mIdentityRequiredPreference.setChecked(mSiteSettings.getIdentityRequired());
+ mUserAccountRequiredPref.setChecked(mSiteSettings.getUserAccountRequired());
+ mThreadingPref.setSummary(mSiteSettings.getThreadingDescription());
+ mCloseAfterPref.setSummary(mSiteSettings.getCloseAfterDescriptionForPeriod());
+ mPagingPref.setSummary(mSiteSettings.getPagingDescription());
+ mRelatedPostsPref.setSummary(mSiteSettings.getRelatedPostsDescription());
+ mModerationHoldPref.setSummary(mSiteSettings.getModerationHoldDescription());
+ mBlacklistPref.setSummary(mSiteSettings.getBlacklistDescription());
+ }
+
+ private void setCategories() {
+ // Ignore if there are no changes
+ if (mSiteSettings.isSameCategoryList(mCategoryPref.getEntryValues())) {
+ mCategoryPref.setValue(String.valueOf(mSiteSettings.getDefaultCategory()));
+ mCategoryPref.setSummary(mSiteSettings.getDefaultCategoryForDisplay());
+ return;
+ }
+
+ Map<Integer, String> categories = mSiteSettings.getCategoryNames();
+ CharSequence[] entries = new CharSequence[categories.size()];
+ CharSequence[] values = new CharSequence[categories.size()];
+ int i = 0;
+ for (Integer key : categories.keySet()) {
+ entries[i] = categories.get(key);
+ values[i] = String.valueOf(key);
+ if (key == UNCATEGORIZED_CATEGORY_ID) {
+ CharSequence temp = entries[0];
+ entries[0] = entries[i];
+ entries[i] = temp;
+ temp = values[0];
+ values[0] = values[i];
+ values[i] = temp;
+ }
+ ++i;
+ }
+
+ mCategoryPref.setEntries(entries);
+ mCategoryPref.setEntryValues(values);
+ mCategoryPref.setValue(String.valueOf(mSiteSettings.getDefaultCategory()));
+ mCategoryPref.setSummary(mSiteSettings.getDefaultCategoryForDisplay());
+ }
+
+ private void setPostFormats() {
+ // Ignore if there are no changes
+ if (mSiteSettings.isSameFormatList(mFormatPref.getEntryValues())) {
+ mFormatPref.setValue(String.valueOf(mSiteSettings.getDefaultPostFormat()));
+ mFormatPref.setSummary(mSiteSettings.getDefaultPostFormatDisplay());
+ return;
+ }
+
+ // clone the post formats map
+ final Map<String, String> postFormats = new HashMap<>(mSiteSettings.getFormats());
+
+ // transform the keys and values into arrays and set the ListPreference's data
+ mFormatPref.setEntries(postFormats.values().toArray(new String[0]));
+ mFormatPref.setEntryValues(postFormats.keySet().toArray(new String[0]));
+ mFormatPref.setValue(String.valueOf(mSiteSettings.getDefaultPostFormat()));
+ mFormatPref.setSummary(mSiteSettings.getDefaultPostFormatDisplay());
+ }
+
+ private void setAllowComments(boolean newValue) {
+ mSiteSettings.setAllowComments(newValue);
+ mAllowCommentsPref.setChecked(newValue);
+ mAllowCommentsNested.setChecked(newValue);
+ }
+
+ private void setSendPingbacks(boolean newValue) {
+ mSiteSettings.setSendPingbacks(newValue);
+ mSendPingbacksPref.setChecked(newValue);
+ mSendPingbacksNested.setChecked(newValue);
+ }
+
+ private void setReceivePingbacks(boolean newValue) {
+ mSiteSettings.setReceivePingbacks(newValue);
+ mReceivePingbacksPref.setChecked(newValue);
+ mReceivePingbacksNested.setChecked(newValue);
+ }
+
+ private void setDetailListPreferenceValue(DetailListPreference pref, String value, String summary) {
+ pref.setValue(value);
+ pref.setSummary(summary);
+ pref.refreshAdapter();
+ }
+
+ /**
+ * Helper method to perform validation and set multiple properties on an EditTextPreference.
+ * If newValue is equal to the current preference text no action will be taken.
+ */
+ private void changeEditTextPreferenceValue(EditTextPreference pref, String newValue) {
+ if (newValue == null || pref == null || pref.getEditText().isInEditMode()) return;
+
+ if (!newValue.equals(pref.getSummary())) {
+ String formattedValue = StringUtils.unescapeHTML(newValue.replaceFirst(ADDRESS_FORMAT_REGEX, ""));
+
+ pref.setText(formattedValue);
+ pref.setSummary(formattedValue);
+ }
+ }
+
+ /**
+ * Detail strings for the dialog are generated in the selected language.
+ *
+ * @param newValue
+ * languageCode
+ */
+ private void changeLanguageValue(String newValue) {
+ if (mLanguagePref == null || newValue == null) return;
+
+ if (TextUtils.isEmpty(mLanguagePref.getSummary()) ||
+ !newValue.equals(mLanguagePref.getValue())) {
+ mLanguagePref.setValue(newValue);
+ String summary = WPPrefUtils.getLanguageString(newValue, WPPrefUtils.languageLocale(newValue));
+ mLanguagePref.setSummary(summary);
+ mLanguagePref.refreshAdapter();
+ }
+ }
+
+ private void sortLanguages() {
+ if (mLanguagePref == null) return;
+
+ Pair<String[], String[]> pair = WPPrefUtils.createSortedLanguageDisplayStrings(mLanguagePref.getEntryValues(), WPPrefUtils.languageLocale(null));
+ if (pair != null) {
+ String[] sortedEntries = pair.first;
+ String[] sortedValues = pair.second;
+
+ mLanguagePref.setEntries(sortedEntries);
+ mLanguagePref.setEntryValues(sortedValues);
+ mLanguagePref.setDetails(WPPrefUtils.createLanguageDetailDisplayStrings(sortedValues));
+ }
+ }
+
+ private String getWhitelistSummary(int value) {
+ if (isAdded()) {
+ switch (value) {
+ case -1:
+ return getString(R.string.site_settings_whitelist_none_summary);
+ case 0:
+ return getString(R.string.site_settings_whitelist_known_summary);
+ case 1:
+ return getString(R.string.site_settings_whitelist_all_summary);
+ }
+ }
+ return "";
+ }
+
+ private void updateWhitelistSettings(int val) {
+ mSiteSettings.setManualApproval(val == -1);
+ mSiteSettings.setUseCommentWhitelist(val == 0);
+ setDetailListPreferenceValue(mWhitelistPref,
+ String.valueOf(val),
+ getWhitelistSummary(val));
+ }
+
+ private void showListEditorDialog(int titleRes, int headerRes) {
+ mDialog = new Dialog(getActivity(), R.style.Calypso_SiteSettingsTheme);
+ mDialog.setOnDismissListener(this);
+ mDialog.setContentView(getListEditorView(getString(headerRes)));
+ mDialog.show();
+ WPActivityUtils.addToolbarToDialog(this, mDialog, getString(titleRes));
+ }
+
+ private View getListEditorView(String headerText) {
+ Context themer = new ContextThemeWrapper(getActivity(), R.style.Calypso_SiteSettingsTheme);
+ View view = View.inflate(themer, R.layout.list_editor, null);
+ ((TextView) view.findViewById(R.id.list_editor_header_text)).setText(headerText);
+
+ mAdapter = null;
+ final EmptyViewRecyclerView list = (EmptyViewRecyclerView) view.findViewById(android.R.id.list);
+ list.setLayoutManager(
+ new SmoothScrollLinearLayoutManager(
+ getActivity(),
+ LinearLayoutManager.VERTICAL,
+ false,
+ getResources().getInteger(android.R.integer.config_mediumAnimTime)
+ )
+ );
+ list.setAdapter(getAdapter());
+ list.setEmptyView(view.findViewById(R.id.empty_view));
+ list.addOnItemTouchListener(
+ new RecyclerViewItemClickListener(
+ getActivity(),
+ list,
+ new RecyclerViewItemClickListener.OnItemClickListener() {
+ @Override
+ public void onItemClick(View view, int position) {
+ if (mActionMode != null) {
+ getAdapter().toggleItemSelected(position);
+ mActionMode.invalidate();
+
+ if (getAdapter().getItemsSelected().size() <= 0) {
+ mActionMode.finish();
+ }
+ }
+ }
+
+ @Override
+ public void onLongItemClick(View view, int position) {
+ if (mActionMode == null) {
+ if (view.isHapticFeedbackEnabled()) {
+ view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ }
+
+ mDialog.getWindow().getDecorView().startActionMode(new ActionModeCallback());
+ getAdapter().setItemSelected(position);
+ mActionMode.invalidate();
+ }
+ }
+ }
+ )
+ );
+ view.findViewById(R.id.fab_button).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ AlertDialog.Builder builder =
+ new AlertDialog.Builder(getActivity(), R.style.Calypso_AlertDialog);
+ final EditText input = new EditText(getActivity());
+ WPPrefUtils.layoutAsInput(input);
+ input.setWidth(getResources().getDimensionPixelSize(R.dimen.list_editor_input_max_width));
+ input.setHint(R.string.site_settings_list_editor_input_hint);
+ builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String entry = input.getText().toString();
+ if (!TextUtils.isEmpty(entry) && !mEditingList.contains(entry)) {
+ mEditingList.add(entry);
+ getAdapter().notifyItemInserted(getAdapter().getItemCount() - 1);
+ list.post(
+ new Runnable() {
+ @Override
+ public void run() {
+ list.smoothScrollToPosition(getAdapter().getItemCount() - 1);
+ }
+ }
+ );
+ mSiteSettings.saveSettings();
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_ADDED_LIST_ITEM);
+ }
+ }
+ });
+ builder.setNegativeButton(R.string.cancel, null);
+ final AlertDialog alertDialog = builder.create();
+ int spacing = getResources().getDimensionPixelSize(R.dimen.dlp_padding_start);
+ alertDialog.setView(input, spacing, spacing, spacing, 0);
+ alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ alertDialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+ alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ alertDialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_HIDDEN);
+ }
+ });
+ alertDialog.show();
+ Button positive = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
+ Button negative = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
+ if (positive != null) WPPrefUtils.layoutAsFlatButton(positive);
+ if (negative != null) WPPrefUtils.layoutAsFlatButton(negative);
+ }
+ });
+
+ return view;
+ }
+
+ private void removeBlog() {
+ if (WordPress.wpDB.deleteBlog(getActivity(), mBlog.getLocalTableBlogId())) {
+ StatsTable.deleteStatsForBlog(getActivity(), mBlog.getLocalTableBlogId()); // Remove stats data
+ AnalyticsUtils.refreshMetadata();
+ ToastUtils.showToast(getActivity(), R.string.blog_removed_successfully);
+ WordPress.wpDB.deleteLastBlogId();
+ WordPress.currentBlog = null;
+ getActivity().setResult(RESULT_BLOG_REMOVED);
+
+ // If the last blog is removed and the user is not signed in wpcom, broadcast a UserSignedOut event
+ if (!AccountHelper.isSignedIn()) {
+ EventBus.getDefault().post(new CoreEvents.UserSignedOutCompletely());
+ }
+
+ // Checks for stats widgets that were synched with a blog that could be gone now.
+ StatsWidgetProvider.updateWidgetsOnLogout(getActivity());
+
+ getActivity().finish();
+ } else {
+ AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
+ dialogBuilder.setTitle(getResources().getText(R.string.error));
+ dialogBuilder.setMessage(getResources().getText(R.string.could_not_remove_account));
+ dialogBuilder.setPositiveButton(R.string.ok, null);
+ dialogBuilder.setCancelable(true);
+ dialogBuilder.create().show();
+ }
+ }
+
+ private boolean shouldShowListPreference(DetailListPreference preference) {
+ return preference != null && preference.getEntries() != null && preference.getEntries().length > 0;
+ }
+
+ private boolean setupMorePreferenceScreen() {
+ if (mMorePreference == null || !isAdded()) return false;
+ String title = getString(R.string.site_settings_discussion_title);
+ Dialog dialog = mMorePreference.getDialog();
+ if (dialog != null) {
+ setupPreferenceList((ListView) dialog.findViewById(android.R.id.list), getResources());
+ WPActivityUtils.addToolbarToDialog(this, dialog, title);
+ return true;
+ }
+ return false;
+ }
+
+ private void removeMoreScreenToolbar() {
+ if (mMorePreference == null || !isAdded()) return;
+ Dialog moreDialog = mMorePreference.getDialog();
+ WPActivityUtils.removeToolbarFromDialog(this, moreDialog);
+ }
+
+ private void hideAdminRequiredPreferences() {
+ WPPrefUtils.removePreference(this, R.string.pref_key_site_screen, R.string.pref_key_site_general);
+ WPPrefUtils.removePreference(this, R.string.pref_key_site_screen, R.string.pref_key_site_account);
+ WPPrefUtils.removePreference(this, R.string.pref_key_site_screen, R.string.pref_key_site_discussion);
+ WPPrefUtils.removePreference(this, R.string.pref_key_site_writing, R.string.pref_key_site_category);
+ WPPrefUtils.removePreference(this, R.string.pref_key_site_writing, R.string.pref_key_site_format);
+ WPPrefUtils.removePreference(this, R.string.pref_key_site_writing, R.string.pref_key_site_related_posts);
+ }
+
+ private void removeDotComOnlyPreferences() {
+ WPPrefUtils.removePreference(this, R.string.pref_key_site_general, R.string.pref_key_site_language);
+ WPPrefUtils.removePreference(this, R.string.pref_key_site_writing, R.string.pref_key_site_related_posts);
+ }
+
+ private void removeSelfHostedOnlyPreferences() {
+ WPPrefUtils.removePreference(this, R.string.pref_key_site_screen, R.string.pref_key_site_account);
+ WPPrefUtils.removePreference(this, R.string.pref_key_site_screen, R.string.pref_key_site_delete_site_screen);
+ }
+
+ private Preference getChangePref(int id) {
+ return WPPrefUtils.getPrefAndSetChangeListener(this, id, this);
+ }
+
+ private Preference getClickPref(int id) {
+ return WPPrefUtils.getPrefAndSetClickListener(this, id, this);
+ }
+
+ private void handleDeleteSiteError() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.error_deleting_site);
+ builder.setMessage(R.string.error_deleting_site_summary);
+ builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ });
+ builder.setPositiveButton(R.string.contact_support, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ HelpshiftHelper.getInstance().showConversation(getActivity(), HelpshiftHelper.Tag.ORIGIN_DELETE_SITE);
+ }
+ });
+ builder.show();
+ }
+
+ private void exportSite() {
+ final Blog currentBlog = WordPress.getCurrentBlog();
+ if (currentBlog.isDotcomFlag()) {
+ final ProgressDialog progressDialog = ProgressDialog.show(getActivity(), "", getActivity().getString(R.string.exporting_content_progress), true, true);
+ WordPress.getRestClientUtils().exportContentAll(currentBlog.getDotComBlogId(), new RestRequest.Listener() {
+ @Override
+ public void onResponse(JSONObject response) {
+ if (isAdded()) {
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_EXPORT_SITE_RESPONSE_OK);
+ dismissProgressDialog(progressDialog);
+ Snackbar.make(getView(), R.string.export_email_sent, Snackbar.LENGTH_LONG).show();
+ }
+ }
+ }, new RestRequest.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ if (isAdded()) {
+ HashMap<String, Object> errorProperty = new HashMap<>();
+ errorProperty.put(ANALYTICS_ERROR_PROPERTY_KEY, error.getMessage());
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_EXPORT_SITE_RESPONSE_ERROR, errorProperty);
+ dismissProgressDialog(progressDialog);
+ }
+ }
+ });
+ }
+ }
+
+ private void deleteSite() {
+ final Blog currentBlog = WordPress.getCurrentBlog();
+ if (currentBlog.isDotcomFlag()) {
+ final ProgressDialog progressDialog = ProgressDialog.show(getActivity(), "", getString(R.string.delete_site_progress), true, false);
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_REQUESTED);
+ WordPress.getRestClientUtils().deleteSite(currentBlog.getDotComBlogId(), new RestRequest.Listener() {
+ @Override
+ public void onResponse(JSONObject response) {
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_RESPONSE_OK);
+ progressDialog.dismiss();
+ removeBlog();
+ }
+ }, new RestRequest.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ HashMap<String, Object> errorProperty = new HashMap<>();
+ errorProperty.put(ANALYTICS_ERROR_PROPERTY_KEY, error.getMessage());
+ AnalyticsUtils.trackWithCurrentBlogDetails(
+ AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_RESPONSE_ERROR, errorProperty);
+ dismissProgressDialog(progressDialog);
+ handleDeleteSiteError();
+ }
+ });
+ }
+ }
+
+ private MultiSelectRecyclerViewAdapter getAdapter() {
+ if (mAdapter == null) {
+ mAdapter = new MultiSelectRecyclerViewAdapter(getActivity(), mEditingList);
+ }
+
+ return mAdapter;
+ }
+
+ private final class ActionModeCallback implements ActionMode.Callback {
+ @Override
+ public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
+ switch (menuItem.getItemId()) {
+ case R.id.menu_delete:
+ SparseBooleanArray checkedItems = getAdapter().getItemsSelected();
+
+ HashMap<String, Object> properties = new HashMap<>();
+ properties.put("num_items_deleted", checkedItems.size());
+ AnalyticsUtils.trackWithCurrentBlogDetails(AnalyticsTracker.Stat.SITE_SETTINGS_DELETED_LIST_ITEMS, properties);
+
+ for (int i = checkedItems.size() - 1; i >= 0; i--) {
+ final int index = checkedItems.keyAt(i);
+
+ if (checkedItems.get(index)) {
+ mEditingList.remove(index);
+ }
+ }
+
+ mSiteSettings.saveSettings();
+ mActionMode.finish();
+ return true;
+ case R.id.menu_select_all:
+ for (int i = 0; i < getAdapter().getItemCount(); i++) {
+ getAdapter().setItemSelected(i);
+ }
+
+ mActionMode.invalidate();
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
+ WPActivityUtils.setStatusBarColor(mDialog.getWindow(), R.color.action_mode_status_bar_tint);
+ mActionMode = actionMode;
+ MenuInflater inflater = actionMode.getMenuInflater();
+ inflater.inflate(R.menu.list_editor, menu);
+ return true;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ WPActivityUtils.setStatusBarColor(mDialog.getWindow(), R.color.status_bar_tint);
+ getAdapter().removeItemsSelected();
+ mActionMode = null;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
+ actionMode.setTitle(getString(
+ R.string.site_settings_list_editor_action_mode_title,
+ getAdapter().getItemsSelected().size())
+ );
+ return true;
+ }
+ }
+}