Merge pull request #9 from gedoor/master

merge
pull/441/head
口口吕 4 years ago committed by GitHub
commit 897d3fd8ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/src/main/assets/updateLog.md
  2. 9
      app/src/main/java/io/legado/app/data/dao/BookDao.kt
  3. 12
      app/src/main/java/io/legado/app/data/dao/BookGroupDao.kt
  4. 23
      app/src/main/java/io/legado/app/data/entities/BookChapter.kt
  5. 14
      app/src/main/java/io/legado/app/data/entities/BookGroup.kt
  6. 39
      app/src/main/java/io/legado/app/data/entities/RssSource.kt
  7. 19
      app/src/main/java/io/legado/app/help/BookHelp.kt
  8. 16
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSoup.kt
  9. 14
      app/src/main/java/io/legado/app/ui/about/AboutFragment.kt
  10. 45
      app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt
  11. 42
      app/src/main/java/io/legado/app/ui/book/read/config/BgAdapter.kt
  12. 38
      app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
  13. 8
      app/src/main/java/io/legado/app/ui/main/MainActivity.kt
  14. 21
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt
  15. 25
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt
  16. 22
      app/src/main/java/io/legado/app/ui/main/my/MyFragment.kt
  17. 17
      app/src/main/java/io/legado/app/ui/widget/SearchView.kt
  18. 5
      app/src/main/java/io/legado/app/ui/widget/image/CircleImageView.kt
  19. 20
      app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt
  20. 42
      app/src/main/java/io/legado/app/ui/widget/image/FilletImageView.kt
  21. 408
      app/src/main/java/io/legado/app/ui/widget/image/PhotoView.kt
  22. 2
      app/src/main/java/io/legado/app/ui/widget/text/AccentBgTextView.kt
  23. 13
      app/src/main/java/io/legado/app/ui/widget/text/AutoCompleteTextView.kt
  24. 10
      app/src/main/java/io/legado/app/utils/ContextExtensions.kt
  25. 43
      app/src/main/java/io/legado/app/utils/EncodingDetect.java
  26. 2
      app/src/main/java/io/legado/app/utils/Toasts.kt

@ -3,6 +3,9 @@
* 关注合作公众号 **[小说拾遗]()** 获取好看的小说。
* 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。
**2020/10/20**
* 默认分组无书籍时自动隐藏
**2020/10/19**
* 优化分组管理
* 修复预下载没有保存的bug

@ -18,16 +18,9 @@ interface BookDao {
@Query("SELECT * FROM books WHERE origin = '${BookType.local}'")
fun observeLocal(): LiveData<List<Book>>
@Query(
"""
select * from books where ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0 and type != ${BookType.audio} and origin != '${BookType.local}'
"""
)
@Query("select * from books where type != ${BookType.audio} and origin != '${BookType.local}' and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0")
fun observeNoGroup(): LiveData<List<Book>>
@Query("select count(bookUrl) from books where (SELECT sum(groupId) FROM book_groups where groupId > 0) & `group` = 0")
fun observeNoGroupSize(): LiveData<Int>
@Query("SELECT bookUrl FROM books WHERE origin = '${BookType.local}'")
fun observeLocalUri(): LiveData<List<String>>

@ -2,6 +2,7 @@ package io.legado.app.data.dao
import androidx.lifecycle.LiveData
import androidx.room.*
import io.legado.app.constant.BookType
import io.legado.app.data.entities.BookGroup
@Dao
@ -16,7 +17,16 @@ interface BookGroupDao {
@Query("SELECT * FROM book_groups ORDER BY `order`")
fun liveDataAll(): LiveData<List<BookGroup>>
@Query("SELECT * FROM book_groups where show > 0 or groupId >= 0 ORDER BY `order`")
@Query(
"""
SELECT * FROM book_groups where groupId >= 0
or (groupId = -4 and show > 0 and (select count(bookUrl) from books where type != ${BookType.audio} and origin != '${BookType.local}' and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0) > 0)
or (groupId = -3 and show > 0 and (select count(bookUrl) from books where type = ${BookType.audio}) > 0)
or (groupId = -2 and show > 0 and (select count(bookUrl) from books where origin = '${BookType.local}') > 0)
or (groupId = -1 and show > 0)
ORDER BY `order`
"""
)
fun liveDataShow(): LiveData<List<BookGroup>>
@Query("SELECT * FROM book_groups where groupId >= 0 ORDER BY `order`")

@ -36,25 +36,26 @@ data class BookChapter(
var variable: String? = null //变量
) : Parcelable {
@Ignore
@delegate:Transient
@delegate:Ignore
@IgnoredOnParcel
var variableMap: HashMap<String, String>? = null
private set
get() {
if (field == null) {
field = GSON.fromJsonObject<HashMap<String, String>>(variable) ?: HashMap()
}
return field
}
val variableMap by lazy {
GSON.fromJsonObject<HashMap<String, String>>(variable) ?: HashMap()
}
fun putVariable(key: String, value: String) {
variableMap?.put(key, value)
variableMap[key] = value
variable = GSON.toJson(variableMap)
}
override fun hashCode() = url.hashCode()
override fun equals(other: Any?) = if (other is BookChapter) other.url == url else false
override fun equals(other: Any?): Boolean {
if (other is BookChapter) {
return other.url == url
}
return false
}
}

@ -28,4 +28,18 @@ data class BookGroup(
}
}
override fun hashCode(): Int {
return groupId.hashCode()
}
override fun equals(other: Any?): Boolean {
if (other is BookGroup) {
return other.groupId == groupId
&& other.groupName == groupName
&& other.order == order
&& other.show == show
}
return false
}
}

