This commit is contained in:
Horis 2023-02-21 17:21:10 +08:00
parent dd816f8bb9
commit 3dcd0c35ed
33 changed files with 284 additions and 112 deletions

View File

@ -4,7 +4,7 @@
- 新增目录规则当Legado自带的规则不能够满足需求时用户可根据自己的情况自定义目录规则
- 导入默认规则 在旧版本中Legado自带的规则不会随着软件的更新而更新。用户需要使用最新规则或对自带规则修改后需要重置时可点击 导入默认规则。**注意:导入默认规则不会重置用户自定义的规则,但如果您对自带的规则进行了修改,则修改的规则会被重置为默认规则。**
- 导入在线规则 为了方便异步调试以及用户导入他人的目录规则Legado增加目录规则的网络导入功能。点击 网络导入 的输入框,可以通过内置的链接导入在线规则。(在线规则优先比内置的规则更加激进,但适配了更多类型的标题格式,用户需根据自己的情况选择是否导入)
- 网络导入 为了方便异步调试以及用户导入他人的目录规则Legado增加目录规则的网络导入功能。点击 网络导入 的输入框,可以通过内置的链接导入在线规则。(在线规则优先比内置的规则更加激进,但适配了更多类型的标题格式,用户需根据自己的情况选择是否导入)
- 拆分超长章节 根据目录正则分章时若单章超过三万字左右将自动分为多章
### 操作区

View File

