public void store(View v) {
    Spanned s = (Spanned) mTextView.getText();
    BackgroundColorSpan[] spans = s.getSpans(0, s.length(), BackgroundColorSpan.class);

    BufferedWriter bw = null;
    try {
      int len = spans.length;
      bw = new BufferedWriter(new FileWriter(mFile));
      bw.write(String.valueOf(len));
      bw.newLine();
      for (BackgroundColorSpan span : spans) {
        int start = s.getSpanStart(span);
        int end = s.getSpanEnd(span);
        int color = span.getBackgroundColor();
        bw.write("" + start + "," + end + "," + color);
        bw.newLine();
      }
      bw.write(mText);
      clear(v);
    } catch (IOException e) {
      Log.e(TAG, "IO error", e);
    } finally {
      closeQuietly(bw);
    }
  }
Ejemplo n.º 2
0
  /**
   * Extract the text from a HTML based string. This is similar to what HTML.fromHtml(...) does, but
   * this method also removes the embedded images instead of replacing them by a small rectangular
   * representation character.
   *
   * @param html
   * @return
   */
  public static String extractText(CharSequence html) {
    String result = html.toString();

    // recognize images in textview HTML contents
    if (html instanceof Spanned) {
      Spanned text = (Spanned) html;
      Object[] styles = text.getSpans(0, text.length(), Object.class);
      ArrayList<Pair<Integer, Integer>> removals = new ArrayList<Pair<Integer, Integer>>();
      for (Object style : styles) {
        if (style instanceof ImageSpan) {
          int start = text.getSpanStart(style);
          int end = text.getSpanEnd(style);
          removals.add(Pair.of(start, end));
        }
      }

      // sort reversed and delete image spans
      Collections.sort(
          removals,
          new Comparator<Pair<Integer, Integer>>() {

            @Override
            public int compare(Pair<Integer, Integer> lhs, Pair<Integer, Integer> rhs) {
              return rhs.getRight().compareTo(lhs.getRight());
            }
          });
      result = text.toString();
      for (Pair<Integer, Integer> removal : removals) {
        result = result.substring(0, removal.getLeft()) + result.substring(removal.getRight());
      }
    }

    // some line breaks are still in the text, source is unknown
    return StringUtils.replace(result, "<br />", "\n").trim();
  }
Ejemplo n.º 3
0
 private static CharSequence removeJumpingBeansSpans(Spanned text) {
   SpannableStringBuilder sbb = new SpannableStringBuilder(text.toString());
   Object[] spans = text.getSpans(0, text.length(), Object.class);
   for (Object span : spans) {
     if (!(span instanceof JumpingBeansSpan)) {
       sbb.setSpan(span, text.getSpanStart(span), text.getSpanEnd(span), text.getSpanFlags(span));
     }
   }
   return sbb;
 }
Ejemplo n.º 4
0
  @Override
  public int reactTagForTouch(float touchX, float touchY) {
    Spanned text = (Spanned) getText();
    int target = getId();

    int x = (int) touchX;
    int y = (int) touchY;

    Layout layout = getLayout();
    if (layout == null) {
      // If the layout is null, the view hasn't been properly laid out yet. Therefore, we can't find
      // the exact text tag that has been touched, and the correct tag to return is the default one.
      return target;
    }
    int line = layout.getLineForVertical(y);

    int lineStartX = (int) layout.getLineLeft(line);
    int lineEndX = (int) layout.getLineRight(line);

    // TODO(5966918): Consider extending touchable area for text spans by some DP constant
    if (x >= lineStartX && x <= lineEndX) {
      int index = layout.getOffsetForHorizontal(line, x);

      // We choose the most inner span (shortest) containing character at the given index
      // if no such span can be found we will send the textview's react id as a touch handler
      // In case when there are more than one spans with same length we choose the last one
      // from the spans[] array, since it correspond to the most inner react element
      ReactTagSpan[] spans = text.getSpans(index, index, ReactTagSpan.class);

      if (spans != null) {
        int targetSpanTextLength = text.length();
        for (int i = 0; i < spans.length; i++) {
          int spanStart = text.getSpanStart(spans[i]);
          int spanEnd = text.getSpanEnd(spans[i]);
          if (spanEnd > index && (spanEnd - spanStart) <= targetSpanTextLength) {
            target = spans[i].getReactTag();
            targetSpanTextLength = (spanEnd - spanStart);
          }
        }
      }
    }

    return target;
  }
