diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 95849bc66953..2c3e82b3c811 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -101,7 +101,8 @@
+ android:theme="@style/WordPress.Dialog"
+ android:windowSoftInputMode="stateVisible" />
- -
-
-
-
-
-
+ -
+
+
+
+
+
- -
-
-
-
-
-
- -
-
-
-
-
-
+ -
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/format_bar_bg_bottom.xml b/res/drawable/format_bar_bg_bottom.xml
new file mode 100644
index 000000000000..19e86a4f81e3
--- /dev/null
+++ b/res/drawable/format_bar_bg_bottom.xml
@@ -0,0 +1,15 @@
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/format_bar_btn.xml b/res/drawable/format_bar_btn.xml
index c3b2e6938107..3b28dee7fbea 100644
--- a/res/drawable/format_bar_btn.xml
+++ b/res/drawable/format_bar_btn.xml
@@ -7,8 +7,8 @@
android:top="4dp"
android:bottom="4dp"/>
-
+
\ No newline at end of file
diff --git a/res/drawable/format_bar_btn_toggled.xml b/res/drawable/format_bar_btn_toggled.xml
deleted file mode 100644
index 986e50787c46..000000000000
--- a/res/drawable/format_bar_btn_toggled.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- -
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/drawable/wp_button_toggle.xml b/res/drawable/wp_button_toggle.xml
index e75edad0a1b1..01f78e4e2914 100644
--- a/res/drawable/wp_button_toggle.xml
+++ b/res/drawable/wp_button_toggle.xml
@@ -3,8 +3,8 @@
xmlns:android="http://schemas.android.com/apk/res/android">
+ android:drawable="@android:color/transparent" />
+ android:drawable="@color/pressed_wordpress" />
\ No newline at end of file
diff --git a/res/layout/edit.xml b/res/layout/activity_edit_post.xml
similarity index 98%
rename from res/layout/edit.xml
rename to res/layout/activity_edit_post.xml
index 1d46c0e8b178..673865efe164 100644
--- a/res/layout/edit.xml
+++ b/res/layout/activity_edit_post.xml
@@ -29,6 +29,7 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
+ android:textSize="22sp"
android:hint="@string/title"
android:inputType="textCapSentences|textAutoCorrect" />
@@ -38,10 +39,13 @@
android:layout_height="wrap_content"
android:gravity="top"
android:hint="@string/post_content"
+ android:lineSpacingExtra="4dp"
+ android:textSize="18sp"
android:inputType="textMultiLine|textCapSentences|textAutoCorrect"
android:minLines="@integer/content_editor_min_lines"
android:paddingBottom="@dimen/content_edit_padding"
- android:textColorLink="#21759b" />
+ android:textColorLink="#21759b"
+ android:layerType="software" />
diff --git a/res/layout/fragment_edit_post_content.xml b/res/layout/fragment_edit_post_content.xml
new file mode 100644
index 000000000000..efe43033ccae
--- /dev/null
+++ b/res/layout/fragment_edit_post_content.xml
@@ -0,0 +1,159 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/fragment_edit_post_preview.xml b/res/layout/fragment_edit_post_preview.xml
new file mode 100644
index 000000000000..d2c316fe41be
--- /dev/null
+++ b/res/layout/fragment_edit_post_preview.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/fragment_edit_post_settings.xml b/res/layout/fragment_edit_post_settings.xml
new file mode 100644
index 000000000000..61e20cbb921f
--- /dev/null
+++ b/res/layout/fragment_edit_post_settings.xml
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/fragment_new_edit_post.xml b/res/layout/fragment_new_edit_post.xml
new file mode 100644
index 000000000000..e76752cc6e95
--- /dev/null
+++ b/res/layout/fragment_new_edit_post.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/res/layout/media_listitem_details.xml b/res/layout/media_listitem_details.xml
index 6c11433cafa9..01e047c3cea6 100644
--- a/res/layout/media_listitem_details.xml
+++ b/res/layout/media_listitem_details.xml
@@ -27,7 +27,6 @@
diff --git a/res/layout/viewpost.xml b/res/layout/viewpost.xml
index 847e200f8575..f11b6fbcbb49 100644
--- a/res/layout/viewpost.xml
+++ b/res/layout/viewpost.xml
@@ -10,7 +10,7 @@
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentTop="true"
- android:background="@drawable/format_bar_bg"
+ android:background="@drawable/format_bar_bg_bottom"
android:orientation="horizontal"
android:paddingBottom="6dp"
android:paddingTop="6dp" >
diff --git a/res/menu/edit.xml b/res/menu/edit_post.xml
similarity index 53%
rename from res/menu/edit.xml
rename to res/menu/edit_post.xml
index aa7648a0f62e..ad023698b20a 100644
--- a/res/menu/edit.xml
+++ b/res/menu/edit_post.xml
@@ -1,7 +1,12 @@
", "");
- content = content.replace("
", "
");
- // sometimes the editor creates extra tags
- content = content.replace("", "").replace("", "").replace("", "")
- .replace("", "").replace("", "");
- } else {
- content = mContentEditText.getText().toString();
- }
-
- long pubDateTimestamp = 0;
- if (!pubDate.equals(getResources().getText(R.string.immediately))) {
- if (mIsCustomPubDate)
- pubDateTimestamp = mCustomPubDate;
- else if (!mIsNew)
- pubDateTimestamp = mPost.getDate_created_gmt();
- }
-
- String tags = "", postFormat = "";
- if (!mIsPage) {
- tags = mTagsEditText.getText().toString();
- // post format
- Spinner postFormatSpinner = (Spinner) findViewById(R.id.postFormat);
- postFormat = mPostFormats[postFormatSpinner.getSelectedItemPosition()];
- }
-
- String images = "";
- boolean success = false;
-
- if (content.equals("") && !isAutoSave && !isDraftSave) {
- AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(EditPostActivity.this);
- dialogBuilder.setTitle(getResources().getText(R.string.empty_fields));
- dialogBuilder.setMessage(getResources().getText(R.string.title_post_required));
- dialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int whichButton) {
- dialog.dismiss();
- }
- });
- dialogBuilder.setCancelable(true);
- dialogBuilder.create().show();
- } else {
- if (!mIsNew) {
- // update the images
- mPost.deleteMediaFiles();
-
- Editable s = mContentEditText.getText();
-
- // Add gallery shortcode
- MediaGalleryImageSpan[] gallerySpans = s.getSpans(0, s.length(), MediaGalleryImageSpan.class);
- for (MediaGalleryImageSpan gallerySpan : gallerySpans) {
- int start = s.getSpanStart(gallerySpan);
- s.removeSpan(gallerySpan);
- s.insert(start, WPHtml.getGalleryShortcode(gallerySpan));
- }
-
- WPImageSpan[] imageSpans = s.getSpans(0, s.length(), WPImageSpan.class);
- if (imageSpans.length != 0) {
-
- for (int i = 0; i < imageSpans.length; i++) {
- WPImageSpan wpIS = imageSpans[i];
- images += wpIS.getImageSource().toString() + ",";
-
- if (wpIS.getMediaId() != null) {
- updateMediaFileOnServer(wpIS);
- } else {
- MediaFile mf = new MediaFile();
- mf.setBlogId(WordPress.getCurrentBlog().getBlogId() + "");
- mf.setPostID(mPost.getId());
- mf.setTitle(wpIS.getTitle());
- mf.setCaption(wpIS.getCaption());
- // mf.setDescription(wpIS.getDescription());
- mf.setFeatured(wpIS.isFeatured());
- mf.setFeaturedInPost(wpIS.isFeaturedInPost());
- mf.setFileName(wpIS.getImageSource().toString());
- mf.setFilePath(wpIS.getImageSource().toString());
- mf.setHorizontalAlignment(wpIS.getHorizontalAlignment());
- mf.setWidth(wpIS.getWidth());
- mf.setVideo(wpIS.isVideo());
- mf.save();
- }
-
- int tagStart = s.getSpanStart(wpIS);
- if (!isAutoSave) {
- s.removeSpan(wpIS);
-
- // network image has a mediaId
- if (wpIS.getMediaId() != null && wpIS.getMediaId().length() > 0) {
- s.insert(tagStart, WPHtml.getContent(wpIS));
-
- } else { // local image for upload
- s.insert(tagStart, "
");
- }
- }
- }
- }
-
- if (mLocalDraft)
- content = WPHtml.toHtml(s);
- else
- content = s.toString();
- } else {
-
- Editable s = mContentEditText.getText();
- WPImageSpan[] click_spans = s.getSpans(0, s.length(), WPImageSpan.class);
-
- // update the description, caption and title of media files on the server
- if (click_spans.length != 0) {
-
- for (int i = 0; i < click_spans.length; i++) {
- WPImageSpan wpIS = click_spans[i];
- images += wpIS.getImageSource().toString() + ",";
-
- if (wpIS.getMediaId() != null) {
- updateMediaFileOnServer(wpIS);
- }
-
- }
- }
- }
-
-
- final String moreTag = "";
- int selectedStatus = mStatusSpinner.getSelectedItemPosition();
- String status = "";
-
- switch (selectedStatus) {
+ public CharSequence getPageTitle(int position) {
+ Locale l = Locale.getDefault();
+ switch (position) {
case 0:
- status = "publish";
- break;
+ return "WRITE";
case 1:
- status = "draft";
- break;
+ return getString(R.string.settings).toUpperCase(l);
case 2:
- status = "pending";
- break;
- case 3:
- status = "private";
- break;
- }
-
- Double latitude = 0.0;
- Double longitude = 0.0;
- if (mBlog.isLocation()) {
-
- // attempt to get the device's location
- try {
- latitude = mCurrentLocation.getLatitude();
- longitude = mCurrentLocation.getLongitude();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- if (mIsNew) {
-
- JSONArray categorisList = JSONUtil.fromStringListToJSONArray(mCategories);
- mPost = new Post(mBlogID, title, content, excerpt, images, pubDateTimestamp, categorisList.toString(), tags, status, password,
- latitude, longitude, mIsPage, postFormat, true, false);
- mPost.setLocalDraft(true);
-
- // split up the post content if there's a more tag
- if (content.indexOf(moreTag) >= 0) {
- mPost.setDescription(content.substring(0, content.indexOf(moreTag)));
- mPost.setMt_text_more(content.substring(content.indexOf(moreTag) + moreTag.length(), content.length()));
- }
-
- success = mPost.save();
-
- if (success) {
- mIsNew = false;
- }
-
- mPost.deleteMediaFiles();
-
- Spannable s = mContentEditText.getText();
- WPImageSpan[] image_spans = s.getSpans(0, s.length(), WPImageSpan.class);
-
- if (image_spans.length != 0) {
-
- for (int i = 0; i < image_spans.length; i++) {
- WPImageSpan wpIS = image_spans[i];
- images += wpIS.getImageSource().toString() + ",";
-
- MediaFile mf = new MediaFile();
- mf.setBlogId(WordPress.getCurrentBlog().getBlogId() + "");
- mf.setPostID(mPost.getId());
- mf.setTitle(wpIS.getTitle());
- mf.setCaption(wpIS.getCaption());
- // mf.setDescription(wpIS.getDescription());
- mf.setFeatured(wpIS.isFeatured());
- mf.setFeaturedInPost(wpIS.isFeaturedInPost());
- mf.setFileName(wpIS.getImageSource().toString());
- mf.setFilePath(wpIS.getImageSource().toString());
- mf.setHorizontalAlignment(wpIS.getHorizontalAlignment());
- mf.setWidth(wpIS.getWidth());
- mf.setVideo(wpIS.isVideo());
- mf.save();
- }
- }
-
- WordPress.currentPost = mPost;
-
- } else {
-
- if (mCurrentLocation == null) {
- latitude = mPost.getLatitude();
- longitude = mPost.getLongitude();
- }
-
- mPost.setTitle(title);
- mPost.setMt_excerpt(excerpt);
- // split up the post content if there's a more tag
- if (mLocalDraft && content.indexOf(moreTag) >= 0) {
- mPost.setDescription(content.substring(0, content.indexOf(moreTag)));
- mPost.setMt_text_more(content.substring(content.indexOf(moreTag) + moreTag.length(), content.length()));
- } else {
- mPost.setDescription(content);
- mPost.setMt_text_more("");
- }
- mPost.setMediaPaths(images);
- mPost.setDate_created_gmt(pubDateTimestamp);
- mPost.setJSONCategories(new JSONArray(mCategories));
- mPost.setMt_keywords(tags);
- mPost.setPost_status(status);
- mPost.setWP_password(password);
- mPost.setLatitude(latitude);
- mPost.setLongitude(longitude);
- mPost.setWP_post_form(postFormat);
- if (!mPost.isLocalDraft())
- mPost.setLocalChange(true);
- success = mPost.update();
- }
- }
- return success;
- }
-
- private MediaFile getMediaFileFromWPImageSpan(WPImageSpan wpIS) {
- MediaFile mf = new MediaFile();
- mf.setMediaId(wpIS.getMediaId());
- if (mPost != null)
- mf.setPostID(mPost.getId());
- mf.setMIMEType(wpIS.getMimeType());
- mf.setHeight(wpIS.getHeight());
- mf.setFileName(wpIS.getFileName());
- mf.setTitle(wpIS.getTitle());
- mf.setCaption(wpIS.getCaption());
- mf.setDescription(wpIS.getDescription());
- mf.setFeatured(wpIS.isFeatured());
- mf.setFeaturedInPost(wpIS.isFeaturedInPost());
- mf.setHorizontalAlignment(wpIS.getHorizontalAlignment());
- mf.setWidth(wpIS.getWidth());
- mf.setBlogId(WordPress.getCurrentBlog().getBlogId() + "");
- mf.setDateCreatedGMT(wpIS.getDateCreatedGMT());
- mf.save();
- return mf;
- }
-
-
- private void updateMediaFileOnServer(WPImageSpan wpIS) {
-
- Blog currentBlog = WordPress.getCurrentBlog();
- if (currentBlog == null || wpIS == null)
- return;
-
- MediaFile mf = getMediaFileFromWPImageSpan(wpIS);
-
- final String mediaId = mf.getMediaId();
- final String title = mf.getTitle();
- final String description = mf.getDescription();
- final String caption = mf.getCaption();
-
- ApiHelper.EditMediaItemTask task = new ApiHelper.EditMediaItemTask(mf.getMediaId(), mf.getTitle(),
- mf.getDescription(), mf.getCaption(),
- new ApiHelper.EditMediaItemTask.Callback() {
-
- @Override
- public void onSuccess() {
- String blogId = String.valueOf(WordPress.getCurrentBlog().getBlogId());
- WordPress.wpDB.updateMediaFile(blogId, mediaId, title, description, caption);
- }
-
- @Override
- public void onFailure() {
- Toast.makeText(EditPostActivity.this, R.string.media_edit_failure, Toast.LENGTH_LONG).show();
- }
- });
-
- List
", "").replace("", "").replace("", "")
+ .replace("", "").replace("", "");
+ } else {
+ content = (mContentEditText.getText() != null) ? mContentEditText.getText().toString() : "";
+ }
+
+ String images = "";
+ // update the images
+ post.deleteMediaFiles();
+
+ Editable s = mContentEditText.getText();
+
+ if (!isAutoSave) {
+ // Add gallery shortcode
+ MediaGalleryImageSpan[] gallerySpans = s.getSpans(0, s.length(), MediaGalleryImageSpan.class);
+ for (MediaGalleryImageSpan gallerySpan : gallerySpans) {
+ int start = s.getSpanStart(gallerySpan);
+ s.removeSpan(gallerySpan);
+ s.insert(start, WPHtml.getGalleryShortcode(gallerySpan));
+ }
+ }
+
+ WPImageSpan[] imageSpans = s.getSpans(0, s.length(), WPImageSpan.class);
+ if (imageSpans.length != 0) {
+
+ for (WPImageSpan wpIS : imageSpans) {
+ images += wpIS.getImageSource().toString() + ",";
+
+ if (wpIS.getMediaId() != null) {
+ updateMediaFileOnServer(wpIS);
+ } else {
+ MediaFile mf = new MediaFile();
+ mf.setBlogId(WordPress.getCurrentBlog().getBlogId() + "");
+ mf.setPostID(post.getId());
+ mf.setTitle(wpIS.getTitle());
+ mf.setCaption(wpIS.getCaption());
+ // mf.setDescription(wpIS.getDescription());
+ mf.setFeatured(wpIS.isFeatured());
+ mf.setFeaturedInPost(wpIS.isFeaturedInPost());
+ mf.setFileName(wpIS.getImageSource().toString());
+ mf.setFilePath(wpIS.getImageSource().toString());
+ mf.setHorizontalAlignment(wpIS.getHorizontalAlignment());
+ mf.setWidth(wpIS.getWidth());
+ mf.setVideo(wpIS.isVideo());
+ mf.save();
+ }
+
+ int tagStart = s.getSpanStart(wpIS);
+ if (!isAutoSave) {
+ s.removeSpan(wpIS);
+
+ // network image has a mediaId
+ if (wpIS.getMediaId() != null && wpIS.getMediaId().length() > 0) {
+ s.insert(tagStart, WPHtml.getContent(wpIS));
+
+ } else { // local image for upload
+ s.insert(tagStart, "
");
+ }
+ }
+ }
+ }
+
+ String moreTag = "";
+
+ post.setTitle(title);
+ // split up the post content if there's a more tag
+ if (post.isLocalDraft() && content.contains(moreTag)) {
+ post.setDescription(content.substring(0, content.indexOf(moreTag)));
+ post.setMt_text_more(content.substring(content.indexOf(moreTag) + moreTag.length(), content.length()));
+ } else {
+ post.setDescription(content);
+ post.setMt_text_more("");
+ }
+ post.setMediaPaths(images);
+ if (!post.isLocalDraft())
+ post.setLocalChange(true);
+ post.update();
+ }
+
+ public boolean hasEmptyContentFields() {
+ return TextUtils.isEmpty(mTitleEditText.getText()) && TextUtils.isEmpty(mContentEditText.getText());
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ mFullViewBottom = mRootView.getBottom();
+ }
+
+ /**
+ * Media
+ */
+
+ private class processAttachmentsTask extends AsyncTask, Void, SpannableStringBuilder> {
+
+ protected void onPreExecute() {
+ Toast.makeText(getActivity(), R.string.loading, Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ protected SpannableStringBuilder doInBackground(List>... args) {
+ ArrayList> multi_stream = (ArrayList>) args[0].get(0);
+ String type = (String) args[0].get(1);
+ SpannableStringBuilder ssb = new SpannableStringBuilder();
+ for (Object streamUri : multi_stream) {
+ if (streamUri instanceof Uri) {
+ Uri imageUri = (Uri) streamUri;
+ if (type != null) {
+ addMedia(imageUri, ssb);
+ }
+ }
+ }
+ return ssb;
+ }
+
+ protected void onPostExecute(SpannableStringBuilder ssb) {
+ if (ssb != null) {
+ if (ssb.length() > 0) {
+ mContentEditText.setText(ssb);
+ }
+ } else {
+ Toast.makeText(getActivity(), getResources().getText(R.string.gallery_error), Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+
+ private void launchPictureLibrary() {
+ MediaUtils.launchPictureLibrary(this);
+ AppLockManager.getInstance().setExtendedTimeout();
+ }
+
+ private void launchCamera() {
+ MediaUtils.launchCamera(this, new MediaUtils.LaunchCameraCallback() {
+
+ @Override
+ public void onMediaCapturePathReady(String mediaCapturePath) {
+ mMediaCapturePath = mediaCapturePath;
+ AppLockManager.getInstance().setExtendedTimeout();
+ }
+ });
+ }
+
+ private void launchVideoLibrary() {
+ MediaUtils.launchVideoLibrary(this);
+ AppLockManager.getInstance().setExtendedTimeout();
+ }
+
+ private void launchVideoCamera() {
+ MediaUtils.launchVideoCamera(this);
+ AppLockManager.getInstance().setExtendedTimeout();
+ }
+
+ private void verifyImage(Uri imageUri) {
+ if (!MediaUtils.isLocalImage(imageUri)) {
+ // Create an AsyncTask to download the file
+ new DownloadImageTask().execute(imageUri);
+ } else {
+ // It is a regular local image file
+ if (!addMedia(imageUri, null))
+ Toast.makeText(getActivity(), getResources().getText(R.string.gallery_error), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private class DownloadImageTask extends AsyncTask {
+
+ @Override
+ protected Uri doInBackground(Uri... uris) {
+ Uri imageUri = uris[0];
+ return MediaUtils.downloadExternalImage(getActivity(), imageUri);
+ }
+
+ @Override
+ protected void onPreExecute() {
+ Toast.makeText(getActivity(), R.string.download, Toast.LENGTH_SHORT).show();
+ }
+
+ protected void onPostExecute(Uri newUri) {
+ //dismissDialog(ID_DIALOG_DOWNLOAD);
+ if (newUri != null)
+ addMedia(newUri, null);
+ else
+ Toast.makeText(getActivity(), getString(R.string.error_downloading_image), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void prepareMediaGallery() {
+ MediaGallery mediaGallery = new MediaGallery();
+ mediaGallery.setIds(getActivity().getIntent().getStringArrayListExtra(NEW_MEDIA_GALLERY_EXTRA_IDS));
+
+ startMediaGalleryActivity(mediaGallery);
+ }
+
+ private void prepareMediaPost() {
+ String mediaId = getActivity().getIntent().getStringExtra(NEW_MEDIA_POST_EXTRA);
+ addExistingMediaToEditor(mediaId);
+ }
+
+ private void addExistingMediaToEditor(String mediaId) {
+ if (WordPress.getCurrentBlog() == null)
+ return;
+
+ String blogId = String.valueOf(WordPress.getCurrentBlog().getBlogId());
+
+ WPImageSpan imageSpan = MediaUtils.prepareWPImageSpan(getActivity(), blogId, mediaId);
+ if (imageSpan == null)
+ return;
+
+ // based on addMedia()
+
+ int selectionStart = mContentEditText.getSelectionStart();
+ int selectionEnd = mContentEditText.getSelectionEnd();
+
+ if (selectionStart > selectionEnd) {
+ int temp = selectionEnd;
+ selectionEnd = selectionStart;
+ selectionStart = temp;
+ }
+
+ int line, column = 0;
+ if (mContentEditText.getLayout() != null) {
+ line = mContentEditText.getLayout().getLineForOffset(selectionStart);
+ column = mContentEditText.getSelectionStart() - mContentEditText.getLayout().getLineStart(line);
+ }
+
+ Editable s = mContentEditText.getText();
+ if (s != null) {
+ WPImageSpan[] gallerySpans = s.getSpans(selectionStart, selectionEnd, WPImageSpan.class);
+ if (gallerySpans.length != 0) {
+ // insert a few line breaks if the cursor is already on an image
+ s.insert(selectionEnd, "\n\n");
+ selectionStart = selectionStart + 2;
+ selectionEnd = selectionEnd + 2;
+ } else if (column != 0) {
+ // insert one line break if the cursor is not at the first column
+ s.insert(selectionEnd, "\n");
+ selectionStart = selectionStart + 1;
+ selectionEnd = selectionEnd + 1;
+ }
+
+ s.insert(selectionStart, " ");
+ s.setSpan(imageSpan, selectionStart, selectionEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ AlignmentSpan.Standard as = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER);
+ s.setSpan(as, selectionStart, selectionEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ s.insert(selectionEnd + 1, "\n\n");
+ try {
+ mContentEditText.setSelection(s.length());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // load image from server
+ loadWPImageSpanThumbnail(imageSpan);
+ }
+
+ private void updateMediaFileOnServer(WPImageSpan wpIS) {
+
+ Blog currentBlog = WordPress.getCurrentBlog();
+ if (currentBlog == null || wpIS == null)
+ return;
+
+ MediaFile mf = getMediaFileFromWPImageSpan(wpIS);
+
+ final String mediaId = mf.getMediaId();
+ final String title = mf.getTitle();
+ final String description = mf.getDescription();
+ final String caption = mf.getCaption();
+
+ ApiHelper.EditMediaItemTask task = new ApiHelper.EditMediaItemTask(mf.getMediaId(), mf.getTitle(),
+ mf.getDescription(), mf.getCaption(),
+ new ApiHelper.EditMediaItemTask.Callback() {
+
+ @Override
+ public void onSuccess() {
+ String blogId = String.valueOf(WordPress.getCurrentBlog().getBlogId());
+ WordPress.wpDB.updateMediaFile(blogId, mediaId, title, description, caption);
+ }
+
+ @Override
+ public void onFailure() {
+ Toast.makeText(getActivity(), R.string.media_edit_failure, Toast.LENGTH_LONG).show();
+ }
+ });
+
+ List apiArgs = new ArrayList();
+ apiArgs.add(currentBlog);
+ task.execute(apiArgs);
+ }
+
+ private MediaFile getMediaFileFromWPImageSpan(WPImageSpan wpIS) {
+ MediaFile mf = new MediaFile();
+ mf.setMediaId(wpIS.getMediaId());
+ if (mActivity.getPost() != null)
+ mf.setPostID(mActivity.getPost().getId());
+ mf.setMIMEType(wpIS.getMimeType());
+ mf.setHeight(wpIS.getHeight());
+ mf.setFileName(wpIS.getFileName());
+ mf.setTitle(wpIS.getTitle());
+ mf.setCaption(wpIS.getCaption());
+ mf.setDescription(wpIS.getDescription());
+ mf.setFeatured(wpIS.isFeatured());
+ mf.setFeaturedInPost(wpIS.isFeaturedInPost());
+ mf.setHorizontalAlignment(wpIS.getHorizontalAlignment());
+ mf.setWidth(wpIS.getWidth());
+ mf.setBlogId(WordPress.getCurrentBlog().getBlogId() + "");
+ mf.setDateCreatedGMT(wpIS.getDateCreatedGMT());
+ mf.save();
+ return mf;
+ }
+
+ /** Loads the thumbnail url in the imagespan from a server **/
+ private void loadWPImageSpanThumbnail(WPImageSpan imageSpan) {
+ final String mediaId = imageSpan.getMediaId();
+ String imageUrl = imageSpan.getThumbnailURL();
+ if (imageUrl == null || mediaId == null)
+ return;
+
+ if (WordPress.getCurrentBlog() != null && WordPress.getCurrentBlog().isPhotonCapable()) {
+ String photonUrl = imageSpan.getImageSource().toString();
+ imageUrl = StringUtils.getPhotonUrl(photonUrl, 400);
+ }
+
+ WordPress.imageLoader.get(imageUrl, new ImageLoader.ImageListener() {
+
+ @Override
+ public void onErrorResponse(VolleyError arg0) {
+
+ }
+
+ @Override
+ public void onResponse(ImageLoader.ImageContainer container, boolean arg1) {
+ if (container.getBitmap() != null) {
+
+ Bitmap bitmap = container.getBitmap();
+
+ ImageHelper ih = new ImageHelper();
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
+ byte[] bitmapByteArray = stream.toByteArray();
+ Bitmap resizedBitmap = ih.getResizedImageThumbnail(getActivity(), bitmapByteArray, null);
+ if (resizedBitmap == null)
+ return;
+ Editable s = mContentEditText.getText();
+ if (s == null)
+ return;
+ WPImageSpan[] spans = s.getSpans(0, s.length(), WPImageSpan.class);
+ if (spans.length != 0) {
+ for (WPImageSpan is : spans) {
+ if (mediaId.equals(is.getMediaId()) && !is.isNetworkImageLoaded()) {
+
+ // replace the existing span with a new one with the correct image, re-add it to the same position.
+ int spanStart = s.getSpanStart(is);
+ int spanEnd = s.getSpanEnd(is);
+ WPImageSpan imageSpan = new WPImageSpan(getActivity(), resizedBitmap, is.getImageSource());
+ imageSpan.setCaption(is.getCaption());
+ imageSpan.setDescription(is.getDescription());
+ imageSpan.setFeatured(is.isFeatured());
+ imageSpan.setFeaturedInPost(is.isFeaturedInPost());
+ imageSpan.setHeight(is.getHeight());
+ imageSpan.setHorizontalAlignment(is.getHorizontalAlignment());
+ imageSpan.setMediaId(is.getMediaId());
+ imageSpan.setMimeType(is.getMimeType());
+ imageSpan.setTitle(is.getTitle());
+ imageSpan.setVideo(is.isVideo());
+ imageSpan.setWidth(is.getWidth());
+ imageSpan.setFileName(is.getFileName());
+ imageSpan.setThumbnailURL(is.getThumbnailURL());
+ imageSpan.setDateCreatedGMT(is.getDateCreatedGMT());
+ imageSpan.setNetworkImageLoaded(true);
+ s.removeSpan(is);
+ s.setSpan(imageSpan, spanStart, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }, 0, 0);
+ }
+
+ private void startMediaGalleryActivity(MediaGallery mediaGallery) {
+ Intent intent = new Intent(getActivity(), MediaGalleryActivity.class);
+ intent.putExtra(MediaGalleryActivity.PARAMS_MEDIA_GALLERY, mediaGallery);
+ if (mediaGallery == null)
+ intent.putExtra(MediaGalleryActivity.PARAMS_LAUNCH_PICKER, true);
+ startActivityForResult(intent, MediaGalleryActivity.REQUEST_CODE);
+ }
+
+ private void startMediaGalleryAddActivity() {
+ Intent intent = new Intent(getActivity(), MediaGalleryPickerActivity.class);
+ intent.putExtra(MediaGalleryPickerActivity.PARAM_SELECT_ONE_ITEM, true);
+ startActivityForResult(intent, MediaGalleryPickerActivity.REQUEST_CODE);
+ }
+
+ private void handleMediaGalleryPickerResult(Intent data) {
+ ArrayList ids = data.getStringArrayListExtra(MediaGalleryPickerActivity.RESULT_IDS);
+ if (ids == null || ids.size() == 0)
+ return;
+
+ String mediaId = ids.get(0);
+ addExistingMediaToEditor(mediaId);
+ }
+
+ private void handleMediaGalleryResult(Intent data) {
+ MediaGallery gallery = (MediaGallery) data.getSerializableExtra(MediaGalleryActivity.RESULT_MEDIA_GALLERY);
+
+ // if blank gallery returned, don't add to span
+ if (gallery == null || gallery.getIds().size() == 0)
+ return;
+
+
+ int selectionStart = mContentEditText.getSelectionStart();
+ int selectionEnd = mContentEditText.getSelectionEnd();
+
+ if (selectionStart > selectionEnd) {
+ int temp = selectionEnd;
+ selectionEnd = selectionStart;
+ selectionStart = temp;
+ }
+
+ int line, column = 0;
+ if (mContentEditText.getLayout() != null) {
+ line = mContentEditText.getLayout().getLineForOffset(selectionStart);
+ column = mContentEditText.getSelectionStart() - mContentEditText.getLayout().getLineStart(line);
+ }
+
+ Editable s = mContentEditText.getText();
+ if (s == null)
+ return;
+ MediaGalleryImageSpan[] gallerySpans = s.getSpans(selectionStart, selectionEnd, MediaGalleryImageSpan.class);
+ if (gallerySpans.length != 0) {
+ for (MediaGalleryImageSpan gallerySpan : gallerySpans) {
+ if (gallerySpan.getMediaGallery().getUniqueId() == gallery.getUniqueId()) {
+ // replace the existing span with a new gallery, re-add it to the same position.
+ gallerySpan.setMediaGallery(gallery);
+ int spanStart = s.getSpanStart(gallerySpan);
+ int spanEnd = s.getSpanEnd(gallerySpan);
+ s.setSpan(gallerySpan, spanStart, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ }
+ return;
+ } else if (column != 0) {
+ // insert one line break if the cursor is not at the first column
+ s.insert(selectionEnd, "\n");
+ selectionStart = selectionStart + 1;
+ selectionEnd = selectionEnd + 1;
+ }
+
+ s.insert(selectionStart, " ");
+ MediaGalleryImageSpan is = new MediaGalleryImageSpan(getActivity(), gallery);
+ s.setSpan(is, selectionStart, selectionEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ AlignmentSpan.Standard as = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER);
+ s.setSpan(as, selectionStart, selectionEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ s.insert(selectionEnd + 1, "\n\n");
+ try {
+ mContentEditText.setSelection(s.length());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private boolean addMedia(Uri imageUri, SpannableStringBuilder ssb) {
+
+ if (ssb != null && !MediaUtils.isLocalImage(imageUri))
+ imageUri = MediaUtils.downloadExternalImage(getActivity(), imageUri);
+
+ if (imageUri == null) {
+ return false;
+ }
+
+ ImageHelper ih = new ImageHelper();
+ Map mediaData = ih.getImageBytesForPath(imageUri.getEncodedPath(), getActivity());
+
+ if (mediaData == null) {
+ // data stream not returned
+ return false;
+ }
+
+ Bitmap resizedBitmap = ih.getResizedImageThumbnail(getActivity(), (byte[]) mediaData.get("bytes"), (String) mediaData.get("orientation"));
+ if (resizedBitmap == null)
+ return false;
+
+ if (ssb != null) {
+ WPImageSpan is = new WPImageSpan(getActivity(), resizedBitmap, imageUri);
+
+ MediaUtils.setWPImageSpanWidth(getActivity(), imageUri, is);
+
+ is.setTitle((String) mediaData.get("title"));
+ is.setImageSource(imageUri);
+ if (imageUri.getEncodedPath() != null)
+ is.setVideo(imageUri.getEncodedPath().contains("video"));
+ ssb.append(" ");
+ ssb.setSpan(is, ssb.length() - 1, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ AlignmentSpan.Standard as = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER);
+ ssb.setSpan(as, ssb.length() - 1, ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ ssb.append("\n");
+ } else {
+ int selectionStart = mContentEditText.getSelectionStart();
+ mStyleStart = selectionStart;
+ int selectionEnd = mContentEditText.getSelectionEnd();
+
+ if (selectionStart > selectionEnd) {
+ int temp = selectionEnd;
+ selectionEnd = selectionStart;
+ selectionStart = temp;
+ }
+
+ Editable s = mContentEditText.getText();
+ if (s == null)
+ return false;
+ WPImageSpan is = new WPImageSpan(getActivity(), resizedBitmap, imageUri);
+
+ MediaUtils.setWPImageSpanWidth(getActivity(), imageUri, is);
+
+ is.setTitle((String) mediaData.get("title"));
+ is.setImageSource(imageUri);
+ if (imageUri.getEncodedPath() != null)
+ is.setVideo(imageUri.getEncodedPath().contains("video"));
+
+ int line, column = 0;
+ if (mContentEditText.getLayout() != null) {
+ line = mContentEditText.getLayout().getLineForOffset(selectionStart);
+ column = mContentEditText.getSelectionStart() - mContentEditText.getLayout().getLineStart(line);
+ }
+
+ WPImageSpan[] image_spans = s.getSpans(selectionStart, selectionEnd, WPImageSpan.class);
+ if (image_spans.length != 0) {
+ // insert a few line breaks if the cursor is already on an image
+ s.insert(selectionEnd, "\n\n");
+ selectionStart = selectionStart + 2;
+ selectionEnd = selectionEnd + 2;
+ } else if (column != 0) {
+ // insert one line break if the cursor is not at the first column
+ s.insert(selectionEnd, "\n");
+ selectionStart = selectionStart + 1;
+ selectionEnd = selectionEnd + 1;
+ }
+
+ s.insert(selectionStart, " ");
+ s.setSpan(is, selectionStart, selectionEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ AlignmentSpan.Standard as = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER);
+ s.setSpan(as, selectionStart, selectionEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ s.insert(selectionEnd + 1, "\n\n");
+ try {
+ mContentEditText.setSelection(s.length());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ // Show the soft keyboard after adding media
+ if (mActivity != null)
+ ((InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
+ }
+ return true;
+ }
+
+ /**
+ * Formatting bar
+ */
+
+ private View.OnClickListener mFormatBarButtonClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if (id == R.id.bold) {
+ onFormatButtonClick(mBoldToggleButton, TAG_FORMAT_BAR_BUTTON_STRONG);
+ trackFormatButtonClick(WPMobileStatsUtil.StatsPropertyPostDetailClickedKeyboardToolbarBoldButton);
+ } else if (id == R.id.em) {
+ onFormatButtonClick(mEmToggleButton, TAG_FORMAT_BAR_BUTTON_EM);
+ trackFormatButtonClick(WPMobileStatsUtil.StatsPropertyPostDetailClickedKeyboardToolbarItalicButton);
+ } else if (id == R.id.underline) {
+ onFormatButtonClick(mUnderlineToggleButton, TAG_FORMAT_BAR_BUTTON_UNDERLINE);
+ trackFormatButtonClick(WPMobileStatsUtil.StatsPropertyPostDetailClickedKeyboardToolbarUnderlineButton);
+ } else if (id == R.id.strike) {
+ onFormatButtonClick(mStrikeToggleButton, TAG_FORMAT_BAR_BUTTON_STRIKE);
+ trackFormatButtonClick(WPMobileStatsUtil.StatsPropertyPostDetailClickedKeyboardToolbarDelButton);
+ } else if (id == R.id.bquote) {
+ onFormatButtonClick(mBquoteToggleButton, TAG_FORMAT_BAR_BUTTON_QUOTE);
+ trackFormatButtonClick(WPMobileStatsUtil.StatsPropertyPostDetailClickedKeyboardToolbarBlockquoteButton);
+ } else if (id == R.id.more) {
+ mSelectionEnd = mContentEditText.getSelectionEnd();
+ Editable str = mContentEditText.getText();
+ if (str != null)
+ str.insert(mSelectionEnd, "\n\n");
+ trackFormatButtonClick(WPMobileStatsUtil.StatsPropertyPostDetailClickedKeyboardToolbarMoreButton);
+ } else if (id == R.id.link) {
+ mSelectionStart = mContentEditText.getSelectionStart();
+ mStyleStart = mSelectionStart;
+ mSelectionEnd = mContentEditText.getSelectionEnd();
+ if (mSelectionStart > mSelectionEnd) {
+ int temp = mSelectionEnd;
+ mSelectionEnd = mSelectionStart;
+ mSelectionStart = temp;
+ }
+ Intent i = new Intent(getActivity(), EditLinkActivity.class);
+ if (mSelectionEnd > mSelectionStart) {
+ if (mContentEditText.getText() != null) {
+ String selectedText = mContentEditText.getText().subSequence(mSelectionStart, mSelectionEnd).toString();
+ i.putExtra("selectedText", selectedText);
+ }
+ }
+ trackFormatButtonClick(WPMobileStatsUtil.StatsPropertyPostDetailClickedKeyboardToolbarLinkButton);
+ startActivityForResult(i, ACTIVITY_REQUEST_CODE_CREATE_LINK);
+ } else if (id == R.id.addPictureButton) {
+ mAddPictureButton.performLongClick();
+ trackFormatButtonClick(WPMobileStatsUtil.StatsPropertyPostDetailClickedKeyboardToolbarPictureButton);
+ }
+ }
+ };
+
+ public void trackFormatButtonClick(String statPropertyName) {
+ WPMobileStatsUtil.flagProperty(mActivity.getStatEventEditorClosed(), statPropertyName);
+ }
+
+ /**
+ * Applies formatting to selected text, or marks the entry for a new text style
+ * at the current cursor position
+ * @param toggleButton button from formatting bar
+ * @param tag HTML tag name for text style
+ */
+ private void onFormatButtonClick(ToggleButton toggleButton, String tag) {
+ Spannable s = mContentEditText.getText();
+ if (s == null)
+ return;
+ int selectionStart = mContentEditText.getSelectionStart();
+ mStyleStart = selectionStart;
+ int selectionEnd = mContentEditText.getSelectionEnd();
+
+ if (selectionStart > selectionEnd) {
+ int temp = selectionEnd;
+ selectionEnd = selectionStart;
+ selectionStart = temp;
+ }
+
+ Class styleClass = null;
+ if (tag.equals(TAG_FORMAT_BAR_BUTTON_STRONG) || tag.equals(TAG_FORMAT_BAR_BUTTON_EM))
+ styleClass = StyleSpan.class;
+ else if (tag.equals(TAG_FORMAT_BAR_BUTTON_UNDERLINE))
+ styleClass = WPUnderlineSpan.class;
+ else if (tag.equals(TAG_FORMAT_BAR_BUTTON_STRIKE))
+ styleClass = StrikethroughSpan.class;
+ else if (tag.equals(TAG_FORMAT_BAR_BUTTON_QUOTE))
+ styleClass = QuoteSpan.class;
+
+ if (styleClass == null)
+ return;
+
+ Object[] allSpans = s.getSpans(selectionStart, selectionEnd, styleClass);
+ boolean textIsSelected = selectionEnd > selectionStart;
+ if (mActivity.getPost().isLocalDraft()) {
+ // Local drafts can use the rich text editor. Yay!
+ boolean shouldAddSpan = true;
+ for (Object span : allSpans) {
+ if (span instanceof StyleSpan) {
+ StyleSpan styleSpan = (StyleSpan)span;
+ if ((styleSpan.getStyle() == Typeface.BOLD && !tag.equals(TAG_FORMAT_BAR_BUTTON_STRONG))
+ || (styleSpan.getStyle() == Typeface.ITALIC && !tag.equals(TAG_FORMAT_BAR_BUTTON_EM))) {
+ continue;
+ }
+ }
+ if (!toggleButton.isChecked() && textIsSelected) {
+ // If span exists and text is selected, remove the span
+ s.removeSpan(span);
+ shouldAddSpan = false;
+ break;
+ } else if (!toggleButton.isChecked()) {
+ // Remove span at cursor point if button isn't checked
+ Object[] spans = s.getSpans(mStyleStart - 1, mStyleStart, styleClass);
+ for (Object removeSpan : spans) {
+ selectionStart = s.getSpanStart(removeSpan);
+ selectionEnd = s.getSpanEnd(removeSpan);
+ s.removeSpan(removeSpan);
+ }
+ }
+ }
+
+ if (shouldAddSpan) {
+ if (tag.equals(TAG_FORMAT_BAR_BUTTON_STRONG)) {
+ s.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ } else if (tag.equals(TAG_FORMAT_BAR_BUTTON_EM)) {
+ s.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ } else {
+ try {
+ s.setSpan(styleClass.newInstance(), selectionStart, selectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ } catch (java.lang.InstantiationException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ } else {
+ // Add HTML tags when editing an existing post
+ String startTag = "<" + tag + ">";
+ String endTag = "" + tag + ">";
+ Editable content = mContentEditText.getText();
+ if (textIsSelected) {
+ content.insert(selectionStart, startTag);
+ content.insert(selectionEnd + startTag.length(), endTag);
+ toggleButton.setChecked(false);
+ mContentEditText.setSelection(selectionEnd + startTag.length() + endTag.length());
+ } else if (toggleButton.isChecked()) {
+ content.insert(selectionStart, startTag);
+ mContentEditText.setSelection(selectionEnd + startTag.length());
+ } else if (!toggleButton.isChecked()) {
+ content.insert(selectionEnd, endTag);
+ mContentEditText.setSelection(selectionEnd + endTag.length());
+ }
+ }
+ }
+
+ /**
+ * Rich Text Editor
+ */
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ float pos = event.getY();
+
+ if (event.getAction() == 0)
+ mLastYPos = pos;
+
+ if (event.getAction() > 1) {
+ if (((mLastYPos - pos) > 2.0f) || ((pos - mLastYPos) > 2.0f))
+ mScrollDetected = true;
+ }
+
+ mLastYPos = pos;
+
+ if (event.getAction() == MotionEvent.ACTION_UP) {
+ if (mActivity != null && mActivity.getSupportActionBar().isShowing()) {
+ setContentEditingModeVisible(true);
+ return false;
+ }
+ }
+
+ if (event.getAction() == MotionEvent.ACTION_UP && !mScrollDetected) {
+ Layout layout = ((TextView) v).getLayout();
+ int x = (int) event.getX();
+ int y = (int) event.getY();
+
+ x += v.getScrollX();
+ y += v.getScrollY();
+ if (layout != null) {
+ int line = layout.getLineForVertical(y);
+ int charPosition = layout.getOffsetForHorizontal(line, x);
+
+ final Spannable s = mContentEditText.getText();
+ if (s == null)
+ return false;
+ // check if image span was tapped
+ WPImageSpan[] image_spans = s.getSpans(charPosition, charPosition, WPImageSpan.class);
+
+ if (image_spans.length != 0) {
+ final WPImageSpan span = image_spans[0];
+ if (!span.isVideo()) {
+ LayoutInflater factory = LayoutInflater.from(getActivity());
+ final View alertView = factory.inflate(R.layout.alert_image_options, null);
+ if (alertView == null)
+ return false;
+ final EditText imageWidthText = (EditText) alertView.findViewById(R.id.imageWidthText);
+ final EditText titleText = (EditText) alertView.findViewById(R.id.title);
+ // final EditText descText = (EditText)
+ // alertView.findViewById(R.id.description);
+ final EditText caption = (EditText) alertView.findViewById(R.id.caption);
+ final CheckBox featuredCheckBox = (CheckBox) alertView.findViewById(R.id.featuredImage);
+ final CheckBox featuredInPostCheckBox = (CheckBox) alertView.findViewById(R.id.featuredInPost);
+
+ // show featured image checkboxes if theme support it
+ if (WordPress.getCurrentBlog().isFeaturedImageCapable()) {
+ featuredCheckBox.setVisibility(View.VISIBLE);
+ featuredInPostCheckBox.setVisibility(View.VISIBLE);
+ }
+
+ featuredCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ featuredInPostCheckBox.setVisibility(View.VISIBLE);
+ } else {
+ featuredInPostCheckBox.setVisibility(View.GONE);
+ }
+
+ }
+ });
+
+ final SeekBar seekBar = (SeekBar) alertView.findViewById(R.id.imageWidth);
+ final Spinner alignmentSpinner = (Spinner) alertView.findViewById(R.id.alignment_spinner);
+ ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(), R.array.alignment_array,
+ android.R.layout.simple_spinner_item);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ alignmentSpinner.setAdapter(adapter);
+
+ imageWidthText.setText(String.valueOf(span.getWidth()) + "px");
+ seekBar.setProgress(span.getWidth());
+ titleText.setText(span.getTitle());
+ // descText.setText(span.getDescription());
+ caption.setText(span.getCaption());
+ featuredCheckBox.setChecked(span.isFeatured());
+
+ if (span.isFeatured())
+ featuredInPostCheckBox.setVisibility(View.VISIBLE);
+ else
+ featuredInPostCheckBox.setVisibility(View.GONE);
+
+ featuredInPostCheckBox.setChecked(span.isFeaturedInPost());
+
+ alignmentSpinner.setSelection(span.getHorizontalAlignment(), true);
+
+ final int maxWidth = MediaUtils.getMinimumImageWitdh(getActivity(), span.getImageSource());
+ seekBar.setMax(maxWidth / 10);
+ if (span.getWidth() != 0)
+ seekBar.setProgress(span.getWidth() / 10);
+ seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (progress == 0)
+ progress = 1;
+ imageWidthText.setText(progress * 10 + "px");
+ }
+ });
+
+ imageWidthText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (hasFocus) {
+ imageWidthText.setText("");
+ }
+ }
+ });
+
+ imageWidthText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ int width = getEditTextIntegerClamped(imageWidthText, 10, maxWidth);
+ seekBar.setProgress(width / 10);
+ imageWidthText.setSelection((String.valueOf(width).length()));
+
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(imageWidthText.getWindowToken(),
+ InputMethodManager.RESULT_UNCHANGED_SHOWN);
+
+ return true;
+ }
+ });
+
+ AlertDialog ad = new AlertDialog.Builder(getActivity()).setTitle(getString(R.string.image_settings))
+ .setView(alertView).setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+
+ String title = (titleText.getText() != null) ? titleText.getText().toString() : "";
+ span.setTitle(title);
+ // span.setDescription(descText.getText().toString());
+ span.setHorizontalAlignment(alignmentSpinner.getSelectedItemPosition());
+ span.setWidth(getEditTextIntegerClamped(imageWidthText, 10, maxWidth));
+ String captionText = (caption.getText() != null) ? caption.getText().toString() : "";
+ span.setCaption(captionText);
+ span.setFeatured(featuredCheckBox.isChecked());
+ if (featuredCheckBox.isChecked()) {
+ // remove featured flag from all
+ // other images
+ WPImageSpan[] click_spans = s.getSpans(0, s.length(), WPImageSpan.class);
+ if (click_spans.length > 1) {
+ for (WPImageSpan verifySpan : click_spans) {
+ if (verifySpan != span) {
+ verifySpan.setFeatured(false);
+ verifySpan.setFeaturedInPost(false);
+ }
+ }
+ }
+ }
+ span.setFeaturedInPost(featuredInPostCheckBox.isChecked());
+ }
+ }).setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ dialog.dismiss();
+ }
+ }).create();
+ ad.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
+ ad.show();
+ mScrollDetected = false;
+ return true;
+ }
+
+ } else {
+ mContentEditText.setMovementMethod(ArrowKeyMovementMethod.getInstance());
+ int selectionStart = mContentEditText.getSelectionStart();
+ if (selectionStart >= 0 && mContentEditText.getSelectionEnd() >= selectionStart)
+ mContentEditText.setSelection(selectionStart, mContentEditText.getSelectionEnd());
+ }
+
+ // get media gallery spans
+
+ MediaGalleryImageSpan[] gallerySpans = s.getSpans(charPosition, charPosition, MediaGalleryImageSpan.class);
+ if (gallerySpans.length > 0) {
+ final MediaGalleryImageSpan gallerySpan = gallerySpans[0];
+ startMediaGalleryActivity(gallerySpan.getMediaGallery());
+ }
+
+ }
+ } else if (event.getAction() == 1) {
+ mScrollDetected = false;
+ }
+ return false;
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+
+ int position = Selection.getSelectionStart(mContentEditText.getText());
+ if ((mIsBackspace && position != 1) || mLastPosition == position || !mActivity.getPost().isLocalDraft())
+ return;
+
+ if (position < 0) {
+ position = 0;
+ }
+ mLastPosition = position;
+ if (position > 0) {
+
+ if (mStyleStart > position) {
+ mStyleStart = position - 1;
+ }
+
+ boolean shouldBold = mBoldToggleButton.isChecked();
+ boolean shouldEm = mEmToggleButton.isChecked();
+ boolean shouldUnderline = mUnderlineToggleButton.isChecked();
+ boolean shouldStrike = mStrikeToggleButton.isChecked();
+ boolean shouldQuote = mBquoteToggleButton.isChecked();
+
+ Object[] allSpans = s.getSpans(mStyleStart, position, Object.class);
+ for (Object span : allSpans) {
+ if (span instanceof StyleSpan) {
+ StyleSpan styleSpan = (StyleSpan) span;
+ if (styleSpan.getStyle() == Typeface.BOLD)
+ shouldBold = false;
+ else if (styleSpan.getStyle() == Typeface.ITALIC)
+ shouldEm = false;
+ } else if (span instanceof WPUnderlineSpan) {
+ shouldUnderline = false;
+ } else if (span instanceof StrikethroughSpan) {
+ shouldStrike = false;
+ } else if (span instanceof QuoteSpan) {
+ shouldQuote = false;
+ }
+ }
+
+ if (shouldBold)
+ s.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), mStyleStart, position, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ if (shouldEm)
+ s.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), mStyleStart, position, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ if (shouldUnderline)
+ s.setSpan(new WPUnderlineSpan(), mStyleStart, position, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ if (shouldStrike)
+ s.setSpan(new StrikethroughSpan(), mStyleStart, position, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ if (shouldQuote)
+ s.setSpan(new QuoteSpan(), mStyleStart, position, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ mIsBackspace = (count - after == 1) || (s.length() == 0);
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void onSelectionChanged() {
+ if (!mActivity.getPost().isLocalDraft())
+ return;
+
+ final Spannable s = mContentEditText.getText();
+ if (s == null)
+ return;
+ // set toggle buttons if cursor is inside of a matching span
+ mStyleStart = mContentEditText.getSelectionStart();
+ Object[] spans = s.getSpans(mContentEditText.getSelectionStart(), mContentEditText.getSelectionStart(), Object.class);
+
+ mBoldToggleButton.setChecked(false);
+ mEmToggleButton.setChecked(false);
+ mBquoteToggleButton.setChecked(false);
+ mUnderlineToggleButton.setChecked(false);
+ mStrikeToggleButton.setChecked(false);
+ for (Object span : spans) {
+ if (span instanceof StyleSpan) {
+ StyleSpan ss = (StyleSpan) span;
+ if (ss.getStyle() == android.graphics.Typeface.BOLD) {
+ mBoldToggleButton.setChecked(true);
+ }
+ if (ss.getStyle() == android.graphics.Typeface.ITALIC) {
+ mEmToggleButton.setChecked(true);
+ }
+ }
+ if (span instanceof QuoteSpan) {
+ mBquoteToggleButton.setChecked(true);
+ }
+ if (span instanceof WPUnderlineSpan) {
+ mUnderlineToggleButton.setChecked(true);
+ }
+ if (span instanceof StrikethroughSpan) {
+ mStrikeToggleButton.setChecked(true);
+ }
+ }
+ }
+
+ private int getEditTextIntegerClamped(EditText editText, int min, int max) {
+ int width = 10;
+ try {
+ if (editText.getText() != null)
+ width = Integer.parseInt(editText.getText().toString().replace("px", ""));
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ width = Math.min(max, Math.max(width, min));
+ return width;
+ }
+}
\ No newline at end of file
diff --git a/src/org/wordpress/android/ui/posts/EditPostPreviewFragment.java b/src/org/wordpress/android/ui/posts/EditPostPreviewFragment.java
new file mode 100644
index 000000000000..bf9600663379
--- /dev/null
+++ b/src/org/wordpress/android/ui/posts/EditPostPreviewFragment.java
@@ -0,0 +1,63 @@
+package org.wordpress.android.ui.posts;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebView;
+import android.widget.TextView;
+
+import com.actionbarsherlock.app.SherlockFragment;
+
+import org.wordpress.android.R;
+import org.wordpress.android.models.Post;
+import org.wordpress.android.util.StringUtils;
+import org.wordpress.android.util.WPHtml;
+
+/**
+ * Created by dan on 11/26/13.
+ */
+public class EditPostPreviewFragment extends SherlockFragment {
+
+ EditPostActivity mActivity;
+ WebView mWebView;
+ TextView mTextView;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mActivity = (EditPostActivity)getActivity();
+
+ ViewGroup rootView = (ViewGroup) inflater
+ .inflate(R.layout.fragment_edit_post_preview, container, false);
+ mWebView = (WebView) rootView.findViewById(R.id.post_preview_webview);
+ mTextView = (TextView) rootView.findViewById(R.id.post_preview_textview);
+
+ return rootView;
+ }
+
+ public void loadPost(Post post) {
+
+ // Don't load if the Post object of title are null, see #395
+ if (post == null || post.getTitle() == null)
+ return;
+
+ String postTitle = "" + post.getTitle() + "
";
+ String postContent = postTitle + post.getDescription() + "\n\n" + post.getMt_text_more();
+
+ if (post.isLocalDraft()) {
+ mTextView.setVisibility(View.VISIBLE);
+ mWebView.setVisibility(View.GONE);
+ mTextView.setText(WPHtml.fromHtml(postContent.replaceAll("\uFFFC", ""), getActivity().getBaseContext(), post));
+ } else {
+ mTextView.setVisibility(View.GONE);
+ mWebView.setVisibility(View.VISIBLE);
+
+ String htmlText = "%s
";
+ htmlText = String.format(htmlText, StringUtils.addPTags(postContent));
+ mWebView.loadDataWithBaseURL("file:///android_asset/", htmlText,
+ "text/html", "utf-8", null);
+ }
+
+ }
+}
diff --git a/src/org/wordpress/android/ui/posts/EditPostSettingsFragment.java b/src/org/wordpress/android/ui/posts/EditPostSettingsFragment.java
new file mode 100644
index 000000000000..ce7e2558839b
--- /dev/null
+++ b/src/org/wordpress/android/ui/posts/EditPostSettingsFragment.java
@@ -0,0 +1,733 @@
+package org.wordpress.android.ui.posts;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.DatePickerDialog;
+import android.app.TimePickerDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.location.Address;
+import android.location.Geocoder;
+import android.location.Location;
+import android.location.LocationManager;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.Html;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.DatePicker;
+import android.widget.EditText;
+import android.widget.RelativeLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.TimePicker;
+import android.widget.Toast;
+
+import com.actionbarsherlock.app.SherlockFragment;
+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.ui.media.MediaUtils;
+import org.wordpress.android.util.JSONUtil;
+import org.wordpress.android.util.LocationHelper;
+import org.wordpress.android.util.WPMobileStatsUtil;
+import org.xmlrpc.android.ApiHelper;
+
+import java.io.IOException;
+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.Locale;
+import java.util.Map;
+import java.util.Vector;
+
+/**
+ * Created by dan on 11/20/13.
+ */
+public class EditPostSettingsFragment extends SherlockFragment implements View.OnClickListener {
+
+ private static final int ACTIVITY_REQUEST_CODE_SELECT_CATEGORIES = 5;
+
+ private static final String CATEGORY_PREFIX_TAG = "category-";
+
+ private EditPostActivity mActivity;
+
+ private Spinner mStatusSpinner;
+ private EditText mPasswordEditText, mTagsEditText, mExcerptEditText;
+ private TextView mLocationText, mPubDateText;
+ private ViewGroup mSectionCategories;
+ private RelativeLayout mLocationRelativeLayout;
+
+ private ArrayList mCategories;
+
+ private Location mCurrentLocation;
+ private LocationHelper mLocationHelper;
+
+ private int mYear, mMonth, mDay, mHour, mMinute;
+ private long mCustomPubDate = 0;
+ private boolean mIsCustomPubDate;
+
+ private String[] mPostFormats;
+ private String[] mPostFormatTitles;
+
+ private static enum LocationStatus {NONE, FOUND, NOT_FOUND, SEARCHING}
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ 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();
+
+ ViewGroup rootView = (ViewGroup) inflater
+ .inflate(R.layout.fragment_edit_post_settings, container, false);
+
+ if (rootView == null)
+ return null;
+
+ mActivity = (EditPostActivity) getActivity();
+
+ mExcerptEditText = (EditText) rootView.findViewById(R.id.postExcerpt);
+ mPasswordEditText = (EditText) rootView.findViewById(R.id.post_password);
+ mLocationText = (TextView) rootView.findViewById(R.id.locationText);
+ Button mPubDateButton = (Button) rootView.findViewById(R.id.pubDateButton);
+ mPubDateText = (TextView) rootView.findViewById(R.id.pubDate);
+ mStatusSpinner = (Spinner) rootView.findViewById(R.id.status);
+ mTagsEditText = (EditText) rootView.findViewById(R.id.tags);
+ mSectionCategories = ((ViewGroup) rootView.findViewById(R.id.sectionCategories));
+
+ mPubDateButton.setOnClickListener(this);
+
+ // Set header labels to upper case
+ ((TextView) rootView.findViewById(R.id.categoryLabel)).setText(getResources().getString(R.string.categories).toUpperCase());
+ ((TextView) rootView.findViewById(R.id.statusLabel)).setText(getResources().getString(R.string.status).toUpperCase());
+ ((TextView) rootView.findViewById(R.id.postFormatLabel)).setText(getResources().getString(R.string.post_format).toUpperCase());
+ ((TextView) rootView.findViewById(R.id.pubDateLabel)).setText(getResources().getString(R.string.publish_date).toUpperCase());
+ ((TextView) rootView.findViewById(R.id.locationLabel)).setText(getResources().getString(R.string.location).toUpperCase());
+
+ if (mActivity.getPost().isPage()) { // remove post specific views
+ mExcerptEditText.setVisibility(View.GONE);
+ (rootView.findViewById(R.id.sectionTags)).setVisibility(View.GONE);
+ (rootView.findViewById(R.id.sectionCategories)).setVisibility(View.GONE);
+ (rootView.findViewById(R.id.sectionLocation)).setVisibility(View.GONE);
+ (rootView.findViewById(R.id.postFormatLabel)).setVisibility(View.GONE);
+ (rootView.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("")) {
+ List args = new Vector();
+ args.add(WordPress.getCurrentBlog());
+ args.add(mActivity);
+ new ApiHelper.getPostFormatsTask().execute(args);
+ } else {
+ try {
+ Gson gson = new Gson();
+ Type type = new TypeToken