@ -14,7 +14,7 @@ interface DictRuleDao {
@get:Query("select * from dictRules where enabled = 1 order by sortNumber")
val enabled: List<DictRule>
@Query("select * from dictRules where enabled = 1 order by sortNumber")
@Query("select * from dictRules order by sortNumber")
fun flowAll(): Flow<List<DictRule>>
@Query("select * from dictRules where name = :name")

View File

@ -21,6 +21,17 @@ data class DictRule(
var sortNumber: Int = 0
) {
override fun hashCode(): Int {
return name.hashCode()
}
override fun equals(other: Any?): Boolean {
if (other is DictRule) {
return name == other.name
}
return false
}
/**
* 搜索字典
*/

View File

@ -17,18 +17,12 @@ data class TxtTocRule(
) {
override fun hashCode(): Int {
return GSON.toJson(this).hashCode()
return id.hashCode()
}
override fun equals(other: Any?): Boolean {
other ?: return false
if (other is TxtTocRule) {
return id == other.id
&& name == other.name
&& rule == other.rule
&& example == other.example
&& serialNumber == other.serialNumber
&& enable == other.enable
}
return false
}

View File

@ -51,7 +51,7 @@ class ImportDictRuleDialog() : BaseDialogFragment(R.layout.dialog_recycler_view)
@SuppressLint("NotifyDataSetChanged")
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
binding.toolBar.setBackgroundColor(primaryColor)
binding.toolBar.setTitle(R.string.import_tts)
binding.toolBar.setTitle(R.string.import_dict_rule)
binding.rotateLoading.visible()
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
binding.recyclerView.adapter = adapter

View File

@ -30,7 +30,6 @@ import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.book.search.SearchScope
import io.legado.app.ui.book.source.debug.BookSourceDebugActivity
import io.legado.app.ui.book.source.edit.BookSourceEditActivity
import io.legado.app.ui.book.toc.rule.TxtTocRuleActivity
import io.legado.app.ui.config.CheckSourceConfig
import io.legado.app.ui.document.HandleFileContract
import io.legado.app.ui.qrcode.QrCodeResult

View File

@ -40,44 +40,43 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
}
}
val diffItemCallback: DiffUtil.ItemCallback<BookSource>
get() = object : DiffUtil.ItemCallback<BookSource>() {
override fun areItemsTheSame(oldItem: BookSource, newItem: BookSource): Boolean {
return oldItem.bookSourceUrl == newItem.bookSourceUrl
}
override fun areContentsTheSame(oldItem: BookSource, newItem: BookSource): Boolean {
return oldItem.bookSourceName == newItem.bookSourceName
&& oldItem.bookSourceGroup == newItem.bookSourceGroup
&& oldItem.enabled == newItem.enabled
&& oldItem.enabledExplore == newItem.enabledExplore
&& oldItem.exploreUrl == newItem.exploreUrl
}
override fun getChangePayload(oldItem: BookSource, newItem: BookSource): Any? {
val payload = Bundle()
if (oldItem.bookSourceName != newItem.bookSourceName
|| oldItem.bookSourceGroup != newItem.bookSourceGroup
) {
payload.putBoolean("upName", true)
}
if (oldItem.enabled != newItem.enabled) {
payload.putBoolean("enabled", newItem.enabled)
}
if (oldItem.enabledExplore != newItem.enabledExplore ||
oldItem.exploreUrl != newItem.exploreUrl
) {
payload.putBoolean("upExplore", true)
}
if (payload.isEmpty) {
return null
}
return payload
}
val diffItemCallback = object : DiffUtil.ItemCallback<BookSource>() {
override fun areItemsTheSame(oldItem: BookSource, newItem: BookSource): Boolean {
return oldItem.bookSourceUrl == newItem.bookSourceUrl
}
override fun areContentsTheSame(oldItem: BookSource, newItem: BookSource): Boolean {
return oldItem.bookSourceName == newItem.bookSourceName
&& oldItem.bookSourceGroup == newItem.bookSourceGroup
&& oldItem.enabled == newItem.enabled
&& oldItem.enabledExplore == newItem.enabledExplore
&& oldItem.exploreUrl == newItem.exploreUrl
}
override fun getChangePayload(oldItem: BookSource, newItem: BookSource): Any? {
val payload = Bundle()
if (oldItem.bookSourceName != newItem.bookSourceName
|| oldItem.bookSourceGroup != newItem.bookSourceGroup
) {
payload.putBoolean("upName", true)
}
if (oldItem.enabled != newItem.enabled) {
payload.putBoolean("enabled", newItem.enabled)
}
if (oldItem.enabledExplore != newItem.enabledExplore ||
oldItem.exploreUrl != newItem.exploreUrl
) {
payload.putBoolean("upExplore", true)
}
if (payload.isEmpty) {
return null
}
return payload
}
}
override fun getViewBinding(parent: ViewGroup): ItemBookSourceBinding {
return ItemBookSourceBinding.inflate(inflater, parent, false)
}
@ -190,7 +189,10 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
}
R.id.menu_search -> callBack.searchBook(source)
R.id.menu_debug_source -> callBack.debug(source)
R.id.menu_del -> callBack.del(source)
R.id.menu_del -> {
callBack.del(source)
selected.remove(source)
}
R.id.menu_enable_explore -> {
callBack.update(source.copy(enabledExplore = !source.enabledExplore))
}

View File

@ -5,6 +5,7 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu
import androidx.recyclerview.widget.ItemTouchHelper
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
@ -12,8 +13,13 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.TxtTocRule
import io.legado.app.databinding.ActivityTxtTocRuleBinding
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.DirectLinkUpload
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.association.ImportDictRuleDialog
import io.legado.app.ui.association.ImportTxtTocRuleDialog
import io.legado.app.ui.document.HandleFileContract
import io.legado.app.ui.qrcode.QrCodeResult
import io.legado.app.ui.widget.SelectActionBar
import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
@ -27,7 +33,8 @@ import kotlinx.coroutines.launch
class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleViewModel>(),
TxtTocRuleAdapter.CallBack,
SelectActionBar.CallBack,
TxtTocRuleEditDialog.Callback {
TxtTocRuleEditDialog.Callback,
PopupMenu.OnMenuItemClickListener {
override val viewModel: TxtTocRuleViewModel by viewModels()
override val binding: ActivityTxtTocRuleBinding by viewBinding(ActivityTxtTocRuleBinding::inflate)
@ -35,6 +42,38 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
TxtTocRuleAdapter(this, this)
}
private val importTocRuleKey = "tocRuleUrl"
private val qrCodeResult = registerForActivityResult(QrCodeResult()) {
it ?: return@registerForActivityResult
showDialogFragment(ImportTxtTocRuleDialog(it))
}
private val importDoc = registerForActivityResult(HandleFileContract()) {
kotlin.runCatching {
it.uri?.readText(this)?.let {
showDialogFragment(ImportTxtTocRuleDialog(it))
}
}.onFailure {
toastOnUi("readTextError:${it.localizedMessage}")
}
}
private val exportResult = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
alert(R.string.export_success) {
if (uri.toString().isAbsUrl()) {
DirectLinkUpload.getSummary()?.let { summary ->
setMessage(summary)
}
}
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = getString(R.string.path)
editView.setText(uri.toString())
}
customView { alertBinding.root }
okButton {
sendToClip(uri.toString())
}
}
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
initView()
@ -59,20 +98,22 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
private fun initBottomActionBar() {
binding.selectActionBar.setMainActionText(R.string.delete)
binding.selectActionBar.inflateMenu(R.menu.txt_toc_rule_sel)
binding.selectActionBar.setOnMenuItemClickListener(this)
binding.selectActionBar.setCallBack(this)
}
private fun initData() {
launch {
appDb.txtTocRuleDao.observeAll().conflate().collect { tocRules ->
adapter.setItems(tocRules)
adapter.setItems(tocRules, adapter.diffItemCallBack)
upCountView()
}
}
}
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.txt_toc_regex, menu)
menuInflater.inflate(R.menu.txt_toc_rule, menu)
return super.onCompatCreateOptionsMenu(menu)
}
@ -84,9 +125,15 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_add -> showDialogFragment(TxtTocRuleEditDialog())
R.id.menu_default -> viewModel.importDefault()
R.id.menu_import -> showImportDialog()
R.id.menu_help -> showTxtTocRegexHelp()
R.id.menu_import_local -> importDoc.launch {
mode = HandleFileContract.FILE
allowExtensions = arrayOf("txt", "json")
}
R.id.menu_import_onLine -> showImportDialog()
R.id.menu_import_qr -> qrCodeResult.launch()
R.id.menu_import_default -> viewModel.importDefault()
R.id.menu_help -> showTxtTocRuleHelp()
}
return super.onCompatOptionsItemSelected(item)
}
@ -182,18 +229,32 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
cacheUrls.add(0, it)
aCache.put(importTocRuleKey, cacheUrls.joinToString(","))
}
viewModel.importOnLine(it) { msg ->
toastOnUi(msg)
}
showDialogFragment(ImportTxtTocRuleDialog(it))
}
}
cancelButton()
}
}
private fun showTxtTocRegexHelp() {
val text = String(assets.open("help/txtTocRegexHelp.md").readBytes())
private fun showTxtTocRuleHelp() {
val text = String(assets.open("help/txtTocRuleHelp.md").readBytes())
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
}
}
override fun onMenuItemClick(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_enable_selection -> viewModel.enableSelection(*adapter.selection.toTypedArray())
R.id.menu_disable_selection -> viewModel.disableSelection(*adapter.selection.toTypedArray())
R.id.menu_export_selection -> exportResult.launch {
mode = HandleFileContract.EXPORT
fileData = HandleFileContract.FileData(
"exportTxtTocRule.json",
GSON.toJson(adapter.selection).toByteArray(),
"application/json"
)
}
}
return true
}
}