Ejemplo n.º 5
0
  @Override
  public void setObject(Item item) {
    try {
      dobroitem = (DobroPostItem) item;
    } catch (ClassCastException e) {
      e.printStackTrace();
      return;
    }
    if (dobroitem == null || dobroitem.post == null) return;
    dobroitem.post.setLastContext(getContext());
    this.board = dobroitem.post.getBoardName();
    this.thread = dobroitem.post.getThreadDisplay_id();
    ((HorizontalScrollView) findViewById(R.id.horizScroll)).scrollTo(0, 0);

    CharSequence txt = dobroitem.post.getFormattedText();
    if (txt.length() > 800) {
      Pattern p1 = Pattern.compile("\\.|\n");
      Matcher m1 = p1.matcher(txt);
      Pattern p2 = Pattern.compile("\\b");
      Matcher m2 = p2.matcher(txt);
      if (m1.find(500) && m1.end() < 700) txt = txt.subSequence(0, m1.end());
      else if (m2.find(500) && m2.start() < 700) txt = txt.subSequence(0, m2.start());
      else txt = txt.subSequence(0, 500);
      messageView.setText(txt, BufferType.SPANNABLE);
      SpannableStringBuilder builder =
          new SpannableStringBuilder("\nСообщение слишком длинное. Полная версия");
      builder.setSpan(
          new ClickableSpan() {
            @Override
            public void onClick(View widget) {
              try {
                messageView.setText(dobroitem.post.getFormattedText(), BufferType.SPANNABLE);
              } catch (IndexOutOfBoundsException e) {

              }
            }
          },
          1,
          builder.length(),
          0);
      messageView.append(builder.subSequence(0, builder.length()));
    } else messageView.setText(txt, BufferType.SPANNABLE);
    // FIXME
    messageView.setMovementMethod(LinkMovementMethod.getInstance());
    messageView.setClickable(false);
    messageView.setFocusable(false);
    messageView.setFocusableInTouchMode(false);
    /*
    refsView.setMovementMethod(LinkMovementMethod.getInstance());
    refsView.setClickable(false);
    refsView.setFocusable(false);
    refsView.setFocusableInTouchMode(false);
    */
    //
    imagesLayout.removeAllViewsInLayout();
    if (dobroitem.post.isOp()) {
      numberView.setVisibility(GONE);
      titleView.setText(
          dobroitem.post.getSubject().length() == 0
              ? getContext().getString(R.string.untitled)
              : dobroitem.post.getSubject());
      titleView.setVisibility(VISIBLE);
    } else {
      int pos = dobroitem.post.getNumber();
      if (pos > 0) {
        numberView.setVisibility(VISIBLE);
        numberView.setText(String.valueOf(pos));
      } else numberView.setVisibility(GONE);
      titleView.setText("");
      titleView.setVisibility(GONE);
    }

    TypedValue backgroundRef = new TypedValue();
    getContext().getTheme().resolveAttribute(R.attr.dcPicrelatedColor, backgroundRef, true);
    int backgroundColor = getContext().getResources().getColor(backgroundRef.resourceId);
    SharedPreferences prefs = DobroApplication.getApplicationStatic().getDefaultPrefs();
    boolean show_info = prefs.getBoolean("show_fileinfo", true);
    boolean force_op_load = prefs.getBoolean("op_pictures_force", false);

    if (dobroitem.post.getFiles().length > 0) {
      for (DobroFile file : dobroitem.post.getFiles()) {
        CachedAsyncImageView imageView = new CachedAsyncImageView(getContext());
        VerticalTextView textView = null;
        String fname1 = file.getThumb().substring(file.getThumb().lastIndexOf("/") + 1);
        int e = fname1.lastIndexOf("s.");
        if (e > 0)
          fname1 = fname1.substring(0, e) + file.getSrc().substring(file.getSrc().lastIndexOf("."));
        String fname2 = file.getSrc().substring(file.getSrc().lastIndexOf("/") + 1);
        String size = humanReadableByteCount(file.getSize(), true);
        String date = getThumbnailDate(file.getThumb());
        if (date == null)
          try {
            date = file.getSrc().split("/")[2];
            date = date.substring(2) + "." + date.substring(0, 2);
          } catch (Exception ex) {
            date = "?";
          }
        imageView.setInfo(
            getContext()
                .getString(
                    R.string.file_info_parretn,
                    fname1,
                    fname2,
                    size,
                    date,
                    file.getRating(),
                    getMetadataText(file.getMetadata())));
        if (file.getMetadata().width != null)
          imageView.setSize(file.getMetadata().height, file.getMetadata().width);
        if (show_info) {
          textView = new VerticalTextView(getContext(), null);
          textView.setLinkedImageView(imageView);
          String text = "";
          if (dobroitem.post.getBoardName().equals("b")
              || dobroitem.post.getBoardName().equals("rf")) text += fname1;
          else text += fname2;
          text += "\n" + size;
          if (file.getMetadata() != null
              && file.getMetadata().width != null
              && file.getMetadata().height != null) {
            text +=
                ", "
                    + String.valueOf(file.getMetadata().width)
                    + "x"
                    + String.valueOf(file.getMetadata().height);
          }
          textView.setText(text);
          textView.setGravity(Gravity.BOTTOM);
          textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
        }
        imageView.setRating(file.getRat());
        imageView.setForceLoad(force_op_load && dobroitem.post.isOp());
        imageView.setUrl(file.getThumb());
        final String urlTag = file.getSrc();
        imageView.setTag(urlTag);
        imageView.setPadding(2, 2, 2, 2);
        imageView.setAdjustViewBounds(true);
        imageView.setMaxHeight(mImageHeight);
        imageView.setMaxWidth(mImageHeight);
        imageView.setBackgroundColor(backgroundColor);
        imageView.setScaleType(ScaleType.CENTER);
        imageView.setOnCreateContextMenuListener(imageView);
        float h = mImageHeight;
        int w =
            Math.min(
                Math.round((h / (float) file.getThumb_height()) * file.getThumb_width()),
                file.getThumb_width());
        imageView.setLayoutParams(new LayoutParams(w + 4, mImageHeight + 4));
        if (show_info) {
          textView.setWidth(mImageHeight + 4);
          textView.setLinkedImageView(imageView);
          imagesLayout.addView(textView);
        }
        imagesLayout.addView(imageView);
      }
      imagesLayout.setVisibility(VISIBLE);
    } else {
      imagesLayout.setVisibility(GONE);
    }
    if (prefs.getBoolean("youtube", true)) {
      Spanned s = null;
      boolean cast_ok = false;
      try {
        s = (Spanned) dobroitem.post.getFormattedText();
        cast_ok = true;
      } catch (ClassCastException e) {
        cast_ok = false;
      }
      if (cast_ok) {
        URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
        for (URLSpan span : spans) {
          String url = span.getURL();
          Pattern p = Pattern.compile("(youtube\\.com/watch\\?v=|youtu\\.be/)(\\S{11})");
          Matcher m = p.matcher(url);
          if (!m.find()) continue;
          String yt_id = m.group(2);
          String text = s.subSequence(s.getSpanStart(span), s.getSpanEnd(span)).toString();
          CachedAsyncImageView imageView = new CachedAsyncImageView(getContext());
          imageView.setLayoutParams(
              new LayoutParams((int) ((mImageHeight + 4) / 0.75), mImageHeight + 4));

          imageView.setRating(Rating.SWF);
          imageView.setForceLoad(false);
          imageView.setTag(url);
          imageView.setPadding(2, 2, 2, 2);
          imageView.setAdjustViewBounds(true);
          imageView.setMaxHeight(mImageHeight);
          imageView.setMaxWidth((int) ((mImageHeight + 4) / 0.75));

          imageView.setUrl("http://img.youtube.com/vi/" + yt_id + "/0.jpg");

          imageView.setBackgroundColor(backgroundColor);
          imageView.setScaleType(ScaleType.CENTER);

          VerticalTextView textView = new VerticalTextView(getContext(), null);
          textView.setGravity(Gravity.BOTTOM);
          textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
          textView.setText(text);
          textView.setLinkedImageView(imageView);
          textView.setWidth(mImageHeight + 4);

          if (show_info) imagesLayout.addView(textView);
          imagesLayout.addView(imageView);
          imagesLayout.setVisibility(VISIBLE);
        }
      }
    }
    metadataRightView.setText(
        getContext()
            .getString(
                R.string.post_date, String.valueOf(dobroitem.post.getDate().replace(' ', '\n'))));
    metadataLeftView.setText(
        dobroitem.post.getName()
            + "\n"
            + getContext()
                .getString(R.string.post_id, String.valueOf(dobroitem.post.getDisplay_id())));
    List<String> refs = dobroitem.post.getRefs();
    if (!refs.isEmpty()) {
      /*
      CharSequence seq = getContext().getText(R.string.answers);
      SpannableStringBuilder s = new SpannableStringBuilder(seq);
      s.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, seq.length(), 0);
      s.append(" ");
      for (String ref : refs) {
      	int start = s.length();
      	s.append(ref + ", ");
      	s.setSpan(
      			new DobroLinkSpan(dobroitem.post.getBoardName(), ref
      					.substring(2), getContext(), null), start, start
      					+ ref.length(), 0);
      }
      refsView.setText(s.subSequence(0, s.length() - 2),
      		BufferType.SPANNABLE);
       */
      refsButton.setText(String.format("/%d", refs.size()));
      refsButton.setVisibility(View.VISIBLE);
    } else refsButton.setVisibility(View.GONE);
    checkSpells();
  }