Skip to content

Commit 5ba94e3

Browse files
authored
Write out aligned postings according to a user preference (#218)
Fixes #15.
1 parent 4999803 commit 5ba94e3

File tree

6 files changed

+60
-3
lines changed

6 files changed

+60
-3
lines changed

app/src/main/java/be/chvp/nanoledger/data/PreferencesDataSource.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const val FILE_URI_KEY = "file_uri"
1111
const val DEFAULT_CURRENCY_KEY = "default_currency"
1212
const val DEFAULT_STATUS_KEY = "default_status"
1313
const val CURRENCY_BEFORE_AMOUNT_KEY = "currency_before_amount"
14+
const val POSTING_WIDTH_KEY = "posting_width"
1415

1516
class PreferencesDataSource
1617
@Inject
@@ -80,4 +81,10 @@ class PreferencesDataSource
8081
CURRENCY_BEFORE_AMOUNT_KEY,
8182
currencyBeforeAmount,
8283
).apply()
84+
85+
val postingWidth: LiveData<Int> = sharedPreferences.intLiveData(POSTING_WIDTH_KEY, 72).map { it!! }
86+
87+
fun getPostingWidth(): Int = sharedPreferences.getInt(POSTING_WIDTH_KEY, 72)!!
88+
89+
fun setPostingWidth(width: Int) = sharedPreferences.edit().putInt(POSTING_WIDTH_KEY, width).apply()
8390
}

app/src/main/java/be/chvp/nanoledger/data/Util.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,23 @@ fun SharedPreferences.booleanLiveData(
7171
): SharedPreferenceLiveData<Boolean> {
7272
return SharedPreferenceBooleanLiveData(this, key, default)
7373
}
74+
75+
class SharedPreferenceIntLiveData(
76+
sharedPrefs: SharedPreferences,
77+
key: String,
78+
private val default: Int,
79+
) :
80+
SharedPreferenceLiveData<Int>(sharedPrefs, key) {
81+
init {
82+
value = this.getValueFromPreferences(key)
83+
}
84+
85+
override fun getValueFromPreferences(key: String): Int = if (sharedPrefs.contains(key)) sharedPrefs.getInt(key, default) else default
86+
}
87+
88+
fun SharedPreferences.intLiveData(
89+
key: String,
90+
default: Int = 0,
91+
): SharedPreferenceLiveData<Int> {
92+
return SharedPreferenceIntLiveData(this, key, default)
93+
}

app/src/main/java/be/chvp/nanoledger/ui/common/TransactionFormViewModel.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,22 @@ abstract class TransactionFormViewModel
134134
transaction.append(" | ${note.value}")
135135
}
136136
transaction.append('\n')
137-
// Drop last element, it should always be an empty posting
137+
// Drop last element, it should always be an empty posting (and the only empty posting)
138138
for (posting in postings.value!!.dropLast(1)) {
139+
val usedLength = 7 + posting.first.length + posting.second.length + posting.third.length
140+
val numberOfSpaces = preferencesDataSource.getPostingWidth() - usedLength
141+
val spaces = " ".repeat(maxOf(0, numberOfSpaces))
139142
if (posting.third == "") {
140143
transaction.append(
141144
" ${posting.first}\n",
142145
)
143146
} else if (preferencesDataSource.getCurrencyBeforeAmount()) {
144147
transaction.append(
145-
" ${posting.first} ${posting.second} ${posting.third}\n",
148+
" ${posting.first} ${spaces}${posting.second} ${posting.third}\n",
146149
)
147150
} else {
148151
transaction.append(
149-
" ${posting.first} ${posting.third} ${posting.second}\n",
152+
" ${posting.first} ${spaces}${posting.third} ${posting.second}\n",
150153
)
151154
}
152155
}