View File

@ -6,10 +6,12 @@ import android.view.View
import android.view.ViewGroup
import android.widget.PopupMenu
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.data.entities.ReplaceRule
import io.legado.app.data.entities.TxtTocRule
import io.legado.app.databinding.ItemTxtTocRuleBinding
import io.legado.app.lib.theme.backgroundColor
@ -28,6 +30,43 @@ class TxtTocRuleAdapter(context: Context, private val callBack: CallBack) :
selected.contains(it)
}
val diffItemCallBack = object : DiffUtil.ItemCallback<TxtTocRule>() {
override fun areItemsTheSame(oldItem: TxtTocRule, newItem: TxtTocRule): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: TxtTocRule, newItem: TxtTocRule): Boolean {
if (oldItem.name != newItem.name) {
return false
}
if (oldItem.enable != newItem.enable) {
return false
}
if (oldItem.example != newItem.example) {
return false
}
return true
}
override fun getChangePayload(oldItem: TxtTocRule, newItem: TxtTocRule): Any? {
val payload = Bundle()
if (oldItem.name != newItem.name) {
payload.putBoolean("upName", true)
}
if (oldItem.enable != newItem.enable) {
payload.putBoolean("enabled", newItem.enable)
}
if (oldItem.example != newItem.example) {
payload.putBoolean("upExample", true)
}
if (payload.isEmpty) {
return null
}
return payload
}
}
override fun getViewBinding(parent: ViewGroup): ItemTxtTocRuleBinding {
return ItemTxtTocRuleBinding.inflate(inflater, parent, false)
}
@ -50,6 +89,9 @@ class TxtTocRuleAdapter(context: Context, private val callBack: CallBack) :
bundle.keySet().map {
when (it) {
"selected" -> cbSource.isChecked = selected.contains(item)
"upNmae" -> cbSource.text = item.name
"upExample" -> titleExample.text = item.example
"enabled" -> swtEnabled.isChecked = item.enable
}
}
}
@ -95,7 +137,10 @@ class TxtTocRuleAdapter(context: Context, private val callBack: CallBack) :
when (menuItem.itemId) {
R.id.menu_top -> callBack.toTop(source)
R.id.menu_bottom -> callBack.toBottom(source)
R.id.menu_del -> callBack.del(source)
R.id.menu_del -> {
callBack.del(source)
selected.remove(source)
}
}
true
}

