ReaderActivity.kt 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. package com.kdanmobile.reader
  2. import android.annotation.SuppressLint
  3. import android.app.Activity
  4. import android.app.Dialog
  5. import android.arch.lifecycle.Observer
  6. import android.arch.lifecycle.ViewModelProviders
  7. import android.content.Intent
  8. import android.net.Uri
  9. import android.os.Build
  10. import android.os.Bundle
  11. import android.support.constraint.ConstraintLayout
  12. import android.support.constraint.ConstraintSet
  13. import android.support.design.widget.Snackbar
  14. import android.support.v4.content.ContextCompat
  15. import android.support.v7.app.AlertDialog
  16. import android.support.v7.app.AppCompatActivity
  17. import android.util.DisplayMetrics
  18. import android.view.*
  19. import android.view.animation.AnimationUtils
  20. import android.widget.EditText
  21. import android.widget.LinearLayout
  22. import android.widget.TextView
  23. import android.widget.Toast
  24. import com.kdanmobile.kmpdfkit.globaldata.KMPDFAnnotEditMode
  25. import com.kdanmobile.kmpdfkit.pdfcommon.KMPDFReaderView
  26. import com.kdanmobile.kmpdfkit.pdfcommon.PDFInfo
  27. import com.kdanmobile.reader.Utils.applyConstraintSet
  28. import com.kdanmobile.reader.annotationattribute.AnnotationAttribute
  29. import com.kdanmobile.reader.annotationattribute.AnnotationColor
  30. import com.kdanmobile.reader.annotationattribute.InkAttribute
  31. import com.kdanmobile.reader.password.DialogPasswordActivity
  32. import com.kdanmobile.reader.screen.contextmenu.TextBoxContextMenuActionListener
  33. import com.kdanmobile.reader.screen.model.SharePrefsModel
  34. import com.kdanmobile.reader.screen.reader.mediabox.MediaBoxView
  35. import com.kdanmobile.reader.screen.reader.mediabox.shape.ShapeTabView
  36. import com.kdanmobile.reader.screen.reader.mediabox.signature.SignatureTabView
  37. import com.kdanmobile.reader.screen.reader.mediabox.stamp.StampTabView
  38. import com.kdanmobile.reader.screen.reader.mediabox.textbox.TextBoxTabView
  39. import com.kdanmobile.reader.screen.view.*
  40. import com.kdanmobile.reader.setting.ReaderSettingDialogFragment
  41. import com.kdanmobile.reader.setting.ReaderSettingListener
  42. import com.kdanmobile.reader.thumb.PdfThumbActivity
  43. import com.kdanmobile.reader.utils.AnimationUtil
  44. import com.kdanmobile.reader.utils.DensityUtil
  45. import com.kdanmobile.reader.utils.UriToPathUtil
  46. import com.kdanmobile.reader.view.AnnotationAttributeView
  47. import com.kdanmobile.reader.view.AnnotationAttributeWindow
  48. import kotlinx.android.synthetic.main.activity_reader.*
  49. import java.io.File
  50. import java.util.*
  51. import kotlin.properties.Delegates
  52. abstract class ReaderActivity : AppCompatActivity() {
  53. abstract fun onClickShare()
  54. abstract fun onClickKdanCloud()
  55. abstract fun onClickTextReflow()
  56. abstract fun onClickFileInfo()
  57. abstract fun onClickPrint()
  58. abstract fun onClickUserGuide()
  59. abstract fun transferThumbIntent(): Intent
  60. abstract fun provideReaderSettingDialogFragment(): ReaderSettingDialogFragment
  61. open fun saveCurrentPageIndex(filename: String, currentPage: Int) {}
  62. open fun loadCurrentPageIndex(filename: String, defaultValue: Int): Int = 0
  63. companion object {
  64. const val KEY_FILE_ABSOLUTE = "file_absolutepath"
  65. const val THUMB = 221
  66. const val REQUEST_PASSWORD = 222
  67. }
  68. protected val file: File?
  69. get() {
  70. return viewModel.file
  71. }
  72. protected var filePath: String? = null
  73. private set
  74. protected val pdfInfo: PDFInfo?
  75. get() {
  76. return viewModel.pdfInfo
  77. }
  78. protected val isPasswordProtected: Boolean
  79. get() {
  80. return viewModel.isPasswordProtected
  81. }
  82. protected val currentPageIndex: Int
  83. get() {
  84. return viewModel.pdfInfoHandler.getCurrentPage()
  85. }
  86. protected val pageCount: Int
  87. get() {
  88. return viewModel.pdfInfoHandler.getPdfPageCount()
  89. }
  90. protected val password: String
  91. get() {
  92. return viewModel.password
  93. }
  94. private lateinit var viewModel: ReaderViewModel
  95. private var isShowPasswordActivity = false
  96. // For hide/show toolbars
  97. private var isHideToolbar = false
  98. private lateinit var originConstraintSet: ConstraintSet
  99. private var menuItemBookmark: MenuItem? = null
  100. private val UI_ANIMATION_DURATION = 300L
  101. private val FRAGMENT_READER_SETTING_TAG = "ReaderSetting"
  102. private var w_318: Int = 0
  103. private var w_240: Int = 0
  104. private var w_left: Int = 0
  105. private var oldLeftToolbarType = ReaderViewModel.LeftToolbarType.NONE
  106. private var snackbarMediaBox: Snackbar? = null
  107. private var isHidePdfPage: Boolean by Delegates.observable(false) { property, oldValue, newValue ->
  108. if (newValue == oldValue) return@observable
  109. // println("${property.name} changed from $oldValue to $newValue")
  110. tv_readerActivity_pdfPage.clearAnimation()
  111. when (newValue) {
  112. true -> tv_readerActivity_pdfPage.startAnimation(AnimationUtils.loadAnimation(this, R.anim.fade_out))
  113. false -> tv_readerActivity_pdfPage.startAnimation(AnimationUtils.loadAnimation(this, R.anim.fade_in))
  114. }
  115. }
  116. override fun onCreate(savedInstanceState: Bundle?) {
  117. super.onCreate(savedInstanceState)
  118. window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
  119. setContentView(R.layout.activity_reader)
  120. setSupportActionBar(toolbar_readerActivity)
  121. isShowPasswordActivity = savedInstanceState?.getBoolean("isShowPasswordActivity") ?: false
  122. filePath = savedInstanceState?.getString("filePath")
  123. val displayMetrics = DisplayMetrics()
  124. windowManager.defaultDisplay.getMetrics(displayMetrics)
  125. val width = Math.min(DensityUtil.getScreenWidthPx(baseContext), DensityUtil.getScreenHeightPx(baseContext))
  126. w_318 = 318 * width / 800
  127. w_240 = 240 * width / 800
  128. w_left = resources.getDimension(R.dimen.reader_left_right_toolbar_icon_width).toInt()
  129. cloneOriginConstraintSet()
  130. setupToolbar()
  131. setupLeftToolbar()
  132. setupRightSideToolbar()
  133. setupBottomToolbar()
  134. setupMediaBoxView()
  135. val factory = ReaderViewModelFactory()
  136. viewModel = ViewModelProviders.of(this, factory).get(ReaderViewModel::class.java)
  137. ReaderModel.onViewModelCreate(viewModel)
  138. viewModel.isOpenedFileLiveData.observe(this, Observer(this::onIsOpenedFileUpdate))
  139. viewModel.fileNameLiveData.observe(this, Observer { tv_readerActivity_title.text = it })
  140. viewModel.annotationModeLiveData.observe(this, Observer(this::onAnnotationModeUpdate))
  141. viewModel.annotationEitModeLiveData.observe(this, Observer(this::onAnnotationEditModeUpdate))
  142. viewModel.isCopyModeLiveData.observe(this, Observer (this::onIsCopyModeUpdate))
  143. viewModel.highLightAttributeLiveData.observe(this, Observer(this::onHighlightAttributeUpdate))
  144. viewModel.strikeAttributeLiveData.observe(this, Observer(this::onStrikeAttributeUpdate))
  145. viewModel.underLineAttributeLiveData.observe(this, Observer(this::onUnderlineAttributeUpdate))
  146. viewModel.inkAttributeLiveData.observe(this, Observer(this::onInkAttributeUpdate))
  147. viewModel.isOpenedFileLiveData.value?.also { isOpened ->
  148. if (isShowPasswordActivity) return@also
  149. if (isOpened) return@also
  150. val uri = if (intent.action == Intent.ACTION_VIEW) {
  151. val uri = intent.data
  152. filePath = UriToPathUtil.getInstance().getPath(applicationContext, uri)
  153. uri
  154. } else {
  155. filePath = intent.getStringExtra(KEY_FILE_ABSOLUTE)
  156. Uri.parse(filePath)
  157. }
  158. viewModel.openPdfFile(applicationContext, uri, password, Runnable { requestPassword() }, intent.type)
  159. }
  160. setupRightToolbar()
  161. viewModel.pageIndexLiveData.observe(this, Observer(this::onPageIndexChanged))
  162. viewModel.isPageInBookmarksLiveData.observe(this, Observer(this::onIsPageInBookmarksChanged))
  163. viewModel.isLeftToolbarOpenLiveData.observe(this, Observer(this::onLeftToolbarOpenStateChanged))
  164. viewModel.leftToolbarTypeLiveData.observe(this, Observer(this::onLeftToolbarTypeChanged))
  165. isHidePdfPage = true
  166. applySetting()
  167. if (savedInstanceState != null) {
  168. val settingDialog = supportFragmentManager.findFragmentByTag(FRAGMENT_READER_SETTING_TAG) as ReaderSettingDialogFragment?
  169. settingDialog?.setReaderSettingListener(readerSettingListener)
  170. }
  171. setupPdfChangedListener()
  172. }
  173. override fun onSaveInstanceState(outState: Bundle?) {
  174. super.onSaveInstanceState(outState)
  175. outState?.putBoolean("isShowPasswordActivity", isShowPasswordActivity)
  176. outState?.putString("filePath", filePath)
  177. }
  178. private fun requestPassword(isIncorrectPassword: Boolean = false) {
  179. isShowPasswordActivity = true
  180. val intent = Intent(baseContext, DialogPasswordActivity::class.java)
  181. val bundle = Bundle()
  182. bundle.putBoolean("isIncorrectPassword", isIncorrectPassword)
  183. intent.putExtras(bundle)
  184. startActivityForResult(intent, REQUEST_PASSWORD)
  185. }
  186. override fun onBackPressed() {
  187. when {
  188. mediaBoxView.isShown -> mediaBoxView.dismiss()
  189. else -> super.onBackPressed()
  190. }
  191. }
  192. override fun onCreateOptionsMenu(menu: Menu?): Boolean {
  193. menuInflater.inflate(R.menu.reader_more, menu)
  194. menuItemBookmark = menu?.findItem(R.id.item_reader_bookmark)
  195. onIsPageInBookmarksChanged(viewModel.isPageInBookmarksLiveData.value)
  196. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
  197. menu?.findItem(R.id.item_reader_more_print)?.isVisible = false
  198. }
  199. // TODO: Check is pdf file or epub file, these action support only pdf file
  200. val isPdf = true
  201. if (!isPdf) {
  202. menu?.apply {
  203. findItem(R.id.item_reader_more_text_reflow)?.isVisible = false
  204. findItem(R.id.item_reader_more_file_info)?.isVisible = false
  205. findItem(R.id.item_reader_more_print)?.isVisible = false
  206. }
  207. }
  208. return true
  209. }
  210. @SuppressLint("RestrictedApi")
  211. override fun onPrepareOptionsPanel(view: View?, menu: Menu?): Boolean {
  212. /** Force show action menu item icon **/
  213. menu?.also {
  214. if ("MenuBuilder" != it::javaClass.get().simpleName) return@also
  215. try {
  216. val method = it.javaClass.getDeclaredMethod("setOptionalIconsVisible", java.lang.Boolean.TYPE)
  217. method.isAccessible = true
  218. method.invoke(it, true)
  219. } catch (e: Exception) {
  220. // Do nothing
  221. }
  222. }
  223. return super.onPrepareOptionsPanel(view, menu)
  224. }
  225. protected fun getPageText(pageIndex: Int) = viewModel.getPageText(pageIndex)
  226. private fun cloneOriginConstraintSet() {
  227. if (!isBelowKitkat()) {
  228. originConstraintSet = ConstraintSet().apply {
  229. clone(constrainLayout_readerActivity_root)
  230. }
  231. }
  232. }
  233. private fun onIsCopyModeUpdate(isCopyMode: Boolean?) {
  234. if (isCopyMode == null) return
  235. when (isCopyMode) {
  236. true -> hideTopLeftBottomToolbars()
  237. false -> showAllToolbars()
  238. }
  239. }
  240. private fun onHighlightAttributeUpdate(annotationAttribute: AnnotationAttribute?) {
  241. if (annotationAttribute == null) return
  242. view_readerActivity_highLightStroke.setBackgroundColor(annotationAttribute.color)
  243. }
  244. private fun onStrikeAttributeUpdate(annotationAttribute: AnnotationAttribute?) {
  245. if (annotationAttribute == null) return
  246. view_readerActivity_strikeStroke.setBackgroundColor(annotationAttribute.color)
  247. }
  248. private fun onUnderlineAttributeUpdate(annotationAttribute: AnnotationAttribute?) {
  249. if (annotationAttribute == null) return
  250. view_readerActivity_underlineStroke.setBackgroundColor(annotationAttribute.color)
  251. }
  252. private fun onInkAttributeUpdate(inkAttribute: InkAttribute?) {
  253. if (inkAttribute == null) return
  254. val color = inkAttribute.color
  255. AnnotationColor.values().forEach {
  256. if (ContextCompat.getColor(this, it.colorResId) == color) {
  257. val drawableResId = when (it) {
  258. AnnotationColor.Color1 -> R.drawable.ic_reader_right_toolbar_ink_color1
  259. AnnotationColor.Color2 -> R.drawable.ic_reader_right_toolbar_ink_color2
  260. AnnotationColor.Color3 -> R.drawable.ic_reader_right_toolbar_ink_color3
  261. AnnotationColor.Color4 -> R.drawable.ic_reader_right_toolbar_ink_color4
  262. AnnotationColor.Color5 -> R.drawable.ic_reader_right_toolbar_ink_color5
  263. AnnotationColor.Color6 -> R.drawable.ic_reader_right_toolbar_ink_color6
  264. AnnotationColor.Color7 -> R.drawable.ic_reader_right_toolbar_ink_color7
  265. AnnotationColor.Color8 -> R.drawable.ic_reader_right_toolbar_ink_color8
  266. AnnotationColor.Color9 -> R.drawable.ic_reader_right_toolbar_ink_color9
  267. AnnotationColor.Color10 -> R.drawable.ic_reader_right_toolbar_ink_color10
  268. }
  269. iv_readerActivity_ink.setImageResource(drawableResId)
  270. return
  271. }
  272. }
  273. }
  274. private fun onAnnotationModeUpdate(annotationMode: ReaderViewModel.AnnotationMode?) {
  275. if (annotationMode == null) return
  276. if (viewModel.isCrop) return
  277. val map = HashMap<ReaderViewModel.AnnotationMode, View>().apply {
  278. put(ReaderViewModel.AnnotationMode.Highlight, iv_readerActivity_highLight)
  279. put(ReaderViewModel.AnnotationMode.Strike, iv_readerActivity_strike)
  280. put(ReaderViewModel.AnnotationMode.Underline, iv_readerActivity_underline)
  281. put(ReaderViewModel.AnnotationMode.Ink, iv_readerActivity_ink)
  282. }
  283. map.forEach {
  284. if (it.key == annotationMode) {
  285. val color = ContextCompat.getColor(this, R.color.reader_right_toolbar_selected_bg)
  286. it.value.setBackgroundColor(color)
  287. } else {
  288. it.value.setBackgroundDrawable(null)
  289. }
  290. }
  291. when (annotationMode == ReaderViewModel.AnnotationMode.None) {
  292. true -> showAllToolbars()
  293. false -> hideTopLeftBottomToolbars()
  294. }
  295. ReaderModel.onPdfChangedListener?.onPageUpdated(arrayListOf(currentPageIndex))
  296. }
  297. private fun onAnnotationEditModeUpdate(mode: KMPDFAnnotEditMode.Mode?) {
  298. when (mode) {
  299. KMPDFAnnotEditMode.Mode.NULL -> {
  300. showAllToolbars()
  301. isHideToolbar = false
  302. snackbarMediaBox?.dismiss()
  303. snackbarMediaBox = null
  304. }
  305. KMPDFAnnotEditMode.Mode.SIGN_MODIFY -> {
  306. hideAllToolbars()
  307. isHideToolbar = true
  308. }
  309. KMPDFAnnotEditMode.Mode.FREETEXT_MODIFY, KMPDFAnnotEditMode.Mode.STAMP_MODIFY, KMPDFAnnotEditMode.Mode.SHAPE_MODIFY -> {
  310. hideAllToolbars()
  311. isHideToolbar = true
  312. snackbarMediaBox?.dismiss()
  313. snackbarMediaBox = null
  314. }
  315. else -> {}
  316. }
  317. isHidePdfPage = true
  318. ReaderModel.onPdfChangedListener?.onPageUpdated(arrayListOf(currentPageIndex))
  319. }
  320. private fun onIsOpenedFileUpdate(isOpened: Boolean?) {
  321. if (isOpened == null) return
  322. val container = viewGroup_readerActivity_container
  323. container.removeAllViews()
  324. if (!isOpened) return
  325. val context = this
  326. val readerView = object : KMPDFReaderView(context) {
  327. @SuppressLint("ClickableViewAccessibility")
  328. override fun onTouchEvent(motionEvent: MotionEvent): Boolean {
  329. if (motionEvent.action == MotionEvent.ACTION_UP) {
  330. if (viewModel.isCopyModeLiveData.value == true) {
  331. if (viewModel.copySelection()) {
  332. val context = this@ReaderActivity
  333. Toast.makeText(context, R.string.reader_copy_text_success, Toast.LENGTH_SHORT).show()
  334. }
  335. }
  336. }
  337. return super.onTouchEvent(motionEvent)
  338. }
  339. override fun onTapMainDocArea() {
  340. super.onTapMainDocArea()
  341. when (isHideToolbar) {
  342. true -> {
  343. showAllToolbars()
  344. viewModel.clearSelection()
  345. }
  346. false -> hideAllToolbars()
  347. }
  348. isHideToolbar = !isHideToolbar
  349. }
  350. override fun onMoveToChild(pageIndex: Int) {
  351. super.onMoveToChild(pageIndex)
  352. viewModel.setPageIndex(pageIndex)
  353. }
  354. override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean {
  355. val isEditMode = viewModel.annotationModeLiveData.value != ReaderViewModel.AnnotationMode.None
  356. val isCopyMode = viewModel.isCopyModeLiveData.value != false
  357. if (!isEditMode && !isCopyMode && !isHideToolbar) {
  358. hideAllToolbars()
  359. isHideToolbar = true
  360. }
  361. isHidePdfPage = isEditMode || isCopyMode
  362. return super.onScroll(e1, e2, distanceX, distanceY)
  363. }
  364. }
  365. viewModel.setReaderView(readerView)
  366. if (!filePath.isNullOrEmpty()) {
  367. val defaultValue = viewModel.pageIndexLiveData.value ?: 0
  368. val pageIndex = loadCurrentPageIndex(filePath as String, defaultValue)
  369. viewModel.pdfInfoHandler.setCurrentPage(pageIndex)
  370. }
  371. initTextBoxContextMenuActions()
  372. container.addView(readerView)
  373. if (SharePrefsModel(this).isCropModeEnable.value == true) {
  374. val settingDialog = supportFragmentManager.findFragmentByTag(FRAGMENT_READER_SETTING_TAG) as ReaderSettingDialogFragment?
  375. settingDialog?.dismiss()
  376. readerView.post {
  377. readerSettingListener.onCropModeEnableChanged(true)
  378. }
  379. }
  380. }
  381. private fun initTextBoxContextMenuActions() {
  382. viewModel.setTextBoxContextMenuActions(object : TextBoxContextMenuActionListener {
  383. override fun onDelete(): Boolean {
  384. viewModel.deleteSelectedTextBox()
  385. return true
  386. }
  387. override fun onEditStyle(): Boolean {
  388. mediaBoxView.showTextBoxStyleView()
  389. viewModel.editSelectedTextBoxStyle()
  390. return true
  391. }
  392. override fun onEditText(): Boolean {
  393. hideAllToolbars()
  394. isHideToolbar = true
  395. viewModel.editSelectedTextBoxText()
  396. return true
  397. }
  398. override fun onCopy(): Boolean {
  399. viewModel.copySelectedTextBox()
  400. return true
  401. }
  402. })
  403. }
  404. override fun onStop() {
  405. viewModel.saveModifyingAnnotation()
  406. viewModel.temporarySave()
  407. if (!filePath.isNullOrEmpty()) {
  408. saveCurrentPageIndex(filePath as String, currentPageIndex)
  409. }
  410. super.onStop()
  411. }
  412. private fun onPageIndexChanged(pageIndex: Int?) {
  413. pageIndex?.also {
  414. viewModel.setBookmarkDisplay(pageIndex)
  415. ReaderModel.onPdfChangedListener?.onPageSelected(pageIndex)
  416. tv_readerActivity_pdfPage.post {
  417. tv_readerActivity_pdfPage.text="${(pageIndex) + 1}/${viewModel.pdfInfoHandler.getPdfPageCount()}"
  418. }
  419. }
  420. }
  421. private fun onIsPageInBookmarksChanged(isPageInBookmarks: Boolean?) {
  422. isPageInBookmarks?.let {
  423. if (it) {
  424. menuItemBookmark?.icon = ContextCompat.getDrawable(this, R.drawable.ic_bookmark_fill)
  425. } else {
  426. menuItemBookmark?.icon = ContextCompat.getDrawable(this, R.drawable.ic_bookmark_border)
  427. }
  428. }
  429. }
  430. private fun isBelowKitkat(): Boolean {
  431. return true
  432. // return Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT
  433. }
  434. private fun showAllToolbars() {
  435. if (isBelowKitkat()) {
  436. val duration = ((1 - toolbar_readerActivity.alpha) * UI_ANIMATION_DURATION).toLong()
  437. AnimationUtil.showViewFromTopToBottom(toolbar_readerActivity, duration)
  438. AnimationUtil.showViewFromBottomToTop(viewGroup_readerActivity_bottomToolbar, duration)
  439. AnimationUtil.showViewFromLeftToRight(viewGroup_readerActivity_leftToolbar, duration)
  440. AnimationUtil.showViewFromRightToLeft(viewGroup_readerActivity_rightToolbar, duration)
  441. } else {
  442. constrainLayout_readerActivity_root.applyConstraintSet(originConstraintSet, UI_ANIMATION_DURATION)
  443. }
  444. isHidePdfPage = true
  445. }
  446. private fun hideAllToolbars() {
  447. if (isBelowKitkat()) {
  448. val duration = (toolbar_readerActivity.alpha * UI_ANIMATION_DURATION).toLong()
  449. AnimationUtil.hideViewFromBottomToTop(toolbar_readerActivity, duration)
  450. AnimationUtil.hideViewFromTopToBottom(viewGroup_readerActivity_bottomToolbar, duration)
  451. AnimationUtil.hideViewFromRightToLeft(viewGroup_readerActivity_leftToolbar, duration)
  452. AnimationUtil.hideViewFromLeftToRight(viewGroup_readerActivity_rightToolbar, duration)
  453. hideSearchViewSoftKeyboard()
  454. } else {
  455. constrainLayout_readerActivity_root.applyConstraintSet(this, R.layout.activity_reader_hide_all, UI_ANIMATION_DURATION)
  456. }
  457. }
  458. private fun hideTopLeftBottomToolbars() {
  459. if (isBelowKitkat()) {
  460. val duration = (toolbar_readerActivity.alpha * UI_ANIMATION_DURATION).toLong()
  461. AnimationUtil.hideViewFromBottomToTop(toolbar_readerActivity, duration)
  462. AnimationUtil.hideViewFromTopToBottom(viewGroup_readerActivity_bottomToolbar, duration)
  463. AnimationUtil.hideViewFromRightToLeft(viewGroup_readerActivity_leftToolbar, duration)
  464. hideSearchViewSoftKeyboard()
  465. } else {
  466. constrainLayout_readerActivity_root.applyConstraintSet(this, R.layout.activity_reader_hide_top_left_bottom, UI_ANIMATION_DURATION)
  467. }
  468. }
  469. private fun setupPdfChangedListener() {
  470. ReaderModel.onPdfChangedListener = object : OnPdfChangedListener {
  471. override fun onPageCreated(pages: List<Int>) {
  472. TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
  473. }
  474. override fun onPageDeleted(pages: List<Int>) {
  475. val view = linearLayout_readerActivity_leftToolbarContainer.getChildAt(0)
  476. if (view is LeftToolbarView) {
  477. view.updateContent()
  478. view.onScrollToContent(currentPageIndex, true)
  479. }
  480. }
  481. override fun onPageSelected(pageIndex: Int) {
  482. val view = linearLayout_readerActivity_leftToolbarContainer.getChildAt(0)
  483. if (view is LeftToolbarView) {
  484. view.onScrollToContent(currentPageIndex, true)
  485. }
  486. }
  487. override fun onPageUpdated(pages: List<Int>) {
  488. val view = linearLayout_readerActivity_leftToolbarContainer.getChildAt(0)
  489. if (view is LeftToolbarView) {
  490. view.updateContent()
  491. view.onScrollToContent(currentPageIndex, true)
  492. }
  493. }
  494. }
  495. }
  496. private fun updateBookmarkView() {
  497. val view = linearLayout_readerActivity_leftToolbarContainer.getChildAt(0)
  498. if (view is BookmarkView) {
  499. view.updateContent()
  500. view.onScrollToContent(currentPageIndex, true)
  501. }
  502. }
  503. private fun setupToolbar() {
  504. toolbar_readerActivity.setNavigationOnClickListener { finish() }
  505. toolbar_readerActivity.setOnMenuItemClickListener {
  506. when (it.itemId) {
  507. R.id.item_reader_bookmark -> onClickBookmark()
  508. R.id.item_reader_more_text_reflow -> onClickTextReflow()
  509. R.id.item_reader_more_file_info -> onClickFileInfo()
  510. R.id.item_reader_more_print -> onClickPrint()
  511. R.id.item_reader_more_user_guide -> onClickUserGuide()
  512. }
  513. return@setOnMenuItemClickListener true
  514. }
  515. }
  516. private fun onClickBookmark() {
  517. viewModel.isPageInBookmarksLiveData.value?.let {
  518. if (!it) {
  519. showAddBookmarkDialog()
  520. } else {
  521. showDeleteBookmarkDialog()
  522. }
  523. }
  524. }
  525. private fun showAddBookmarkDialog() {
  526. val alertDialogBuilder = AlertDialog.Builder(this)
  527. val editText = EditText(this)
  528. val layoutParams =
  529. LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
  530. editText.layoutParams = layoutParams
  531. val defaultTitle = getString(R.string.dialogAddBookmark_page) + " " + (viewModel.pdfInfoHandler.getCurrentPage() + 1)
  532. editText.setText(defaultTitle, TextView.BufferType.EDITABLE)
  533. editText.setSelection(0, defaultTitle.length)
  534. alertDialogBuilder.setTitle(getString(R.string.reader_alert_dialog_title_add_bookmark))
  535. alertDialogBuilder.setView(editText)
  536. alertDialogBuilder.setPositiveButton(getString(R.string.reader_alert_dialog_button_confirm)) { dialog, which ->
  537. viewModel.addBookmark(editText.text.toString())
  538. updateBookmarkView()
  539. }
  540. alertDialogBuilder.setNegativeButton(getString(R.string.reader_alert_dialog_button_cancel)) { dialog, which ->
  541. }
  542. alertDialogBuilder.create().show()
  543. editText.requestFocus()
  544. }
  545. private fun getBookmarkTitle(page: Int): String {
  546. val bookmarks = viewModel.bookmarkHandler.getBookmarks()
  547. for (bookmark in bookmarks) {
  548. if (bookmark.pageNum == page) {
  549. return bookmark.title
  550. }
  551. }
  552. return ""
  553. }
  554. private fun showDeleteBookmarkDialog() {
  555. val alertDialogBuilder = AlertDialog.Builder(this)
  556. alertDialogBuilder.setTitle(getString(R.string.reader_alert_dialog_title_delete_bookmark))
  557. val bookmarkTitle = getBookmarkTitle(viewModel.pdfInfoHandler.getCurrentPage())
  558. val message = String.format(getString(R.string.reader_alert_dialog_message_delete_bookmark), bookmarkTitle)
  559. alertDialogBuilder.setMessage(message)
  560. alertDialogBuilder.setPositiveButton(getString(R.string.reader_alert_dialog_button_confirm)) { dialog, which ->
  561. viewModel.deleteBookmark()
  562. updateBookmarkView()
  563. }
  564. alertDialogBuilder.setNegativeButton(getString(R.string.reader_alert_dialog_button_cancel)) { dialog, which ->
  565. }
  566. alertDialogBuilder.create().show()
  567. }
  568. private fun hideSearchViewSoftKeyboard() {
  569. val view = linearLayout_readerActivity_leftToolbarContainer.getChildAt(0)
  570. if (view is SearchView) {
  571. view.hideSoftKeyboard()
  572. }
  573. }
  574. private fun setupLeftToolbar() {
  575. viewGroup_readerActivity_leftToolbar.setScroll(false)
  576. setLeftToolbarWidth(w_240)
  577. viewGroup_readerActivity_leftToolbar.smoothScrollTo(w_240, 0, 0)
  578. val child = layoutInflater.inflate(R.layout.view_thumbnail, null)
  579. linearLayout_readerActivity_leftToolbarContainer.addView(child)
  580. fun onClickLeftToolbarItem(leftToolbarType: ReaderViewModel.LeftToolbarType) {
  581. viewModel.setLeftToolbarType(leftToolbarType)
  582. updateLeftToolbarOpenState(leftToolbarType)
  583. }
  584. iv_readerActivity_thumbnail.setOnClickListener { onClickLeftToolbarItem(ReaderViewModel.LeftToolbarType.THUMBNAIL) }
  585. iv_readerActivity_bookmark.setOnClickListener { onClickLeftToolbarItem(ReaderViewModel.LeftToolbarType.BOOKMARK) }
  586. iv_readerActivity_outline.setOnClickListener { onClickLeftToolbarItem(ReaderViewModel.LeftToolbarType.OUTLINE) }
  587. iv_readerActivity_search.setOnClickListener { onClickLeftToolbarItem(ReaderViewModel.LeftToolbarType.SEARCH) }
  588. }
  589. private val readerSettingListener = object : ReaderSettingListener {
  590. override fun onReadModeChanged(readMode: Int) {
  591. viewModel.readMode = when (readMode) {
  592. ReadingModeSelectView.modeDay -> ReaderViewModel.ReadMode.READ_MODE_DAY
  593. ReadingModeSelectView.modeNight -> ReaderViewModel.ReadMode.READ_MODE_NIGHT
  594. ReadingModeSelectView.modeLilac -> ReaderViewModel.ReadMode.READ_MODE_SOFT
  595. ReadingModeSelectView.modeSefia -> ReaderViewModel.ReadMode.USER_DEFINED
  596. else -> ReaderViewModel.ReadMode.READ_MODE_DAY
  597. }
  598. }
  599. override fun onCropModeEnableChanged(enable: Boolean) {
  600. viewModel.isCrop = enable
  601. val buttons = arrayOf(iv_readerActivity_highLight, iv_readerActivity_strike, iv_readerActivity_underline, iv_readerActivity_ink, ib_readerActivity_bottomToolbarMediaBox)
  602. if (enable) {
  603. viewModel.stopAnnotationMode()
  604. val color = ContextCompat.getColor(baseContext, R.color.reader_right_toolbar_disabled_bg)
  605. for (button in buttons) {
  606. button.isEnabled = false
  607. button.setBackgroundColor(color)
  608. }
  609. } else {
  610. for (button in buttons) {
  611. button.isEnabled = true
  612. button.setBackgroundDrawable(null)
  613. }
  614. }
  615. }
  616. override fun onShowStateBarEnableChanged(enable: Boolean, dialog: Dialog?) {
  617. when (enable) {
  618. true -> {
  619. dialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
  620. window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
  621. }
  622. false -> {
  623. dialog?.window?.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
  624. window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
  625. }
  626. }
  627. }
  628. override fun onTurnPageDirectionChanged(direction: Int) {
  629. viewModel.viewDirection = when (direction == 0) {
  630. true -> ReaderViewModel.ViewDirection.VerticalSinglePageContinues
  631. false -> ReaderViewModel.ViewDirection.HorizontalSinglePage
  632. }
  633. }
  634. override fun onShowTurnPageBtnEnableChanged(enable: Boolean) {
  635. when (enable) {
  636. true -> {
  637. ib_readerActivity_bottomToolbarPrevious.visibility = View.VISIBLE
  638. ib_readerActivity_bottomToolbarNext.visibility = View.VISIBLE
  639. }
  640. false -> {
  641. ib_readerActivity_bottomToolbarPrevious.visibility = View.GONE
  642. ib_readerActivity_bottomToolbarNext.visibility = View.GONE
  643. }
  644. }
  645. }
  646. override fun onLockScreenSleepEnableChanged(enable: Boolean) {
  647. when (enable) {
  648. true -> window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
  649. false -> window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
  650. }
  651. }
  652. override fun onShowCommentToolEnableChanged(enable: Boolean) {
  653. }
  654. override fun onShowBOTAToolEnableChanged(enable: Boolean) {
  655. }
  656. }
  657. private fun setupRightSideToolbar() {
  658. iv_readerActivity_setting.setOnClickListener {
  659. val settingDialog = provideReaderSettingDialogFragment()
  660. settingDialog.show(supportFragmentManager, FRAGMENT_READER_SETTING_TAG)
  661. settingDialog.setReaderSettingListener(readerSettingListener)
  662. }
  663. }
  664. private fun applySetting() {
  665. val model = SharePrefsModel(this)
  666. readerSettingListener.onReadModeChanged(model.readMode.value ?: 0)
  667. readerSettingListener.onShowStateBarEnableChanged(model.isShowStateBarEnable.value ?: false, null)
  668. readerSettingListener.onTurnPageDirectionChanged(model.turnPageDirection.value ?: 0)
  669. readerSettingListener.onShowTurnPageBtnEnableChanged(model.isShowTurnPageBtnEnable.value ?: false)
  670. readerSettingListener.onLockScreenSleepEnableChanged(model.isLockScreenSleepEnable.value ?: false)
  671. readerSettingListener.onShowCommentToolEnableChanged(model.isShowCommentToolEnable.value ?: false)
  672. readerSettingListener.onShowBOTAToolEnableChanged(model.isShowBOTAToolEnable.value ?: false)
  673. }
  674. private fun setupBottomToolbar() {
  675. ib_readerActivity_bottomToolbarMediaBox.setOnClickListener { mediaBoxView.show() }
  676. ib_readerActivity_bottomToolbarViewAll.setOnClickListener {
  677. onClickBottomThumb1()
  678. }
  679. ib_readerActivity_bottomToolbarPrevious.setOnClickListener {
  680. val handler = viewModel.pdfInfoHandler
  681. val pageIndex = handler.getCurrentPage()
  682. val previousPageIndex = Math.max(pageIndex - 1, 0)
  683. handler.setCurrentPage(previousPageIndex)
  684. }
  685. ib_readerActivity_bottomToolbarNext.setOnClickListener {
  686. val handler = viewModel.pdfInfoHandler
  687. val pageIndex = handler.getCurrentPage()
  688. val nextPageIndex = Math.min(pageIndex + 1, handler.getPdfPageCount())
  689. handler.setCurrentPage(nextPageIndex)
  690. }
  691. ib_readerActivity_bottomToolbarKdanCloud.setOnClickListener {
  692. onClickKdanCloud()
  693. }
  694. ib_readerActivity_bottomToolbarShare.setOnClickListener {
  695. onClickShare()
  696. }
  697. }
  698. private fun setupMediaBoxView() {
  699. fun showSnackbar(title: String, btnText: String) {
  700. snackbarMediaBox = Snackbar.make(mediaBoxView, title, Snackbar.LENGTH_INDEFINITE)
  701. .setAction(btnText) {
  702. viewModel.clearSelection()
  703. mediaBoxView.post {
  704. mediaBoxView.show()
  705. snackbarMediaBox?.dismiss()
  706. snackbarMediaBox = null
  707. }
  708. }
  709. snackbarMediaBox?.setActionTextColor(ContextCompat.getColor(this, R.color.bright_blue))
  710. snackbarMediaBox?.show()
  711. }
  712. mediaBoxView.apply {
  713. onShowListener = Runnable {
  714. onMediaBoxShown()
  715. snackbarMediaBox?.dismiss()
  716. snackbarMediaBox = null
  717. }
  718. onDismissListener = Runnable {
  719. onMediaBoxDismissed()
  720. snackbarMediaBox?.dismiss()
  721. snackbarMediaBox = null
  722. }
  723. onClickAddButtonListener = object : MediaBoxView.OnClickHeaderButtonListener {
  724. override fun onClickTextBoxAddButton(textBoxTabView: TextBoxTabView) {
  725. dismiss(false)
  726. viewModel.setTextBoxAttribute(textBoxTabView.getTextBoxAttribute())
  727. showSnackbar(resources.getString(R.string.reader_mediaBox_snakebar_textBox), resources.getString(R.string.reader_mediaBox_snakebar_undo))
  728. }
  729. override fun onClickTextBoxStyleApplyButton(textBoxTabView: TextBoxTabView) {
  730. dismiss(false)
  731. viewModel.setTextBoxAttribute(textBoxTabView.getTextBoxAttribute(), true)
  732. }
  733. override fun onClickSignatureAddButton(signatureTabView: SignatureTabView) {
  734. dismiss(false)
  735. viewModel.setSignatureAttribute(signatureTabView.getSignatureAttribute())
  736. showSnackbar(resources.getString(R.string.reader_mediaBox_snakebar_signature), resources.getString(R.string.reader_mediaBox_snakebar_undo))
  737. }
  738. override fun onClickStampAddButton(stampTabView: StampTabView) {
  739. dismiss(false)
  740. viewModel.setStampAttribute(stampTabView.getStampAttribute())
  741. showSnackbar(resources.getString(R.string.reader_mediaBox_snakebar_stamp), resources.getString(R.string.reader_mediaBox_snakebar_undo))
  742. }
  743. override fun onClickShapeAddButton(shapeTabView: ShapeTabView) {
  744. dismiss(false)
  745. viewModel.setShapeAttribute(shapeTabView.getShapeAttribute())
  746. showSnackbar(resources.getString(R.string.reader_mediaBox_snakebar_shape), resources.getString(R.string.reader_mediaBox_snakebar_undo))
  747. }
  748. }
  749. }
  750. }
  751. private fun setupRightToolbar() {
  752. iv_readerActivity_highLight.apply {
  753. setOnClickListener { viewModel.onClickHighlightBtn() }
  754. setOnLongClickListener { btn ->
  755. viewModel.onLongClickHighlightBtn()
  756. val context = this@ReaderActivity
  757. AnnotationAttributeWindow(context, true).also { window ->
  758. viewModel.highLightAttributeLiveData.value?.let { attr ->
  759. window.annotationAttributeView.annotationAttribute = attr
  760. }
  761. window.annotationAttributeView.onChangeListener = object : AnnotationAttributeView.OnChangeListener {
  762. override fun onChange(annotationAttributeView: AnnotationAttributeView) {
  763. viewModel.setHighLightAttributes(annotationAttributeView.annotationAttribute)
  764. }
  765. }
  766. val contentView = window.contentView.apply {
  767. val w = Utils.makeDropDownMeasureSpec(window.width)
  768. val y = Utils.makeDropDownMeasureSpec(window.height)
  769. measure(w, y)
  770. }
  771. val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
  772. val xOff = (-contentView.measuredWidth - space).toInt()
  773. val yOff = -btn.height
  774. window.showAsDropDown(btn, xOff, yOff)
  775. }
  776. return@setOnLongClickListener true
  777. }
  778. }
  779. iv_readerActivity_strike.apply {
  780. setOnClickListener { viewModel.onClickStrikeBtn() }
  781. setOnLongClickListener { btn ->
  782. viewModel.onLongClickStrikeBtn()
  783. val context = this@ReaderActivity
  784. AnnotationAttributeWindow(context, true).also { window ->
  785. viewModel.strikeAttributeLiveData.value?.let { attr ->
  786. window.annotationAttributeView.annotationAttribute = attr
  787. }
  788. window.annotationAttributeView.onChangeListener = object : AnnotationAttributeView.OnChangeListener {
  789. override fun onChange(annotationAttributeView: AnnotationAttributeView) {
  790. viewModel.setStrikeOutAttributes(annotationAttributeView.annotationAttribute)
  791. }
  792. }
  793. val contentView = window.contentView.apply {
  794. val w = Utils.makeDropDownMeasureSpec(window.width)
  795. val y = Utils.makeDropDownMeasureSpec(window.height)
  796. measure(w, y)
  797. }
  798. val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
  799. val xOff = (-contentView.measuredWidth - space).toInt()
  800. val yOff = -btn.height
  801. window.showAsDropDown(btn, xOff, yOff)
  802. }
  803. return@setOnLongClickListener true
  804. }
  805. }
  806. iv_readerActivity_underline.apply {
  807. setOnClickListener { viewModel.onClickUnderlineBtn() }
  808. setOnLongClickListener { btn ->
  809. viewModel.onLongClickUnderlineBtn()
  810. val context = this@ReaderActivity
  811. AnnotationAttributeWindow(context, true).also { window ->
  812. viewModel.underLineAttributeLiveData.value?.let { attr ->
  813. window.annotationAttributeView.annotationAttribute = attr
  814. }
  815. window.annotationAttributeView.onChangeListener = object : AnnotationAttributeView.OnChangeListener {
  816. override fun onChange(annotationAttributeView: AnnotationAttributeView) {
  817. viewModel.setUnderLineAttributes(annotationAttributeView.annotationAttribute)
  818. }
  819. }
  820. val contentView = window.contentView.apply {
  821. val w = Utils.makeDropDownMeasureSpec(window.width)
  822. val y = Utils.makeDropDownMeasureSpec(window.height)
  823. measure(w, y)
  824. }
  825. val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
  826. val xOff = (-contentView.measuredWidth - space).toInt()
  827. val yOff = -btn.height
  828. window.showAsDropDown(btn, xOff, yOff)
  829. }
  830. return@setOnLongClickListener true
  831. }
  832. }
  833. iv_readerActivity_ink.apply {
  834. setOnClickListener { viewModel.onClickInkBtn() }
  835. setOnLongClickListener { btn ->
  836. viewModel.onLongClickInkBtn()
  837. val context = this@ReaderActivity
  838. AnnotationAttributeWindow(context, false).also { window ->
  839. viewModel.inkAttributeLiveData.value?.let { attr ->
  840. window.annotationAttributeView.inkAttribute = attr
  841. }
  842. window.annotationAttributeView.onChangeListener = object : AnnotationAttributeView.OnChangeListener {
  843. override fun onChange(annotationAttributeView: AnnotationAttributeView) {
  844. viewModel.setInkAttributes(annotationAttributeView.inkAttribute)
  845. }
  846. }
  847. val contentView = window.contentView.apply {
  848. val w = Utils.makeDropDownMeasureSpec(window.width)
  849. val y = Utils.makeDropDownMeasureSpec(window.height)
  850. measure(w, y)
  851. }
  852. val space = resources.getDimension(R.dimen.reader_annotation_property_setting_window_right_toolbar_space)
  853. val xOff = (-contentView.measuredWidth - space).toInt()
  854. val yOff = -contentView.measuredHeight
  855. window.showAsDropDown(btn, xOff, yOff)
  856. }
  857. return@setOnLongClickListener true
  858. }
  859. }
  860. }
  861. private fun setLeftToolbarWidth(width: Int) {
  862. var params = viewGroup_readerActivity_leftToolbar.layoutParams as ConstraintLayout.LayoutParams
  863. params.width = width + w_left
  864. params.height = 0
  865. viewGroup_readerActivity_leftToolbar.layoutParams = params
  866. params = linearLayout_readerActivity_leftToolbarContainer.layoutParams as ConstraintLayout.LayoutParams
  867. params.width = width
  868. linearLayout_readerActivity_leftToolbarContainer.layoutParams = params
  869. }
  870. private fun updateLeftToolbarOpenState(type: ReaderViewModel.LeftToolbarType) {
  871. val isLeftToolbarOpen = viewModel.isLeftToolbarOpenLiveData.value ?: false
  872. viewModel.setIsLeftToolbarOpen(!isLeftToolbarOpen || oldLeftToolbarType != type)
  873. cloneOriginConstraintSet()
  874. }
  875. private fun onMediaBoxShown() {
  876. hideAllToolbars()
  877. isHideToolbar = true
  878. }
  879. private fun onMediaBoxDismissed() {
  880. showAllToolbars()
  881. isHideToolbar = false
  882. viewModel.clearSelection()
  883. }
  884. private fun setLeftToolbarContentView(leftToolbarType: ReaderViewModel.LeftToolbarType) {
  885. if (oldLeftToolbarType != leftToolbarType) {
  886. linearLayout_readerActivity_leftToolbarContainer.removeAllViews()
  887. val view = when (leftToolbarType) {
  888. ReaderViewModel.LeftToolbarType.NONE,
  889. ReaderViewModel.LeftToolbarType.THUMBNAIL -> {
  890. val thumbnailView = ThumbnailView(this)
  891. thumbnailView.setHandlers(viewModel.pdfInfoHandler, viewModel.thumbnailHandler)
  892. thumbnailView
  893. }
  894. ReaderViewModel.LeftToolbarType.BOOKMARK -> {
  895. val bookmarkView = BookmarkView(this)
  896. bookmarkView.setHandlers(viewModel.pdfInfoHandler, viewModel.thumbnailHandler, viewModel.bookmarkHandler)
  897. bookmarkView
  898. }
  899. ReaderViewModel.LeftToolbarType.OUTLINE -> {
  900. val outlineView = OutlineView(this)
  901. outlineView.setHandlers(viewModel.pdfInfoHandler, viewModel.outlineHandler)
  902. outlineView
  903. }
  904. ReaderViewModel.LeftToolbarType.SEARCH -> {
  905. val searchView = SearchView(this)
  906. searchView.setHandlers(viewModel.pdfInfoHandler, viewModel.searchHandler)
  907. searchView
  908. }
  909. }
  910. linearLayout_readerActivity_leftToolbarContainer.addView(view as View)
  911. oldLeftToolbarType = leftToolbarType
  912. }
  913. }
  914. private fun getLeftToolbarContentWidth(): Int {
  915. return when (viewModel.leftToolbarTypeLiveData.value == ReaderViewModel.LeftToolbarType.THUMBNAIL) {
  916. true -> w_240
  917. false -> w_318
  918. }
  919. }
  920. private fun onLeftToolbarTypeChanged(leftToolbarType: ReaderViewModel.LeftToolbarType?) {
  921. updateLeftToolbarIcons()
  922. setLeftToolbarWidth(getLeftToolbarContentWidth())
  923. cloneOriginConstraintSet()
  924. if (leftToolbarType != null) {
  925. setLeftToolbarContentView(leftToolbarType)
  926. }
  927. }
  928. private fun onLeftToolbarOpenStateChanged(open: Boolean?) {
  929. updateLeftToolbarIcons()
  930. when (open == true) {
  931. true -> viewGroup_readerActivity_leftToolbar.smoothScrollTo(0, 0, UI_ANIMATION_DURATION.toInt())
  932. false -> viewGroup_readerActivity_leftToolbar.smoothScrollTo(getLeftToolbarContentWidth(), 0, UI_ANIMATION_DURATION.toInt())
  933. }
  934. }
  935. private fun updateLeftToolbarIcons() {
  936. iv_readerActivity_thumbnail.setImageResource(R.drawable.ic_left_toolbar_thumbnails)
  937. iv_readerActivity_bookmark.setImageResource(R.drawable.ic_left_toolbar_bookmarks)
  938. iv_readerActivity_outline.setImageResource(R.drawable.ic_left_toolbar_outline)
  939. iv_readerActivity_search.setImageResource(R.drawable.ic_left_toolbar_search)
  940. if (viewModel.isLeftToolbarOpenLiveData.value == true) {
  941. when (viewModel.leftToolbarTypeLiveData.value) {
  942. ReaderViewModel.LeftToolbarType.NONE -> {}
  943. ReaderViewModel.LeftToolbarType.THUMBNAIL -> iv_readerActivity_thumbnail.setImageResource(R.drawable.ic_left_toolbar_thumbnails_selected)
  944. ReaderViewModel.LeftToolbarType.BOOKMARK -> iv_readerActivity_bookmark.setImageResource(R.drawable.ic_left_toolbar_bookmarks_selected)
  945. ReaderViewModel.LeftToolbarType.OUTLINE -> iv_readerActivity_outline.setImageResource(R.drawable.ic_left_toolbar_outline_selected)
  946. ReaderViewModel.LeftToolbarType.SEARCH -> iv_readerActivity_search.setImageResource(R.drawable.ic_left_toolbar_search_selected)
  947. }
  948. }
  949. }
  950. private fun onClickBottomThumb1() {
  951. val intent = transferThumbIntent()
  952. startActivityForResult(intent, THUMB)
  953. }
  954. override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  955. super.onActivityResult(requestCode, resultCode, data)
  956. if (resultCode == Activity.RESULT_OK){
  957. when (requestCode) {
  958. THUMB -> {
  959. val mode = data?.getIntExtra("operate", -1)
  960. when (mode) {
  961. PdfThumbActivity.THUMB_NORMAL -> {
  962. val pageIndex = data.getIntExtra("result", 0)
  963. viewModel.pdfInfoHandler.setCurrentPage(pageIndex)
  964. viewModel.setPageIndex(pageIndex)
  965. }
  966. }
  967. }
  968. REQUEST_PASSWORD -> {
  969. val password = data?.getStringExtra("password") ?: ""
  970. if (password.isEmpty()) {
  971. finish()
  972. } else {
  973. viewModel.isOpenedFileLiveData.value?.also { isOpened ->
  974. if (isOpened) return@also
  975. val filePath = intent.getStringExtra(KEY_FILE_ABSOLUTE)
  976. val uri = Uri.parse(filePath)
  977. viewModel.openPdfFile(this, uri, password, Runnable { requestPassword(true) }, intent.type)
  978. }
  979. }
  980. }
  981. }
  982. }
  983. }
  984. }