aboutsummaryrefslogtreecommitdiff
path: root/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostSettingsFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostSettingsFragment.java')
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostSettingsFragment.java1054
1 files changed, 1054 insertions, 0 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostSettingsFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostSettingsFragment.java
new file mode 100644
index 000000000..cdcde6efc
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/EditPostSettingsFragment.java
@@ -0,0 +1,1054 @@
+package org.wordpress.android.ui.posts;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.location.Address;
+import android.location.Location;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v7.widget.AppCompatButton;
+import android.text.Editable;
+import android.text.Html;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewStub;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.view.inputmethod.EditorInfo;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.DatePicker;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.TimePicker;
+import android.widget.Toast;
+
+import com.android.volley.toolbox.NetworkImageView;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.json.JSONArray;
+import org.wordpress.android.R;
+import org.wordpress.android.WordPress;
+import org.wordpress.android.models.Post;
+import org.wordpress.android.models.PostLocation;
+import org.wordpress.android.models.PostStatus;
+import org.wordpress.android.ui.RequestCodes;
+import org.wordpress.android.ui.media.MediaGalleryPickerActivity;
+import org.wordpress.android.ui.media.WordPressMediaUtils;
+import org.wordpress.android.ui.prefs.AppPrefs;
+import org.wordpress.android.ui.prefs.SiteSettingsInterface;
+import org.wordpress.android.ui.suggestion.adapters.TagSuggestionAdapter;
+import org.wordpress.android.ui.suggestion.util.SuggestionServiceConnectionManager;
+import org.wordpress.android.ui.suggestion.util.SuggestionUtils;
+import org.wordpress.android.util.AppLog;
+import org.wordpress.android.util.AppLog.T;
+import org.wordpress.android.util.DisplayUtils;
+import org.wordpress.android.util.EditTextUtils;
+import org.wordpress.android.util.GeocoderUtils;
+import org.wordpress.android.util.JSONUtils;
+import org.wordpress.android.util.PermissionUtils;
+import org.wordpress.android.util.StringUtils;
+import org.wordpress.android.util.ToastUtils;
+import org.wordpress.android.util.helpers.LocationHelper;
+import org.wordpress.android.widgets.SuggestionAutoCompleteText;
+import org.xmlrpc.android.ApiHelper;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+public class EditPostSettingsFragment extends Fragment
+ implements View.OnClickListener, TextView.OnEditorActionListener {
+ private static final int ACTIVITY_REQUEST_CODE_SELECT_CATEGORIES = 5;
+ private static final String CATEGORY_PREFIX_TAG = "category-";
+
+ private static final int SELECT_LIBRARY_MENU_POSITION = 100;
+ private static final int CLEAR_FEATURED_IMAGE_MENU_POSITION = 101;
+
+ private Post mPost;
+
+ private Spinner mStatusSpinner, mPostFormatSpinner;
+ private EditText mPasswordEditText, mExcerptEditText;
+ private TextView mPubDateText;
+ private ViewGroup mSectionCategories;
+ private ViewGroup mRootView;
+ private TextView mFeaturedImageLabel;
+ private NetworkImageView mFeaturedImageView;
+ private Button mFeaturedImageButton;
+ private SuggestionAutoCompleteText mTagsEditText;
+
+ private SuggestionServiceConnectionManager mSuggestionServiceConnectionManager;
+
+ private long mFeaturedImageId;
+
+ private ArrayList<String> mCategories;
+
+ private PostLocation mPostLocation;
+ private LocationHelper mLocationHelper;
+
+ private int mYear, mMonth, mDay, mHour, mMinute;
+ private long mCustomPubDate = 0;
+ private boolean mIsCustomPubDate;
+
+ private String[] mPostFormats;
+ private String[] mPostFormatTitles;
+
+ private enum LocationStatus {NONE, FOUND, NOT_FOUND, SEARCHING}
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getActivity() != null) {
+ PreferenceManager.setDefaultValues(getActivity(), R.xml.account_settings, false);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ if (mSuggestionServiceConnectionManager != null) {
+ mSuggestionServiceConnectionManager.unbindFromService();
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mPost = ((EditPostActivity) getActivity()).getPost();
+ mRootView = (ViewGroup) inflater.inflate(R.layout.edit_post_settings_fragment, container, false);
+
+ if (mRootView == null || mPost == null) {
+ return null;
+ }
+
+ Calendar c = Calendar.getInstance();
+ mYear = c.get(Calendar.YEAR);
+ mMonth = c.get(Calendar.MONTH);
+ mDay = c.get(Calendar.DAY_OF_MONTH);
+ mHour = c.get(Calendar.HOUR_OF_DAY);
+ mMinute = c.get(Calendar.MINUTE);
+ mCategories = new ArrayList<String>();
+
+ mExcerptEditText = (EditText) mRootView.findViewById(R.id.postExcerpt);
+ mPasswordEditText = (EditText) mRootView.findViewById(R.id.post_password);
+ mPubDateText = (TextView) mRootView.findViewById(R.id.pubDate);
+ mPubDateText.setOnClickListener(this);
+ mStatusSpinner = (Spinner) mRootView.findViewById(R.id.status);
+ mStatusSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ updatePostSettingsAndSaveButton();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+
+ }
+ });
+ mSectionCategories = ((ViewGroup) mRootView.findViewById(R.id.sectionCategories));
+
+ mFeaturedImageLabel = (TextView) mRootView.findViewById(R.id.featuredImageLabel);
+ mFeaturedImageView = (NetworkImageView) mRootView.findViewById(R.id.featuredImage);
+ mFeaturedImageButton = (Button) mRootView.findViewById(R.id.addFeaturedImage);
+
+ if (AppPrefs.isVisualEditorEnabled()) {
+ registerForContextMenu(mFeaturedImageView);
+ mFeaturedImageView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ view.showContextMenu();
+ }
+ });
+
+ mFeaturedImageButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ launchMediaGalleryActivity();
+ }
+ });
+ } else {
+ mFeaturedImageLabel.setVisibility(View.GONE);
+ mFeaturedImageView.setVisibility(View.GONE);
+ mFeaturedImageButton.setVisibility(View.GONE);
+ }
+
+ if (mPost.isPage()) { // remove post specific views
+ mExcerptEditText.setVisibility(View.GONE);
+ mRootView.findViewById(R.id.sectionTags).setVisibility(View.GONE);
+ mRootView.findViewById(R.id.sectionCategories).setVisibility(View.GONE);
+ mRootView.findViewById(R.id.postFormatLabel).setVisibility(View.GONE);
+ mRootView.findViewById(R.id.postFormat).setVisibility(View.GONE);
+ } else {
+ mPostFormatTitles = getResources().getStringArray(R.array.post_formats_array);
+ mPostFormats =
+ new String[]{"aside", "audio", "chat", "gallery", "image", "link", "quote", "standard", "status",
+ "video"};
+ if (WordPress.getCurrentBlog().getPostFormats().equals("")) {
+ new ApiHelper.GetPostFormatsTask().execute(WordPress.getCurrentBlog());
+ } else {
+ try {
+ Gson gson = new Gson();
+ Type type = new TypeToken<Map<String, String>>() {}.getType();
+ Map<String, String> jsonPostFormats = gson.fromJson(WordPress.getCurrentBlog().getPostFormats(),
+ type);
+ mPostFormats = new String[jsonPostFormats.size()];
+ mPostFormatTitles = new String[jsonPostFormats.size()];
+ int i = 0;
+ for (Map.Entry<String, String> entry : jsonPostFormats.entrySet()) {
+ String key = entry.getKey();
+ String val = entry.getValue();
+ mPostFormats[i] = key;
+ mPostFormatTitles[i] = StringEscapeUtils.unescapeHtml(val);
+ i++;
+ }
+ } catch (RuntimeException e) {
+ AppLog.e(T.POSTS, e);
+ }
+ }
+ mPostFormatSpinner = (Spinner) mRootView.findViewById(R.id.postFormat);
+ ArrayAdapter<String> pfAdapter = new ArrayAdapter<>(getActivity(), R.layout.simple_spinner_item,
+ mPostFormatTitles);
+ pfAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mPostFormatSpinner.setAdapter(pfAdapter);
+ String activePostFormat = "standard";
+
+ if (!TextUtils.isEmpty(mPost.getPostFormat())) {
+ activePostFormat = mPost.getPostFormat();
+ }
+
+ for (int i = 0; i < mPostFormats.length; i++) {
+ if (mPostFormats[i].equals(activePostFormat))
+ mPostFormatSpinner.setSelection(i);
+ }
+
+ mPostFormatSpinner.setOnTouchListener(
+ new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ return false;
+ }
+ }
+ );
+
+ mTagsEditText = (SuggestionAutoCompleteText) mRootView.findViewById(R.id.tags);
+ if (mTagsEditText != null) {
+ mTagsEditText.setTokenizer(new SuggestionAutoCompleteText.CommaTokenizer());
+
+ setupSuggestionServiceAndAdapter();
+ }
+ }
+
+ initSettingsFields();
+ populateSelectedCategories();
+ initLocation(mRootView);
+ return mRootView;
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ menu.add(0, SELECT_LIBRARY_MENU_POSITION, 0, getResources().getText(R.string.select_from_media_library));
+ menu.add(0, CLEAR_FEATURED_IMAGE_MENU_POSITION, 0, "Remove featured image");
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case SELECT_LIBRARY_MENU_POSITION:
+ launchMediaGalleryActivity();
+ return true;
+ case CLEAR_FEATURED_IMAGE_MENU_POSITION:
+ mFeaturedImageId = -1;
+ mFeaturedImageView.setVisibility(View.GONE);
+ mFeaturedImageButton.setVisibility(View.VISIBLE);
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private void setupSuggestionServiceAndAdapter() {
+ if (!isAdded()) return;
+
+ int remoteBlogId = -1;
+ String blogID = WordPress.getCurrentRemoteBlogId();
+ remoteBlogId = StringUtils.stringToInt(blogID, -1);
+
+ mSuggestionServiceConnectionManager = new SuggestionServiceConnectionManager(getActivity(), remoteBlogId);
+ TagSuggestionAdapter tagSuggestionAdapter = SuggestionUtils.setupTagSuggestions(remoteBlogId, getActivity(), mSuggestionServiceConnectionManager);
+ if (tagSuggestionAdapter != null) {
+ mTagsEditText.setAdapter(tagSuggestionAdapter);
+ }
+ }
+
+ private void initSettingsFields() {
+ mExcerptEditText.setText(mPost.getPostExcerpt());
+
+ String[] items = new String[]{ getResources().getString(R.string.publish_post),
+ getResources().getString(R.string.draft),
+ getResources().getString(R.string.pending_review),
+ getResources().getString(R.string.post_private) };
+
+ ArrayAdapter<String> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, items);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mStatusSpinner.setAdapter(adapter);
+ mStatusSpinner.setOnTouchListener(
+ new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ return false;
+ }
+ }
+ );
+
+ long pubDate = mPost.getDate_created_gmt();
+ if (pubDate != 0) {
+ try {
+ int flags = 0;
+ flags |= android.text.format.DateUtils.FORMAT_SHOW_DATE;
+ flags |= android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
+ flags |= android.text.format.DateUtils.FORMAT_SHOW_YEAR;
+ flags |= android.text.format.DateUtils.FORMAT_SHOW_TIME;
+ String formattedDate = DateUtils.formatDateTime(getActivity(), pubDate,
+ flags);
+ mPubDateText.setText(formattedDate);
+ } catch (RuntimeException e) {
+ AppLog.e(T.POSTS, e);
+ }
+ }
+
+ if (!TextUtils.isEmpty(mPost.getPassword())) {
+ mPasswordEditText.setText(mPost.getPassword());
+ }
+
+ switch (mPost.getStatusEnum()) {
+ case PUBLISHED:
+ case SCHEDULED:
+ case UNKNOWN:
+ mStatusSpinner.setSelection(0, true);
+ break;
+ case DRAFT:
+ mStatusSpinner.setSelection(1, true);
+ break;
+ case PENDING:
+ mStatusSpinner.setSelection(2, true);
+ break;
+ case PRIVATE:
+ mStatusSpinner.setSelection(3, true);
+ break;
+ }
+
+ if (!mPost.isPage()) {
+ if (mPost.getJSONCategories() != null) {
+ mCategories = JSONUtils.fromJSONArrayToStringList(mPost.getJSONCategories());
+ }
+ }
+ String tags = mPost.getKeywords();
+ if (!tags.equals("")) {
+ mTagsEditText.setText(tags);
+ }
+
+ if (AppPrefs.isVisualEditorEnabled()) {
+ updateFeaturedImage(mPost.getFeaturedImageId());
+ }
+ }
+
+ public long getFeaturedImageId() {
+ return mFeaturedImageId;
+ }
+
+ public void updateFeaturedImage(long id) {
+ if (mFeaturedImageId != id) {
+ mFeaturedImageId = id;
+ if (mFeaturedImageId > 0) {
+ int blogId = WordPress.getCurrentBlog().getLocalTableBlogId();
+ Cursor cursor = WordPress.wpDB.getMediaFile(String.valueOf(blogId), String.valueOf(mFeaturedImageId));
+ if (cursor != null && cursor.moveToFirst()) {
+ mFeaturedImageView.setVisibility(View.VISIBLE);
+ mFeaturedImageButton.setVisibility(View.GONE);
+
+ // Get max width for photon thumbnail
+ int maxWidth = getResources().getDisplayMetrics().widthPixels;
+ int padding = DisplayUtils.dpToPx(getActivity(), 16);
+ int imageWidth = (maxWidth - padding);
+
+ String thumbUrl = WordPressMediaUtils.getNetworkThumbnailUrl(cursor, imageWidth);
+ WordPressMediaUtils.loadNetworkImage(thumbUrl, mFeaturedImageView);
+ }
+
+ if (cursor != null) {
+ cursor.close();
+ }
+ } else {
+ mFeaturedImageView.setVisibility(View.GONE);
+ mFeaturedImageButton.setVisibility(View.VISIBLE);
+ }
+ }
+ }
+
+ private void launchMediaGalleryActivity() {
+ Intent intent = new Intent(getActivity(), MediaGalleryPickerActivity.class);
+ intent.putExtra(MediaGalleryPickerActivity.PARAM_SELECT_ONE_ITEM, true);
+ startActivityForResult(intent, MediaGalleryPickerActivity.REQUEST_CODE);
+ }
+
+ private String getPostStatusForSpinnerPosition(int position) {
+ switch (position) {
+ case 0:
+ return PostStatus.toString(PostStatus.PUBLISHED);
+ case 1:
+ return PostStatus.toString(PostStatus.DRAFT);
+ case 2:
+ return PostStatus.toString(PostStatus.PENDING);
+ case 3:
+ return PostStatus.toString(PostStatus.PRIVATE);
+ default:
+ return PostStatus.toString(PostStatus.UNKNOWN);
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ if (data != null || ((requestCode == RequestCodes.TAKE_PHOTO ||
+ requestCode == RequestCodes.TAKE_VIDEO))) {
+ Bundle extras;
+
+ switch (requestCode) {
+ case ACTIVITY_REQUEST_CODE_SELECT_CATEGORIES:
+ extras = data.getExtras();
+ if (extras != null && extras.containsKey("selectedCategories")) {
+ mCategories = (ArrayList<String>) extras.getSerializable("selectedCategories");
+ populateSelectedCategories();
+ }
+ break;
+ case MediaGalleryPickerActivity.REQUEST_CODE:
+ if (resultCode == Activity.RESULT_OK) {
+ ArrayList<String> ids = data.getStringArrayListExtra(MediaGalleryPickerActivity.RESULT_IDS);
+ if (ids == null || ids.size() == 0) {
+ return;
+ }
+
+ updateFeaturedImage(Long.parseLong(ids.get(0)));
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if (id == R.id.pubDate) {
+ showPostDateSelectionDialog();
+ } else if (id == R.id.selectCategories) {
+ Bundle bundle = new Bundle();
+ bundle.putInt("id", WordPress.getCurrentBlog().getLocalTableBlogId());
+ if (mCategories != null && mCategories.size() > 0) {
+ bundle.putSerializable("categories", new HashSet<String>(mCategories));
+ }
+ Intent categoriesIntent = new Intent(getActivity(), SelectCategoriesActivity.class);
+ categoriesIntent.putExtras(bundle);
+ startActivityForResult(categoriesIntent, ACTIVITY_REQUEST_CODE_SELECT_CATEGORIES);
+ } else if (id == R.id.categoryButton) {
+ onCategoryButtonClick(v);
+ } else if (id == R.id.locationText) {
+ viewLocation();
+ } else if (id == R.id.updateLocation) {
+ showLocationSearch();
+ } else if (id == R.id.removeLocation) {
+ removeLocation();
+ showLocationAdd();
+ } else if (id == R.id.addLocation) {
+ // Init Location settings when we switch to the fragment, that could trigger the opening of
+ // a dialog asking the user to enable the Geolocation permission (starting Android 6.+).
+ if (checkForLocationPermission()) {
+ showLocationSearch();
+ }
+ } else if (id == R.id.searchLocation) {
+ if (checkForLocationPermission()) {
+ searchLocation();
+ }
+ }
+ }
+
+ @Override
+ public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
+ boolean handled = false;
+ int id = view.getId();
+ if (id == R.id.searchLocationText && actionId == EditorInfo.IME_ACTION_SEARCH && checkForLocationPermission()) {
+ searchLocation();
+ handled = true;
+ }
+ return handled;
+ }
+
+ private void showPostDateSelectionDialog() {
+ final DatePicker datePicker = new DatePicker(getActivity());
+ datePicker.init(mYear, mMonth, mDay, null);
+ datePicker.setCalendarViewShown(false);
+
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.select_date)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mYear = datePicker.getYear();
+ mMonth = datePicker.getMonth();
+ mDay = datePicker.getDayOfMonth();
+ showPostTimeSelectionDialog();
+ }
+ })
+ .setNeutralButton(getResources().getText(R.string.immediately),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface,
+ int i) {
+ mIsCustomPubDate = true;
+ mPubDateText.setText(R.string.immediately);
+ updatePostSettingsAndSaveButton();
+ }
+ })
+ .setNegativeButton(android.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog,
+ int which) {
+ }
+ }
+ ).setView(datePicker).show();
+
+ }
+
+ private void showPostTimeSelectionDialog() {
+ final TimePicker timePicker = new TimePicker(getActivity());
+ timePicker.setIs24HourView(DateFormat.is24HourFormat(getActivity()));
+ timePicker.setCurrentHour(mHour);
+ timePicker.setCurrentMinute(mMinute);
+
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.select_time)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mHour = timePicker.getCurrentHour();
+ mMinute = timePicker.getCurrentMinute();
+
+ Date d = new Date(mYear - 1900, mMonth, mDay, mHour, mMinute);
+ long timestamp = d.getTime();
+
+ try {
+ int flags = 0;
+ flags |= DateUtils.FORMAT_SHOW_DATE;
+ flags |= DateUtils.FORMAT_ABBREV_MONTH;
+ flags |= DateUtils.FORMAT_SHOW_YEAR;
+ flags |= DateUtils.FORMAT_SHOW_TIME;
+ String formattedDate = DateUtils.formatDateTime(getActivity(), timestamp, flags);
+ mCustomPubDate = timestamp;
+ mPubDateText.setText(formattedDate);
+ mIsCustomPubDate = true;
+
+ updatePostSettingsAndSaveButton();
+ } catch (RuntimeException e) {
+ AppLog.e(T.POSTS, e);
+ }
+ }
+ })
+ .setNegativeButton(android.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog,
+ int which) {
+ }
+ }).setView(timePicker).show();
+ }
+
+ /**
+ * Updates post object with content of this fragment
+ */
+ public void updatePostSettings() {
+ if (!isAdded() || mPost == null) {
+ return;
+ }
+
+ String password = EditTextUtils.getText(mPasswordEditText);
+ String pubDate = EditTextUtils.getText(mPubDateText);
+ String excerpt = EditTextUtils.getText(mExcerptEditText);
+
+ long pubDateTimestamp = 0;
+ if (mIsCustomPubDate && pubDate.equals(getText(R.string.immediately)) && !mPost.isLocalDraft()) {
+ Date d = new Date();
+ pubDateTimestamp = d.getTime();
+ } else if (!pubDate.equals(getText(R.string.immediately))) {
+ if (mIsCustomPubDate)
+ pubDateTimestamp = mCustomPubDate;
+ else if (mPost.getDate_created_gmt() > 0)
+ pubDateTimestamp = mPost.getDate_created_gmt();
+ } else if (pubDate.equals(getText(R.string.immediately)) && mPost.isLocalDraft()) {
+ mPost.setDate_created_gmt(0);
+ mPost.setDateCreated(0);
+ }
+
+ String tags = "", postFormat = "";
+ if (!mPost.isPage()) {
+ tags = EditTextUtils.getText(mTagsEditText);
+
+ // post format
+ if (mPostFormats != null && mPostFormatSpinner != null &&
+ mPostFormatSpinner.getSelectedItemPosition() < mPostFormats.length) {
+ postFormat = mPostFormats[mPostFormatSpinner.getSelectedItemPosition()];
+ }
+ }
+
+ String status;
+ if (mStatusSpinner != null) {
+ status = getPostStatusForSpinnerPosition(mStatusSpinner.getSelectedItemPosition());
+ } else {
+ status = mPost.getPostStatus();
+ }
+
+ // We want to flag this post as having changed statuses from draft to published so that we
+ // properly track stats we care about for when users first publish posts.
+ if (!mPost.isLocalDraft() && mPost.getPostStatus().equals(PostStatus.toString(PostStatus.DRAFT))
+ && status.equals(PostStatus.toString(PostStatus.PUBLISHED))) {
+ mPost.setChangedFromDraftToPublished(true);
+ }
+
+ if (mPost.supportsLocation()) {
+ mPost.setLocation(mPostLocation);
+ }
+
+ if (mCategories != null) {
+ mPost.setJSONCategories(new JSONArray(mCategories));
+ }
+
+ if (AppPrefs.isVisualEditorEnabled()) {
+ mPost.setFeaturedImageId(mFeaturedImageId);
+ }
+
+ mPost.setPostExcerpt(excerpt);
+ mPost.setDate_created_gmt(pubDateTimestamp);
+ mPost.setKeywords(tags);
+ mPost.setPostStatus(status);
+ mPost.setPassword(password);
+ mPost.setPostFormat(postFormat);
+ }
+
+ /*
+ * Saves settings to post object and updates save button text in the ActionBar
+ */
+ private void updatePostSettingsAndSaveButton() {
+ if (isAdded()) {
+ updatePostSettings();
+ getActivity().invalidateOptionsMenu();
+ }
+ }
+
+ /**
+ * Location methods
+ */
+
+ /*
+ * retrieves and displays the friendly address for a lat/long location
+ */
+ private class GetAddressTask extends AsyncTask<Double, Void, Address> {
+ double latitude;
+ double longitude;
+
+ @Override
+ protected void onPreExecute() {
+ setLocationStatus(LocationStatus.SEARCHING);
+ showLocationView();
+ }
+
+ @Override
+ protected Address doInBackground(Double... args) {
+ // args will be the latitude, longitude to look up
+ latitude = args[0];
+ longitude = args[1];
+
+ return GeocoderUtils.getAddressFromCoords(getActivity(), latitude, longitude);
+ }
+
+ protected void onPostExecute(Address address) {
+ setLocationStatus(LocationStatus.FOUND);
+ if (address == null) {
+ // show lat/long when Geocoder fails (ugly, but better than not showing anything
+ // or showing an error since the location has been assigned to the post already)
+ updateLocationText(Double.toString(latitude) + ", " + Double.toString(longitude));
+ } else {
+ String locationName = GeocoderUtils.getLocationNameFromAddress(address);
+ updateLocationText(locationName);
+ }
+ }
+ }
+
+ private class GetCoordsTask extends AsyncTask<String, Void, Address> {
+ @Override
+ protected void onPreExecute() {
+ setLocationStatus(LocationStatus.SEARCHING);
+ showLocationView();
+ }
+
+ @Override
+ protected Address doInBackground(String... args) {
+ String locationName = args[0];
+
+ return GeocoderUtils.getAddressFromLocationName(getActivity(), locationName);
+ }
+
+ @Override
+ protected void onPostExecute(Address address) {
+ setLocationStatus(LocationStatus.FOUND);
+ showLocationView();
+
+ if (address != null) {
+ double[] coordinates = GeocoderUtils.getCoordsFromAddress(address);
+ setLocation(coordinates[0], coordinates[1]);
+
+ String locationName = GeocoderUtils.getLocationNameFromAddress(address);
+ updateLocationText(locationName);
+ } else {
+ showLocationNotAvailableError();
+ showLocationSearch();
+ }
+ }
+ }
+
+ private LocationHelper.LocationResult locationResult = new LocationHelper.LocationResult() {
+ @Override
+ public void gotLocation(final Location location) {
+ if (getActivity() == null)
+ return;
+ // note that location will be null when requesting location fails
+ getActivity().runOnUiThread(new Runnable() {
+ public void run() {
+ setLocation(location);
+ }
+ });
+ }
+ };
+
+ private View mLocationAddSection;
+ private View mLocationSearchSection;
+ private View mLocationViewSection;
+ private TextView mLocationText;
+ private EditText mLocationEditText;
+ private Button mButtonSearchLocation;
+
+ private TextWatcher mLocationEditTextWatcher = new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) { }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ String buttonText;
+ if (s.length() > 0) {
+ buttonText = getResources().getString(R.string.search_location);
+ } else {
+ buttonText = getResources().getString(R.string.search_current_location);
+ }
+ mButtonSearchLocation.setText(buttonText);
+ }
+ };
+
+ /*
+ * called when activity is created to initialize the location provider, show views related
+ * to location if enabled for this blog, and retrieve the current location if necessary
+ */
+ private void initLocation(ViewGroup rootView) {
+ if (!mPost.supportsLocation()) return;
+
+ // show the location views if a provider was found and this is a post on a blog that has location enabled
+ View locationRootView = ((ViewStub) rootView.findViewById(R.id.stub_post_location_settings)).inflate();
+
+ TextView locationLabel = ((TextView) locationRootView.findViewById(R.id.locationLabel));
+ locationLabel.setText(getResources().getString(R.string.location).toUpperCase());
+
+ mLocationText = (TextView) locationRootView.findViewById(R.id.locationText);
+ mLocationText.setOnClickListener(this);
+
+ mLocationAddSection = locationRootView.findViewById(R.id.sectionLocationAdd);
+ mLocationSearchSection = locationRootView.findViewById(R.id.sectionLocationSearch);
+ mLocationViewSection = locationRootView.findViewById(R.id.sectionLocationView);
+
+ Button addLocation = (Button) locationRootView.findViewById(R.id.addLocation);
+ addLocation.setOnClickListener(this);
+
+ mButtonSearchLocation = (Button) locationRootView.findViewById(R.id.searchLocation);
+ mButtonSearchLocation.setOnClickListener(this);
+
+ mLocationEditText = (EditText) locationRootView.findViewById(R.id.searchLocationText);
+ mLocationEditText.setOnEditorActionListener(this);
+ mLocationEditText.addTextChangedListener(mLocationEditTextWatcher);
+
+ Button updateLocation = (Button) locationRootView.findViewById(R.id.updateLocation);
+ Button removeLocation = (Button) locationRootView.findViewById(R.id.removeLocation);
+ updateLocation.setOnClickListener(this);
+ removeLocation.setOnClickListener(this);
+
+ // this is where we ask for location permission when EditPostActivity is oppened
+ if (SiteSettingsInterface.getGeotagging(getActivity()) && !checkForLocationPermission()) return;
+
+ // if this post has location attached to it, look up the location address
+ if (mPost.hasLocation()) {
+ showLocationView();
+ PostLocation location = mPost.getLocation();
+ setLocation(location.getLatitude(), location.getLongitude());
+ } else {
+ // Search for current location to geotag post if preferences allow
+ EditPostActivity activity = (EditPostActivity) getActivity();
+ if (SiteSettingsInterface.getGeotagging(activity) && activity.isNewPost()) {
+ searchLocation();
+ } else {
+ showLocationAdd();
+ }
+ }
+ }
+
+ private boolean checkForLocationPermission() {
+ return isAdded() && PermissionUtils.checkLocationPermissions(getActivity(),
+ EditPostActivity.LOCATION_PERMISSION_REQUEST_CODE);
+ }
+
+ public void showLocationSearch() {
+ mLocationAddSection.setVisibility(View.GONE);
+ mLocationSearchSection.setVisibility(View.VISIBLE);
+ mLocationViewSection.setVisibility(View.GONE);
+
+ EditTextUtils.showSoftInput(mLocationEditText);
+ }
+
+ private void showLocationAdd() {
+ mLocationAddSection.setVisibility(View.VISIBLE);
+ mLocationSearchSection.setVisibility(View.GONE);
+ mLocationViewSection.setVisibility(View.GONE);
+ }
+
+ private void showLocationView() {
+ mLocationAddSection.setVisibility(View.GONE);
+ mLocationSearchSection.setVisibility(View.GONE);
+ mLocationViewSection.setVisibility(View.VISIBLE);
+ }
+
+ public void searchLocation() {
+ if(!isAdded() || mLocationEditText == null) return;
+
+ EditTextUtils.hideSoftInput(mLocationEditText);
+ String location = EditTextUtils.getText(mLocationEditText);
+
+ removeLocation();
+
+ if (location.isEmpty()) {
+ fetchCurrentLocation();
+ } else {
+ new GetCoordsTask().execute(location);
+ }
+ }
+
+ /*
+ * get the current location
+ */
+ private void fetchCurrentLocation() {
+ if (!isAdded()) {
+ return;
+ }
+ if (mLocationHelper == null) {
+ mLocationHelper = new LocationHelper();
+ }
+ boolean canGetLocation = mLocationHelper.getLocation(getActivity(), locationResult);
+
+ if (canGetLocation) {
+ setLocationStatus(LocationStatus.SEARCHING);
+ showLocationView();
+ } else {
+ setLocation(null);
+ showLocationNotAvailableError();
+ showLocationAdd();
+ }
+ }
+
+ /*
+ * called when location is retrieved/updated for this post - looks up the address to
+ * display for the lat/long
+ */
+ private void setLocation(Location location) {
+ if (location != null) {
+ setLocation(location.getLatitude(), location.getLongitude());
+ } else {
+ updateLocationText(getString(R.string.location_not_found));
+ setLocationStatus(LocationStatus.NOT_FOUND);
+ }
+ }
+
+ private void setLocation(double latitude, double longitude) {
+ mPostLocation = new PostLocation(latitude, longitude);
+ new GetAddressTask().execute(mPostLocation.getLatitude(), mPostLocation.getLongitude());
+ }
+
+ private void removeLocation() {
+ mPostLocation = null;
+ mPost.unsetLocation();
+
+ updateLocationText("");
+ setLocationStatus(LocationStatus.NONE);
+ }
+
+ private void viewLocation() {
+ if (mPostLocation != null && mPostLocation.isValid()) {
+ String uri = "geo:" + mPostLocation.getLatitude() + "," + mPostLocation.getLongitude();
+ startActivity(new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(uri)));
+ } else {
+ showLocationNotAvailableError();
+ showLocationAdd();
+ }
+ }
+
+ private void showLocationNotAvailableError() {
+ if (!isAdded()) {
+ return;
+ }
+ Toast.makeText(getActivity(), getResources().getText(R.string.location_not_found), Toast.LENGTH_SHORT).show();
+ }
+
+ private void updateLocationText(String locationName) {
+ mLocationText.setText(locationName);
+ }
+
+ /*
+ * changes the left drawable on the location text to match the passed status
+ */
+ private void setLocationStatus(LocationStatus status) {
+ if (!isAdded()) {
+ return;
+ }
+
+ // animate location text when searching
+ if (status == LocationStatus.SEARCHING) {
+ updateLocationText(getString(R.string.loading));
+
+ Animation aniBlink = AnimationUtils.loadAnimation(getActivity(), R.anim.blink);
+ if (aniBlink != null) {
+ mLocationText.startAnimation(aniBlink);
+ }
+ } else {
+ mLocationText.clearAnimation();
+ }
+
+ final int drawableId;
+ switch (status) {
+ case FOUND:
+ drawableId = R.drawable.ic_action_location_found;
+ break;
+ case NOT_FOUND:
+ drawableId = R.drawable.ic_action_location_off;
+ break;
+ case SEARCHING:
+ drawableId = R.drawable.ic_action_location_searching;
+ break;
+ case NONE:
+ drawableId = 0;
+ break;
+ default:
+ return;
+ }
+
+ mLocationText.setCompoundDrawablesWithIntrinsicBounds(drawableId, 0, 0, 0);
+ }
+
+ /**
+ * Categories
+ */
+
+ private void onCategoryButtonClick(View v) {
+ if (mCategories == null) {
+ ToastUtils.showToast(getActivity(), R.string.error_generic);
+ return;
+ }
+
+ // Get category name by removing prefix from the tag
+ boolean listChanged = false;
+ String categoryName = (String) v.getTag();
+ categoryName = categoryName.replaceFirst(CATEGORY_PREFIX_TAG, "");
+
+ // Remove clicked category from list
+ for (int i = 0; i < mCategories.size(); i++) {
+ if (mCategories.get(i).equals(categoryName)) {
+ mCategories.remove(i);
+ listChanged = true;
+ break;
+ }
+ }
+
+ // Recreate category views
+ if (listChanged) {
+ populateSelectedCategories();
+ }
+ }
+
+ private void populateSelectedCategories() {
+ // Remove previous category buttons if any + select category button
+ List<View> viewsToRemove = new ArrayList<View>();
+ for (int i = 0; i < mSectionCategories.getChildCount(); i++) {
+ View v = mSectionCategories.getChildAt(i);
+ if (v == null)
+ return;
+ Object tag = v.getTag();
+ if (tag != null && tag.getClass() == String.class &&
+ (((String) tag).startsWith(CATEGORY_PREFIX_TAG) || tag.equals("select-category"))) {
+ viewsToRemove.add(v);
+ }
+ }
+ for (View viewToRemove : viewsToRemove) {
+ mSectionCategories.removeView(viewToRemove);
+ }
+ viewsToRemove.clear();
+
+ // New category buttons
+ LayoutInflater layoutInflater = getActivity().getLayoutInflater();
+
+ if (mCategories != null) {
+ for (String categoryName : mCategories) {
+ AppCompatButton buttonCategory = (AppCompatButton) layoutInflater.inflate(R.layout.category_button, null);
+ if (categoryName != null && buttonCategory != null) {
+ buttonCategory.setText(Html.fromHtml(categoryName));
+ buttonCategory.setTag(CATEGORY_PREFIX_TAG + categoryName);
+ buttonCategory.setOnClickListener(this);
+ mSectionCategories.addView(buttonCategory);
+ }
+ }
+ }
+
+ // Add select category button
+ Button selectCategory = (Button) layoutInflater.inflate(R.layout.category_select_button, null);
+ if (selectCategory != null) {
+ selectCategory.setOnClickListener(this);
+ mSectionCategories.addView(selectCategory);
+ }
+ }
+}