View File

@ -61,8 +61,8 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
binding.toolBar.setBackgroundColor(primaryColor)
durRegex = arguments?.getString("tocRegex")
binding.toolBar.setTitle(R.string.txt_toc_regex)
binding.toolBar.inflateMenu(R.menu.txt_toc_regex)
binding.toolBar.setTitle(R.string.txt_toc_rule)
binding.toolBar.inflateMenu(R.menu.txt_toc_rule)
binding.toolBar.menu.applyTint(requireContext())
binding.toolBar.menu.findItem(R.id.menu_split_long_chapter)
?.isChecked = ReadBook.book?.getSplitLongChapter() == true
@ -125,7 +125,7 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
item.isChecked = !item.isChecked
if (!item.isChecked) context?.longToastOnUi(R.string.need_more_time_load_content)
}
R.id.menu_help -> showTxtTocRegexHelp()
R.id.menu_help -> showTxtTocRuleHelp()
}
return false
}
@ -170,8 +170,8 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
}
}
private fun showTxtTocRegexHelp() {
val text = String(requireContext().assets.open("help/txtTocRegexHelp.md").readBytes())
private fun showTxtTocRuleHelp() {
val text = String(requireContext().assets.open("help/txtTocRuleHelp.md").readBytes())
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
}

View File

@ -3,6 +3,7 @@ package io.legado.app.ui.book.toc.rule
import android.app.Application
import io.legado.app.base.BaseViewModel
import io.legado.app.data.appDb
import io.legado.app.data.entities.DictRule
import io.legado.app.data.entities.TxtTocRule
import io.legado.app.help.DefaultData
import io.legado.app.help.http.newCallResponseBody
@ -83,4 +84,18 @@ class TxtTocRuleViewModel(app: Application) : BaseViewModel(app) {
}
}
}
fun enableSelection(vararg txtTocRule: TxtTocRule) {
execute {
val array = txtTocRule.map { it.copy(enable = true) }.toTypedArray()
appDb.txtTocRuleDao.insert(*array)
}
}
fun disableSelection(vararg txtTocRule: TxtTocRule) {
execute {
val array = txtTocRule.map { it.copy(enable = false) }.toTypedArray()
appDb.txtTocRuleDao.insert(*array)
}
}
}

View File

