| package org.wordpress.android.editor; |
| |
| import android.app.AlertDialog; |
| import android.content.Context; |
| import android.content.DialogInterface; |
| import android.content.Intent; |
| import android.content.res.Configuration; |
| import android.graphics.Bitmap; |
| import android.graphics.BitmapFactory; |
| import android.graphics.Typeface; |
| import android.net.Uri; |
| import android.os.AsyncTask; |
| import android.os.Bundle; |
| import android.os.Parcelable; |
| import android.support.v7.app.ActionBar; |
| import android.support.v7.app.AppCompatActivity; |
| import android.text.Editable; |
| import android.text.Layout; |
| import android.text.Selection; |
| import android.text.Spannable; |
| import android.text.Spanned; |
| import android.text.TextUtils; |
| import android.text.TextWatcher; |
| import android.text.method.ArrowKeyMovementMethod; |
| import android.text.style.AlignmentSpan; |
| import android.text.style.QuoteSpan; |
| import android.text.style.StrikethroughSpan; |
| import android.text.style.StyleSpan; |
| import android.text.style.URLSpan; |
| import android.view.KeyEvent; |
| import android.view.LayoutInflater; |
| import android.view.MotionEvent; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.view.ViewTreeObserver; |
| import android.view.WindowManager; |
| import android.view.animation.AlphaAnimation; |
| import android.view.animation.Animation; |
| import android.view.inputmethod.EditorInfo; |
| import android.view.inputmethod.InputMethodManager; |
| import android.webkit.URLUtil; |
| import android.widget.ArrayAdapter; |
| import android.widget.Button; |
| import android.widget.CheckBox; |
| import android.widget.CompoundButton; |
| import android.widget.EditText; |
| import android.widget.LinearLayout; |
| import android.widget.SeekBar; |
| import android.widget.Spinner; |
| import android.widget.TextView; |
| import android.widget.ToggleButton; |
| |
| import com.android.volley.VolleyError; |
| import com.android.volley.toolbox.ImageLoader; |
| |
| import org.wordpress.android.editor.legacy.EditLinkActivity; |
| import org.wordpress.android.editor.legacy.WPEditImageSpan; |
| import org.wordpress.android.util.AppLog; |
| import org.wordpress.android.util.AppLog.T; |
| import org.wordpress.android.util.DisplayUtils; |
| import org.wordpress.android.util.ImageUtils; |
| import org.wordpress.android.util.MediaUtils; |
| import org.wordpress.android.util.ToastUtils; |
| import org.wordpress.android.util.ToastUtils.Duration; |
| import org.wordpress.android.util.helpers.MediaFile; |
| import org.wordpress.android.util.helpers.MediaGallery; |
| import org.wordpress.android.util.helpers.MediaGalleryImageSpan; |
| import org.wordpress.android.util.helpers.WPImageSpan; |
| import org.wordpress.android.util.helpers.WPUnderlineSpan; |
| import org.wordpress.android.util.widgets.WPEditText; |
| |
| import java.util.Locale; |
| |
| public class LegacyEditorFragment extends EditorFragmentAbstract implements TextWatcher, |
| WPEditText.OnSelectionChangedListener, View.OnTouchListener { |
| public static final int ACTIVITY_REQUEST_CODE_CREATE_LINK = 4; |
| public static final String ACTION_MEDIA_GALLERY_TOUCHED = "MEDIA_GALLERY_TOUCHED"; |
| public static final String EXTRA_MEDIA_GALLERY = "EXTRA_MEDIA_GALLERY"; |
| |
| private static final int MIN_THUMBNAIL_WIDTH = 200; |
| private static final int CONTENT_ANIMATION_DURATION = 250; |
| private static final String KEY_IMAGE_SPANS = "image-spans"; |
| private static final String KEY_START = "start"; |
| private static final String KEY_END = "end"; |
| private static final String KEY_CONTENT = "content"; |
| private static final String TAG_FORMAT_BAR_BUTTON_STRONG = "strong"; |
| private static final String TAG_FORMAT_BAR_BUTTON_EM = "em"; |
| private static final String TAG_FORMAT_BAR_BUTTON_UNDERLINE = "u"; |
| private static final String TAG_FORMAT_BAR_BUTTON_STRIKE = "strike"; |
| private static final String TAG_FORMAT_BAR_BUTTON_QUOTE = "blockquote"; |
| |
| private View mRootView; |
| private WPEditText mContentEditText; |
| private EditText mTitleEditText; |
| private ToggleButton mBoldToggleButton, mEmToggleButton, mBquoteToggleButton; |
| private ToggleButton mUnderlineToggleButton, mStrikeToggleButton; |
| private LinearLayout mFormatBar, mPostContentLinearLayout, mPostSettingsLinearLayout; |
| private Button mAddPictureButton; |
| private boolean mIsBackspace; |
| private boolean mScrollDetected; |
| private boolean mIsLocalDraft; |
| |
| private int mStyleStart, mSelectionStart, mSelectionEnd, mFullViewBottom; |
| private int mLastPosition = -1; |
| private CharSequence mTitle; |
| private CharSequence mContent; |
| |
| private float mLastYPos = 0; |
| |
| @Override |
| public boolean onBackPressed() { |
| // leave full screen mode back button is pressed |
| if (getActionBar() != null && !getActionBar().isShowing()) { |
| setContentEditingModeVisible(false); |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public CharSequence getTitle() { |
| if (mTitleEditText != null) { |
| return mTitleEditText.getText().toString(); |
| } |
| return mTitle; |
| } |
| |
| @Override |
| public CharSequence getContent() { |
| if (mContentEditText != null) { |
| return mContentEditText.getText().toString(); |
| } |
| return mContent; |
| } |
| |
| @Override |
| public void setTitle(CharSequence text) { |
| mTitle = text; |
| if (mTitleEditText != null) { |
| mTitleEditText.setText(text); |
| } else { |
| // TODO |
| } |
| } |
| |
| @Override |
| public void setContent(CharSequence text) { |
| mContent = text; |
| if (mContentEditText != null) { |
| mContentEditText.setText(text); |
| mContentEditText.setSelection(mSelectionStart, mSelectionEnd); |
| } else { |
| // TODO |
| } |
| } |
| |
| @Override |
| public Spanned getSpannedContent() { |
| return mContentEditText.getText(); |
| } |
| |
| public void setLocalDraft(boolean isLocalDraft) { |
| mIsLocalDraft = isLocalDraft; |
| } |
| |
| @Override |
| public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { |
| final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_edit_post_content, container, false); |
| |
| mFormatBar = (LinearLayout) rootView.findViewById(R.id.format_bar); |
| mTitleEditText = (EditText) rootView.findViewById(R.id.post_title); |
| mTitleEditText.setText(mTitle); |
| mTitleEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { |
| @Override |
| public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { |
| // Go to full screen editor when 'next' button is tapped on soft keyboard |
| ActionBar actionBar = getActionBar(); |
| if (actionId == EditorInfo.IME_ACTION_NEXT && actionBar != null && actionBar.isShowing()) { |
| setContentEditingModeVisible(true); |
| } |
| return false; |
| } |
| }); |
| |
| mContentEditText = (WPEditText) rootView.findViewById(R.id.post_content); |
| mContentEditText.setText(mContent); |
| |
| mPostContentLinearLayout = (LinearLayout) rootView.findViewById(R.id.post_content_wrapper); |
| mPostSettingsLinearLayout = (LinearLayout) rootView.findViewById(R.id.post_settings_wrapper); |
| Button postSettingsButton = (Button) rootView.findViewById(R.id.post_settings_button); |
| postSettingsButton.setOnClickListener(new View.OnClickListener() { |
| @Override |
| public void onClick(View v) { |
| mEditorFragmentListener.onSettingsClicked(); |
| } |
| }); |
| mBoldToggleButton = (ToggleButton) rootView.findViewById(R.id.bold); |
| mEmToggleButton = (ToggleButton) rootView.findViewById(R.id.em); |
| mBquoteToggleButton = (ToggleButton) rootView.findViewById(R.id.bquote); |
| mUnderlineToggleButton = (ToggleButton) rootView.findViewById(R.id.underline); |
| mStrikeToggleButton = (ToggleButton) rootView.findViewById(R.id.strike); |
| mAddPictureButton = (Button) rootView.findViewById(R.id.addPictureButton); |
| Button linkButton = (Button) rootView.findViewById(R.id.link); |
| Button moreButton = (Button) rootView.findViewById(R.id.more); |
| |
| registerForContextMenu(mAddPictureButton); |
| mContentEditText = (WPEditText) rootView.findViewById(R.id.post_content); |
| mContentEditText.setOnSelectionChangedListener(this); |
| mContentEditText.setOnTouchListener(this); |
| mContentEditText.addTextChangedListener(this); |
| mContentEditText.setOnEditTextImeBackListener(new WPEditText.EditTextImeBackListener() { |
| @Override |
| public void onImeBack(WPEditText ctrl, String text) { |
| // Go back to regular editor if IME keyboard is dismissed |
| // Bottom comparison is there to ensure that the keyboard is actually showing |
| ActionBar actionBar = getActionBar(); |
| if (mRootView.getBottom() < mFullViewBottom && actionBar != null && !actionBar.isShowing()) { |
| setContentEditingModeVisible(false); |
| } |
| } |
| }); |
| mAddPictureButton.setOnClickListener(mFormatBarButtonClickListener); |
| mBoldToggleButton.setOnClickListener(mFormatBarButtonClickListener); |
| linkButton.setOnClickListener(mFormatBarButtonClickListener); |
| mEmToggleButton.setOnClickListener(mFormatBarButtonClickListener); |
| mUnderlineToggleButton.setOnClickListener(mFormatBarButtonClickListener); |
| mStrikeToggleButton.setOnClickListener(mFormatBarButtonClickListener); |
| mBquoteToggleButton.setOnClickListener(mFormatBarButtonClickListener); |
| moreButton.setOnClickListener(mFormatBarButtonClickListener); |
| mEditorFragmentListener.onEditorFragmentInitialized(); |
| |
| if (savedInstanceState != null) { |
| Parcelable[] spans = savedInstanceState.getParcelableArray(KEY_IMAGE_SPANS); |
| |
| mContent = savedInstanceState.getString(KEY_CONTENT, ""); |
| mContentEditText.setText(mContent); |
| mContentEditText.setSelection(savedInstanceState.getInt(KEY_START, 0), |
| savedInstanceState.getInt(KEY_END, 0)); |
| |
| if (spans != null && spans.length > 0) { |
| for (Parcelable s : spans) { |
| WPImageSpan editSpan = (WPImageSpan)s; |
| addMediaFile(editSpan.getMediaFile(), editSpan.getMediaFile().getFilePath(), |
| mImageLoader, editSpan.getStartPosition(), editSpan.getEndPosition()); |
| } |
| } |
| } |
| |
| return rootView; |
| } |
| |
| @Override |
| public void onViewCreated(View view, Bundle savedInstanceState) { |
| super.onViewCreated(view, savedInstanceState); |
| mRootView = view; |
| mRootView.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener); |
| } |
| |
| private ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { |
| public void onGlobalLayout() { |
| mRootView.getViewTreeObserver().removeGlobalOnLayoutListener(this); |
| mFullViewBottom = mRootView.getBottom(); |
| } |
| }; |
| |
| private ActionBar getActionBar() { |
| if (!isAdded()) { |
| return null; |
| } |
| if (getActivity() instanceof AppCompatActivity) { |
| return ((AppCompatActivity) getActivity()).getSupportActionBar(); |
| } else { |
| return null; |
| } |
| } |
| |
| public void setContentEditingModeVisible(boolean isVisible) { |
| if (!isAdded()) { |
| return; |
| } |
| ActionBar actionBar = getActionBar(); |
| if (isVisible) { |
| Animation fadeAnimation = new AlphaAnimation(1, 0); |
| fadeAnimation.setDuration(CONTENT_ANIMATION_DURATION); |
| fadeAnimation.setAnimationListener(new Animation.AnimationListener() { |
| @Override |
| public void onAnimationStart(Animation animation) { |
| mTitleEditText.setVisibility(View.GONE); |
| } |
| |
| @Override |
| public void onAnimationEnd(Animation animation) { |
| mPostSettingsLinearLayout.setVisibility(View.GONE); |
| mFormatBar.setVisibility(View.VISIBLE); |
| } |
| |
| @Override |
| public void onAnimationRepeat(Animation animation) { |
| } |
| }); |
| |
| mPostContentLinearLayout.startAnimation(fadeAnimation); |
| if (actionBar != null) { |
| actionBar.hide(); |
| } |
| } else { |
| mTitleEditText.setVisibility(View.VISIBLE); |
| mFormatBar.setVisibility(View.GONE); |
| Animation fadeAnimation = new AlphaAnimation(0, 1); |
| fadeAnimation.setDuration(CONTENT_ANIMATION_DURATION); |
| fadeAnimation.setAnimationListener(new Animation.AnimationListener() { |
| @Override |
| public void onAnimationStart(Animation animation) { |
| } |
| |
| @Override |
| public void onAnimationEnd(Animation animation) { |
| mPostSettingsLinearLayout.setVisibility(View.VISIBLE); |
| } |
| |
| @Override |
| public void onAnimationRepeat(Animation animation) { |
| } |
| }); |
| mPostContentLinearLayout.startAnimation(fadeAnimation); |
| getActivity().invalidateOptionsMenu(); |
| if (actionBar != null) { |
| actionBar.show(); |
| } |
| } |
| } |
| |
| @Override |
| public void onActivityResult(int requestCode, int resultCode, Intent data) { |
| super.onActivityResult(requestCode, resultCode, data); |
| |
| if (requestCode == LegacyEditorFragment.ACTIVITY_REQUEST_CODE_CREATE_LINK && data != null) { |
| Bundle extras = data.getExtras(); |
| if (extras == null) { |
| return; |
| } |
| String linkURL = extras.getString("linkURL"); |
| String linkText = extras.getString("linkText"); |
| createLinkFromSelection(linkURL, linkText); |
| } |
| } |
| |
| public boolean hasEmptyContentFields() { |
| return TextUtils.isEmpty(mTitleEditText.getText()) && TextUtils.isEmpty(mContentEditText.getText()); |
| } |
| |
| @Override |
| public void onConfigurationChanged(Configuration newConfig) { |
| super.onConfigurationChanged(newConfig); |
| mFullViewBottom = mRootView.getBottom(); |
| } |
| |
| private void createLinkFromSelection(String linkURL, String linkText) { |
| try { |
| if (linkURL != null && !linkURL.equals("http://") && !linkURL.equals("")) { |
| if (mSelectionStart > mSelectionEnd) { |
| int temp = mSelectionEnd; |
| mSelectionEnd = mSelectionStart; |
| mSelectionStart = temp; |
| } |
| Editable editable = mContentEditText.getText(); |
| if (editable == null) { |
| return; |
| } |
| if (mIsLocalDraft) { |
| if (linkText == null) { |
| if (mSelectionStart < mSelectionEnd) { |
| editable.delete(mSelectionStart, mSelectionEnd); |
| } |
| editable.insert(mSelectionStart, linkURL); |
| editable.setSpan(new URLSpan(linkURL), mSelectionStart, mSelectionStart + linkURL.length(), |
| Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); |
| mContentEditText.setSelection(mSelectionStart + linkURL.length()); |
| } else { |
| if (mSelectionStart < mSelectionEnd) { |
| editable.delete(mSelectionStart, mSelectionEnd); |
| } |
| editable.insert(mSelectionStart, linkText); |
| editable.setSpan(new URLSpan(linkURL), mSelectionStart, mSelectionStart + linkText.length(), |
| Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); |
| mContentEditText.setSelection(mSelectionStart + linkText.length()); |
| } |
| } else { |
| if (linkText == null) { |
| if (mSelectionStart < mSelectionEnd) { |
| editable.delete(mSelectionStart, mSelectionEnd); |
| } |
| String urlHTML = "<a href=\"" + linkURL + "\">" + linkURL + "</a>"; |
| editable.insert(mSelectionStart, urlHTML); |
| mContentEditText.setSelection(mSelectionStart + urlHTML.length()); |
| } else { |
| if (mSelectionStart < mSelectionEnd) { |
| editable.delete(mSelectionStart, mSelectionEnd); |
| } |
| String urlHTML = "<a href=\"" + linkURL + "\">" + linkText + "</a>"; |
| editable.insert(mSelectionStart, urlHTML); |
| mContentEditText.setSelection(mSelectionStart + urlHTML.length()); |
| } |
| } |
| } |
| } catch (RuntimeException e) { |
| AppLog.e(T.POSTS, e); |
| } |
| } |
| |
| /** |
| * Formatting bar |
| */ |
| private View.OnClickListener mFormatBarButtonClickListener = new View.OnClickListener() { |
| @Override |
| public void onClick(View v) { |
| int id = v.getId(); |
| if (id == R.id.bold) { |
| mEditorFragmentListener.onTrackableEvent(TrackableEvent.BOLD_BUTTON_TAPPED); |
| onFormatButtonClick(mBoldToggleButton, TAG_FORMAT_BAR_BUTTON_STRONG); |
| } else if (id == R.id.em) { |
| mEditorFragmentListener.onTrackableEvent(TrackableEvent.ITALIC_BUTTON_TAPPED); |
| onFormatButtonClick(mEmToggleButton, TAG_FORMAT_BAR_BUTTON_EM); |
| } else if (id == R.id.underline) { |
| mEditorFragmentListener.onTrackableEvent(TrackableEvent.UNDERLINE_BUTTON_TAPPED); |
| onFormatButtonClick(mUnderlineToggleButton, TAG_FORMAT_BAR_BUTTON_UNDERLINE); |
| } else if (id == R.id.strike) { |
| mEditorFragmentListener.onTrackableEvent(TrackableEvent.STRIKETHROUGH_BUTTON_TAPPED); |
| onFormatButtonClick(mStrikeToggleButton, TAG_FORMAT_BAR_BUTTON_STRIKE); |
| } else if (id == R.id.bquote) { |
| mEditorFragmentListener.onTrackableEvent(TrackableEvent.BLOCKQUOTE_BUTTON_TAPPED); |
| onFormatButtonClick(mBquoteToggleButton, TAG_FORMAT_BAR_BUTTON_QUOTE); |
| } else if (id == R.id.more) { |
| mEditorFragmentListener.onTrackableEvent(TrackableEvent.MORE_BUTTON_TAPPED); |
| mSelectionEnd = mContentEditText.getSelectionEnd(); |
| Editable str = mContentEditText.getText(); |
| if (str != null) { |
| if (mSelectionEnd > str.length()) |
| mSelectionEnd = str.length(); |
| str.insert(mSelectionEnd, "\n<!--more-->\n"); |
| } |
| } else if (id == R.id.link) { |
| mEditorFragmentListener.onTrackableEvent(TrackableEvent.LINK_BUTTON_TAPPED); |
| 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); |
| } |
| } |
| startActivityForResult(i, ACTIVITY_REQUEST_CODE_CREATE_LINK); |
| } else if (id == R.id.addPictureButton) { |
| mEditorFragmentListener.onTrackableEvent(TrackableEvent.MEDIA_BUTTON_TAPPED); |
| mEditorFragmentListener.onAddMediaClicked(); |
| if (isAdded()) { |
| getActivity().openContextMenu(mAddPictureButton); |
| } |
| } |
| } |
| }; |
| |
| private WPEditImageSpan createWPEditImageSpanLocal(Context context, MediaFile mediaFile) { |
| if (context == null || mediaFile == null || mediaFile.getFilePath() == null) { |
| return null; |
| } |
| Uri imageUri = Uri.parse(mediaFile.getFilePath()); |
| Bitmap thumbnailBitmap; |
| if (MediaUtils.isVideo(imageUri.toString())) { |
| thumbnailBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.media_movieclip); |
| } else { |
| thumbnailBitmap = ImageUtils.getWPImageSpanThumbnailFromFilePath(context, imageUri.getEncodedPath(), |
| ImageUtils.getMaximumThumbnailWidthForEditor(context)); |
| if (thumbnailBitmap == null) { |
| // Use a placeholder in case thumbnail can't be decoded (OOM for instance) |
| thumbnailBitmap = BitmapFactory.decodeResource(context.getResources(), |
| R.drawable.legacy_dashicon_format_image_big_grey); |
| } |
| } |
| WPEditImageSpan imageSpan = new WPEditImageSpan(context, thumbnailBitmap, imageUri); |
| mediaFile.setWidth(MediaUtils.getMaximumImageWidth(context, imageUri, mBlogSettingMaxImageWidth)); |
| imageSpan.setMediaFile(mediaFile); |
| return imageSpan; |
| } |
| |
| private WPEditImageSpan createWPEditImageSpanRemote(Context context, MediaFile mediaFile) { |
| if (context == null || mediaFile == null || mediaFile.getFileURL() == null) { |
| return null; |
| } |
| int drawable = mediaFile.isVideo() ? R.drawable.media_movieclip : R.drawable.legacy_dashicon_format_image_big_grey; |
| Uri uri = Uri.parse(mediaFile.getFileURL()); |
| WPEditImageSpan imageSpan = new WPEditImageSpan(context, drawable, uri); |
| imageSpan.setMediaFile(mediaFile); |
| return imageSpan; |
| } |
| |
| private WPEditImageSpan createWPEditImageSpan(Context context, MediaFile mediaFile) { |
| if (!URLUtil.isNetworkUrl(mediaFile.getFileURL())) { |
| return createWPEditImageSpanLocal(context, mediaFile); |
| } else { |
| return createWPEditImageSpanRemote(context, mediaFile); |
| } |
| } |
| |
| /** |
| * 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 (mIsLocalDraft) { |
| // 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) { |
| AppLog.e(T.POSTS, e); |
| } catch (IllegalAccessException e) { |
| AppLog.e(T.POSTS, e); |
| } |
| } |
| } |
| } 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 |
| */ |
| public void showImageSettings(final View alertView, final EditText titleText, |
| final EditText caption, final EditText imageWidthText, |
| final CheckBox featuredCheckBox, final CheckBox featuredInPostCheckBox, |
| final int maxWidth, final Spinner alignmentSpinner, final WPImageSpan imageSpan) { |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| builder.setTitle(getString(R.string.image_settings)); |
| builder.setView(alertView); |
| builder.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int whichButton) { |
| String title = (titleText.getText() != null) ? titleText.getText().toString() : ""; |
| MediaFile mediaFile = imageSpan.getMediaFile(); |
| if (mediaFile == null) { |
| return; |
| } |
| mediaFile.setTitle(title); |
| mediaFile.setHorizontalAlignment(alignmentSpinner.getSelectedItemPosition()); |
| mediaFile.setWidth(getEditTextIntegerClamped(imageWidthText, 10, maxWidth)); |
| String captionText = (caption.getText() != null) ? caption.getText().toString() : ""; |
| mediaFile.setCaption(captionText); |
| mediaFile.setFeatured(featuredCheckBox.isChecked()); |
| if (featuredCheckBox.isChecked()) { |
| // remove featured flag from all other images |
| Spannable contentSpannable = mContentEditText.getText(); |
| WPImageSpan[] imageSpans = |
| contentSpannable.getSpans(0, contentSpannable.length(), WPImageSpan.class); |
| if (imageSpans.length > 1) { |
| for (WPImageSpan postImageSpan : imageSpans) { |
| if (postImageSpan != imageSpan) { |
| MediaFile postMediaFile = postImageSpan.getMediaFile(); |
| postMediaFile.setFeatured(false); |
| postMediaFile.setFeaturedInPost(false); |
| // TODO: remove this |
| mEditorFragmentListener.saveMediaFile(postMediaFile); |
| } |
| } |
| } |
| } |
| mediaFile.setFeaturedInPost(featuredInPostCheckBox.isChecked()); |
| // TODO: remove this |
| mEditorFragmentListener.saveMediaFile(mediaFile); |
| } |
| }); |
| builder.setNegativeButton(getString(android.R.string.cancel), new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int whichButton) { |
| dialog.dismiss(); |
| } |
| }); |
| AlertDialog alertDialog = builder.create(); |
| alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); |
| alertDialog.show(); |
| } |
| |
| @Override |
| public boolean onTouch(View v, MotionEvent event) { |
| float pos = event.getY(); |
| |
| if (event.getAction() == 0) |
| mLastYPos = pos; |
| |
| if (event.getAction() > 1) { |
| int scrollThreshold = DisplayUtils.dpToPx(getActivity(), 2); |
| if (((mLastYPos - pos) > scrollThreshold) || ((pos - mLastYPos) > scrollThreshold)) |
| mScrollDetected = true; |
| } |
| |
| mLastYPos = pos; |
| |
| if (event.getAction() == MotionEvent.ACTION_UP) { |
| ActionBar actionBar = getActionBar(); |
| if (actionBar != null && actionBar.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); |
| |
| Spannable spannable = mContentEditText.getText(); |
| if (spannable == null) { |
| return false; |
| } |
| // check if image span was tapped |
| WPImageSpan[] imageSpans = spannable.getSpans(charPosition, charPosition, WPImageSpan.class); |
| |
| if (imageSpans.length != 0) { |
| final WPImageSpan imageSpan = imageSpans[0]; |
| MediaFile mediaFile = imageSpan.getMediaFile(); |
| if (mediaFile == null) |
| return false; |
| if (!mediaFile.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 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 supported |
| if (mFeaturedImageSupported) { |
| 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<CharSequence> 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); |
| |
| seekBar.setProgress(mediaFile.getWidth()); |
| titleText.setText(mediaFile.getTitle()); |
| caption.setText(mediaFile.getCaption()); |
| featuredCheckBox.setChecked(mediaFile.isFeatured()); |
| |
| if (mediaFile.isFeatured()) { |
| featuredInPostCheckBox.setVisibility(View.VISIBLE); |
| } else { |
| featuredInPostCheckBox.setVisibility(View.GONE); |
| } |
| |
| featuredInPostCheckBox.setChecked(mediaFile.isFeaturedInPost()); |
| |
| alignmentSpinner.setSelection(mediaFile.getHorizontalAlignment(), true); |
| |
| final int maxWidth = MediaUtils.getMaximumImageWidth(getActivity(), |
| imageSpan.getImageSource(), mBlogSettingMaxImageWidth); |
| seekBar.setMax(maxWidth / 10); |
| imageWidthText.setText(String.format(Locale.US, "%dpx", maxWidth)); |
| if (mediaFile.getWidth() != 0) { |
| seekBar.setProgress(mediaFile.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(String.format(Locale.US, "%dpx", progress * 10)); |
| } |
| }); |
| |
| 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; |
| } |
| }); |
| |
| showImageSettings(alertView, titleText, caption, imageWidthText, featuredCheckBox, |
| featuredInPostCheckBox, maxWidth, alignmentSpinner, imageSpan); |
| 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 = spannable.getSpans(charPosition, charPosition, MediaGalleryImageSpan.class); |
| if (gallerySpans.length > 0) { |
| final MediaGalleryImageSpan gallerySpan = gallerySpans[0]; |
| Intent intent = new Intent(ACTION_MEDIA_GALLERY_TOUCHED); |
| intent.putExtra(EXTRA_MEDIA_GALLERY, gallerySpan.getMediaGallery()); |
| getActivity().sendBroadcast(intent); |
| } |
| } |
| } 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 || !mIsLocalDraft) |
| 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 (!mIsLocalDraft) { |
| 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) { |
| AppLog.e(T.POSTS, e); |
| } |
| width = Math.min(max, Math.max(width, min)); |
| return width; |
| } |
| |
| private void loadWPImageSpanThumbnail(MediaFile mediaFile, String imageURL, ImageLoader imageLoader) { |
| if (mediaFile == null || imageURL == null) { |
| return; |
| } |
| final String mediaId = mediaFile.getMediaId(); |
| if (mediaId == null) { |
| return; |
| } |
| |
| final int maxThumbWidth = ImageUtils.getMaximumThumbnailWidthForEditor(getActivity()); |
| |
| imageLoader.get(imageURL, new ImageLoader.ImageListener() { |
| @Override |
| public void onErrorResponse(VolleyError arg0) { |
| } |
| |
| @Override |
| public void onResponse(ImageLoader.ImageContainer container, boolean arg1) { |
| Bitmap downloadedBitmap = container.getBitmap(); |
| if (downloadedBitmap == null) { |
| // no bitmap downloaded from the server. |
| return; |
| } |
| |
| if (downloadedBitmap.getWidth() < MIN_THUMBNAIL_WIDTH) { |
| // Picture is too small. Show the placeholder in this case. |
| return; |
| } |
| |
| Bitmap resizedBitmap; |
| // resize the downloaded bitmap |
| resizedBitmap = ImageUtils.getScaledBitmapAtLongestSide(downloadedBitmap, maxThumbWidth); |
| |
| if (resizedBitmap == null) { |
| return; |
| } |
| |
| final EditText editText = mContentEditText; |
| Editable s = editText.getText(); |
| if (s == null) { |
| return; |
| } |
| WPImageSpan[] spans = s.getSpans(0, s.length(), WPImageSpan.class); |
| if (spans.length != 0 && getActivity() != null) { |
| for (WPImageSpan is : spans) { |
| MediaFile mediaFile = is.getMediaFile(); |
| if (mediaFile == null) { |
| continue; |
| } |
| if (mediaId.equals(mediaFile.getMediaId()) && !is.isNetworkImageLoaded()) { |
| // replace the existing span with a new one with the correct image, re-add |
| // it to the same position. |
| int spanStart = is.getStartPosition(); |
| int spanEnd = is.getEndPosition(); |
| WPEditImageSpan imageSpan = new WPEditImageSpan(getActivity(), resizedBitmap, |
| is.getImageSource()); |
| imageSpan.setMediaFile(is.getMediaFile()); |
| imageSpan.setNetworkImageLoaded(true); |
| imageSpan.setPosition(spanStart, spanEnd); |
| s.removeSpan(is); |
| s.setSpan(imageSpan, spanStart, spanEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); |
| break; |
| } |
| } |
| } |
| } |
| }, 0, 0); |
| } |
| |
| @Override |
| public void onSaveInstanceState(Bundle outState) { |
| super.onSaveInstanceState(outState); |
| |
| WPImageSpan[] spans = mContentEditText.getText().getSpans(0, mContentEditText.getText().length(), WPEditImageSpan.class); |
| |
| if (spans != null && spans.length > 0) { |
| outState.putParcelableArray(KEY_IMAGE_SPANS, spans); |
| } |
| |
| outState.putInt(KEY_START, mContentEditText.getSelectionStart()); |
| outState.putInt(KEY_END, mContentEditText.getSelectionEnd()); |
| outState.putString(KEY_CONTENT, mContentEditText.getText().toString()); |
| } |
| |
| private class AddMediaFileTask extends AsyncTask<Void, Void, WPEditImageSpan> { |
| private MediaFile mMediaFile; |
| private String mImageUrl; |
| private ImageLoader mImageLoader; |
| private int mStart; |
| private int mEnd; |
| |
| public AddMediaFileTask(MediaFile mediaFile, String imageUrl, ImageLoader imageLoader, int start, int end) { |
| mMediaFile = mediaFile; |
| mImageUrl = imageUrl; |
| mImageLoader = imageLoader; |
| mStart = start; |
| mEnd = end; |
| } |
| |
| protected WPEditImageSpan doInBackground(Void... voids) { |
| mMediaFile.setFileURL(mImageUrl); |
| mMediaFile.setFilePath(mImageUrl); |
| WPEditImageSpan imageSpan = createWPEditImageSpan(getActivity(), mMediaFile); |
| mEditorFragmentListener.saveMediaFile(mMediaFile); |
| return imageSpan; |
| } |
| |
| protected void onPostExecute(WPEditImageSpan imageSpan) { |
| if (imageSpan == null) { |
| if (isAdded()) { |
| ToastUtils.showToast(getActivity(), R.string.alert_error_adding_media, Duration.LONG); |
| } |
| return ; |
| } |
| // Insert the WPImageSpan in the content field |
| int selectionStart = mStart; |
| int selectionEnd = mEnd; |
| |
| if (selectionStart > selectionEnd) { |
| int temp = selectionEnd; |
| selectionEnd = selectionStart; |
| selectionStart = temp; |
| } |
| |
| imageSpan.setPosition(selectionStart, selectionEnd); |
| |
| int line, column = 0; |
| if (mContentEditText.getLayout() != null) { |
| line = mContentEditText.getLayout().getLineForOffset(selectionStart); |
| column = selectionStart - mContentEditText.getLayout().getLineStart(line); |
| } |
| |
| Editable s = mContentEditText.getText(); |
| if (s == null) { |
| return; |
| } |
| |
| WPImageSpan[] imageSpans = s.getSpans(selectionStart, selectionEnd, WPImageSpan.class); |
| if (imageSpans.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"); |
| |
| // Fetch and replace the WPImageSpan if it's a remote media |
| if (mImageLoader != null && URLUtil.isNetworkUrl(mImageUrl)) { |
| loadWPImageSpanThumbnail(mMediaFile, mImageUrl, mImageLoader); |
| } |
| } |
| } |
| |
| public void addMediaFile(final MediaFile mediaFile, final String imageUrl, final ImageLoader imageLoader, |
| final int start, final int end) { |
| AddMediaFileTask addMediaFileTask = new AddMediaFileTask(mediaFile, imageUrl, imageLoader, start, end); |
| addMediaFileTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
| } |
| |
| @Override |
| public void appendMediaFile(final MediaFile mediaFile, final String imageUrl, final ImageLoader imageLoader) { |
| addMediaFile(mediaFile, imageUrl, imageLoader, mContentEditText.getSelectionStart(), mContentEditText.getSelectionEnd()); |
| } |
| |
| @Override |
| public void appendGallery(MediaGallery mediaGallery) { |
| Editable editableText = mContentEditText.getText(); |
| if (editableText == null) { |
| 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); |
| } |
| |
| if (column != 0) { |
| // insert one line break if the cursor is not at the first column |
| editableText.insert(selectionEnd, "\n"); |
| selectionStart = selectionStart + 1; |
| selectionEnd = selectionEnd + 1; |
| } |
| |
| editableText.insert(selectionStart, " "); |
| MediaGalleryImageSpan is = new MediaGalleryImageSpan(getActivity(), mediaGallery, |
| R.drawable.legacy_icon_mediagallery_placeholder); |
| editableText.setSpan(is, selectionStart, selectionEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); |
| AlignmentSpan.Standard as = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER); |
| editableText.setSpan(as, selectionStart, selectionEnd + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); |
| editableText.insert(selectionEnd + 1, "\n\n"); |
| } |
| |
| @Override |
| public void setUrlForVideoPressId(String videoPressId, String url, String posterUrl) { |
| |
| } |
| |
| @Override |
| public boolean isUploadingMedia() { |
| return false; |
| } |
| |
| @Override |
| public boolean hasFailedMediaUploads() { |
| return false; |
| } |
| |
| @Override |
| public void removeAllFailedMediaUploads() {} |
| |
| @Override |
| public void setTitlePlaceholder(CharSequence text) { |
| } |
| |
| @Override |
| public void setContentPlaceholder(CharSequence text) { |
| } |
| |
| @Override |
| public boolean isActionInProgress() { |
| return false; |
| } |
| } |