mirror of
https://github.com/M66B/FairEmail.git
synced 2026-01-03 11:28:41 +01:00
Added composing sub lists
This commit is contained in:
68
app/src/main/java/eu/faircode/email/BulletSpanEx.java
Normal file
68
app/src/main/java/eu/faircode/email/BulletSpanEx.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package eu.faircode.email;
|
||||
|
||||
/*
|
||||
This file is part of FairEmail.
|
||||
|
||||
FairEmail is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FairEmail is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2018-2021 by Marcel Bokhorst (M66B)
|
||||
*/
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Build;
|
||||
import android.text.Layout;
|
||||
import android.text.style.BulletSpan;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
public class BulletSpanEx extends BulletSpan {
|
||||
private int indentWidth;
|
||||
private int level;
|
||||
|
||||
public BulletSpanEx(int indentWidth, int gapWidth, int color, int level) {
|
||||
super(gapWidth, color);
|
||||
this.indentWidth = indentWidth;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.P)
|
||||
public BulletSpanEx(int indentWidth, int gapWidth, int color, int bulletRadius, int level) {
|
||||
super(gapWidth, color, bulletRadius);
|
||||
this.indentWidth = indentWidth;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
int getLevel() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
void setLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLeadingMargin(boolean first) {
|
||||
// https://issuetracker.google.com/issues/36956124
|
||||
// This is called before drawLeadingMargin to justify the text
|
||||
return indentWidth * level + super.getLeadingMargin(first);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLeadingMargin(@NonNull Canvas canvas, @NonNull Paint paint, int x, int dir, int top, int baseline, int bottom, @NonNull CharSequence text, int start, int end, boolean first, @Nullable Layout layout) {
|
||||
super.drawLeadingMargin(canvas, paint, x + indentWidth * level, dir, top, baseline, bottom, text, start, end, first, layout);
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,9 @@ import android.text.style.TypefaceSpan;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.style.UnderlineSpan;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static android.text.Html.TO_HTML_PARAGRAPH_LINES_CONSECUTIVE;
|
||||
|
||||
public class HtmlEx {
|
||||
@@ -211,7 +214,8 @@ public class HtmlEx {
|
||||
|
||||
private /* static */ void withinBlockquoteIndividual(StringBuilder out, Spanned text, int start,
|
||||
int end) {
|
||||
Boolean isInBulletList = null;
|
||||
List<Boolean> levels = new ArrayList<>();
|
||||
|
||||
int next;
|
||||
for (int i = start; i <= end; i = next) {
|
||||
next = TextUtils.indexOf(text, '\n', i, end);
|
||||
@@ -220,14 +224,16 @@ public class HtmlEx {
|
||||
}
|
||||
|
||||
if (next == i) {
|
||||
if (isInBulletList != null) {
|
||||
if (levels.size() > 0) {
|
||||
// Current paragraph is no longer a list item; close the previously opened list
|
||||
out.append(isInBulletList ? "</ul>\n" : "</ol>\n");
|
||||
isInBulletList = null;
|
||||
for (int l = levels.size() - 1; l >= 0; l--)
|
||||
out.append(levels.get(l) ? "</ul>\n" : "</ol>\n");
|
||||
levels.clear();
|
||||
}
|
||||
if (i != text.length())
|
||||
out.append("<br>\n");
|
||||
} else {
|
||||
int level = 0;
|
||||
Boolean isBulletListItem = null;
|
||||
ParagraphStyle[] paragraphStyles = text.getSpans(i, next, ParagraphStyle.class);
|
||||
for (ParagraphStyle paragraphStyle : paragraphStyles) {
|
||||
@@ -235,29 +241,34 @@ public class HtmlEx {
|
||||
if ((spanFlags & Spanned.SPAN_PARAGRAPH) == Spanned.SPAN_PARAGRAPH
|
||||
&& paragraphStyle instanceof BulletSpan) {
|
||||
isBulletListItem = !(paragraphStyle instanceof eu.faircode.email.NumberSpan);
|
||||
if (paragraphStyle instanceof NumberSpan)
|
||||
level = ((NumberSpan) paragraphStyle).getLevel();
|
||||
else if (paragraphStyle instanceof BulletSpanEx)
|
||||
level = ((BulletSpanEx) paragraphStyle).getLevel();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isBulletListItem != null && isInBulletList != null && isBulletListItem != isInBulletList) {
|
||||
out.append(isInBulletList ? "</ul>\n" : "</ol>\n");
|
||||
isInBulletList = null;
|
||||
}
|
||||
if (isBulletListItem == null)
|
||||
level = -1;
|
||||
|
||||
if (isBulletListItem != null && isInBulletList == null) {
|
||||
// Current paragraph is the first item in a list
|
||||
isInBulletList = isBulletListItem;
|
||||
out.append(isInBulletList ? "<ul" : "<ol")
|
||||
while (levels.size() > level + 1) {
|
||||
Boolean bullet = levels.remove(levels.size() - 1);
|
||||
out.append(bullet ? "</ul>\n" : "</ol>\n");
|
||||
}
|
||||
if (level >= 0 &&
|
||||
levels.size() == level + 1 &&
|
||||
levels.get(level) != isBulletListItem) {
|
||||
Boolean bullet = levels.remove(level);
|
||||
out.append(bullet ? "</ul>\n" : "</ol>\n");
|
||||
}
|
||||
while (levels.size() < level + 1) {
|
||||
levels.add(isBulletListItem);
|
||||
out.append(isBulletListItem ? "<ul" : "<ol")
|
||||
.append(getTextStyles(text, i, next, true, false))
|
||||
.append(">\n");
|
||||
}
|
||||
|
||||
if (isInBulletList != null && isBulletListItem == null) {
|
||||
// Current paragraph is no longer a list item; close the previously opened list
|
||||
out.append(isInBulletList ? "</ul>\n" : "</ol>\n");
|
||||
isInBulletList = null;
|
||||
}
|
||||
|
||||
String tagType = isBulletListItem != null ? "li" : "span";
|
||||
out.append("<").append(tagType)
|
||||
.append(getTextDirection(text, i, next))
|
||||
@@ -272,9 +283,10 @@ public class HtmlEx {
|
||||
if (isBulletListItem == null)
|
||||
out.append("<br>\n");
|
||||
|
||||
if (next == end && isInBulletList != null) {
|
||||
out.append(isInBulletList ? "</ul>\n" : "</ol>\n");
|
||||
isInBulletList = null;
|
||||
if (next == end && levels.size() > 0) {
|
||||
for (int l = levels.size() - 1; l >= 0; l--)
|
||||
out.append(levels.get(l) ? "</ul>\n" : "</ol>\n");
|
||||
levels.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ import android.text.style.AlignmentSpan;
|
||||
import android.text.style.BulletSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.text.style.LeadingMarginSpan;
|
||||
import android.text.style.QuoteSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.ReplacementSpan;
|
||||
@@ -1915,12 +1914,19 @@ public class HtmlHelper {
|
||||
|
||||
for (BulletSpan span : ssb.getSpans(0, ssb.length(), BulletSpan.class)) {
|
||||
int start = ssb.getSpanStart(span);
|
||||
ssb.insert(start, "* ");
|
||||
}
|
||||
|
||||
for (NumberSpan span : ssb.getSpans(0, ssb.length(), NumberSpan.class)) {
|
||||
int start = ssb.getSpanStart(span);
|
||||
ssb.insert(start, "- ");
|
||||
if (span instanceof NumberSpan) {
|
||||
ssb.insert(start, "- ");
|
||||
int level = ((NumberSpan) span).getLevel();
|
||||
for (int l = 1; l <= level; l++)
|
||||
ssb.insert(start, "\t");
|
||||
} else {
|
||||
ssb.insert(start, "* ");
|
||||
if (span instanceof BulletSpanEx) {
|
||||
int level = ((BulletSpanEx) span).getLevel();
|
||||
for (int l = 1; l <= level; l++)
|
||||
ssb.insert(start, "\t");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ssb.toString();
|
||||
@@ -2372,23 +2378,32 @@ public class HtmlHelper {
|
||||
if (ssb.length() == 0 || ssb.charAt(ssb.length() - 1) != '\n')
|
||||
ssb.append("\n");
|
||||
|
||||
int level = 0;
|
||||
Element type = null;
|
||||
Element parent = element.parent();
|
||||
while (parent != null &&
|
||||
!"ol".equals(parent.tagName()) &&
|
||||
!"ul".equals(parent.tagName()))
|
||||
while (parent != null) {
|
||||
if ("ol".equals(parent.tagName()) || "ul".equals(parent.tagName())) {
|
||||
level++;
|
||||
if (type == null)
|
||||
type = parent;
|
||||
}
|
||||
parent = parent.parent();
|
||||
if (parent == null || "ul".equals(parent.tagName()))
|
||||
}
|
||||
if (level > 0)
|
||||
level--;
|
||||
|
||||
if (type == null || "ul".equals(type.tagName())) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P)
|
||||
setSpan(ssb, new BulletSpan(dp6, colorAccent), start, ssb.length());
|
||||
setSpan(ssb, new BulletSpanEx(dp24, dp6, colorAccent, level), start, ssb.length());
|
||||
else
|
||||
setSpan(ssb, new BulletSpan(dp6, colorAccent, dp3), start, ssb.length());
|
||||
else {
|
||||
setSpan(ssb, new BulletSpanEx(dp24, dp6, colorAccent, dp3, level), start, ssb.length());
|
||||
} else {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol
|
||||
int index = 0;
|
||||
String s = parent.attr("start");
|
||||
String s = type.attr("start");
|
||||
if (!TextUtils.isEmpty(s) && TextUtils.isDigitsOnly(s))
|
||||
index = Integer.parseInt(s) - 1;
|
||||
for (Node child : parent.childNodes()) {
|
||||
for (Node child : type.childNodes()) {
|
||||
if (child instanceof Element &&
|
||||
child.nodeName().equals(element.tagName())) {
|
||||
index++;
|
||||
@@ -2397,8 +2412,9 @@ public class HtmlHelper {
|
||||
}
|
||||
}
|
||||
|
||||
setSpan(ssb, new NumberSpan(dp6, colorAccent, textSize, index), start, ssb.length());
|
||||
setSpan(ssb, new NumberSpan(dp24, dp6, colorAccent, textSize, level, index), start, ssb.length());
|
||||
}
|
||||
|
||||
break;
|
||||
case "pre":
|
||||
// Signature
|
||||
@@ -2409,15 +2425,6 @@ public class HtmlHelper {
|
||||
break;
|
||||
case "ol":
|
||||
case "ul":
|
||||
int llevel = 0;
|
||||
Element lparent = element.parent();
|
||||
while (lparent != null) {
|
||||
if ("ol".equals(lparent.tagName()) || "ul".equals(lparent.tagName()))
|
||||
llevel++;
|
||||
lparent = lparent.parent();
|
||||
}
|
||||
if (llevel > 0)
|
||||
setSpan(ssb, new LeadingMarginSpan.Standard(llevel * dp24), start, ssb.length());
|
||||
break;
|
||||
case "meta":
|
||||
// Signature
|
||||
|
||||
@@ -28,29 +28,41 @@ import android.text.TextPaint;
|
||||
import android.text.style.BulletSpan;
|
||||
|
||||
public class NumberSpan extends BulletSpan {
|
||||
int indentWidth;
|
||||
private int level;
|
||||
private int index;
|
||||
|
||||
private TextPaint tp;
|
||||
private String number;
|
||||
private int margin;
|
||||
|
||||
public NumberSpan(int gapWidth, int color, float textSize, int index) {
|
||||
public NumberSpan(int indentWidth, int gapWidth, int color, float textSize, int level, int index) {
|
||||
tp = new TextPaint();
|
||||
tp.setStyle(Paint.Style.FILL);
|
||||
tp.setColor(color);
|
||||
tp.setTypeface(Typeface.MONOSPACE);
|
||||
tp.setTextSize(textSize);
|
||||
|
||||
this.indentWidth = indentWidth;
|
||||
this.level = level;
|
||||
this.index = index;
|
||||
|
||||
number = index + ".";
|
||||
margin = Math.round(tp.measureText(number) + gapWidth);
|
||||
margin = Math.round(tp.measureText(number)) + gapWidth;
|
||||
}
|
||||
|
||||
float getTextSize() {
|
||||
return tp.getTextSize();
|
||||
}
|
||||
|
||||
int getLevel() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
void setLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
int getIndex() {
|
||||
return index;
|
||||
}
|
||||
@@ -59,7 +71,7 @@ public class NumberSpan extends BulletSpan {
|
||||
public int getLeadingMargin(boolean first) {
|
||||
// https://issuetracker.google.com/issues/36956124
|
||||
// This is called before drawLeadingMargin to justify the text
|
||||
return margin;
|
||||
return indentWidth * level + margin;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,7 +81,7 @@ public class NumberSpan extends BulletSpan {
|
||||
float textSize = tp.getTextSize();
|
||||
if (textSize > p.getTextSize())
|
||||
tp.setTextSize(p.getTextSize());
|
||||
c.drawText(number, x + dir, baseline, tp);
|
||||
c.drawText(number, x + indentWidth * level, baseline, tp);
|
||||
tp.setTextSize(textSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,6 @@ import android.graphics.Typeface;
|
||||
import android.os.Build;
|
||||
import android.text.Editable;
|
||||
import android.text.Layout;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.AlignmentSpan;
|
||||
@@ -124,6 +122,16 @@ public class StyleHelper {
|
||||
smenu.add(R.id.group_style_font, i, 0, fontNames[i]);
|
||||
smenu.add(R.id.group_style_font, fontNames.length, 0, R.string.title_style_font_default);
|
||||
|
||||
int level = -1;
|
||||
BulletSpan[] spans = edit.getSpans(start, end, BulletSpan.class);
|
||||
for (BulletSpan span : spans)
|
||||
if (span instanceof NumberSpan)
|
||||
level = ((NumberSpan) span).getLevel();
|
||||
else if (span instanceof BulletSpanEx)
|
||||
level = ((BulletSpanEx) span).getLevel();
|
||||
popupMenu.getMenu().findItem(R.id.menu_style_list_increase).setVisible(level >= 0);
|
||||
popupMenu.getMenu().findItem(R.id.menu_style_list_decrease).setVisible(level > 0);
|
||||
|
||||
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
@@ -136,7 +144,11 @@ public class StyleHelper {
|
||||
} else if (groupId == R.id.group_style_align) {
|
||||
return setAlignment(item);
|
||||
} else if (groupId == R.id.group_style_list) {
|
||||
return setList(item);
|
||||
if (item.getItemId() == R.id.menu_style_list_increase ||
|
||||
item.getItemId() == R.id.menu_style_list_decrease)
|
||||
return setListLevel(item);
|
||||
else
|
||||
return setList(item);
|
||||
} else if (groupId == R.id.group_style_font) {
|
||||
return setFont(item);
|
||||
} else if (groupId == R.id.group_style_blockquote) {
|
||||
@@ -248,12 +260,38 @@ public class StyleHelper {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setListLevel(MenuItem item) {
|
||||
Context context = etBody.getContext();
|
||||
int add = (item.getItemId() == R.id.menu_style_list_increase ? 1 : -1);
|
||||
|
||||
boolean renum = false;
|
||||
BulletSpan[] spans = edit.getSpans(start, end, BulletSpan.class);
|
||||
for (BulletSpan span : spans)
|
||||
if (span instanceof BulletSpanEx) {
|
||||
BulletSpanEx bs = (BulletSpanEx) span;
|
||||
bs.setLevel(bs.getLevel() + add);
|
||||
} else if (span instanceof NumberSpan) {
|
||||
renum = true;
|
||||
NumberSpan ns = (NumberSpan) span;
|
||||
ns.setLevel(ns.getLevel() + add);
|
||||
}
|
||||
|
||||
if (renum)
|
||||
renumber(edit, false, context);
|
||||
|
||||
etBody.setText(edit);
|
||||
etBody.setSelection(start, end);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setList(MenuItem item) {
|
||||
Context context = etBody.getContext();
|
||||
|
||||
int colorAccent = Helper.resolveColor(context, R.attr.colorAccent);
|
||||
int dp3 = Helper.dp2pixels(context, 3);
|
||||
int dp6 = Helper.dp2pixels(context, 6);
|
||||
int dp24 = Helper.dp2pixels(context, 24);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
int message_zoom = prefs.getInt("message_zoom", 100);
|
||||
@@ -271,22 +309,28 @@ public class StyleHelper {
|
||||
int i = s;
|
||||
int j = s + 1;
|
||||
int index = 1;
|
||||
boolean renum = false;
|
||||
while (j < e) {
|
||||
if (i > 0 && edit.charAt(i - 1) == '\n' && edit.charAt(j) == '\n') {
|
||||
Log.i("Insert " + i + "..." + (j + 1) + " size=" + e);
|
||||
if (item.getItemId() == R.id.menu_style_list_bullets)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P)
|
||||
edit.setSpan(new BulletSpan(dp6, colorAccent), i, j + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_PARAGRAPH);
|
||||
edit.setSpan(new BulletSpanEx(dp24, dp6, colorAccent, 0), i, j + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_PARAGRAPH);
|
||||
else
|
||||
edit.setSpan(new BulletSpan(dp6, colorAccent, dp3), i, j + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_PARAGRAPH);
|
||||
else
|
||||
edit.setSpan(new NumberSpan(dp6, colorAccent, textSize, index++), i, j + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_PARAGRAPH);
|
||||
edit.setSpan(new BulletSpanEx(dp24, dp6, colorAccent, dp3, 0), i, j + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_PARAGRAPH);
|
||||
else {
|
||||
renum = true;
|
||||
edit.setSpan(new NumberSpan(dp24, dp6, colorAccent, textSize, 0, index++), i, j + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE | Spanned.SPAN_PARAGRAPH);
|
||||
}
|
||||
|
||||
i = j + 1;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
if (renum)
|
||||
renumber(edit, false, context);
|
||||
|
||||
etBody.setText(edit);
|
||||
etBody.setSelection(s, e);
|
||||
|
||||
@@ -472,7 +516,7 @@ public class StyleHelper {
|
||||
if (end == edit.length())
|
||||
edit.append("\n"); // workaround Android bug
|
||||
|
||||
return new Pair(start, end);
|
||||
return new Pair<>(start, end);
|
||||
}
|
||||
|
||||
static <T extends ParagraphStyle> T clone(Object span, Class<T> type, Context context) {
|
||||
@@ -485,16 +529,18 @@ public class StyleHelper {
|
||||
} else if (NumberSpan.class.isAssignableFrom(type)) {
|
||||
NumberSpan n = (NumberSpan) span;
|
||||
int dp6 = Helper.dp2pixels(context, 6);
|
||||
int dp24 = Helper.dp2pixels(context, 24);
|
||||
int colorAccent = Helper.resolveColor(context, R.attr.colorAccent);
|
||||
return (T) new NumberSpan(dp6, colorAccent, n.getTextSize(), n.getIndex() + 1);
|
||||
} else if (BulletSpan.class.isAssignableFrom(type)) {
|
||||
BulletSpan b = (BulletSpan) span;
|
||||
return (T) new NumberSpan(dp24, dp6, colorAccent, n.getTextSize(), n.getLevel(), n.getIndex() + 1);
|
||||
} else if (BulletSpanEx.class.isAssignableFrom(type)) {
|
||||
BulletSpanEx b = (BulletSpanEx) span;
|
||||
int dp24 = Helper.dp2pixels(context, 24);
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
|
||||
int dp6 = Helper.dp2pixels(context, 6);
|
||||
int colorAccent = Helper.resolveColor(context, R.attr.colorAccent);
|
||||
return (T) new BulletSpan(dp6, colorAccent);
|
||||
return (T) new BulletSpanEx(dp24, dp6, colorAccent, b.getLevel());
|
||||
} else
|
||||
return (T) new BulletSpan(b.getGapWidth(), b.getColor(), b.getBulletRadius());
|
||||
return (T) new BulletSpanEx(dp24, b.getGapWidth(), b.getColor(), b.getBulletRadius(), b.getLevel());
|
||||
|
||||
} else
|
||||
throw new IllegalArgumentException(type.getName());
|
||||
@@ -502,13 +548,14 @@ public class StyleHelper {
|
||||
|
||||
static void renumber(Editable text, boolean clean, Context context) {
|
||||
int dp6 = Helper.dp2pixels(context, 6);
|
||||
int dp24 = Helper.dp2pixels(context, 24);
|
||||
int colorAccent = Helper.resolveColor(context, R.attr.colorAccent);
|
||||
|
||||
Log.i("Renumber clean=" + clean + " text=" + text);
|
||||
|
||||
int next;
|
||||
int index = 1;
|
||||
int pos = -1;
|
||||
List<Integer> levels = new ArrayList<>();
|
||||
for (int i = 0; i < text.length(); i = next) {
|
||||
next = text.nextSpanTransition(i, text.length(), NumberSpan.class);
|
||||
Log.i("Bullet span next=" + next);
|
||||
@@ -525,16 +572,33 @@ public class StyleHelper {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (span instanceof NumberSpan) {
|
||||
if (start == pos)
|
||||
index++;
|
||||
else
|
||||
index = 1;
|
||||
int level;
|
||||
if (span instanceof NumberSpan)
|
||||
level = ((NumberSpan) span).getLevel();
|
||||
else if (span instanceof BulletSpanEx)
|
||||
level = ((BulletSpanEx) span).getLevel();
|
||||
else
|
||||
level = 0;
|
||||
|
||||
if (start != pos)
|
||||
levels.clear();
|
||||
while (levels.size() > level + 1)
|
||||
levels.remove(levels.size() - 1);
|
||||
if (levels.size() == level + 1 && !(span instanceof NumberSpan))
|
||||
levels.remove(level - 1);
|
||||
while (levels.size() < level + 1)
|
||||
levels.add(0);
|
||||
|
||||
int index = levels.get(level) + 1;
|
||||
levels.remove(level);
|
||||
levels.add(level, index);
|
||||
|
||||
if (span instanceof NumberSpan) {
|
||||
NumberSpan ns = (NumberSpan) span;
|
||||
if (index != ns.getIndex()) {
|
||||
NumberSpan clone = new NumberSpan(dp6, colorAccent, ns.getTextSize(), index);
|
||||
text.removeSpan(span);
|
||||
// Text size needs measuring
|
||||
NumberSpan clone = new NumberSpan(dp24, dp6, colorAccent, ns.getTextSize(), level, index);
|
||||
text.setSpan(clone, start, end, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,12 @@
|
||||
<item
|
||||
android:id="@+id/menu_style_list_numbered"
|
||||
android:title="@string/title_style_list_numbered" />
|
||||
<item
|
||||
android:id="@+id/menu_style_list_increase"
|
||||
android:title="@string/title_style_list_level_increase" />
|
||||
<item
|
||||
android:id="@+id/menu_style_list_decrease"
|
||||
android:title="@string/title_style_list_level_decrease" />
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
@@ -1073,6 +1073,8 @@
|
||||
<string name="title_style_list">List</string>
|
||||
<string name="title_style_list_bullets">Bullets</string>
|
||||
<string name="title_style_list_numbered">Numbered</string>
|
||||
<string name="title_style_list_level_increase">Increase indentation</string>
|
||||
<string name="title_style_list_level_decrease">Decrease indentation</string>
|
||||
<string name="title_style_font">Font</string>
|
||||
<string name="title_style_font_default">Default</string>
|
||||
<string name="title_style_blockquote">Block quote</string>
|
||||
|
||||
Reference in New Issue
Block a user