app/src/main/java/be/chvp/nanoledger/ui/preferences/PreferencesActivity.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.Column
1414
import androidx.compose.foundation.layout.fillMaxWidth
1515
import androidx.compose.foundation.layout.padding
1616
import androidx.compose.foundation.rememberScrollState
17+
import androidx.compose.foundation.text.KeyboardOptions
1718
import androidx.compose.foundation.verticalScroll
1819
import androidx.compose.material.icons.Icons
1920
import androidx.compose.material.icons.automirrored.filled.ArrowBack
@@ -43,6 +44,7 @@ import androidx.compose.ui.Modifier
4344
import androidx.compose.ui.platform.LocalContext
4445
import androidx.compose.ui.res.stringResource
4546
import androidx.compose.ui.text.font.FontWeight
47+
import androidx.compose.ui.text.input.KeyboardType
4648
import androidx.compose.ui.unit.dp
4749
import be.chvp.nanoledger.R
4850
import be.chvp.nanoledger.ui.theme.NanoLedgerTheme
@@ -112,6 +114,26 @@ class PreferencesActivity() : ComponentActivity() {
112114
OutlinedTextField(newDefaultCurrency, { newDefaultCurrency = it })
113115
}
114116
HorizontalDivider()
117+
val postingWidth by preferencesViewModel.postingWidth.observeAsState()
118+
var newPostingWidth by remember { mutableStateOf("${postingWidth ?: 72}") }
119+
var postingWidthOpen by remember { mutableStateOf(false) }
120+
Setting(stringResource(R.string.posting_width), "${postingWidth ?: 72}") {
121+
postingWidthOpen = true
122+
}
123+
SettingDialog(postingWidthOpen, stringResource(R.string.change_posting_width), true, {
124+
preferencesViewModel.storePostingWidth(Integer.parseInt(newPostingWidth))
125+
}, { postingWidthOpen = false }) {
126+
OutlinedTextField(
127+
newPostingWidth,
128+
{
129+
if (it.isEmpty() || it.matches(Regex("^\\d+$"))) {
130+
newPostingWidth = it
131+
}
132+
},
133+
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
134+
)
135+
}
136+
HorizontalDivider()
115137
val defaultStatus by preferencesViewModel.defaultStatus.observeAsState()
116138
var expandedStatus by rememberSaveable { mutableStateOf(false) }
117139
ExposedDropdownMenuBox(

app/src/main/java/be/chvp/nanoledger/ui/preferences/PreferencesViewModel.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class PreferencesViewModel
1919
val defaultCurrency: LiveData<String> = preferencesDataSource.defaultCurrency
2020
val defaultStatus: LiveData<String> = preferencesDataSource.defaultStatus
2121
val currencyBeforeAmount: LiveData<Boolean> = preferencesDataSource.currencyBeforeAmount
22+
val postingWidth: LiveData<Int> = preferencesDataSource.postingWidth
2223

2324
fun storeFileUri(uri: Uri) = preferencesDataSource.setFileUri(uri)
2425

@@ -30,4 +31,6 @@ class PreferencesViewModel
3031
preferencesDataSource.setCurrencyBeforeAmount(
3132
enable,
3233
)
34+
35+
fun storePostingWidth(width: Int) = preferencesDataSource.setPostingWidth(width)
3336
}

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<string name="back">Back</string>
77
<string name="cancel">Cancel</string>
88
<string name="change_default_currency">Change default currency</string>
9+
<string name="change_posting_width">Change posting width</string>
910
<string name="copy">Copy</string>
1011
<string name="copy_and_edit">Copy and edit</string>
1112
<string name="currency_amount_order">Order of currency and amount</string>
@@ -27,6 +28,7 @@
2728
<string name="note">Note</string>
2829
<string name="ok">OK</string>
2930
<string name="payee">Payee</string>
31+
<string name="posting_width">Width of postings written to file</string>
3032
<string name="save">Save</string>
3133
<string name="select_file">Select file…</string>
3234
<string name="settings">Settings</string>

0 commit comments

Comments
 (0)