use of org.wordpress.android.util.helpers.WPImageSpan in project WordPress-Android by wordpress-mobile.
the class EditPostActivity method updatePostContent.
// TODO: Replace with contents of the updatePostContentNewEditor() method when legacy editor is dropped
/**
* Updates post object with content of this fragment
*/
public void updatePostContent(boolean isAutoSave) throws IllegalEditorStateException {
if (mPost == null) {
return;
}
String title = StringUtils.notNullStr((String) mEditorFragment.getTitle());
SpannableStringBuilder postContent;
if (mEditorFragment.getSpannedContent() != null) {
// needed by the legacy editor to save local drafts
try {
postContent = new SpannableStringBuilder(mEditorFragment.getSpannedContent());
} catch (IndexOutOfBoundsException e) {
// A core android bug might cause an out of bounds exception, if so we'll just use the current editable
// See https://code.google.com/p/android/issues/detail?id=5164
postContent = new SpannableStringBuilder(StringUtils.notNullStr((String) mEditorFragment.getContent()));
}
} else {
postContent = new SpannableStringBuilder(StringUtils.notNullStr((String) mEditorFragment.getContent()));
}
String content;
if (mPost.isLocalDraft()) {
// remove suggestion spans, they cause craziness in WPHtml.toHTML().
CharacterStyle[] characterStyles = postContent.getSpans(0, postContent.length(), CharacterStyle.class);
for (CharacterStyle characterStyle : characterStyles) {
if (characterStyle instanceof SuggestionSpan) {
postContent.removeSpan(characterStyle);
}
}
content = WPHtml.toHtml(postContent);
// replace duplicate <p> tags so there's not duplicates, trac #86
content = content.replace("<p><p>", "<p>");
content = content.replace("</p></p>", "</p>");
content = content.replace("<br><br>", "<br>");
// sometimes the editor creates extra tags
content = content.replace("</strong><strong>", "").replace("</em><em>", "").replace("</u><u>", "").replace("</strike><strike>", "").replace("</blockquote><blockquote>", "");
} else {
if (!isAutoSave) {
// Add gallery shortcode
MediaGalleryImageSpan[] gallerySpans = postContent.getSpans(0, postContent.length(), MediaGalleryImageSpan.class);
for (MediaGalleryImageSpan gallerySpan : gallerySpans) {
int start = postContent.getSpanStart(gallerySpan);
postContent.removeSpan(gallerySpan);
postContent.insert(start, WPHtml.getGalleryShortcode(gallerySpan));
}
}
WPImageSpan[] imageSpans = postContent.getSpans(0, postContent.length(), WPImageSpan.class);
if (imageSpans.length != 0) {
for (WPImageSpan wpIS : imageSpans) {
MediaFile mediaFile = wpIS.getMediaFile();
if (mediaFile == null) {
continue;
}
if (mediaFile.getMediaId() != null) {
updateMediaFileOnServer(mediaFile);
} else {
mediaFile.setFileName(wpIS.getImageSource().toString());
mediaFile.setFilePath(wpIS.getImageSource().toString());
}
int tagStart = postContent.getSpanStart(wpIS);
if (!isAutoSave) {
postContent.removeSpan(wpIS);
// network image has a mediaId
if (mediaFile.getMediaId() != null && mediaFile.getMediaId().length() > 0) {
postContent.insert(tagStart, WPHtml.getContent(wpIS));
} else {
// local image for upload
postContent.insert(tagStart, "<img android-uri=\"" + wpIS.getImageSource().toString() + "\" />");
}
}
}
}
content = postContent.toString();
}
mPost.setTitle(title);
mPost.setContent(content);
if (!mPost.isLocalDraft()) {
mPost.setIsLocallyChanged(true);
}
}
use of org.wordpress.android.util.helpers.WPImageSpan in project WordPress-Android by wordpress-mobile.
the class LegacyEditorFragment method loadWPImageSpanThumbnail.
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);
}
use of org.wordpress.android.util.helpers.WPImageSpan in project WordPress-Android by wordpress-mobile.
the class LegacyEditorFragment method onTouch.
@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;
}
use of org.wordpress.android.util.helpers.WPImageSpan in project WordPress-Android by wordpress-mobile.
the class LegacyEditorFragment method onCreateView.
@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;
}
use of org.wordpress.android.util.helpers.WPImageSpan in project WordPress-Android by wordpress-mobile.
the class HtmlToSpannedConverter method startImg.
private void startImg(SpannableStringBuilder text, Attributes attributes, WPHtml.ImageGetter img) {
if (mContext == null)
return;
String src = attributes.getValue("android-uri");
Bitmap resizedBitmap = null;
try {
resizedBitmap = ImageUtils.getWPImageSpanThumbnailFromFilePath(mContext, src, mMaxImageWidth);
if (resizedBitmap == null && src != null) {
if (src.contains("video")) {
resizedBitmap = BitmapFactory.decodeResource(mContext.getResources(), org.wordpress.android.editor.R.drawable.media_movieclip);
} else {
resizedBitmap = BitmapFactory.decodeResource(mContext.getResources(), org.wordpress.android.R.drawable.media_image_placeholder);
}
}
} catch (OutOfMemoryError e) {
CrashlyticsUtils.logException(e, AppLog.T.UTILS);
}
if (resizedBitmap != null) {
int len = text.length();
text.append("");
Uri curStream = Uri.parse(src);
if (curStream == null) {
return;
}
WPImageSpan is = new WPImageSpan(mContext, resizedBitmap, curStream);
// Get the MediaFile data from db
MediaModel mediaModel = mMediaStore.getPostMediaWithPath(mPost.getId(), src);
MediaFile mediaFile = FluxCUtils.mediaFileFromMediaModel(mediaModel);
if (mediaFile != null) {
is.setMediaFile(mediaFile);
is.setImageSource(curStream);
text.setSpan(is, len, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
AlignmentSpan.Standard as = new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER);
text.setSpan(as, text.getSpanStart(is), text.getSpanEnd(is), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} else if (mPost != null) {
if (mPost.isLocalDraft()) {
if (attributes != null) {
text.append("<img");
for (int i = 0; i < attributes.getLength(); i++) {
// Attr name
String aName = attributes.getLocalName(i);
if ("".equals(aName))
aName = attributes.getQName(i);
text.append(" ");
text.append(aName + "=\"" + attributes.getValue(i) + "\"");
}
text.append(" />\n");
}
}
} else if (src == null) {
//get regular src value from <img/> tag's src attribute
src = attributes.getValue("", "src");
Drawable d = null;
if (img != null) {
d = img.getDrawable(src);
}
if (d != null) {
int len = text.length();
text.append("");
text.setSpan(new ImageSpan(d, src), len, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
// noop - we're not showing a default image here
}
}
}
Aggregations