@ -21,6 +21,7 @@ import io.legado.app.ui.association.ImportDictRuleDialog
import io.legado.app.ui.document.HandleFileContract
import io.legado.app.ui.qrcode.QrCodeResult
import io.legado.app.ui.widget.SelectActionBar
import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider
@ -120,15 +121,15 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_create -> showDialogFragment<DictRuleEditDialog>()
R.id.menu_import_default -> viewModel.importDefault()
R.id.menu_add -> showDialogFragment<DictRuleEditDialog>()
R.id.menu_import_local -> importDoc.launch {
mode = HandleFileContract.FILE
allowExtensions = arrayOf("txt", "json")
}
R.id.menu_import_onLine -> showImportDialog()
R.id.menu_import_qr -> qrCodeResult.launch()
R.id.menu_help -> {}
R.id.menu_import_default -> viewModel.importDefault()
R.id.menu_help -> showDictRuleHelp()
}
return super.onCompatOptionsItemSelected(item)
}
@ -195,7 +196,7 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
.getAsString(importRecordKey)
?.splitNotBlank(",")
?.toMutableList() ?: mutableListOf()
alert(titleResource = R.string.import_replace_rule_on_line) {
alert(titleResource = R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = "url"
editView.setFilterValues(cacheUrls)
@ -220,4 +221,9 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
cancelButton()
}
}
}
private fun showDictRuleHelp() {
val text = String(assets.open("help/dictRuleHelp.md").readBytes())
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
}
}

View File

@ -141,6 +141,7 @@ class DictRuleAdapter(context: Context, var callBack: CallBack) :
ivDelete.setOnClickListener {
getItem(holder.layoutPosition)?.let {
callBack.delete(it)
selected.remove(it)
}
}
}

View File

