/*
* Copyright 2016. SHENQINCI(沈钦赐)<dev@qinc.me>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ren.qinc.markdowneditors.engine;
import android.view.View;
import android.widget.EditText;
import ren.qinc.markdowneditors.R;
import ren.qinc.markdowneditors.utils.Check;
/**
* 格式相关操作
* Created by 沈钦赐 on 16/6/22.
*/
public class PerformEditable implements View.OnClickListener {
private EditText mEditText;
public PerformEditable(EditText editText) {
Check.CheckNull(editText, "EditText不能为空");
this.mEditText = editText;
}
public void perform(int id, Object... param) {
switch (id) {
case R.id.id_shortcut_console://代码行
performConsole();
break;
case R.id.id_shortcut_format_header_1://
H(1);
break;
case R.id.id_shortcut_format_header_2://
H(2);
break;
case R.id.id_shortcut_format_header_3://
H(3);
break;
case R.id.id_shortcut_format_header_4://
H(4);
break;
case R.id.id_shortcut_format_header_5://
H(5);
break;
case R.id.id_shortcut_format_header_6://
H(6);
break;
case R.id.id_shortcut_format_italic://斜体
performItalic();
break;
case R.id.id_shortcut_format_bold://粗体
performBold();
break;
case R.id.id_shortcut_list_bulleted://列表
performList("* ");
break;
case R.id.id_shortcut_format_numbers://数字列表
performList("1. ");
break;
case R.id.id_shortcut_format_quote://引用
performQuote();
break;
case R.id.id_shortcut_format_strikethrough://字体删除线
performStrikethrough();
break;
case R.id.id_shortcut_grid://插入表格
performInsertTable(param);
break;
case R.id.id_shortcut_insert_link://插入链接
performInsertLink(param);
break;
case R.id.id_shortcut_insert_photo://插入图片
performInsertPhoto(param);
break;
case R.id.id_shortcut_minus://插入分割线
performMinus();
break;
case R.id.id_shortcut_xml://xml
performXML();
break;
}
}
private void performList(String tag) {
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
int selectionEnd = mEditText.getSelectionEnd();
String substring = source.substring(0, selectionStart);
int line = substring.lastIndexOf(10);
if (line != -1) {
selectionStart = line + 1;
} else {
selectionStart = 0;
}
substring = source.substring(selectionStart, selectionEnd);
String[] split = substring.split("\n");
StringBuffer stringBuffer = new StringBuffer();
if (split != null && split.length > 0)
for (String s : split) {
if (s.length() == 0 && stringBuffer.length() != 0) {
stringBuffer.append("\n");
continue;
}
if (!s.trim().startsWith(tag)) {
//不是 空行或者已经是序号开头
if (stringBuffer.length() > 0) stringBuffer.append("\n");
stringBuffer.append(tag).append(s);
} else {
if (stringBuffer.length() > 0) stringBuffer.append("\n");
stringBuffer.append(s);
}
}
if (stringBuffer.length() == 0) {
stringBuffer.append(tag);
}
mEditText.getText().replace(selectionStart, selectionEnd, stringBuffer.toString());
mEditText.setSelection(stringBuffer.length() + selectionStart);
completed();
}
@Override
public void onClick(View v) {
if (mEditText == null) return;
perform(v.getId());
}
/**
* H.
*
* @param level the level
*/
public final void H(int level) {
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
int selectionEnd = mEditText.getSelectionEnd();
StringBuilder result = new StringBuilder();
String substring = source.substring(selectionStart, selectionEnd);
if (!hasNewLine(source, selectionStart))
result.append("\n");
for (int i = 0; i < level; i++) {
result.append("#");
}
result.append(" ").append(substring);
mEditText.getText().replace(selectionStart, selectionEnd, result.toString());
mEditText.setSelection(selectionStart + result.length());
completed();
}
private void performInsertTable(Object... param) {
int row;
int column;
int i;
if (param == null || param.length < 2) {
row = 3;
column = 3;
} else {
try {
row = Integer.parseInt(param[0].toString());
column = Integer.parseInt(param[1].toString());
} catch (NumberFormatException e) {
row = 3;
column = 3;
}
}
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
StringBuilder stringBuilder = new StringBuilder();
if (!hasNewTwoLine(source, selectionStart)) {
if (hasNewLine(source, selectionStart))
stringBuilder.append("\n");
else
stringBuilder.append("\n\n");
}
stringBuilder.append("|");
for (i = 0; i < column; i++) {
stringBuilder.append(" Header |");
}
stringBuilder.append("\n|");
for (i = 0; i < column; i++) {
stringBuilder.append(":----------:|");
}
stringBuilder.append("\n");
for (int i2 = 0; i2 < row; i2++) {
stringBuilder.append("|");
for (i = 0; i < column; i++) {
stringBuilder.append(" |");
}
stringBuilder.append("\n");
}
String result = stringBuilder.toString();
mEditText.getText().insert(selectionStart, result);
mEditText.setSelection(selectionStart + result.length());
completed();
}
private void performInsertPhoto(Object[] param) {
Object[] temp = param;
if (param == null) param = new Object[]{""};
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
String result;
if (hasNewLine(source, selectionStart)) {
result = "";
} else {
result = "\n" + "";
}
mEditText.getText().insert(selectionStart, result);
if (temp == null || temp[0].toString().length() == 0)
mEditText.setSelection(result.length() + selectionStart - 1);
else
mEditText.setSelection(result.length() + selectionStart);
completed();
}
/**
* 插入链接
* Perform insert link.
*
* @param param the param
*/
private void performInsertLink(Object[] param) {
int selectionStart = mEditText.getSelectionStart();
String result;
if (param == null || param.length == 0) {
result = "[]()\n";
mEditText.getText().insert(selectionStart, result);
mEditText.setSelection(selectionStart + 1);
} else if (param.length == 1) {
result = "[" + param[0] + "](" + param[0] + ")\n";
mEditText.getText().insert(selectionStart, result);
mEditText.setSelection(selectionStart + result.length());
} else {
result = "[" + param[0] + "](" + param[1] + ")\n";
mEditText.getText().insert(selectionStart, result);
mEditText.setSelection(selectionStart + result.length());
}
completed();
}
private void performItalic() {
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
int selectionEnd = mEditText.getSelectionEnd();
String substring = source.substring(selectionStart, selectionEnd);
String result = " *" + substring + "* ";
mEditText.getText().replace(selectionStart, selectionEnd, result);
mEditText.setSelection(result.length() + selectionStart - 2);
completed();
}
private void performBold() {
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
int selectionEnd = mEditText.getSelectionEnd();
String substring = source.substring(selectionStart, selectionEnd);
String result = " **" + substring + "** ";
mEditText.getText().replace(selectionStart, selectionEnd, result);
mEditText.setSelection(result.length() + selectionStart - 3);
completed();
}
private void performConsole() {
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
int selectionEnd = mEditText.getSelectionEnd();
String substring = source.substring(selectionStart, selectionEnd);
String result;
if (hasNewLine(source, selectionStart))
result = "```\n" + substring + "\n```\n";
else
result = "\n```\n" + substring + "\n```\n";
mEditText.getText().replace(selectionStart, selectionEnd, result);
mEditText.setSelection(result.length() + selectionStart - 5);
completed();
}
private void performXML() {
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
int selectionEnd = mEditText.getSelectionEnd();
String substring = source.substring(selectionStart, selectionEnd);
String result = " `" + substring + "` ";
mEditText.getText().replace(selectionStart, selectionEnd, result);
mEditText.setSelection(result.length() + selectionStart - 2);
completed();
}
private void performStrikethrough() {
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
int selectionEnd = mEditText.getSelectionEnd();
String substring = source.substring(selectionStart, selectionEnd);
String result = " ~~" + substring + "~~ ";
mEditText.getText().replace(selectionStart, selectionEnd, result);
mEditText.setSelection(result.length() + selectionStart - 3);
completed();
}
public void performQuote() {
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
int selectionEnd = mEditText.getSelectionEnd();
String substring = source.substring(selectionStart, selectionEnd);
String result;
if (hasNewLine(source, selectionStart)) {
result = "> " + substring;
} else {
result = "\n> " + substring;
}
mEditText.getText().replace(selectionStart, selectionEnd, result);
mEditText.setSelection(result.length() + selectionStart);
completed();
}
/**
* 插入横向
* Perform minus.
*/
public void performMinus() {
String source = mEditText.getText().toString();
int selectionStart = mEditText.getSelectionStart();
String result;
if (hasNewLine(source, selectionStart)) {
//已经单独一行
result = "-------\n";
} else {
//同一行,加上换行
result = "\n-------\n";
}
mEditText.getText().replace(selectionStart, selectionStart, result);
mEditText.setSelection(result.length() + selectionStart);
completed();
}
protected void completed() {
}
private boolean hasNewLine(String source, int selectionStart) {
if (source.isEmpty()) return true;
source = source.substring(0, selectionStart);
return source.charAt(source.length() - 1) == 10;
}
private boolean hasNewTwoLine(String source, int selectionStart) {
source = source.substring(0, selectionStart);
return source.length() >= 2 && source.charAt(source.length() - 1) == 10 && source.charAt(source.length() - 2) == 10;
}
private boolean isEmptyLine(String source, int selectionStart) {
if (source.isEmpty()) return true;
if (selectionStart == source.length()) return hasNewLine(source, selectionStart);
String startStr = source.substring(0, selectionStart);
//最后一行
return source.charAt(startStr.length() - 1) == 10 && source.charAt(startStr.length()) == 10;
}
}