Implemented displaying icon for bank

This commit is contained in:
dankito 2020-04-27 01:28:33 +02:00
parent 584b797788
commit d91bffdd0a
5 changed files with 93 additions and 6 deletions

View File

@ -9,6 +9,7 @@ import net.dankito.banking.ui.javafx.controls.AccountsView
import net.dankito.banking.ui.javafx.dialogs.mainwindow.controls.MainMenuBar import net.dankito.banking.ui.javafx.dialogs.mainwindow.controls.MainMenuBar
import net.dankito.banking.ui.javafx.util.Base64ServiceJava8 import net.dankito.banking.ui.javafx.util.Base64ServiceJava8
import net.dankito.banking.ui.presenter.BankingPresenter import net.dankito.banking.ui.presenter.BankingPresenter
import net.dankito.banking.util.BankIconFinder
import net.dankito.fints.banks.LuceneBankFinder import net.dankito.fints.banks.LuceneBankFinder
import net.dankito.utils.web.client.OkHttpWebClient import net.dankito.utils.web.client.OkHttpWebClient
import tornadofx.* import tornadofx.*
@ -25,9 +26,9 @@ class MainWindow : View(messages["application.title"]) {
private val indexFolder = File(dataFolder, "index") private val indexFolder = File(dataFolder, "index")
private val presenter = BankingPresenter(fints4javaBankingClientCreator(OkHttpWebClient(), Base64ServiceJava8()), private val presenter = BankingPresenter(fints4javaBankingClientCreator(OkHttpWebClient(), Base64ServiceJava8()),
LuceneBankFinder(indexFolder), databaseFolder, BankingPersistenceJson(File(databaseFolder, "accounts.json")), RouterJavaFx()) LuceneBankFinder(indexFolder), databaseFolder, dataFolder, BankingPersistenceJson(File(databaseFolder, "accounts.json")), BankIconFinder(), RouterJavaFx())
// private val presenter = BankingPresenter(hbci4jBankingClientCreator(), LuceneBankFinder(indexFolder), databaseFolder, // private val presenter = BankingPresenter(hbci4jBankingClientCreator(), LuceneBankFinder(indexFolder), databaseFolder,
// BankingPersistenceJson(File(databaseFolder, "accounts.json")), RouterJavaFx()) // dataFolder, BankingPersistenceJson(File(databaseFolder, "accounts.json")), BankIconFinder(), RouterJavaFx())

View File

@ -1,16 +1,40 @@
package net.dankito.banking.ui.javafx.model package net.dankito.banking.ui.javafx.model
import javafx.scene.Node
import javafx.scene.image.ImageView
import net.dankito.banking.ui.model.Account import net.dankito.banking.ui.model.Account
open class AccountsAccountTreeItem(val account: Account) : AccountsTreeItemBase(account.displayName) { open class AccountsAccountTreeItem(val account: Account) : AccountsTreeItemBase(account.displayName) {
companion object {
private const val IconSize = 16.0
}
init { init {
isExpanded = true isExpanded = true
graphic = createIconImageView()
account.bankAccounts.forEach { bankAccount -> account.bankAccounts.forEach { bankAccount ->
children.add(AccountsBankAccountTreeItem(bankAccount)) children.add(AccountsBankAccountTreeItem(bankAccount))
} }
} }
protected open fun createIconImageView(): Node? {
account.bank.iconUrl?.let {
val iconImageView = ImageView(it)
iconImageView.fitHeight = IconSize
iconImageView.fitWidth = IconSize
iconImageView.isPreserveRatio = true
return iconImageView
}
// TODO: otherwise set default icon
return null
}
} }

View File

@ -16,6 +16,7 @@ import net.dankito.banking.ui.model.tan.EnterTanGeneratorAtcResult
import net.dankito.banking.ui.model.tan.EnterTanResult import net.dankito.banking.ui.model.tan.EnterTanResult
import net.dankito.banking.ui.model.tan.TanChallenge import net.dankito.banking.ui.model.tan.TanChallenge
import net.dankito.banking.ui.model.tan.TanGeneratorTanMedium import net.dankito.banking.ui.model.tan.TanGeneratorTanMedium
import net.dankito.banking.util.IBankIconFinder
import net.dankito.fints.banks.IBankFinder import net.dankito.fints.banks.IBankFinder
import net.dankito.fints.model.BankInfo import net.dankito.fints.model.BankInfo
import net.dankito.utils.IThreadPool import net.dankito.utils.IThreadPool
@ -24,7 +25,9 @@ import net.dankito.utils.extensions.containsExactly
import net.dankito.utils.extensions.ofMaxLength import net.dankito.utils.extensions.ofMaxLength
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.io.File import java.io.File
import java.io.FileOutputStream
import java.math.BigDecimal import java.math.BigDecimal
import java.net.URL
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
@ -33,7 +36,9 @@ open class BankingPresenter(
protected val bankingClientCreator: IBankingClientCreator, protected val bankingClientCreator: IBankingClientCreator,
protected val bankFinder: IBankFinder, protected val bankFinder: IBankFinder,
protected val databaseFolder: File, protected val databaseFolder: File,
protected val dataFolder: File,
protected val persister: IBankingPersistence, protected val persister: IBankingPersistence,
protected val bankIconFinder: IBankIconFinder,
protected val router: IRouter, protected val router: IRouter,
protected val threadPool: IThreadPool = ThreadPool() protected val threadPool: IThreadPool = ThreadPool()
) { ) {
@ -155,12 +160,54 @@ open class BankingPresenter(
retrievedAccountTransactions(bankAccount, response) retrievedAccountTransactions(bankAccount, response)
} }
} }
findIconForBankAsync(account)
} }
callback(response) callback(response)
} }
} }
protected open fun findIconForBankAsync(account: Account) {
threadPool.runAsync {
findIconForBank(account)
}
}
protected open fun findIconForBank(account: Account) {
val bank = account.bank
try {
bankIconFinder.findIconForBank(bank.name)?.let { bankIconUrl ->
val bankIconFile = saveBankIconToDisk(bankIconUrl)
bank.iconUrl = "file://" + bankIconFile.absolutePath // without 'file://' Android will not find it
persistAccount(account)
callAccountsChangedListeners()
}
} catch (e: Exception) {
log.error("Could not get icon for bank $bank", e)
}
}
private fun saveBankIconToDisk(bankIconUrl: String): File {
val bankIconsDir = File(dataFolder, "bank_icons")
bankIconsDir.mkdirs()
val bankIconFile = File(bankIconsDir, File(bankIconUrl).name)
URL(bankIconUrl).openConnection().getInputStream().buffered().use { iconInputStream ->
FileOutputStream(bankIconFile).use { fileOutputStream ->
iconInputStream.copyTo(fileOutputStream)
}
}
return bankIconFile
}
open fun deleteAccount(account: Account) { open fun deleteAccount(account: Account) {
val wasSelected = isSingleSelectedAccount(account) or // either account or one of its bank accounts is currently selected val wasSelected = isSingleSelectedAccount(account) or // either account or one of its bank accounts is currently selected
(account.bankAccounts.firstOrNull { isSingleSelectedBankAccount(it) } != null) (account.bankAccounts.firstOrNull { isSingleSelectedBankAccount(it) } != null)

View File

@ -14,6 +14,8 @@ import net.dankito.banking.search.LuceneRemitteeSearcher
import net.dankito.banking.ui.IBankingClientCreator import net.dankito.banking.ui.IBankingClientCreator
import net.dankito.banking.ui.IRouter import net.dankito.banking.ui.IRouter
import net.dankito.banking.ui.presenter.BankingPresenter import net.dankito.banking.ui.presenter.BankingPresenter
import net.dankito.banking.util.BankIconFinder
import net.dankito.banking.util.IBankIconFinder
import net.dankito.fints.banks.IBankFinder import net.dankito.fints.banks.IBankFinder
import net.dankito.fints.banks.LuceneBankFinder import net.dankito.fints.banks.LuceneBankFinder
import net.dankito.utils.IThreadPool import net.dankito.utils.IThreadPool
@ -75,17 +77,24 @@ class BankingModule(internal val mainActivity: AppCompatActivity) {
@Provides @Provides
@Singleton @Singleton
fun provideBankingPresenter(bankingClientCreator: IBankingClientCreator, bankFinder: IBankFinder, fun provideBankingPresenter(bankingClientCreator: IBankingClientCreator, bankFinder: IBankFinder,
@Named(DatabaseFolderKey) databaseFolder: File, persister: IBankingPersistence, @Named(DatabaseFolderKey) databaseFolder: File, @Named(DataFolderKey) dataFolder: File,
persister: IBankingPersistence, bankIconFinder: IBankIconFinder,
router: IRouter, threadPool: IThreadPool) : BankingPresenter { router: IRouter, threadPool: IThreadPool) : BankingPresenter {
return BankingPresenter(bankingClientCreator, bankFinder, databaseFolder, persister, router, threadPool) return BankingPresenter(bankingClientCreator, bankFinder, databaseFolder, dataFolder, persister, bankIconFinder, router, threadPool)
} }
@Provides @Provides
@Singleton @Singleton
fun provideBankFinder(@Named(IndexFolderKey) indexFolder: File, threadPool: IThreadPool) : IBankFinder { fun provideBankFinder(@Named(IndexFolderKey) indexFolder: File) : IBankFinder {
return LuceneBankFinder(indexFolder) return LuceneBankFinder(indexFolder)
} }
@Provides
@Singleton
fun provideBankIconFinder() : IBankIconFinder {
return BankIconFinder()
}
@Provides @Provides
@Singleton @Singleton
fun provideBankingClientCreator(webClient: IWebClient, base64Service: net.dankito.banking.util.IBase64Service) : IBankingClientCreator { fun provideBankingClientCreator(webClient: IWebClient, base64Service: net.dankito.banking.util.IBase64Service) : IBankingClientCreator {

View File

@ -117,7 +117,7 @@ open class DrawerView(
private fun createAccountDrawerItem(account: Account): IDrawerItem<*> { private fun createAccountDrawerItem(account: Account): IDrawerItem<*> {
return AccountDrawerItem() val accountItem = AccountDrawerItem()
.withName(account.displayName) .withName(account.displayName)
.withLevel(AccountLevel) .withLevel(AccountLevel)
// .withSecondaryIcon(GoogleMaterial.Icon.gmd_settings) // used when editing account is implemented // .withSecondaryIcon(GoogleMaterial.Icon.gmd_settings) // used when editing account is implemented
@ -127,6 +127,12 @@ open class DrawerView(
.withIcon(activity, FontAwesome.Icon.faw_piggy_bank, R.color.primaryTextColor_Dark) .withIcon(activity, FontAwesome.Icon.faw_piggy_bank, R.color.primaryTextColor_Dark)
.withSelected(presenter.isSingleSelectedAccount(account)) .withSelected(presenter.isSingleSelectedAccount(account))
.withOnDrawerItemClickListener { _, _, _ -> itemClicked { presenter.selectedAccount(account) } } .withOnDrawerItemClickListener { _, _, _ -> itemClicked { presenter.selectedAccount(account) } }
account.bank.iconUrl?.let { bankIconUrl ->
accountItem.withIcon(bankIconUrl)
}
return accountItem
} }
private fun createBankAccountsDrawerItems(account: Account): List<IDrawerItem<*>> { private fun createBankAccountsDrawerItems(account: Account): List<IDrawerItem<*>> {