@ -41,19 +41,15 @@ class DictRuleViewModel(application: Application) : BaseViewModel(application) {
fun enableSelection(vararg dictRule: DictRule) {
execute {
dictRule.forEach {
it.enabled = true
}
appDb.dictRuleDao.insert(*dictRule)
val array = dictRule.map { it.copy(enabled = true) }.toTypedArray()
appDb.dictRuleDao.insert(*array)
}
}
fun disableSelection(vararg dictRule: DictRule) {
execute {
dictRule.forEach {
it.enabled = false
}
appDb.dictRuleDao.insert(*dictRule)
val array = dictRule.map { it.copy(enabled = false) }.toTypedArray()
appDb.dictRuleDao.insert(*array)
}
}

View File

@ -139,7 +139,7 @@ class MyFragment : BaseFragment(R.layout.fragment_my_config) {
"bookSourceManage" -> startActivity<BookSourceActivity>()
"replaceManage" -> startActivity<ReplaceRuleActivity>()
"dictRuleManage" -> startActivity<DictRuleActivity>()
"txtTocRegexManage" -> startActivity<TxtTocRuleActivity>()
"txtTocRuleManage" -> startActivity<TxtTocRuleActivity>()
"bookmark" -> startActivity<AllBookmarkActivity>()
"setting" -> startActivity<ConfigActivity> {
putExtra("configTag", ConfigTag.OTHER_CONFIG)

View File

@ -270,7 +270,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
.getAsString(importRecordKey)
?.splitNotBlank(",")
?.toMutableList() ?: mutableListOf()
alert(titleResource = R.string.import_replace_rule_on_line) {
alert(titleResource = R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = "url"
editView.setFilterValues(cacheUrls)

View File

@ -160,7 +160,10 @@ class ReplaceRuleAdapter(context: Context, var callBack: CallBack) :
when (menuItem.itemId) {
R.id.menu_top -> callBack.toTop(item)
R.id.menu_bottom -> callBack.toBottom(item)
R.id.menu_del -> callBack.delete(item)
R.id.menu_del -> {
callBack.delete(item)
selected.remove(item)
}
}
true
}

View File

@ -179,7 +179,10 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
when (menuItem.itemId) {
R.id.menu_top -> callBack.toTop(source)
R.id.menu_bottom -> callBack.toBottom(source)
R.id.menu_del -> callBack.del(source)
R.id.menu_del -> {
callBack.del(source)
selected.remove(source)
}
}
true
}

View File

@ -9,10 +9,7 @@
android:id="@+id/title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentInsetStartWithNavigation="0dp"
app:contentLayout="@layout/view_search"
app:displayHomeAsUp="true"
app:title="@string/txt_toc_regex" />
app:title="@string/txt_toc_rule" />
<FrameLayout
android:layout_width="match_parent"

View File

@ -24,7 +24,7 @@
app:displayHomeAsUp="false"
app:fitStatusBar="false"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="@string/txt_toc_regex"
app:title="@string/txt_toc_rule"
app:titleTextAppearance="@style/ToolbarTitle" />
<androidx.core.widget.NestedScrollView

View File

@ -29,7 +29,7 @@
<item
android:id="@+id/menu_toc_regex"
android:icon="@drawable/ic_exchange"
android:title="@string/txt_toc_regex"
android:title="@string/txt_toc_rule"
android:visible="false"
app:showAsAction="always" />
</group>

View File

@ -16,7 +16,7 @@
<item
android:id="@+id/menu_toc_regex"
android:title="@string/txt_toc_regex"
android:title="@string/txt_toc_rule"
app:showAsAction="never" />
</group>

View File

@ -5,7 +5,7 @@
tools:ignore="AlwaysShowAction">
<item
android:id="@+id/menu_create"
android:id="@+id/menu_add"
android:icon="@drawable/ic_add"
android:title="@string/create"
app:showAsAction="always" />

View File

@ -11,14 +11,26 @@
tools:ignore="AlwaysShowAction" />
<item
android:id="@+id/menu_default"
android:title="@string/import_default_rule"
android:id="@+id/menu_import_local"
android:icon="@drawable/ic_import"
android:title="@string/import_local"
app:showAsAction="never" />
<item
android:id="@+id/menu_import_onLine"
android:title="@string/import_on_line"
android:icon="@drawable/ic_import"
app:showAsAction="never" />
<item
android:id="@+id/menu_import"
android:title="@string/import_replace_rule_on_line"
android:id="@+id/menu_import_qr"
android:icon="@drawable/ic_import"
android:title="@string/import_by_qr_code"
app:showAsAction="never" />
<item
android:id="@+id/menu_import_default"
android:title="@string/import_default_rule"
android:icon="@drawable/ic_import"
app:showAsAction="never" />

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_enable_selection"
android:title="@string/enable_selection"
app:showAsAction="never" />
<item
android:id="@+id/menu_disable_selection"
android:title="@string/disable_selection"
app:showAsAction="never" />
<item
android:id="@+id/menu_export_selection"
android:title="@string/export_selection"
app:showAsAction="never" />
</menu>

View File

@ -342,7 +342,7 @@
<string name="pt_show_all_find">Mostrar todos los buscados</string>
<string name="ps_show_all_find">Mostrar la fuente de búsqueda si Descubrir fue cerrado</string>
<string name="update_toc">Actualizar capítulos</string>
<string name="txt_toc_regex">Capítulos de Txt Regex</string>
<string name="txt_toc_rule">Capítulos de Txt Rule</string>
<string name="set_charset">Codificación de texto</string>
<string name="swap_sort">Orden ascendente/descendente</string>
<string name="sort">Ordenar</string>
@ -1077,5 +1077,6 @@
<string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</string>
<string name="config_txt_toc_regex">配置 TXT 目录正则</string>
<string name="config_txt_toc_rule">配置 TXT 目录规则</string>
<string name="import_dict_rule">导入字典规则</string>
</resources>

View File

@ -346,7 +346,7 @@
<string name="pt_show_all_find">Display all Discovery</string>
<string name="ps_show_all_find">Display the selected origin\'s Discovery if closed</string>
<string name="update_toc">Update chapters</string>
<string name="txt_toc_regex">Txt Chapters Regex</string>
<string name="txt_toc_rule">Txt Chapters Rule</string>
<string name="set_charset">Text encoding</string>
<string name="swap_sort">Ascending/Descending order</string>
<string name="sort">Sort</string>
@ -1080,5 +1080,6 @@
<string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</string>
<string name="config_txt_toc_regex">配置 TXT 目录正则</string>
<string name="config_txt_toc_rule">配置 TXT 目录规则</string>
<string name="import_dict_rule">导入字典规则</string>
</resources>

View File

@ -344,7 +344,7 @@
<string name="pt_show_all_find">Mostrar todas as Descobertas</string>
<string name="ps_show_all_find">Mostrar a fonte da Descoberta selecionada se encerrado</string>
<string name="update_toc">Atualizar os capítulos</string>
<string name="txt_toc_regex">Capítulos de Txt Regex</string>
<string name="txt_toc_rule">Capítulos de Txt Rule</string>
<string name="set_charset">Codificação de texto</string>
<string name="swap_sort">Ordem ascendente/descendente</string>
<string name="sort">Ordenar</string>
@ -1080,5 +1080,6 @@
<string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</string>
<string name="config_txt_toc_regex">配置 TXT 目录正则</string>
<string name="config_txt_toc_rule">配置 TXT 目录规则</string>
<string name="import_dict_rule">导入字典规则</string>
</resources>

View File

@ -343,7 +343,7 @@
<string name="pt_show_all_find">顯示所有發現</string>
<string name="ps_show_all_find">關閉則只顯示勾選源的發現</string>
<string name="update_toc">更新目錄</string>
<string name="txt_toc_regex">TXT目錄正</string>
<string name="txt_toc_rule">TXT 目錄規</string>
<string name="set_charset">設置編碼</string>
<string name="swap_sort">倒序-順序</string>
<string name="sort">排序</string>
@ -1077,5 +1077,6 @@
<string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</string>
<string name="config_txt_toc_regex">配置 TXT 目录正则</string>
<string name="config_txt_toc_rule">配置 TXT 目录规则</string>
<string name="import_dict_rule">导入字典规则</string>
</resources>

View File

@ -345,7 +345,7 @@
<string name="pt_show_all_find">顯示所有發現</string>
<string name="ps_show_all_find">關閉則只顯示勾選源的發現</string>
<string name="update_toc">更新目錄</string>
<string name="txt_toc_regex">TXT目錄正</string>
<string name="txt_toc_rule">TXT 目錄規</string>
<string name="set_charset">設定編碼</string>
<string name="swap_sort">倒序-順序</string>
<string name="sort">排序</string>
@ -1079,5 +1079,6 @@
<string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</string>
<string name="config_txt_toc_regex">配置 TXT 目录正则</string>
<string name="config_txt_toc_rule">配置 TXT 目录规则</string>
<string name="import_dict_rule">导入字典规则</string>
</resources>

View File

@ -345,7 +345,7 @@
<string name="pt_show_all_find">显示所有发现</string>
<string name="ps_show_all_find">关闭则只显示勾选源的发现</string>
<string name="update_toc">更新目录</string>
<string name="txt_toc_regex">TXT 目录正</string>
<string name="txt_toc_rule">TXT 目录规</string>
<string name="set_charset">设置编码</string>
<string name="swap_sort">倒序-顺序</string>
<string name="sort">排序</string>
@ -1079,5 +1079,6 @@
<string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</string>
<string name="config_txt_toc_regex">配置 TXT 目录正则</string>
<string name="config_txt_toc_rule">配置 TXT 目录规则</string>
<string name="import_dict_rule">导入字典规则</string>
</resources>

View File

@ -346,7 +346,7 @@
<string name="pt_show_all_find">Display all Discovery</string>
<string name="ps_show_all_find">Display the selected origin\'s Discovery if closed</string>
<string name="update_toc">Update chapters</string>
<string name="txt_toc_regex">Txt Chapters Regex</string>
<string name="txt_toc_rule">Txt Chapters Rule</string>
<string name="set_charset">Text encoding</string>
<string name="swap_sort">Ascending/Descending order</string>
<string name="sort">Sort</string>
@ -1080,5 +1080,6 @@
<string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</string>
<string name="config_txt_toc_regex">配置 TXT 目录正则</string>
<string name="config_txt_toc_rule">配置 TXT 目录规则</string>
<string name="import_dict_rule">导入字典规则</string>
</resources>

View File

@ -13,9 +13,9 @@
app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.Preference
android:key="txtTocRegexManage"
android:title="@string/txt_toc_regex"
android:summary="@string/config_txt_toc_regex"
android:key="txtTocRuleManage"
android:title="@string/txt_toc_rule"
android:summary="@string/config_txt_toc_rule"
android:icon="@drawable/ic_cfg_source"
app:iconSpaceReserved="false" />