package Ġcom . aqu atic . luc re . activities . entry Ċ Ċ import Ġandroid . app . AlertDialog Ċ import Ġandroid . content . Intent Ċ import Ġandroid . os . Bundle Ċ import Ġandroid . view . Menu Ċ import Ġandroid . view . MenuItem Ċ import Ġandroid . view . View Ċ import Ġandroidx . activity . view Models Ċ import Ġandroidx . appcompat . app . AppCompatActivity Ċ import Ġandroidx . core . util . Predicate Ċ import Ġandroidx . lifecycle . Observer Ċ import Ġcom . aqu atic . luc re . R Ċ import Ġcom . aqu atic . luc re . activities . ui . Maps Activity Ċ import Ġcom . aqu atic . luc re . activities . ui . Spinner Activity Ċ import Ġcom . aqu atic . luc re . extensions . validate Ċ import Ġcom . aqu atic . luc re . main . App Ċ import Ġcom . aqu atic . luc re . models . Category Ċ import Ġcom . aqu atic . luc re . models . Entry Ċ import Ġcom . aqu atic . luc re . models . Entry Type Ċ import Ġcom . aqu atic . luc re . models . Location Ċ import Ġcom . aqu atic . luc re . utilities . IMAGE _ REQUEST Ċ import Ġcom . aqu atic . luc re . utilities . LOCATION _ REQUEST Ċ import Ġcom . aqu atic . luc re . utilities . read Image Ċ import Ġcom . aqu atic . luc re . utilities . show Image Picker Ċ import Ġcom . aqu atic . luc re . view models . Category ViewModel Ċ import Ġcom . aqu atic . luc re . view models . Entry ViewModel Ċ import Ġkotlinx . android . synt hetic . main . activity _ entry .* Ċ import Ġorg . jetbrains . ank o . An ko Logger Ċ import Ġorg . jetbrains . ank o . intent For Ċ Ċ class ĠEntry Activity Ġ: ĠAppCompatActivity (), ĠAn ko Logger Ġ{ ĊĊĠĠĠ Ġ/* ĠEmpty Ġentry Ġobject Ġ*/ ĊĠĠĠ Ġvar Ġentry Ġ= ĠEntry () ĊĊĠĠĠ Ġ/* ĠVault Ġid Ġ*/ ĊĠĠĠ Ġvar Ġvault : ĠString ? Ġ= Ġnull ĊĊĠĠĠ Ġ/* ĠDefault Ġlocation Ġ*/ ĊĠĠĠ Ġvar Ġlocation Ġ= ĠLocation ( 5 2 . 2 4 5 6 9 6 , Ġ- 7 . 1 3 9 1 0 2 , Ġ 1 5 f ) ĊĊĠĠĠ Ġ/* ĠEntry Ġexp enses Ġin Ġlist Ġformat Ġ*/ ĊĠĠĠ Ġvar Ġtypes Ġ= Ġmutable ListOf (" Income ", Ġ" Expense ") ĊĊĠĠĠ Ġ/* ĠSp inner Ġfor Ġcategory Ġtype Ġ*/ ĊĠĠĠ Ġlateinit Ġvar Ġcategory : ĠSp inner Activity < Category > ĊĊĠĠĠ Ġ/* ĠSp inner Ġfor Ġentry Ġtype Ġ*/ ĊĠĠĠ Ġlateinit Ġvar Ġtype : ĠSp inner Activity < String > ĊĊĠĠĠ Ġ/* ĠAndroid Ġapplication Ġobject Ġ*/ ĊĠĠĠ Ġlateinit Ġvar Ġapp : ĠApp ĊĊĠĠĠ Ġ/* ĠCategory ĠViewModel Ġby Ġinjection Ġ*/ ĊĠĠĠ Ġval Ġcategory Model : ĠCategory ViewModel Ġby Ġview Models () ĊĊĠĠĠ Ġ/* ĠEntry ĠViewModel Ġby Ġinjection Ġ*/ ĊĠĠĠ Ġval Ġmodel : ĠEntry ViewModel Ġby Ġview Models () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSetup Ġthe Ġactivity ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun ĠonCreate ( savedInstanceState : ĠBundle ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . onCreate ( savedInstanceState ) ĊĠĠĠĠĠĠĠ ĠsetContentView ( R . layout . activity _ entry ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġinstantiate Ġapplication Ġobject ĊĠĠĠĠĠĠĠ Ġapp Ġ= Ġapplication Ġas ĠApp ĊĊĠĠĠĠĠĠĠ Ġ// Ġset Ġthe Ġoptions Ġfor Ġthe Ġtype Ġspinner ĊĠĠĠĠĠĠĠ Ġtype Ġ= ĠSp inner Activity ( this , Ġentry Type , Ġtypes ) ĊĊĠĠĠĠĠĠĠ Ġentry Image Button . setOnClickListener Ġ{ Ġselect Image () Ġ} ĊĠĠĠĠĠĠĠ Ġentry Location . setOnClickListener Ġ{ Ġset Location () Ġ} ĊĠĠĠĠĠĠĠ Ġentry Submit . setOnClickListener Ġ{ Ġsubmit () Ġ} ĊĠĠĠĠĠĠĠ Ġentry Delete . setOnClickListener Ġ{ Ġopen Delete Dialog () Ġ} ĊĊĠĠĠĠĠĠĠ Ġhandle Intent () ĊĠĠĠĠĠĠĠ Ġget Categories () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġa Ġlist Ġof Ġcategories Ġfor Ġthe Ġcategories ĊĠĠĠĠ Ġ* Ġdropdown Ġspinner ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġget Categories () Ġ{ ĊĠĠĠĠĠĠĠ Ġcategory Model . list . observe ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠObserver Ġ{ Ġcategories Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġonce Ġwe Ġhave Ġthe Ġcategories , Ġwe Ġcan Ġpopulate Ġthe Ġspinner ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcategory Ġ= ĠSp inner Activity ( this , Ġentry Category , Ġcategories ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġthere Ġis Ġan Ġintent , Ġwe Ġneed Ġto Ġset Ġthe Ġcategory ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( intent . has Extra (" entry _ edit ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġpredicate Ġ= ĠPredicate < Category > Ġ{ Ġit . id Ġ=== Ġentry . category Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġneedle Ġ= Ġcategory Model . find ( predicate , Ġcategories ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcategory . setSelected Item ( needle ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠIf Ġthere Ġis Ġan Ġintent , Ġwe Ġneed Ġto Ġhandle Ġthis ĊĠĠĠĠ Ġ* Ġand Ġset Ġthe Ġassociated Ġdata ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġhandle Intent () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( intent . has Extra (" vault ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvault Ġ= Ġintent . extras ?. getString (" vault ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( intent . has Extra (" entry _ edit ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry Ġ= Ġintent . extras ?. get Parcelable < Entry >(" entry _ edit ") !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvault Ġ= Ġentry . vault ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry Amount . setText ( entry . amount . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry Vendor . setText ( entry . vendor ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtype . setSelected Item ( entry . type . toString (). toLowerCase ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry Description . setText ( entry . description ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entry . image . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbitmap Ġ= Ġread Image ( this , Ġentry . image ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry Image . setImage Bitmap ( bitmap ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry Image Button . setText ( R . string . entry _ edit _ image ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry Image . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry Delete . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry Submit . setText ( R . string . item _ edit ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠUpdate Ġthe Ġentry Ġlocation ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġset Location () Ġ{ ĊĠĠĠĠĠĠĠ Ġlocation Ġ= ĠLocation ( 5 2 . 2 4 5 6 9 6 , Ġ- 7 . 1 3 9 1 0 2 , Ġ 1 5 f , Ġentry . vendor Ġ?: Ġentry Vendor . text . toString ()) ĊĠĠĠĠĠĠĠ ĠstartActivity For Result ( intent For < Maps Activity >(). putExtra (" location ", Ġlocation ), ĠLOC ATION _ REQUEST ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠLaunch Ġthe Ġimage Ġpicker ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġselect Image () Ġ{ ĊĠĠĠĠĠĠĠ Ġshow Image Picker ( this , ĠIMAGE _ REQUEST ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSubmit Ġthe Ġentry Ġcreate / update Ġrequest ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġsubmit () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( validate ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry . amount Ġ= Ġentry Amount . text . toString (). toFloat () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry . type Ġ= ĠEntry Type . valueOf ( type . selection !!. toUpperCase ()). toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry . vendor Ġ= Ġentry Vendor . text . toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry . description Ġ= Ġentry Description . text . toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry . category Ġ= Ġcategory . selection ?. id !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry . location Ġ= Ġlocation ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry . vault Ġ= Ġvault ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . save Entry ( entry . copy ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Result ( AppCompatActivity . RESULT _ OK ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfinish () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠValidate Ġthe ĠEditText Ġfields ĊĠĠĠĠ Ġ* Ġto Ġmake Ġsure Ġall Ġinputs Ġare ĊĠĠĠĠ Ġ* Ġvalid ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġvalidate (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġget Resources (). getString ( R . string . required ) ĊĠĠĠĠĠĠĠ Ġreturn Ġentry Amount . validate ( message ) Ġ{ Ġit . isNotEmpty () Ġ} Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠ Ġentry Vendor . validate ( message ) Ġ{ Ġit . isNotEmpty () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠProgram matically Ġopen Ġthe Ġdelete Ġcategory ĊĠĠĠĠ Ġ* Ġdialog ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġopen Delete Dialog () Ġ{ ĊĠĠĠĠĠĠĠ ĠAlertDialog . Builder ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. setTitle (" Delete Ġentry ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. setMessage (" Are Ġyou Ġsure Ġyou Ġwant Ġto Ġdelete Ġthis Ġentry ?") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Cancel able ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Negative Button ( android . R . string . cancel , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Positive Button ( android . R . string . ok ) Ġ{ Ġ_, Ġ_ Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmodel . delete Entry ( entry ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfinish () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. show () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCheck Ġif Ġthere Ġhave Ġbeen Ġany Ġchanges Ġfor Ġimage Ġor Ġlocation Ġrequests ĊĠĠĠĠ Ġ* Ġand , Ġif Ġso , Ġupdate Ġthe Ġentry Ġaccordingly ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġon Activity Result ( request Code : ĠInt , ĠresultCode : ĠInt , Ġdata : ĠIntent ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġsuper . on Activity Result ( request Code , ĠresultCode , Ġdata ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ( request Code ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠIMAGE _ REQUEST Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( data Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO ĠUse Ġfirebase Ġfile Ġupload ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġpermissions Ġissues ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġhttps :// developer . android . com / training / data - storage / shared / documents - files # persist - permissions ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtake Flags : ĠInt Ġ= ĠIntent . FLAG _ GRANT _ READ _ URI _ PERMISSION Ġor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIntent . FLAG _ GRANT _ WRITE _ URI _ PERMISSION ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġfor Ġthe Ġf res hest Ġdata . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Resolver . take Persist able Uri Permission ( data . getData () !! , Ġtake Flags ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . image Ġ= Ġdata . getData (). toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry Image . setImage URI ( data . getData ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry Image . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOC ATION _ REQUEST Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( data Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlocation Ġ= Ġdata . extras ?. get Parcelable < Location >(" location ") !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAdd Ġthe Ġcancel Ġoptions Ġmenu Ġfor Ġthe Ġactivity ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun ĠonCreate Options Menu ( menu : ĠMenu ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġmenu Inflater . inflate ( R . menu . menu _ entry _ add , Ġmenu ) ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . onCreate Options Menu ( menu ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReturn Ġto Ġprevious Ġactivity Ġif Ġactivity Ġis ĊĠĠĠĠ Ġ* Ġcancelled ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġon Options ItemSelected ( item : ĠMenuItem ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( item . itemId ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠR . id . entry _ cancel Ġ-> Ġ{ Ġfinish () Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . on Options ItemSelected ( item ) ĊĠĠĠ Ġ} Ċ } Ċ