@ -41,9 +41,14 @@ data class RssSource(
var loadWithBaseUrl: Boolean = false,
var customOrder: Int = 0
): Parcelable, JsExtensions {
) : Parcelable, JsExtensions {
override fun equals(other: Any?) = if (other is RssSource) other.sourceUrl == sourceUrl else false
override fun equals(other: Any?): Boolean {
if (other is RssSource) {
return other.sourceUrl == sourceUrl
}
return false
}
override fun hashCode() = sourceUrl.hashCode()
@ -69,22 +74,26 @@ data class RssSource(
* 执行JS
*/
@Throws(Exception::class)
private fun evalJS(jsStr: String): Any = AppConst.SCRIPT_ENGINE.eval(jsStr, SimpleBindings().apply { this["java"] = this@RssSource })
private fun evalJS(jsStr: String): Any? {
val bindings = SimpleBindings()
bindings["java"] = this
return AppConst.SCRIPT_ENGINE.eval(jsStr, bindings)
}
fun equal(source: RssSource): Boolean {
return equal(sourceUrl, source.sourceUrl)
&& equal(sourceIcon, source.sourceIcon)
&& enabled == source.enabled
&& equal(sourceGroup, source.sourceGroup)
&& equal(ruleArticles, source.ruleArticles)
&& equal(ruleNextPage, source.ruleNextPage)
&& equal(ruleTitle, source.ruleTitle)
&& equal(rulePubDate, source.rulePubDate)
&& equal(ruleDescription, source.ruleDescription)
&& equal(ruleLink, source.ruleLink)
&& equal(ruleContent, source.ruleContent)
&& enableJs == source.enableJs
&& loadWithBaseUrl == source.loadWithBaseUrl
&& equal(sourceIcon, source.sourceIcon)
&& enabled == source.enabled
&& equal(sourceGroup, source.sourceGroup)
&& equal(ruleArticles, source.ruleArticles)
&& equal(ruleNextPage, source.ruleNextPage)
&& equal(ruleTitle, source.ruleTitle)
&& equal(rulePubDate, source.rulePubDate)
&& equal(ruleDescription, source.ruleDescription)
&& equal(ruleLink, source.ruleLink)
&& equal(ruleContent, source.ruleContent)
&& enableJs == source.enableJs
&& loadWithBaseUrl == source.loadWithBaseUrl
}
private fun equal(a: String?, b: String?): Boolean {

@ -11,7 +11,6 @@ import io.legado.app.help.coroutine.Coroutine
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.model.localBook.LocalBook
import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
@ -307,17 +306,13 @@ object BookHelp {
private var replaceRules: List<ReplaceRule> = arrayListOf()
@Synchronized
suspend fun upReplaceRules() {
withContext(IO) {
synchronized(this) {
val o = bookOrigin
bookName?.let {
replaceRules = if (o.isNullOrEmpty()) {
App.db.replaceRuleDao().findEnabledByScope(it)
} else {
App.db.replaceRuleDao().findEnabledByScope(it, o)
}
}
fun upReplaceRules() {
val o = bookOrigin
bookName?.let {
replaceRules = if (o.isNullOrEmpty()) {
App.db.replaceRuleDao().findEnabledByScope(it)
} else {
App.db.replaceRuleDao().findEnabledByScope(it, o)
}
}
}

@ -196,20 +196,20 @@ class AnalyzeByJSoup {
private fun filterElements(elements: Elements, rules: Array<String>?): Elements {
if (rules == null || rules.size < 2) return elements
val selectedEls = Elements()
for (ele in elements) {
val result = Elements()
for (element in elements) {
var isOk = false
when (rules[0]) {
"class" -> isOk = ele.getElementsByClass(rules[1]).size > 0
"id" -> isOk = ele.getElementById(rules[1]) != null
"tag" -> isOk = ele.getElementsByTag(rules[1]).size > 0
"text" -> isOk = ele.getElementsContainingOwnText(rules[1]).size > 0
"class" -> isOk = element.getElementsByClass(rules[1]).size > 0
"id" -> isOk = element.getElementById(rules[1]) != null
"tag" -> isOk = element.getElementsByTag(rules[1]).size > 0
"text" -> isOk = element.getElementsContainingOwnText(rules[1]).size > 0
}
if (isOk) {
selectedEls.add(ele)
result.add(element)
}
}
return selectedEls
return result
}
/**

@ -13,8 +13,8 @@ import io.legado.app.lib.dialogs.alert
import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.applyTint
import io.legado.app.utils.openUrl
import io.legado.app.utils.sendMail
import io.legado.app.utils.sendToClip
import io.legado.app.utils.toast
class AboutFragment : PreferenceFragmentCompat() {
@ -48,7 +48,7 @@ class AboutFragment : PreferenceFragmentCompat() {
"contributors" -> openUrl(R.string.contributors_url)
"update_log" -> showUpdateLog()
"check_update" -> openUrl(R.string.latest_release_url)
"mail" -> sendMail()
"mail" -> requireContext().sendMail("kunfei.ge@gmail.com")
"sourceRuleSummary" -> openUrl(R.string.source_rule_url)
"git" -> openUrl(R.string.this_github_url)
"home_page" -> openUrl(R.string.home_page_url)
@ -66,16 +66,6 @@ class AboutFragment : PreferenceFragmentCompat() {
requireContext().openUrl(getString(addressID))
}
private fun sendMail() {
try {
val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:kunfei.ge@gmail.com")
startActivity(intent)
} catch (e: Exception) {
toast(e.localizedMessage ?: "Error")
}
}
private fun showUpdateLog() {
val log = String(requireContext().assets.open("updateLog.md").readBytes())
TextDialog.show(childFragmentManager, log, TextDialog.MD)

@ -21,37 +21,30 @@ import kotlinx.android.synthetic.main.view_read_menu.view.*
import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick
class ReadMenu : FrameLayout {
/**
* 阅读界面菜单
*/
class ReadMenu @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
var cnaShowMenu: Boolean = false
private var callBack: CallBack? = null
private val callBack: CallBack? get() = activity as? CallBack
private lateinit var menuTopIn: Animation
private lateinit var menuTopOut: Animation
private lateinit var menuBottomIn: Animation
private lateinit var menuBottomOut: Animation
private val bgColor: Int
private val textColor: Int
private var bottomBackgroundList: ColorStateList
private val bgColor: Int = context.bottomBackground
private val textColor: Int = context.getPrimaryTextColor(ColorUtils.isColorLight(bgColor))
private val bottomBackgroundList: ColorStateList = Selector.colorBuild()
.setDefaultColor(bgColor)
.setPressedColor(ColorUtils.darkenColor(bgColor))
.create()
private var onMenuOutEnd: (() -> Unit)? = null
val showBrightnessView get() = context.getPrefBoolean(PreferKey.showBrightnessView, true)
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
init {
callBack = activity as? CallBack
bgColor = context.bottomBackground
textColor = context.getPrimaryTextColor(ColorUtils.isColorLight(bgColor))
bottomBackgroundList = Selector.colorBuild()
.setDefaultColor(bgColor)
.setPressedColor(ColorUtils.darkenColor(bgColor))
.create()
inflate(context, R.layout.view_read_menu, this)
if (AppConfig.isNightTheme) {
fabNightTheme.setImageResource(R.drawable.ic_daytime)
@ -254,9 +247,7 @@ class ReadMenu : FrameLayout {
}
}
override fun onAnimationRepeat(animation: Animation) {
}
override fun onAnimationRepeat(animation: Animation) = Unit
})
//隐藏菜单
@ -277,9 +268,7 @@ class ReadMenu : FrameLayout {
callBack?.upSystemUiVisibility()
}
override fun onAnimationRepeat(animation: Animation) {
}
override fun onAnimationRepeat(animation: Animation) = Unit
})
}

@ -0,0 +1,42 @@
package io.legado.app.ui.book.read.config
import android.content.Context
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.EventBus
import io.legado.app.help.ImageLoader
import io.legado.app.help.ReadBookConfig
import io.legado.app.utils.postEvent
import kotlinx.android.synthetic.main.item_bg_image.view.*
import org.jetbrains.anko.sdk27.listeners.onClick
import java.io.File
class BgAdapter(context: Context, val textColor: Int) :
SimpleRecyclerAdapter<String>(context, R.layout.item_bg_image) {
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) {
with(holder.itemView) {
ImageLoader.load(
context,
context.assets.open("bg${File.separator}$item").readBytes()
)
.centerCrop()
.into(iv_bg)
tv_name.setTextColor(textColor)
tv_name.text = item.substringBeforeLast(".")
}
}
override fun registerListener(holder: ItemViewHolder) {
holder.itemView.apply {
this.onClick {
getItemByLayoutPosition(holder.layoutPosition)?.let {
ReadBookConfig.durConfig.setCurBg(1, it)
ReadBookConfig.upBg()
postEvent(EventBus.UP_CONFIG, false)
}
}
}
}
}

@ -2,7 +2,6 @@ package io.legado.app.ui.book.read.config
import android.annotation.SuppressLint
import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Color
@ -14,10 +13,7 @@ import androidx.documentfile.provider.DocumentFile
import com.jaredrummler.android.colorpicker.ColorPickerDialog
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.EventBus
import io.legado.app.help.ImageLoader
import io.legado.app.help.ReadBookConfig
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.permission.Permissions
@ -53,8 +49,8 @@ class BgTextConfigDialog : BaseDialogFragment(), FileChooserDialog.CallBack {
private val requestCodeImport = 132
private val configFileName = "readConfig.zip"
private lateinit var adapter: BgAdapter
var primaryTextColor = 0
var secondaryTextColor = 0
private var primaryTextColor = 0
private var secondaryTextColor = 0
override fun onStart() {
super.onStart()
@ -109,7 +105,7 @@ class BgTextConfigDialog : BaseDialogFragment(), FileChooserDialog.CallBack {
@SuppressLint("InflateParams")
private fun initData() = with(ReadBookConfig.durConfig) {
sw_dark_status_icon.isChecked = curStatusIconDark()
adapter = BgAdapter(requireContext())
adapter = BgAdapter(requireContext(), secondaryTextColor)
recycler_view.adapter = adapter
val headerView = LayoutInflater.from(requireContext())
.inflate(R.layout.item_bg_image, recycler_view, false)
@ -119,7 +115,7 @@ class BgTextConfigDialog : BaseDialogFragment(), FileChooserDialog.CallBack {
headerView.iv_bg.setImageResource(R.drawable.ic_image)
headerView.iv_bg.setColorFilter(primaryTextColor)
headerView.onClick { selectImage() }
requireContext().assets.list("bg/")?.let {
requireContext().assets.list("bg${File.separator}")?.let {
adapter.setItems(it.toList())
}
}
@ -189,32 +185,6 @@ class BgTextConfigDialog : BaseDialogFragment(), FileChooserDialog.CallBack {
startActivityForResult(intent, requestCodeBg)
}
inner class BgAdapter(context: Context) :
SimpleRecyclerAdapter<String>(context, R.layout.item_bg_image) {
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) {
with(holder.itemView) {
ImageLoader.load(context, context.assets.open("bg/$item").readBytes())
.centerCrop()
.into(iv_bg)
tv_name.setTextColor(secondaryTextColor)
tv_name.text = item.substringBeforeLast(".")
}
}
override fun registerListener(holder: ItemViewHolder) {
holder.itemView.apply {
this.onClick {
getItemByLayoutPosition(holder.layoutPosition)?.let {
ReadBookConfig.durConfig.setCurBg(1, it)
ReadBookConfig.upBg()
postEvent(EventBus.UP_CONFIG, false)
}
}
}
}
}
@Suppress("BlockingMethodInNonBlockingContext")
private fun exportConfig(uri: Uri) {
execute {

@ -191,10 +191,10 @@ class MainActivity : VMBaseActivity<MainViewModel>(R.layout.activity_main),
override fun getItem(position: Int): Fragment {
return when (getId(position)) {
0 -> BookshelfFragment()
1 -> ExploreFragment()
2 -> RssFragment()
else -> MyFragment()
0 -> fragmentMap[0] ?: BookshelfFragment()
1 -> fragmentMap[1] ?: ExploreFragment()
2 -> fragmentMap[2] ?: RssFragment()
else -> fragmentMap[3] ?: MyFragment()
}
}

@ -105,11 +105,12 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
private fun initBookGroupData() {
bookGroupLiveData?.removeObservers(viewLifecycleOwner)
bookGroupLiveData = App.db.bookGroupDao().liveDataShow()
bookGroupLiveData?.observe(viewLifecycleOwner, {
viewModel.checkGroup(it)
upGroup(it)
})
bookGroupLiveData = App.db.bookGroupDao().liveDataShow().apply {
observe(viewLifecycleOwner) {
viewModel.checkGroup(it)
upGroup(it)
}
}
}
override fun onQueryTextSubmit(query: String?): Boolean {
@ -126,10 +127,12 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
if (data.isEmpty()) {
App.db.bookGroupDao().enableGroup(AppConst.bookGroupAllId)
} else {
bookGroups.clear()
bookGroups.addAll(data)
adapter.notifyDataSetChanged()
selectLastTab()
if (data != bookGroups) {
bookGroups.clear()
bookGroups.addAll(data)
adapter.notifyDataSetChanged()
selectLastTab()
}
}
}

@ -107,19 +107,20 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
AppConst.bookGroupAudioId -> App.db.bookDao().observeAudio()
AppConst.bookGroupNoneId -> App.db.bookDao().observeNoGroup()
else -> App.db.bookDao().observeByGroup(groupId)
}
bookshelfLiveData?.observe(this, { list ->
tv_empty_msg.isGone = list.isNotEmpty()
val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> list.sortedByDescending { it.latestChapterTime }
2 -> list.sortedBy { it.name }
3 -> list.sortedBy { it.order }
else -> list.sortedByDescending { it.durChapterTime }
}.apply {
observe(viewLifecycleOwner) { list ->
tv_empty_msg.isGone = list.isNotEmpty()
val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> list.sortedByDescending { it.latestChapterTime }
2 -> list.sortedBy { it.name }
3 -> list.sortedBy { it.order }
else -> list.sortedByDescending { it.durChapterTime }
}
val diffResult = DiffUtil
.calculateDiff(BooksDiffCallBack(booksAdapter.getItems(), books))
booksAdapter.setItems(books, diffResult)
}
val diffResult = DiffUtil
.calculateDiff(BooksDiffCallBack(booksAdapter.getItems(), books))
booksAdapter.setItems(books, diffResult)
})
}
}
fun getBooks(): List<Book> {

@ -29,12 +29,8 @@ import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.ui.widget.prefs.NameListPreference
import io.legado.app.ui.widget.prefs.PreferenceCategory
import io.legado.app.ui.widget.prefs.SwitchPreference
import io.legado.app.utils.LogUtils
import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.observeEventSticky
import io.legado.app.utils.putPrefBoolean
import io.legado.app.utils.*
import kotlinx.android.synthetic.main.view_title_bar.*
import org.jetbrains.anko.startActivity
class MyFragment : BaseFragment(R.layout.fragment_my_config), FileChooserDialog.CallBack {
@ -138,20 +134,20 @@ class MyFragment : BaseFragment(R.layout.fragment_my_config), FileChooserDialog.
override fun onPreferenceTreeClick(preference: Preference?): Boolean {
when (preference?.key) {
"bookSourceManage" -> context?.startActivity<BookSourceActivity>()
"replaceManage" -> context?.startActivity<ReplaceRuleActivity>()
"setting" -> context?.startActivity<ConfigActivity>(
"bookSourceManage" -> startActivity<BookSourceActivity>()
"replaceManage" -> startActivity<ReplaceRuleActivity>()
"setting" -> startActivity<ConfigActivity>(
Pair("configType", ConfigViewModel.TYPE_CONFIG)
)
"web_dav_setting" -> context?.startActivity<ConfigActivity>(
"web_dav_setting" -> startActivity<ConfigActivity>(
Pair("configType", ConfigViewModel.TYPE_WEB_DAV_CONFIG)
)
"theme_setting" -> context?.startActivity<ConfigActivity>(
"theme_setting" -> startActivity<ConfigActivity>(
Pair("configType", ConfigViewModel.TYPE_THEME_CONFIG)
)
"readRecord" -> context?.startActivity<ReadRecordActivity>()
"donate" -> context?.startActivity<DonateActivity>()
"about" -> context?.startActivity<AboutActivity>()
"readRecord" -> startActivity<ReadRecordActivity>()
"donate" -> startActivity<DonateActivity>()
"about" -> startActivity<AboutActivity>()
}
return super.onPreferenceTreeClick(preference)
}

@ -16,21 +16,14 @@ import android.widget.TextView
import androidx.appcompat.widget.SearchView
import io.legado.app.R
class SearchView : SearchView {
class SearchView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : SearchView(context, attrs, defStyleAttr) {
private var mSearchHintIcon: Drawable? = null
private var textView: TextView? = null
constructor(
context: Context,
attrs: AttributeSet? = null
) : super(context, attrs)
constructor(
context: Context,
attrs: AttributeSet?,
defStyleAttr: Int
) : super(context, attrs, defStyleAttr)
@SuppressLint("UseCompatLoadingForDrawables")
override fun onLayout(
changed: Boolean,

@ -26,10 +26,7 @@ import kotlin.math.pow
@Suppress("unused", "MemberVisibilityCanBePrivate")
class CircleImageView(context: Context, attrs: AttributeSet) :
AppCompatImageView(
context,
attrs
) {
AppCompatImageView(context, attrs) {
private val mDrawableRect = RectF()
private val mBorderRect = RectF()

@ -20,7 +20,15 @@ import io.legado.app.utils.getPrefString
* 封面
*/
@Suppress("unused")
class CoverImageView : androidx.appcompat.widget.AppCompatImageView {
class CoverImageView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : androidx.appcompat.widget.AppCompatImageView(
context,
attrs,
defStyleAttr
) {
internal var width: Float = 0.toFloat()
internal var height: Float = 0.toFloat()
private var nameHeight = 0f
@ -45,16 +53,6 @@ class CoverImageView : androidx.appcompat.widget.AppCompatImageView {
private var author: String? = null
private var loadFailed = false
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val measuredWidth = MeasureSpec.getSize(widthMeasureSpec)
val measuredHeight = measuredWidth * 7 / 5

@ -10,7 +10,11 @@ import io.legado.app.R
import io.legado.app.utils.dp
import kotlin.math.max
class FilletImageView : AppCompatImageView {
class FilletImageView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {
internal var width: Float = 0.toFloat()
internal var height: Float = 0.toFloat()
private var leftTopRadius: Int = 0
@ -18,26 +22,29 @@ class FilletImageView : AppCompatImageView {
private var rightBottomRadius: Int = 0
private var leftBottomRadius: Int = 0
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init(context, attrs)
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init(context, attrs)
}
private fun init(context: Context, attrs: AttributeSet) {
init {
// 读取配置
val array = context.obtainStyledAttributes(attrs, R.styleable.FilletImageView)
val defaultRadius = 5.dp
val radius = array.getDimensionPixelOffset(R.styleable.FilletImageView_radius, defaultRadius)
leftTopRadius = array.getDimensionPixelOffset(R.styleable.FilletImageView_left_top_radius, defaultRadius)
rightTopRadius = array.getDimensionPixelOffset(R.styleable.FilletImageView_right_top_radius, defaultRadius)
val radius =
array.getDimensionPixelOffset(R.styleable.FilletImageView_radius, defaultRadius)
leftTopRadius = array.getDimensionPixelOffset(
R.styleable.FilletImageView_left_top_radius,
defaultRadius
)
rightTopRadius = array.getDimensionPixelOffset(
R.styleable.FilletImageView_right_top_radius,
defaultRadius
)
rightBottomRadius =
array.getDimensionPixelOffset(R.styleable.FilletImageView_right_bottom_radius, defaultRadius)
leftBottomRadius = array.getDimensionPixelOffset(R.styleable.FilletImageView_left_bottom_radius, defaultRadius)
array.getDimensionPixelOffset(
R.styleable.FilletImageView_right_bottom_radius,
defaultRadius
)
leftBottomRadius = array.getDimensionPixelOffset(
R.styleable.FilletImageView_left_bottom_radius,
defaultRadius
)
//如果四个角的值没有设置,那么就使用通用的radius的值。
if (defaultRadius == leftTopRadius) {
@ -53,7 +60,6 @@ class FilletImageView : AppCompatImageView {
leftBottomRadius = radius
}
array.recycle()
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {

@ -16,6 +16,7 @@ import android.view.animation.Interpolator
import android.widget.ImageView
import android.widget.OverScroller
import android.widget.Scroller
import androidx.appcompat.widget.AppCompatImageView
import io.legado.app.R
import io.legado.app.ui.widget.image.photo.Info
import io.legado.app.ui.widget.image.photo.OnRotateListener
@ -23,10 +24,12 @@ import io.legado.app.ui.widget.image.photo.RotateGestureDetector
import kotlin.math.abs
import kotlin.math.roundToInt
@Suppress("UNUSED_PARAMETER", "unused", "MemberVisibilityCanBePrivate")
@SuppressLint("AppCompatCustomView")
class PhotoView : ImageView {
@Suppress("UNUSED_PARAMETER", "unused", "MemberVisibilityCanBePrivate", "PropertyName")
class PhotoView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {
val MIN_ROTATE = 35
val ANIMA_DURING = 340
val MAX_SCALE = 2.5f
@ -45,9 +48,9 @@ class PhotoView : ImageView {
private val mSynthesisMatrix: Matrix = Matrix()
private val mTmpMatrix: Matrix = Matrix()
private var mRotateDetector: RotateGestureDetector? = null
private var mDetector: GestureDetector? = null
private var mScaleDetector: ScaleGestureDetector? = null
private val mRotateDetector: RotateGestureDetector
private val mDetector: GestureDetector
private val mScaleDetector: ScaleGestureDetector
private var mClickListener: OnClickListener? = null
private var mScaleType: ScaleType? = null
@ -100,23 +103,11 @@ class PhotoView : ImageView {
private var mLongClick: OnLongClickListener? = null
constructor(context: Context) : super(context) {
init()
}
private val mRotateListener = RotateListener()
private val mGestureListener = GestureListener()
private val mScaleListener = ScaleGestureListener()
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init()
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init()
}
private fun init() {
init {
super.setScaleType(ScaleType.MATRIX)
if (mScaleType == null) mScaleType = ScaleType.CENTER_INSIDE
mRotateDetector = RotateGestureDetector(mRotateListener)
@ -484,11 +475,11 @@ class PhotoView : ImageView {
return if (isEnable) {
val action = event.actionMasked
if (event.pointerCount >= 2) hasMultiTouch = true
mDetector!!.onTouchEvent(event)
mDetector.onTouchEvent(event)
if (isRotateEnable) {
mRotateDetector!!.onTouchEvent(event)
mRotateDetector.onTouchEvent(event)
}
mScaleDetector!!.onTouchEvent(event)
mScaleDetector.onTouchEvent(event)
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) onUp()
true
} else {
@ -566,49 +557,6 @@ class PhotoView : ImageView {
return abs(rect.left.roundToInt() - (mWidgetRect.width() - rect.width()) / 2) < 1
}
private val mRotateListener: OnRotateListener = object :
OnRotateListener {
override fun onRotate(
degrees: Float,
focusX: Float,
focusY: Float
) {
mRotateFlag += degrees
if (canRotate) {
mDegrees += degrees
mAnimMatrix.postRotate(degrees, focusX, focusY)
} else {
if (abs(mRotateFlag) >= mMinRotate) {
canRotate = true
mRotateFlag = 0f
}
}
}
}
private val mScaleListener: OnScaleGestureListener = object : OnScaleGestureListener {
override fun onScale(detector: ScaleGestureDetector): Boolean {
val scaleFactor = detector.scaleFactor
if (java.lang.Float.isNaN(scaleFactor) || java.lang.Float.isInfinite(scaleFactor)) return false
mScale *= scaleFactor
//mScaleCenter.set(detector.getFocusX(), detector.getFocusY());
mAnimMatrix.postScale(
scaleFactor,
scaleFactor,
detector.focusX,
detector.focusY
)
executeTranslate()
return true
}
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
return true
}
override fun onScaleEnd(detector: ScaleGestureDetector) {}
}
private fun resistanceScrollByX(
overScroll: Float,
detalX: Float
@ -652,147 +600,6 @@ class PhotoView : ImageView {
mClickListener?.onClick(this)
}
private val mGestureListener: GestureDetector.OnGestureListener =
object : SimpleOnGestureListener() {
override fun onLongPress(e: MotionEvent) {
mLongClick?.onLongClick(this@PhotoView)
}
override fun onDown(e: MotionEvent): Boolean {
hasOverTranslate = false
hasMultiTouch = false
canRotate = false
removeCallbacks(mClickRunnable)
return false
}
override fun onFling(
e1: MotionEvent,
e2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
if (hasMultiTouch) return false
if (!imgLargeWidth && !imgLargeHeight) return false
if (mTranslate.isRunning) return false
var vx = velocityX
var vy = velocityY
if (mImgRect.left.roundToInt() >= mWidgetRect.left
|| mImgRect.right.roundToInt() <= mWidgetRect.right
) {
vx = 0f
}
if (mImgRect.top.roundToInt() >= mWidgetRect.top
|| mImgRect.bottom.roundToInt() <= mWidgetRect.bottom
) {
vy = 0f
}
if (canRotate || mDegrees % 90 != 0f) {
var toDegrees = (mDegrees / 90).toInt() * 90.toFloat()
val remainder = mDegrees % 90
if (remainder > 45) toDegrees += 90f else if (remainder < -45) toDegrees -= 90f
mTranslate.withRotate(mDegrees.toInt(), toDegrees.toInt())
mDegrees = toDegrees
}
doTranslateReset(mImgRect)
mTranslate.withFling(vx, vy)
mTranslate.start()
// onUp(e2);
return super.onFling(e1, e2, velocityX, velocityY)
}
override fun onScroll(
e1: MotionEvent,
e2: MotionEvent,
distanceX: Float,
distanceY: Float
): Boolean {
var x = distanceX
var y = distanceY
if (mTranslate.isRunning) {
mTranslate.stop()
}
if (canScrollHorizontallySelf(x)) {
if (x < 0 && mImgRect.left - x > mWidgetRect.left)
x = mImgRect.left
if (x > 0 && mImgRect.right - x < mWidgetRect.right)
x = mImgRect.right - mWidgetRect.right
mAnimMatrix.postTranslate(-x, 0f)
mTranslateX -= x.toInt()
} else if (imgLargeWidth || hasMultiTouch || hasOverTranslate) {
checkRect()
if (!hasMultiTouch) {
if (x < 0 && mImgRect.left - x > mCommonRect.left) x =
resistanceScrollByX(mImgRect.left - mCommonRect.left, x)
if (x > 0 && mImgRect.right - x < mCommonRect.right) x =
resistanceScrollByX(mImgRect.right - mCommonRect.right, x)
}
mTranslateX -= x.toInt()
mAnimMatrix.postTranslate(-x, 0f)
hasOverTranslate = true
}
if (canScrollVerticallySelf(y)) {
if (y < 0 && mImgRect.top - y > mWidgetRect.top) y =
mImgRect.top
if (y > 0 && mImgRect.bottom - y < mWidgetRect.bottom) y =
mImgRect.bottom - mWidgetRect.bottom
mAnimMatrix.postTranslate(0f, -y)
mTranslateY -= y.toInt()
} else if (imgLargeHeight || hasOverTranslate || hasMultiTouch) {
checkRect()
if (!hasMultiTouch) {
if (y < 0 && mImgRect.top - y > mCommonRect.top) y =
resistanceScrollByY(mImgRect.top - mCommonRect.top, y)
if (y > 0 && mImgRect.bottom - y < mCommonRect.bottom) y =
resistanceScrollByY(mImgRect.bottom - mCommonRect.bottom, y)
}
mAnimMatrix.postTranslate(0f, -y)
mTranslateY -= y.toInt()
hasOverTranslate = true
}
executeTranslate()
return true
}
override fun onSingleTapUp(e: MotionEvent): Boolean {
postDelayed(mClickRunnable, 250)
return false
}
override fun onDoubleTap(e: MotionEvent): Boolean {
mTranslate.stop()
val from: Float
val to: Float
val imgCx = mImgRect.left + mImgRect.width() / 2
val imgCy = mImgRect.top + mImgRect.height() / 2
mScaleCenter[imgCx] = imgCy
mRotateCenter[imgCx] = imgCy
mTranslateX = 0
mTranslateY = 0
if (isZoonUp) {
from = mScale
to = 1f
} else {
from = mScale
to = mMaxScale
mScaleCenter[e.x] = e.y
}
mTmpMatrix.reset()
mTmpMatrix.postTranslate(-mBaseRect.left, -mBaseRect.top)
mTmpMatrix.postTranslate(mRotateCenter.x, mRotateCenter.y)
mTmpMatrix.postTranslate(-mHalfBaseRectWidth, -mHalfBaseRectHeight)
mTmpMatrix.postRotate(mDegrees, mRotateCenter.x, mRotateCenter.y)
mTmpMatrix.postScale(to, to, mScaleCenter.x, mScaleCenter.y)
mTmpMatrix.postTranslate(mTranslateX.toFloat(), mTranslateY.toFloat())
mTmpMatrix.mapRect(mTmpRect, mBaseRect)
doTranslateReset(mTmpRect)
isZoonUp = !isZoonUp
mTranslate.withScale(from, to)
mTranslate.start()
return false
}
}
fun canScrollHorizontallySelf(direction: Float): Boolean {
if (mImgRect.width() <= mWidgetRect.width())
return false
@ -1268,4 +1075,185 @@ class PhotoView : ImageView {
executeTranslate()
}
inner class RotateListener : OnRotateListener {
override fun onRotate(
degrees: Float,
focusX: Float,
focusY: Float
) {
mRotateFlag += degrees
if (canRotate) {
mDegrees += degrees
mAnimMatrix.postRotate(degrees, focusX, focusY)
} else {
if (abs(mRotateFlag) >= mMinRotate) {
canRotate = true
mRotateFlag = 0f
}
}
}
}
inner class GestureListener : SimpleOnGestureListener() {
override fun onLongPress(e: MotionEvent) {
mLongClick?.onLongClick(this@PhotoView)
}
override fun onDown(e: MotionEvent): Boolean {
hasOverTranslate = false
hasMultiTouch = false
canRotate = false
removeCallbacks(mClickRunnable)
return false
}
override fun onFling(
e1: MotionEvent,
e2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
if (hasMultiTouch) return false
if (!imgLargeWidth && !imgLargeHeight) return false
if (mTranslate.isRunning) return false
var vx = velocityX
var vy = velocityY
if (mImgRect.left.roundToInt() >= mWidgetRect.left
|| mImgRect.right.roundToInt() <= mWidgetRect.right
) {
vx = 0f
}
if (mImgRect.top.roundToInt() >= mWidgetRect.top
|| mImgRect.bottom.roundToInt() <= mWidgetRect.bottom
) {
vy = 0f
}
if (canRotate || mDegrees % 90 != 0f) {
var toDegrees = (mDegrees / 90).toInt() * 90.toFloat()
val remainder = mDegrees % 90
if (remainder > 45) toDegrees += 90f else if (remainder < -45) toDegrees -= 90f
mTranslate.withRotate(mDegrees.toInt(), toDegrees.toInt())
mDegrees = toDegrees
}
doTranslateReset(mImgRect)
mTranslate.withFling(vx, vy)
mTranslate.start()
// onUp(e2);
return super.onFling(e1, e2, velocityX, velocityY)
}
override fun onScroll(
e1: MotionEvent,
e2: MotionEvent,
distanceX: Float,
distanceY: Float
): Boolean {
var x = distanceX
var y = distanceY
if (mTranslate.isRunning) {
mTranslate.stop()
}
if (canScrollHorizontallySelf(x)) {
if (x < 0 && mImgRect.left - x > mWidgetRect.left)
x = mImgRect.left
if (x > 0 && mImgRect.right - x < mWidgetRect.right)
x = mImgRect.right - mWidgetRect.right
mAnimMatrix.postTranslate(-x, 0f)
mTranslateX -= x.toInt()
} else if (imgLargeWidth || hasMultiTouch || hasOverTranslate) {
checkRect()
if (!hasMultiTouch) {
if (x < 0 && mImgRect.left - x > mCommonRect.left) x =
resistanceScrollByX(mImgRect.left - mCommonRect.left, x)
if (x > 0 && mImgRect.right - x < mCommonRect.right) x =
resistanceScrollByX(mImgRect.right - mCommonRect.right, x)
}
mTranslateX -= x.toInt()
mAnimMatrix.postTranslate(-x, 0f)
hasOverTranslate = true
}
if (canScrollVerticallySelf(y)) {
if (y < 0 && mImgRect.top - y > mWidgetRect.top) y =
mImgRect.top
if (y > 0 && mImgRect.bottom - y < mWidgetRect.bottom) y =
mImgRect.bottom - mWidgetRect.bottom
mAnimMatrix.postTranslate(0f, -y)
mTranslateY -= y.toInt()
} else if (imgLargeHeight || hasOverTranslate || hasMultiTouch) {
checkRect()
if (!hasMultiTouch) {
if (y < 0 && mImgRect.top - y > mCommonRect.top) y =
resistanceScrollByY(mImgRect.top - mCommonRect.top, y)
if (y > 0 && mImgRect.bottom - y < mCommonRect.bottom) y =
resistanceScrollByY(mImgRect.bottom - mCommonRect.bottom, y)
}
mAnimMatrix.postTranslate(0f, -y)
mTranslateY -= y.toInt()
hasOverTranslate = true
}
executeTranslate()
return true
}
override fun onSingleTapUp(e: MotionEvent): Boolean {
postDelayed(mClickRunnable, 250)
return false
}
override fun onDoubleTap(e: MotionEvent): Boolean {
mTranslate.stop()
val from: Float
val to: Float
val imgCx = mImgRect.left + mImgRect.width() / 2
val imgCy = mImgRect.top + mImgRect.height() / 2
mScaleCenter[imgCx] = imgCy
mRotateCenter[imgCx] = imgCy
mTranslateX = 0
mTranslateY = 0
if (isZoonUp) {
from = mScale
to = 1f
} else {
from = mScale
to = mMaxScale
mScaleCenter[e.x] = e.y
}
mTmpMatrix.reset()
mTmpMatrix.postTranslate(-mBaseRect.left, -mBaseRect.top)
mTmpMatrix.postTranslate(mRotateCenter.x, mRotateCenter.y)
mTmpMatrix.postTranslate(-mHalfBaseRectWidth, -mHalfBaseRectHeight)
mTmpMatrix.postRotate(mDegrees, mRotateCenter.x, mRotateCenter.y)
mTmpMatrix.postScale(to, to, mScaleCenter.x, mScaleCenter.y)
mTmpMatrix.postTranslate(mTranslateX.toFloat(), mTranslateY.toFloat())
mTmpMatrix.mapRect(mTmpRect, mBaseRect)
doTranslateReset(mTmpRect)
isZoonUp = !isZoonUp
mTranslate.withScale(from, to)
mTranslate.start()
return false
}
}
inner class ScaleGestureListener : OnScaleGestureListener {
override fun onScale(detector: ScaleGestureDetector): Boolean {
val scaleFactor = detector.scaleFactor
if (java.lang.Float.isNaN(scaleFactor) || java.lang.Float.isInfinite(scaleFactor)) return false
mScale *= scaleFactor
//mScaleCenter.set(detector.getFocusX(), detector.getFocusY());
mAnimMatrix.postScale(
scaleFactor,
scaleFactor,
detector.focusX,
detector.focusY
)
executeTranslate()
return true
}
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
return true
}
override fun onScaleEnd(detector: ScaleGestureDetector) {}
}
}

@ -11,7 +11,7 @@ import io.legado.app.utils.ColorUtils
import io.legado.app.utils.dp
import io.legado.app.utils.getCompatColor
class AccentBgTextView(context: Context, attrs: AttributeSet?) :
class AccentBgTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
AppCompatTextView(context, attrs) {
private var radius = 0

@ -16,12 +16,12 @@ import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_1line_text_and_del.view.*
import org.jetbrains.anko.sdk27.listeners.onClick
class AutoCompleteTextView : AppCompatAutoCompleteTextView {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
@Suppress("unused")
class AutoCompleteTextView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatAutoCompleteTextView(context, attrs, defStyleAttr) {
var delCallBack: ((value: String) -> Unit)? = null
@ -33,7 +33,6 @@ class AutoCompleteTextView : AppCompatAutoCompleteTextView {
return true
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent?): Boolean {
if (event?.action == MotionEvent.ACTION_DOWN) {

@ -156,6 +156,16 @@ fun Context.getClipText(): String? {
return null
}
fun Context.sendMail(mail: String) {
try {
val intent = Intent(Intent.ACTION_SENDTO)
intent.data = Uri.parse("mailto:$mail")
startActivity(intent)
} catch (e: Exception) {
toast(e.localizedMessage ?: "Error")
}
}
/**
* 系统是否暗色主题
*/

@ -35,6 +35,7 @@ import static android.text.TextUtils.isEmpty;
* @version 1.0
* @since Create on 2010-01-27 11:19:00
*/
@SuppressWarnings("ALL")
public class EncodingDetect {
public static String getHtmlEncode(@NonNull byte[] bytes) {
@ -117,6 +118,7 @@ public class EncodingDetect {
}
@SuppressWarnings("ALL")
class BytesEncodingDetect extends Encoding {
// Frequency tables to hold the GB, Big5, and EUC-TW character
// frequencies
@ -271,9 +273,7 @@ class BytesEncodingDetect extends Encoding {
rawtextlen = rawtext.length;
for (i = 0; i < rawtextlen - 1; i++) {
// System.err.println(rawtext[i]);
if (rawtext[i] >= 0) {
// asciichars++;
} else {
if (rawtext[i] < 0) {
dbchars++;
if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xF7
&& (byte) 0xA1 <= rawtext[i + 1]
@ -312,9 +312,7 @@ class BytesEncodingDetect extends Encoding {
rawtextlen = rawtext.length;
for (i = 0; i < rawtextlen - 1; i++) {
// System.err.println(rawtext[i]);
if (rawtext[i] >= 0) {
// asciichars++;
} else {
if (rawtext[i] < 0) {
dbchars++;
if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xF7
&& // Original GB range
@ -373,9 +371,7 @@ class BytesEncodingDetect extends Encoding {
rawtextlen = rawtext.length;
for (i = 0; i < rawtextlen - 1; i++) {
// System.err.println(rawtext[i]);
if (rawtext[i] >= 0) {
// asciichars++;
} else {
if (rawtext[i] < 0) {
dbchars++;
if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xF7
&& // Original GB range
@ -516,9 +512,7 @@ class BytesEncodingDetect extends Encoding {
// Check to see if characters fit into acceptable ranges
rawtextlen = rawtext.length;
for (i = 0; i < rawtextlen - 1; i++) {
if (rawtext[i] >= 0) {
// asciichars++;
} else {
if (rawtext[i] < 0) {
dbchars++;
if ((byte) 0xA1 <= rawtext[i]
&& rawtext[i] <= (byte) 0xF9
@ -560,9 +554,7 @@ class BytesEncodingDetect extends Encoding {
rawtextlen = rawtext.length;
for (i = 0; i < rawtextlen - 1; i++) {
// System.err.println(rawtext[i]);
if (rawtext[i] >= 128) {
// asciichars++;
} else {
if (rawtext[i] < 128) {
dbchars++;
if (0xA1 <= rawtext[i]
&& rawtext[i] <= 0xF9
@ -626,9 +618,7 @@ class BytesEncodingDetect extends Encoding {
// and have expected frequency of use
rawtextlen = rawtext.length;
for (i = 0; i < rawtextlen - 1; i++) {
if (rawtext[i] >= 0) { // in ASCII range
// asciichars++;
} else { // high bit set
if (rawtext[i] < 0) { // high bit set
dbchars++;
if (i + 3 < rawtextlen && (byte) 0x8E == rawtext[i]
&& (byte) 0xA1 <= rawtext[i + 1]
@ -846,9 +836,7 @@ class BytesEncodingDetect extends Encoding {
rawtextlen = rawtext.length;
for (i = 0; i < rawtextlen - 1; i++) {
// System.err.println(rawtext[i]);
if (rawtext[i] >= 0) {
// asciichars++;
} else {
if (rawtext[i] < 0) {
dbchars++;
if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xFE
&& (byte) 0xA1 <= rawtext[i + 1]
@ -886,9 +874,7 @@ class BytesEncodingDetect extends Encoding {
rawtextlen = rawtext.length;
for (i = 0; i < rawtextlen - 1; i++) {
// System.err.println(rawtext[i]);
if (rawtext[i] >= 0) {
// asciichars++;
} else {
if (rawtext[i] < 0) {
dbchars++;
if ((byte) 0x81 <= rawtext[i]
&& rawtext[i] <= (byte) 0xFE
@ -945,9 +931,7 @@ class BytesEncodingDetect extends Encoding {
rawtextlen = rawtext.length;
for (i = 0; i < rawtextlen - 1; i++) {
// System.err.println(rawtext[i]);
if (rawtext[i] >= 0) {
// asciichars++;
} else {
if (rawtext[i] < 0) {
dbchars++;
if ((byte) 0xA1 <= rawtext[i] && rawtext[i] <= (byte) 0xFE
&& (byte) 0xA1 <= rawtext[i + 1]
@ -997,9 +981,7 @@ class BytesEncodingDetect extends Encoding {
rawtextlen = rawtext.length;
for (i = 0; i < rawtextlen - 1; i++) {
// System.err.println(rawtext[i]);
if (rawtext[i] >= 0) {
// asciichars++;
} else {
if (rawtext[i] < 0) {
dbchars++;
if (i + 1 < rawtext.length
&& (((byte) 0x81 <= rawtext[i] && rawtext[i] <= (byte) 0x9F) || ((byte) 0xE0 <= rawtext[i] && rawtext[i] <= (byte) 0xEF))
@ -4383,6 +4365,7 @@ class BytesEncodingDetect extends Encoding {
}
}
@SuppressWarnings("ALL")
class Encoding {
// Supported Encoding Types
static int GB2312 = 0;

@ -1,3 +1,5 @@
@file:Suppress("unused")
package io.legado.app.utils
import android.widget.Toast

Loading…
Cancel
Save