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
@@ -4,7 +4,7 @@
- 新增目录规则,当Legado自带的规则不能够满足需求时,用户可根据自己的情况自定义目录规则 - 新增目录规则,当Legado自带的规则不能够满足需求时,用户可根据自己的情况自定义目录规则
- 导入默认规则 在旧版本中,Legado自带的规则不会随着软件的更新而更新。用户需要使用最新规则或对自带规则修改后需要重置时,可点击 导入默认规则。**注意:导入默认规则不会重置用户自定义的规则,但如果您对自带的规则进行了修改,则修改的规则会被重置为默认规则。** - 导入默认规则 在旧版本中,Legado自带的规则不会随着软件的更新而更新。用户需要使用最新规则或对自带规则修改后需要重置时,可点击 导入默认规则。**注意:导入默认规则不会重置用户自定义的规则,但如果您对自带的规则进行了修改,则修改的规则会被重置为默认规则。**
- 导入在线规则 为了方便异步调试以及用户导入他人的目录规则,Legado增加目录规则的网络导入功能。点击 网络导入 的输入框,可以通过内置的链接导入在线规则。(在线规则优先比内置的规则更加激进,但适配了更多类型的标题格式,用户需根据自己的情况选择是否导入) - 网络导入 为了方便异步调试以及用户导入他人的目录规则,Legado增加目录规则的网络导入功能。点击 网络导入 的输入框,可以通过内置的链接导入在线规则。(在线规则优先比内置的规则更加激进,但适配了更多类型的标题格式,用户需根据自己的情况选择是否导入)
- 拆分超长章节 根据目录正则分章时若单章超过三万字左右将自动分为多章 - 拆分超长章节 根据目录正则分章时若单章超过三万字左右将自动分为多章
### 操作区 ### 操作区
@@ -14,7 +14,7 @@ interface DictRuleDao {
@get:Query("select * from dictRules where enabled = 1 order by sortNumber") @get:Query("select * from dictRules where enabled = 1 order by sortNumber")
val enabled: List<DictRule> 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>> fun flowAll(): Flow<List<DictRule>>
@Query("select * from dictRules where name = :name") @Query("select * from dictRules where name = :name")
@@ -21,6 +21,17 @@ data class DictRule(
var sortNumber: Int = 0 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
}
/** /**
* 搜索字典 * 搜索字典
*/ */
@@ -17,18 +17,12 @@ data class TxtTocRule(
) { ) {
override fun hashCode(): Int { override fun hashCode(): Int {
return GSON.toJson(this).hashCode() return id.hashCode()
} }
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
other ?: return false
if (other is TxtTocRule) { if (other is TxtTocRule) {
return id == other.id return id == other.id
&& name == other.name
&& rule == other.rule
&& example == other.example
&& serialNumber == other.serialNumber
&& enable == other.enable
} }
return false return false
} }
@@ -51,7 +51,7 @@ class ImportDictRuleDialog() : BaseDialogFragment(R.layout.dialog_recycler_view)
@SuppressLint("NotifyDataSetChanged") @SuppressLint("NotifyDataSetChanged")
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
binding.toolBar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
binding.toolBar.setTitle(R.string.import_tts) binding.toolBar.setTitle(R.string.import_dict_rule)
binding.rotateLoading.visible() binding.rotateLoading.visible()
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
@@ -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.search.SearchScope
import io.legado.app.ui.book.source.debug.BookSourceDebugActivity import io.legado.app.ui.book.source.debug.BookSourceDebugActivity
import io.legado.app.ui.book.source.edit.BookSourceEditActivity 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.config.CheckSourceConfig
import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.document.HandleFileContract
import io.legado.app.ui.qrcode.QrCodeResult import io.legado.app.ui.qrcode.QrCodeResult
@@ -40,44 +40,43 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
} }
} }
val diffItemCallback: DiffUtil.ItemCallback<BookSource> val diffItemCallback = object : 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
}
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 { override fun getViewBinding(parent: ViewGroup): ItemBookSourceBinding {
return ItemBookSourceBinding.inflate(inflater, parent, false) 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_search -> callBack.searchBook(source)
R.id.menu_debug_source -> callBack.debug(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 -> { R.id.menu_enable_explore -> {
callBack.update(source.copy(enabledExplore = !source.enabledExplore)) callBack.update(source.copy(enabledExplore = !source.enabledExplore))
} }
@@ -5,6 +5,7 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity 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.data.entities.TxtTocRule
import io.legado.app.databinding.ActivityTxtTocRuleBinding import io.legado.app.databinding.ActivityTxtTocRuleBinding
import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.DirectLinkUpload
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.primaryColor 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.SelectActionBar
import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
@@ -27,7 +33,8 @@ import kotlinx.coroutines.launch
class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleViewModel>(), class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleViewModel>(),
TxtTocRuleAdapter.CallBack, TxtTocRuleAdapter.CallBack,
SelectActionBar.CallBack, SelectActionBar.CallBack,
TxtTocRuleEditDialog.Callback { TxtTocRuleEditDialog.Callback,
PopupMenu.OnMenuItemClickListener {
override val viewModel: TxtTocRuleViewModel by viewModels() override val viewModel: TxtTocRuleViewModel by viewModels()
override val binding: ActivityTxtTocRuleBinding by viewBinding(ActivityTxtTocRuleBinding::inflate) override val binding: ActivityTxtTocRuleBinding by viewBinding(ActivityTxtTocRuleBinding::inflate)
@@ -35,6 +42,38 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
TxtTocRuleAdapter(this, this) TxtTocRuleAdapter(this, this)
} }
private val importTocRuleKey = "tocRuleUrl" 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?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
initView() initView()
@@ -59,20 +98,22 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
private fun initBottomActionBar() { private fun initBottomActionBar() {
binding.selectActionBar.setMainActionText(R.string.delete) binding.selectActionBar.setMainActionText(R.string.delete)
binding.selectActionBar.inflateMenu(R.menu.txt_toc_rule_sel)
binding.selectActionBar.setOnMenuItemClickListener(this)
binding.selectActionBar.setCallBack(this) binding.selectActionBar.setCallBack(this)
} }
private fun initData() { private fun initData() {
launch { launch {
appDb.txtTocRuleDao.observeAll().conflate().collect { tocRules -> appDb.txtTocRuleDao.observeAll().conflate().collect { tocRules ->
adapter.setItems(tocRules) adapter.setItems(tocRules, adapter.diffItemCallBack)
upCountView() upCountView()
} }
} }
} }
override fun onCompatCreateOptionsMenu(menu: Menu): Boolean { 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) return super.onCompatCreateOptionsMenu(menu)
} }
@@ -84,9 +125,15 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.menu_add -> showDialogFragment(TxtTocRuleEditDialog()) R.id.menu_add -> showDialogFragment(TxtTocRuleEditDialog())
R.id.menu_default -> viewModel.importDefault() R.id.menu_import_local -> importDoc.launch {
R.id.menu_import -> showImportDialog() mode = HandleFileContract.FILE
R.id.menu_help -> showTxtTocRegexHelp() 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) return super.onCompatOptionsItemSelected(item)
} }
@@ -182,18 +229,32 @@ class TxtTocRuleActivity : VMBaseActivity<ActivityTxtTocRuleBinding, TxtTocRuleV
cacheUrls.add(0, it) cacheUrls.add(0, it)
aCache.put(importTocRuleKey, cacheUrls.joinToString(",")) aCache.put(importTocRuleKey, cacheUrls.joinToString(","))
} }
viewModel.importOnLine(it) { msg -> showDialogFragment(ImportTxtTocRuleDialog(it))
toastOnUi(msg)
}
} }
} }
cancelButton() cancelButton()
} }
} }
private fun showTxtTocRegexHelp() { private fun showTxtTocRuleHelp() {
val text = String(assets.open("help/txtTocRegexHelp.md").readBytes()) val text = String(assets.open("help/txtTocRuleHelp.md").readBytes())
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD)) 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
}
}
@@ -6,10 +6,12 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.PopupMenu import android.widget.PopupMenu
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter 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.data.entities.TxtTocRule
import io.legado.app.databinding.ItemTxtTocRuleBinding import io.legado.app.databinding.ItemTxtTocRuleBinding
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
@@ -28,6 +30,43 @@ class TxtTocRuleAdapter(context: Context, private val callBack: CallBack) :
selected.contains(it) 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 { override fun getViewBinding(parent: ViewGroup): ItemTxtTocRuleBinding {
return ItemTxtTocRuleBinding.inflate(inflater, parent, false) return ItemTxtTocRuleBinding.inflate(inflater, parent, false)
} }
@@ -50,6 +89,9 @@ class TxtTocRuleAdapter(context: Context, private val callBack: CallBack) :
bundle.keySet().map { bundle.keySet().map {
when (it) { when (it) {
"selected" -> cbSource.isChecked = selected.contains(item) "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) { when (menuItem.itemId) {
R.id.menu_top -> callBack.toTop(source) R.id.menu_top -> callBack.toTop(source)
R.id.menu_bottom -> callBack.toBottom(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 true
} }
@@ -61,8 +61,8 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
binding.toolBar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
durRegex = arguments?.getString("tocRegex") durRegex = arguments?.getString("tocRegex")
binding.toolBar.setTitle(R.string.txt_toc_regex) binding.toolBar.setTitle(R.string.txt_toc_rule)
binding.toolBar.inflateMenu(R.menu.txt_toc_regex) binding.toolBar.inflateMenu(R.menu.txt_toc_rule)
binding.toolBar.menu.applyTint(requireContext()) binding.toolBar.menu.applyTint(requireContext())
binding.toolBar.menu.findItem(R.id.menu_split_long_chapter) binding.toolBar.menu.findItem(R.id.menu_split_long_chapter)
?.isChecked = ReadBook.book?.getSplitLongChapter() == true ?.isChecked = ReadBook.book?.getSplitLongChapter() == true
@@ -125,7 +125,7 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
item.isChecked = !item.isChecked item.isChecked = !item.isChecked
if (!item.isChecked) context?.longToastOnUi(R.string.need_more_time_load_content) if (!item.isChecked) context?.longToastOnUi(R.string.need_more_time_load_content)
} }
R.id.menu_help -> showTxtTocRegexHelp() R.id.menu_help -> showTxtTocRuleHelp()
} }
return false return false
} }
@@ -170,8 +170,8 @@ class TxtTocRuleDialog() : BaseDialogFragment(R.layout.dialog_toc_regex),
} }
} }
private fun showTxtTocRegexHelp() { private fun showTxtTocRuleHelp() {
val text = String(requireContext().assets.open("help/txtTocRegexHelp.md").readBytes()) val text = String(requireContext().assets.open("help/txtTocRuleHelp.md").readBytes())
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD)) showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
} }
@@ -3,6 +3,7 @@ package io.legado.app.ui.book.toc.rule
import android.app.Application import android.app.Application
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.DictRule
import io.legado.app.data.entities.TxtTocRule import io.legado.app.data.entities.TxtTocRule
import io.legado.app.help.DefaultData import io.legado.app.help.DefaultData
import io.legado.app.help.http.newCallResponseBody 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)
}
}
}
@@ -21,6 +21,7 @@ import io.legado.app.ui.association.ImportDictRuleDialog
import io.legado.app.ui.document.HandleFileContract import io.legado.app.ui.document.HandleFileContract
import io.legado.app.ui.qrcode.QrCodeResult import io.legado.app.ui.qrcode.QrCodeResult
import io.legado.app.ui.widget.SelectActionBar 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.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
@@ -120,15 +121,15 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.menu_create -> showDialogFragment<DictRuleEditDialog>() R.id.menu_add -> showDialogFragment<DictRuleEditDialog>()
R.id.menu_import_default -> viewModel.importDefault()
R.id.menu_import_local -> importDoc.launch { R.id.menu_import_local -> importDoc.launch {
mode = HandleFileContract.FILE mode = HandleFileContract.FILE
allowExtensions = arrayOf("txt", "json") allowExtensions = arrayOf("txt", "json")
} }
R.id.menu_import_onLine -> showImportDialog() R.id.menu_import_onLine -> showImportDialog()
R.id.menu_import_qr -> qrCodeResult.launch() 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) return super.onCompatOptionsItemSelected(item)
} }
@@ -195,7 +196,7 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
.getAsString(importRecordKey) .getAsString(importRecordKey)
?.splitNotBlank(",") ?.splitNotBlank(",")
?.toMutableList() ?: mutableListOf() ?.toMutableList() ?: mutableListOf()
alert(titleResource = R.string.import_replace_rule_on_line) { alert(titleResource = R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = "url" editView.hint = "url"
editView.setFilterValues(cacheUrls) editView.setFilterValues(cacheUrls)
@@ -220,4 +221,9 @@ class DictRuleActivity : VMBaseActivity<ActivityDictRuleBinding, DictRuleViewMod
cancelButton() cancelButton()
} }
} }
}
private fun showDictRuleHelp() {
val text = String(assets.open("help/dictRuleHelp.md").readBytes())
showDialogFragment(TextDialog(getString(R.string.help), text, TextDialog.Mode.MD))
}
}
@@ -141,6 +141,7 @@ class DictRuleAdapter(context: Context, var callBack: CallBack) :
ivDelete.setOnClickListener { ivDelete.setOnClickListener {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.delete(it) callBack.delete(it)
selected.remove(it)
} }
} }
} }
@@ -41,19 +41,15 @@ class DictRuleViewModel(application: Application) : BaseViewModel(application) {
fun enableSelection(vararg dictRule: DictRule) { fun enableSelection(vararg dictRule: DictRule) {
execute { execute {
dictRule.forEach { val array = dictRule.map { it.copy(enabled = true) }.toTypedArray()
it.enabled = true appDb.dictRuleDao.insert(*array)
}
appDb.dictRuleDao.insert(*dictRule)
} }
} }
fun disableSelection(vararg dictRule: DictRule) { fun disableSelection(vararg dictRule: DictRule) {
execute { execute {
dictRule.forEach { val array = dictRule.map { it.copy(enabled = false) }.toTypedArray()
it.enabled = false appDb.dictRuleDao.insert(*array)
}
appDb.dictRuleDao.insert(*dictRule)
} }
} }
@@ -139,7 +139,7 @@ class MyFragment : BaseFragment(R.layout.fragment_my_config) {
"bookSourceManage" -> startActivity<BookSourceActivity>() "bookSourceManage" -> startActivity<BookSourceActivity>()
"replaceManage" -> startActivity<ReplaceRuleActivity>() "replaceManage" -> startActivity<ReplaceRuleActivity>()
"dictRuleManage" -> startActivity<DictRuleActivity>() "dictRuleManage" -> startActivity<DictRuleActivity>()
"txtTocRegexManage" -> startActivity<TxtTocRuleActivity>() "txtTocRuleManage" -> startActivity<TxtTocRuleActivity>()
"bookmark" -> startActivity<AllBookmarkActivity>() "bookmark" -> startActivity<AllBookmarkActivity>()
"setting" -> startActivity<ConfigActivity> { "setting" -> startActivity<ConfigActivity> {
putExtra("configTag", ConfigTag.OTHER_CONFIG) putExtra("configTag", ConfigTag.OTHER_CONFIG)
@@ -270,7 +270,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
.getAsString(importRecordKey) .getAsString(importRecordKey)
?.splitNotBlank(",") ?.splitNotBlank(",")
?.toMutableList() ?: mutableListOf() ?.toMutableList() ?: mutableListOf()
alert(titleResource = R.string.import_replace_rule_on_line) { alert(titleResource = R.string.import_on_line) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply { val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = "url" editView.hint = "url"
editView.setFilterValues(cacheUrls) editView.setFilterValues(cacheUrls)
@@ -160,7 +160,10 @@ class ReplaceRuleAdapter(context: Context, var callBack: CallBack) :
when (menuItem.itemId) { when (menuItem.itemId) {
R.id.menu_top -> callBack.toTop(item) R.id.menu_top -> callBack.toTop(item)
R.id.menu_bottom -> callBack.toBottom(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 true
} }
@@ -179,7 +179,10 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
when (menuItem.itemId) { when (menuItem.itemId) {
R.id.menu_top -> callBack.toTop(source) R.id.menu_top -> callBack.toTop(source)
R.id.menu_bottom -> callBack.toBottom(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 true
} }
@@ -9,10 +9,7 @@
android:id="@+id/title_bar" android:id="@+id/title_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:contentInsetStartWithNavigation="0dp" app:title="@string/txt_toc_rule" />
app:contentLayout="@layout/view_search"
app:displayHomeAsUp="true"
app:title="@string/txt_toc_regex" />
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -24,7 +24,7 @@
app:displayHomeAsUp="false" app:displayHomeAsUp="false"
app:fitStatusBar="false" app:fitStatusBar="false"
app:popupTheme="@style/AppTheme.PopupOverlay" app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="@string/txt_toc_regex" app:title="@string/txt_toc_rule"
app:titleTextAppearance="@style/ToolbarTitle" /> app:titleTextAppearance="@style/ToolbarTitle" />
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
+1 -1
View File
@@ -29,7 +29,7 @@
<item <item
android:id="@+id/menu_toc_regex" android:id="@+id/menu_toc_regex"
android:icon="@drawable/ic_exchange" android:icon="@drawable/ic_exchange"
android:title="@string/txt_toc_regex" android:title="@string/txt_toc_rule"
android:visible="false" android:visible="false"
app:showAsAction="always" /> app:showAsAction="always" />
</group> </group>
+1 -1
View File
@@ -16,7 +16,7 @@
<item <item
android:id="@+id/menu_toc_regex" android:id="@+id/menu_toc_regex"
android:title="@string/txt_toc_regex" android:title="@string/txt_toc_rule"
app:showAsAction="never" /> app:showAsAction="never" />
</group> </group>
+1 -1
View File
@@ -5,7 +5,7 @@
tools:ignore="AlwaysShowAction"> tools:ignore="AlwaysShowAction">
<item <item
android:id="@+id/menu_create" android:id="@+id/menu_add"
android:icon="@drawable/ic_add" android:icon="@drawable/ic_add"
android:title="@string/create" android:title="@string/create"
app:showAsAction="always" /> app:showAsAction="always" />
@@ -11,14 +11,26 @@
tools:ignore="AlwaysShowAction" /> tools:ignore="AlwaysShowAction" />
<item <item
android:id="@+id/menu_default" android:id="@+id/menu_import_local"
android:title="@string/import_default_rule" 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" android:icon="@drawable/ic_import"
app:showAsAction="never" /> app:showAsAction="never" />
<item <item
android:id="@+id/menu_import" android:id="@+id/menu_import_qr"
android:title="@string/import_replace_rule_on_line" 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" android:icon="@drawable/ic_import"
app:showAsAction="never" /> app:showAsAction="never" />
@@ -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>
+3 -2
View File
@@ -342,7 +342,7 @@
<string name="pt_show_all_find">Mostrar todos los buscados</string> <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="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="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="set_charset">Codificación de texto</string>
<string name="swap_sort">Orden ascendente/descendente</string> <string name="swap_sort">Orden ascendente/descendente</string>
<string name="sort">Ordenar</string> <string name="sort">Ordenar</string>
@@ -1077,5 +1077,6 @@
<string name="create">新建</string> <string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string> <string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</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> </resources>
+3 -2
View File
@@ -346,7 +346,7 @@
<string name="pt_show_all_find">Display all Discovery</string> <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="ps_show_all_find">Display the selected origin\'s Discovery if closed</string>
<string name="update_toc">Update chapters</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="set_charset">Text encoding</string>
<string name="swap_sort">Ascending/Descending order</string> <string name="swap_sort">Ascending/Descending order</string>
<string name="sort">Sort</string> <string name="sort">Sort</string>
@@ -1080,5 +1080,6 @@
<string name="create">新建</string> <string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string> <string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</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> </resources>
+3 -2
View File
@@ -344,7 +344,7 @@
<string name="pt_show_all_find">Mostrar todas as Descobertas</string> <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="ps_show_all_find">Mostrar a fonte da Descoberta selecionada se encerrado</string>
<string name="update_toc">Atualizar os capítulos</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="set_charset">Codificação de texto</string>
<string name="swap_sort">Ordem ascendente/descendente</string> <string name="swap_sort">Ordem ascendente/descendente</string>
<string name="sort">Ordenar</string> <string name="sort">Ordenar</string>
@@ -1080,5 +1080,6 @@
<string name="create">新建</string> <string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string> <string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</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> </resources>
+3 -2
View File
@@ -343,7 +343,7 @@
<string name="pt_show_all_find">顯示所有發現</string> <string name="pt_show_all_find">顯示所有發現</string>
<string name="ps_show_all_find">關閉則只顯示勾選源的發現</string> <string name="ps_show_all_find">關閉則只顯示勾選源的發現</string>
<string name="update_toc">更新目錄</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="set_charset">設置編碼</string>
<string name="swap_sort">倒序-順序</string> <string name="swap_sort">倒序-順序</string>
<string name="sort">排序</string> <string name="sort">排序</string>
@@ -1077,5 +1077,6 @@
<string name="create">新建</string> <string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string> <string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</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> </resources>
+3 -2
View File
@@ -345,7 +345,7 @@
<string name="pt_show_all_find">顯示所有發現</string> <string name="pt_show_all_find">顯示所有發現</string>
<string name="ps_show_all_find">關閉則只顯示勾選源的發現</string> <string name="ps_show_all_find">關閉則只顯示勾選源的發現</string>
<string name="update_toc">更新目錄</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="set_charset">設定編碼</string>
<string name="swap_sort">倒序-順序</string> <string name="swap_sort">倒序-順序</string>
<string name="sort">排序</string> <string name="sort">排序</string>
@@ -1079,5 +1079,6 @@
<string name="create">新建</string> <string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string> <string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</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> </resources>
+3 -2
View File
@@ -345,7 +345,7 @@
<string name="pt_show_all_find">显示所有发现</string> <string name="pt_show_all_find">显示所有发现</string>
<string name="ps_show_all_find">关闭则只显示勾选源的发现</string> <string name="ps_show_all_find">关闭则只显示勾选源的发现</string>
<string name="update_toc">更新目录</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="set_charset">设置编码</string>
<string name="swap_sort">倒序-顺序</string> <string name="swap_sort">倒序-顺序</string>
<string name="sort">排序</string> <string name="sort">排序</string>
@@ -1079,5 +1079,6 @@
<string name="create">新建</string> <string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string> <string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</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> </resources>
+3 -2
View File
@@ -346,7 +346,7 @@
<string name="pt_show_all_find">Display all Discovery</string> <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="ps_show_all_find">Display the selected origin\'s Discovery if closed</string>
<string name="update_toc">Update chapters</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="set_charset">Text encoding</string>
<string name="swap_sort">Ascending/Descending order</string> <string name="swap_sort">Ascending/Descending order</string>
<string name="sort">Sort</string> <string name="sort">Sort</string>
@@ -1080,5 +1080,6 @@
<string name="create">新建</string> <string name="create">新建</string>
<string name="url_rule">url规则(urlRule)</string> <string name="url_rule">url规则(urlRule)</string>
<string name="show_rule">显示规则(showRule)</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> </resources>
+3 -3
View File
@@ -13,9 +13,9 @@
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<io.legado.app.lib.prefs.Preference <io.legado.app.lib.prefs.Preference
android:key="txtTocRegexManage" android:key="txtTocRuleManage"
android:title="@string/txt_toc_regex" android:title="@string/txt_toc_rule"
android:summary="@string/config_txt_toc_regex" android:summary="@string/config_txt_toc_rule"
android:icon="@drawable/ic_cfg_source" android:icon="@drawable/ic_cfg_source"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />