diff --git a/app/src/main/java/io/legado/app/service/help/ReadBook.kt b/app/src/main/java/io/legado/app/service/help/ReadBook.kt index e8485261c..5bdcaa25e 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadBook.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadBook.kt @@ -1,5 +1,6 @@ package io.legado.app.service.help +import android.util.Log import androidx.lifecycle.MutableLiveData import com.hankcs.hanlp.HanLP import io.legado.app.App @@ -16,6 +17,7 @@ import io.legado.app.help.coroutine.Coroutine import io.legado.app.model.webBook.WebBook import io.legado.app.service.BaseReadAloudService import io.legado.app.ui.book.read.page.entities.TextChapter +import io.legado.app.ui.book.read.page.entities.TextPage import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.book.read.page.provider.ImageProvider import kotlinx.coroutines.Dispatchers @@ -324,6 +326,46 @@ object ReadBook { } } + fun searchResultPositions(pages: List, contentPosition: Int): Array{ + // + // calculate search result's pageIndex + var pageIndex = 0 + var length = pages[pageIndex].text.length + Log.d("h11128", "page size ${pages.size}") + while (length < contentPosition){ + pageIndex += 1 + if (pageIndex >pages.size){ + pageIndex = pages.size + break + } + length += pages[pageIndex].text.length + Log.d("h11128", "to next page , add length change to $length") + } + + Log.d("h11128", "at pageindex $pageIndex") + + // calculate search result's lineIndex + val currentPage = pages[pageIndex] + var lineIndex = 0 + length = length - currentPage.text.length + currentPage.textLines[lineIndex].text.length + while (length < contentPosition){ + lineIndex += 1 + if (lineIndex >currentPage.textLines.size){ + lineIndex = currentPage.textLines.size + break + } + length += currentPage.textLines[lineIndex].text.length + + } + + // charIndex + val currentLine = currentPage.textLines[lineIndex] + length -= currentLine.text.length + val charIndex = contentPosition - length + + return arrayOf(pageIndex, lineIndex, charIndex) + } + /** * 内容加载完成 */ @@ -426,4 +468,5 @@ object ReadBook { fun pageChanged() fun contentLoadFinish() } + } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index bc6198e83..5b4991c37 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -9,6 +9,7 @@ import android.graphics.drawable.ColorDrawable import android.net.Uri import android.os.Bundle import android.os.Handler +import android.util.Log import android.view.* import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import androidx.core.view.get @@ -48,6 +49,7 @@ import io.legado.app.ui.book.read.page.PageView import io.legado.app.ui.book.read.page.TextPageFactory import io.legado.app.ui.book.read.page.delegate.PageDelegate import io.legado.app.ui.book.searchContent.SearchListActivity +import io.legado.app.ui.book.searchContent.SearchResult import io.legado.app.ui.book.source.edit.BookSourceEditActivity import io.legado.app.ui.login.SourceLogin import io.legado.app.ui.replacerule.ReplaceRuleActivity @@ -80,6 +82,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo private val requestCodeChapterList = 568 private val requestCodeEditSource = 111 private val requestCodeReplace = 312 + private val requestCodeSearchResult = 123 private var menu: Menu? = null private var textActionMenu: TextActionMenu? = null @@ -675,7 +678,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo override fun openSearchList() { ReadBook.book?.let { startActivityForResult( - requestCodeChapterList, + requestCodeSearchResult, Pair("bookUrl", it.bookUrl) ) } @@ -761,11 +764,31 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo requestCodeChapterList -> data?.getIntExtra("index", ReadBook.durChapterIndex)?.let { index -> if (index != ReadBook.durChapterIndex) { - viewModel.openChapter(index) + val pageIndex = data.getIntExtra("pageIndex", 0) + viewModel.openChapter(index, pageIndex) + } + } + requestCodeSearchResult -> + data?.getIntExtra("index", ReadBook.durChapterIndex)?.let { index -> + val contentPosition = data.getIntExtra("contentPosition", 0) + val query = data.getStringExtra("query") + ReadBook.durChapterIndex = index + ReadBook.saveRead() + ReadBook.loadContent(resetPageOffset = true) + val pages = ReadBook.curTextChapter?.pages + if (pages != null){ + val positions = ReadBook.searchResultPositions(pages, contentPosition) + viewModel.openChapter(index, positions[0]) + Log.d("h11128", positions[0].toString()) + Log.d("h11128", positions[1].toString()) + Log.d("h11128", positions[2].toString()) + //page_view.curPage.selectStartMoveIndex(positions[0], positions[1], 0) + //page_view.curPage.selectEndMoveIndex(positions[0], positions[1], 0 + query!!.length ) } } requestCodeReplace -> onReplaceRuleSave() } + } } diff --git a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchListFragment.kt b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchListFragment.kt index 1053d02cf..a52cfac6a 100644 --- a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchListFragment.kt +++ b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchListFragment.kt @@ -16,6 +16,9 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.help.BookHelp import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.getPrimaryTextColor +import io.legado.app.service.help.ReadBook +import io.legado.app.ui.book.read.page.entities.TextPage +import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.widget.recycler.UpLinearLayoutManager import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.utils.ColorUtils @@ -37,6 +40,8 @@ class SearchListFragment : VMBaseFragment(R.layout.fragment lateinit var adapter: SearchListAdapter private lateinit var mLayoutManager: UpLinearLayoutManager private var searchResultCounts = 0 + private var pageSize = 0 + private var searchResultList: MutableList = mutableListOf() override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { viewModel.searchCallBack = this @@ -103,39 +108,36 @@ class SearchListFragment : VMBaseFragment(R.layout.fragment // 按章节搜索内容 if (!newText.isBlank()) { adapter.clearItems() + searchResultList.clear() searchResultCounts = 0 viewModel.lastQuery = newText - App.db.bookChapterDao().getChapterList(viewModel.bookUrl).map{ - launch(IO) { - val beginTime = System.currentTimeMillis() - if (isLocalBook - || adapter.cacheFileNames.contains(BookHelp.formatChapterName(it)) - ) { - val searchResults = searchChapter(newText, it) - if (searchResults.size > 0 ){ - searchResultCounts += searchResults.size - - withContext(Main){ - tv_current_search_info.text = "搜索结果:$searchResultCounts" - adapter.addItems(searchResults) - } + var searchResults = listOf() + launch(Main){ + App.db.bookChapterDao().getChapterList(viewModel.bookUrl).map{ chapter -> + val job = async(IO){ + if (isLocalBook || adapter.cacheFileNames.contains(BookHelp.formatChapterName(chapter))) { + searchResults = searchChapter(newText, chapter) + Log.d("h11128", "find ${searchResults.size} results in chapter ${chapter.title}") } } - val finishedTime = System.currentTimeMillis() - beginTime - Log.d("h11128", "Search finished, the total time cost is $finishedTime") - Log.d("h11128", "Search finished, the total count is $searchResultCounts") + job.await() + if (searchResults.isNotEmpty()){ + Log.d("h11128", "load ${searchResults.size} results in chapter ${chapter.title}") + searchResultList.addAll(searchResults) + tv_current_search_info.text = "搜索结果:$searchResultCounts" + Log.d("h11128", "searchResultList size ${searchResultList.size}") + adapter.addItems(searchResults) + searchResults = listOf() + } } } } - } - private fun searchChapter(query: String, chapter: BookChapter?): MutableList { - val startTime = System.currentTimeMillis() + private fun searchChapter(query: String, chapter: BookChapter?): List { val searchResults: MutableList = mutableListOf() var positions : List? = listOf() if (chapter != null){ - Log.d("h11128", "Search ${chapter.title}") viewModel.book?.let { bookSource -> val bookContent = BookHelp.getContent(bookSource, chapter) if (bookContent != null){ @@ -169,22 +171,21 @@ class SearchListFragment : VMBaseFragment(R.layout.fragment positions = searchPosition(bookContent, query) positions?.map{ val construct = constructText(bookContent, it, query) - val result = SearchResult(index = 0, + val result = SearchResult(index = searchResultCounts, text = construct[1] as String, chapterTitle = chapter.title, query = query, pageIndex = 0, //todo: 计算搜索结果所在的pageIndex直接跳转 chapterIndex = chapter.index, - newPosition = construct[0] as Int + newPosition = construct[0] as Int, + contentPosition = it ) + searchResultCounts += 1 searchResults.add(result) // Log.d("h11128", result.presentText) } - Log.d("h11128", "Search ${chapter.title} finished, the appeared count is ${positions!!.size}") } } - val endTime = System.currentTimeMillis() - startTime - Log.d("h11128", "Search ${chapter.title} finished, the time cost is $endTime") } return searchResults } @@ -222,11 +223,16 @@ class SearchListFragment : VMBaseFragment(R.layout.fragment get() = viewModel.book?.isLocalBook() == true override fun openSearchResult(searchResult: SearchResult) { + val searchData = Intent() searchData.putExtra("index", searchResult.chapterIndex) - searchData.putExtra("pageIndex", searchResult.pageIndex) + searchData.putExtra("contentPosition", searchResult.contentPosition) + searchData.putExtra("query", searchResult.query) + Log.d("h11128","current chapter index ${searchResult.chapterIndex}") activity?.setResult(RESULT_OK, searchData) activity?.finish() + + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchResult.kt b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchResult.kt index 7682a9b5d..fd1873464 100644 --- a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchResult.kt +++ b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchResult.kt @@ -1,5 +1,8 @@ package io.legado.app.ui.book.searchContent +import android.util.Log +import io.legado.app.ui.book.read.page.entities.TextPage + data class SearchResult( var index: Int = 0, var text: String = "", @@ -8,7 +11,8 @@ data class SearchResult( var pageSize: Int = 0, var chapterIndex: Int = 0, var pageIndex: Int = 0, - var newPosition: Int = 0 + var newPosition: Int = 0, + var contentPosition: Int =0 ) { val presentText: String get(){ @@ -20,4 +24,5 @@ data class SearchResult( "($chapterTitle)" } + } \ No newline at end of file