83 Commits
Author SHA1 Message Date
sora 2ee7c14e77 Fix stats render and add 'disabled-member' setting 2026-09-06 18:59:08 +02:00
sora 8d28ee2d6c Cleanup & Pruning legacy code 2026-09-06 17:13:23 +02:00
sora aee1bd582b Reset low quality translations 2026-09-06 13:30:19 +02:00
sora 8d398db1cb Refactor, translation and fixes 2026-09-06 13:26:24 +02:00
sora 9da65e0725 Refactor Sync 2026-09-06 04:19:07 +02:00
sora 38128d12a0 Fix small sync 2026-09-06 03:53:02 +02:00
sora 2d7f1b9c2d Preview Test 2026-09-06 03:08:12 +02:00
sora 34ed687234 Bill Sync 2026-09-06 03:05:29 +02:00
sora 8564f64576 Project Cleanup/Refactor 2026-09-06 02:56:32 +02:00
sora c6be8eda6b Manage Currencies 2026-09-06 02:56:02 +02:00
sora 7904aabbc3 Accessibility 2026-09-06 02:55:11 +02:00
sora e59680e710 Prefill setting 2026-09-03 22:00:27 +02:00
sora fff3490719 Default color to system 2026-09-03 22:00:27 +02:00
sora aedefc9010 Partial Sync 2026-09-03 22:00:27 +02:00
sora 492230faa2 Fix currency and added user weighting 2026-09-03 22:00:26 +02:00
sora 488aa9bba6 Update .github/workflows/build.yml 2026-09-03 13:59:32 +02:00
sora f321eee4f5 Update .github/workflows/build.yml 2026-09-03 12:58:15 +02:00
sora 78da09a312 Merge pull request 'Update dependency com.github.nextcloud:Android-SingleSignOn to v1.3.4' (#2) from renovate/com.github.nextcloud-android-singlesignon-1.x into main
Reviewed-on: #2
2026-09-03 12:14:04 +02:00
sora 1c6b246ea0 Merge pull request 'Update actions/checkout action to v7' (#4) from renovate/actions-checkout-7.x into main
Reviewed-on: #4
2026-09-03 12:13:51 +02:00
sora f78dc42f44 Merge pull request 'Update actions/setup-java action to v6' (#12) from renovate/actions-setup-java-6.x into main
Reviewed-on: #12
2026-09-03 12:13:37 +02:00
sora 7e7d7face2 Merge branch 'main' into renovate/actions-setup-java-6.x 2026-09-03 12:13:27 +02:00
sora 7ae20373da Merge pull request 'Update actions/upload-artifact action to v7' (#13) from renovate/actions-upload-artifact-7.x into main
Reviewed-on: #13
2026-09-03 12:08:09 +02:00
sora 67359d98e0 Merge branch 'main' into renovate/actions-upload-artifact-7.x 2026-09-03 12:02:26 +02:00
sora e91fd05bac Update .github/workflows/build.yml 2026-09-03 11:58:19 +02:00
Renovate Bot 48fa785681 Update actions/upload-artifact action to v7 2026-09-03 02:01:49 +00:00
Renovate Bot 16410b7a7a Update actions/setup-java action to v6 2026-09-03 02:01:47 +00:00
Renovate Bot 367a13a84b Update actions/checkout action to v7 2026-09-03 02:01:45 +00:00
Renovate Bot 0d98576b6b Update dependency com.github.nextcloud:Android-SingleSignOn to v1.3.4 2026-09-03 02:01:40 +00:00
sora 54481c8dc2 Merge remote-tracking branch 'gh/pr/12' 2026-09-03 01:49:39 +02:00
sora 0179fdbee7 Merge remote-tracking branch 'gh/pr/8' 2026-09-03 01:49:24 +02:00
sora 375830a9bd Minor tweaks 2026-09-03 01:43:00 +02:00
sora 373a56a68a Unit Test and Build Artifact 2026-09-03 00:49:11 +02:00
sora c487ca644e Importer Fix 2026-09-03 00:01:08 +02:00
sora 72867a9b5e Focus Flow 2026-09-02 23:58:03 +02:00
sora f84d44770d Add empty box at bottom of bill list 2026-09-02 23:28:00 +02:00
sora bd6ab50859 Focus amount and default payer 2026-09-02 23:22:54 +02:00
sora b9e995f30d Archiving Sync 2026-09-02 23:12:08 +02:00
gtcrowdandGitHub 95bdc28336 Update strings.xml with spanish strings 2026-09-02 10:20:40 +00:00
sora 72ba99f4b6 Formula Input & rounding & more 2026-09-02 00:43:39 +02:00
sora 42f67dfbe4 Percent Split 2026-09-02 00:17:42 +02:00
sora 54ddf69afb Gradle Update 2026-09-01 23:47:55 +02:00
Florian Völker 90b5c7a6e9 Fix german translation for labels vs category 2026-08-04 00:01:41 +02:00
Florian Völker 805a8d0bc4 Fix german translation. Use informal style wording 2026-08-03 22:59:45 +02:00
choelzlandGitHub 10bf854a50 New Crowdin updates (#6)
* New translations strings.xml (Romanian)

[ci skip]

* New translations strings.xml (French)

[ci skip]

* New translations strings.xml (Spanish)

[ci skip]

* New translations strings.xml (Afrikaans)

[ci skip]

* New translations strings.xml (Arabic)

[ci skip]

* New translations strings.xml (Catalan)

[ci skip]

* New translations strings.xml (Czech)

[ci skip]

* New translations strings.xml (Danish)

[ci skip]

* New translations strings.xml (German)

[ci skip]

* New translations strings.xml (Greek)

[ci skip]

* New translations strings.xml (Finnish)

[ci skip]

* New translations strings.xml (Hebrew)

[ci skip]

* New translations strings.xml (Hungarian)

[ci skip]

* New translations strings.xml (Italian)

[ci skip]

* New translations strings.xml (Japanese)

[ci skip]

* New translations strings.xml (Korean)

[ci skip]

* New translations strings.xml (Dutch)

[ci skip]

* New translations strings.xml (Norwegian)

[ci skip]

* New translations strings.xml (Polish)

[ci skip]

* New translations strings.xml (Portuguese)

[ci skip]

* New translations strings.xml (Russian)

[ci skip]

* New translations strings.xml (Serbian (Cyrillic))

[ci skip]

* New translations strings.xml (Swedish)

[ci skip]

* New translations strings.xml (Turkish)

[ci skip]

* New translations strings.xml (Ukrainian)

[ci skip]

* New translations strings.xml (Chinese Simplified)

[ci skip]

* New translations strings.xml (Chinese Traditional)

[ci skip]

* New translations strings.xml (English)

[ci skip]

* New translations strings.xml (Vietnamese)

[ci skip]

* New translations strings.xml (Portuguese, Brazilian)

[ci skip]

* New translations strings.xml (Romanian)

[ci skip]

* New translations strings.xml (French)

[ci skip]

* New translations strings.xml (Spanish)

[ci skip]

* New translations strings.xml (Arabic)

[ci skip]

* New translations strings.xml (Czech)

[ci skip]

* New translations strings.xml (Danish)

[ci skip]

* New translations strings.xml (German)

[ci skip]

* New translations strings.xml (Greek)

[ci skip]

* New translations strings.xml (Finnish)

[ci skip]

* New translations strings.xml (Italian)

[ci skip]

* New translations strings.xml (Japanese)

[ci skip]

* New translations strings.xml (Dutch)

[ci skip]

* New translations strings.xml (Norwegian)

[ci skip]

* New translations strings.xml (Polish)

[ci skip]

* New translations strings.xml (Portuguese)

[ci skip]

* New translations strings.xml (Russian)

[ci skip]

* New translations strings.xml (Swedish)

[ci skip]

* New translations strings.xml (Ukrainian)

[ci skip]

* New translations strings.xml (Chinese Simplified)

[ci skip]

* New translations strings.xml (Portuguese, Brazilian)

[ci skip]
2026-08-03 20:20:30 +02:00
choelzl e7a72bef48 Update Crowdin configuration file
[ci skip]
2026-08-03 20:02:44 +02:00
sora e45065e3b8 Fix project creation nextcloud 2026-08-03 19:51:26 +02:00
sora db3e27a215 Allow comma in title 2026-08-03 19:51:26 +02:00
sora ad0928b719 Merge pull request 'Configure Renovate' (#1) from renovate/configure into main
Reviewed-on: #1
2026-07-12 14:47:56 +02:00
sora 0c700232c9 Merge branch 'main' into renovate/configure 2026-07-12 14:47:47 +02:00
sora 7237aedb02 Fix sync and add beta features 2026-07-09 19:22:04 +02:00
sora 4a10025c4f Label sync and workflows 2026-07-05 15:02:36 +02:00
sora a3709d2f04 Update metadata/en-US/full_description.txt 2026-07-02 03:05:16 +02:00
sora db6c681ac1 Fix toast & minor category/paymentmode fix 2026-07-02 02:43:33 +02:00
sora 480a7ccdc7 Better category/paymentmode storage and handling 2026-07-02 02:37:40 +02:00
sora d7d1e09bc8 Update app/src/main/java/net/helcel/cowspent/model/DBPaymentMode.kt 2026-07-02 02:06:55 +02:00
sora 5e43d7767f Update app/src/main/java/net/helcel/cowspent/model/DBCategory.kt 2026-07-02 02:06:41 +02:00
sora abff06ff7c Update app/src/main/java/net/helcel/cowspent/persistence/CowspentSQLiteOpenHelper.kt 2026-07-02 02:06:08 +02:00
sora 986b1a537e Disable custom Label until fully implemented 2026-07-02 02:01:36 +02:00
sora 0b20abde38 Stripping fix 2026-07-01 22:12:42 +02:00
sora ed8b99985f Custom Labels, User archive, Versioning, String and UI cleanup 2026-07-01 22:10:08 +02:00
sora 11c72a0e51 Archiving and Label options 2026-06-30 20:40:32 +02:00
sora 46fd446b35 Fix monochrome logo 2026-06-30 19:31:39 +02:00
sora a0e61648c3 Migrate to SecureStorage 2026-06-30 19:24:25 +02:00
sora e8c4a5624f Migrate to encryptedPref 2026-06-30 18:59:50 +02:00
sora a98fe57734 Hide inactive members in drawer 2026-06-30 07:41:34 +02:00
sora 9d258d4579 String cleanup 2026-06-30 07:37:52 +02:00
sora 9233156ee1 More cleanup 2026-06-30 07:33:49 +02:00
sora a9486e4c23 Cleanup imports and co 2026-06-30 07:30:57 +02:00
sora c3ad7cdb4e Fix Monochrome 2026-06-30 07:26:33 +02:00
sora 91e39388ab Disable dependency tree, logo to png 2026-06-30 07:17:57 +02:00
sora c1e1e6c5d3 Better formating and placeholder 2026-06-29 21:38:01 +02:00
sora 080db964f2 Fix keyboard padding and better currency management 2026-06-29 21:31:59 +02:00
sora edf8303027 Currency parsing and formating
# Conflicts:
#	app/src/main/java/net/helcel/cowspent/android/main/BillsListComponents.kt
2026-06-29 21:30:35 +02:00
sora fb4bc50db4 Fixes for currency, logo, render and more 2026-06-27 12:18:33 +02:00
sora 80a098351d project creation and currency db 2026-06-14 21:34:58 +02:00
sora a7a69deb42 better currency handling 2026-06-14 21:33:08 +02:00
sora 4a47b0006b Update README.md 2026-06-09 19:19:24 +02:00
sora 6c19867df9 Upload files to ".github/images" 2026-06-09 19:18:02 +02:00
sora 90ef58aa81 Update app/build.gradle 2026-06-09 08:51:43 +02:00
sora ef5f5fceba fix ui 2026-06-09 01:51:42 +02:00
Renovate Bot 7f04a41d32 Add renovate.json 2026-05-30 02:02:13 +00:00
sora 747b74be77 Update README.md 2026-05-30 00:00:04 +02:00
sora 62a98c9184 init 2026-05-29 23:19:55 +02:00
81 changed files with 6833 additions and 5486 deletions
+19 -3
View File
@@ -23,7 +23,7 @@ jobs:
contents: write contents: write
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v7
with: with:
fetch-depth: 0 fetch-depth: 0
@@ -41,7 +41,7 @@ jobs:
run: git checkout -B "$BRANCH" run: git checkout -B "$BRANCH"
- name: set up JDK - name: set up JDK
uses: actions/setup-java@v5 uses: actions/setup-java@v6
with: with:
java-version: 21 java-version: 21
distribution: "temurin" distribution: "temurin"
@@ -49,12 +49,28 @@ jobs:
- name: Setup Gradle - name: Setup Gradle
uses: gradle/actions/setup-gradle@v6 uses: gradle/actions/setup-gradle@v6
- name: Run unit tests
run: ./gradlew testDebugUnitTest
- name: Build APK - name: Build APK
run: | run: |
VERSION_CODE=$(git rev-list --count HEAD) VERSION_CODE=$(git rev-list --count HEAD)
VERSION_NAME=$(git describe --tags --always) VERSION_BASE=$(git describe --tags --abbrev=0 | sed 's/^v//')
VERSION_DEV=$(git rev-list --count $(git describe --tags --abbrev=0)..HEAD)
if [ $VERSION_DEV -gt 0 ]; then
VERSION_NAME="${VERSION_BASE}.${VERSION_DEV}"
else
VERSION_NAME="${VERSION_BASE}"
fi
./gradlew assembleSignedRelease -PVERSION_CODE=$VERSION_CODE -PVERSION_NAME=$VERSION_NAME ./gradlew assembleSignedRelease -PVERSION_CODE=$VERSION_CODE -PVERSION_NAME=$VERSION_NAME
- name: Upload APK
uses: actions/upload-artifact@v7
with:
path: app/build/outputs/apk/signedRelease/app-signedRelease.apk
compression-level: 0
archive: false
- name: Release - name: Release
uses: softprops/action-gh-release@v3 uses: softprops/action-gh-release@v3
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
+66 -11
View File
@@ -1,7 +1,8 @@
plugins { plugins {
id 'com.android.application' version '9.4.0' id 'com.android.application' version '9.3.2'
id 'org.jetbrains.kotlin.plugin.serialization' version '2.4.0' id 'org.jetbrains.kotlin.plugin.serialization' version '2.4.10'
id 'org.jetbrains.kotlin.plugin.compose' version '2.4.0' id 'org.jetbrains.kotlin.plugin.compose' version '2.4.10'
id 'jacoco'
} }
android { android {
@@ -16,6 +17,8 @@ android {
targetSdk = 37 targetSdk = 37
versionName project.hasProperty('VERSION_NAME') ? project.property('VERSION_NAME') : "1.4" versionName project.hasProperty('VERSION_NAME') ? project.property('VERSION_NAME') : "1.4"
versionCode project.hasProperty('VERSION_CODE') ? project.property('VERSION_CODE').toInteger() : 1 versionCode project.hasProperty('VERSION_CODE') ? project.property('VERSION_CODE').toInteger() : 1
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
signingConfigs { signingConfigs {
@@ -40,6 +43,7 @@ android {
debuggable true debuggable true
initWith(buildTypes.release) initWith(buildTypes.release)
signingConfig = signingConfigs.debug signingConfig = signingConfigs.debug
enableUnitTestCoverage true
} }
release { release {
minifyEnabled true minifyEnabled true
@@ -69,6 +73,24 @@ android {
compose = true compose = true
} }
testOptions {
unitTests {
includeAndroidResources = true
all {
maxParallelForks = 2
forkEvery = 50
maxHeapSize = "1024m"
// Robolectric loads classes through its own sandbox classloader, which leaves them
// without a code-source location. Without this JaCoCo skips them entirely and the
// report only sees the handful of plain JVM classes.
jacoco {
includeNoLocationClasses = true
excludes = ["jdk.internal.*"]
}
}
}
}
kotlin { kotlin {
jvmToolchain(21) jvmToolchain(21)
} }
@@ -96,21 +118,21 @@ android {
} }
dependencies { dependencies {
implementation 'androidx.compose.foundation:foundation:1.11.4' implementation 'androidx.compose.foundation:foundation:1.12.0'
implementation 'androidx.compose.runtime:runtime:1.11.4' implementation 'androidx.compose.runtime:runtime:1.12.0'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'androidx.work:work-runtime-ktx:2.11.2' implementation 'androidx.work:work-runtime-ktx:2.11.2'
implementation 'com.google.zxing:core:3.5.4' implementation 'com.google.zxing:core:3.5.4'
implementation 'androidx.camera:camera-camera2:1.6.1' implementation 'androidx.camera:camera-camera2:1.6.2'
implementation 'androidx.camera:camera-lifecycle:1.6.1' implementation 'androidx.camera:camera-lifecycle:1.6.2'
implementation 'androidx.camera:camera-view:1.6.1' implementation 'androidx.camera:camera-view:1.6.2'
implementation 'com.github.nextcloud:Android-SingleSignOn:1.1.0' implementation 'com.github.nextcloud:Android-SingleSignOn:1.3.4'
implementation 'com.opencsv:opencsv:5.12.0' implementation 'com.opencsv:opencsv:5.12.0'
implementation platform('androidx.compose:compose-bom:2026.06.01') implementation platform('androidx.compose:compose-bom:2026.08.00')
implementation 'androidx.compose.ui:ui' implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.material:material' implementation 'androidx.compose.material:material'
implementation 'androidx.compose.material:material-icons-extended' implementation 'androidx.compose.material:material-icons-extended'
@@ -121,5 +143,38 @@ dependencies {
implementation 'androidx.security:security-crypto:1.1.0' implementation 'androidx.security:security-crypto:1.1.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.11.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.11.0'
implementation "androidx.datastore:datastore-preferences:1.2.1" implementation "androidx.datastore:datastore-preferences:1.2.1"
implementation "com.google.crypto.tink:tink-android:1.22.0" implementation "com.google.crypto.tink:tink-android:1.23.0"
testImplementation 'junit:junit:4.13.2'
testImplementation 'io.mockk:mockk:1.14.11'
testImplementation 'org.robolectric:robolectric:4.16.1'
testImplementation 'androidx.test:core:1.7.0'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.11.0'
testImplementation 'androidx.compose.ui:ui-test-junit4'
androidTestImplementation platform('androidx.compose:compose-bom:2026.08.00')
androidTestImplementation 'androidx.test.ext:junit:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.7.0'
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
androidTestImplementation 'io.mockk:mockk-android:1.14.11'
debugImplementation 'androidx.compose.ui:ui-test-manifest'
}
tasks.register('jacocoTestReport', JacocoReport) {
dependsOn 'testDebugUnitTest'
reports {
xml.required = true
html.required = true
}
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*']
def debugTree = fileTree(dir: "${project.layout.buildDirectory.asFile.get()}/intermediates/built_in_kotlinc/debug/compileDebugKotlin/classes", excludes: fileFilter)
def mainSrc = "${project.projectDir}/src/main/java"
sourceDirectories.from = files([mainSrc])
classDirectories.from = files([debugTree])
executionData.from = fileTree(dir: project.layout.buildDirectory.asFile.get(), includes: [
'jacoco/testDebugUnitTest.exec', 'outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec'
])
} }
@@ -48,7 +48,7 @@ fun AboutScreen(
title = { Text(stringResource(R.string.title_about)) }, title = { Text(stringResource(R.string.title_about)) },
navigationIcon = { navigationIcon = {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
} }
}, },
backgroundColor = MaterialTheme.colors.primary, backgroundColor = MaterialTheme.colors.primary,
@@ -48,7 +48,7 @@ import java.util.Locale
class AccountActivity : AppCompatActivity() { class AccountActivity : AppCompatActivity() {
private val viewModel: AccountViewModel by viewModels() internal val viewModel: AccountViewModel by viewModels()
companion object { companion object {
private val TAG = AccountActivity::class.java.simpleName private val TAG = AccountActivity::class.java.simpleName
@@ -12,6 +12,7 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@@ -33,7 +34,7 @@ import java.util.Calendar
class EditBillActivity : AppCompatActivity() { class EditBillActivity : AppCompatActivity() {
private val viewModel: EditBillViewModel by viewModels() internal val viewModel: EditBillViewModel by viewModels()
private lateinit var db: CowspentSQLiteOpenHelper private lateinit var db: CowspentSQLiteOpenHelper
private lateinit var bill: DBBill private lateinit var bill: DBBill
private var projectType: ProjectType = ProjectType.LOCAL private var projectType: ProjectType = ProjectType.LOCAL
@@ -151,11 +152,25 @@ class EditBillActivity : AppCompatActivity() {
val billIdToDuplicate = intent.getLongExtra(PARAM_BILL_ID_TO_DUPLICATE, 0) val billIdToDuplicate = intent.getLongExtra(PARAM_BILL_ID_TO_DUPLICATE, 0)
val timeNowSeconds = System.currentTimeMillis() / 1000 val timeNowSeconds = System.currentTimeMillis() / 1000
if (billIdToDuplicate == 0L) { if (billIdToDuplicate == 0L) {
bill = DBBill( val preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
0, 0, projectId, 0, 0.0, timeNowSeconds, val fillFromLast = preferences.getBoolean(getString(R.string.pref_key_fill_new_bill_from_last), false)
"", DBBill.STATE_ADDED, DBBill.NON_REPEATED, val lastBill = if (fillFromLast) db.getLastBillOfProject(projectId) else null
DBBill.PAYMODE_NONE, DBBill.CATEGORY_NONE, "", DBBill.PAYMODE_ID_NONE
) if (lastBill != null) {
bill = DBBill(
0, 0, projectId, lastBill.payerId, 0.0, timeNowSeconds,
"", DBBill.STATE_ADDED, lastBill.repeat ?: DBBill.NON_REPEATED,
lastBill.paymentMode, lastBill.categoryId, "", lastBill.paymentModeId
)
bill.billOwers = lastBill.billOwers.map { DBBillOwer(0, 0, it.memberId) }
} else {
val project = db.getProject(projectId)
bill = DBBill(
0, 0, projectId, project?.lastPayerId ?: 0, 0.0, timeNowSeconds,
"", DBBill.STATE_ADDED, DBBill.NON_REPEATED,
DBBill.PAYMODE_NONE, DBBill.CATEGORY_NONE, "", DBBill.PAYMODE_ID_NONE
)
}
} else { } else {
val btd = db.getBill(billIdToDuplicate)!! val btd = db.getBill(billIdToDuplicate)!!
bill = DBBill( bill = DBBill(
@@ -316,7 +331,7 @@ class EditBillActivity : AppCompatActivity() {
bill.amount == viewModel.getFinalAmount() && bill.amount == viewModel.getFinalAmount() &&
bill.payerId == viewModel.payerId && bill.payerId == viewModel.payerId &&
bill.comment == viewModel.getFinalComment() && bill.comment == viewModel.getFinalComment() &&
bill.repeat == viewModel.repeat && (bill.repeat ?: DBBill.NON_REPEATED) == viewModel.repeat &&
bill.categoryId == viewModel.categoryId && bill.categoryId == viewModel.categoryId &&
bill.paymentModeId == viewModel.paymentModeId && bill.paymentModeId == viewModel.paymentModeId &&
!owersChanged) !owersChanged)
@@ -324,15 +339,25 @@ class EditBillActivity : AppCompatActivity() {
private suspend fun saveBill(): Long = withContext(Dispatchers.IO) { private suspend fun saveBill(): Long = withContext(Dispatchers.IO) {
val groupedBillIds = intent.getLongArrayExtra(PARAM_GROUPED_BILL_IDS) val groupedBillIds = intent.getLongArrayExtra(PARAM_GROUPED_BILL_IDS)
val isCustomSplit = viewModel.isCustomSplit val splitMode = viewModel.splitMode
if (isCustomSplit) { if (splitMode != SplitMode.EVEN) {
val splits: Map<Long, Double> = viewModel.owersCustomSplit.filter { (id, amountStr) -> val splits: Map<Long, Double> = if (splitMode == SplitMode.CUSTOM) {
viewModel.owersSelection[id] == true && (amountStr.replace(',', '.').toDoubleOrNull() viewModel.owersCustomSplit.filter { (id, amountStr) ->
?: 0.0) > 0 viewModel.owersSelection[id] == true && viewModel.parseAmountFromUi(amountStr) > 0
}.mapValues { }.mapValues {
val uiAmount = it.value.replace(',', '.').toDoubleOrNull() ?: 0.0 val uiAmount = viewModel.parseAmountFromUi(it.value)
SupportUtil.round2(uiAmount / viewModel.selectedCurrencyRate) SupportUtil.round2(uiAmount * viewModel.selectedCurrencyRate)
}
} else { // PERCENT
val totalAmount = viewModel.amountAsDouble
viewModel.owersPercentSplit.filter { (id, percentStr) ->
viewModel.owersSelection[id] == true && viewModel.parseAmountFromUi(percentStr) > 0
}.mapValues {
val percent = viewModel.parseAmountFromUi(it.value)
val uiAmount = SupportUtil.round2(totalAmount * percent / 100.0)
SupportUtil.round2(uiAmount * viewModel.selectedCurrencyRate)
}
} }
if (splits.isEmpty()) return@withContext 0L if (splits.isEmpty()) return@withContext 0L
@@ -405,16 +430,8 @@ class EditBillActivity : AppCompatActivity() {
val proj = db.getProject(bill.projectId) val proj = db.getProject(bill.projectId)
if (proj != null) db.syncIfRemote(proj) if (proj != null) db.syncIfRemote(proj)
db.updateProject( db.updateProject(
bill.projectId, projId = bill.projectId,
null, newLastPayerId = viewModel.payerId
null,
null,
viewModel.payerId,
null,
null,
null,
null,
null
) )
return@withContext firstSavedId return@withContext firstSavedId
@@ -458,16 +475,8 @@ class EditBillActivity : AppCompatActivity() {
newOwersIds.forEach { newBill.billOwers += DBBillOwer(0, 0, it) } newOwersIds.forEach { newBill.billOwers += DBBillOwer(0, 0, it) }
val newBillId = db.addBill(newBill) val newBillId = db.addBill(newBill)
db.updateProject( db.updateProject(
bill.projectId, projId = bill.projectId,
null, newLastPayerId = viewModel.payerId
null,
null,
viewModel.payerId,
null,
null,
null,
null,
null
) )
val proj = db.getProject(bill.projectId) val proj = db.getProject(bill.projectId)
if (proj != null) db.syncIfRemote(proj) if (proj != null) db.syncIfRemote(proj)
@@ -1,11 +1,13 @@
package net.helcel.cowspent.android.bill_edit package net.helcel.cowspent.android.bill_edit
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.* import androidx.compose.material.*
@@ -16,12 +18,18 @@ import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale import androidx.compose.ui.draw.scale
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@@ -53,6 +61,13 @@ fun EditBillScreen(
) { ) {
val canEdit = accessLevel == DBProject.ACCESS_LEVEL_UNKNOWN || accessLevel >= DBProject.ACCESS_LEVEL_PARTICIPANT val canEdit = accessLevel == DBProject.ACCESS_LEVEL_UNKNOWN || accessLevel >= DBProject.ACCESS_LEVEL_PARTICIPANT
val context = LocalContext.current val context = LocalContext.current
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
if (viewModel.isNewBill) {
focusRequester.requestFocus()
}
}
StatefulAlertDialog( StatefulAlertDialog(
state = viewModel.dialogState, state = viewModel.dialogState,
@@ -128,7 +143,8 @@ fun EditBillScreen(
viewModel = viewModel, viewModel = viewModel,
canEdit = canEdit, canEdit = canEdit,
onDateClick = onDateClick, onDateClick = onDateClick,
onTimeClick = onTimeClick onTimeClick = onTimeClick,
amountFocusRequester = focusRequester
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@@ -164,7 +180,8 @@ fun BillBasicInfoSection(
viewModel: EditBillViewModel, viewModel: EditBillViewModel,
canEdit: Boolean, canEdit: Boolean,
onDateClick: () -> Unit, onDateClick: () -> Unit,
onTimeClick: () -> Unit onTimeClick: () -> Unit,
amountFocusRequester: FocusRequester
) { ) {
Text( Text(
text = "GENERAL", text = "GENERAL",
@@ -175,29 +192,20 @@ fun BillBasicInfoSection(
) )
val context = LocalContext.current val context = LocalContext.current
val focusManager = LocalFocusManager.current
val currencyDialogTitle = val currencyDialogTitle =
stringResource(R.string.currency_dialog_title, viewModel.mainCurrencyName) stringResource(R.string.currency_dialog_title, viewModel.mainCurrencyName)
OutlinedTextField(
value = viewModel.what,
onValueChange = { viewModel.what = it },
enabled = canEdit,
placeholder = { Text(stringResource(R.string.label_what)) },
modifier = Modifier.fillMaxWidth(),
leadingIcon = { Icon(Icons.Default.Title, contentDescription = null) }
)
Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField( OutlinedTextField(
value = viewModel.amount, value = viewModel.amount,
onValueChange = { onValueChange = { nv->
viewModel.amount = it val filteredValue = nv.filter { it in "0123456789.+-*/" }
viewModel.amount = filteredValue
viewModel.updateSplits() viewModel.updateSplits()
}, },
enabled = canEdit, enabled = canEdit,
placeholder = { Text("0") }, placeholder = { Text("0") },
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth().focusRequester(amountFocusRequester),
leadingIcon = { leadingIcon = {
val currencyToShow = viewModel.selectedCurrencyName.ifEmpty { val currencyToShow = viewModel.selectedCurrencyName.ifEmpty {
viewModel.mainCurrencyName.ifEmpty { "$" } viewModel.mainCurrencyName.ifEmpty { "$" }
@@ -231,7 +239,21 @@ fun BillBasicInfoSection(
Icon(Icons.Default.SwapHoriz, contentDescription = "Change Currency") Icon(Icons.Default.SwapHoriz, contentDescription = "Change Currency")
} }
}, },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone, imeAction = ImeAction.Next),
keyboardActions = KeyboardActions(onNext = { focusManager.moveFocus(FocusDirection.Next) })
)
Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField(
value = viewModel.what,
onValueChange = { viewModel.what = it },
enabled = canEdit,
placeholder = { Text(stringResource(R.string.label_what)) },
modifier = Modifier.fillMaxWidth(),
leadingIcon = { Icon(Icons.Default.Title, contentDescription = null) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
keyboardActions = KeyboardActions(onNext = { focusManager.moveFocus(FocusDirection.Next) })
) )
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
@@ -357,34 +379,54 @@ fun OwerSelectionSection(
) )
Spacer(Modifier.weight(1f)) Spacer(Modifier.weight(1f))
if (viewModel.isCustomSplit) { if (viewModel.splitMode != SplitMode.EVEN) {
val diff = viewModel.getDiffSplit() val diff = viewModel.getDiffSplit()
if (abs(diff) > 0.01) { if (abs(diff) > 0.01) {
val unit = if (viewModel.splitMode == SplitMode.PERCENT) "%" else ""
val diffText = val diffText =
if (diff > 0) "Missing: ${SupportUtil.normalNumberFormat.format(diff)}" else "Excess: ${ if (diff > 0) "Missing: ${SupportUtil.normalNumberFormat.format(diff)}$unit" else "Excess: ${
SupportUtil.normalNumberFormat.format(-diff) SupportUtil.normalNumberFormat.format(-diff)
}" }$unit"
Text( Text(
diffText, diffText,
color = MaterialTheme.colors.error, color = MaterialTheme.colors.error,
fontSize = 12.sp, fontSize = 12.sp,
modifier = Modifier.padding(horizontal = 16.dp) modifier = Modifier.padding(horizontal = 4.dp)
) )
} }
} else {
Text("Even Split", fontSize = 12.sp)
} }
Switch(
checked = !viewModel.isCustomSplit, val splitOptions = listOf(SplitMode.EVEN, SplitMode.CUSTOM, SplitMode.PERCENT)
enabled = canEdit, Row(
onCheckedChange = { modifier = Modifier
viewModel.isCustomSplit = !it .padding(start = 8.dp)
viewModel.updateSplits() .background(MaterialTheme.colors.onSurface.copy(alpha = 0.05f), MaterialTheme.shapes.small)
}, ) {
colors = SwitchDefaults.colors( splitOptions.forEach { mode ->
uncheckedThumbColor = MaterialTheme.colors.onSurface, val isSelected = viewModel.splitMode == mode
) Box(
) modifier = Modifier
.clip(MaterialTheme.shapes.small)
.background(if (isSelected) MaterialTheme.colors.primary else Color.Transparent)
.clickable(enabled = canEdit) {
viewModel.splitMode = mode
viewModel.updateSplits()
}
.padding(horizontal = 8.dp, vertical = 4.dp)
) {
Text(
text = when (mode) {
SplitMode.EVEN -> "="
SplitMode.CUSTOM -> "#"
SplitMode.PERCENT -> "%"
},
color = if (isSelected) MaterialTheme.colors.onPrimary else MaterialTheme.colors.onSurface,
fontSize = 14.sp,
fontWeight = FontWeight.Bold
)
}
}
}
} }
viewModel.members.forEach { member -> viewModel.members.forEach { member ->
@@ -408,23 +450,39 @@ fun OwerSelectionSection(
size = 32.dp size = 32.dp
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text(member.name, modifier = Modifier.weight(1f)) val weightSuffix = if (viewModel.hasDifferentWeights && member.weight != 1.0) {
" (x${member.weight.toString().removeSuffix(".0")})"
} else ""
Text("${member.name}$weightSuffix", modifier = Modifier.weight(1f))
if (isSelected || viewModel.isCustomSplit) { if (isSelected || viewModel.splitMode != SplitMode.EVEN) {
val focusManager = LocalFocusManager.current
val interactionSource = remember { MutableInteractionSource() } val interactionSource = remember { MutableInteractionSource() }
val value = if (viewModel.splitMode == SplitMode.PERCENT) {
viewModel.owersPercentSplit[member.id] ?: ""
} else {
viewModel.owersCustomSplit[member.id] ?: ""
}
BasicTextField( BasicTextField(
value = viewModel.owersCustomSplit[member.id] ?: "", value = value,
onValueChange = { onValueChange = { nv ->
viewModel.owersCustomSplit[member.id] = it val filteredValue = nv.filter { it in "0123456789.+-*/" }
viewModel.owersSelection[member.id] = (it != "") if (viewModel.splitMode == SplitMode.PERCENT) {
viewModel.owersPercentSplit[member.id] = filteredValue
} else {
viewModel.owersCustomSplit[member.id] = filteredValue
}
viewModel.owersSelection[member.id] = (filteredValue != "")
}, },
modifier = Modifier modifier = Modifier
.width(80.dp) .width(80.dp)
.height(46.dp), .height(46.dp),
interactionSource = interactionSource, interactionSource = interactionSource,
singleLine = true, singleLine = true,
enabled = viewModel.isCustomSplit && canEdit, enabled = viewModel.splitMode != SplitMode.EVEN && canEdit,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Next),
keyboardActions = KeyboardActions(onNext = { focusManager.moveFocus(FocusDirection.Next) }),
cursorBrush = SolidColor(MaterialTheme.colors.onSurface), cursorBrush = SolidColor(MaterialTheme.colors.onSurface),
textStyle = LocalTextStyle.current.copy( textStyle = LocalTextStyle.current.copy(
textAlign = TextAlign.Right, textAlign = TextAlign.Right,
@@ -432,13 +490,13 @@ fun OwerSelectionSection(
), ),
) { innerTextField -> ) { innerTextField ->
TextFieldDefaults.OutlinedTextFieldDecorationBox( TextFieldDefaults.OutlinedTextFieldDecorationBox(
value = viewModel.owersCustomSplit[member.id] ?: "", value = value,
visualTransformation = VisualTransformation.None, visualTransformation = VisualTransformation.None,
innerTextField = innerTextField, innerTextField = innerTextField,
singleLine = true, singleLine = true,
enabled = viewModel.isCustomSplit && canEdit, enabled = viewModel.splitMode != SplitMode.EVEN && canEdit,
interactionSource = interactionSource, interactionSource = interactionSource,
contentPadding = PaddingValues(horizontal = 12.dp, vertical = 0.dp), contentPadding = PaddingValues(horizontal = 8.dp, vertical = 0.dp),
colors = TextFieldDefaults.textFieldColors( colors = TextFieldDefaults.textFieldColors(
cursorColor = MaterialTheme.colors.onSurface, cursorColor = MaterialTheme.colors.onSurface,
backgroundColor = Color.Transparent, backgroundColor = Color.Transparent,
@@ -616,19 +674,115 @@ fun BillAdditionalDetailsSection(
} }
@SuppressLint("ViewModelConstructorInComposable") @SuppressLint("ViewModelConstructorInComposable")
@Preview(showBackground = true) @Preview(showBackground = true, name = "Standard Split")
@Composable @Composable
fun EditBillScreenPreview() { fun EditBillScreenPreview() {
MaterialTheme { MaterialTheme {
EditBillScreen( EditBillScreen(
viewModel = EditBillViewModel().apply { viewModel = EditBillViewModel().apply {
what = "Pizza" what = "Pizza"
amount = "12.50" amount = "12.00"
mainCurrencyName = "EUR" mainCurrencyName = "EUR"
members = listOf( members = listOf(
DBMember(1, 0, 0, "Alice", true, 1.0, 0, null, null, null, null, null), DBMember(1, 0, 0, "Alice", true, 1.0, 0, null, null, null, null, null),
DBMember(2, 0, 0, "Bob", true, 1.0, 0, null, null, null, null, null) DBMember(2, 0, 0, "Bob", true, 1.0, 0, null, null, null, null, null)
) )
owersSelection[1] = true
owersSelection[2] = true
updateSplits()
},
categories = emptyList(),
paymentModes = emptyList(),
onSave = {},
onBack = {},
onDateClick = {},
onTimeClick = {},
onScan = {}
)
}
}
@SuppressLint("ViewModelConstructorInComposable")
@Preview(showBackground = true, name = "Weighted Split")
@Composable
fun EditBillScreenWeightedPreview() {
MaterialTheme {
EditBillScreen(
viewModel = EditBillViewModel().apply {
what = "Weighted Pizza"
amount = "60.00"
mainCurrencyName = "EUR"
members = listOf(
DBMember(1, 0, 0, "Alice", true, 2.0, 0, null, null, null, null, null),
DBMember(2, 0, 0, "Bob", true, 1.0, 0, null, null, null, null, null),
DBMember(3, 0, 0, "Charlie", true, 1.0, 0, null, null, null, null, null)
)
owersSelection[1] = true
owersSelection[2] = true
owersSelection[3] = true
updateSplits()
},
categories = emptyList(),
paymentModes = emptyList(),
onSave = {},
onBack = {},
onDateClick = {},
onTimeClick = {},
onScan = {}
)
}
}
@SuppressLint("ViewModelConstructorInComposable")
@Preview(showBackground = true, name = "Custom Split (#)")
@Composable
fun EditBillScreenCustomPreview() {
MaterialTheme {
EditBillScreen(
viewModel = EditBillViewModel().apply {
what = "Custom Split Pizza"
amount = "60.00"
mainCurrencyName = "EUR"
members = listOf(
DBMember(1, 0, 0, "Alice", true, 1.0, 0, null, null, null, null, null),
DBMember(2, 0, 0, "Bob", true, 1.0, 0, null, null, null, null, null)
)
splitMode = SplitMode.CUSTOM
owersSelection[1] = true
owersSelection[2] = true
owersCustomSplit[1] = "40.00"
owersCustomSplit[2] = "20.00"
},
categories = emptyList(),
paymentModes = emptyList(),
onSave = {},
onBack = {},
onDateClick = {},
onTimeClick = {},
onScan = {}
)
}
}
@SuppressLint("ViewModelConstructorInComposable")
@Preview(showBackground = true, name = "Percent Split (%)")
@Composable
fun EditBillScreenPercentPreview() {
MaterialTheme {
EditBillScreen(
viewModel = EditBillViewModel().apply {
what = "Percent Split Pizza"
amount = "100.00"
mainCurrencyName = "EUR"
members = listOf(
DBMember(1, 0, 0, "Alice", true, 1.0, 0, null, null, null, null, null),
DBMember(2, 0, 0, "Bob", true, 1.0, 0, null, null, null, null, null)
)
splitMode = SplitMode.PERCENT
owersSelection[1] = true
owersSelection[2] = true
owersPercentSplit[1] = "70"
owersPercentSplit[2] = "30"
}, },
categories = emptyList(), categories = emptyList(),
paymentModes = emptyList(), paymentModes = emptyList(),
@@ -16,6 +16,10 @@ import net.helcel.cowspent.model.DBMember
import net.helcel.cowspent.util.SupportUtil import net.helcel.cowspent.util.SupportUtil
import net.helcel.cowspent.util.evalMath import net.helcel.cowspent.util.evalMath
enum class SplitMode {
EVEN, CUSTOM, PERCENT
}
class EditBillViewModel : ViewModel() { class EditBillViewModel : ViewModel() {
var what by mutableStateOf("") var what by mutableStateOf("")
var amount by mutableStateOf("") var amount by mutableStateOf("")
@@ -34,48 +38,75 @@ class EditBillViewModel : ViewModel() {
var members by mutableStateOf<List<DBMember>>(emptyList()) var members by mutableStateOf<List<DBMember>>(emptyList())
var owersSelection = mutableStateMapOf<Long, Boolean>() var owersSelection = mutableStateMapOf<Long, Boolean>()
var isCustomSplit by mutableStateOf(false) var splitMode by mutableStateOf(SplitMode.EVEN)
var owersCustomSplit = mutableStateMapOf<Long, String>() var owersCustomSplit = mutableStateMapOf<Long, String>()
var owersPercentSplit = mutableStateMapOf<Long, String>()
var dialogState by mutableStateOf<DialogState?>(null) var dialogState by mutableStateOf<DialogState?>(null)
val amountAsDouble: Double fun parseAmountFromUi(input: String): Double {
get() { if (input.isBlank()) return 0.0
return parseAmount(amount) ?: try { val sanitized = input.replace(',', '.')
evalMath(amount.replace(',', '.')) // If it contains any math operator, try evalMath first
} catch (_: Exception) { if (sanitized.any { it in "+-*/" }) {
0.0 try {
} val result = evalMath(sanitized)
if (result != 0.0) return SupportUtil.round2(result)
} catch (_: Exception) {}
} }
val parsed = parseAmount(input) ?: 0.0
fun getEvenSplit(): Double { return SupportUtil.round2(parsed)
val selectedOwersCount = owersSelection.count { it.value }
return if (selectedOwersCount > 0) amountAsDouble / selectedOwersCount else 0.0
} }
val amountAsDouble: Double
get() = parseAmountFromUi(amount)
val hasDifferentWeights: Boolean
get() = members.isNotEmpty() && members.any { it.weight != members[0].weight }
fun updateSplits() { fun updateSplits() {
if (!isCustomSplit) { if (splitMode == SplitMode.EVEN) {
val even = getEvenSplit() val selectedMembers = members.filter { owersSelection[it.id] == true }
val evenStr = if (even == 0.0) "" else SupportUtil.round2(even).toString() val totalWeight = selectedMembers.sumOf { it.weight }
val uiAmount = amountAsDouble
members.forEach { m -> members.forEach { m ->
if (owersSelection[m.id] == true) { if (owersSelection[m.id] == true) {
owersCustomSplit[m.id] = evenStr val share = if (totalWeight > 0) (uiAmount * m.weight) / totalWeight else 0.0
owersCustomSplit[m.id] = if (share == 0.0) "" else SupportUtil.round2(share).toString()
} else { } else {
owersCustomSplit.remove(m.id) owersCustomSplit.remove(m.id)
} }
} }
} else if (splitMode == SplitMode.PERCENT) {
val selectedCount = owersSelection.count { it.value }
if (selectedCount > 0) {
val evenPercent = 100.0 / selectedCount
val evenPercentStr = SupportUtil.round2(evenPercent).toString()
members.forEach { m ->
if (owersSelection[m.id] == true) {
if (owersPercentSplit[m.id].isNullOrEmpty()) {
owersPercentSplit[m.id] = evenPercentStr
}
} else {
owersPercentSplit.remove(m.id)
}
}
}
} }
} }
fun toggleMember(id: Long, selected: Boolean) { fun toggleMember(id: Long, selected: Boolean) {
owersSelection[id] = selected owersSelection[id] = selected
if (isCustomSplit) { if (splitMode != SplitMode.EVEN) {
if (selected) { if (selected) {
if (owersCustomSplit[id].isNullOrEmpty()) { if (splitMode == SplitMode.CUSTOM && owersCustomSplit[id].isNullOrEmpty()) {
owersCustomSplit[id] = "0" owersCustomSplit[id] = "0"
} else if (splitMode == SplitMode.PERCENT && owersPercentSplit[id].isNullOrEmpty()) {
owersPercentSplit[id] = "0"
} }
} else { } else {
owersCustomSplit.remove(id) owersCustomSplit.remove(id)
owersPercentSplit.remove(id)
} }
} else { } else {
updateSplits() updateSplits()
@@ -83,10 +114,17 @@ class EditBillViewModel : ViewModel() {
} }
fun getDiffSplit(): Double { fun getDiffSplit(): Double {
val customTotal = owersCustomSplit.entries return if (splitMode == SplitMode.PERCENT) {
.filter { owersSelection[it.key] == true } val customTotal = owersPercentSplit.entries
.sumOf { it.value.replace(',', '.').toDoubleOrNull() ?: 0.0 } .filter { owersSelection[it.key] == true }
return amountAsDouble - customTotal .sumOf { parseAmountFromUi(it.value) }
SupportUtil.round2(100.0 - customTotal)
} else {
val customTotal = owersCustomSplit.entries
.filter { owersSelection[it.key] == true }
.sumOf { parseAmountFromUi(it.value) }
SupportUtil.round2(amountAsDouble - customTotal)
}
} }
fun getOwersIds(): List<Long> { fun getOwersIds(): List<Long> {
@@ -142,7 +180,7 @@ class EditBillViewModel : ViewModel() {
} }
fun getFinalAmount(): Double { fun getFinalAmount(): Double {
return SupportUtil.round2(amountAsDouble / selectedCurrencyRate) return SupportUtil.round2(amountAsDouble * selectedCurrencyRate)
} }
fun getFinalComment(): String { fun getFinalComment(): String {
@@ -204,37 +242,38 @@ class EditBillViewModel : ViewModel() {
owersSelection.clear() owersSelection.clear()
owersCustomSplit.clear() owersCustomSplit.clear()
owersPercentSplit.clear()
if (customSplits != null) { if (customSplits != null) {
isCustomSplit = true splitMode = SplitMode.CUSTOM
for (member in members) { for (member in members) {
val selected = customSplits.containsKey(member.id) val selected = customSplits.containsKey(member.id)
owersSelection[member.id] = selected owersSelection[member.id] = selected
if (selected) { if (selected) {
// If we have metadata, the custom splits from DB are also converted. // If we have metadata, the custom splits from DB are also converted.
// We should show them as "Original" if possible? // We should show them as "Original" if possible?
// Actually, if we use metadata, we should probably store original splits too, // Reverse calculation for display: UI Part = DB Part / Rate
// but for now let's just reverse the rate for display.
val dbPart = customSplits[member.id]!! val dbPart = customSplits[member.id]!!
val uiPart = if (selectedCurrencyRate != 1.0) dbPart * selectedCurrencyRate else dbPart val uiPart = if (selectedCurrencyRate != 0.0) dbPart / selectedCurrencyRate else dbPart
owersCustomSplit[member.id] = SupportUtil.round2(uiPart).toString() owersCustomSplit[member.id] = SupportUtil.round2(uiPart).toString()
} }
} }
} else { } else {
// Even split logic // Even split logic
splitMode = SplitMode.EVEN
val billOwerIds = bill.billOwersIds val billOwerIds = bill.billOwersIds
val selectedCount = billOwerIds.size val selectedMembers = members.filter { billOwerIds.contains(it.id) }
val totalWeight = selectedMembers.sumOf { it.weight }
// Use UI amount for even split calculation // Use UI amount for even split calculation
val uiAmount = amountAsDouble val uiAmount = amountAsDouble
val evenSplit = if (selectedCount > 0) uiAmount / selectedCount else 0.0
val evenSplitStr = if (evenSplit == 0.0) "" else SupportUtil.round2(evenSplit).toString()
for (member in members) { for (member in members) {
val selected = billOwerIds.contains(member.id) val selected = billOwerIds.contains(member.id)
owersSelection[member.id] = selected owersSelection[member.id] = selected
if (selected) { if (selected) {
owersCustomSplit[member.id] = evenSplitStr val share = if (totalWeight > 0) (uiAmount * member.weight) / totalWeight else 0.0
owersCustomSplit[member.id] = if (share == 0.0) "" else SupportUtil.round2(share).toString()
} }
} }
} }
@@ -17,7 +17,7 @@ import net.helcel.cowspent.model.DBBill
import net.helcel.cowspent.model.ProjectType import net.helcel.cowspent.model.ProjectType
class LabelBillsActivity : AppCompatActivity() { class LabelBillsActivity : AppCompatActivity() {
private val viewModel: LabelBillsViewModel by viewModels() internal val viewModel: LabelBillsViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge() enableEdgeToEdge()
@@ -15,6 +15,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@@ -45,7 +46,10 @@ fun LabelBillsScreen(
title = { Text(stringResource(R.string.title_label_bills)) }, title = { Text(stringResource(R.string.title_label_bills)) },
navigationIcon = { navigationIcon = {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) Icon(
Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(R.string.simple_back)
)
} }
}, },
backgroundColor = MaterialTheme.colors.primary, backgroundColor = MaterialTheme.colors.primary,
@@ -223,7 +227,10 @@ fun BillSummaryCard(bill: DBBill, members: List<DBMember>, remainingCount: Int)
fun CategoryButton(icon: String, name: String, onClick: () -> Unit) { fun CategoryButton(icon: String, name: String, onClick: () -> Unit) {
OutlinedButton( OutlinedButton(
onClick = onClick, onClick = onClick,
modifier = Modifier.fillMaxWidth().height(60.dp), modifier = Modifier
.fillMaxWidth()
.height(60.dp)
.testTag("CategoryButton_$name"),
contentPadding = PaddingValues(2.dp) contentPadding = PaddingValues(2.dp)
) { ) {
Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) { Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) {
@@ -7,14 +7,8 @@ import androidx.activity.enableEdgeToEdge
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.helcel.cowspent.R import net.helcel.cowspent.R
import net.helcel.cowspent.android.helper.showToast import net.helcel.cowspent.android.helper.showToast
import net.helcel.cowspent.model.DBBill
import net.helcel.cowspent.model.DBCurrency
import net.helcel.cowspent.model.ProjectType import net.helcel.cowspent.model.ProjectType
import net.helcel.cowspent.persistence.CowspentSQLiteOpenHelper import net.helcel.cowspent.persistence.CowspentSQLiteOpenHelper
import net.helcel.cowspent.theme.ThemeUtils import net.helcel.cowspent.theme.ThemeUtils
@@ -23,9 +17,8 @@ import net.helcel.cowspent.util.ICallback
class ManageCurrenciesActivity : AppCompatActivity() { class ManageCurrenciesActivity : AppCompatActivity() {
private val viewModel: ManageCurrenciesViewModel by viewModels() internal val viewModel: ManageCurrenciesViewModel by viewModels()
private var db: CowspentSQLiteOpenHelper? = null private var db: CowspentSQLiteOpenHelper? = null
private var selectedProjectID: Long = -1
private val editMainCurrencyCallBack: ICallback = object : ICallback { private val editMainCurrencyCallBack: ICallback = object : ICallback {
override fun onFinish() {} override fun onFinish() {}
@@ -47,125 +40,45 @@ class ManageCurrenciesActivity : AppCompatActivity() {
enableEdgeToEdge() enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
intent.extras?.let { val selectedProjectID = intent.getLongExtra(EXTRA_PROJECT_ID, -1L)
selectedProjectID = it.getLong(EXTRA_PROJECT_ID)
}
if (selectedProjectID == -1L) { if (selectedProjectID == -1L) {
Log.e(TAG, "Missing project id") Log.e(TAG, "Missing project id")
finish() finish()
return return
} }
db = CowspentSQLiteOpenHelper.getInstance(this) viewModel.projectId = selectedProjectID
viewModel.loadCurrencies()
lifecycleScope.launch {
val project = withContext(Dispatchers.IO) { db!!.getProject(selectedProjectID) }
viewModel.mainCurrencyName = project?.currencyName?.let { if (it == "null") "" else it } ?: ""
updateCurrenciesList()
setContent { db = CowspentSQLiteOpenHelper.getInstance(this)
ThemeUtils.CowspentTheme {
ManageCurrenciesScreen( setContent {
viewModel = viewModel, ThemeUtils.CowspentTheme {
onBack = { finish() }, ManageCurrenciesScreen(
onSaveMain = { saveMainCurrency() }, viewModel = viewModel,
onAdd = { addOrUpdateCurrency() }, onBack = { finish() },
onDelete = { deleteCurrency(it) }, onSaveMain = { saveMainCurrency() },
onEdit = { startEditing(it) }, onAdd = { viewModel.addCurrency() },
onCancelEdit = { cancelEditing() } onDelete = { viewModel.deleteCurrency(it.id) },
) onEdit = { viewModel.startEditing(it) },
} onCancelEdit = { viewModel.cancelEditing() }
)
} }
} }
} }
private fun saveMainCurrency() { private fun saveMainCurrency() {
val newMainCurrencyName = viewModel.mainCurrencyName val project = db?.getProject(viewModel.projectId)
lifecycleScope.launch { if (project != null) {
withContext(Dispatchers.IO) { if (project.type == ProjectType.COSPEND) {
db!!.updateProject( if (!db!!.cowspentServerSyncHelper.isSyncPossible) {
selectedProjectID, null, null, null, showToast(this, getString(R.string.remote_project_operation_no_network), Toast.LENGTH_LONG)
null, null, newMainCurrencyName,
null, null, null
)
val project = db!!.getProject(selectedProjectID)
if (project != null) {
db!!.syncIfRemote(project)
if (project.type == ProjectType.COSPEND) {
withContext(Dispatchers.Main) {
if (!db!!.cowspentServerSyncHelper
.editRemoteProject(selectedProjectID, project.name, null, null, newMainCurrencyName, editMainCurrencyCallBack)
) {
showToast(this@ManageCurrenciesActivity, getString(R.string.remote_project_operation_no_network), Toast.LENGTH_LONG)
}
}
} else {
withContext(Dispatchers.Main) {
showToast(this@ManageCurrenciesActivity, getString(R.string.currency_saved_success), Toast.LENGTH_LONG)
}
}
} }
} else {
showToast(this, getString(R.string.currency_saved_success), Toast.LENGTH_LONG)
} }
} }
} viewModel.saveMainCurrency(editMainCurrencyCallBack)
private fun addOrUpdateCurrency() {
val exchangeRate = try { viewModel.newCurrencyRate.toDouble() } catch (_: Exception) { 0.0 }
val currencyName = viewModel.newCurrencyName
val editingId = viewModel.editingCurrencyId
lifecycleScope.launch {
withContext(Dispatchers.IO) {
if (editingId != null) {
db!!.updateCurrency(editingId, currencyName, exchangeRate)
val currency = db!!.getCurrency(editingId)
if (currency != null) {
db!!.setCurrencyStateSync(editingId, DBBill.STATE_EDITED)
}
} else {
val newCurrency = DBCurrency(
0, 0, selectedProjectID,
currencyName, exchangeRate, DBBill.STATE_ADDED
)
db!!.addCurrencyAndSync(newCurrency)
}
}
cancelEditing()
updateCurrenciesList()
}
}
private fun startEditing(currency: DBCurrency) {
viewModel.editingCurrencyId = currency.id
viewModel.newCurrencyName = currency.name ?: ""
viewModel.newCurrencyRate = currency.exchangeRate.toString()
}
private fun cancelEditing() {
viewModel.editingCurrencyId = null
viewModel.newCurrencyName = ""
viewModel.newCurrencyRate = ""
}
private fun deleteCurrency(currency: DBCurrency) {
lifecycleScope.launch {
withContext(Dispatchers.IO) {
db!!.setCurrencyStateSync(currency.id, DBBill.STATE_DELETED)
}
updateCurrenciesList()
}
}
private suspend fun updateCurrenciesList() {
val currenciesDB = withContext(Dispatchers.IO) {
val list = db!!.getCurrenciesOfProjectWithState(selectedProjectID, DBBill.STATE_ADDED).toMutableList()
list.addAll(db!!.getCurrenciesOfProjectWithState(selectedProjectID, DBBill.STATE_EDITED))
list.addAll(db!!.getCurrenciesOfProjectWithState(selectedProjectID, DBBill.STATE_OK))
list
}
withContext(Dispatchers.Main) {
viewModel.currencies = currenciesDB
}
} }
override fun onSupportNavigateUp(): Boolean { override fun onSupportNavigateUp(): Boolean {
@@ -1,6 +1,7 @@
package net.helcel.cowspent.android.currencies package net.helcel.cowspent.android.currencies
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Application
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@@ -41,6 +42,8 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
@@ -48,7 +51,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import net.helcel.cowspent.R import net.helcel.cowspent.R
import net.helcel.cowspent.android.helper.AlertDialog import net.helcel.cowspent.android.helper.StatefulAlertDialog
import net.helcel.cowspent.android.helper.formatAmount import net.helcel.cowspent.android.helper.formatAmount
import net.helcel.cowspent.model.DBCurrency import net.helcel.cowspent.model.DBCurrency
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
@@ -63,35 +66,10 @@ fun ManageCurrenciesScreen(
onEdit: (DBCurrency) -> Unit, onEdit: (DBCurrency) -> Unit,
onCancelEdit: () -> Unit onCancelEdit: () -> Unit
) { ) {
val dialogState = viewModel.dialogState StatefulAlertDialog(
if (dialogState != null) { state = viewModel.dialogState,
AlertDialog( onDismissRequest = { viewModel.dismissDialog() }
showDialog = true, )
onDismissRequest = { viewModel.dismissDialog() },
title = dialogState.title,
message = dialogState.message,
icon = dialogState.icon,
items = dialogState.items,
positiveText = dialogState.positiveText,
negativeText = dialogState.negativeText,
neutralText = dialogState.neutralText,
onConfirm = {
dialogState.onConfirm?.invoke()
viewModel.dismissDialog()
},
onCancel = {
dialogState.onCancel?.invoke()
viewModel.dismissDialog()
},
onNeutral = {
dialogState.onNeutral?.invoke()
viewModel.dismissDialog()
}
) {
dialogState.onItemSelected?.invoke(it)
viewModel.dismissDialog()
}
}
Scaffold( Scaffold(
topBar = { topBar = {
@@ -216,7 +194,7 @@ fun ManageCurrenciesScreen(
) { ) {
Icon( Icon(
imageVector = if (isEditing) Icons.Default.Done else Icons.Default.Add, imageVector = if (isEditing) Icons.Default.Done else Icons.Default.Add,
contentDescription = null, contentDescription = if (isEditing) "Done" else "Add",
tint = if (viewModel.isAddEnabled()) { tint = if (viewModel.isAddEnabled()) {
if (isEditing) MaterialTheme.colors.secondary else MaterialTheme.colors.primary if (isEditing) MaterialTheme.colors.secondary else MaterialTheme.colors.primary
} else MaterialTheme.colors.onSurface.copy(alpha = 0.2f) } else MaterialTheme.colors.onSurface.copy(alpha = 0.2f)
@@ -274,7 +252,9 @@ fun CurrencyRow(
shape = RoundedCornerShape(12.dp), shape = RoundedCornerShape(12.dp),
elevation = if (isEditing) 4.dp else 1.dp, elevation = if (isEditing) 4.dp else 1.dp,
border = if (isEditing) BorderStroke(1.dp, MaterialTheme.colors.secondary.copy(alpha = 0.5f)) else null, border = if (isEditing) BorderStroke(1.dp, MaterialTheme.colors.secondary.copy(alpha = 0.5f)) else null,
modifier = Modifier.fillMaxWidth() modifier = Modifier
.fillMaxWidth()
.testTag("CurrencyRow_${currency.name}")
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
@@ -304,7 +284,7 @@ fun CurrencyRow(
modifier = Modifier.padding(horizontal = 8.dp) modifier = Modifier.padding(horizontal = 8.dp)
) )
Text( Text(
text = formatAmount(currency.exchangeRate), text = formatAmount(if (currency.exchangeRate != 0.0) 1.0 / currency.exchangeRate else 0.0),
style = MaterialTheme.typography.body1, style = MaterialTheme.typography.body1,
fontWeight = FontWeight.ExtraBold, fontWeight = FontWeight.ExtraBold,
color = if (isEditing) MaterialTheme.colors.secondary else MaterialTheme.colors.onSurface color = if (isEditing) MaterialTheme.colors.secondary else MaterialTheme.colors.onSurface
@@ -320,7 +300,7 @@ fun CurrencyRow(
IconButton(onClick = onDelete) { IconButton(onClick = onDelete) {
Icon( Icon(
imageVector = Icons.Default.Delete, imageVector = Icons.Default.Delete,
contentDescription = null, contentDescription = "Delete",
tint = MaterialTheme.colors.error.copy(alpha = 0.7f), tint = MaterialTheme.colors.error.copy(alpha = 0.7f),
modifier = Modifier.size(20.dp) modifier = Modifier.size(20.dp)
) )
@@ -347,9 +327,10 @@ fun CurrencyRowPreview() {
@Preview(showBackground = true) @Preview(showBackground = true)
@Composable @Composable
fun ManageCurrenciesScreenPreview() { fun ManageCurrenciesScreenPreview() {
val application = LocalContext.current.applicationContext as Application
MaterialTheme { MaterialTheme {
ManageCurrenciesScreen( ManageCurrenciesScreen(
viewModel = ManageCurrenciesViewModel().apply { viewModel = ManageCurrenciesViewModel(application).apply {
mainCurrencyName = "EUR" mainCurrencyName = "EUR"
currencies = listOf( currencies = listOf(
DBCurrency(1, 0, 0, "USD", 1.1, 0), DBCurrency(1, 0, 0, "USD", 1.1, 0),
@@ -1,14 +1,24 @@
package net.helcel.cowspent.android.currencies package net.helcel.cowspent.android.currencies
import android.app.Application
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.lifecycle.ViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.helcel.cowspent.android.helper.DialogState import net.helcel.cowspent.android.helper.DialogState
import net.helcel.cowspent.model.DBBill
import net.helcel.cowspent.model.DBCurrency import net.helcel.cowspent.model.DBCurrency
import net.helcel.cowspent.model.ProjectType
import net.helcel.cowspent.persistence.CowspentSQLiteOpenHelper
import net.helcel.cowspent.util.ICallback
class ManageCurrenciesViewModel : ViewModel() { class ManageCurrenciesViewModel(application: Application) : AndroidViewModel(application) {
var projectId: Long = -1
var mainCurrencyName by mutableStateOf("") var mainCurrencyName by mutableStateOf("")
var newCurrencyName by mutableStateOf("") var newCurrencyName by mutableStateOf("")
var newCurrencyRate by mutableStateOf("") var newCurrencyRate by mutableStateOf("")
@@ -19,6 +29,105 @@ class ManageCurrenciesViewModel : ViewModel() {
var dialogState by mutableStateOf<DialogState?>(null) var dialogState by mutableStateOf<DialogState?>(null)
private val db = CowspentSQLiteOpenHelper.getInstance(application)
fun loadCurrencies() {
if (projectId == -1L) return
viewModelScope.launch {
val project = withContext(Dispatchers.IO) { db.getProject(projectId) }
mainCurrencyName = project?.currencyName?.let { if (it == "null") "" else it } ?: ""
updateCurrenciesList()
}
}
suspend fun updateCurrenciesList() {
val currenciesDB = withContext(Dispatchers.IO) {
val list = db.getCurrenciesOfProjectWithState(projectId, DBBill.STATE_ADDED).toMutableList()
list.addAll(db.getCurrenciesOfProjectWithState(projectId, DBBill.STATE_EDITED))
list.addAll(db.getCurrenciesOfProjectWithState(projectId, DBBill.STATE_OK))
list
}
withContext(Dispatchers.Main) {
currencies = currenciesDB
}
}
fun saveMainCurrency(callback: ICallback) {
val newMainCurrencyName = mainCurrencyName
viewModelScope.launch {
withContext(Dispatchers.IO) {
db.updateProject(
projId = projectId,
newCurrencyName = newMainCurrencyName
)
val project = db.getProject(projectId)
if (project != null) {
db.syncIfRemote(project)
if (project.type == ProjectType.COSPEND) {
withContext(Dispatchers.Main) {
if (!db.cowspentServerSyncHelper
.editRemoteProject(
projId = projectId,
newName = project.name,
newMainCurrencyName = newMainCurrencyName,
callback = callback
)
) {
// Handled by activity showing toast
}
}
}
}
}
}
}
fun addCurrency() {
val uiRate = try { newCurrencyRate.toDouble() } catch (_: Exception) { 0.0 }
val exchangeRate = if (uiRate != 0.0) 1.0 / uiRate else 0.0
val currencyName = newCurrencyName
val editingId = editingCurrencyId
viewModelScope.launch {
withContext(Dispatchers.IO) {
if (editingId != null) {
db.updateCurrency(editingId, currencyName, exchangeRate)
db.setCurrencyStateSync(editingId, DBBill.STATE_EDITED)
} else {
val newCurrency = DBCurrency(
0, 0, projectId,
currencyName, exchangeRate, DBBill.STATE_ADDED
)
db.addCurrencyAndSync(newCurrency)
}
}
cancelEditing()
updateCurrenciesList()
}
}
fun deleteCurrency(currencyId: Long) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
db.setCurrencyStateSync(currencyId, DBBill.STATE_DELETED)
}
updateCurrenciesList()
}
}
fun startEditing(currency: DBCurrency) {
editingCurrencyId = currency.id
newCurrencyName = currency.name ?: ""
val uiRate = if (currency.exchangeRate != 0.0) 1.0 / currency.exchangeRate else 0.0
newCurrencyRate = uiRate.toString()
}
fun cancelEditing() {
editingCurrencyId = null
newCurrencyName = ""
newCurrencyRate = ""
}
fun showDialog( fun showDialog(
title: String? = null, title: String? = null,
message: String? = null, message: String? = null,
@@ -61,11 +61,7 @@ fun ColorPicker(
var chroma by remember { mutableFloatStateOf(initialLch[1]) } var chroma by remember { mutableFloatStateOf(initialLch[1]) }
var hue by remember { mutableFloatStateOf(initialLch[2]) } var hue by remember { mutableFloatStateOf(initialLch[2]) }
val currentColorInt = remember(lightness, chroma, hue) { val currentColorInt = remember(lightness, chroma, hue) { mLCHtoRBG(lightness, chroma, hue) }
val color = mLCHtoRBG(lightness,chroma,hue)
onColorChanged(color)
color
}
val currentColor = Color(currentColorInt) val currentColor = Color(currentColorInt)
@@ -74,8 +70,9 @@ fun ColorPicker(
var isHexValid by remember { mutableStateOf(true) } var isHexValid by remember { mutableStateOf(true) }
val interactionSource = remember { MutableInteractionSource() } val interactionSource = remember { MutableInteractionSource() }
// Sync HEX with LCH // Report the colour, and keep the HEX field in step with the LCH sliders.
LaunchedEffect(currentColorInt) { LaunchedEffect(currentColorInt) {
onColorChanged(currentColorInt)
val newHex = "%06X".format(0xFFFFFF and currentColorInt) val newHex = "%06X".format(0xFFFFFF and currentColorInt)
if (hexText.uppercase() != newHex) { if (hexText.uppercase() != newHex) {
hexText = newHex hexText = newHex
@@ -1,7 +1,6 @@
package net.helcel.cowspent.android.helper package net.helcel.cowspent.android.helper
import android.graphics.* import android.graphics.Color
import android.graphics.drawable.Drawable
import java.security.MessageDigest import java.security.MessageDigest
import java.security.NoSuchAlgorithmException import java.security.NoSuchAlgorithmException
import java.util.* import java.util.*
@@ -11,209 +10,143 @@ import kotlin.math.round
import kotlin.math.sqrt import kotlin.math.sqrt
/** /**
* A Drawable object that draws text (1 character) on top of a circular/filled background. * The color a member's avatar gets, derived from their name.
*/ */
class TextDrawable private constructor( object TextDrawable {
private val mText: String, private const val INDEX_RED = 0
r: Int, private const val INDEX_GREEN = 1
g: Int, private const val INDEX_BLUE = 2
b: Int, private const val INDEX_HUE = 0
private val mRadius: Float, private const val INDEX_SATURATION = 1
private val mDisabled: Boolean private const val INDEX_LUMINATION = 2
) : Drawable() {
private val mTextPaint: Paint = Paint()
private val mBackground: Paint = Paint()
private val mDisabledCircle: Paint = Paint()
init { fun getColorFromName(name: String): Int {
mBackground.style = Paint.Style.FILL return try {
mBackground.isAntiAlias = true val hsl = calculateHSL(name)
mBackground.color = Color.rgb(r, g, b) val rgb = hslToRgb(hsl[0].toFloat(), hsl[1].toFloat(), hsl[2].toFloat(), 1f)
Color.rgb(rgb[0], rgb[1], rgb[2])
if ((r + g + b) / 3 < 220) { } catch (_: NoSuchAlgorithmException) {
mTextPaint.color = Color.WHITE Color.WHITE
} else {
mTextPaint.color = Color.BLACK
} }
mTextPaint.textSize = mRadius
mTextPaint.isAntiAlias = true
mTextPaint.textAlign = Paint.Align.CENTER
mDisabledCircle.style = Paint.Style.STROKE
mDisabledCircle.strokeWidth = mRadius * 0.2f
mDisabledCircle.isAntiAlias = true
mDisabledCircle.color = Color.DKGRAY
} }
override fun draw(canvas: Canvas) { @Throws(NoSuchAlgorithmException::class)
canvas.drawCircle(mRadius, mRadius, mRadius, mBackground) private fun calculateHSL(name: String): IntArray {
canvas.drawText( val result = arrayOf("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0")
mText, val rgb = doubleArrayOf(0.0, 0.0, 0.0)
mRadius, var sat = 70
mRadius - (mTextPaint.descent() + mTextPaint.ascent()) / 2, val lum = 68
mTextPaint val modulo = 16
var hash = name.lowercase(Locale.ROOT).replace("[^0-9a-f]".toRegex(), "")
if (!hash.matches("^[0-9a-f]{32}$".toRegex())) {
hash = md5(hash)
}
for (i in hash.indices) {
result[i % modulo] = (result[i % modulo].toInt() + hash.substring(i, i + 1).toInt(16)).toString()
}
for (count in 1 until modulo) {
rgb[count % 3] += result[count].toDouble()
}
rgb[INDEX_RED] = rgb[INDEX_RED] % 255
rgb[INDEX_GREEN] = rgb[INDEX_GREEN] % 255
rgb[INDEX_BLUE] = rgb[INDEX_BLUE] % 255
val hsl = rgbToHsl(rgb[INDEX_RED], rgb[INDEX_GREEN], rgb[INDEX_BLUE])
val bright = sqrt(
0.299 * rgb[INDEX_RED].pow(2.0) + 0.587 * rgb[INDEX_GREEN].pow(2.0) + 0.114 * rgb[INDEX_BLUE].pow(2.0)
) )
if (mDisabled) {
canvas.drawCircle(mRadius, mRadius, mRadius * 0.9f, mDisabledCircle) if (bright >= 200) {
canvas.drawLine( sat = 60
mRadius * 0.4f,
mRadius * 1.6f,
mRadius * 1.6f,
mRadius * 0.4f,
mDisabledCircle
)
} }
return intArrayOf((hsl[INDEX_HUE] * 360).toInt(), sat, lum)
} }
override fun setAlpha(alpha: Int) { private fun hslToRgb(hParam: Float, sParam: Float, lParam: Float, alpha: Float): IntArray {
mTextPaint.alpha = alpha var h = hParam
var s = sParam
var l = lParam
if (s !in 0.0f..100.0f) {
throw IllegalArgumentException("Color parameter outside of expected range - Saturation")
}
if (l !in 0.0f..100.0f) {
throw IllegalArgumentException("Color parameter outside of expected range - Luminance")
}
if (alpha !in 0.0f..1.0f) {
throw IllegalArgumentException("Color parameter outside of expected range - Alpha")
}
h %= 360.0f
h /= 360f
s /= 100f
l /= 100f
val q = if (l < 0.5) {
l * (1 + s)
} else {
(l + s) - s * l
}
val p = 2 * l - q
val r = round(max(0f, hueToRgb(p, q, h + 1.0f / 3.0f)) * 256).toInt()
val g = round(max(0f, hueToRgb(p, q, h)) * 256).toInt()
val b = round(max(0f, hueToRgb(p, q, h - 1.0f / 3.0f)) * 256).toInt()
return intArrayOf(r, g, b)
} }
override fun setColorFilter(cf: ColorFilter?) { private fun hueToRgb(p: Float, q: Float, hParam: Float): Float {
mTextPaint.colorFilter = cf var h = hParam
if (h < 0) h += 1f
if (h > 1) h -= 1f
if (6 * h < 1) return p + (q - p) * 6 * h
if (2 * h < 1) return q
if (3 * h < 2) return p + (q - p) * 6 * (2.0f / 3.0f - h)
return p
} }
@Deprecated("Deprecated in Java") private fun rgbToHsl(rUntrimmed: Double, gUntrimmed: Double, bUntrimmed: Double): DoubleArray {
override fun getOpacity(): Int { val r = rUntrimmed / 255
return PixelFormat.TRANSLUCENT val g = gUntrimmed / 255
} val b = bUntrimmed / 255
val max = max(r, max(g, b))
companion object { val min = r.coerceAtMost(g.coerceAtMost(b))
private const val INDEX_RED = 0 var h = (max + min) / 2
private const val INDEX_GREEN = 1 val s: Double
private const val INDEX_BLUE = 2 val l = (max + min) / 2
private const val INDEX_HUE = 0 if (max == min) {
private const val INDEX_SATURATION = 1 s = 0.0
private const val INDEX_LUMINATION = 2 h = s // achromatic
} else {
fun getColorFromName(name: String): Int { val d = max - min
return try { s = if (l > 0.5) d / (2 - max - min) else d / (max + min)
val hsl = calculateHSL(name) when (max) {
val rgb = hslToRgb(hsl[0].toFloat(), hsl[1].toFloat(), hsl[2].toFloat(), 1f) r -> {
Color.rgb(rgb[0], rgb[1], rgb[2]) h = (g - b) / d + (if (g < b) 6 else 0)
} catch (_: NoSuchAlgorithmException) { }
Color.WHITE g -> {
} h = (b - r) / d + 2
} }
b -> {
@Throws(NoSuchAlgorithmException::class) h = (r - g) / d + 4
private fun calculateHSL(name: String): IntArray {
val result = arrayOf("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0")
val rgb = doubleArrayOf(0.0, 0.0, 0.0)
var sat = 70
val lum = 68
val modulo = 16
var hash = name.lowercase(Locale.ROOT).replace("[^0-9a-f]".toRegex(), "")
if (!hash.matches("^[0-9a-f]{32}$".toRegex())) {
hash = md5(hash)
}
for (i in hash.indices) {
result[i % modulo] = (result[i % modulo].toInt() + hash.substring(i, i + 1).toInt(16)).toString()
}
for (count in 1 until modulo) {
rgb[count % 3] += result[count].toDouble()
}
rgb[INDEX_RED] = rgb[INDEX_RED] % 255
rgb[INDEX_GREEN] = rgb[INDEX_GREEN] % 255
rgb[INDEX_BLUE] = rgb[INDEX_BLUE] % 255
val hsl = rgbToHsl(rgb[INDEX_RED], rgb[INDEX_GREEN], rgb[INDEX_BLUE])
val bright = sqrt(
0.299 * rgb[INDEX_RED].pow(2.0) + 0.587 * rgb[INDEX_GREEN].pow(2.0) + 0.114 * rgb[INDEX_BLUE].pow(2.0)
)
if (bright >= 200) {
sat = 60
}
return intArrayOf((hsl[INDEX_HUE] * 360).toInt(), sat, lum)
}
private fun hslToRgb(hParam: Float, sParam: Float, lParam: Float, alpha: Float): IntArray {
var h = hParam
var s = sParam
var l = lParam
if (s !in 0.0f..100.0f) {
throw IllegalArgumentException("Color parameter outside of expected range - Saturation")
}
if (l !in 0.0f..100.0f) {
throw IllegalArgumentException("Color parameter outside of expected range - Luminance")
}
if (alpha !in 0.0f..1.0f) {
throw IllegalArgumentException("Color parameter outside of expected range - Alpha")
}
h %= 360.0f
h /= 360f
s /= 100f
l /= 100f
val q = if (l < 0.5) {
l * (1 + s)
} else {
(l + s) - s * l
}
val p = 2 * l - q
val r = round(max(0f, hueToRgb(p, q, h + 1.0f / 3.0f)) * 256).toInt()
val g = round(max(0f, hueToRgb(p, q, h)) * 256).toInt()
val b = round(max(0f, hueToRgb(p, q, h - 1.0f / 3.0f)) * 256).toInt()
return intArrayOf(r, g, b)
}
private fun hueToRgb(p: Float, q: Float, hParam: Float): Float {
var h = hParam
if (h < 0) h += 1f
if (h > 1) h -= 1f
if (6 * h < 1) return p + (q - p) * 6 * h
if (2 * h < 1) return q
if (3 * h < 2) return p + (q - p) * 6 * (2.0f / 3.0f - h)
return p
}
private fun rgbToHsl(rUntrimmed: Double, gUntrimmed: Double, bUntrimmed: Double): DoubleArray {
val r = rUntrimmed / 255
val g = gUntrimmed / 255
val b = bUntrimmed / 255
val max = max(r, max(g, b))
val min = r.coerceAtMost(g.coerceAtMost(b))
var h = (max + min) / 2
val s: Double
val l = (max + min) / 2
if (max == min) {
s = 0.0
h = s // achromatic
} else {
val d = max - min
s = if (l > 0.5) d / (2 - max - min) else d / (max + min)
when (max) {
r -> {
h = (g - b) / d + (if (g < b) 6 else 0)
}
g -> {
h = (b - r) / d + 2
}
b -> {
h = (r - g) / d + 4
}
} }
h /= 6.0
} }
val hsl = DoubleArray(3) h /= 6.0
hsl[INDEX_HUE] = h
hsl[INDEX_SATURATION] = s
hsl[INDEX_LUMINATION] = l
return hsl
} }
val hsl = DoubleArray(3)
hsl[INDEX_HUE] = h
hsl[INDEX_SATURATION] = s
hsl[INDEX_LUMINATION] = l
return hsl
}
@Throws(NoSuchAlgorithmException::class) @Throws(NoSuchAlgorithmException::class)
private fun md5(string: String): String { private fun md5(string: String): String {
val md5 = MessageDigest.getInstance("MD5").digest(string.toByteArray()) val md5 = MessageDigest.getInstance("MD5").digest(string.toByteArray())
return md5.joinToString("") { "%02x".format(it) } return md5.joinToString("") { "%02x".format(it) }
}
} }
} }
@@ -10,7 +10,7 @@ import androidx.appcompat.app.AppCompatActivity
import net.helcel.cowspent.theme.ThemeUtils import net.helcel.cowspent.theme.ThemeUtils
class LabelManagementActivity : AppCompatActivity() { class LabelManagementActivity : AppCompatActivity() {
private val viewModel: LabelManagementViewModel by viewModels() internal val viewModel: LabelManagementViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge() enableEdgeToEdge()
@@ -3,6 +3,7 @@ package net.helcel.cowspent.android.label
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.ui.window.Dialog
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
@@ -90,7 +91,7 @@ fun LabelManagementScreenContent(
title = { Text(stringResource(R.string.title_labels)) }, title = { Text(stringResource(R.string.title_labels)) },
navigationIcon = { navigationIcon = {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.simple_back))
} }
}, },
backgroundColor = MaterialTheme.colors.primary, backgroundColor = MaterialTheme.colors.primary,
@@ -107,7 +108,7 @@ fun LabelManagementScreenContent(
showEditDialog = true showEditDialog = true
} }
}) { }) {
Icon(Icons.Default.Add, contentDescription = null) Icon(Icons.Default.Add, contentDescription = "Add Label")
} }
} }
) { padding -> ) { padding ->
@@ -267,14 +268,22 @@ fun LabelItem(
Spacer(modifier = Modifier.width(32.dp)) Spacer(modifier = Modifier.width(32.dp))
Text(text = name, modifier = Modifier.weight(1f), style = MaterialTheme.typography.subtitle1) Text(text = name, modifier = Modifier.weight(1f), style = MaterialTheme.typography.subtitle1)
IconButton(onClick = onEdit) { IconButton(onClick = onEdit) {
Icon(Icons.Default.Edit, contentDescription = null, tint = MaterialTheme.colors.onSurface.copy(alpha = 0.6f)) Icon(Icons.Default.Edit, contentDescription = stringResource(R.string.action_edit), tint = MaterialTheme.colors.onSurface.copy(alpha = 0.6f))
} }
IconButton(onClick = onDelete) { IconButton(onClick = onDelete) {
Icon(Icons.Default.Delete, contentDescription = null, tint = MaterialTheme.colors.error.copy(alpha = 0.6f)) Icon(Icons.Default.Delete, contentDescription = stringResource(R.string.action_delete), tint = MaterialTheme.colors.error.copy(alpha = 0.6f))
} }
} }
} }
/**
* Split into a window and its content, the same way MemberEditDialogContent is.
*
* A Compose text field inside a Material AlertDialog never reaches idle under Robolectric: the
* composition spins in measure/layout until Espresso gives up 60s later, having exhausted the
* test heap and taken every later test class in that worker with it. A plain Dialog holding a
* Surface behaves, so the dialog body lives there instead - which is also what makes it testable.
*/
@Composable @Composable
fun EditLabelDialog( fun EditLabelDialog(
title: String, title: String,
@@ -283,15 +292,33 @@ fun EditLabelDialog(
initialColor: String, initialColor: String,
onDismiss: () -> Unit, onDismiss: () -> Unit,
onSave: (String, String, String) -> Unit onSave: (String, String, String) -> Unit
) {
Dialog(onDismissRequest = onDismiss) {
EditLabelDialogContent(title, initialName, initialIcon, initialColor, onDismiss, onSave)
}
}
@Composable
fun EditLabelDialogContent(
title: String,
initialName: String,
initialIcon: String,
initialColor: String,
onDismiss: () -> Unit,
onSave: (String, String, String) -> Unit
) { ) {
var name by remember { mutableStateOf(initialName) } var name by remember { mutableStateOf(initialName) }
var icon by remember { mutableStateOf(initialIcon) } var icon by remember { mutableStateOf(initialIcon) }
var color by remember { mutableStateOf(initialColor) } var color by remember { mutableStateOf(initialColor) }
AlertDialog( Surface(
onDismissRequest = onDismiss, shape = MaterialTheme.shapes.medium,
title = { Text(title) }, color = MaterialTheme.colors.surface,
text = { contentColor = contentColorFor(MaterialTheme.colors.surface)
) {
Column(modifier = Modifier.padding(24.dp)) {
Text(title, style = MaterialTheme.typography.h6)
Spacer(modifier = Modifier.height(16.dp))
Column(modifier = Modifier.verticalScroll(rememberScrollState())) { Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
OutlinedTextField( OutlinedTextField(
value = name, value = name,
@@ -315,21 +342,25 @@ fun EditLabelDialog(
onColorChanged = { color = String.format("#%06X", 0xFFFFFF and it) } onColorChanged = { color = String.format("#%06X", 0xFFFFFF and it) }
) )
} }
}, Spacer(modifier = Modifier.height(16.dp))
confirmButton = { Row(
Button( modifier = Modifier.fillMaxWidth(),
onClick = { onSave(name, icon, color) }, horizontalArrangement = Arrangement.End,
enabled = name.isNotBlank() verticalAlignment = Alignment.CenterVertically
) { ) {
Text(stringResource(R.string.action_save)) TextButton(onClick = onDismiss) {
} Text(stringResource(R.string.simple_cancel))
}, }
dismissButton = { Spacer(modifier = Modifier.width(8.dp))
TextButton(onClick = onDismiss) { Button(
Text(stringResource(R.string.simple_cancel)) onClick = { onSave(name, icon, color) },
enabled = name.isNotBlank()
) {
Text(stringResource(R.string.action_save))
}
} }
} }
) }
} }
fun parseColor(colorString: String): Color { fun parseColor(colorString: String): Color {
@@ -4,8 +4,10 @@ import android.annotation.SuppressLint
import android.content.Intent import android.content.Intent
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
@@ -291,7 +293,7 @@ fun BillsListScreen(
isSearchExpanded = false isSearchExpanded = false
viewModel.searchQuery = "" viewModel.searchQuery = ""
}) { }) {
Icon(Icons.Default.Close, contentDescription = null, tint = MaterialTheme.colors.onPrimary) Icon(Icons.Default.Close, contentDescription = stringResource(R.string.action_clear_search), tint = MaterialTheme.colors.onPrimary)
} }
} }
) )
@@ -320,13 +322,13 @@ fun BillsListScreen(
isSearchExpanded = false isSearchExpanded = false
viewModel.searchQuery = "" viewModel.searchQuery = ""
}) { }) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.action_close_search))
} }
} else { } else {
IconButton(onClick = { IconButton(onClick = {
scope.launch { scaffoldState.drawerState.open() } scope.launch { scaffoldState.drawerState.open() }
}) { }) {
Icon(Icons.Default.Menu, contentDescription = null) Icon(Icons.Default.Menu, contentDescription = stringResource(R.string.action_open_menu))
} }
} }
}, },
@@ -341,7 +343,10 @@ fun BillsListScreen(
} }
} }
IconButton(onClick = { isSearchExpanded = true }) { IconButton(onClick = { isSearchExpanded = true }) {
Icon(Icons.Default.Search, contentDescription = null) Icon(
Icons.Default.Search,
contentDescription = stringResource(R.string.action_search)
)
} }
} }
}, },
@@ -417,6 +422,9 @@ fun BillsListScreen(
is SectionItem -> SectionHeader(item.title) is SectionItem -> SectionHeader(item.title)
} }
} }
item {
Spacer(modifier = Modifier.height(64.dp).fillMaxWidth())
}
} }
} }
} }
@@ -88,6 +88,7 @@ object BillsListUtils {
shareIntent, shareIntent,
context.getString(R.string.title_settle) context.getString(R.string.title_settle)
) )
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(chooserIntent) context.startActivity(chooserIntent)
} }
@@ -4,6 +4,7 @@ import android.app.SearchManager
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences
import android.content.IntentFilter import android.content.IntentFilter
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.net.Uri import android.net.Uri
@@ -18,6 +19,7 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.annotation.VisibleForTesting
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
@@ -53,7 +55,9 @@ import net.helcel.cowspent.util.CospendClientUtil
import net.helcel.cowspent.util.ExportUtil import net.helcel.cowspent.util.ExportUtil
import net.helcel.cowspent.util.ICallback import net.helcel.cowspent.util.ICallback
import net.helcel.cowspent.util.IRefreshBillsListCallback import net.helcel.cowspent.util.IRefreshBillsListCallback
import net.helcel.cowspent.util.SyncSettings
import net.helcel.cowspent.util.SupportUtil import net.helcel.cowspent.util.SupportUtil
import net.helcel.cowspent.util.VersatileProjectSyncClient
import java.io.IOException import java.io.IOException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
@@ -63,13 +67,16 @@ class BillsListViewActivity :
AppCompatActivity(), AppCompatActivity(),
IRefreshBillsListCallback { IRefreshBillsListCallback {
private val viewModel: BillsListViewModel by viewModels() internal val viewModel: BillsListViewModel by viewModels()
companion object { companion object {
var DEBUG = false var DEBUG = false
private val TAG = BillsListViewActivity::class.java.simpleName private val TAG = BillsListViewActivity::class.java.simpleName
// Opening a project only re-syncs it if it has not synced within this window.
private const val SELECTED_PROJECT_SYNC_INTERVAL_MS = 60 * 1000L
private const val SAVED_STATE_NAVIGATION_SELECTION = "navigationSelection" private const val SAVED_STATE_NAVIGATION_SELECTION = "navigationSelection"
private const val SAVED_STATE_NAVIGATION_OPEN = "navigationOpen" private const val SAVED_STATE_NAVIGATION_OPEN = "navigationOpen"
@@ -276,7 +283,7 @@ class BillsListViewActivity :
labelBillsLauncher.launch(LabelBillsActivity.createIntent(this, selectedProjectId)) labelBillsLauncher.launch(LabelBillsActivity.createIntent(this, selectedProjectId))
} }
}, },
onRefresh = { synchronize(true) } onRefresh = { synchronize(SyncTrigger.MANUAL) }
) )
} }
} }
@@ -330,10 +337,7 @@ class BillsListViewActivity :
} }
viewModel.isRefreshing = false viewModel.isRefreshing = false
if (db.cowspentServerSyncHelper.isSyncPossible) { synchronize(SyncTrigger.APP_OPEN)
db.cowspentServerSyncHelper.addCallbackPull(syncCallBack)
synchronize()
}
registerBroadcastReceiver() registerBroadcastReceiver()
updateAvatarInDrawer(CowspentServerSyncHelper.isNextcloudAccountConfigured(this)) updateAvatarInDrawer(CowspentServerSyncHelper.isNextcloudAccountConfigured(this))
@@ -347,6 +351,9 @@ class BillsListViewActivity :
} catch (_: RuntimeException) { } catch (_: RuntimeException) {
if (DEBUG) Log.d(TAG, "RECEIVER PROBLEM, let's ignore it...") if (DEBUG) Log.d(TAG, "RECEIVER PROBLEM, let's ignore it...")
} }
// The helper outlives the activity, and it only drains its pull callbacks when a task
// starts; drop ours so a paused activity is not retained by it.
db.cowspentServerSyncHelper.removeCallbackPull(syncCallBack)
isActivityVisible = false isActivityVisible = false
} }
@@ -373,7 +380,7 @@ class BillsListViewActivity :
navigationSelection = Category(null, null) navigationSelection = Category(null, null)
refreshLists(true) refreshLists(true)
synchronize() synchronize(SyncTrigger.PROJECT_OPEN)
} }
fun onManageProjectClick(projectId: Long) { fun onManageProjectClick(projectId: Long) {
@@ -401,12 +408,14 @@ class BillsListViewActivity :
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
db.deleteProject(projectId) db.deleteProject(projectId)
PreferenceManager.getDefaultSharedPreferences(applicationContext)
.edit { remove(lastProjectSyncKey(projectId)) }
val dbProjects = db.projects val dbProjects = db.projects
if (dbProjects.isNotEmpty()) setSelectedProject(dbProjects[0].id) else setSelectedProject(0) if (dbProjects.isNotEmpty()) setSelectedProject(dbProjects[0].id) else setSelectedProject(0)
} }
setupDrawerProjects() setupDrawerProjects()
refreshLists() refreshLists()
synchronize() synchronize(SyncTrigger.PROJECT_OPEN)
val projectNameString = proj.name.ifEmpty { proj.remoteId } val projectNameString = proj.name.ifEmpty { proj.remoteId }
showToast(this@BillsListViewActivity, getString(R.string.remove_project_confirmation, projectNameString)) showToast(this@BillsListViewActivity, getString(R.string.remove_project_confirmation, projectNameString))
} }
@@ -421,22 +430,34 @@ class BillsListViewActivity :
lifecycleScope.launch { lifecycleScope.launch {
val proj = withContext(Dispatchers.IO) { db.getProject(projectId) } ?: return@launch val proj = withContext(Dispatchers.IO) { db.getProject(projectId) } ?: return@launch
val isArchiving = !proj.isArchived val isArchiving = !proj.isArchived
val newArchivedTs = if (isArchiving) System.currentTimeMillis() / 1000 else 0L val localArchivedTs = if (isArchiving) System.currentTimeMillis() / 1000 else 0L
val remoteArchivedTs = if (isArchiving) {
localArchivedTs
} else {
VersatileProjectSyncClient.REMOTE_ARCHIVED_TS_UNSET
}
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
db.updateProject( db.updateProject(
projId = projectId, projId = projectId,
newName = null, newArchivedTs = localArchivedTs
newEmail = null, )
newPassword = null, }
newLastPayerId = null,
newLastSyncedTimestamp = null, if (!proj.isLocal) {
newCurrencyName = null, db.cowspentServerSyncHelper.editRemoteProject(
newDeletionDisabled = null, projId = projectId,
newMyAccessLevel = null, newArchivedTs = remoteArchivedTs,
newBearerToken = null, callback = object : ICallback {
newArchivedTs = newArchivedTs override fun onFinish() {}
override fun onFinish(result: String, message: String) {
if (message.isNotEmpty()) {
showToast(this@BillsListViewActivity, getString(R.string.error_sync, message))
}
}
override fun onScheduled() {}
}
) )
} }
@@ -739,31 +760,73 @@ class BillsListViewActivity :
} }
} }
private fun synchronize(manual: Boolean = false) { /**
* What prompted a sync. Only [APP_OPEN] may refresh the account and every project, and only
* then when the SyncOnOpen interval has elapsed; the other triggers touch the selected
* project alone.
*/
@VisibleForTesting
internal enum class SyncTrigger { APP_OPEN, PROJECT_OPEN, MANUAL }
@VisibleForTesting
internal fun synchronize(trigger: SyncTrigger) {
val preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext) val preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
val offlineMode = preferences.getBoolean(getString(R.string.pref_key_offline_mode), false) // isSyncPossible is networkConnected && !offlineMode, so offline mode is already covered
if (offlineMode && !manual) { // here - including for a manual refresh, which cannot currently override it.
return if (!db.cowspentServerSyncHelper.isSyncPossible) return
}
val selectedProjectId = preferences.getLong("selected_project", 0)
val now = System.currentTimeMillis()
// The account and all-projects refresh belongs to opening the app, throttled by the
// SyncOnOpen interval so that resuming within the interval does not repeat it.
val intervalMinutes = SyncSettings.intervalMinutes(applicationContext)
val lastAccountSync = preferences.getLong(getString(R.string.pref_key_last_account_sync_timestamp), 0L)
val accountSyncDue = trigger == SyncTrigger.APP_OPEN &&
now - lastAccountSync > intervalMinutes * 60 * 1000L
lifecycleScope.launch {
val remoteProjects = withContext(Dispatchers.IO) { db.projects }
.filter { !it.isLocal && !it.isArchived }
if (db.cowspentServerSyncHelper.isSyncPossible) {
viewModel.isRefreshing = true viewModel.isRefreshing = true
val selectedProjectId = PreferenceManager.getDefaultSharedPreferences(applicationContext).getLong("selected_project", 0) db.cowspentServerSyncHelper.addCallbackPull(syncCallBack)
if (selectedProjectId != 0L) {
lifecycleScope.launch { val started = if (accountSyncDue) {
val proj = withContext(Dispatchers.IO) { db.getProject(selectedProjectId) } if (CowspentServerSyncHelper.isNextcloudAccountConfigured(applicationContext)) {
if (proj != null && !proj.isLocal) { db.cowspentServerSyncHelper.runAccountProjectsSync()
db.cowspentServerSyncHelper.addCallbackPull(syncCallBack)
db.cowspentServerSyncHelper.scheduleSync(false, selectedProjectId)
} else viewModel.isRefreshing = false
} }
} else viewModel.isRefreshing = false remoteProjects.count {
if (CowspentServerSyncHelper.isNextcloudAccountConfigured(applicationContext)) { val scheduled = db.cowspentServerSyncHelper.scheduleSync(false, it, false) != null
db.cowspentServerSyncHelper.runAccountProjectsSync() if (scheduled) markProjectSynced(preferences, it.id, now)
scheduled
}
} else {
val selectedProj = remoteProjects.find { it.id == selectedProjectId }
val lastSync = preferences.getLong(lastProjectSyncKey(selectedProjectId), 0L)
val due = trigger == SyncTrigger.MANUAL ||
now - lastSync > SELECTED_PROJECT_SYNC_INTERVAL_MS
if (selectedProj != null && due &&
db.cowspentServerSyncHelper.scheduleSync(
false, selectedProj, trigger == SyncTrigger.MANUAL
) != null
) {
markProjectSynced(preferences, selectedProj.id, now)
1
} else 0
} }
// Only a task that actually started reports back through syncCallBack, so clear
// the indicator here when none did - nothing else would.
if (started == 0) viewModel.isRefreshing = false
} }
} }
private fun lastProjectSyncKey(projectId: Long) = "lastProjectSyncTimestamp_$projectId"
private fun markProjectSynced(preferences: SharedPreferences, projectId: Long, at: Long) {
preferences.edit { putLong(lastProjectSyncKey(projectId), at) }
}
private fun registerBroadcastReceiver() { private fun registerBroadcastReceiver() {
val filter = IntentFilter().apply { val filter = IntentFilter().apply {
addAction(MainConstants.BROADCAST_PROJECT_SYNC_FAILED) addAction(MainConstants.BROADCAST_PROJECT_SYNC_FAILED)
@@ -803,7 +866,7 @@ class BillsListViewActivity :
refreshLists() refreshLists()
} }
MainConstants.BROADCAST_SYNC_PROJECT -> { MainConstants.BROADCAST_SYNC_PROJECT -> {
synchronize() synchronize(SyncTrigger.PROJECT_OPEN)
} }
MainConstants.BROADCAST_NETWORK_AVAILABLE -> { MainConstants.BROADCAST_NETWORK_AVAILABLE -> {
} }
@@ -831,7 +894,7 @@ class BillsListViewActivity :
refreshLists() refreshLists()
if (db.cowspentServerSyncHelper.isSyncPossible) { if (db.cowspentServerSyncHelper.isSyncPossible) {
db.cowspentServerSyncHelper.addCallbackPull(syncCallBack) db.cowspentServerSyncHelper.addCallbackPull(syncCallBack)
synchronize() synchronize(SyncTrigger.PROJECT_OPEN)
} }
} }
} }
@@ -17,8 +17,6 @@ object MainConstants {
const val BROADCAST_AVATAR_UPDATED = "net.helcel.cowspent.broadcast.avatar_updated" const val BROADCAST_AVATAR_UPDATED = "net.helcel.cowspent.broadcast.avatar_updated"
const val BROADCAST_AVATAR_UPDATED_MEMBER = "net.helcel.cowspent.broadcast.avatar_updated_for_member" const val BROADCAST_AVATAR_UPDATED_MEMBER = "net.helcel.cowspent.broadcast.avatar_updated_for_member"
const val MAIN_CHANNEL_ID = 1234567890
const val PARAM_DIALOG_CONTENT = "net.helcel.cowspent.PARAM_DIALOG_CONTENT" const val PARAM_DIALOG_CONTENT = "net.helcel.cowspent.PARAM_DIALOG_CONTENT"
const val PARAM_PROJECT_TO_SELECT = "net.helcel.cowspent.PARAM_PROJECT_TO_SELECT" const val PARAM_PROJECT_TO_SELECT = "net.helcel.cowspent.PARAM_PROJECT_TO_SELECT"
@@ -114,7 +114,7 @@ object ProjectImportHelper {
} }
else -> 0 else -> 0
} }
val payerName = if (columns.containsKey("payer_name")) line[columns["payer_name"]!!] else "" val payerName = if (columns.containsKey("payer_name")) line[columns["payer_name"]!!].trim() else ""
val payerWeight = if (columns.containsKey("payer_weight")) line[columns["payer_weight"]!!].toDouble() else 1.0 val payerWeight = if (columns.containsKey("payer_weight")) line[columns["payer_weight"]!!].toDouble() else 1.0
val owersStr = if (columns.containsKey("owers")) line[columns["owers"]!!] else "" val owersStr = if (columns.containsKey("owers")) line[columns["owers"]!!] else ""
val payerActive = columns.containsKey("payer_active") && line[columns["payer_active"]!!] == "1" val payerActive = columns.containsKey("payer_active") && line[columns["payer_active"]!!] == "1"
@@ -122,8 +122,10 @@ object ProjectImportHelper {
val pmId = if (columns.containsKey("paymentmodeid") && line[columns["paymentmodeid"]!!].isNotEmpty()) line[columns["paymentmodeid"]!!].toLong() else 0L val pmId = if (columns.containsKey("paymentmodeid") && line[columns["paymentmodeid"]!!].isNotEmpty()) line[columns["paymentmodeid"]!!].toLong() else 0L
val pm = if (columns.containsKey("paymentmode")) line[columns["paymentmode"]!!] else null val pm = if (columns.containsKey("paymentmode")) line[columns["paymentmode"]!!] else null
membersActive[payerName] = payerActive if (payerName.isNotEmpty()) {
membersWeight[payerName] = payerWeight membersActive[payerName] = payerActive
membersWeight[payerName] = payerWeight
}
if (owersStr.trim().isEmpty()) { if (owersStr.trim().isEmpty()) {
onError(context.getString(R.string.import_error_owers, row)) onError(context.getString(R.string.import_error_owers, row))
@@ -132,10 +134,10 @@ object ProjectImportHelper {
if (what != "deleteMeIfYouWant") { if (what != "deleteMeIfYouWant") {
billRemoteIdToOwerStr[row.toLong()] = owersStr billRemoteIdToOwerStr[row.toLong()] = owersStr
val owersArray = owersStr.split(", ").filter { it.isNotEmpty() } val owersArray = owersStr.split(",").map { it.trim() }.filter { it.isNotEmpty() }
for (ower in owersArray) { for (ower in owersArray) {
if (!membersWeight.containsKey(ower.trim())) { if (!membersWeight.containsKey(ower)) {
membersWeight[ower.trim()] = 1.0 membersWeight[ower] = 1.0
} }
} }
bills.add(DBBill(0, row.toLong(), 0, 0, amount, timestamp, what, DBBill.STATE_OK, "n", pm, catId, comment, pmId)) bills.add(DBBill(0, row.toLong(), 0, 0, amount, timestamp, what, DBBill.STATE_OK, "n", pm, catId, comment, pmId))
@@ -149,6 +151,9 @@ object ProjectImportHelper {
val memberNameToId = mutableMapOf<String, Long>() val memberNameToId = mutableMapOf<String, Long>()
val pid = db.addProject(DBProject(0, projectRemoteId, "", projectRemoteId, null, null, null, ProjectType.LOCAL, 0L, mainCurrencyName, false, DBProject.ACCESS_LEVEL_UNKNOWN, null)) val pid = db.addProject(DBProject(0, projectRemoteId, "", projectRemoteId, null, null, null, ProjectType.LOCAL, 0L, mainCurrencyName, false, DBProject.ACCESS_LEVEL_UNKNOWN, null))
// addProject only inserts a subset of the row, currency not among it, so the main
// currency the file declared has to be written separately or it is lost.
if (mainCurrencyName != null) db.updateProject(pid, newCurrencyName = mainCurrencyName)
val pmRemoteToLocal = mutableMapOf<Long, Long>() val pmRemoteToLocal = mutableMapOf<Long, Long>()
paymentModes.forEach { paymentModes.forEach {
@@ -171,8 +176,8 @@ object ProjectImportHelper {
val localCatId = catRemoteToLocal[b.categoryId] ?: 0L val localCatId = catRemoteToLocal[b.categoryId] ?: 0L
val localPmId = pmRemoteToLocal[b.paymentModeId] ?: 0L val localPmId = pmRemoteToLocal[b.paymentModeId] ?: 0L
val billId = db.addBill(DBBill(0, 0, pid, payerId, b.amount, b.timestamp, b.what, DBBill.STATE_OK, b.repeat, b.paymentMode, localCatId, b.comment, localPmId)) val billId = db.addBill(DBBill(0, 0, pid, payerId, b.amount, b.timestamp, b.what, DBBill.STATE_OK, b.repeat, b.paymentMode, localCatId, b.comment, localPmId))
billRemoteIdToOwerStr[b.remoteId]?.split(", ")?.filter { it.isNotEmpty() }?.forEach { ower -> billRemoteIdToOwerStr[b.remoteId]?.split(",")?.map { it.trim() }?.filter { it.isNotEmpty() }?.forEach { ower ->
memberNameToId[ower.trim()]?.let { owerId -> db.addBillower(billId, owerId) } memberNameToId[ower]?.let { owerId -> db.addBillower(billId, owerId) }
} }
} }
onSuccess(pid) onSuccess(pid)
@@ -10,10 +10,8 @@ import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import net.helcel.cowspent.R import net.helcel.cowspent.R
@@ -31,7 +29,7 @@ import net.helcel.cowspent.android.project.ProjectImportHelper
class NewProjectActivity : AppCompatActivity() { class NewProjectActivity : AppCompatActivity() {
private val viewModel: NewProjectViewModel by viewModels() internal val viewModel: NewProjectViewModel by viewModels()
private lateinit var db: CowspentSQLiteOpenHelper private lateinit var db: CowspentSQLiteOpenHelper
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@@ -57,9 +55,6 @@ class NewProjectActivity : AppCompatActivity() {
.setAction(Intent.ACTION_GET_CONTENT) .setAction(Intent.ACTION_GET_CONTENT)
importFileLauncher.launch(Intent.createChooser(intent, "Select a file")) importFileLauncher.launch(Intent.createChooser(intent, "Select a file"))
}, },
onChooseFromNextcloud = {
chooseFromNextcloud()
},
onOkPressed = { onPressOk() }, onOkPressed = { onPressOk() },
onBack = { finish() }, onBack = { finish() },
onFieldsChanged = { updateAuthStatus() } onFieldsChanged = { updateAuthStatus() }
@@ -130,19 +125,6 @@ class NewProjectActivity : AppCompatActivity() {
} }
} }
private fun chooseFromNextcloud() {
lifecycleScope.launch {
val accountProjects = withContext(Dispatchers.IO) { db.accountProjects }
if (accountProjects.isEmpty()) {
showToast(getString(R.string.choose_account_project_dialog_impossible), Toast.LENGTH_LONG)
return@launch
}
viewModel.nextcloudProjects = accountProjects
viewModel.showNextcloudProjectDialog = true
}
}
private fun updateAuthStatus() { private fun updateAuthStatus() {
val url = getFormattedUrl() val url = getFormattedUrl()
val fakeProj = DBProject( val fakeProj = DBProject(
@@ -154,19 +136,7 @@ class NewProjectActivity : AppCompatActivity() {
viewModel.isAuthenticatedAccount = db.cowspentServerSyncHelper.canCreateAuthenticatedProject(fakeProj) viewModel.isAuthenticatedAccount = db.cowspentServerSyncHelper.canCreateAuthenticatedProject(fakeProj)
} }
private fun onPressOk() { private fun onPressOk() = createProject()
val type = viewModel.projectType
val todoCreate = viewModel.whatTodoIsCreate
val url = getFormattedUrl()
val fakeProj = DBProject(
0, "", "", "", url,
"", 0L, type, 0L,
null, false, DBProject.ACCESS_LEVEL_UNKNOWN,
""
)
createProject()
}
private fun getFormattedUrl(): String { private fun getFormattedUrl(): String {
var url = viewModel.projectUrl.trim() var url = viewModel.projectUrl.trim()
@@ -3,7 +3,6 @@ package net.helcel.cowspent.android.project.create
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
@@ -31,7 +30,6 @@ fun NewProjectScreen(
viewModel: NewProjectViewModel, viewModel: NewProjectViewModel,
onScanQrCode: () -> Unit, onScanQrCode: () -> Unit,
onImportFile: () -> Unit, onImportFile: () -> Unit,
onChooseFromNextcloud: () -> Unit,
onOkPressed: () -> Unit, onOkPressed: () -> Unit,
onBack: () -> Unit, onBack: () -> Unit,
onFieldsChanged: () -> Unit onFieldsChanged: () -> Unit
@@ -224,40 +222,6 @@ fun NewProjectScreen(
) )
} }
if (viewModel.showNextcloudProjectDialog) {
AlertDialog(
onDismissRequest = { viewModel.showNextcloudProjectDialog = false },
title = { Text(stringResource(R.string.choose_account_project_dialog_title)) },
text = {
Column {
viewModel.nextcloudProjects.forEach { project ->
Row(
Modifier
.fillMaxWidth()
.selectable(
selected = false,
onClick = {
viewModel.projectId = project.remoteId
viewModel.projectUrl = project.ncUrl
viewModel.showNextcloudProjectDialog = false
}
)
.padding(16.dp)
) {
Text(text = project.name)
}
}
}
},
confirmButton = {},
dismissButton = {
TextButton(onClick = { viewModel.showNextcloudProjectDialog = false }) {
Text(stringResource(R.string.simple_cancel))
}
}
)
}
if (viewModel.isCreatingRemoteProject) { if (viewModel.isCreatingRemoteProject) {
AlertDialog( AlertDialog(
onDismissRequest = { }, onDismissRequest = { },
@@ -337,7 +301,6 @@ fun NewProjectScreenPreview() {
}, },
onScanQrCode = {}, onScanQrCode = {},
onImportFile = {}, onImportFile = {},
onChooseFromNextcloud = {},
onOkPressed = {}, onOkPressed = {},
onBack = {}, onBack = {},
onFieldsChanged = {} onFieldsChanged = {}
@@ -5,7 +5,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import net.helcel.cowspent.model.DBAccountProject
import net.helcel.cowspent.model.ProjectType import net.helcel.cowspent.model.ProjectType
class NewProjectViewModel : ViewModel() { class NewProjectViewModel : ViewModel() {
@@ -33,8 +32,6 @@ class NewProjectViewModel : ViewModel() {
var isAuthenticatedAccount by mutableStateOf(false) var isAuthenticatedAccount by mutableStateOf(false)
var showAuthWarningDialog by mutableStateOf(false) var showAuthWarningDialog by mutableStateOf(false)
var showNextcloudProjectDialog by mutableStateOf(false)
var nextcloudProjects by mutableStateOf<List<DBAccountProject>>(emptyList())
var isCreatingRemoteProject by mutableStateOf(false) var isCreatingRemoteProject by mutableStateOf(false)
var errorDialogMessage by mutableStateOf<String?>(null) var errorDialogMessage by mutableStateOf<String?>(null)
@@ -3,8 +3,8 @@ package net.helcel.cowspent.android.project.edit
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.widget.Toast import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@@ -13,17 +13,16 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import net.helcel.cowspent.R import net.helcel.cowspent.R
import net.helcel.cowspent.android.helper.showToast import net.helcel.cowspent.android.helper.showToast
import net.helcel.cowspent.android.main.MainConstants
import net.helcel.cowspent.model.DBProject import net.helcel.cowspent.model.DBProject
import net.helcel.cowspent.persistence.CowspentSQLiteOpenHelper import net.helcel.cowspent.persistence.CowspentSQLiteOpenHelper
import net.helcel.cowspent.theme.ThemeUtils import net.helcel.cowspent.theme.ThemeUtils
import net.helcel.cowspent.util.ICallback import net.helcel.cowspent.util.ICallback
import net.helcel.cowspent.util.SupportUtil
import net.helcel.cowspent.android.main.MainConstants
class EditProjectActivity : AppCompatActivity() { class EditProjectActivity : AppCompatActivity() {
private val viewModel: EditProjectViewModel by viewModels() internal val viewModel: EditProjectViewModel by viewModels()
private lateinit var db: CowspentSQLiteOpenHelper private lateinit var db: CowspentSQLiteOpenHelper
private lateinit var project: DBProject private lateinit var project: DBProject
@@ -56,39 +55,44 @@ class EditProjectActivity : AppCompatActivity() {
} }
private fun onSave() { private fun onSave() {
when (viewModel.validate()) {
EditProjectViewModel.ValidationError.EMPTY_NAME -> {
showToast(this, getString(R.string.error_invalid_project_name), Toast.LENGTH_LONG)
return
}
EditProjectViewModel.ValidationError.INVALID_EMAIL -> {
showToast(this, getString(R.string.error_invalid_email), Toast.LENGTH_LONG)
return
}
null -> Unit
}
val changes = viewModel.changesFrom(project)
if (!changes.any) {
showToast(this, getString(R.string.project_edition_no_change), Toast.LENGTH_LONG)
return
}
val currentPwd = viewModel.password val currentPwd = viewModel.password
val newPwd = viewModel.newPassword val newPwd = viewModel.newPassword
val newName = viewModel.name val newName = viewModel.name
val newEmail = viewModel.email val newEmail = viewModel.email
if (newName.isEmpty()) { val nameChanged = changes.name
showToast(this, getString(R.string.error_invalid_project_name), Toast.LENGTH_LONG) val emailChanged = changes.email
return val pwdChanged = changes.newPassword
} val currentPwdChanged = changes.currentPassword
if (newEmail.isNotEmpty() && !SupportUtil.isValidEmail(newEmail)) {
showToast(this, getString(R.string.error_invalid_email), Toast.LENGTH_LONG)
return
}
val nameChanged = newName != project.name
val emailChanged = newEmail != project.email
val pwdChanged = newPwd != project.password
val currentPwdChanged = currentPwd != project.password
if (!nameChanged && !emailChanged && !pwdChanged && !currentPwdChanged) {
showToast(this, getString(R.string.project_edition_no_change), Toast.LENGTH_LONG)
return
}
if (project.isLocal) { if (project.isLocal) {
val targetPwd = if (pwdChanged) newPwd else currentPwd val targetPwd = if (pwdChanged) newPwd else currentPwd
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
db.updateProject( db.updateProject(
project.id, newName, newEmail, targetPwd, projId = project.id,
null, project.type, null, newName = newName,
null, null, newEmail = newEmail,
null, null newPassword = targetPwd,
projectType = project.type
) )
} }
closeOnEdit(project.id) closeOnEdit(project.id)
@@ -103,18 +107,21 @@ class EditProjectActivity : AppCompatActivity() {
project.password = currentPwd project.password = currentPwd
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
db.updateProject(project.id, null, null, currentPwd, null, project.type, null, null, null, null, null) db.updateProject(
projId = project.id,
newPassword = currentPwd,
projectType = project.type
)
} }
} }
} }
if (!db.cowspentServerSyncHelper.editRemoteProject( if (!db.cowspentServerSyncHelper.editRemoteProject(
project.id, projId = project.id,
newName, newName = newName,
newEmail, newEmail = newEmail,
if (pwdChanged) newPwd else null, newPassword = if (pwdChanged) newPwd else null,
null, callback = editCallBack
editCallBack
) )
) { ) {
showToast(this, getString(R.string.remote_project_operation_no_network), Toast.LENGTH_LONG) showToast(this, getString(R.string.remote_project_operation_no_network), Toast.LENGTH_LONG)
@@ -124,10 +131,9 @@ class EditProjectActivity : AppCompatActivity() {
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
db.updateProject( db.updateProject(
project.id, null, null, currentPwd, projId = project.id,
null, project.type, null, newPassword = currentPwd,
null, null, projectType = project.type
null, null
) )
} }
closeOnEdit(project.id) closeOnEdit(project.id)
@@ -7,6 +7,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import net.helcel.cowspent.android.helper.DialogState import net.helcel.cowspent.android.helper.DialogState
import net.helcel.cowspent.model.DBProject import net.helcel.cowspent.model.DBProject
import net.helcel.cowspent.util.SupportUtil
class EditProjectViewModel : ViewModel() { class EditProjectViewModel : ViewModel() {
var name by mutableStateOf("") var name by mutableStateOf("")
@@ -17,6 +18,31 @@ class EditProjectViewModel : ViewModel() {
var dialogState by mutableStateOf<DialogState?>(null) var dialogState by mutableStateOf<DialogState?>(null)
enum class ValidationError { EMPTY_NAME, INVALID_EMAIL }
fun validate(): ValidationError? = when {
name.isBlank() -> ValidationError.EMPTY_NAME
email.isNotEmpty() && !SupportUtil.isValidEmail(email) -> ValidationError.INVALID_EMAIL
else -> null
}
data class Changes(
val name: Boolean,
val email: Boolean,
val newPassword: Boolean,
val currentPassword: Boolean
) {
val any: Boolean get() = name || email || newPassword || currentPassword
}
fun changesFrom(project: DBProject) = Changes(
name = name != project.name,
// initFromProject maps a null or "null" email to "", so treat those as unchanged
email = email != project.email && !(email.isEmpty() && project.email == null),
newPassword = newPassword != project.password,
currentPassword = password != project.password
)
fun showDialog( fun showDialog(
title: String? = null, title: String? = null,
message: String? = null, message: String? = null,
@@ -12,6 +12,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardCapitalization
@@ -100,6 +101,7 @@ fun MemberEditDialogContent(
.fillMaxWidth() .fillMaxWidth()
.clickable { isActivated = !isActivated } .clickable { isActivated = !isActivated }
.padding(vertical = 8.dp) .padding(vertical = 8.dp)
.testTag("member_activated_row")
) { ) {
Icon( Icon(
imageVector = Icons.Default.Block, imageVector = Icons.Default.Block,
@@ -22,7 +22,7 @@ import net.helcel.cowspent.theme.ThemeUtils
class MemberManagementActivity : AppCompatActivity() { class MemberManagementActivity : AppCompatActivity() {
private val viewModel: MemberManagementViewModel by viewModels() internal val viewModel: MemberManagementViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge() enableEdgeToEdge()
@@ -20,6 +20,7 @@ import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.RadioButton import androidx.compose.material.RadioButton
import androidx.compose.material.Scaffold import androidx.compose.material.Scaffold
import androidx.compose.material.Slider
import androidx.compose.material.Switch import androidx.compose.material.Switch
import androidx.compose.material.SwitchDefaults import androidx.compose.material.SwitchDefaults
import androidx.compose.material.Text import androidx.compose.material.Text
@@ -30,6 +31,7 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.AccountCircle import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.Archive import androidx.compose.material.icons.filled.Archive
import androidx.compose.material.icons.filled.Brightness2 import androidx.compose.material.icons.filled.Brightness2
import androidx.compose.material.icons.filled.Group
import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.Palette import androidx.compose.material.icons.filled.Palette
import androidx.compose.material.icons.filled.Sync import androidx.compose.material.icons.filled.Sync
@@ -49,13 +51,16 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import kotlin.math.roundToInt
import androidx.core.content.edit import androidx.core.content.edit
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import net.helcel.cowspent.R import net.helcel.cowspent.R
import net.helcel.cowspent.android.helper.ColorPicker import net.helcel.cowspent.android.helper.ColorPicker
import net.helcel.cowspent.persistence.CowspentSQLiteOpenHelper import net.helcel.cowspent.persistence.CowspentSQLiteOpenHelper
import net.helcel.cowspent.persistence.CowspentServerSyncHelper
import net.helcel.cowspent.util.ColorUtils import net.helcel.cowspent.util.ColorUtils
import net.helcel.cowspent.util.Cowspent import net.helcel.cowspent.util.Cowspent
import net.helcel.cowspent.util.SyncSettings
@Composable @Composable
fun SettingsScreen( fun SettingsScreen(
@@ -80,22 +85,31 @@ fun SettingsScreen(
val keyOfflineMode = stringResource(R.string.pref_key_offline_mode) val keyOfflineMode = stringResource(R.string.pref_key_offline_mode)
val keyShowArchived = stringResource(R.string.pref_key_show_archived) val keyShowArchived = stringResource(R.string.pref_key_show_archived)
val keyBetaFeatures = stringResource(R.string.pref_key_beta_features) val keyBetaFeatures = stringResource(R.string.pref_key_beta_features)
val keyStatsIncludeDeactivated = stringResource(R.string.pref_key_stats_include_deactivated)
val keyAutoSyncOnOpen = stringResource(R.string.pref_key_auto_sync_on_open)
val keyFillNewBillFromLast = stringResource(R.string.pref_key_fill_new_bill_from_last)
val keyLastAccountSync = stringResource(R.string.pref_key_last_account_sync_timestamp)
val isNextcloudConfigured = CowspentServerSyncHelper.isNextcloudAccountConfigured(context)
// States for preferences // States for preferences
var nightMode by remember(keyNightMode) { var nightMode by remember(keyNightMode) {
mutableStateOf(sharedPreferences.getString(keyNightMode, "-1") ?: "-1") mutableStateOf(sharedPreferences.getString(keyNightMode, "-1") ?: "-1")
} }
var colorMode by remember(keyColorMode, keyUseServerColor, keyUseSystemColor) { var colorMode by remember(keyColorMode, keyUseServerColor, keyUseSystemColor, isNextcloudConfigured) {
mutableStateOf(sharedPreferences.getString(keyColorMode, null) ?: run { val savedMode = sharedPreferences.getString(keyColorMode, null)
val useServer = sharedPreferences.getBoolean(keyUseServerColor, true) val mode = savedMode ?: run {
val useServer = sharedPreferences.getBoolean(keyUseServerColor, false)
val useSystem = sharedPreferences.getBoolean(keyUseSystemColor, true) val useSystem = sharedPreferences.getBoolean(keyUseSystemColor, true)
when { when {
useServer -> "server" useServer && isNextcloudConfigured -> "server"
useSystem -> "system" useSystem -> "system"
else -> "manual" else -> "manual"
} }
}) }
// Fallback to system if server is selected but not configured
mutableStateOf(if (mode == "server" && !isNextcloudConfigured) "system" else mode)
} }
// Apply theme globally only when leaving settings to avoid flickering/restarts during selection // Apply theme globally only when leaving settings to avoid flickering/restarts during selection
@@ -117,6 +131,24 @@ fun SettingsScreen(
var betaFeatures by remember(keyBetaFeatures) { var betaFeatures by remember(keyBetaFeatures) {
mutableStateOf(sharedPreferences.getBoolean(keyBetaFeatures, false)) mutableStateOf(sharedPreferences.getBoolean(keyBetaFeatures, false))
} }
var fillNewBillFromLast by remember(keyFillNewBillFromLast) {
mutableStateOf(sharedPreferences.getBoolean(keyFillNewBillFromLast, false))
}
var statsIncludeDeactivated by remember(keyStatsIncludeDeactivated) {
mutableStateOf(sharedPreferences.getBoolean(keyStatsIncludeDeactivated, false))
}
val syncIntervals = SyncSettings.INTERVAL_CHOICES_MINUTES
val syncIntervalLabels = listOf(
stringResource(R.string.pref_value_sync_1m),
stringResource(R.string.pref_value_sync_10m),
stringResource(R.string.pref_value_sync_1h),
stringResource(R.string.pref_value_sync_1d)
)
var syncInterval by remember(keyAutoSyncOnOpen) {
mutableIntStateOf(SyncSettings.intervalMinutes(context))
}
Scaffold( Scaffold(
topBar = { topBar = {
@@ -124,7 +156,7 @@ fun SettingsScreen(
title = { Text(stringResource(R.string.action_settings)) }, title = { Text(stringResource(R.string.action_settings)) },
navigationIcon = { navigationIcon = {
IconButton(onClick = onBack) { IconButton(onClick = onBack) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
} }
}, },
backgroundColor = MaterialTheme.colors.primary, backgroundColor = MaterialTheme.colors.primary,
@@ -181,15 +213,19 @@ fun SettingsScreen(
} }
) )
val colorModeEntries = buildMap {
put("system", stringResource(R.string.pref_value_color_system))
if (isNextcloudConfigured) {
put("server", stringResource(R.string.pref_value_color_server))
}
put("manual", stringResource(R.string.pref_value_color_manual))
}
SettingsListPreference( SettingsListPreference(
title = stringResource(R.string.settings_color_mode), title = stringResource(R.string.settings_color_mode),
icon = Icons.Default.Palette, icon = Icons.Default.Palette,
value = colorMode, value = colorMode,
entries = mapOf( entries = colorModeEntries,
"system" to stringResource(R.string.pref_value_color_system),
"server" to stringResource(R.string.pref_value_color_server),
"manual" to stringResource(R.string.pref_value_color_manual)
),
onValueChange = { mode -> onValueChange = { mode ->
colorMode = mode colorMode = mode
sharedPreferences.edit { sharedPreferences.edit {
@@ -259,6 +295,51 @@ fun SettingsScreen(
} }
) )
if (betaFeatures) {
SettingsSwitchPreference(
title = stringResource(R.string.settings_fill_new_bill_from_last),
summary = stringResource(R.string.settings_fill_new_bill_from_last_summary),
icon = Icons.Default.Info,
checked = fillNewBillFromLast,
onCheckedChange = {
fillNewBillFromLast = it
sharedPreferences.edit {
putBoolean(keyFillNewBillFromLast, it)
}
}
)
SettingsSwitchPreference(
title = stringResource(R.string.settings_stats_include_deactivated),
icon = Icons.Default.Group,
checked = statsIncludeDeactivated,
onCheckedChange = {
statsIncludeDeactivated = it
sharedPreferences.edit {
putBoolean(keyStatsIncludeDeactivated, it)
}
}
)
SettingsSliderPreference(
title = stringResource(R.string.settings_auto_sync_on_open),
summary = stringResource(R.string.settings_auto_sync_on_open_summary),
icon = Icons.Default.Sync,
value = syncInterval,
values = syncIntervals,
labels = syncIntervalLabels,
onValueChange = { newInterval ->
// Slider reports every drag delta, not just the snapped steps.
if (newInterval != syncInterval) {
syncInterval = newInterval
sharedPreferences.edit {
putInt(keyAutoSyncOnOpen, newInterval)
}
}
}
)
}
SettingsPreference( SettingsPreference(
title = stringResource(R.string.title_about), title = stringResource(R.string.title_about),
icon = Icons.Default.Info, icon = Icons.Default.Info,
@@ -372,13 +453,7 @@ fun SettingsListPreference(
), ),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
RadioButton( RadioButton(selected = (key == value), onClick = null)
selected = (key == value),
onClick = {
onValueChange(key)
showDialog = false
}
)
Spacer(Modifier.width(8.dp)) Spacer(Modifier.width(8.dp))
Text(text = label) Text(text = label)
} }
@@ -441,6 +516,47 @@ fun SettingsColorPreference(
} }
} }
@Composable
fun SettingsSliderPreference(
title: String,
summary: String? = null,
icon: Any? = null,
value: Int,
values: List<Int>,
labels: List<String>,
onValueChange: (Int) -> Unit
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp, 8.dp)
) {
Row(verticalAlignment = Alignment.CenterVertically) {
SettingsIcon(icon)
Spacer(modifier = Modifier.width(32.dp))
Column(modifier = Modifier.weight(1f)) {
Text(text = title, style = MaterialTheme.typography.subtitle1)
if (summary != null) {
Text(text = summary, style = MaterialTheme.typography.caption)
}
}
}
val currentIndex = values.indexOf(value).coerceAtLeast(0)
val steps = (values.size - 2).coerceAtLeast(0)
Column(modifier = Modifier.padding(start = 56.dp, top = 8.dp)) {
Slider(
value = currentIndex.toFloat(),
onValueChange = { onValueChange(values[it.roundToInt()]) },
valueRange = 0f..(values.size - 1).toFloat(),
steps = steps
)
Text(text = labels[currentIndex], style = MaterialTheme.typography.caption, fontWeight = FontWeight.Bold, color = MaterialTheme.colors.primary)
}
}
}
@Composable @Composable
fun SettingsIcon(icon: Any?) { fun SettingsIcon(icon: Any?) {
Box(modifier = Modifier.size(24.dp), contentAlignment = Alignment.Center) { Box(modifier = Modifier.size(24.dp), contentAlignment = Alignment.Center) {
@@ -121,17 +121,19 @@ fun ProjectSankeyDiagram(
val catMap = mutableMapOf<Long, Double>() val catMap = mutableMapOf<Long, Double>()
activeBills.forEach { bill -> activeBills.forEach { bill ->
val totalWeight = bill.billOwers.sumOf { membersMap[it.memberId]?.weight ?: 1.0 } val totalWeight = bill.billOwers.sumOf { membersMap[it.memberId]?.weight ?: 0.0 }
if (totalWeight > 0) { if (totalWeight > 0) {
if (selectedMemberId == -1L) { if (selectedMemberId == -1L) {
catMap[bill.categoryId] = (catMap[bill.categoryId] ?: 0.0) + bill.amount catMap[bill.categoryId] = (catMap[bill.categoryId] ?: 0.0) + bill.amount
bill.billOwers.forEach { bo -> bill.billOwers.forEach { bo ->
val weight = membersMap[bo.memberId]?.weight ?: 1.0 if (membersMap.containsKey(bo.memberId)) {
spentMap[bo.memberId] = (spentMap[bo.memberId] ?: 0.0) + (bill.amount / totalWeight) * weight val weight = membersMap[bo.memberId]?.weight ?: 0.0
spentMap[bo.memberId] = (spentMap[bo.memberId] ?: 0.0) + (bill.amount / totalWeight) * weight
}
} }
} else { } else {
bill.billOwers.find { it.memberId == selectedMemberId }?.let { bo -> bill.billOwers.find { it.memberId == selectedMemberId }?.let { bo ->
val weight = membersMap[bo.memberId]?.weight ?: 1.0 val weight = membersMap[bo.memberId]?.weight ?: 0.0
catMap[bill.categoryId] = (catMap[bill.categoryId] ?: 0.0) + (bill.amount / totalWeight) * weight catMap[bill.categoryId] = (catMap[bill.categoryId] ?: 0.0) + (bill.amount / totalWeight) * weight
spentMap[selectedMemberId] = (spentMap[selectedMemberId] ?: 0.0) + (bill.amount / totalWeight) * weight spentMap[selectedMemberId] = (spentMap[selectedMemberId] ?: 0.0) + (bill.amount / totalWeight) * weight
} }
@@ -344,7 +346,9 @@ private fun SankeyContent(
scope.launch { topFocalIndex.animateTo(index.toFloat(), spring(Spring.DampingRatioLowBouncy, Spring.StiffnessLow)) } scope.launch { topFocalIndex.animateTo(index.toFloat(), spring(Spring.DampingRatioLowBouncy, Spring.StiffnessLow)) }
} else Modifier), contentAlignment = Alignment.Center) { } else Modifier), contentAlignment = Alignment.Center) {
Column(modifier = Modifier.fillMaxSize().background(color = member?.let { Color(it.r ?: 128, it.g ?: 128, it.b ?: 128) } ?: Color.Gray, shape = RoundedCornerShape(10.dp)), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) { Column(modifier = Modifier.fillMaxSize().background(color = member?.let { Color(it.r ?: 128, it.g ?: 128, it.b ?: 128) } ?: Color.Gray, shape = RoundedCornerShape(10.dp)), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) {
Text(text = member?.name ?: "???", color = Color.White, fontWeight = FontWeight.Bold, maxLines = 1, overflow = TextOverflow.Ellipsis, textAlign = TextAlign.Center, modifier = Modifier.wrapContentWidth(unbounded = true)) if (wDp >= 32.dp) {
Text(text = member?.name ?: "???", color = Color.White, fontWeight = FontWeight.Bold, maxLines = 1, overflow = TextOverflow.Ellipsis, textAlign = TextAlign.Center, modifier = Modifier.wrapContentWidth(unbounded = true))
}
if (wDp >= 40.dp) Text(text = formatShortValue(amount), fontSize = 12.sp, color = Color.White.copy(alpha = 0.9f), textAlign = TextAlign.Center) if (wDp >= 40.dp) Text(text = formatShortValue(amount), fontSize = 12.sp, color = Color.White.copy(alpha = 0.9f), textAlign = TextAlign.Center)
} }
} }
@@ -382,7 +386,9 @@ private fun SankeyContent(
scope.launch { bottomFocalIndex.animateTo(index.toFloat(), spring(Spring.DampingRatioLowBouncy, Spring.StiffnessLow)) } scope.launch { bottomFocalIndex.animateTo(index.toFloat(), spring(Spring.DampingRatioLowBouncy, Spring.StiffnessLow)) }
} else Modifier), contentAlignment = Alignment.Center) { } else Modifier), contentAlignment = Alignment.Center) {
Column(modifier = Modifier.fillMaxSize().background(color = category?.color?.let { try { Color(it.toColorInt()) } catch (_: Exception) { Color(0xFF999999) } } ?: Color(0xFF999999), shape = RoundedCornerShape(10.dp)), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) { Column(modifier = Modifier.fillMaxSize().background(color = category?.color?.let { try { Color(it.toColorInt()) } catch (_: Exception) { Color(0xFF999999) } } ?: Color(0xFF999999), shape = RoundedCornerShape(10.dp)), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) {
Text(text = category?.icon ?: "", fontSize = 20.sp, textAlign = TextAlign.Center, modifier = Modifier.wrapContentWidth(unbounded = true)) if (wDp >= 24.dp) {
Text(text = category?.icon ?: "", fontSize = 20.sp, textAlign = TextAlign.Center, modifier = Modifier.wrapContentWidth(unbounded = true))
}
if (wDp >= 40.dp) Text(text = formatShortValue(amount), fontSize = 12.sp, color = Color.White.copy(alpha = 0.9f), textAlign = TextAlign.Center) if (wDp >= 40.dp) Text(text = formatShortValue(amount), fontSize = 12.sp, color = Color.White.copy(alpha = 0.9f), textAlign = TextAlign.Center)
} }
} }
@@ -47,7 +47,7 @@ class ProjectStatisticsActivity : AppCompatActivity() {
} }
companion object { companion object {
private const val EXTRA_PROJECT_ID = "extra_project_id" internal const val EXTRA_PROJECT_ID = "extra_project_id"
fun createIntent(context: Context, projectId: Long): Intent { fun createIntent(context: Context, projectId: Long): Intent {
return Intent(context, ProjectStatisticsActivity::class.java).apply { return Intent(context, ProjectStatisticsActivity::class.java).apply {
@@ -40,6 +40,8 @@ fun ProjectStatisticsScreen(
"Sankey" "Sankey"
) )
val keyStatsIncludeDeactivated = stringResource(R.string.pref_key_stats_include_deactivated)
Scaffold( Scaffold(
topBar = { topBar = {
TopAppBar( TopAppBar(
@@ -103,7 +105,11 @@ fun ProjectStatisticsScreen(
val bills = db.getBillsOfProject(proj.id) val bills = db.getBillsOfProject(proj.id)
val categories = db.getCategories(proj.id) val categories = db.getCategories(proj.id)
val paymentModes = db.getPaymentModes(proj.id) val paymentModes = db.getPaymentModes(proj.id)
StatisticsData(members, bills, categories, paymentModes)
val includeDeactivated = prefs.getBoolean(keyStatsIncludeDeactivated, false)
val filteredMembers = if (includeDeactivated) members else members.filter { it.isActivated }
StatisticsData(filteredMembers, bills, categories, paymentModes)
} }
} }
@@ -3,8 +3,8 @@ package net.helcel.cowspent.android.statistics
import android.app.DatePickerDialog import android.app.DatePickerDialog
import android.content.Context import android.content.Context
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.verticalScroll
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.* import androidx.compose.material.icons.filled.*
@@ -285,9 +285,18 @@ fun ProjectStatisticsTable(
Spacer(modifier = Modifier.height(4.dp)) Spacer(modifier = Modifier.height(4.dp))
LazyColumn(modifier = Modifier.weight(1f)) { Column(
items(stats.memberStats) { m -> modifier = Modifier
Row(modifier = Modifier.fillMaxWidth().padding(vertical = 12.dp, horizontal = 8.dp), verticalAlignment = Alignment.CenterVertically) { .weight(1f)
.verticalScroll(rememberScrollState())
) {
stats.memberStats.forEach { m ->
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 12.dp, horizontal = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(m.name, modifier = Modifier.weight(2f), color = MaterialTheme.colors.onSurface, fontWeight = FontWeight.Medium) Text(m.name, modifier = Modifier.weight(2f), color = MaterialTheme.colors.onSurface, fontWeight = FontWeight.Medium)
Text( Text(
@@ -12,7 +12,6 @@ enum class ProjectType(val id: String) {
} }
} }
@JvmStatic
fun getTypeById(id: String?): ProjectType? { fun getTypeById(id: String?): ProjectType? {
return reverseMap[id] return reverseMap[id]
} }
@@ -7,6 +7,7 @@ import android.database.Cursor
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper import android.database.sqlite.SQLiteOpenHelper
import android.text.TextUtils import android.text.TextUtils
import androidx.annotation.VisibleForTesting
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import net.helcel.cowspent.R import net.helcel.cowspent.R
@@ -271,12 +272,18 @@ class CowspentSQLiteOpenHelper private constructor(val context: Context) :
} }
fun updateProject( fun updateProject(
projId: Long, newName: String?, newEmail: String?, projId: Long,
newPassword: String?, newLastPayerId: Long?, newName: String? = null,
newLastSyncedTimestamp: Long?, newEmail: String? = null,
newCurrencyName: String?, newDeletionDisabled: Boolean?, newPassword: String? = null,
newMyAccessLevel: Int?, newBearerToken: String?, newLastPayerId: Long? = null,
newArchivedTs: Long? = null newLastSyncedTimestamp: Long? = null,
newCurrencyName: String? = null,
newDeletionDisabled: Boolean? = null,
newMyAccessLevel: Int? = null,
newBearerToken: String? = null,
newArchivedTs: Long? = null,
projectType: ProjectType? = null
) { ) {
val db = writableDatabase val db = writableDatabase
val values = ContentValues() val values = ContentValues()
@@ -290,47 +297,7 @@ class CowspentSQLiteOpenHelper private constructor(val context: Context) :
if (newDeletionDisabled != null) values.put(key_deletionDisabled, if (newDeletionDisabled) 1 else 0) if (newDeletionDisabled != null) values.put(key_deletionDisabled, if (newDeletionDisabled) 1 else 0)
if (newMyAccessLevel != null) values.put(key_myAccessLevel, newMyAccessLevel) if (newMyAccessLevel != null) values.put(key_myAccessLevel, newMyAccessLevel)
if (newArchivedTs != null) values.put(key_archived, newArchivedTs) if (newArchivedTs != null) values.put(key_archived, newArchivedTs)
if (values.size() > 0) { if (projectType != null) values.put(key_type, projectType.id)
db.update(table_projects, values, "$key_id = ?", arrayOf(projId.toString()))
}
}
fun updateProject(
projId: Long, newName: String?, newEmail: String?,
newPassword: String?, newLastPayerId: Long?,
projectType: ProjectType, newLastSyncedTimestamp: Long?,
newCurrencyName: String?, newDeletionDisabled: Boolean?,
newMyAccessLevel: Int?, newBearerToken: String?,
newArchivedTs: Long? = null
) {
val db = writableDatabase
updateProject(
projId, newName, newEmail, newPassword, newLastPayerId, projectType,
newLastSyncedTimestamp, newCurrencyName, newDeletionDisabled, newMyAccessLevel,
newBearerToken, newArchivedTs, db
)
}
private fun updateProject(
projId: Long, newName: String?, newEmail: String?,
newPassword: String?, newLastPayerId: Long?,
projectType: ProjectType, newLastSyncedTimestamp: Long?,
newCurrencyName: String?, newDeletionDisabled: Boolean?,
newMyAccessLevel: Int?, newBearerToken: String?,
newArchivedTs: Long?, db: SQLiteDatabase
) {
val values = ContentValues()
if (newName != null) values.put(key_name, newName)
if (newEmail != null) values.put(key_email, newEmail)
if (newPassword != null) SecureStorage.savePasswordSync(context, "ProjectPassword_$projId", newPassword)
if (newBearerToken != null) values.put(key_bearer_token, newBearerToken)
if (newLastPayerId != null) values.put(key_lastPayerId, newLastPayerId)
if (newLastSyncedTimestamp != null) values.put(key_lastSyncTimestamp, newLastSyncedTimestamp)
if (newCurrencyName != null) values.put(key_currencyName, newCurrencyName)
if (newDeletionDisabled != null) values.put(key_deletionDisabled, if (newDeletionDisabled) 1 else 0)
if (newMyAccessLevel != null) values.put(key_myAccessLevel, newMyAccessLevel)
if (newArchivedTs != null) values.put(key_archived, newArchivedTs)
values.put(key_type, projectType.id)
if (values.size() > 0) { if (values.size() > 0) {
db.update(table_projects, values, "$key_id = ?", arrayOf(projId.toString())) db.update(table_projects, values, "$key_id = ?", arrayOf(projId.toString()))
} }
@@ -424,8 +391,8 @@ class CowspentSQLiteOpenHelper private constructor(val context: Context) :
fun getActivatedMembersOfProject(projId: Long): List<DBMember> { fun getActivatedMembersOfProject(projId: Long): List<DBMember> {
return getMembersCustom( return getMembersCustom(
"$key_projectid = ? AND $key_activated = 1", "$key_projectid = ? AND $key_activated = 1 AND $key_state != ?",
arrayOf(projId.toString()), arrayOf(projId.toString(), DBBill.STATE_DELETED.toString()),
"$key_name ASC" "$key_name ASC"
) )
} }
@@ -591,74 +558,67 @@ class CowspentSQLiteOpenHelper private constructor(val context: Context) :
return if (bills.isEmpty()) null else bills[0] return if (bills.isEmpty()) null else bills[0]
} }
fun getLastBillOfProject(projectId: Long): DBBill? {
val list = getBillsCustom(
"$key_projectid = ? AND $key_state != ?",
arrayOf(projectId.toString(), DBBill.STATE_DELETED.toString()),
"$key_id DESC LIMIT 1"
)
return if (list.isEmpty()) null else list[0]
}
@WorkerThread @WorkerThread
fun searchBills(query: CharSequence?, projectId: Long): List<DBBill> { fun searchBills(query: CharSequence?, projectId: Long): List<DBBill> {
val andWhere: MutableList<String> = ArrayList() val andWhere: MutableList<String> = ArrayList()
val args: MutableList<String> = ArrayList() val args: MutableList<String> = ArrayList()
andWhere.add("($key_projectid = $projectId)") andWhere.add("($key_projectid = ?)")
args.add(projectId.toString())
andWhere.add("($key_state != ${DBBill.STATE_DELETED})") andWhere.add("($key_state != ${DBBill.STATE_DELETED})")
if (query != null) {
args.add("%$query%") val terms = query?.toString()?.split("\\s+".toRegex())?.filter { it.isNotEmpty() }.orEmpty()
var whereStr = "($key_what LIKE ?" if (terms.isNotEmpty()) {
if (SupportUtil.isDouble(query.toString())) { val memberIdsByName = getMembersOfProject(projectId, null)
whereStr += " OR ($key_amount <= (? + 10) AND $key_amount >= (? - 10))" .associateBy({ it.name.lowercase(Locale.ROOT) }, { it.id })
args.add(query.toString()) // Every clause appends its arguments as it is built, so args stay in the same order
args.add(query.toString()) // as the placeholders they bind to.
for (term in terms) {
andWhere.add(memberClause(term, memberIdsByName, args) ?: textClause(term, args))
} }
val members = getMembersOfProject(projectId, null)
val memberNames: MutableList<String> = ArrayList()
val memberIds: MutableList<Long> = ArrayList()
for (m in members) {
memberNames.add(m.name.lowercase(Locale.ROOT))
memberIds.add(m.id)
}
val queryStr = query.toString()
val words = queryStr.split("\\s+".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
var nameSql = ""
for (word in words) {
if (word.startsWith("+")) {
val nameQuery = word.replace("^\\+".toRegex(), "")
val memberIndex = memberNames.indexOf(nameQuery.lowercase(Locale.ROOT))
if (memberIndex != -1) {
val searchMemberId = memberIds[memberIndex]
nameSql += "($key_payer_id=?) AND "
args.add(searchMemberId.toString())
}
}
if (word.startsWith("-")) {
val nameQuery = word.replace("^-".toRegex(), "")
val memberIndex = memberNames.indexOf(nameQuery.lowercase(Locale.ROOT))
if (memberIndex != -1) {
val searchMemberId = memberIds[memberIndex]
val joinOwer = "select $table_bills.$key_id from $table_bills inner join $table_billowers " +
"where $key_member_id=? and $table_bills.$key_id=$table_billowers.$key_billId"
nameSql += "($key_id IN ($joinOwer)) AND "
args.add(searchMemberId.toString())
}
}
if (word.startsWith("@")) {
val nameQuery = word.replace("^@".toRegex(), "")
val memberIndex = memberNames.indexOf(nameQuery.lowercase(Locale.ROOT))
if (memberIndex != -1) {
val searchMemberId = memberIds[memberIndex]
nameSql += "( ($key_payer_id=?) OR "
args.add(searchMemberId.toString())
val joinOwer = "select $table_bills.$key_id from $table_bills inner join $table_billowers " +
"where $key_member_id=? and $table_bills.$key_id=$table_billowers.$key_billId"
nameSql += "($key_id IN ($joinOwer)) ) AND "
args.add(searchMemberId.toString())
}
}
}
if (nameSql != "") {
nameSql = nameSql.replace(" AND $".toRegex(), "")
whereStr += " OR ($nameSql)"
}
whereStr += ")"
andWhere.add(whereStr)
} }
val order = "$key_timestamp DESC" return getBillsCustom(TextUtils.join(" AND ", andWhere), args.toTypedArray(), "$key_timestamp DESC")
return getBillsCustom(TextUtils.join(" AND ", andWhere), args.toTypedArray(), order) }
/** Clause for a `+name`/`-name`/`@name` term, or null when the term names no member. */
private fun memberClause(term: String, memberIdsByName: Map<String, Long>, args: MutableList<String>): String? {
val prefix = term.first()
if (prefix != '+' && prefix != '-' && prefix != '@') return null
val memberId = memberIdsByName[term.substring(1).lowercase(Locale.ROOT)] ?: return null
val owedByMember = "SELECT $table_bills.$key_id FROM $table_bills INNER JOIN $table_billowers " +
"WHERE $key_member_id = ? AND $table_bills.$key_id = $table_billowers.$key_billId"
args.add(memberId.toString())
return when (prefix) {
'+' -> "($key_payer_id = ?)"
'-' -> "($key_id IN ($owedByMember))"
else -> {
args.add(memberId.toString())
"(($key_payer_id = ?) OR ($key_id IN ($owedByMember)))"
}
}
}
/** Clause matching a free text term against the description, the comment and the amount. */
private fun textClause(term: String, args: MutableList<String>): String {
val needle = "%" + term.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_") + "%"
args.add(needle)
args.add(needle)
var clause = "(($key_what LIKE ? ESCAPE '\\') OR ($key_comment LIKE ? ESCAPE '\\')"
if (SupportUtil.isDouble(term)) {
clause += " OR ($key_amount <= (? + $AMOUNT_SEARCH_TOLERANCE) AND " +
"$key_amount >= (? - $AMOUNT_SEARCH_TOLERANCE))"
args.add(term)
args.add(term)
}
return "$clause)"
} }
@WorkerThread @WorkerThread
@@ -1265,6 +1225,9 @@ class CowspentSQLiteOpenHelper private constructor(val context: Context) :
) )
private const val default_order = "$key_id DESC" private const val default_order = "$key_id DESC"
/** Half width of the window a numeric search term matches, in project currency. */
private const val AMOUNT_SEARCH_TOLERANCE = 10
@Volatile @Volatile
private var instance: CowspentSQLiteOpenHelper? = null private var instance: CowspentSQLiteOpenHelper? = null
@@ -1274,5 +1237,15 @@ class CowspentSQLiteOpenHelper private constructor(val context: Context) :
instance ?: CowspentSQLiteOpenHelper(context.applicationContext).also { instance = it } instance ?: CowspentSQLiteOpenHelper(context.applicationContext).also { instance = it }
} }
} }
@VisibleForTesting
fun setInstance(helper: CowspentSQLiteOpenHelper?) {
instance = helper
}
@VisibleForTesting
fun resetInstance() {
instance = null
}
} }
} }
@@ -1,13 +1,11 @@
package net.helcel.cowspent.persistence package net.helcel.cowspent.persistence
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.ServiceConnection
import android.content.SharedPreferences import android.content.SharedPreferences
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.os.IBinder
import android.util.Log import android.util.Log
import androidx.annotation.VisibleForTesting
import androidx.core.content.edit import androidx.core.content.edit
import androidx.core.graphics.toColorInt import androidx.core.graphics.toColorInt
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
@@ -29,6 +27,7 @@ import net.helcel.cowspent.android.account.AccountActivity
import net.helcel.cowspent.android.main.BillsListViewActivity import net.helcel.cowspent.android.main.BillsListViewActivity
import net.helcel.cowspent.android.main.MainConstants import net.helcel.cowspent.android.main.MainConstants
import net.helcel.cowspent.model.DBBill import net.helcel.cowspent.model.DBBill
import net.helcel.cowspent.model.DBMember
import net.helcel.cowspent.model.DBProject import net.helcel.cowspent.model.DBProject
import net.helcel.cowspent.model.ProjectType import net.helcel.cowspent.model.ProjectType
import net.helcel.cowspent.util.CospendClientUtil.LoginStatus import net.helcel.cowspent.util.CospendClientUtil.LoginStatus
@@ -48,24 +47,6 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
private val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(dbHelper.context) private val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(dbHelper.context)
private var networkConnected = false private var networkConnected = false
private val certService = object : ServiceConnection {
override fun onServiceConnected(componentName: ComponentName, iBinder: IBinder) {
if (isSyncPossible) {
val lastId = PreferenceManager.getDefaultSharedPreferences(dbHelper.context).getLong("selected_project", 0)
if (lastId != 0L) {
val proj = dbHelper.getProject(lastId)
if (proj != null) {
appContext.sendBroadcast(Intent(MainConstants.BROADCAST_SYNC_PROJECT))
appContext.sendBroadcast(Intent(MainConstants.BROADCAST_NETWORK_AVAILABLE))
}
}
}
}
override fun onServiceDisconnected(p0: ComponentName?) {
}
}
private var syncActive = false private var syncActive = false
private var syncAccountProjectsActive = false private var syncAccountProjectsActive = false
@@ -77,29 +58,49 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
updateNetworkStatus() updateNetworkStatus()
} }
@Throws(Throwable::class)
protected fun finalize() {
appContext.unbindService(certService)
}
val isSyncPossible: Boolean val isSyncPossible: Boolean
get() { get() {
updateNetworkStatus() updateNetworkStatus()
return networkConnected val offlineMode = preferences.getBoolean(appContext.getString(R.string.pref_key_offline_mode), false)
return networkConnected && !offlineMode
} }
fun addCallbackPull(callback: ICallback) { fun addCallbackPull(callback: ICallback) {
callbacksPull.add(callback) // Callers register on every resume but the list is only drained when a task actually
// starts, so refuse duplicates rather than letting the same callback pile up.
if (!callbacksPull.contains(callback)) {
callbacksPull.add(callback)
}
} }
fun scheduleSync(onlyLocalChanges: Boolean, projId: Long): SyncTask? { fun removeCallbackPull(callback: ICallback) {
Log.d(TAG, "Sync requested (${if (onlyLocalChanges) "onlyLocalChanges" else "full"}; ${if (syncActive) "sync active" else "sync NOT active"}) ...") callbacksPull.remove(callback)
}
fun scheduleSync(onlyLocalChanges: Boolean, projId: Long, forceFullSync: Boolean = false): SyncTask? =
scheduleSync(onlyLocalChanges, projId, forceFullSync) { dbHelper.getProject(projId) }
/**
* Overload for callers that already hold the project. Resolving one by id costs a query plus
* a blocking DataStore read and an AEAD decrypt in getProjectFromCursor, which adds up when
* scheduling a sync for every project at app open.
*/
fun scheduleSync(onlyLocalChanges: Boolean, project: DBProject, forceFullSync: Boolean = false): SyncTask? =
scheduleSync(onlyLocalChanges, project.id, forceFullSync) { project }
private fun scheduleSync(
onlyLocalChanges: Boolean,
projId: Long,
forceFullSync: Boolean,
resolveProject: () -> DBProject?
): SyncTask? {
Log.d(TAG, "Sync requested (${if (onlyLocalChanges) "onlyLocalChanges" else "full"}; ${if (syncActive) "sync active" else "sync NOT active"}; forceFullSync=$forceFullSync) ...")
updateNetworkStatus() updateNetworkStatus()
if (isSyncPossible && (!syncActive || onlyLocalChanges)) { if (isSyncPossible && (!syncActive || onlyLocalChanges)) {
val project = dbHelper.getProject(projId) val project = resolveProject()
if (project != null) { if (project != null) {
Log.d(TAG, "... starting now") Log.d(TAG, "... starting now")
val syncTask = SyncTask(onlyLocalChanges, project) val syncTask = SyncTask(onlyLocalChanges, project, forceFullSync)
syncTask.addCallbacks(callbacksPush) syncTask.addCallbacks(callbacksPush)
callbacksPush = ArrayList() callbacksPush = ArrayList()
if (!onlyLocalChanges) { if (!onlyLocalChanges) {
@@ -137,7 +138,25 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
} }
} }
inner class SyncTask(private val onlyLocalChanges: Boolean, private val project: DBProject) { /** The server's ids for the things a bill points at, mapped to their local row ids. */
private class RemoteIdMaps(
val members: Map<Long, Long>,
val categories: Map<Long, Long>,
val paymentModes: Map<Long, Long>
)
/** One pull of the bills endpoint. */
private class RemoteBills(
val bills: List<DBBill>,
/**
* Every bill id the server holds. Only the complete fetch reports this; after a paged
* walk it is empty, and nothing may be deleted locally on the strength of it.
*/
val allIds: List<Long>,
val syncTimestamp: Long?
)
inner class SyncTask(private val onlyLocalChanges: Boolean, private val project: DBProject, private val forceFullSync: Boolean = false) {
private val callbacks: MutableList<ICallback> = ArrayList() private val callbacks: MutableList<ICallback> = ArrayList()
private var nextcloudClient: NextcloudClient? = null private var nextcloudClient: NextcloudClient? = null
private var client: VersatileProjectSyncClient? = null private var client: VersatileProjectSyncClient? = null
@@ -529,298 +548,37 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
} }
} }
/**
* Brings the local copy of the project in line with the server: its own row, then each of
* its collections, then its bills. Each step is applied as it goes, so a failure part way
* through leaves the earlier steps written - the next sync picks up where this one stopped.
*/
private fun pullRemoteChanges(): LoginStatus { private fun pullRemoteChanges(): LoginStatus {
Log.d(TAG, "pullRemoteChanges($project)") Log.d(TAG, "pullRemoteChanges($project)")
val lastETag: String? = null
val lastModified: Long = 0
return try { return try {
val projResponse = client!!.getProject(project, lastModified, lastETag) val projResponse = client!!.getProject(project, 0, null)
Log.d(TAG,projResponse.toString())
val name = projResponse.name
Log.i(TAG, "AAA getProjectInfo, project name: $name")
val email = projResponse.email
val currencyName = projResponse.currencyName
val deletionDisabled = projResponse.deletionDisabled
val myAccessLevel = projResponse.myAccessLevel
val archivedTs = projResponse.archivedTs
if (project.name == "" || name != project.name || project.email == null || project.email == "" || project.isDeletionDisabled != deletionDisabled || project.myAccessLevel != myAccessLevel || project.archivedTs != archivedTs || (project.currencyName == null) || (currencyName != project.currencyName) || email != project.email updateLocalProject(projResponse)
) { syncPaymentModes(projResponse)
Log.d(TAG, "update local project : $project") syncCategories(projResponse)
project.name = name syncCurrencies(projResponse)
project.currencyName = currencyName val remoteMembersByRemoteId = syncMembers(projResponse)
project.isDeletionDisabled = deletionDisabled
project.myAccessLevel = myAccessLevel
project.archivedTs = archivedTs
dbHelper.updateProject(
projId = project.id,
newName = name,
newEmail = email,
newPassword = null,
newLastPayerId = null,
newLastSyncedTimestamp = null,
newCurrencyName = currencyName,
newDeletionDisabled = deletionDisabled,
newMyAccessLevel = myAccessLevel,
newBearerToken = null,
newArchivedTs = archivedTs ?: 0L
)
}
val remotePaymentModes = projResponse.getPaymentModes(project.id) // Bills arrive with the server's ids for their member, category and payment mode,
val remotePaymentModesByRemoteId = remotePaymentModes.associateBy { it.remoteId } // so the maps have to be built after those collections are in place.
val idMaps = buildRemoteIdMaps()
for (pm in remotePaymentModes) {
val localPaymentMode = dbHelper.getPaymentMode(pm.remoteId, project.id)
if (localPaymentMode == null) {
Log.d(TAG, "Add local pm : $pm")
dbHelper.addPaymentMode(pm)
} else {
if (pm.name == localPaymentMode.name &&
pm.color == localPaymentMode.color &&
pm.icon == localPaymentMode.icon
) {
Log.d(TAG, "Nothing to do for pm : $localPaymentMode")
} else {
Log.d(TAG, "Update local pm : $pm")
dbHelper.updatePaymentMode(localPaymentMode.id, pm.name, pm.icon, pm.color)
}
}
}
val localPaymentModes = dbHelper.getPaymentModes(project.id)
for (localPaymentMode in localPaymentModes) {
if (localPaymentMode.state == DBBill.STATE_OK && !remotePaymentModesByRemoteId.containsKey(localPaymentMode.remoteId)) {
dbHelper.deletePaymentMode(localPaymentMode.id)
Log.d(TAG, "Delete local pm : $localPaymentMode")
}
}
val remoteCategories = projResponse.getCategories(project.id)
val remoteCategoriesByRemoteId = remoteCategories.associateBy { it.remoteId }
for (c in remoteCategories) {
if (c.remoteId == DBBill.CATEGORY_REIMBURSEMENT) continue
val localCategory = dbHelper.getCategory(c.remoteId, project.id)
if (localCategory == null) {
Log.d(TAG, "Add local category : $c")
dbHelper.addCategory(c)
} else {
if (c.name == localCategory.name &&
c.color == localCategory.color &&
c.icon == localCategory.icon
) {
Log.d(TAG, "Nothing to do for category : $localCategory")
} else {
Log.d(TAG, "Update local category : $c")
dbHelper.updateCategory(localCategory.id, c.name, c.icon, c.color)
}
}
}
val localCategories = dbHelper.getCategories(project.id)
for (localCategory in localCategories) {
if (localCategory.state == DBBill.STATE_OK && !remoteCategoriesByRemoteId.containsKey(localCategory.remoteId)) {
dbHelper.deleteCategory(localCategory.id)
Log.d(TAG, "Delete local category : $localCategory")
}
}
val remoteCurrencies = projResponse.getCurrencies(project.id)
val remoteCurrenciesByRemoteId = remoteCurrencies.associateBy { it.remoteId }
for (c in remoteCurrencies) {
val localCurrency = dbHelper.getCurrency(c.remoteId, project.id)
if (localCurrency == null) {
Log.d(TAG, "Add local currency : $c")
dbHelper.addCurrency(c)
} else {
if (c.name == localCurrency.name &&
c.exchangeRate == localCurrency.exchangeRate
) {
Log.d(TAG, "Nothing to do for currency : $localCurrency")
} else {
Log.d(TAG, "Update local currency : $c")
dbHelper.updateCurrency(localCurrency.id, c.name, c.exchangeRate)
}
}
}
val localCurrencies = dbHelper.getCurrencies(project.id)
for (localCurrency in localCurrencies) {
if (localCurrency.state == DBBill.STATE_OK && !remoteCurrenciesByRemoteId.containsKey(localCurrency.remoteId)) {
dbHelper.deleteCurrency(localCurrency.id)
Log.d(TAG, "Delete local currency : $localCurrencies")
}
}
val remoteMembers = projResponse.getMembers(project.id)
val remoteMembersByRemoteId = remoteMembers.associateBy { it.remoteId }
for (m in remoteMembers) {
val localMember = dbHelper.getMember(m.remoteId, project.id)
if (localMember == null) {
Log.d(TAG, "Add local member : $m")
val mid = dbHelper.addMember(m)
if (!m.ncUserId.isNullOrEmpty()) {
updateMemberAvatar(mid)
}
} else {
val ncUserIdChanged = (
(m.ncUserId == null && localMember.ncUserId != null) ||
(m.ncUserId != null && localMember.ncUserId == null) ||
(m.ncUserId != null && m.ncUserId != localMember.ncUserId)
)
Log.e("PULLREMOTE", "member NC user id : ${localMember.ncUserId} => ${m.ncUserId} ID changed $ncUserIdChanged")
if (ncUserIdChanged && m.ncUserId == null) {
m.ncUserId = ""
}
if (m.name == localMember.name &&
m.weight == localMember.weight &&
m.isActivated == localMember.isActivated &&
((m.r == null && m.g == null && m.b == null) ||
(m.r == localMember.r && m.g == localMember.g && m.b == localMember.b)) &&
!ncUserIdChanged
) {
Log.d(TAG, "Nothing to do for member : $localMember")
if (!localMember.ncUserId.isNullOrEmpty() && localMember.avatar.isNullOrEmpty()) {
Log.d(TAG, "except updating avatar")
updateMemberAvatar(localMember.id)
}
} else {
Log.d(TAG, "Update local member : $m")
var r = m.r
var g = m.g
var b = m.b
if (m.r == null && m.g == null && m.b == null) {
r = localMember.r
g = localMember.g
b = localMember.b
}
val needAvatarUpdate = (ncUserIdChanged && !m.ncUserId.isNullOrEmpty())
val newAvatar = if (ncUserIdChanged) "" else null
dbHelper.updateMember(
localMember.id, m.name, m.weight,
m.isActivated, null, null,
r, g, b, m.ncUserId, newAvatar
)
if (needAvatarUpdate) {
Log.e("PLOP", "pullremote : update member avatar")
updateMemberAvatar(localMember.id)
}
}
}
}
val dbMembers = dbHelper.getMembersOfProject(project.id, null)
val memberRemoteIdToId = dbMembers.associate { it.remoteId to it.id }
val dbCategories = dbHelper.getCategories(project.id)
val categoriesRemoteIdToId = dbCategories.associate { it.remoteId to it.id }.toMutableMap()
// Map hardcoded constants to their local IDs if they exist in DB, else to themselves
categoriesRemoteIdToId[DBBill.CATEGORY_REIMBURSEMENT] = DBBill.CATEGORY_REIMBURSEMENT
dbCategories.filter { it.remoteId < 0 }.forEach { categoriesRemoteIdToId[it.remoteId] = it.id }
val dbPaymentModes = dbHelper.getPaymentModes(project.id)
val paymentModesRemoteIdToId = dbPaymentModes.associate { it.remoteId to it.id }.toMutableMap()
dbPaymentModes.filter { it.remoteId < 0 }.forEach { paymentModesRemoteIdToId[it.remoteId] = it.id }
val billsResponse = client!!.getBills(project)
val isIHM = project.type == ProjectType.IHATEMONEY
val serverSyncTimestamp = if (isIHM) 0L else billsResponse.syncTimestamp
val remoteBills: List<DBBill> = if (isIHM) {
billsResponse.getBillsIHM(project.id, memberRemoteIdToId, categoriesRemoteIdToId, paymentModesRemoteIdToId)
} else {
billsResponse.getBillsCospend(project.id, memberRemoteIdToId, categoriesRemoteIdToId, paymentModesRemoteIdToId)
}
val remoteAllBillIds: List<Long> = if (isIHM) {
remoteBills.map { it.remoteId }
} else {
billsResponse.allBillIds
}
val remoteBillsByRemoteId = remoteBills.associateBy { it.remoteId }
val localBills = dbHelper.getBillsOfProject(project.id) val localBills = dbHelper.getBillsOfProject(project.id)
val localBillsByRemoteId = localBills.associateBy { it.remoteId } val localBillsByRemoteId = localBills.associateBy { it.remoteId }
val pulled = fetchRemoteBills(idMaps, localBillsByRemoteId)
for (remoteBill in remoteBills) { applyRemoteBills(pulled.bills, localBillsByRemoteId)
if (!localBillsByRemoteId.containsKey(remoteBill.remoteId)) { deleteVanishedBills(pulled, localBills)
dbHelper.addBill(remoteBill) deleteVanishedMembers(remoteMembersByRemoteId)
nbPulledNewBills++
newBillsDialogText += "+ ${remoteBill.what}\n"
} else {
val localBill = localBillsByRemoteId[remoteBill.remoteId]!!
if (hasChanged(localBill, remoteBill)) {
dbHelper.updateBill(
localBill.id, null, remoteBill.payerId,
remoteBill.amount, remoteBill.timestamp,
remoteBill.what, DBBill.STATE_OK, remoteBill.repeat,
remoteBill.paymentMode, remoteBill.paymentModeId,
remoteBill.categoryId, remoteBill.comment
)
nbPulledUpdatedBills++
updatedBillsDialogText += "${remoteBill.what}\n"
} else {
Log.d(TAG, "Nothing to do for bill : $localBill")
}
val localBillOwersByIds = localBill.billOwers.associateBy { it.memberId }
val remoteBillOwersByIds = remoteBill.billOwers.associateBy { it.memberId }
for (rbo in remoteBill.billOwers) {
if (!localBillOwersByIds.containsKey(rbo.memberId)) {
dbHelper.addBillower(localBill.id, rbo.memberId)
Log.d(TAG, "Add local billOwer : $rbo")
}
}
for (lbo in localBill.billOwers) {
if (!remoteBillOwersByIds.containsKey(lbo.memberId)) {
dbHelper.deleteBillOwer(lbo.id)
Log.d(TAG, "Delete local billOwer : $lbo")
}
}
}
}
if (project.type == ProjectType.COSPEND || project.type == ProjectType.IHATEMONEY) {
for (localBill in localBills) {
if (!remoteAllBillIds.contains(localBill.remoteId)) {
dbHelper.deleteBill(localBill.id)
nbPulledDeletedBills++
deletedBillsDialogText += "🗑 ${localBill.what}\n"
Log.d(TAG, "Delete local bill : $localBill")
}
}
} else {
for (localBill in localBills) {
if (!remoteBillsByRemoteId.containsKey(localBill.remoteId)) {
dbHelper.deleteBill(localBill.id)
nbPulledDeletedBills++
deletedBillsDialogText += "🗑 ${localBill.what}\n"
Log.d(TAG, "Delete local bill : $localBill")
}
}
}
val localMembers = dbHelper.getMembersOfProject(project.id, null)
for (localMember in localMembers) {
if (!remoteMembersByRemoteId.containsKey(localMember.remoteId)) {
if (dbHelper.getBillsOfMember(localMember.id).isEmpty()
&& dbHelper.getBillowersOfMember(localMember.id).isEmpty()
) {
dbHelper.deleteMember(localMember.id)
Log.d(TAG, "Delete local member : $localMember")
} else {
Log.d(TAG, "WARNING local member : ${localMember.name} does not exist remotely but is still involved in some bills")
}
}
}
dbHelper.updateProject( dbHelper.updateProject(
project.id, null, null, projId = project.id,
null, null, serverSyncTimestamp, newLastSyncedTimestamp = pulled.syncTimestamp
null, null, null,
null
) )
LoginStatus.OK LoginStatus.OK
} catch (_: ServerResponse.NotModifiedException) { } catch (_: ServerResponse.NotModifiedException) {
@@ -844,6 +602,394 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
LoginStatus.REQ_FAILED LoginStatus.REQ_FAILED
} }
} }
private fun updateLocalProject(projResponse: ServerResponse.ProjectResponse) {
val name = projResponse.name
val email = projResponse.email
val currencyName = projResponse.currencyName
val deletionDisabled = projResponse.deletionDisabled
val myAccessLevel = projResponse.myAccessLevel
val archivedTs = projResponse.archivedTs
val unchanged = project.name.isNotEmpty() &&
name == project.name &&
!project.email.isNullOrEmpty() &&
email == project.email &&
project.isDeletionDisabled == deletionDisabled &&
project.myAccessLevel == myAccessLevel &&
project.archivedTs == archivedTs &&
project.currencyName != null &&
currencyName == project.currencyName
if (unchanged) return
Log.d(TAG, "update local project : $project")
project.name = name
project.currencyName = currencyName
project.isDeletionDisabled = deletionDisabled
project.myAccessLevel = myAccessLevel
project.archivedTs = archivedTs
dbHelper.updateProject(
projId = project.id,
newName = name,
newEmail = email,
newPassword = null,
newLastPayerId = null,
newLastSyncedTimestamp = null,
newCurrencyName = currencyName,
newDeletionDisabled = deletionDisabled,
newMyAccessLevel = myAccessLevel,
newBearerToken = null,
newArchivedTs = archivedTs ?: 0L
)
}
private fun syncPaymentModes(projResponse: ServerResponse.ProjectResponse) {
val remote = projResponse.getPaymentModes(project.id)
for (pm in remote) {
val local = dbHelper.getPaymentMode(pm.remoteId, project.id)
if (local == null) {
Log.d(TAG, "Add local pm : $pm")
dbHelper.addPaymentMode(pm)
} else if (pm.name == local.name && pm.color == local.color && pm.icon == local.icon) {
Log.d(TAG, "Nothing to do for pm : $local")
} else {
Log.d(TAG, "Update local pm : $pm")
dbHelper.updatePaymentMode(local.id, pm.name, pm.icon, pm.color)
}
}
// Only settled rows may be dropped; one still waiting to be pushed is not "gone".
val remoteIds = remote.map { it.remoteId }.toSet()
for (local in dbHelper.getPaymentModes(project.id)) {
if (local.state == DBBill.STATE_OK && local.remoteId !in remoteIds) {
dbHelper.deletePaymentMode(local.id)
Log.d(TAG, "Delete local pm : $local")
}
}
}
private fun syncCategories(projResponse: ServerResponse.ProjectResponse) {
val remote = projResponse.getCategories(project.id)
for (c in remote) {
if (c.remoteId == DBBill.CATEGORY_REIMBURSEMENT) continue
val local = dbHelper.getCategory(c.remoteId, project.id)
if (local == null) {
Log.d(TAG, "Add local category : $c")
dbHelper.addCategory(c)
} else if (c.name == local.name && c.color == local.color && c.icon == local.icon) {
Log.d(TAG, "Nothing to do for category : $local")
} else {
Log.d(TAG, "Update local category : $c")
dbHelper.updateCategory(local.id, c.name, c.icon, c.color)
}
}
val remoteIds = remote.map { it.remoteId }.toSet()
for (local in dbHelper.getCategories(project.id)) {
if (local.state == DBBill.STATE_OK && local.remoteId !in remoteIds) {
dbHelper.deleteCategory(local.id)
Log.d(TAG, "Delete local category : $local")
}
}
}
private fun syncCurrencies(projResponse: ServerResponse.ProjectResponse) {
val remote = projResponse.getCurrencies(project.id)
for (c in remote) {
val local = dbHelper.getCurrency(c.remoteId, project.id)
if (local == null) {
Log.d(TAG, "Add local currency : $c")
dbHelper.addCurrency(c)
} else if (c.name == local.name && c.exchangeRate == local.exchangeRate) {
Log.d(TAG, "Nothing to do for currency : $local")
} else {
Log.d(TAG, "Update local currency : $c")
dbHelper.updateCurrency(local.id, c.name, c.exchangeRate)
}
}
val remoteIds = remote.map { it.remoteId }.toSet()
for (local in dbHelper.getCurrencies(project.id)) {
if (local.state == DBBill.STATE_OK && local.remoteId !in remoteIds) {
dbHelper.deleteCurrency(local.id)
Log.d(TAG, "Delete local currency : $local")
}
}
}
/** Returns the members the server listed, keyed by remote id, for the later cleanup pass. */
private fun syncMembers(projResponse: ServerResponse.ProjectResponse): Map<Long, DBMember> {
val remote = projResponse.getMembers(project.id)
for (m in remote) {
val local = dbHelper.getMember(m.remoteId, project.id)
if (local == null) {
Log.d(TAG, "Add local member : $m")
val mid = dbHelper.addMember(m)
if (!m.ncUserId.isNullOrEmpty()) {
updateMemberAvatar(mid)
}
} else {
updateLocalMember(m, local)
}
}
return remote.associateBy { it.remoteId }
}
private fun updateLocalMember(remote: DBMember, local: DBMember) {
val ncUserIdChanged = remote.ncUserId != local.ncUserId
Log.d(TAG, "member NC user id : ${local.ncUserId} => ${remote.ncUserId} ID changed $ncUserIdChanged")
if (ncUserIdChanged && remote.ncUserId == null) {
remote.ncUserId = ""
}
// The server omits colours it has never been told about, which is not the same as
// clearing them, so a null triple means "unchanged" rather than "no colour".
val remoteHasNoColour = remote.r == null && remote.g == null && remote.b == null
val colourUnchanged = remoteHasNoColour ||
(remote.r == local.r && remote.g == local.g && remote.b == local.b)
if (remote.name == local.name && remote.weight == local.weight &&
remote.isActivated == local.isActivated && colourUnchanged && !ncUserIdChanged
) {
Log.d(TAG, "Nothing to do for member : $local")
if (!local.ncUserId.isNullOrEmpty() && local.avatar.isNullOrEmpty()) {
Log.d(TAG, "except updating avatar")
updateMemberAvatar(local.id)
}
return
}
Log.d(TAG, "Update local member : $remote")
val r = if (remoteHasNoColour) local.r else remote.r
val g = if (remoteHasNoColour) local.g else remote.g
val b = if (remoteHasNoColour) local.b else remote.b
val needAvatarUpdate = ncUserIdChanged && !remote.ncUserId.isNullOrEmpty()
dbHelper.updateMember(
local.id, remote.name, remote.weight,
remote.isActivated, null, null,
r, g, b, remote.ncUserId, if (ncUserIdChanged) "" else null
)
if (needAvatarUpdate) {
updateMemberAvatar(local.id)
}
}
private fun buildRemoteIdMaps(): RemoteIdMaps {
val members = dbHelper.getMembersOfProject(project.id, null)
.associate { it.remoteId to it.id }
val categories = dbHelper.getCategories(project.id)
.associate { it.remoteId to it.id }
.toMutableMap()
// The built-in categories keep their negative ids rather than getting local rows.
categories[DBBill.CATEGORY_REIMBURSEMENT] = DBBill.CATEGORY_REIMBURSEMENT
dbHelper.getCategories(project.id).filter { it.remoteId < 0 }
.forEach { categories[it.remoteId] = it.id }
val paymentModes = dbHelper.getPaymentModes(project.id)
.associate { it.remoteId to it.id }
.toMutableMap()
dbHelper.getPaymentModes(project.id).filter { it.remoteId < 0 }
.forEach { paymentModes[it.remoteId] = it.id }
return RemoteIdMaps(members, categories, paymentModes)
}
/**
* Fetches the bills, by paged walk where the server supports one and by complete fetch
* otherwise. Falls back to the complete fetch whenever the walk cannot be trusted, so the
* caller always gets a usable result.
*/
private fun fetchRemoteBills(
idMaps: RemoteIdMaps,
localBillsByRemoteId: Map<Long, DBBill>
): RemoteBills {
val usePagedWalk = project.type == ProjectType.COSPEND && !forceFullSync &&
localBillsByRemoteId.isNotEmpty() && client!!.supportsPagedBills
if (usePagedWalk) {
walkBillPages(idMaps, localBillsByRemoteId)?.let { return it }
}
return fetchAllBills(idMaps)
}
/**
* Walks back through pages of bills, newest first, until it has seen a run of
* [UNCHANGED_RUN_TO_SETTLE] consecutive bills that already match locally - at which point
* everything older is taken on trust.
*
* That only terminates while the server really does reverse the order and honour the
* offset. One that does neither returns the same oldest-first page every time, and since
* the walk compares against local rows it never writes, a single unknown bill keeps the
* run at zero and the same page is requested forever. Returns null when the responses
* show that happening, so the caller can fall back to the complete fetch.
*/
private fun walkBillPages(
idMaps: RemoteIdMaps,
localBillsByRemoteId: Map<Long, DBBill>
): RemoteBills? {
Log.d(TAG, "Starting partial sync for project ${project.remoteId}")
val limit = 50
val bills = mutableListOf<DBBill>()
var syncTimestamp = project.lastSyncedTimestamp
var offset = 0
var previousPageIds: List<Long>? = null
// Counted across pages, not restarted at each one: a run that begins near the end of
// a page still finishes on the next.
var unchangedRun = 0
while (true) {
val response = client!!.getBills(project, offset, limit, true, 0)
val page = response.getBillsCospend(
project.id, idMaps.members, idMaps.categories, idMaps.paymentModes
)
if (page.isEmpty()) break
if (page.first().timestamp < page.last().timestamp) {
Log.w(TAG, "Server returned bills oldest-first; the paged walk cannot be trusted")
return null
}
val pageIds = page.map { it.remoteId }
if (pageIds == previousPageIds) {
Log.w(TAG, "Server returned the same page for offset $offset; it is ignoring the offset")
return null
}
previousPageIds = pageIds
bills.addAll(page)
if (offset == 0 && response.syncTimestamp > 0) {
syncTimestamp = response.syncTimestamp
}
var settled = false
for (remote in page) {
val local = localBillsByRemoteId[remote.remoteId]
if (local != null && !hasChanged(local, remote)) {
unchangedRun++
if (unchangedRun >= UNCHANGED_RUN_TO_SETTLE) {
settled = true
break
}
} else {
unchangedRun = 0
}
}
// A short page is the end of the collection: there is nothing older to walk back
// to, so asking for the next offset would only refetch it.
if (settled || page.size < limit) break
offset += limit
}
// A walk reports no allIds, so it never causes a local deletion.
return RemoteBills(bills, emptyList(), syncTimestamp)
}
private fun fetchAllBills(idMaps: RemoteIdMaps): RemoteBills {
Log.d(TAG, "Starting full sync for project ${project.remoteId}")
val response = client!!.getBills(project)
return if (project.type == ProjectType.IHATEMONEY) {
val bills = response.getBillsIHM(
project.id, idMaps.members, idMaps.categories, idMaps.paymentModes
)
RemoteBills(bills, bills.map { it.remoteId }, 0L)
} else {
RemoteBills(
response.getBillsCospend(
project.id, idMaps.members, idMaps.categories, idMaps.paymentModes
),
response.allBillIds,
response.syncTimestamp
)
}
}
private fun applyRemoteBills(
remoteBills: List<DBBill>,
localBillsByRemoteId: Map<Long, DBBill>
) {
for (remoteBill in remoteBills) {
val localBill = localBillsByRemoteId[remoteBill.remoteId]
if (localBill == null) {
dbHelper.addBill(remoteBill)
nbPulledNewBills++
newBillsDialogText += "+ ${remoteBill.what}\n"
continue
}
if (hasChanged(localBill, remoteBill)) {
dbHelper.updateBill(
localBill.id, null, remoteBill.payerId,
remoteBill.amount, remoteBill.timestamp,
remoteBill.what, DBBill.STATE_OK, remoteBill.repeat,
remoteBill.paymentMode, remoteBill.paymentModeId,
remoteBill.categoryId, remoteBill.comment
)
nbPulledUpdatedBills++
updatedBillsDialogText += "${remoteBill.what}\n"
} else {
Log.d(TAG, "Nothing to do for bill : $localBill")
}
syncBillOwers(localBill, remoteBill)
}
}
private fun syncBillOwers(localBill: DBBill, remoteBill: DBBill) {
val localMemberIds = localBill.billOwers.map { it.memberId }.toSet()
val remoteMemberIds = remoteBill.billOwers.map { it.memberId }.toSet()
for (rbo in remoteBill.billOwers) {
if (rbo.memberId !in localMemberIds) {
dbHelper.addBillower(localBill.id, rbo.memberId)
Log.d(TAG, "Add local billOwer : $rbo")
}
}
for (lbo in localBill.billOwers) {
if (lbo.memberId !in remoteMemberIds) {
dbHelper.deleteBillOwer(lbo.id)
Log.d(TAG, "Delete local billOwer : $lbo")
}
}
}
/**
* Drops local bills the server no longer has. An empty allIds means the server never told
* us the full set - after a paged walk, say - and nothing may be deleted on that basis.
*/
private fun deleteVanishedBills(pulled: RemoteBills, localBills: List<DBBill>) {
if (pulled.allIds.isEmpty()) return
val stillRemote: Set<Long> =
if (project.type == ProjectType.COSPEND || project.type == ProjectType.IHATEMONEY) {
pulled.allIds.toSet()
} else {
pulled.bills.map { it.remoteId }.toSet()
}
for (localBill in localBills) {
if (localBill.remoteId !in stillRemote) {
dbHelper.deleteBill(localBill.id)
nbPulledDeletedBills++
deletedBillsDialogText += "🗑 ${localBill.what}\n"
Log.d(TAG, "Delete local bill : $localBill")
}
}
}
private fun deleteVanishedMembers(remoteMembersByRemoteId: Map<Long, DBMember>) {
for (localMember in dbHelper.getMembersOfProject(project.id, null)) {
if (remoteMembersByRemoteId.containsKey(localMember.remoteId)) continue
// A member still named by a bill cannot be removed without orphaning it.
if (dbHelper.getBillsOfMember(localMember.id).isEmpty() &&
dbHelper.getBillowersOfMember(localMember.id).isEmpty()
) {
dbHelper.deleteMember(localMember.id)
Log.d(TAG, "Delete local member : $localMember")
} else {
Log.d(TAG, "WARNING local member : ${localMember.name} does not exist remotely but is still involved in some bills")
}
}
}
private fun onPostExecute(status: LoginStatus) { private fun onPostExecute(status: LoginStatus) {
if (status != LoginStatus.OK) { if (status != LoginStatus.OK) {
@@ -935,11 +1081,18 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
return isCospend && projUrl == accountUrl return isCospend && projUrl == accountUrl
} }
fun editRemoteProject(projId: Long, newName: String?, newEmail: String?, fun editRemoteProject(
newPassword: String?, newMainCurrencyName: String?, callback: ICallback): Boolean { projId: Long,
newName: String? = null,
newEmail: String? = null,
newPassword: String? = null,
newMainCurrencyName: String? = null,
newArchivedTs: Long? = null,
callback: ICallback
): Boolean {
updateNetworkStatus() updateNetworkStatus()
if (isSyncPossible) { if (isSyncPossible) {
EditRemoteProjectTask(projId, newName, newEmail, newPassword, newMainCurrencyName, callback).execute() EditRemoteProjectTask(projId, newName, newEmail, newPassword, newMainCurrencyName, newArchivedTs, callback).execute()
return true return true
} }
return false return false
@@ -951,6 +1104,7 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
private val newEmail: String?, private val newEmail: String?,
private val newPassword: String?, private val newPassword: String?,
private val newMainCurrencyName: String?, private val newMainCurrencyName: String?,
private val newArchivedTs: Long?,
private val callback: ICallback private val callback: ICallback
) { ) {
private val project: DBProject? = dbHelper.getProject(projId) private val project: DBProject? = dbHelper.getProject(projId)
@@ -984,8 +1138,21 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
} }
var status = LoginStatus.OK var status = LoginStatus.OK
try { try {
// Pass current project values if the new ones are null to ensure a complete project object is sent to the server
val currentProj = project!!
val finalName = (newName ?: currentProj.name).let { if (it.isBlank() || it == "null") currentProj.remoteId else it }
// Stay null when the project has no main currency, so the PUT omits currencyName
// instead of silently setting the server-side currency.
val finalCurrency = (newMainCurrencyName ?: currentProj.currencyName)
?.takeUnless { it.isBlank() || it == "null" }
val response = client!!.editRemoteProject( val response = client!!.editRemoteProject(
project!!, newName, newEmail, newPassword, newMainCurrencyName currentProj,
finalName,
newEmail ?: currentProj.email,
newPassword,
finalCurrency,
newArchivedTs
) )
if (BillsListViewActivity.DEBUG) { if (BillsListViewActivity.DEBUG) {
Log.i(TAG, "RESPONSE edit remote project : ${response.stringContent}") Log.i(TAG, "RESPONSE edit remote project : ${response.stringContent}")
@@ -1025,8 +1192,11 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
} }
} else { } else {
dbHelper.updateProject( dbHelper.updateProject(
project!!.id, newName, newEmail, newPassword, projId = project!!.id,
null, null, null, null, null, null newName = newName,
newEmail = newEmail,
newPassword = newPassword,
newArchivedTs = newArchivedTs
) )
} }
callback.onFinish(newName ?: "", errorString) callback.onFinish(newName ?: "", errorString)
@@ -1205,7 +1375,7 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
} }
} }
private fun hasChanged(localBill: DBBill, remoteBill: DBBill): Boolean { internal fun hasChanged(localBill: DBBill, remoteBill: DBBill): Boolean {
if (localBill.payerId == remoteBill.payerId && if (localBill.payerId == remoteBill.payerId &&
localBill.amount == remoteBill.amount && localBill.amount == remoteBill.amount &&
localBill.timestamp == remoteBill.timestamp && localBill.timestamp == remoteBill.timestamp &&
@@ -1372,6 +1542,11 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
} }
private fun onPostExecute(status: LoginStatus) { private fun onPostExecute(status: LoginStatus) {
if (status == LoginStatus.OK) {
preferences.edit {
putLong(appContext.getString(R.string.pref_key_last_account_sync_timestamp), System.currentTimeMillis())
}
}
if (status != LoginStatus.OK) { if (status != LoginStatus.OK) {
var errorString = appContext.getString(R.string.error_sync, appContext.getString(status.str)) + "\n\n" var errorString = appContext.getString(R.string.error_sync, appContext.getString(status.str)) + "\n\n"
for (errorMessage in errorMessages) { for (errorMessage in errorMessages) {
@@ -1616,6 +1791,16 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
companion object { companion object {
private val TAG = CowspentServerSyncHelper::class.java.simpleName private val TAG = CowspentServerSyncHelper::class.java.simpleName
/**
* How many consecutive bills, walking newest to oldest, must already match locally before
* the paged walk concludes that every older bill matches too.
*
* A whole page of 50 had to match before, so one edit anywhere in a page forced another
* page to be fetched. A trailing run is the same bet on a smaller sample: it can settle
* part way into a page, and it carries across page boundaries rather than restarting.
*/
private const val UNCHANGED_RUN_TO_SETTLE = 25
private var instance: CowspentServerSyncHelper? = null private var instance: CowspentServerSyncHelper? = null
private val projectIdsToSync: MutableList<Long> = ArrayList() private val projectIdsToSync: MutableList<Long> = ArrayList()
@@ -1627,6 +1812,12 @@ class CowspentServerSyncHelper private constructor(private val dbHelper: Cowspen
return instance!! return instance!!
} }
@VisibleForTesting
fun resetInstance() {
instance = null
projectIdsToSync.clear()
}
fun isNextcloudAccountConfigured(context: Context): Boolean { fun isNextcloudAccountConfigured(context: Context): Boolean {
val preferences = PreferenceManager.getDefaultSharedPreferences(context) val preferences = PreferenceManager.getDefaultSharedPreferences(context)
return !preferences.getString(AccountActivity.SETTINGS_URL, AccountActivity.DEFAULT_SETTINGS).isNullOrEmpty() || return !preferences.getString(AccountActivity.SETTINGS_URL, AccountActivity.DEFAULT_SETTINGS).isNullOrEmpty() ||
@@ -24,7 +24,7 @@ object ColorUtils {
val colorMode = if (prefs.contains(modeKey)) { val colorMode = if (prefs.contains(modeKey)) {
prefs.getString(modeKey, "system") prefs.getString(modeKey, "system")
} else { } else {
val useServer = prefs.getBoolean(context.getString(R.string.pref_key_use_server_color), true) val useServer = prefs.getBoolean(context.getString(R.string.pref_key_use_server_color), false)
val useSystem = prefs.getBoolean(context.getString(R.string.pref_key_use_system_color), true) val useSystem = prefs.getBoolean(context.getString(R.string.pref_key_use_system_color), true)
when { when {
useServer -> "server" useServer -> "server"
@@ -51,7 +51,7 @@ class NextcloudClient(
@Throws(JSONException::class, IOException::class, TokenMismatchException::class, NextcloudHttpRequestFailedException::class) @Throws(JSONException::class, IOException::class, TokenMismatchException::class, NextcloudHttpRequestFailedException::class)
fun getCapabilities(project: DBProject?): ServerResponse.CapabilitiesResponse { fun getCapabilities(project: DBProject?): ServerResponse.CapabilitiesResponse {
val target: String = if (project == null || url != "") { val target: String = if (project == null || url != "" || nextcloudAPI != null) {
"/ocs/v2.php/cloud/capabilities" "/ocs/v2.php/cloud/capabilities"
} else { } else {
val realServerUrl = project.serverUrl!! val realServerUrl = project.serverUrl!!
@@ -86,7 +86,7 @@ class NextcloudClient(
} }
@Throws(TokenMismatchException::class, NextcloudHttpRequestFailedException::class) @Throws(TokenMismatchException::class, NextcloudHttpRequestFailedException::class)
private fun requestServerWithSSO( internal fun requestServerWithSSO(
nextcloudAPI: NextcloudAPI, nextcloudAPI: NextcloudAPI,
target: String, target: String,
method: String, method: String,
@@ -141,7 +141,7 @@ class NextcloudClient(
} }
@Throws(TokenMismatchException::class, NextcloudHttpRequestFailedException::class) @Throws(TokenMismatchException::class, NextcloudHttpRequestFailedException::class)
private fun imageRequestServerWithSSO( internal fun imageRequestServerWithSSO(
nextcloudAPI: NextcloudAPI, nextcloudAPI: NextcloudAPI,
target: String, target: String,
method: String, method: String,
@@ -182,7 +182,7 @@ class NextcloudClient(
} }
@Throws(IOException::class, NextcloudHttpRequestFailedException::class) @Throws(IOException::class, NextcloudHttpRequestFailedException::class)
private fun requestServer( internal fun requestServer(
target: String, target: String,
method: String, params: JSONObject?, lastETag: String?, needLogin: Boolean, isOCSRequest: Boolean method: String, params: JSONObject?, lastETag: String?, needLogin: Boolean, isOCSRequest: Boolean
): VersatileProjectSyncClient.ResponseData { ): VersatileProjectSyncClient.ResponseData {
@@ -248,7 +248,7 @@ class NextcloudClient(
} }
@Throws(IOException::class, NextcloudHttpRequestFailedException::class) @Throws(IOException::class, NextcloudHttpRequestFailedException::class)
private fun imageRequestServer( internal fun imageRequestServer(
target: String, target: String,
method: String, params: JSONObject?, lastETag: String?, needLogin: Boolean, isOCSRequest: Boolean method: String, params: JSONObject?, lastETag: String?, needLogin: Boolean, isOCSRequest: Boolean
): VersatileProjectSyncClient.ResponseData { ): VersatileProjectSyncClient.ResponseData {
@@ -12,15 +12,10 @@ import net.helcel.cowspent.model.DBProject
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import org.xml.sax.SAXException
import java.io.ByteArrayInputStream
import java.io.IOException import java.io.IOException
import java.io.InputStream
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.parsers.ParserConfigurationException
/** /**
@@ -41,6 +36,10 @@ open class ServerResponse(
val lastModified: Long val lastModified: Long
get() = response.lastModified get() = response.lastModified
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
@Throws(JSONException::class) @Throws(JSONException::class)
fun getResponseObjectData(): JSONObject { fun getResponseObjectData(): JSONObject {
val rawData = JSONObject(content) val rawData = JSONObject(content)
@@ -125,10 +124,6 @@ open class ServerResponse(
private val isJsonMember: Boolean private val isJsonMember: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse) {
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
@get:Throws(JSONException::class) @get:Throws(JSONException::class)
val remoteMemberId: Long val remoteMemberId: Long
get() = if (isJsonMember) get() = if (isJsonMember)
@@ -142,10 +137,6 @@ open class ServerResponse(
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse) {
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
@get:Throws(JSONException::class) @get:Throws(JSONException::class)
val remoteCategoryId: Long val remoteCategoryId: Long
get() { get() {
@@ -162,32 +153,18 @@ open class ServerResponse(
class EditRemoteCategoryResponse( class EditRemoteCategoryResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse)
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
}
class DeleteRemoteCategoryResponse( class DeleteRemoteCategoryResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse)
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
}
class CreateRemotePaymentModeResponse( class CreateRemotePaymentModeResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse) {
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
@get:Throws(JSONException::class) @get:Throws(JSONException::class)
val remotePaymentModeId: Long val remotePaymentModeId: Long
get() { get() {
@@ -204,32 +181,18 @@ open class ServerResponse(
class EditRemotePaymentModeResponse( class EditRemotePaymentModeResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse)
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
}
class DeleteRemotePaymentModeResponse( class DeleteRemotePaymentModeResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse)
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
}
class CreateRemoteCurrencyResponse( class CreateRemoteCurrencyResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse) {
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
@get:Throws(JSONException::class) @get:Throws(JSONException::class)
val remoteCurrencyId: Long val remoteCurrencyId: Long
get() { get() {
@@ -246,32 +209,17 @@ open class ServerResponse(
class EditRemoteCurrencyResponse( class EditRemoteCurrencyResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse)
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
}
class DeleteRemoteCurrencyResponse( class DeleteRemoteCurrencyResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse)
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
}
class EditRemoteProjectResponse( class EditRemoteProjectResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse)
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
}
class EditRemoteMemberResponse( class EditRemoteMemberResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
@@ -289,10 +237,6 @@ open class ServerResponse(
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse) {
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
@get:Throws(JSONException::class) @get:Throws(JSONException::class)
val remoteBillId: Long val remoteBillId: Long
get() { get() {
@@ -311,10 +255,6 @@ open class ServerResponse(
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse) {
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
@get:Throws(JSONException::class) @get:Throws(JSONException::class)
val remoteBillId: Long val remoteBillId: Long
get() { get() {
@@ -331,32 +271,17 @@ open class ServerResponse(
class DeleteRemoteBillResponse( class DeleteRemoteBillResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse)
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
}
class DeleteRemoteProjectResponse( class DeleteRemoteProjectResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse)
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
}
class CreateRemoteProjectResponse( class CreateRemoteProjectResponse(
response: VersatileProjectSyncClient.ResponseData, response: VersatileProjectSyncClient.ResponseData,
isOcsResponse: Boolean isOcsResponse: Boolean
) : ServerResponse(response, isOcsResponse) { ) : ServerResponse(response, isOcsResponse)
@get:Throws(JSONException::class)
val stringContent: String
get() = getResponseStringData()
}
class BillsResponse(response: VersatileProjectSyncClient.ResponseData, isOcsResponse: Boolean) : class BillsResponse(response: VersatileProjectSyncClient.ResponseData, isOcsResponse: Boolean) :
ServerResponse(response, isOcsResponse) { ServerResponse(response, isOcsResponse) {
@@ -457,17 +382,6 @@ open class ServerResponse(
get() = content get() = content
} }
@Throws(JSONException::class)
protected fun getPublicTokenFromJSON(json: JSONObject): String? {
if (json.has("code") && json.has("sharetoken")) {
val done = json.getInt("code")
val publicToken = json.getString("sharetoken")
if (done == 1) {
return publicToken
}
}
return null
}
@Throws(JSONException::class) @Throws(JSONException::class)
protected fun getNameFromJSON(json: JSONObject): String { protected fun getNameFromJSON(json: JSONObject): String {
@@ -897,7 +811,9 @@ open class ServerResponse(
memberRemoteIdToId: Map<Long, Long> memberRemoteIdToId: Map<Long, Long>
): List<DBBillOwer> { ): List<DBBillOwer> {
val billOwers: MutableList<DBBillOwer> = ArrayList() val billOwers: MutableList<DBBillOwer> = ArrayList()
if (json.has("owers")) { // As everywhere else here, an explicitly null value is not a value: getJSONArray would
// throw on it, and that exception fails the whole project sync over one bill.
if (json.has("owers") && !json.isNull("owers")) {
val jsonOs = json.getJSONArray("owers") val jsonOs = json.getJSONArray("owers")
for (i in 0 until jsonOs.length()) { for (i in 0 until jsonOs.length()) {
val obj = jsonOs.get(i) val obj = jsonOs.get(i)
@@ -935,6 +851,8 @@ open class ServerResponse(
remoteId = json.getString("id") remoteId = json.getString("id")
} }
if (!json.isNull("ncurl")) { if (!json.isNull("ncurl")) {
ncUrl = json.getString("ncurl")
} else if (!json.isNull("ncUrl")) {
ncUrl = json.getString("ncUrl") ncUrl = json.getString("ncUrl")
} }
val archivedTs: Long? = getArchivedTsFromJSON(json) val archivedTs: Long? = getArchivedTsFromJSON(json)
@@ -944,26 +862,6 @@ open class ServerResponse(
return DBAccountProject(0, remoteId, null, name, ncUrl, archivedTs) return DBAccountProject(0, remoteId, null, name, ncUrl, archivedTs)
} }
@Throws(IOException::class)
protected fun getColorFromContent(content: String): String? {
var result: String? = null
try {
val dbf = DocumentBuilderFactory.newInstance()
val db = dbf.newDocumentBuilder()
val stream: InputStream = ByteArrayInputStream(content.toByteArray())
val doc = db.parse(stream)
doc.documentElement.normalize()
// Locate the Tag Name
val nodeList = doc.getElementsByTagName("color")
if (nodeList.length > 0) {
result = nodeList.item(0).textContent
Log.i(TAG, "I GOT THE COLOR from server: $result")
}
} catch (_: ParserConfigurationException) {
} catch (_: SAXException) {
}
return result
}
protected fun getColorFromJsonContent(json: JSONObject): String? { protected fun getColorFromJsonContent(json: JSONObject): String? {
return try { return try {
@@ -0,0 +1,33 @@
package net.helcel.cowspent.util
import android.content.Context
import androidx.preference.PreferenceManager
import net.helcel.cowspent.R
/**
* The SyncOnOpen preference: how often opening the app refreshes the account and every project.
*
* The choices and the default live here rather than in the settings screen so that the screen and
* the sync trigger cannot disagree about what is in effect.
*/
object SyncSettings {
/** Steps offered by the slider, in minutes. */
val INTERVAL_CHOICES_MINUTES = listOf(1, 10, 60, 1440)
const val DEFAULT_INTERVAL_MINUTES = 10
/**
* The configured interval in minutes. A stored value that is not one of the offered steps
* from a restored backup, or a build that changed the steps falls back to the default
* rather than being displayed as the first step while a different value drives the sync.
*/
fun intervalMinutes(context: Context): Int {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val stored = prefs.getInt(
context.getString(R.string.pref_key_auto_sync_on_open),
DEFAULT_INTERVAL_MINUTES
)
return if (stored in INTERVAL_CHOICES_MINUTES) stored else DEFAULT_INTERVAL_MINUTES
}
}
@@ -47,6 +47,8 @@ class VersatileProjectSyncClient(
gt gt
} }
val supportsPagedBills: Boolean get() = cospendVersionGT161
fun canAccessProjectWithNCLogin(project: DBProject): Boolean { fun canAccessProjectWithNCLogin(project: DBProject): Boolean {
return (project.password == "" return (project.password == ""
&& url.replace("/+$".toRegex(), "") != "" && url.replace("/+$".toRegex(), "") != ""
@@ -114,7 +116,7 @@ class VersatileProjectSyncClient(
@Throws(IOException::class, TokenMismatchException::class, NextcloudHttpRequestFailedException::class) @Throws(IOException::class, TokenMismatchException::class, NextcloudHttpRequestFailedException::class)
fun editRemoteProject( fun editRemoteProject(
project: DBProject, newName: String?, newEmail: String?, newPassword: String?, project: DBProject, newName: String?, newEmail: String?, newPassword: String?,
newMainCurrencyName: String? newMainCurrencyName: String?, newArchivedTs: Long? = null
): ServerResponse.EditRemoteProjectResponse { ): ServerResponse.EditRemoteProjectResponse {
val paramKeys: MutableList<String> = ArrayList() val paramKeys: MutableList<String> = ArrayList()
val paramValues: MutableList<String> = ArrayList() val paramValues: MutableList<String> = ArrayList()
@@ -130,6 +132,10 @@ class VersatileProjectSyncClient(
paramKeys.add("password") paramKeys.add("password")
paramValues.add(newPassword) paramValues.add(newPassword)
} }
if (newArchivedTs != null) {
paramKeys.add("archived_ts")
paramValues.add(newArchivedTs.toString())
}
var target: String var target: String
var username: String? = null var username: String? = null
@@ -154,10 +160,18 @@ class VersatileProjectSyncClient(
paramKeys.add("password") paramKeys.add("password")
paramValues.add(newPassword) paramValues.add(newPassword)
} }
if (newEmail != null) {
paramKeys.add("contact_email")
paramValues.add(newEmail)
}
if (newMainCurrencyName != null) { if (newMainCurrencyName != null) {
paramKeys.add("currencyName") paramKeys.add("currencyName")
paramValues.add(newMainCurrencyName) paramValues.add(newMainCurrencyName)
} }
if (newArchivedTs != null) {
paramKeys.add("archivedTs")
paramValues.add(newArchivedTs.toString())
}
} }
if (canAccessProjectWithNCLogin(project)) { if (canAccessProjectWithNCLogin(project)) {
username = this.username username = this.username
@@ -675,22 +689,66 @@ class VersatileProjectSyncClient(
} }
@Throws(JSONException::class, IOException::class, TokenMismatchException::class, NextcloudHttpRequestFailedException::class) @Throws(JSONException::class, IOException::class, TokenMismatchException::class, NextcloudHttpRequestFailedException::class)
fun getBills(project: DBProject): ServerResponse.BillsResponse { fun getBills(
project: DBProject,
offset: Int? = null,
limit: Int? = null,
reverse: Boolean? = null,
deleted: Int? = null
): ServerResponse.BillsResponse {
var target: String var target: String
var username: String? var username: String?
var password: String? var password: String?
var bearerToken: String? var bearerToken: String?
var useOcsApiRequest: Boolean var useOcsApiRequest: Boolean
val paramKeys: MutableList<String> = ArrayList()
val paramValues: MutableList<String> = ArrayList()
if (ProjectType.COSPEND == project.type) { if (ProjectType.COSPEND == project.type) {
val tsLastSync = project.lastSyncedTimestamp val tsLastSync = project.lastSyncedTimestamp
if (offset == null) {
if (cospendVersionGT161) {
paramKeys.add("lastChanged")
} else {
paramKeys.add("lastchanged")
}
paramValues.add(tsLastSync.toString())
} else {
paramKeys.add("offset")
paramValues.add(offset.toString())
if (limit != null) {
paramKeys.add("limit")
paramValues.add(limit.toString())
}
if (reverse != null) {
paramKeys.add("reverse")
paramValues.add(reverse.toString())
}
if (deleted != null) {
paramKeys.add("deleted")
paramValues.add(deleted.toString())
}
}
if (canAccessProjectWithNCLogin(project)) { if (canAccessProjectWithNCLogin(project)) {
username = this.username username = this.username
password = this.password password = this.password
target = if (cospendVersionGT161)
project.getRequestBaseUrl(true) + "/api/v1/projects/" + project.remoteId + "/bills?lastChanged=" + tsLastSync
else
project.getRequestBaseUrl(false) + "/api-priv/projects/" + project.remoteId + "/bills?lastchanged=" + tsLastSync
useOcsApiRequest = cospendVersionGT161 useOcsApiRequest = cospendVersionGT161
val baseUrl = project.getRequestBaseUrl(useOcsApiRequest)
target = if (useOcsApiRequest)
"$baseUrl/api/v1/projects/${project.remoteId}/bills"
else
"$baseUrl/api-priv/projects/${project.remoteId}/bills"
if (paramKeys.isNotEmpty()) {
target += "?"
for (i in paramKeys.indices) {
if (i > 0) target += "&"
target += "${paramKeys[i]}=${paramValues[i]}"
}
}
return ServerResponse.BillsResponse( return ServerResponse.BillsResponse(
requestServer( requestServer(
target, METHOD_GET, null, null, target, METHOD_GET, null, null,
@@ -699,14 +757,6 @@ class VersatileProjectSyncClient(
useOcsApiRequest useOcsApiRequest
) )
} else if (canAccessProjectWithSSO(project)) { } else if (canAccessProjectWithSSO(project)) {
val paramKeys: MutableList<String> = ArrayList()
val paramValues: MutableList<String> = ArrayList()
if (cospendVersionGT161) {
paramKeys.add("lastChanged")
} else {
paramKeys.add("lastchanged")
}
paramValues.add(tsLastSync.toString())
return if (cospendVersionGT161) { return if (cospendVersionGT161) {
target = "/ocs/v2.php/apps/cospend/api/v1/projects/" + project.remoteId + "/bills" target = "/ocs/v2.php/apps/cospend/api/v1/projects/" + project.remoteId + "/bills"
ServerResponse.BillsResponse(requestServerWithSSO(nextcloudAPI!!, target, METHOD_GET, paramKeys, paramValues, true), true) ServerResponse.BillsResponse(requestServerWithSSO(nextcloudAPI!!, target, METHOD_GET, paramKeys, paramValues, true), true)
@@ -716,10 +766,20 @@ class VersatileProjectSyncClient(
} }
} else { } else {
useOcsApiRequest = cospendVersionGT161 useOcsApiRequest = cospendVersionGT161
target = if (cospendVersionGT161) val baseUrl = project.getRequestBaseUrl(useOcsApiRequest)
project.getRequestBaseUrl(true) + "/api/v1/public/projects/" + project.remoteId + "/" + getEncodedPassword(project.password) + "/bills?lastChanged=" + tsLastSync target = if (useOcsApiRequest)
"$baseUrl/api/v1/public/projects/${project.remoteId}/${getEncodedPassword(project.password)}/bills"
else else
project.getRequestBaseUrl(false) + "/apiv2/projects/" + project.remoteId + "/" + getEncodedPassword(project.password) + "/bills?lastchanged=" + tsLastSync "$baseUrl/apiv2/projects/${project.remoteId}/${getEncodedPassword(project.password)}/bills"
if (paramKeys.isNotEmpty()) {
target += "?"
for (i in paramKeys.indices) {
if (i > 0) target += "&"
target += "${paramKeys[i]}=${paramValues[i]}"
}
}
return ServerResponse.BillsResponse( return ServerResponse.BillsResponse(
requestServer( requestServer(
target, METHOD_GET, null, null, target, METHOD_GET, null, null,
@@ -1470,5 +1530,8 @@ class VersatileProjectSyncClient(
const val METHOD_POST = "POST" const val METHOD_POST = "POST"
const val METHOD_PUT = "PUT" const val METHOD_PUT = "PUT"
const val METHOD_DELETE = "DELETE" const val METHOD_DELETE = "DELETE"
const val REMOTE_ARCHIVED_TS_NOW = 0L
const val REMOTE_ARCHIVED_TS_UNSET = -1L
} }
} }
@@ -5,9 +5,11 @@ fun evalMath(expression: String): Double {
var result = 0.0 var result = 0.0
var db: SQLiteDatabase? = null var db: SQLiteDatabase? = null
try { try {
// Force floating point division by replacing / with * 1.0 /
val forcedRealExpr = expression.replace("/", "* 1.0 /")
// Opens a temporary, in-memory system database block // Opens a temporary, in-memory system database block
db = SQLiteDatabase.create(null) db = SQLiteDatabase.create(null)
val cursor = db.rawQuery("SELECT ($expression);", null) val cursor = db.rawQuery("SELECT ($forcedRealExpr);", null)
if (cursor.moveToFirst()) { if (cursor.moveToFirst()) {
result = cursor.getDouble(0) result = cursor.getDouble(0)
} }
+39 -8
View File
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">New bill</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Add project</string> <string name="action_add_project">Add project</string>
@@ -8,7 +15,11 @@
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_open_menu">Open menu</string>
<string name="action_close_search">Close search</string>
<string name="action_clear_search">Clear search</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="simple_back">Back</string>
<string name="action_archive">Archive</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string> <string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string> <string name="action_export">Export</string>
@@ -23,6 +34,7 @@
<string name="action_members">Members</string> <string name="action_members">Members</string>
<string name="action_labels">Labels</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Currencies</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistics</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Edit project</string> <string name="title_edit_project">Edit project</string>
@@ -38,6 +50,7 @@
<string name="title_share_web">Web link</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Are you sure?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">All bills</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categories</string> <string name="label_categories">Categories</string>
@@ -61,6 +74,7 @@
<string name="label_project_id">Project ID/name</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project title</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Use Nextcloud App Account</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Unsaved changes</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Save changes before leaving?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
@@ -81,6 +95,7 @@
<string name="msg_stats_intro">Stats for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Member (Paid | Spent | Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Error</string> <string name="error_generic">Error</string>
<string name="error_loading">Loading</string> <string name="error_loading">Loading</string>
@@ -109,6 +124,7 @@
<string name="error_server">Server error</string> <string name="error_server">Server error</string>
<string name="error_io">Server connection broken</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Cannot share this project</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Connect to Nextcloud account</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
@@ -117,6 +133,7 @@
<string name="simple_yes">Yes</string> <string name="simple_yes">Yes</string>
<string name="simple_no">No</string> <string name="simple_no">No</string>
<string name="simple_close">Close</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Appearance</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Network</string> <string name="settings_network">Network</string>
@@ -129,15 +146,23 @@
<string name="settings_show_archived">Show archived projects</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WARNING: \"http\" is unsafe. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string> <string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string> <string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">No repeat</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Daily</string> <string name="repeat_day">Daily</string>
@@ -145,6 +170,7 @@
<string name="repeat_fortnight">Fortnightly</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Monthly</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Yearly</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">None</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_all">All</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_credit_card">Credit card</string> <string name="payment_mode_credit_card">Credit card</string>
@@ -152,6 +178,7 @@
<string name="payment_mode_check">Check</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">None</string> <string name="category_none">None</string>
<string name="category_all">All</string> <string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
@@ -167,17 +194,14 @@
<string name="category_accomodation">Accommodation</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">Where</string> <string name="new_project_where">Where</string>
<string name="where_local">Local only</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Join existing project</string> <string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string> <string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string> <string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string> <string name="no_projects_text">You have no projects yet.</string>
@@ -196,6 +220,7 @@
<string name="edit_member_dialog_title">Edit Member</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Delete</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">No changes to save.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">None (Optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Who pays</string> <string name="settle_who">Who pays</string>
@@ -204,12 +229,14 @@
<string name="simple_settle_share">Share</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Create bills</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Settlement</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Choose Currency (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">None</string> <string name="setting_none">None</string>
<string name="setting_all">All</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Currency settings saved.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Main Currency</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Suggested Categories</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Skip</string> <string name="label_bills_skip">Skip</string>
@@ -220,6 +247,7 @@
<string name="stats_spent">Spent</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Balance</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Connection failed: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
@@ -230,12 +258,15 @@
<string name="insufficient_access_level">You don\'t have permission to perform this action.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Delete Label</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Maintainer</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">License</string> <string name="about_license_title">License</string>
<string name="about_source_title">Source code</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Share %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+250 -219
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">نفق</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">فاتورة جديدة</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">إضافة مشروع</string> <string name="action_add_project">Add project</string>
<string name="action_save">حفظ</string> <string name="action_save">Save</string>
<string name="action_edit">تحرير</string> <string name="action_edit">Edit</string>
<string name="action_share">مشاركة</string> <string name="action_share">Share</string>
<string name="action_search">البحث</string> <string name="action_search">Search</string>
<string name="action_delete">حذف</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">أرشيف</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">إلغاء الأرشيف</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">تصدير</string> <string name="action_delete">Delete</string>
<string name="action_stats">إحصائيات</string> <string name="simple_back">Back</string>
<string name="action_settle">حسم</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">الإعدادات</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">فئات التسمية المفقودة</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">تسجيل الخروج</string> <string name="action_logout">Logout</string>
<string name="action_connect">الاتصال</string> <string name="action_connect">Connect</string>
<string name="action_discard">تجاهل</string> <string name="action_discard">Discard</string>
<string name="action_members">الأعضاء</string> <string name="action_members">Members</string>
<string name="action_labels">التسميات</string> <string name="action_labels">Labels</string>
<string name="action_currencies">العملات</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">الإحصائيات</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">تحرير المشروع</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">فواتير التسمية</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">إدارة التسميات</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">حول</string> <string name="title_about">About</string>
<string name="title_settle">تسوية المشروع</string> <string name="title_settle">Settle Project</string>
<string name="title_share">مشاركة المشروع</string> <string name="title_share">Share Project</string>
<string name="title_add_project">إضافة مشروع</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">إضافة فئة</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">إضافة وضع الدفع</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">حساب Nextcloud</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">رابط ويب</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">هل أنت متأكد؟</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">جميع الفواتير</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">الفئات</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">طرق الدفع</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">الاسم</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">اللون</string> <string name="label_color">Color</string>
<string name="label_weight">الوزن</string> <string name="label_weight">Weight</string>
<string name="label_activated">مُفعّل</string> <string name="label_activated">Activated</string>
<string name="label_password">كلمة المرور</string> <string name="label_password">Password</string>
<string name="label_email">البريد الإلكتروني</string> <string name="label_email">E-mail</string>
<string name="label_url">عنوان الخادم</string> <string name="label_url">Server address</string>
<string name="label_username">اسم المستخدم</string> <string name="label_username">Username</string>
<string name="label_comment">تعليق</string> <string name="label_comment">Comment</string>
<string name="label_what">ماذا؟</string> <string name="label_what">What?</string>
<string name="label_payer">من المدفوع؟</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">لمن؟</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">كرر كل</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">الوضع</string> <string name="label_mode">Mode</string>
<string name="label_category">الفئة</string> <string name="label_category">Category</string>
<string name="label_project_id">معرف/اسم المشروع</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">عنوان المشروع</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">استخدام حساب تطبيق Nextcloud</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">التغييرات غير المحفوظة</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">حفظ التغييرات قبل المغادرة؟</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">لن يتم حذف المشروع البعيد.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">خطأ في المزامنة</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">تم بالفعل موازنة المصروفات.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">تم إضافة المشروع %1$s</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">جميع الفواتير الموصوفة</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">لا توجد اقتراحات</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">يتطلب انفاق التكلفة v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">تم نسخ الرابط إلى الحافظة</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">امسح رمز QR أو شارك الرابط للانضمام.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">رابط للوصول إلى متصفح الويب.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">شارك هذا الرابط مع مستخدم مستهلك.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">التسوية ل %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s مدين %3$.2f ل %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">إحصائيات %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">عضو (رصيد مدفوع &lt;unk&gt; رصيد مدفوع)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">تم تسجيل الدخول كـ %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">خطأ</string> <string name="error_generic">Error</string>
<string name="error_loading">جاري التحميل</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">لم يتم العثور على مشاريع</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">لم يتم العثور على أعضاء</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">لم يتم العثور على فواتير</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">مطلوب عضو واحد على الأقل</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">الخادم في وضع الصيانة</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 طلب خاطئ</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 غير مأذون</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 محظور</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 غير موجود</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">فشلت المزامنة: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">تسجيل الدخول غير صالح: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">اسم المستخدم أو كلمة المرور خاطئة</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">استجابة الخادم غير صالحة</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">فشل الطلب</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">بريد إلكتروني غير صالح</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">معرف المشروع غير صالح</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">عنوان المشروع غير صالح</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">اسم الفاتورة غير صالح</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">تاريخ الفاتورة غير صالح</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">الدفع مطلوب</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">الحائزين مطلوبون</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">لا يوجد اتصال بالشبكة</string> <string name="error_no_network">No network connection</string>
<string name="error_server">خطأ في الخادم</string> <string name="error_server">Server error</string>
<string name="error_io">تم كسر اتصال الخادم</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">لا يمكن مشاركة هذا المشروع</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">الاتصال بحساب Nextcloud</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">آخر مزامنة: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">إلغاء</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">حسناً</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">نعم</string> <string name="simple_yes">Yes</string>
<string name="simple_no">لا</string> <string name="simple_no">No</string>
<string name="simple_close">أغلق</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">المظهر</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">الشبكة</string> <string name="settings_network">Network</string>
<string name="settings_other">اخرى</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">السمة</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">وضع غير متصل</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">فقط المزامنة يدوياً.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">لون مخصص</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">تحديد الألوان</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">إظهار المشاريع المؤرشفة</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">ميزات بيتا</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">تمكين الميزات التجريبية. استخدمها على مسؤوليتك الخاصة.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">تحذير: \"http\" غير آمن. استخدم \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">اختر اللون</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">النظام</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">السحابة التالية</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">دليل</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">فاتح</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">داكن</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">اتبع النظام</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">لا تكرّر</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">يومياً</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">أسبوعيا</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">نصف شهري</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">شهريا</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">سنوي</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">لا</string>
<string name="payment_mode_all">الكل</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">بطاقة الائتمان</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">نقدا</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">تحقق</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">متصل</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">نقل</string> <string name="payment_mode_online">Online</string>
<string name="category_none">لا</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">الكل</string>
<string name="category_all_except_reimbursement">جميع ما عدا رد التكاليف</string> <string name="category_none">None</string>
<string name="category_groceries">البقالة</string> <string name="category_all">All</string>
<string name="category_leisure">شريط/حفلة</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_rent">إيجار</string> <string name="category_groceries">Grocery</string>
<string name="category_bills">فاتورة</string> <string name="category_leisure">Bar/Party</string>
<string name="category_excursion">الرحلة/الثقافة</string> <string name="category_rent">Rent</string>
<string name="category_health">الصحة</string> <string name="category_bills">Bill</string>
<string name="category_shopping">التسوق</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_reimbursement">رد</string> <string name="category_health">Health</string>
<string name="category_restaurant">مطعم</string> <string name="category_shopping">Shopping</string>
<string name="category_accomodation">السكن</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_transport">النقل</string> <string name="category_restaurant">Restaurant</string>
<string name="category_sport">الرياضة</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string>
<string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">ماذا</string> <string name="new_project_action">What</string>
<string name="new_project_where">أين</string> <string name="new_project_where">Where</string>
<string name="where_local">محلي فقط</string> <string name="where_local">Local only</string>
<string name="where_cospend">انفاق التكلفة</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">الانضمام إلى المشروع الحالي</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">إنشاء مشروع جديد</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">استيراد من الملف</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">اختر المشروع</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">لا توجد مشاريع في هذا الحساب.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">مشروع</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">تمت إضافة المشروع بنجاح.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">ليس لديك مشاريع حتى الآن.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">تكوين حساب Nextcloud</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">إضافة مشروع يدوياً</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">لا يوجد أعضاء في هذا المشروع.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">لا توجد فواتير.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">العضو موجود مسبقا.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">المشروع: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">تمت إزالة المشروع %1$s.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">تم حفظ الملف: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">فشل الاستيراد في الصف %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">تنسيق التاريخ غير صالح في الصف %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">غير صالح في الصف %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">إضافة عضو</string>
<string name="edit_member_dialog_title">تعديل العضو</string>
<string name="member_edit_delete">حذف</string>
<string name="project_edition_no_change">لا توجد تغييرات للحفظ.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">لا شيء (مثالي)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">من يدفع</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">مَن</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">المبلغ</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">مشاركة</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">إنشاء فواتير</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">تسوية</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">اختر العملة (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">لا</string> <string name="setting_none">None</string>
<string name="setting_all">الكل</string> <string name="setting_all">All</string>
<string name="currency_saved_success">تم حفظ إعدادات العملة.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">العملة الرئيسية</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">الفئات المقترحة</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">تخطي</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">من</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">إلى</string> <string name="stats_date_max">To</string>
<string name="stats_who">عضو</string> <string name="stats_who">Member</string>
<string name="stats_paid">مدفوع</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">أنفق</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">الرصيد</string> <string name="stats_balance">Balance</string>
<string name="total">المجموع: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">فشل الاتصال: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">فشل الإنشاء: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">خطأ في تحديث المشروع البعيد: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">الشبكة غير متوفرة للتشغيل عن بعد.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">فشل تحليل رمز QR.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">عدم تطابق رمز المصادقة. الرجاء تسجيل الدخول مرة أخرى.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">ليس لديك الصلاحية للقيام بهذا الإجراء.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">حذف التسمية</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">هل أنت متأكد من أنك تريد حذف هذه التسمية؟</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">الإصدار %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">المشرف</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">الترخيص</string> <string name="about_license_title">License</string>
<string name="about_source_title">الكود المصدري</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">المشروع %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">مشاركة %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+39 -8
View File
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">New bill</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Add project</string> <string name="action_add_project">Add project</string>
@@ -8,7 +15,11 @@
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_open_menu">Open menu</string>
<string name="action_close_search">Close search</string>
<string name="action_clear_search">Clear search</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="simple_back">Back</string>
<string name="action_archive">Archive</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string> <string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string> <string name="action_export">Export</string>
@@ -23,6 +34,7 @@
<string name="action_members">Members</string> <string name="action_members">Members</string>
<string name="action_labels">Labels</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Currencies</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistics</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Edit project</string> <string name="title_edit_project">Edit project</string>
@@ -38,6 +50,7 @@
<string name="title_share_web">Web link</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Are you sure?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">All bills</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categories</string> <string name="label_categories">Categories</string>
@@ -61,6 +74,7 @@
<string name="label_project_id">Project ID/name</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project title</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Use Nextcloud App Account</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Unsaved changes</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Save changes before leaving?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
@@ -81,6 +95,7 @@
<string name="msg_stats_intro">Stats for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Member (Paid | Spent | Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Error</string> <string name="error_generic">Error</string>
<string name="error_loading">Loading</string> <string name="error_loading">Loading</string>
@@ -109,6 +124,7 @@
<string name="error_server">Server error</string> <string name="error_server">Server error</string>
<string name="error_io">Server connection broken</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Cannot share this project</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Connect to Nextcloud account</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
@@ -117,6 +133,7 @@
<string name="simple_yes">Yes</string> <string name="simple_yes">Yes</string>
<string name="simple_no">No</string> <string name="simple_no">No</string>
<string name="simple_close">Close</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Appearance</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Network</string> <string name="settings_network">Network</string>
@@ -129,15 +146,23 @@
<string name="settings_show_archived">Show archived projects</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WARNING: \"http\" is unsafe. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string> <string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string> <string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">No repeat</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Daily</string> <string name="repeat_day">Daily</string>
@@ -145,6 +170,7 @@
<string name="repeat_fortnight">Fortnightly</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Monthly</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Yearly</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">None</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_all">All</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_credit_card">Credit card</string> <string name="payment_mode_credit_card">Credit card</string>
@@ -152,6 +178,7 @@
<string name="payment_mode_check">Check</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">None</string> <string name="category_none">None</string>
<string name="category_all">All</string> <string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
@@ -167,17 +194,14 @@
<string name="category_accomodation">Accommodation</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">Where</string> <string name="new_project_where">Where</string>
<string name="where_local">Local only</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Join existing project</string> <string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string> <string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string> <string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string> <string name="no_projects_text">You have no projects yet.</string>
@@ -196,6 +220,7 @@
<string name="edit_member_dialog_title">Edit Member</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Delete</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">No changes to save.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">None (Optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Who pays</string> <string name="settle_who">Who pays</string>
@@ -204,12 +229,14 @@
<string name="simple_settle_share">Share</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Create bills</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Settlement</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Choose Currency (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">None</string> <string name="setting_none">None</string>
<string name="setting_all">All</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Currency settings saved.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Main Currency</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Suggested Categories</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Skip</string> <string name="label_bills_skip">Skip</string>
@@ -220,6 +247,7 @@
<string name="stats_spent">Spent</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Balance</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Connection failed: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
@@ -230,12 +258,15 @@
<string name="insufficient_access_level">You don\'t have permission to perform this action.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Delete Label</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Maintainer</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">License</string> <string name="about_license_title">License</string>
<string name="about_source_title">Source code</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Share %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+247 -216
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Vyčerpané krávy</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Nový účet</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Přidat projekt</string> <string name="action_add_project">Add project</string>
<string name="action_save">Uložit</string> <string name="action_save">Save</string>
<string name="action_edit">Upravit</string> <string name="action_edit">Edit</string>
<string name="action_share">Sdílet</string> <string name="action_share">Share</string>
<string name="action_search">Hledat</string> <string name="action_search">Search</string>
<string name="action_delete">Vymazat</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Archiv</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Zrušit archiv</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Exportovat</string> <string name="action_delete">Delete</string>
<string name="action_stats">Statistiky</string> <string name="simple_back">Back</string>
<string name="action_settle">Sada</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Nastavení</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Chybí kategorie</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Odhlásit se</string> <string name="action_logout">Logout</string>
<string name="action_connect">Připojit</string> <string name="action_connect">Connect</string>
<string name="action_discard">Zahodit</string> <string name="action_discard">Discard</string>
<string name="action_members">Členové</string> <string name="action_members">Members</string>
<string name="action_labels">Popisky</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Měny</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistiky</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Upravit projekt</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Etiketové účty</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Spravovat štítky</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">O aplikaci</string> <string name="title_about">About</string>
<string name="title_settle">Projekt settle</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Sdílet projekt</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Přidat projekt</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Přidat kategorii</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Přidat platební režim</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Nextcloud účet</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Webový odkaz</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Jste si jisti?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Všechny účty</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Kategorie</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Platební režimy</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Název</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Barva</string> <string name="label_color">Color</string>
<string name="label_weight">Hmotnost</string> <string name="label_weight">Weight</string>
<string name="label_activated">Aktivováno</string> <string name="label_activated">Activated</string>
<string name="label_password">Heslo</string> <string name="label_password">Password</string>
<string name="label_email">E-mail</string> <string name="label_email">E-mail</string>
<string name="label_url">Adresa serveru</string> <string name="label_url">Server address</string>
<string name="label_username">Uživatelské jméno</string> <string name="label_username">Username</string>
<string name="label_comment">Komentář</string> <string name="label_comment">Comment</string>
<string name="label_what">Co to znamená?</string> <string name="label_what">What?</string>
<string name="label_payer">Kdo zaplatil?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Pro koho?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Opakovat každý</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Režim</string> <string name="label_mode">Mode</string>
<string name="label_category">Kategorie</string> <string name="label_category">Category</string>
<string name="label_project_id">ID / název projektu</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Název projektu</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Použít Nextcloud účet aplikace</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Neuložené změny</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Uložit změny před odchodem?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Vzdálený projekt nebude odstraněn.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Chyba synchronizace</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Synchronizace se nezdařila pro %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Výdaje jsou již vyrovnané.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Projekt %1$s byl přidán</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Všechny účty jsou označeny</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Žádné návrhy</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Vyžaduje Cospend v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Odkaz zkopírován do schránky</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Naskenujte QR kód nebo sdílejte odkaz pro připojení.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Odkaz pro přístup k webovému prohlížeči.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Sdílejte tento odkaz s Cowspent uživatelem.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Vyrovnání pro %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s dluží %3$.2f %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Statistiky pro %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Člen (Placené | utraceno | Zůstatek)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Přihlášen jako %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Chyba</string> <string name="error_generic">Error</string>
<string name="error_loading">Načítání</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Nebyly nalezeny žádné projekty</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Nenalezeni žádní členové</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Nebyly nalezeny žádné účty</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Požadován alespoň jeden člen</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Server je v režimu údržby</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 špatný požadavek</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Neautorizováno</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 zakázáno</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Nenalezeno</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Synchronizace selhala: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Neplatné přihlášení: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Nesprávné uživatelské jméno nebo heslo</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Neplatná odpověď serveru</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Požadavek se nezdařil</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Neplatný e-mail</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Neplatné ID projektu</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Neplatný název projektu</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Neplatné jméno účtu</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Neplatné datum faktury</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Je vyžadován plátce</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Je vyžadován majitel</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Žádné připojení k síti</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Chyba serveru</string> <string name="error_server">Server error</string>
<string name="error_io">Připojení k serveru bylo přerušeno</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Nelze sdílet tento projekt</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Připojit k Nextcloud účtu</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Poslední synchronizace: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Zrušit</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Ano</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Ne</string> <string name="simple_no">No</string>
<string name="simple_close">Zavřít</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Vzhled</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Síť</string> <string name="settings_network">Network</string>
<string name="settings_other">Ostatní</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Téma</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Offline režim</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Synchronizovat pouze ručně.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Vlastní barva</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Výběr barvy</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Zobrazit archivované projekty</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta funkce</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Povolit experimentální funkce. Používejte na vlastní riziko.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">VAROVÁNÍ: \"http\" není bezpečné. Použijte \"https://\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Vybrat barvu</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">Systém</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">Ruční</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">Světlý</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">Tmavý</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">Sledovat systém</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Žádné opakování</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Denní</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Týdenní</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Čtvrtletní</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Měsíčně</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Roční</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Nic</string>
<string name="payment_mode_all">e</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Kreditní karta</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Hotovost</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Zkontrolovat</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Převod</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">Nic</string>
<string name="category_all">e</string> <string name="category_none">None</string>
<string name="category_all_except_reimbursement">Všechny kromě úhrady</string> <string name="category_all">All</string>
<string name="category_groceries">Slepičí</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_leisure">Čárka/Party</string> <string name="category_groceries">Grocery</string>
<string name="category_rent">Pronájem</string> <string name="category_leisure">Bar/Party</string>
<string name="category_bills">Faktura</string> <string name="category_rent">Rent</string>
<string name="category_excursion">Výstup/kultura</string> <string name="category_bills">Bill</string>
<string name="category_health">Zdraví</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_shopping">Nakupování</string> <string name="category_health">Health</string>
<string name="category_reimbursement">Náhrada</string> <string name="category_shopping">Shopping</string>
<string name="category_restaurant">Restaurace</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_accomodation">Ubytování</string> <string name="category_restaurant">Restaurant</string>
<string name="category_transport">Přeprava</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Co</string> <string name="new_project_action">What</string>
<string name="new_project_where">Kde</string> <string name="new_project_where">Where</string>
<string name="where_local">Pouze místní</string> <string name="where_local">Local only</string>
<string name="where_cospend">Koutracení</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IhateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Připojit se k existujícímu projektu</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Vytvořit nový projekt</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Importovat ze souboru</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Vybrat projekt</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Na tomto účtu nebyly nalezeny žádné projekty.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Projekt</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Projekt byl úspěšně přidán.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Zatím nemáte žádné projekty.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Konfigurovat Nextcloud účet</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Přidat projekt ručně</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Žádní členové tohoto projektu.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Nebyly nalezeny žádné účty.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Člen již existuje.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">Projekt: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">Projekt %1$s byl odstraněn.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">Soubor uložen: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">Import se nezdařil na řádku %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">Neplatný formát data na řádku %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">Neplatné dlužníky na řádku %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">Přidat člena</string>
<string name="edit_member_dialog_title">Upravit člena</string>
<string name="member_edit_delete">Vymazat</string>
<string name="project_edition_no_change">Žádné změny k uložení.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Žádný (optimální)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Kdo zaplatí</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">komu</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Částka, která má být získána</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Sdílet</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Vytvořit účty</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Vypořádání</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Vybrat měnu (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Nic</string> <string name="setting_none">None</string>
<string name="setting_all">Vše</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Nastavení měny uloženo.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Hlavní měna</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Navrhované kategorie</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Přeskočit</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">Od</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">Komu</string> <string name="stats_date_max">To</string>
<string name="stats_who">Člen</string> <string name="stats_who">Member</string>
<string name="stats_paid">Zaplaceno</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Utraceno</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Zůstatek</string> <string name="stats_balance">Balance</string>
<string name="total">Celkem: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Připojení se nezdařilo: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Vytvoření selhalo: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Chyba při aktualizaci vzdáleného projektu: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Síť není k dispozici pro vzdálenou operaci.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Nepodařilo se zpracovat QR kód.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Ověřovací token se neshoduje. Přihlaste se znovu.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Nemáte oprávnění k provedení této akce.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Odstranit štítek</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Jste si jisti, že chcete odstranit tento štítek?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Verze %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Správce</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Licence</string> <string name="about_license_title">License</string>
<string name="about_source_title">Zdrojový kód</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Projekt %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Sdílet %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+240 -209
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Kowbrugt</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Ny regning</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Tilføj projekt</string> <string name="action_add_project">Add project</string>
<string name="action_save">Gem</string> <string name="action_save">Save</string>
<string name="action_edit">Rediger</string> <string name="action_edit">Edit</string>
<string name="action_share">Del</string> <string name="action_share">Share</string>
<string name="action_search">Søg</string> <string name="action_search">Search</string>
<string name="action_delete">Slet</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Arkiv</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Fjern Arkiv</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Eksporter</string> <string name="action_delete">Delete</string>
<string name="action_stats">Statistik</string> <string name="simple_back">Back</string>
<string name="action_settle">Afregn</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Indstillinger</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Etiket mangler kategorier</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Log Ud</string> <string name="action_logout">Logout</string>
<string name="action_connect">Forbind</string> <string name="action_connect">Connect</string>
<string name="action_discard">Kassér</string> <string name="action_discard">Discard</string>
<string name="action_members">Medlemmer</string> <string name="action_members">Members</string>
<string name="action_labels">Etiketter</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Valutaer</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistik</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Rediger projekt</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Etiketregninger</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Administrer Etiketter</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">Om</string> <string name="title_about">About</string>
<string name="title_settle">Afregn Projekt</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Del Projekt</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Tilføj Projekt</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Tilføj Kategori</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Tilføj Betalingstilstand</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Nextcloud Konto</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Weblink</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Er du sikker?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Alle regninger</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Kategorier</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Betalingstilstande</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Navn</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Farve</string> <string name="label_color">Color</string>
<string name="label_weight">Vægt</string> <string name="label_weight">Weight</string>
<string name="label_activated">Aktiveret</string> <string name="label_activated">Activated</string>
<string name="label_password">Adgangskode</string> <string name="label_password">Password</string>
<string name="label_email">E-mail</string> <string name="label_email">E-mail</string>
<string name="label_url">Server adresse</string> <string name="label_url">Server address</string>
<string name="label_username">Brugernavn</string> <string name="label_username">Username</string>
<string name="label_comment">Kommentar</string> <string name="label_comment">Comment</string>
<string name="label_what">Hvad?</string> <string name="label_what">What?</string>
<string name="label_payer">Hvem betalte?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">For hvem?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Gentag hver</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Tilstand</string> <string name="label_mode">Mode</string>
<string name="label_category">Kategori</string> <string name="label_category">Category</string>
<string name="label_project_id">Projekt ID/navn</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Projektets titel</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Brug Nextcloud App-konto</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Ikke-gemte ændringer</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Gem ændringer før afrejsen?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Fjernprojektet vil ikke blive slettet.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Synkronisering fejl</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Synkronisering mislykkedes for %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Udgifterne er allerede afbalancerede.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Projekt %1$s tilføjet</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Alle regninger mærket</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Ingen forslag</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Kræver Cospend v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Link kopieret til udklipsholder</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Scan QR-kode eller del linket for at deltage.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Link til webbrowser-adgang.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Del dette link med en Cowspent bruger.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Udligning for %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s skylder %3$.2f til %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Statistik for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Medlem (Betalt - Spent - Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logget ind som %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Fejl</string> <string name="error_generic">Error</string>
<string name="error_loading">Indlæser</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Ingen projekter fundet</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Ingen medlemmer fundet</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Ingen regninger fundet</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Mindst et medlem kræves</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Serveren er i vedligeholdelsestilstand</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 Dårlig forespørgsel</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Uautoriseret</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Forbudt</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Ikke Fundet</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Synkronisering mislykkedes: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Ugyldigt login: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Forkert brugernavn eller adgangskode</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Ugyldigt serversvar</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Anmodning mislykkedes</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Ugyldig e-mail</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Ugyldigt projekt ID</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Ugyldig projekttitel</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Ugyldigt regnings navn</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Ugyldig faktureringsdato</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Betaler påkrævet</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Ejere påkrævet</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Ingen netværksforbindelse</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Server fejl</string> <string name="error_server">Server error</string>
<string name="error_io">Server forbindelse ødelagt</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Kan ikke dele dette projekt</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Opret forbindelse til Nextcloud konto</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Seneste synkronisering: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Annuller</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">OK</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Ja</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Nej</string> <string name="simple_no">No</string>
<string name="simple_close">Luk</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Udseende</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Netrk</string> <string name="settings_network">Network</string>
<string name="settings_other">Andet</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Tema</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Offline tilstand</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Synkroniser kun manuelt.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Brugerdefineret farve</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Valg Af Farver</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Vis arkiverede projekter</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Funktioner</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Aktiver eksperimentelle funktioner. Brug på egen risiko.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">ADVARSEL: \"http\" er usikkert. Brug \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Vælg Farve</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_color_manual">Manuelt</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_light">Lys</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_dark">Mørk</string> <string name="pref_value_theme_system">Follow system</string>
<string name="pref_value_theme_system">Følg system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Ingen gentagelse</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Dagligt</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Ugentlig</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Fortnightly</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Månedligt</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Årligt</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Ingen</string>
<string name="payment_mode_all">Alle</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Kreditkort</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Kontant</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Tjek</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Overfør</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">Ingen</string>
<string name="category_all">Alle</string> <string name="category_none">None</string>
<string name="category_all_except_reimbursement">Alle undtagen refusion</string> <string name="category_all">All</string>
<string name="category_groceries">Køller</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_groceries">Grocery</string>
<string name="category_leisure">Bar/Party</string> <string name="category_leisure">Bar/Party</string>
<string name="category_rent">Leje</string> <string name="category_rent">Rent</string>
<string name="category_bills">Regning</string> <string name="category_bills">Bill</string>
<string name="category_excursion">Udflugter/Kultur</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_health">Sundhed</string> <string name="category_health">Health</string>
<string name="category_shopping">Shopping</string> <string name="category_shopping">Shopping</string>
<string name="category_reimbursement">Tilbagebetaling</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_restaurant">Restaurant</string> <string name="category_restaurant">Restaurant</string>
<string name="category_accomodation">Overnatning</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Hvad</string> <string name="new_project_action">What</string>
<string name="new_project_where">Hvor</string> <string name="new_project_where">Where</string>
<string name="where_local">Kun lokalt</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospendér</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Deltag i eksisterende projekt</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Opret nyt projekt</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Importer fra fil</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Vælg projekt</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Ingen projekter fundet på denne konto.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Projekt</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Projekt tilføjet.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Du har endnu ingen projekter.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Konfigurer Nextcloud konto</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Tilføj projekt manuelt</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Ingen medlemmer i dette projekt.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Ingen regninger fundet.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Medlemmet findes allerede.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">Projekt: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">Projekt %1$s fjernet.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">Fil gemt: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">Import mislykkedes ved række %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">Ugyldigt datoformat ved række %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">Ugyldige ejere ved række %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">Tilføj Medlem</string>
<string name="edit_member_dialog_title">Rediger Medlem</string>
<string name="member_edit_delete">Slet</string>
<string name="project_edition_no_change">Ingen ændringer at gemme.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Ingen (Optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Hvem betaler</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">Til hvem</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Beløb</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Del</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Opret regninger</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Afregning</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Vælg Valuta (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Ingen</string> <string name="setting_none">None</string>
<string name="setting_all">Alle</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Valuta indstillinger gemt.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Primær Valuta</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Foreslåede Kategorier</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Overspring</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">Fra</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">Til</string> <string name="stats_date_max">To</string>
<string name="stats_who">Medlem</string> <string name="stats_who">Member</string>
<string name="stats_paid">Betalt</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Brugt</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Saldo</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Forbindelse fejlede: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Oprettelse fejlede: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Fejl under opdatering af fjernprojekt: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Netrk utilgængeligt for fjernbetjening.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Kunne ikke fortolke QR-kode.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Godkendelse token mismatch. Log venligst ind igen.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Du har ikke tilladelse til at udføre denne handling.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Slet Etiket</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Er du sikker på, at du vil slette denne etiket?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Vedligeholder</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Licens</string> <string name="about_license_title">License</string>
<string name="about_source_title">Kilde kode</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Projekt %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Del %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+59 -37
View File
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Kuh ausgegeben</string>
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Neue Rechnung</string> <string name="action_new_bill">Neue Rechnung</string>
<string name="action_add_project">Projekt hinzufügen</string> <string name="action_add_project">Projekt hinzufügen</string>
@@ -8,40 +9,46 @@
<string name="action_edit">Bearbeiten</string> <string name="action_edit">Bearbeiten</string>
<string name="action_share">Teilen</string> <string name="action_share">Teilen</string>
<string name="action_search">Suchen</string> <string name="action_search">Suchen</string>
<string name="action_open_menu">Menü öffnen</string>
<string name="action_close_search">Suche schließen</string>
<string name="action_clear_search">Suche leeren</string>
<string name="action_delete">Löschen</string> <string name="action_delete">Löschen</string>
<string name="simple_back">Zurück</string>
<string name="action_archive">Archivieren</string> <string name="action_archive">Archivieren</string>
<string name="action_unarchive">Archivieren</string> <string name="action_unarchive">Reaktivieren</string>
<string name="action_export">Exportieren</string> <string name="action_export">Exportieren</string>
<string name="action_stats">Statistik</string> <string name="action_stats">Statistik</string>
<string name="action_settle">Abrechnen</string> <string name="action_settle">Abrechnen</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">QR Code einscannen</string>
<string name="action_settings">Einstellungen</string> <string name="action_settings">Einstellungen</string>
<string name="action_label_bills">Fehlende Kategorien</string> <string name="action_label_bills">Fehlende Kategorien</string>
<string name="action_logout">Abmelden</string> <string name="action_logout">Abmelden</string>
<string name="action_connect">Verbinden</string> <string name="action_connect">Verbinden</string>
<string name="action_discard">Verwerfen</string> <string name="action_discard">Verwerfen</string>
<string name="action_members">Mitglieder</string> <string name="action_members">Mitglieder</string>
<string name="action_labels">Etiketten</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Währungen</string> <string name="action_currencies">Währungen</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistiken</string> <string name="title_stats">Statistiken</string>
<string name="title_edit_project">Projekt bearbeiten</string> <string name="title_edit_project">Projekt bearbeiten</string>
<string name="title_label_bills">Etikett Rechnungen</string> <string name="title_label_bills">Rechnungen kennzeichnen</string>
<string name="title_labels">Labels verwalten</string> <string name="title_labels">Labels verwalten</string>
<string name="title_about">Über</string> <string name="title_about">Über</string>
<string name="title_settle">Projekt regeln</string> <string name="title_settle">Projekt abrechnen</string>
<string name="title_share">Projekt teilen</string> <string name="title_share">Projekt teilen</string>
<string name="title_add_project">Projekt hinzufügen</string> <string name="title_add_project">Projekt hinzufügen</string>
<string name="title_add_category">Neue Kategorie</string> <string name="title_add_category">Neue Kategorie</string>
<string name="title_add_payment_mode">Zahlungsmodus hinzufügen</string> <string name="title_add_payment_mode">Zahlungsmethode hinzufügen</string>
<string name="title_account">Nächstes Cloud-Konto</string> <string name="title_account">Nextcloud-Konto</string>
<string name="title_share_web">Weblink</string> <string name="title_share_web">Weblink</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Bist du sicher?</string> <string name="title_confirm">Bist du sicher?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Alle Rechnungen</string> <string name="label_all_bills">Alle Rechnungen</string>
<string name="label_categories">Kategorien</string> <string name="label_categories">Kategorien</string>
<string name="label_payment_modes">Zahlungsarten</string> <string name="label_payment_modes">Zahlungsmethoden</string>
<string name="label_name">Name</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Farbe</string> <string name="label_color">Farbe</string>
@@ -61,26 +68,28 @@
<string name="label_project_id">Projekt-ID/Name</string> <string name="label_project_id">Projekt-ID/Name</string>
<string name="label_project_title">Projekttitel</string> <string name="label_project_title">Projekttitel</string>
<string name="label_use_sso">Nextcloud App-Konto verwenden</string> <string name="label_use_sso">Nextcloud App-Konto verwenden</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Ungespeicherte Änderungen</string> <string name="dialog_unsaved_changes_title">Ungespeicherte Änderungen</string>
<string name="dialog_unsaved_changes_msg">Änderungen vor dem Verlassen speichern?</string> <string name="dialog_unsaved_changes_msg">Änderungen vor dem Verlassen speichern?</string>
<string name="dialog_confirm_remove_project_msg">Das entfernte Projekt wird nicht gelöscht.</string> <string name="dialog_confirm_remove_project_msg">Das Remote-Projekt wird nicht gelöscht.</string>
<string name="dialog_sync_error_title">Sync-Fehler</string> <string name="dialog_sync_error_title">Sync-Fehler</string>
<string name="dialog_sync_error_msg">Synchronisation fehlgeschlagen für %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Synchronisation fehlgeschlagen für %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Die Ausgaben sind bereits ausgeglichen.</string> <string name="dialog_balanced_msg">Die Ausgaben sind bereits ausgeglichen.</string>
<string name="msg_project_added">Projekt %1$s hinzugefügt</string> <string name="msg_project_added">Projekt %1$s hinzugefügt</string>
<string name="msg_bill_labeled_done">Alle Rechnungen markiert</string> <string name="msg_bill_labeled_done">Alle Rechnungen kategorisiert</string>
<string name="msg_no_suggestions">Keine Vorschläge</string> <string name="msg_no_suggestions">Keine Vorschläge</string>
<string name="msg_auth_warning">Benötigt Cospend v0.3.4+.</string> <string name="msg_auth_warning">Benötigt Cospend v0.3.4+.</string>
<string name="msg_link_copied">Link in Zwischenablage kopiert</string> <string name="msg_link_copied">Link in Zwischenablage kopiert</string>
<string name="msg_share_qr">Scannen Sie QR-Code oder teilen Sie den Link, um beizutreten.</string> <string name="msg_share_qr">Scanne den QR-Code oder teile den Link, um beizutreten.</string>
<string name="msg_share_web">Link für den Zugriff auf Web-Browser.</string> <string name="msg_share_web">Link für den Zugriff per Web-Browser.</string>
<string name="msg_share_qr_warn">Teilen Sie diesen Link mit einem Cowspent Benutzer.</string> <string name="msg_share_qr_warn">Teile diesen Link mit einem Cowspent Benutzer.</string>
<string name="msg_settle_intro">Abrechnung für %1$s:</string> <string name="msg_settle_intro">Abrechnung für %1$s:</string>
<string name="msg_settle_sentence">%1$s schuldet %3$.2f %2$s</string> <string name="msg_settle_sentence">%1$s schuldet %3$.2f an %2$s</string>
<string name="msg_stats_intro">Statistiken für %1$s:</string> <string name="msg_stats_intro">Statistiken für %1$s:</string>
<string name="msg_stats_header">Mitglied (Paid | Ausgaben | Guthaben)</string> <string name="msg_stats_header">Mitglied (Gezahlt | Ausgegeben | Saldo)</string>
<string name="msg_logged_in_as">Angemeldet als %1$s</string> <string name="msg_logged_in_as">Angemeldet als %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Fehler</string> <string name="error_generic">Fehler</string>
<string name="error_loading">Lädt</string> <string name="error_loading">Lädt</string>
@@ -104,11 +113,12 @@
<string name="error_invalid_bill_name">Ungültiger Rechnungsname</string> <string name="error_invalid_bill_name">Ungültiger Rechnungsname</string>
<string name="error_invalid_bill_date">Ungültiges Rechnungsdatum</string> <string name="error_invalid_bill_date">Ungültiges Rechnungsdatum</string>
<string name="error_invalid_bill_payer">Zahler erforderlich</string> <string name="error_invalid_bill_payer">Zahler erforderlich</string>
<string name="error_invalid_bill_owers">Eigene erforderlich</string> <string name="error_invalid_bill_owers">Schuldner erforderlich</string>
<string name="error_no_network">Keine Netzwerkverbindung</string> <string name="error_no_network">Keine Netzwerkverbindung</string>
<string name="error_server">Serverfehler</string> <string name="error_server">Serverfehler</string>
<string name="error_io">Serververbindung defekt</string> <string name="error_io">Serververbindung getrennt</string>
<string name="error_share_impossible">Dieses Projekt kann nicht geteilt werden</string> <string name="error_share_impossible">Dieses Projekt kann nicht geteilt werden</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Mit Nextcloud Konto verbinden</string> <string name="drawer_no_account">Mit Nextcloud Konto verbinden</string>
<string name="drawer_last_sync">Letzter Sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Letzter Sync: %1$02d:%2$02d</string>
@@ -117,6 +127,7 @@
<string name="simple_yes">Ja</string> <string name="simple_yes">Ja</string>
<string name="simple_no">Nein</string> <string name="simple_no">Nein</string>
<string name="simple_close">Schließen</string> <string name="simple_close">Schließen</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Erscheinung</string> <string name="settings_appearance">Erscheinung</string>
<string name="settings_network">Netzwerk</string> <string name="settings_network">Netzwerk</string>
@@ -129,58 +140,63 @@
<string name="settings_show_archived">Archivierte Projekte anzeigen</string> <string name="settings_show_archived">Archivierte Projekte anzeigen</string>
<string name="settings_beta_features">Beta-Funktionen</string> <string name="settings_beta_features">Beta-Funktionen</string>
<string name="settings_beta_features_summary">Experimentelle Funktionen aktivieren. Benutzung auf eigene Gefahr.</string> <string name="settings_beta_features_summary">Experimentelle Funktionen aktivieren. Benutzung auf eigene Gefahr.</string>
<string name="settings_url_warn_http">WARNUNG: \"http\" ist unsicher. Verwenden Sie \"https\".</string> <string name="settings_fill_new_bill_from_last">Aus letzter Rechnung vorausfüllen</string>
<string name="settings_fill_new_bill_from_last_summary">Zahler, Kategorie, Zahlungsart und Beteiligte aus der zuletzt erstellten Rechnung des Projekts übernehmen.</string>
<string name="settings_auto_sync_on_open">Synchronisierungsintervall</string>
<string name="settings_auto_sync_on_open_summary">Wie oft Konto und alle Projekte beim Öffnen der App aktualisiert werden.</string>
<string name="pref_value_sync_1m">1 Minute</string>
<string name="pref_value_sync_10m">10 Minuten</string>
<string name="pref_value_sync_1h">1 Stunde</string>
<string name="pref_value_sync_1d">1 Tag</string>
<string name="settings_url_warn_http">WARNUNG: \"http\" ist unsicher. Verwende \"https\".</string>
<string name="settings_colorpicker_title">Farbe wählen</string> <string name="settings_colorpicker_title">Farbe wählen</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nächste Cloud</string>
<string name="pref_value_color_manual">Manuell</string> <string name="pref_value_color_manual">Manuell</string>
<string name="pref_value_theme_light">Hell</string> <string name="pref_value_theme_light">Hell</string>
<string name="pref_value_theme_dark">Dunkel</string> <string name="pref_value_theme_dark">Dunkel</string>
<string name="pref_value_theme_system">System folgen</string> <string name="pref_value_theme_system">System folgen</string>
<!-- Constants (Do not translate) --> <!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Keine Wiederholung</string> <string name="repeat_no">Keine Wiederholung</string>
<string name="repeat_day">Täglich</string> <string name="repeat_day">Täglich</string>
<string name="repeat_week">Wöchentlich</string> <string name="repeat_week">Wöchentlich</string>
<string name="repeat_fortnight">Vierzehn</string> <string name="repeat_fortnight">Vierzehntägig</string>
<string name="repeat_month">Monatlich</string> <string name="repeat_month">Monatlich</string>
<string name="repeat_year">Jährlich</string> <string name="repeat_year">Jährlich</string>
<string name="payment_mode_none">Keine</string> <string name="payment_mode_none">Keine</string>
<string name="payment_mode_all">Alle</string> <string name="payment_mode_all">Alle</string>
<string name="payment_mode_credit_card">Kreditkarte</string> <string name="payment_mode_credit_card">Kreditkarte</string>
<string name="payment_mode_cash">Bargeld</string> <string name="payment_mode_cash">Bargeld</string>
<string name="payment_mode_check">Prüfen</string> <string name="payment_mode_check">Scheck</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Überweisung</string> <string name="payment_mode_transfer">Überweisung</string>
<string name="category_none">Keine</string> <string name="category_none">Keine</string>
<string name="category_all">Alle</string> <string name="category_all">Alle</string>
<string name="category_all_except_reimbursement">Alle außer Rückerstattung</string> <string name="category_all_except_reimbursement">Alle außer Erstattung</string>
<string name="category_groceries">Fleischgerichte</string> <string name="category_groceries">Lebensmittel</string>
<string name="category_leisure">Bar/Party</string> <string name="category_leisure">Bar/Party</string>
<string name="category_rent">Miete</string> <string name="category_rent">Miete</string>
<string name="category_bills">Abrechnung</string> <string name="category_bills">Abrechnung</string>
<string name="category_excursion">Ausflug/Kultur</string> <string name="category_excursion">Ausflug/Kultur</string>
<string name="category_health">Gesundheit</string> <string name="category_health">Gesundheit</string>
<string name="category_shopping">Einkaufen</string> <string name="category_shopping">Einkaufen</string>
<string name="category_reimbursement">Rückzahlung</string> <string name="category_reimbursement">Erstattung</string>
<string name="category_restaurant">Restaurant</string> <string name="category_restaurant">Restaurant</string>
<string name="category_accomodation">Unterkunft</string> <string name="category_accomodation">Unterkunft</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Was</string> <string name="new_project_action">Was</string>
<string name="new_project_where">Wo</string> <string name="new_project_where">Wo</string>
<string name="where_local">Nur lokal</string> <string name="where_local">Nur lokal</string>
<string name="where_cospend">Ko-Ausgaben</string> <string name="todo_join">Bestehendem Projekt beitreten</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Bestehendes Projekt beitreten</string>
<string name="todo_create">Neues Projekt erstellen</string> <string name="todo_create">Neues Projekt erstellen</string>
<string name="import_tooltip">Aus Datei importieren</string> <string name="import_tooltip">Aus Datei importieren</string>
<string name="choose_account_project_dialog_title">Projekt auswählen</string>
<string name="choose_account_project_dialog_impossible">Keine Projekte auf diesem Konto gefunden.</string>
<string name="choose_project_management_action">Projekt</string> <string name="choose_project_management_action">Projekt</string>
<string name="project_added_success">Projekt erfolgreich hinzugefügt.</string> <string name="project_added_success">Projekt erfolgreich hinzugefügt.</string>
<string name="no_projects_text">Sie haben noch keine Projekte.</string> <string name="no_projects_text">Du hast noch keine Projekte.</string>
<string name="configure_account_choice">Nextcloud-Konto konfigurieren</string> <string name="configure_account_choice">Nextcloud-Konto konfigurieren</string>
<string name="add_project_choice">Projekt manuell hinzufügen</string> <string name="add_project_choice">Projekt manuell hinzufügen</string>
<string name="no_members_text">Keine Mitglieder in diesem Projekt.</string> <string name="no_members_text">Keine Mitglieder in diesem Projekt.</string>
@@ -191,11 +207,12 @@
<string name="file_saved_success">Datei gespeichert: %1$s</string> <string name="file_saved_success">Datei gespeichert: %1$s</string>
<string name="import_error_header">Import fehlgeschlagen in Zeile %d</string> <string name="import_error_header">Import fehlgeschlagen in Zeile %d</string>
<string name="import_error_date">Ungültiges Datumsformat in Zeile %d</string> <string name="import_error_date">Ungültiges Datumsformat in Zeile %d</string>
<string name="import_error_owers">Ungültige Eigener in Zeile %d</string> <string name="import_error_owers">Ungültige Schuldner in Zeile %d</string>
<string name="add_member_dialog_title">Mitglied hinzufügen</string> <string name="add_member_dialog_title">Mitglied hinzufügen</string>
<string name="edit_member_dialog_title">Mitglied bearbeiten</string> <string name="edit_member_dialog_title">Mitglied bearbeiten</string>
<string name="member_edit_delete">Löschen</string> <string name="member_edit_delete">Löschen</string>
<string name="project_edition_no_change">Keine zu speichernden Änderungen.</string> <string name="project_edition_no_change">Keine zu speichernden Änderungen.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Keine (optimal)</string> <string name="center_none">Keine (optimal)</string>
<string name="settle_who">Wer zahlt</string> <string name="settle_who">Wer zahlt</string>
@@ -204,12 +221,14 @@
<string name="simple_settle_share">Teilen</string> <string name="simple_settle_share">Teilen</string>
<string name="simple_create_bills">Rechnungen erstellen</string> <string name="simple_create_bills">Rechnungen erstellen</string>
<string name="settle_bill_what">Abrechnung</string> <string name="settle_bill_what">Abrechnung</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Währung wählen (%s)</string> <string name="currency_dialog_title">Währung wählen (%s)</string>
<string name="setting_none">Keine</string> <string name="setting_none">Keine</string>
<string name="setting_all">Alle</string> <string name="setting_all">Alle</string>
<string name="currency_saved_success">Währungseinstellungen gespeichert.</string> <string name="currency_saved_success">Währungseinstellungen gespeichert.</string>
<string name="main_currency">Hauptwährung</string> <string name="main_currency">Hauptwährung</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Empfohlene Kategorien</string> <string name="label_bills_suggested">Empfohlene Kategorien</string>
<string name="label_bills_skip">Überspringen</string> <string name="label_bills_skip">Überspringen</string>
@@ -220,21 +239,24 @@
<string name="stats_spent">Ausgegeben</string> <string name="stats_spent">Ausgegeben</string>
<string name="stats_balance">Saldo</string> <string name="stats_balance">Saldo</string>
<string name="total">Gesamt: %1$s</string> <string name="total">Gesamt: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Verbindung fehlgeschlagen: %1$s</string> <string name="error_project_connect_check">Verbindung fehlgeschlagen: %1$s</string>
<string name="error_create_remote_project_helper">Erstellung fehlgeschlagen: %1$s</string> <string name="error_create_remote_project_helper">Erstellung fehlgeschlagen: %1$s</string>
<string name="error_edit_remote_project_helper">Fehler beim Aktualisieren des fernen Projekts: %1$s</string> <string name="error_edit_remote_project_helper">Fehler beim Aktualisieren des Remote-Projekts: %1$s</string>
<string name="remote_project_operation_no_network">Netzwerk nicht verfügbar für Remote Operation.</string> <string name="remote_project_operation_no_network">Netzwerk nicht verfügbar für Remote Operation.</string>
<string name="error_scanning_bill_qr_code">Fehler beim Analysieren des QR-Codes.</string> <string name="error_scanning_bill_qr_code">Fehler beim Analysieren des QR-Codes.</string>
<string name="error_token_mismatch">Authentifizierungstoken stimmen nicht überein. Bitte melden Sie sich erneut an.</string> <string name="error_token_mismatch">Authentifizierungstoken stimmen nicht überein. Bitte melde dich erneut an.</string>
<string name="insufficient_access_level">Sie haben keine Berechtigung, um diese Aktion durchzuführen.</string> <string name="insufficient_access_level">Du hast keine Berechtigung, um diese Aktion durchzuführen.</string>
<string name="delete_label_confirmation_title">Label löschen</string> <string name="delete_label_confirmation_title">Kategorie löschen</string>
<string name="delete_label_confirmation_message">Sind Sie sicher, dass Sie diese Bezeichnung löschen möchten?</string> <string name="delete_label_confirmation_message">Bist du sicher, dass du diese Kategorie löschen möchtest?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Betreuer</string> <string name="about_maintainer_title">Betreuer</string>
<string name="about_license_title">Lizenz</string> <string name="about_license_title">Lizenz</string>
<string name="about_source_title">Quellcode</string> <string name="about_source_title">Quellcode</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Projekt %1$s</string> <string name="share_intent_title">Projekt %1$s</string>
<string name="share_chooser_title">Teilen %1$s</string> <string name="share_chooser_title">Teilen %1$s</string>
+249 -218
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Έλαιο</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Νέος λογαριασμός</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Προσθήκη έργου</string> <string name="action_add_project">Add project</string>
<string name="action_save">Αποθήκευση</string> <string name="action_save">Save</string>
<string name="action_edit">Επεξεργασία</string> <string name="action_edit">Edit</string>
<string name="action_share">Κοινοποίηση</string> <string name="action_share">Share</string>
<string name="action_search">Αναζήτηση</string> <string name="action_search">Search</string>
<string name="action_delete">Διαγραφή</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Αρχειοθέτηση</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Αποσυμπιεσμένο</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Εξαγωγή</string> <string name="action_delete">Delete</string>
<string name="action_stats">Στατιστικά</string> <string name="simple_back">Back</string>
<string name="action_settle">Διευθέτηση</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Ρυθμίσεις</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Λείπει η ετικέτα κατηγορίες</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Αποσύνδεση</string> <string name="action_logout">Logout</string>
<string name="action_connect">Σύνδεση</string> <string name="action_connect">Connect</string>
<string name="action_discard">Απορρίψτε</string> <string name="action_discard">Discard</string>
<string name="action_members">Μέλη</string> <string name="action_members">Members</string>
<string name="action_labels">Ετικέτες</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Νομίσματα</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Στατιστικά</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Επεξεργασία έργου</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Λογαριασμοί Ετικέτας</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Διαχείριση Ετικετών</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">Σχετικά</string> <string name="title_about">About</string>
<string name="title_settle">Διευθέτηση Έργου</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Μοιραστείτε Το Έργο</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Προσθήκη Έργου</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Προσθήκη Κατηγορίας</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Προσθήκη Λειτουργίας Πληρωμής</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Λογαριασμός Nextcloud</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Σύνδεσμος ιστού</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Είσαι σίγουρος?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Όλοι οι λογαριασμοί</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Κατηγορίες</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Τρόποι Πληρωμής</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Όνομα</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Χρώμα</string> <string name="label_color">Color</string>
<string name="label_weight">Βάρος</string> <string name="label_weight">Weight</string>
<string name="label_activated">Ενεργοποιήθηκε</string> <string name="label_activated">Activated</string>
<string name="label_password">Κωδικός</string> <string name="label_password">Password</string>
<string name="label_email">E-mail</string> <string name="label_email">E-mail</string>
<string name="label_url">Διεύθυνση διακομιστή</string> <string name="label_url">Server address</string>
<string name="label_username">Όνομα Χρήστη</string> <string name="label_username">Username</string>
<string name="label_comment">Σχόλιο</string> <string name="label_comment">Comment</string>
<string name="label_what">Τι Είναι?</string> <string name="label_what">What?</string>
<string name="label_payer">Ποιος πλήρωσε?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Για ποιον?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Επανάληψη κάθε</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Λειτουργία</string> <string name="label_mode">Mode</string>
<string name="label_category">Κατηγορία</string> <string name="label_category">Category</string>
<string name="label_project_id">Ταυτότητα/όνομα Έργου</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Τίτλος έργου</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Χρήση Λογαριασμού Εφαρμογής Nextcloud</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Μη αποθηκευμένες αλλαγές</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Αποθήκευση αλλαγών πριν την αναχώρηση?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Το απομακρυσμένο έργο δεν θα διαγραφεί.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Σφάλμα συγχρονισμού</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Ο Συγχρονισμός απέτυχε για %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Οι δαπάνες είναι ήδη ισορροπημένες.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Το έργο %1$s προστέθηκε</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Όλοι οι λογαριασμοί με επισήμανση</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Δεν υπάρχουν προτάσεις</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Απαιτεί Cospend v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Ο σύνδεσμος αντιγράφηκε στο πρόχειρο</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Σαρώστε τον κωδικό QR ή μοιραστείτε το σύνδεσμο για να ενταχθείτε.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Σύνδεσμος για πρόσβαση στο πρόγραμμα περιήγησης ιστού.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Μοιραστείτε αυτό το σύνδεσμο με έναν χρήστη Cowspent .</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Διευθέτηση για %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Στατιστικά για %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Μέλος (Πάροχος (Ισορροπία)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Συνδεδεμένος ως %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Σφάλμα</string> <string name="error_generic">Error</string>
<string name="error_loading">Φόρτωση</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Δεν βρέθηκαν πρότζεκτ</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Δεν βρέθηκαν μέλη</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Δεν βρέθηκαν λογαριασμοί</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Απαιτείται τουλάχιστον ένα μέλος</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Ο διακομιστής είναι σε λειτουργία συντήρησης</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 Εσφαλμένο αίτημα</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Μη Εξουσιοδοτημένο</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Απαγορευμένο</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Δεν Βρέθηκε</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Συγχρονισμός απέτυχε: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Μη έγκυρη σύνδεση: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Λάθος όνομα χρήστη ή κωδικός πρόσβασης</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Μη έγκυρη απάντηση διακομιστή</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Το αίτημα απέτυχε</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Μη έγκυρο e-mail</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Μη έγκυρο ID έργου</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Μη έγκυρος τίτλος έργου</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Μη έγκυρο όνομα λογαριασμού</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Μη έγκυρη ημερομηνία λογαριασμού</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Απαιτείται πληρωτής</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Απαιτούνται ιδιοκτήτες</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Χωρίς σύνδεση δικτύου</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Σφάλμα διακομιστή</string> <string name="error_server">Server error</string>
<string name="error_io">Η σύνδεση διακομιστή έσπασε</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Αδύνατη η κοινοποίηση αυτού του έργου</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Συνδεθείτε στο λογαριασμό Nextcloud</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Τελευταίος συγχρονισμός: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Ακύρωση</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">Εντάξει</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Ναι</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Όχι</string> <string name="simple_no">No</string>
<string name="simple_close">Κλείσιμο</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Εμφάνιση</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Δίκτυο</string> <string name="settings_network">Network</string>
<string name="settings_other">Άλλο</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Θέμα</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Λειτουργία χωρίς σύνδεση</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Μόνο χειροκίνητος συγχρονισμός.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Προσαρμοσμένο χρώμα</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Επιλογή Χρώματος</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Εμφάνιση αρχειοθετημένων έργων</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Χαρακτηριστικά Beta</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Ενεργοποιήσετε πειραματικά χαρακτηριστικά. Χρησιμοποιήστε το με δική σας ευθύνη.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το \"http\" δεν είναι ασφαλές. Χρησιμοποιήστε το \"Ř\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Επιλογή Χρώματος</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">Σύστημα</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">Χειροκίνητα</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">Φωτεινό</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">Σκοτεινό</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">Ακολουθήστε το σύστημα</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Χωρίς επανάληψη</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Καθημερινά</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Εβδομαδιαία</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Δεκαπενθήμερα</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Μηνιαία</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Ετήσια</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Κανένα</string>
<string name="payment_mode_all">Όλα</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Πιστωτική κάρτα</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Μετρητά</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Έλεγχος</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">Συνδεδεμένος</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">Μεταφορά</string> <string name="payment_mode_online">Online</string>
<string name="category_none">Κανένα</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">Όλα</string>
<string name="category_all_except_reimbursement">Όλα εκτός από την επιστροφή</string> <string name="category_none">None</string>
<string name="category_groceries">Παντοπωλείο</string> <string name="category_all">All</string>
<string name="category_leisure">Μπαρ/Πάρτι</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_rent">Ενοίκιο</string> <string name="category_groceries">Grocery</string>
<string name="category_bills">Λογαριασμός</string> <string name="category_leisure">Bar/Party</string>
<string name="category_excursion">Εκδρομή/Πολιτισμός</string> <string name="category_rent">Rent</string>
<string name="category_health">Υγεία</string> <string name="category_bills">Bill</string>
<string name="category_shopping">Αγορές</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_reimbursement">Επιστροφή</string> <string name="category_health">Health</string>
<string name="category_restaurant">Εστιατόριο</string> <string name="category_shopping">Shopping</string>
<string name="category_accomodation">Διαμονή</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_transport">Μεταφορές</string> <string name="category_restaurant">Restaurant</string>
<string name="category_sport">Αθλητισμός</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string>
<string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Τι</string> <string name="new_project_action">What</string>
<string name="new_project_where">Όπου</string> <string name="new_project_where">Where</string>
<string name="where_local">Τοπικό μόνο</string> <string name="where_local">Local only</string>
<string name="where_cospend">Κόστος</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Συμμετοχή σε υπάρχον έργο</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Δημιουργία νέου έργου</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Εισαγωγή από αρχείο</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Επιλογή έργου</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Δεν βρέθηκαν έργα σε αυτόν τον λογαριασμό.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Έργο</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Το έργο προστέθηκε επιτυχώς.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Δεν έχετε ακόμα πρότζεκτ.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Ρύθμιση λογαριασμού Nextcloud</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Χειροκίνητη προσθήκη έργου</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Κανένα μέλος σε αυτό το έργο.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Δεν βρέθηκαν λογαριασμοί.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Το μέλος υπάρχει ήδη.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">Έργο: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">Το έργο %1$s αφαιρέθηκε.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">Το αρχείο αποθηκεύτηκε: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">Η εισαγωγή απέτυχε στη γραμμή %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">Μη έγκυρη μορφή ημερομηνίας στη γραμμή %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">Μη έγκυρες owers στη σειρά %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">Προσθήκη Μελών</string>
<string name="edit_member_dialog_title">Επεξεργασία Μέλους</string>
<string name="member_edit_delete">Διαγραφή</string>
<string name="project_edition_no_change">Δεν υπάρχουν αλλαγές για αποθήκευση.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Κανένα (Βέλτιστο Μέρος)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Ποιος πληρώνει</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">Σε ποιους</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Ποσό</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Κοινοποίηση</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Δημιουργία λογαριασμών</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Διευθέτηση</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Επιλέξτε Νόμισμα (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Κανένα</string> <string name="setting_none">None</string>
<string name="setting_all">Όλα</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Οι ρυθμίσεις νομίσματος αποθηκεύτηκαν.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Κύριο Νόμισμα</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Προτεινόμενες Κατηγορίες</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Παράλειψη</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">Από</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">Προς</string> <string name="stats_date_max">To</string>
<string name="stats_who">Κράτος</string> <string name="stats_who">Member</string>
<string name="stats_paid">Πληρωμένο</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Δαπανήθηκε</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Υπόλοιπο</string> <string name="stats_balance">Balance</string>
<string name="total">Σύνολο: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Αποτυχία σύνδεσης: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Η δημιουργία απέτυχε: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Σφάλμα ενημέρωσης απομακρυσμένου έργου: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Το δίκτυο δεν είναι διαθέσιμο για απομακρυσμένη λειτουργία.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Αποτυχία ανάλυσης QR code.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Ασυμφωνία διακριτικού ταυτοποίησης. Παρακαλώ συνδεθείτε ξανά.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Δεν έχετε άδεια για να εκτελέσετε αυτήν την ενέργεια.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Διαγραφή Ετικέτας</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτή την ετικέτα?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Έκδοση %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Συντηρητής</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Άδεια</string> <string name="about_license_title">License</string>
<string name="about_source_title">Πηγαίος κώδικας</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Έργο %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Κοινοποίηση %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
-241
View File
@@ -1,241 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!-- Actions -->
<string name="action_new_bill">New bill</string>
<string name="action_add_project">Add project</string>
<string name="action_save">Save</string>
<string name="action_edit">Edit</string>
<string name="action_share">Share</string>
<string name="action_search">Search</string>
<string name="action_delete">Delete</string>
<string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Settings</string>
<string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Logout</string>
<string name="action_connect">Connect</string>
<string name="action_discard">Discard</string>
<string name="action_members">Members</string>
<string name="action_labels">Labels</string>
<string name="action_currencies">Currencies</string>
<!-- Titles -->
<string name="title_stats">Statistics</string>
<string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Label Bills</string>
<string name="title_labels">Manage Labels</string>
<string name="title_about">About</string>
<string name="title_settle">Settle Project</string>
<string name="title_share">Share Project</string>
<string name="title_add_project">Add Project</string>
<string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields -->
<string name="label_all_bills">All bills</string>
<string name="label_categories">Categories</string>
<string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string>
<string name="label_color">Color</string>
<string name="label_weight">Weight</string>
<string name="label_activated">Activated</string>
<string name="label_password">Password</string>
<string name="label_email">E-mail</string>
<string name="label_url">Server address</string>
<string name="label_username">Username</string>
<string name="label_comment">Comment</string>
<string name="label_what">What?</string>
<string name="label_payer">Who paid?</string>
<string name="label_owers">For whom?</string>
<string name="label_repeat">Repeat every</string>
<string name="label_mode">Mode</string>
<string name="label_category">Category</string>
<string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project title</string>
<string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors -->
<string name="error_generic">Error</string>
<string name="error_loading">Loading</string>
<string name="error_no_projects">No projects found</string>
<string name="error_no_members">No members found</string>
<string name="error_no_bills">No bills found</string>
<string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 Bad request</string>
<string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Forbidden</string>
<string name="error_404">404 Not Found</string>
<string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Wrong username or password</string>
<string name="error_json">Invalid server response</string>
<string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">No network connection</string>
<string name="error_server">Server error</string>
<string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI -->
<string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Yes</string>
<string name="simple_no">No</string>
<string name="simple_close">Close</string>
<!-- Settings -->
<string name="settings_appearance">Appearance</string>
<string name="settings_network">Network</string>
<string name="settings_other">Other</string>
<string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WARNING: \"http\" is unsafe. Use \"https\".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists -->
<string name="repeat_no">No repeat</string>
<string name="repeat_day">Daily</string>
<string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Monthly</string>
<string name="repeat_year">Yearly</string>
<string name="payment_mode_none">None</string>
<string name="payment_mode_all">All</string>
<string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_cash">Cash</string>
<string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string>
<string name="category_none">None</string>
<string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_groceries">Grocery</string>
<string name="category_leisure">Bar/Party</string>
<string name="category_rent">Rent</string>
<string name="category_bills">Bill</string>
<string name="category_excursion">Excursion/Culture</string>
<string name="category_health">Health</string>
<string name="category_shopping">Shopping</string>
<string name="category_reimbursement">Reimbursement</string>
<string name="category_restaurant">Restaurant</string>
<string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string>
<string name="category_sport">Sport</string>
<!-- Project specific -->
<string name="new_project_action">What</string>
<string name="new_project_where">Where</string>
<string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string>
<string name="configure_account_choice">Configure Nextcloud account</string>
<string name="add_project_choice">Add project manually</string>
<string name="no_members_text">No members in this project.</string>
<string name="no_bills_text">No bills found.</string>
<string name="member_already_exists">Member already exists.</string>
<string name="activity_dialog_title">Project: %1$s</string>
<string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="file_saved_success">File saved: %1$s</string>
<string name="import_error_header">Import failed at row %d</string>
<string name="import_error_date">Invalid date format at row %d</string>
<string name="import_error_owers">Invalid owers at row %d</string>
<string name="add_member_dialog_title">Add Member</string>
<string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement -->
<string name="center_none">None (Optimal)</string>
<string name="settle_who">Who pays</string>
<string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Settlement</string>
<!-- Currencies -->
<string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">None</string>
<string name="setting_all">All</string>
<string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Main Currency</string>
<!-- Statistics -->
<string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Skip</string>
<string name="stats_date_min">From</string>
<string name="stats_date_max">To</string>
<string name="stats_who">Member</string>
<string name="stats_paid">Paid</string>
<string name="stats_spent">Spent</string>
<string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string>
<!-- Errors Extra -->
<string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About -->
<string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">License</string>
<string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Share %1$s</string>
</resources>
+118 -94
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Capucha gastada</string>
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Nueva factura</string> <string name="action_new_bill">Nueva factura</string>
<string name="action_add_project">Añadir proyecto</string> <string name="action_add_project">Añadir proyecto</string>
@@ -8,154 +8,174 @@
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_share">Compartir</string> <string name="action_share">Compartir</string>
<string name="action_search">Buscar</string> <string name="action_search">Buscar</string>
<string name="action_open_menu">Abrir el menú</string>
<string name="action_close_search">Cerrar la búsqueda</string>
<string name="action_clear_search">Borrar la búsqueda</string>
<string name="action_delete">Eliminar</string> <string name="action_delete">Eliminar</string>
<string name="simple_back">Atrás</string>
<string name="action_archive">Archivar</string> <string name="action_archive">Archivar</string>
<string name="action_unarchive">Desarchivar</string> <string name="action_unarchive">Desarchivar</string>
<string name="action_export">Exportar</string> <string name="action_export">Exportar</string>
<string name="action_stats">Estadísticas</string> <string name="action_stats">Estadísticas</string>
<string name="action_settle">Salir</string> <string name="action_settle">Liquidar</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Escanear código QR</string>
<string name="action_settings">Ajustes</string> <string name="action_settings">Ajustes</string>
<string name="action_label_bills">Categorías faltantes de etiqueta</string> <string name="action_label_bills">Categorizar facturas</string>
<string name="action_logout">Cerrar sesión</string> <string name="action_logout">Cerrar sesión</string>
<string name="action_connect">Conectar</string> <string name="action_connect">Conectar</string>
<string name="action_discard">Descartar</string> <string name="action_discard">Descartar</string>
<string name="action_members">Miembros</string> <string name="action_members">Miembros</string>
<string name="action_labels">Etiquetas</string> <string name="action_labels">Etiquetas</string>
<string name="action_currencies">Monedas</string> <string name="action_currencies">Monedas</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Estadísticas</string> <string name="title_stats">Estadísticas</string>
<string name="title_edit_project">Editar proyecto</string> <string name="title_edit_project">Editar proyecto</string>
<string name="title_label_bills">Facturas de etiqueta</string> <string name="title_label_bills">Categorizar facturas</string>
<string name="title_labels">Administrar etiquetas</string> <string name="title_labels">Gestionar etiquetas</string>
<string name="title_about">Acerca de</string> <string name="title_about">Acerca de</string>
<string name="title_settle">Liquidar Proyecto</string> <string name="title_settle">Liquidar proyecto</string>
<string name="title_share">Compartir proyecto</string> <string name="title_share">Compartir proyecto</string>
<string name="title_add_project">Añadir proyecto</string> <string name="title_add_project">Añadir proyecto</string>
<string name="title_add_category">Añadir categoría</string> <string name="title_add_category">Añadir categoría</string>
<string name="title_add_payment_mode">Añadir modo de pago</string> <string name="title_add_payment_mode">Añadir modo de pago</string>
<string name="title_account">Cuenta Nextcloud</string> <string name="title_account">Cuenta de Nextcloud</string>
<string name="title_share_web">Enlace web</string> <string name="title_share_web">Enlace web</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Enlace de Cowspent</string>
<string name="title_confirm">¿Estás seguro?</string> <string name="title_confirm">¿Estás seguro?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Todas las facturas</string> <string name="label_all_bills">Todas las facturas</string>
<string name="label_categories">Categorías</string> <string name="label_categories">Categorías</string>
<string name="label_payment_modes">Modos de pago</string> <string name="label_payment_modes">Modos de pago</string>
<string name="label_name">Nombre</string> <string name="label_name">Nombre</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icono / Emoji</string>
<string name="label_color">Color</string> <string name="label_color">Color</string>
<string name="label_weight">Peso</string> <string name="label_weight">Peso</string>
<string name="label_activated">Activado</string> <string name="label_activated">Activado</string>
<string name="label_password">Contraseña</string> <string name="label_password">Contraseña</string>
<string name="label_email">E-mail</string> <string name="label_email">Correo electrónico</string>
<string name="label_url">Dirección del servidor</string> <string name="label_url">Dirección del servidor</string>
<string name="label_username">Usuario</string> <string name="label_username">Nombre de usuario</string>
<string name="label_comment">Comentario</string> <string name="label_comment">Comentario</string>
<string name="label_what">¿Qué?</string> <string name="label_what">¿Qué?</string>
<string name="label_payer">¿Quién pagó?</string> <string name="label_payer">¿Quién pagó?</string>
<string name="label_owers">¿Para quién?</string> <string name="label_owers">¿Para quién?</string>
<string name="label_repeat">Repetir cada</string> <string name="label_repeat">Repetición</string>
<string name="label_mode">Modo</string> <string name="label_mode">Modo</string>
<string name="label_category">Categoría</string> <string name="label_category">Categoría</string>
<string name="label_project_id">ID del proyecto/nombre</string> <string name="label_project_id">ID/nombre del proyecto</string>
<string name="label_project_title">Título del proyecto</string> <string name="label_project_title">Título del proyecto</string>
<string name="label_use_sso">Usar cuenta de la aplicación Nextcloud</string> <string name="label_use_sso">Usar la cuenta de la aplicación Nextcloud</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Cambios sin guardar</string> <string name="dialog_unsaved_changes_title">Cambios sin guardar</string>
<string name="dialog_unsaved_changes_msg">¿Guardar cambios antes de salir?</string> <string name="dialog_unsaved_changes_msg">¿Guardar los cambios antes de salir?</string>
<string name="dialog_confirm_remove_project_msg">El proyecto remoto no se eliminará.</string> <string name="dialog_confirm_remove_project_msg">El proyecto remoto no se eliminará.</string>
<string name="dialog_sync_error_title">Error de sincronización</string> <string name="dialog_sync_error_title">Error de sincronización</string>
<string name="dialog_sync_error_msg">Sincronización fallida para %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Error al sincronizar %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Los gastos ya están equilibrados.</string> <string name="dialog_balanced_msg">Los gastos ya están equilibrados.</string>
<string name="msg_project_added">Proyecto %1$s añadido</string> <string name="msg_project_added">Proyecto %1$s añadido</string>
<string name="msg_bill_labeled_done">Todas las facturas etiquetadas</string> <string name="msg_bill_labeled_done">Todas las facturas están categorizadas</string>
<string name="msg_no_suggestions">No hay sugerencias</string> <string name="msg_no_suggestions">No hay sugerencias</string>
<string name="msg_auth_warning">Requiere Gasto v0.3.4+.</string> <string name="msg_auth_warning">Requiere Cospend v0.3.4+.</string>
<string name="msg_link_copied">Enlace copiado al portapapeles</string> <string name="msg_link_copied">Enlace copiado al portapapeles</string>
<string name="msg_share_qr">Escanea el código QR o comparte el enlace para unirte.</string> <string name="msg_share_qr">Escanea el código QR o comparte el enlace para unirte al proyecto.</string>
<string name="msg_share_web">Enlace para acceso al navegador web.</string> <string name="msg_share_web">Enlace de acceso desde un navegador web.</string>
<string name="msg_share_qr_warn">Comparte este enlace con un usuario de Cowged.</string> <string name="msg_share_qr_warn">Comparte este enlace con un usuario de Cowspent.</string>
<string name="msg_settle_intro">Acuerdo para %1$s:</string> <string name="msg_settle_intro">Liquidación de %1$s:</string>
<string name="msg_settle_sentence">%1$s debe %3$.2f a %2$s</string> <string name="msg_settle_sentence">%1$s debe %3$.2f a %2$s</string>
<string name="msg_stats_intro">Estadísticas de %1$s:</string> <string name="msg_stats_intro">Estadísticas de %1$s:</string>
<string name="msg_stats_header">Miembro Pagado | Gasto | Saldo)</string> <string name="msg_stats_header">Miembro (Pagado | Gastado | Saldo)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string> <string name="msg_logged_in_as">Sesión iniciada como %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Error</string> <string name="error_generic">Error</string>
<string name="error_loading">Cargando</string> <string name="error_loading">Cargando</string>
<string name="error_no_projects">No se encontraron proyectos</string> <string name="error_no_projects">No se encontraron proyectos</string>
<string name="error_no_members">Ningún miembro encontrado</string> <string name="error_no_members">No se encontraron miembros</string>
<string name="error_no_bills">No se encontraron facturas</string> <string name="error_no_bills">No se encontraron facturas</string>
<string name="error_no_member">Se requiere al menos un miembro</string> <string name="error_no_member">Se requiere al menos un miembro</string>
<string name="error_maintenance_mode">El servidor está en modo mantenimiento</string> <string name="error_maintenance_mode">El servidor está en modo de mantenimiento</string>
<string name="error_400">400 Solicitud errónea</string> <string name="error_400">400 Solicitud incorrecta</string>
<string name="error_401">401 no autorizado</string> <string name="error_401">401 No autorizado</string>
<string name="error_403">403 Prohibida</string> <string name="error_403">403 Prohibido</string>
<string name="error_404">404 no encontrado</string> <string name="error_404">404 No encontrado</string>
<string name="error_sync">Sincronización fallida: %1$s</string> <string name="error_sync">Error de sincronización: %1$s</string>
<string name="error_invalid_login">Inicio de sesión no válido: %1$s</string> <string name="error_invalid_login">Inicio de sesión no válido: %1$s</string>
<string name="error_auth">Nombre de usuario o contraseña incorrectos</string> <string name="error_auth">Nombre de usuario o contraseña incorrectos</string>
<string name="error_json">Respuesta del servidor inválida</string> <string name="error_json">Respuesta del servidor no válida</string>
<string name="error_req_failed">Petición fallida</string> <string name="error_req_failed">La petición ha fallado</string>
<string name="error_invalid_email">E-mail inválido</string> <string name="error_invalid_email">Correo electrónico no válido</string>
<string name="error_invalid_project_id">ID de proyecto inválido</string> <string name="error_invalid_project_id">ID de proyecto no válido</string>
<string name="error_invalid_project_name">Título del proyecto inválido</string> <string name="error_invalid_project_name">Título de proyecto no válido</string>
<string name="error_invalid_bill_name">Nombre de factura no válido</string> <string name="error_invalid_bill_name">Nombre de factura no válido</string>
<string name="error_invalid_bill_date">Fecha de factura inválida</string> <string name="error_invalid_bill_date">Fecha de factura no válida</string>
<string name="error_invalid_bill_payer">Pagador requerido</string> <string name="error_invalid_bill_payer">Pagador requerido</string>
<string name="error_invalid_bill_owers">Propietarios requeridos</string> <string name="error_invalid_bill_owers">Participantes requeridos</string>
<string name="error_no_network">No hay conexión de red</string> <string name="error_no_network">No hay conexión de red</string>
<string name="error_server">Error del servidor</string> <string name="error_server">Error del servidor</string>
<string name="error_io">Conexión con el servidor dañada</string> <string name="error_io">Se ha perdido la conexión con el servidor</string>
<string name="error_share_impossible">No se puede compartir este proyecto</string> <string name="error_share_impossible">No se puede compartir este proyecto</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Conectar a la cuenta de Nextcloud</string> <string name="drawer_no_account">Conectar a una cuenta de Nextcloud</string>
<string name="drawer_last_sync">Última sincronización: %1$02d:%2$02d</string> <string name="drawer_last_sync">Última sincronización: %1$02d:%2$02d</string>
<string name="simple_cancel">Cancelar</string> <string name="simple_cancel">Cancelar</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes"></string> <string name="simple_yes"></string>
<string name="simple_no">Nu</string> <string name="simple_no">No</string>
<string name="simple_close">Cerrar</string> <string name="simple_close">Cerrar</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Apariencia</string> <string name="settings_appearance">Apariencia</string>
<string name="settings_network">Red</string> <string name="settings_network">Red</string>
<string name="settings_other">Otro</string> <string name="settings_other">Otros</string>
<string name="settings_night_mode">Tema</string> <string name="settings_night_mode">Tema</string>
<string name="settings_offline_mode">Modo sin conexión</string> <string name="settings_offline_mode">Modo sin conexión</string>
<string name="settings_offline_mode_summary">Solo sincronizar manualmente.</string> <string name="settings_offline_mode_summary">Sincronizar solo manualmente.</string>
<string name="settings_color_custom">Color personalizado</string> <string name="settings_color_custom">Color personalizado</string>
<string name="settings_color_mode">Selección de color</string> <string name="settings_color_mode">Selección de color</string>
<string name="settings_show_archived">Mostrar proyectos archivados</string> <string name="settings_show_archived">Mostrar los proyectos archivados</string>
<string name="settings_beta_features">Características beta</string> <string name="settings_beta_features">Funciones beta</string>
<string name="settings_beta_features_summary">Activar características experimentales. Úsalo bajo tu propio riesgo.</string> <string name="settings_beta_features_summary">Activar las funciones experimentales. Úsalas bajo tu propia responsabilidad.</string>
<string name="settings_url_warn_http">ADVERTENCIA: \"http\" no es seguro. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Rellenar desde la última factura</string>
<string name="settings_colorpicker_title">Elegir color</string> <string name="settings_fill_new_bill_from_last_summary">Reutilizar el pagador, la categoría, el modo y los participantes de la última factura creada en el proyecto.</string>
<string name="settings_auto_sync_on_open">Intervalo de sincronización</string>
<string name="settings_auto_sync_on_open_summary">Con qué frecuencia se actualizan la cuenta y todos los proyectos al abrir la aplicación.</string>
<string name="pref_value_sync_1m">1 minuto</string>
<string name="pref_value_sync_10m">10 minutos</string>
<string name="pref_value_sync_1h">1 hora</string>
<string name="pref_value_sync_1d">1 día</string>
<string name="settings_url_warn_http">ADVERTENCIA: \"http\" no es seguro. Usa \"https\".</string>
<string name="settings_colorpicker_title">Elegir un color</string>
<string name="pref_value_color_system">Sistema</string> <string name="pref_value_color_system">Sistema</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Claro</string> <string name="pref_value_theme_light">Claro</string>
<string name="pref_value_theme_dark">Oscuro</string> <string name="pref_value_theme_dark">Oscuro</string>
<string name="pref_value_theme_system">Seguir sistema</string> <string name="pref_value_theme_system">Seguir el sistema</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">No repetir</string> <string name="repeat_no">Sin repetición</string>
<string name="repeat_day">Diario</string> <string name="repeat_day">Diaria</string>
<string name="repeat_week">Semanal</string> <string name="repeat_week">Semanal</string>
<string name="repeat_fortnight">Fortnocturno</string> <string name="repeat_fortnight">Quincenal</string>
<string name="repeat_month">Mensual</string> <string name="repeat_month">Mensual</string>
<string name="repeat_year">Anual</string> <string name="repeat_year">Anual</string>
<string name="payment_mode_none">Ninguna</string>
<string name="payment_mode_none">Ninguno</string>
<string name="payment_mode_all">Todos</string> <string name="payment_mode_all">Todos</string>
<string name="payment_mode_credit_card">Tarjeta de crédito</string> <string name="payment_mode_credit_card">Tarjeta de crédito</string>
<string name="payment_mode_cash">Dinero</string> <string name="payment_mode_cash">Efectivo</string>
<string name="payment_mode_check">Comprobar</string> <string name="payment_mode_check">Cheque</string>
<string name="payment_mode_online">En línea</string> <string name="payment_mode_online">En línea</string>
<string name="payment_mode_transfer">Transferir</string> <string name="payment_mode_transfer">Transferencia</string>
<string name="category_none">Ninguna</string> <string name="category_none">Ninguna</string>
<string name="category_all">Todos</string> <string name="category_all">Todas</string>
<string name="category_all_except_reimbursement">Todos excepto reembolso</string> <string name="category_all_except_reimbursement">Todas excepto reembolso</string>
<string name="category_groceries">Comestible</string> <string name="category_groceries">Supermercado</string>
<string name="category_leisure">Bar/Fiesta</string> <string name="category_leisure">Bar/Fiesta</string>
<string name="category_rent">Alquiler</string> <string name="category_rent">Alquiler</string>
<string name="category_bills">Factura</string> <string name="category_bills">Factura</string>
@@ -167,75 +187,79 @@
<string name="category_accomodation">Alojamiento</string> <string name="category_accomodation">Alojamiento</string>
<string name="category_transport">Transporte</string> <string name="category_transport">Transporte</string>
<string name="category_sport">Deporte</string> <string name="category_sport">Deporte</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Qué</string> <string name="new_project_action">Qué</string>
<string name="new_project_where">Donde</string> <string name="new_project_where">Dónde</string>
<string name="where_local">Solo local</string> <string name="where_local">Solo local</string>
<string name="where_cospend">Gastar</string> <string name="todo_join">Unirse a un proyecto existente</string>
<string name="where_ihatemoney">Dinero IHate</string> <string name="todo_create">Crear un proyecto nuevo</string>
<string name="todo_join">Unirse al proyecto existente</string> <string name="import_tooltip">Importar desde un archivo</string>
<string name="todo_create">Crear nuevo proyecto</string> <string name="choose_project_management_action">Proyecto</string>
<string name="import_tooltip">Importar desde archivo</string>
<string name="choose_account_project_dialog_title">Elegir proyecto</string>
<string name="choose_account_project_dialog_impossible">No se encontraron proyectos en esta cuenta.</string>
<string name="choose_project_management_action">Projekt</string>
<string name="project_added_success">Proyecto añadido correctamente.</string> <string name="project_added_success">Proyecto añadido correctamente.</string>
<string name="no_projects_text">Aún no tienes proyectos.</string> <string name="no_projects_text">Aún no tienes proyectos.</string>
<string name="configure_account_choice">Configurar cuenta Nextcloud</string> <string name="configure_account_choice">Configurar una cuenta de Nextcloud</string>
<string name="add_project_choice">Añadir proyecto manualmente</string> <string name="add_project_choice">Añadir un proyecto manualmente</string>
<string name="no_members_text">No hay miembros en este proyecto.</string> <string name="no_members_text">No hay miembros en este proyecto.</string>
<string name="no_bills_text">No se encontraron facturas.</string> <string name="no_bills_text">No se encontraron facturas.</string>
<string name="member_already_exists">El miembro ya existe.</string> <string name="member_already_exists">El miembro ya existe.</string>
<string name="activity_dialog_title">Proyecto: %1$s</string> <string name="activity_dialog_title">Proyecto: %1$s</string>
<string name="remove_project_confirmation">Proyecto %1$s eliminado.</string> <string name="remove_project_confirmation">Proyecto %1$s eliminado.</string>
<string name="file_saved_success">Archivo guardado: %1$s</string> <string name="file_saved_success">Archivo guardado: %1$s</string>
<string name="import_error_header">Error al importar en la fila %d</string> <string name="import_error_header">Error de importación en la fila %d</string>
<string name="import_error_date">Formato de fecha no válido en la fila %d</string> <string name="import_error_date">Formato de fecha no válido en la fila %d</string>
<string name="import_error_owers">Dueños no válidos en la fila %d</string> <string name="import_error_owers">Participantes no válidos en la fila %d</string>
<string name="add_member_dialog_title">Añadir miembro</string> <string name="add_member_dialog_title">Añadir miembro</string>
<string name="edit_member_dialog_title">Editar miembro</string> <string name="edit_member_dialog_title">Editar miembro</string>
<string name="member_edit_delete">Eliminar</string> <string name="member_edit_delete">Eliminar</string>
<string name="project_edition_no_change">No hay cambios para guardar.</string> <string name="project_edition_no_change">No hay cambios que guardar.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Ninguno (óptimo)</string> <string name="center_none">Ninguno (óptimo)</string>
<string name="settle_who">Quién paga</string> <string name="settle_who">Quién paga</string>
<string name="settle_to_whom">A quien</string> <string name="settle_to_whom">A quién</string>
<string name="settle_how_much">Cantidad</string> <string name="settle_how_much">Importe</string>
<string name="simple_settle_share">Compartir</string> <string name="simple_settle_share">Compartir</string>
<string name="simple_create_bills">Crear facturas</string> <string name="simple_create_bills">Crear las facturas</string>
<string name="settle_bill_what">Acuerdo</string> <string name="settle_bill_what">Liquidación</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Elija la moneda (%s)</string> <string name="currency_dialog_title">Elegir moneda (%s)</string>
<string name="setting_none">Ninguna</string> <string name="setting_none">Ninguna</string>
<string name="setting_all">Todos</string> <string name="setting_all">Todas</string>
<string name="currency_saved_success">Ajustes de moneda guardados.</string> <string name="currency_saved_success">Ajustes de moneda guardados.</string>
<string name="main_currency">Moneda principal</string> <string name="main_currency">Moneda principal</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Categorías sugeridas</string> <string name="label_bills_suggested">Categorías sugeridas</string>
<string name="label_bills_skip">Saltar</string> <string name="label_bills_skip">Omitir</string>
<string name="stats_date_min">De</string> <string name="stats_date_min">Desde</string>
<string name="stats_date_max">A</string> <string name="stats_date_max">Hasta</string>
<string name="stats_who">Miembro</string> <string name="stats_who">Miembro</string>
<string name="stats_paid">Pagado</string> <string name="stats_paid">Pagado</string>
<string name="stats_spent">Escrito</string> <string name="stats_spent">Gastado</string>
<string name="stats_balance">Saldo</string> <string name="stats_balance">Saldo</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Conexión fallida: %1$s</string> <string name="error_project_connect_check">Error de conexión: %1$s</string>
<string name="error_create_remote_project_helper">Creación fallida: %1$s</string> <string name="error_create_remote_project_helper">Error al crear: %1$s</string>
<string name="error_edit_remote_project_helper">Error al actualizar proyecto remoto: %1$s</string> <string name="error_edit_remote_project_helper">Error al actualizar el proyecto remoto: %1$s</string>
<string name="remote_project_operation_no_network">Red no disponible para operaciones remotas.</string> <string name="remote_project_operation_no_network">Red no disponible para esta operación remota.</string>
<string name="error_scanning_bill_qr_code">Error al analizar el código QR.</string> <string name="error_scanning_bill_qr_code">No se ha podido leer el código QR.</string>
<string name="error_token_mismatch">El token de autenticación no coincide. Por favor, inicia sesión de nuevo.</string> <string name="error_token_mismatch">El token de autenticación no coincide. Vuelve a iniciar sesión.</string>
<string name="insufficient_access_level">No tienes permiso para realizar esta acción.</string> <string name="insufficient_access_level">No tienes permiso para realizar esta acción.</string>
<string name="delete_label_confirmation_title">Eliminar Etiqueta</string> <string name="delete_label_confirmation_title">Eliminar etiqueta</string>
<string name="delete_label_confirmation_message">¿Está seguro que desea eliminar esta etiqueta?</string> <string name="delete_label_confirmation_message">¿Seguro que quieres eliminar esta etiqueta?</string>
<!-- About --> <!-- About -->
<string name="about_version">Versión %1$s</string> <string name="about_version">Versión %1$s</string>
<string name="about_maintainer_title">Mantenedor</string> <string name="about_maintainer_title">Mantenedor</string>
<string name="about_license_title">Licencia</string> <string name="about_license_title">Licencia</string>
<string name="about_source_title">Código fuente</string> <string name="about_source_title">Código fuente</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Proyecto %1$s</string> <string name="share_intent_title">Proyecto %1$s</string>
<string name="share_chooser_title">Compartir %1$s</string> <string name="share_chooser_title">Compartir %1$s</string>
</resources> </resources>
+249 -218
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Lehmä</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Uusi lasku</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Lisää projekti</string> <string name="action_add_project">Add project</string>
<string name="action_save">Tallenna</string> <string name="action_save">Save</string>
<string name="action_edit">Muokkaa</string> <string name="action_edit">Edit</string>
<string name="action_share">Jaa</string> <string name="action_share">Share</string>
<string name="action_search">Etsi</string> <string name="action_search">Search</string>
<string name="action_delete">Poista</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Arkistoi</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Poista</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Vie</string> <string name="action_delete">Delete</string>
<string name="action_stats">Tilastot</string> <string name="simple_back">Back</string>
<string name="action_settle">Ratkaise</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Asetukset</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Tunnisteet puuttuvat kategoriat</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Kirjaudu Ulos</string> <string name="action_logout">Logout</string>
<string name="action_connect">Yhdistä</string> <string name="action_connect">Connect</string>
<string name="action_discard">Hylkää</string> <string name="action_discard">Discard</string>
<string name="action_members">Jäsenet</string> <string name="action_members">Members</string>
<string name="action_labels">Tunnisteet</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Valuutat</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Tilastot</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Muokkaa projektia</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Merkitse Laskut</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Hallitse Tunnisteita</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">Tietoja</string> <string name="title_about">About</string>
<string name="title_settle">Ratkaise Projekti</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Jaa Projekti</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Lisää Projekti</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Lisää Kategoria</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Lisää Maksutila</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Nextcloud Tili</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Linkki</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Oletko varma?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Kaikki laskut</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Kategoriat</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Maksutavat</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Nimi</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Väri</string> <string name="label_color">Color</string>
<string name="label_weight">Paino</string> <string name="label_weight">Weight</string>
<string name="label_activated">Aktivoitu</string> <string name="label_activated">Activated</string>
<string name="label_password">Salasana</string> <string name="label_password">Password</string>
<string name="label_email">Sähköposti</string> <string name="label_email">E-mail</string>
<string name="label_url">Palvelimen osoite</string> <string name="label_url">Server address</string>
<string name="label_username">Käyttäjätunnus</string> <string name="label_username">Username</string>
<string name="label_comment">Kommentti</string> <string name="label_comment">Comment</string>
<string name="label_what">Mitä?</string> <string name="label_what">What?</string>
<string name="label_payer">Kuka maksoi?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Kenen puolesta?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Toista joka</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Tila</string> <string name="label_mode">Mode</string>
<string name="label_category">Kategoria</string> <string name="label_category">Category</string>
<string name="label_project_id">Projektin ID/nimi</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Projektin otsikko</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Käytä Nextcloud -sovellustiliä</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Tallentamattomat muutokset</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Tallennetaanko muutokset ennen lähtöä?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Etäprojektia ei poisteta.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Virhe synkronoinnissa</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">%1$ssynkronointi epäonnistui.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Menot ovat jo tasapainossa.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Projekti %1$s lisätty</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Kaikki laskut merkitty</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Ei ehdotuksia</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Tarvitsee Kustannukset v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Linkki kopioitu leikepöydälle</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Skannaa QR-koodi tai jaa linkki johon liittyä.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Linkki selaimen käyttöön.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Jaa tämä linkki Cowkäytetyn käyttäjän kanssa.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">%1$s:n toimitus:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Tilastot %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Jäsenen (Käytetty Saldo)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Kirjautunut sisään nimellä %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Virhe</string> <string name="error_generic">Error</string>
<string name="error_loading">Ladataan</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Projekteja ei löytynyt</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Jäseniä ei löytynyt</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Laskuja ei löytynyt</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Vaadittu vähintään yksi jäsen</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Palvelin on huoltotilassa</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 Virheellinen pyyntö</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Luvaton</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Kielletty</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Ei Löytynyt</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Synkronointi epäonnistui: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Virheellinen kirjautuminen: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Väärä käyttäjätunnus tai salasana</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Virheellinen palvelimen vastaus</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Pyyntö epäonnistui</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Virheellinen sähköpostiosoite</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Virheellinen projektin tunnus</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Virheellinen projektin otsikko</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Virheellinen laskun nimi</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Virheellinen laskun päivämäärä</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Maksaja vaaditaan</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Uutiskirjeet vaaditaan</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Ei verkkoyhteyttä</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Palvelin virhe</string> <string name="error_server">Server error</string>
<string name="error_io">Palvelinyhteys rikki</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Projektia ei voi jakaa</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Yhdistä Nextcloud tiliin</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Peruuta</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">OK</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Kyllä</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Ei</string> <string name="simple_no">No</string>
<string name="simple_close">Sulje</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Ulkoasu</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Verkko</string> <string name="settings_network">Network</string>
<string name="settings_other">Muu</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Teema</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Offline-tila</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Synkronoi vain käsin.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Mukautettu väri</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Värin Valinta</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Näytä arkistoidut projektit</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Ominaisuudet</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Ota käyttöön kokeelliset ominaisuudet. Käytä omalla vastuullasi.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">VAROITUS: \"http\" ei ole turvallinen. Käytä \"℃\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Valitse Väri</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">Järjestelmä</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">Manuaalinen</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">Vaalea</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">Tumma</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">Seuraa järjestelmää</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Ei toistumista</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Päivittäin</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Viikoittain</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Onneksi</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Kuukausittain</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Vuosittain</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Ei Mitään</string>
<string name="payment_mode_all">Kaikki</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Luottokortti</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Käteinen</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Tarkista</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">Paikalla</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">Siirto</string> <string name="payment_mode_online">Online</string>
<string name="category_none">Ei Mitään</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">Kaikki</string>
<string name="category_all_except_reimbursement">Kaikki paitsi korvaukset</string> <string name="category_none">None</string>
<string name="category_groceries">Ruokakauppa</string> <string name="category_all">All</string>
<string name="category_leisure">Baari/Juhla</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_rent">Vuokra</string> <string name="category_groceries">Grocery</string>
<string name="category_bills">Lasku</string> <string name="category_leisure">Bar/Party</string>
<string name="category_excursion">Retki/Kulttuuri</string> <string name="category_rent">Rent</string>
<string name="category_health">Terveys</string> <string name="category_bills">Bill</string>
<string name="category_shopping">Ostokset</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_reimbursement">Korvaus</string> <string name="category_health">Health</string>
<string name="category_restaurant">Ravintola</string> <string name="category_shopping">Shopping</string>
<string name="category_accomodation">Majoitus</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_transport">Kuljetus</string> <string name="category_restaurant">Restaurant</string>
<string name="category_sport">Urheilu</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string>
<string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Mitä</string> <string name="new_project_action">What</string>
<string name="new_project_where">Missä</string> <string name="new_project_where">Where</string>
<string name="where_local">Vain paikallinen</string> <string name="where_local">Local only</string>
<string name="where_cospend">Kulut</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Liity olemassa olevaan projektiin</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Luo uusi projekti</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Tuo tiedostosta</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Valitse projekti</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Tällä tilillä ei löytynyt projekteja.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Projekti</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Projekti lisätty onnistuneesti.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Sinulla ei ole vielä projekteja.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Määritä Nextcloud tili</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Lisää projekti käsin</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Ei jäseniä tässä projektissa.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Laskuja ei löytynyt.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Jäsentä on jo olemassa.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">Projekti: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">Projekti %1$s poistettu.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">Tiedosto tallennettu: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">Tuonti epäonnistui rivillä %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">Päivämäärän muoto ei kelpaa rivillä %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">Virheelliset ruohonleikkurit rivillä %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">Lisää Jäsen</string>
<string name="edit_member_dialog_title">Muokkaa Jäsen</string>
<string name="member_edit_delete">Poista</string>
<string name="project_edition_no_change">Tallennettavia muutoksia ei ole.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Ei Mitään (valinnainen)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Kuka maksaa</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">Kenelle</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Määrä</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Jaa</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Luo laskuja</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Selvitys</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Valitse Valuutta (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Ei Mitään</string> <string name="setting_none">None</string>
<string name="setting_all">Kaikki</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Valuutan asetukset tallennettu.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Päävaluutta</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Ehdotetut Kategoriat</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Ohita</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">Alkaen</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">Vastaanottaja</string> <string name="stats_date_max">To</string>
<string name="stats_who">Jäsen</string> <string name="stats_who">Member</string>
<string name="stats_paid">Maksettu</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Käytetty</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Saldo</string> <string name="stats_balance">Balance</string>
<string name="total">Yhteensä: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Yhteys epäonnistui: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Luonti epäonnistui: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Virhe päivitettäessä etäporjektia: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Verkko ei ole käytettävissä etäkäyttöön.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">QR-koodin jäsentäminen epäonnistui.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Todennustunnus ei täsmää. Kirjaudu sisään uudelleen.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Sinulla ei ole oikeuksia suorittaa tätä toimintoa.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Poista Tunniste</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Oletko varma, että haluat poistaa tämän tunnisteen?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Versio %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Ylläpitäjä</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Lisenssi</string> <string name="about_license_title">License</string>
<string name="about_source_title">Lähdekoodi</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Projekti %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Jaa %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+98 -71
View File
@@ -1,34 +1,40 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Vache dépensée</string>
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Nouvelle facture</string> <string name="action_new_bill">Nouvelle facture</string>
<string name="action_add_project">Ajouter un projet</string> <string name="action_add_project">Ajouter un projet</string>
<string name="action_save">Enregistrer</string> <string name="action_save">Enregistrer</string>
<string name="action_edit">Editer</string> <string name="action_edit">Modifier</string>
<string name="action_share">Partager</string> <string name="action_share">Partager</string>
<string name="action_search">Chercher</string> <string name="action_search">Rechercher</string>
<string name="action_delete">Supprimez</string> <string name="action_open_menu">Ouvrir le menu</string>
<string name="action_archive">Archive</string> <string name="action_close_search">Fermer la recherche</string>
<string name="action_clear_search">Effacer la recherche</string>
<string name="action_delete">Supprimer</string>
<string name="simple_back">Retour</string>
<string name="action_archive">Archiver</string>
<string name="action_unarchive">Désarchiver</string> <string name="action_unarchive">Désarchiver</string>
<string name="action_export">Exportation</string> <string name="action_export">Exporter</string>
<string name="action_stats">Stats</string> <string name="action_stats">Stats</string>
<string name="action_settle">Régler</string> <string name="action_settle">Régler</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scanner un QR code</string>
<string name="action_settings">Réglages</string> <string name="action_settings">Réglages</string>
<string name="action_label_bills">Catégories manquantes</string> <string name="action_label_bills">Catégoriser les factures</string>
<string name="action_logout">Déconnexion</string> <string name="action_logout">Déconnecter</string>
<string name="action_connect">Connecter</string> <string name="action_connect">Connecter</string>
<string name="action_discard">Abandonner</string> <string name="action_discard">Abandonner</string>
<string name="action_members">Membres</string> <string name="action_members">Membres</string>
<string name="action_labels">Étiquettes</string> <string name="action_labels">Étiquettes</string>
<string name="action_currencies">Devises</string> <string name="action_currencies">Devises</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistiques</string> <string name="title_stats">Statistiques</string>
<string name="title_edit_project">Modifier le projet</string> <string name="title_edit_project">Modifier le projet</string>
<string name="title_label_bills">Étiquettes de factures</string> <string name="title_label_bills">Catégoriser les factures</string>
<string name="title_labels">Gérer les étiquettes</string> <string name="title_labels">Gérer les étiquettes</string>
<string name="title_about">À propos de</string> <string name="title_about">À propos</string>
<string name="title_settle">Régler le projet</string> <string name="title_settle">Régler le projet</string>
<string name="title_share">Partager le projet</string> <string name="title_share">Partager le projet</string>
<string name="title_add_project">Ajouter un projet</string> <string name="title_add_project">Ajouter un projet</string>
@@ -36,14 +42,15 @@
<string name="title_add_payment_mode">Ajouter un mode de paiement</string> <string name="title_add_payment_mode">Ajouter un mode de paiement</string>
<string name="title_account">Compte Nextcloud</string> <string name="title_account">Compte Nextcloud</string>
<string name="title_share_web">Lien web</string> <string name="title_share_web">Lien web</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Lien Cowspent</string>
<string name="title_confirm">Êtes-vous sûr(e) ?</string> <string name="title_confirm">Êtes-vous sûr(e) ?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Toutes les factures</string> <string name="label_all_bills">Toutes les factures</string>
<string name="label_categories">Catégories</string> <string name="label_categories">Catégories</string>
<string name="label_payment_modes">Modes de paiement</string> <string name="label_payment_modes">Modes de paiement</string>
<string name="label_name">Nom</string> <string name="label_name">Nom</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icône / Emoji</string>
<string name="label_color">Couleur</string> <string name="label_color">Couleur</string>
<string name="label_weight">Poids</string> <string name="label_weight">Poids</string>
<string name="label_activated">Activé</string> <string name="label_activated">Activé</string>
@@ -51,48 +58,50 @@
<string name="label_email">Courriel</string> <string name="label_email">Courriel</string>
<string name="label_url">Adresse du serveur</string> <string name="label_url">Adresse du serveur</string>
<string name="label_username">Nom d\'utilisateur</string> <string name="label_username">Nom d\'utilisateur</string>
<string name="label_comment">Commenter</string> <string name="label_comment">Commentaire</string>
<string name="label_what">Quoi?</string> <string name="label_what">Quoi ?</string>
<string name="label_payer">Qui a payé ?</string> <string name="label_payer">Qui a payé ?</string>
<string name="label_owers">Pour qui?</string> <string name="label_owers">Pour qui ?</string>
<string name="label_repeat">Répéter toutes les</string> <string name="label_repeat">Répétition</string>
<string name="label_mode">Mode</string> <string name="label_mode">Mode</string>
<string name="label_category">Catégorie</string> <string name="label_category">Catégorie</string>
<string name="label_project_id">ID/nom du projet</string> <string name="label_project_id">ID/nom du projet</string>
<string name="label_project_title">Titre du projet</string> <string name="label_project_title">Titre du projet</string>
<string name="label_use_sso">Utiliser le compte Nextcloud App</string> <string name="label_use_sso">Utiliser le compte de l\'application Nextcloud</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Modifications non enregistrées</string> <string name="dialog_unsaved_changes_title">Modifications non enregistrées</string>
<string name="dialog_unsaved_changes_msg">Enregistrer les modifications avant de partir?</string> <string name="dialog_unsaved_changes_msg">Enregistrer les modifications avant de quitter ?</string>
<string name="dialog_confirm_remove_project_msg">Le projet distant ne sera pas supprimé.</string> <string name="dialog_confirm_remove_project_msg">Le projet distant ne sera pas supprimé.</string>
<string name="dialog_sync_error_title">Erreur de synchronisation</string> <string name="dialog_sync_error_title">Erreur de synchronisation</string>
<string name="dialog_sync_error_msg">Échec de la synchronisation pour %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Échec de la synchronisation pour %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Les dépenses sont déjà équilibrées.</string> <string name="dialog_balanced_msg">Les dépenses sont déjà équilibrées.</string>
<string name="msg_project_added">Projet %1$s ajouté</string> <string name="msg_project_added">Projet %1$s ajouté</string>
<string name="msg_bill_labeled_done">Toutes les factures étiquetées</string> <string name="msg_bill_labeled_done">Toutes les factures sont catégorisées</string>
<string name="msg_no_suggestions">Aucune suggestion</string> <string name="msg_no_suggestions">Aucune suggestion</string>
<string name="msg_auth_warning">Nécessite Cospend v0.3.4+.</string> <string name="msg_auth_warning">Nécessite Cospend v0.3.4+.</string>
<string name="msg_link_copied">Lien copié dans le presse-papiers</string> <string name="msg_link_copied">Lien copié dans le presse-papiers</string>
<string name="msg_share_qr">Scannez le code QR ou partagez le lien pour vous inscrire.</string> <string name="msg_share_qr">Scannez le QR code ou partagez le lien pour rejoindre le projet.</string>
<string name="msg_share_web">Lien pour accéder au navigateur Web.</string> <string name="msg_share_web">Lien d\'accès depuis un navigateur web.</string>
<string name="msg_share_qr_warn">Partagez ce lien avec un utilisateur Cowspent</string> <string name="msg_share_qr_warn">Partagez ce lien avec un utilisateur de Cowspent.</string>
<string name="msg_settle_intro">Réglage pour %1$s:</string> <string name="msg_settle_intro">Règlement pour %1$s :</string>
<string name="msg_settle_sentence">%1$s doit %3$.2f à %2$s</string> <string name="msg_settle_sentence">%1$s doit %3$.2f à %2$s</string>
<string name="msg_stats_intro">Statistiques pour %1$s:</string> <string name="msg_stats_intro">Statistiques pour %1$s :</string>
<string name="msg_stats_header">Membre (payé | Dépensé | Solde)</string> <string name="msg_stats_header">Membre (Payé | Dépensé | Solde)</string>
<string name="msg_logged_in_as">Connecté en tant que %1$s</string> <string name="msg_logged_in_as">Connecté en tant que %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Erreur</string> <string name="error_generic">Erreur</string>
<string name="error_loading">En cours de chargement</string> <string name="error_loading">Chargement</string>
<string name="error_no_projects">Aucun projet trouvé</string> <string name="error_no_projects">Aucun projet trouvé</string>
<string name="error_no_members">Aucun membre trouvé</string> <string name="error_no_members">Aucun membre trouvé</string>
<string name="error_no_bills">Aucune facture trouvée</string> <string name="error_no_bills">Aucune facture trouvée</string>
<string name="error_no_member">Au moins un membre est requis</string> <string name="error_no_member">Au moins un membre est requis</string>
<string name="error_maintenance_mode">Le serveur est en mode maintenance</string> <string name="error_maintenance_mode">Le serveur est en mode maintenance</string>
<string name="error_400">400 Mauvaise requête</string> <string name="error_400">400 Requête incorrecte</string>
<string name="error_401">401 Non autorisé</string> <string name="error_401">401 Non autorisé</string>
<string name="error_403">403 Interdit</string> <string name="error_403">403 Interdit</string>
<string name="error_404">404 introuvable</string> <string name="error_404">404 Introuvable</string>
<string name="error_sync">Échec de la synchronisation : %1$s</string> <string name="error_sync">Échec de la synchronisation : %1$s</string>
<string name="error_invalid_login">Identifiant invalide : %1$s</string> <string name="error_invalid_login">Identifiant invalide : %1$s</string>
<string name="error_auth">Mauvais nom d\'utilisateur ou mot de passe</string> <string name="error_auth">Mauvais nom d\'utilisateur ou mot de passe</string>
@@ -100,64 +109,78 @@
<string name="error_req_failed">La requête a échoué</string> <string name="error_req_failed">La requête a échoué</string>
<string name="error_invalid_email">Adresse e-mail invalide</string> <string name="error_invalid_email">Adresse e-mail invalide</string>
<string name="error_invalid_project_id">ID de projet invalide</string> <string name="error_invalid_project_id">ID de projet invalide</string>
<string name="error_invalid_project_name">Titre du projet non valide</string> <string name="error_invalid_project_name">Titre de projet invalide</string>
<string name="error_invalid_bill_name">Nom de facture invalide</string> <string name="error_invalid_bill_name">Nom de facture invalide</string>
<string name="error_invalid_bill_date">Date de facture invalide</string> <string name="error_invalid_bill_date">Date de facture invalide</string>
<string name="error_invalid_bill_payer">Payeur requis</string> <string name="error_invalid_bill_payer">Payeur requis</string>
<string name="error_invalid_bill_owers">Propriétaires requis</string> <string name="error_invalid_bill_owers">Participants requis</string>
<string name="error_no_network">Aucune connexion réseau</string> <string name="error_no_network">Aucune connexion réseau</string>
<string name="error_server">Erreur serveur</string> <string name="error_server">Erreur serveur</string>
<string name="error_io">La connexion au serveur a échoué</string> <string name="error_io">La connexion au serveur a échoué</string>
<string name="error_share_impossible">Impossible de partager ce projet</string> <string name="error_share_impossible">Impossible de partager ce projet</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Se connecter au compte Nextcloud</string> <string name="drawer_no_account">Se connecter au compte Nextcloud</string>
<string name="drawer_last_sync">Dernière synchronisation : %1$02d:%2$02d</string> <string name="drawer_last_sync">Dernière synchronisation : %1$02d:%2$02d</string>
<string name="simple_cancel">Abandonner</string> <string name="simple_cancel">Annuler</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Oui</string> <string name="simple_yes">Oui</string>
<string name="simple_no">Non</string> <string name="simple_no">Non</string>
<string name="simple_close">Fermer</string> <string name="simple_close">Fermer</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Apparence</string> <string name="settings_appearance">Apparence</string>
<string name="settings_network">Réseau</string> <string name="settings_network">Réseau</string>
<string name="settings_other">Autres</string> <string name="settings_other">Autres</string>
<string name="settings_night_mode">Thème</string> <string name="settings_night_mode">Thème</string>
<string name="settings_offline_mode">Mode hors-ligne</string> <string name="settings_offline_mode">Mode hors ligne</string>
<string name="settings_offline_mode_summary">Synchroniser uniquement manuellement.</string> <string name="settings_offline_mode_summary">Synchroniser uniquement manuellement.</string>
<string name="settings_color_custom">Couleur personnalisée</string> <string name="settings_color_custom">Couleur personnalisée</string>
<string name="settings_color_mode">Sélection de la couleur</string> <string name="settings_color_mode">Sélection de la couleur</string>
<string name="settings_show_archived">Afficher les projets archivés</string> <string name="settings_show_archived">Afficher les projets archivés</string>
<string name="settings_beta_features">Fonctionnalités bêta</string> <string name="settings_beta_features">Fonctionnalités bêta</string>
<string name="settings_beta_features_summary">Activer les fonctionnalités expérimentales. Utiliser à vos propres risques.</string> <string name="settings_beta_features_summary">Activer les fonctionnalités expérimentales. À utiliser à vos risques et périls.</string>
<string name="settings_fill_new_bill_from_last">Pré-remplir depuis la dernière facture</string>
<string name="settings_fill_new_bill_from_last_summary">Reprendre le payeur, la catégorie, le mode et les participants de la dernière facture créée dans le projet.</string>
<string name="settings_auto_sync_on_open">Intervalle de synchronisation</string>
<string name="settings_auto_sync_on_open_summary">Fréquence de rafraîchissement du compte et de tous les projets à l\'ouverture de l\'application.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 heure</string>
<string name="pref_value_sync_1d">1 jour</string>
<string name="settings_url_warn_http">AVERTISSEMENT : \"http\" n\'est pas sûr. Utilisez \"https\".</string> <string name="settings_url_warn_http">AVERTISSEMENT : \"http\" n\'est pas sûr. Utilisez \"https\".</string>
<string name="settings_colorpicker_title">Choisir une couleur</string> <string name="settings_colorpicker_title">Choisir une couleur</string>
<string name="pref_value_color_system">Système</string> <string name="pref_value_color_system">Système</string>
<string name="pref_value_color_server">Nuage suivant</string>
<string name="pref_value_color_manual">Manuelle</string> <string name="pref_value_color_manual">Manuelle</string>
<string name="pref_value_theme_light">Lumière</string> <string name="pref_value_theme_light">Clair</string>
<string name="pref_value_theme_dark">Sombre</string> <string name="pref_value_theme_dark">Sombre</string>
<string name="pref_value_theme_system">Suivre le système</string> <string name="pref_value_theme_system">Suivre le système</string>
<!-- Constants (Do not translate) --> <!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Pas de répétition</string> <string name="repeat_no">Pas de répétition</string>
<string name="repeat_day">Tous les jours</string> <string name="repeat_day">Quotidienne</string>
<string name="repeat_week">Hebdomadaire</string> <string name="repeat_week">Hebdomadaire</string>
<string name="repeat_fortnight">Tous les quinze jours</string> <string name="repeat_fortnight">Toutes les deux semaines</string>
<string name="repeat_month">Mensuel</string> <string name="repeat_month">Mensuelle</string>
<string name="repeat_year">Annuel</string> <string name="repeat_year">Annuelle</string>
<string name="payment_mode_none">Aucun</string> <string name="payment_mode_none">Aucun</string>
<string name="payment_mode_all">Tous</string> <string name="payment_mode_all">Tous</string>
<string name="payment_mode_credit_card">Carte de crédit</string> <string name="payment_mode_credit_card">Carte bancaire</string>
<string name="payment_mode_cash">Espèces</string> <string name="payment_mode_cash">Espèces</string>
<string name="payment_mode_check">Contrôler</string> <string name="payment_mode_check">Chèque</string>
<string name="payment_mode_online">En ligne</string> <string name="payment_mode_online">En ligne</string>
<string name="payment_mode_transfer">Transférer</string> <string name="payment_mode_transfer">Virement</string>
<string name="category_none">Aucun</string>
<string name="category_all">Tous</string> <string name="category_none">Aucune</string>
<string name="category_all_except_reimbursement">Tout sauf remboursement</string> <string name="category_all">Toutes</string>
<string name="category_groceries">Épicerie</string> <string name="category_all_except_reimbursement">Toutes sauf remboursement</string>
<string name="category_leisure">Barre/Fête</string> <string name="category_groceries">Courses</string>
<string name="category_rent">Louer</string> <string name="category_leisure">Bar/Fête</string>
<string name="category_rent">Loyer</string>
<string name="category_bills">Facture</string> <string name="category_bills">Facture</string>
<string name="category_excursion">Excursion/Culture</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_health">Santé</string> <string name="category_health">Santé</string>
@@ -167,75 +190,79 @@
<string name="category_accomodation">Hébergement</string> <string name="category_accomodation">Hébergement</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Qu\'est-ce que</string> <string name="new_project_action">Quoi</string>
<string name="new_project_where"> se trouve</string> <string name="new_project_where"></string>
<string name="where_local">Seulement en local</string> <string name="where_local">Local uniquement</string>
<string name="where_cospend">Codépense</string>
<string name="where_ihatemoney">format@@0 IHateMoney</string>
<string name="todo_join">Rejoindre un projet existant</string> <string name="todo_join">Rejoindre un projet existant</string>
<string name="todo_create">Créer un nouveau projet</string> <string name="todo_create">Créer un nouveau projet</string>
<string name="import_tooltip">Importer depuis un fichier</string> <string name="import_tooltip">Importer depuis un fichier</string>
<string name="choose_account_project_dialog_title">Choisir un projet</string>
<string name="choose_account_project_dialog_impossible">Aucun projet trouvé sur ce compte.</string>
<string name="choose_project_management_action">Projet</string> <string name="choose_project_management_action">Projet</string>
<string name="project_added_success">Le projet a été ajouté avec succès.</string> <string name="project_added_success">Le projet a été ajouté avec succès.</string>
<string name="no_projects_text">Vous n\'avez pas encore de projets.</string> <string name="no_projects_text">Vous n\'avez pas encore de projet.</string>
<string name="configure_account_choice">Configurer le compte Nextcloud</string> <string name="configure_account_choice">Configurer le compte Nextcloud</string>
<string name="add_project_choice">Ajouter un projet manuellement</string> <string name="add_project_choice">Ajouter un projet manuellement</string>
<string name="no_members_text">Aucun membre dans ce projet.</string> <string name="no_members_text">Aucun membre dans ce projet.</string>
<string name="no_bills_text">Aucune facture trouvée.</string> <string name="no_bills_text">Aucune facture trouvée.</string>
<string name="member_already_exists">Ce membre existe déjà.</string> <string name="member_already_exists">Ce membre existe déjà.</string>
<string name="activity_dialog_title">Projet: %1$s</string> <string name="activity_dialog_title">Projet : %1$s</string>
<string name="remove_project_confirmation">Projet %1$s supprimé.</string> <string name="remove_project_confirmation">Projet %1$s supprimé.</string>
<string name="file_saved_success">Fichier enregistré : %1$s</string> <string name="file_saved_success">Fichier enregistré : %1$s</string>
<string name="import_error_header">Échec de l\'importation à la ligne %d</string> <string name="import_error_header">Échec de l\'importation à la ligne %d</string>
<string name="import_error_date">Format de date invalide à la ligne %d</string> <string name="import_error_date">Format de date invalide à la ligne %d</string>
<string name="import_error_owers">Propriétés non valides à la ligne %d</string> <string name="import_error_owers">Participants invalides à la ligne %d</string>
<string name="add_member_dialog_title">Ajouter un membre</string> <string name="add_member_dialog_title">Ajouter un membre</string>
<string name="edit_member_dialog_title">Modifier le membre</string> <string name="edit_member_dialog_title">Modifier le membre</string>
<string name="member_edit_delete">Supprimez</string> <string name="member_edit_delete">Supprimer</string>
<string name="project_edition_no_change">Aucune modification à enregistrer.</string> <string name="project_edition_no_change">Aucune modification à enregistrer.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Aucun (optimiste)</string> <string name="center_none">Aucun (optimal)</string>
<string name="settle_who">Qui paie</string> <string name="settle_who">Qui paie</string>
<string name="settle_to_whom">À qui</string> <string name="settle_to_whom">À qui</string>
<string name="settle_how_much">Montant</string> <string name="settle_how_much">Montant</string>
<string name="simple_settle_share">Partager</string> <string name="simple_settle_share">Partager</string>
<string name="simple_create_bills">Créer des factures</string> <string name="simple_create_bills">Créer les factures</string>
<string name="settle_bill_what">Réglement</string> <string name="settle_bill_what">Règlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Choisir la devise (%s)</string> <string name="currency_dialog_title">Choisir la devise (%s)</string>
<string name="setting_none">Aucun</string> <string name="setting_none">Aucune</string>
<string name="setting_all">Tous</string> <string name="setting_all">Toutes</string>
<string name="currency_saved_success">Paramètres des devises enregistrés.</string> <string name="currency_saved_success">Paramètres des devises enregistrés.</string>
<string name="main_currency">Devise principale</string> <string name="main_currency">Devise principale</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Catégories suggérées</string> <string name="label_bills_suggested">Catégories suggérées</string>
<string name="label_bills_skip">Ignorer</string> <string name="label_bills_skip">Ignorer</string>
<string name="stats_date_min">A partir de</string> <string name="stats_date_min">Du</string>
<string name="stats_date_max">À</string> <string name="stats_date_max">Au</string>
<string name="stats_who">Membre</string> <string name="stats_who">Membre</string>
<string name="stats_paid">Payé</string> <string name="stats_paid">Payé</string>
<string name="stats_spent">Dépensé</string> <string name="stats_spent">Dépensé</string>
<string name="stats_balance">Solde</string> <string name="stats_balance">Solde</string>
<string name="total">Total : %1$s</string> <string name="total">Total : %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Échec de la connexion : %1$s</string> <string name="error_project_connect_check">Échec de la connexion : %1$s</string>
<string name="error_create_remote_project_helper">Échec de la création : %1$s</string> <string name="error_create_remote_project_helper">Échec de la création : %1$s</string>
<string name="error_edit_remote_project_helper">Erreur lors de la mise à jour du projet distant : %1$s</string> <string name="error_edit_remote_project_helper">Erreur lors de la mise à jour du projet distant : %1$s</string>
<string name="remote_project_operation_no_network">Réseau indisponible pour le fonctionnement à distance.</string> <string name="remote_project_operation_no_network">Réseau indisponible pour cette opération distante.</string>
<string name="error_scanning_bill_qr_code">Impossible d\'analyser le code QR.</string> <string name="error_scanning_bill_qr_code">Impossible de lire le QR code.</string>
<string name="error_token_mismatch">Incompatibilité du jeton d\'authentification. Veuillez vous reconnecter.</string> <string name="error_token_mismatch">Jeton d\'authentification invalide. Veuillez vous reconnecter.</string>
<string name="insufficient_access_level">Vous n\'avez pas la permission d\'effectuer cette action.</string> <string name="insufficient_access_level">Vous n\'avez pas la permission d\'effectuer cette action.</string>
<string name="delete_label_confirmation_title">Supprimer l\'étiquette</string> <string name="delete_label_confirmation_title">Supprimer l\'étiquette</string>
<string name="delete_label_confirmation_message">Êtes-vous sûr de vouloir supprimer ce label ?</string> <string name="delete_label_confirmation_message">Voulez-vous vraiment supprimer cette étiquette ?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Mainteneur</string> <string name="about_maintainer_title">Mainteneur</string>
<string name="about_license_title">Licence</string> <string name="about_license_title">Licence</string>
<string name="about_source_title">Code source</string> <string name="about_source_title">Code source</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Projet %1$s</string> <string name="share_intent_title">Projet %1$s</string>
<string name="share_chooser_title">Partager %1$s</string> <string name="share_chooser_title">Partager %1$s</string>
</resources> </resources>
+39 -8
View File
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">New bill</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Add project</string> <string name="action_add_project">Add project</string>
@@ -8,7 +15,11 @@
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_open_menu">Open menu</string>
<string name="action_close_search">Close search</string>
<string name="action_clear_search">Clear search</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="simple_back">Back</string>
<string name="action_archive">Archive</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string> <string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string> <string name="action_export">Export</string>
@@ -23,6 +34,7 @@
<string name="action_members">Members</string> <string name="action_members">Members</string>
<string name="action_labels">Labels</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Currencies</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistics</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Edit project</string> <string name="title_edit_project">Edit project</string>
@@ -38,6 +50,7 @@
<string name="title_share_web">Web link</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Are you sure?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">All bills</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categories</string> <string name="label_categories">Categories</string>
@@ -61,6 +74,7 @@
<string name="label_project_id">Project ID/name</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project title</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Use Nextcloud App Account</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Unsaved changes</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Save changes before leaving?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
@@ -81,6 +95,7 @@
<string name="msg_stats_intro">Stats for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Member (Paid | Spent | Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Error</string> <string name="error_generic">Error</string>
<string name="error_loading">Loading</string> <string name="error_loading">Loading</string>
@@ -109,6 +124,7 @@
<string name="error_server">Server error</string> <string name="error_server">Server error</string>
<string name="error_io">Server connection broken</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Cannot share this project</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Connect to Nextcloud account</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
@@ -117,6 +133,7 @@
<string name="simple_yes">Yes</string> <string name="simple_yes">Yes</string>
<string name="simple_no">No</string> <string name="simple_no">No</string>
<string name="simple_close">Close</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Appearance</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Network</string> <string name="settings_network">Network</string>
@@ -129,15 +146,23 @@
<string name="settings_show_archived">Show archived projects</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WARNING: \"http\" is unsafe. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string> <string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string> <string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">No repeat</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Daily</string> <string name="repeat_day">Daily</string>
@@ -145,6 +170,7 @@
<string name="repeat_fortnight">Fortnightly</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Monthly</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Yearly</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">None</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_all">All</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_credit_card">Credit card</string> <string name="payment_mode_credit_card">Credit card</string>
@@ -152,6 +178,7 @@
<string name="payment_mode_check">Check</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">None</string> <string name="category_none">None</string>
<string name="category_all">All</string> <string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
@@ -167,17 +194,14 @@
<string name="category_accomodation">Accommodation</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">Where</string> <string name="new_project_where">Where</string>
<string name="where_local">Local only</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Join existing project</string> <string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string> <string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string> <string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string> <string name="no_projects_text">You have no projects yet.</string>
@@ -196,6 +220,7 @@
<string name="edit_member_dialog_title">Edit Member</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Delete</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">No changes to save.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">None (Optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Who pays</string> <string name="settle_who">Who pays</string>
@@ -204,12 +229,14 @@
<string name="simple_settle_share">Share</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Create bills</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Settlement</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Choose Currency (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">None</string> <string name="setting_none">None</string>
<string name="setting_all">All</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Currency settings saved.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Main Currency</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Suggested Categories</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Skip</string> <string name="label_bills_skip">Skip</string>
@@ -220,6 +247,7 @@
<string name="stats_spent">Spent</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Balance</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Connection failed: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
@@ -230,12 +258,15 @@
<string name="insufficient_access_level">You don\'t have permission to perform this action.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Delete Label</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Maintainer</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">License</string> <string name="about_license_title">License</string>
<string name="about_source_title">Source code</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Share %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+238 -207
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Nuova bolletta</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Aggiungi progetto</string> <string name="action_add_project">Add project</string>
<string name="action_save">Salva</string> <string name="action_save">Save</string>
<string name="action_edit">Modifica</string> <string name="action_edit">Edit</string>
<string name="action_share">Condividi</string> <string name="action_share">Share</string>
<string name="action_search">Cerca</string> <string name="action_search">Search</string>
<string name="action_delete">Elimina</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Archivio</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Disarchivia</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Esporta</string> <string name="action_delete">Delete</string>
<string name="action_stats">Statistiche</string> <string name="simple_back">Back</string>
<string name="action_settle">Salta</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Impostazioni</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Etichetta categorie mancanti</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Esci</string> <string name="action_logout">Logout</string>
<string name="action_connect">Connetti</string> <string name="action_connect">Connect</string>
<string name="action_discard">Scarta</string> <string name="action_discard">Discard</string>
<string name="action_members">Membri</string> <string name="action_members">Members</string>
<string name="action_labels">Etichette</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Valute</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistiche</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Modifica progetto</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Etichetta Di Bollette</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Gestisci Etichette</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">Informazioni</string> <string name="title_about">About</string>
<string name="title_settle">Settle Project</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Condividi Progetto</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Aggiungi Progetto</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Aggiungi Categoria</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Aggiungi Modalità Di Pagamento</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Account Nextcloud</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Collegamento web</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Sei sicuro?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Tutte le bollette</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categorie</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Modalità Di Pagamento</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Nome</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Colore</string> <string name="label_color">Color</string>
<string name="label_weight">Peso</string> <string name="label_weight">Weight</string>
<string name="label_activated">Attivato</string> <string name="label_activated">Activated</string>
<string name="label_password">Password</string> <string name="label_password">Password</string>
<string name="label_email">E-mail</string> <string name="label_email">E-mail</string>
<string name="label_url">Indirizzo del server</string> <string name="label_url">Server address</string>
<string name="label_username">Username</string> <string name="label_username">Username</string>
<string name="label_comment">Commento</string> <string name="label_comment">Comment</string>
<string name="label_what">Cosa?</string> <string name="label_what">What?</string>
<string name="label_payer">Chi ha pagato?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Per chi?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Ripeti ogni</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Modalità</string> <string name="label_mode">Mode</string>
<string name="label_category">Categoria</string> <string name="label_category">Category</string>
<string name="label_project_id">Id Del Progetto/Nome</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Titolo del progetto</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Usa Account App Nextcloud</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Modifiche non salvate</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Salvare le modifiche prima di partire?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Il progetto remoto non verrà eliminato.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Errore di sincronizzazione</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Sincronizzazione fallita per %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Le spese sono già bilanciate.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Project %1$s added</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Tutte le fatture etichettate</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Nessun suggerimento</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Richiede Cospend v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Link copiato negli appunti</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Scansiona il codice QR o condividi il link per unirsi.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Link per l\'accesso al browser web.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Condividi questo link con un utente Cowspent</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Regolamento per %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s deve %3$.2f a %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Statistiche per %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Membro (Saldo &lt;unk&gt; Speso &lt;unk&gt; Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Accesso effettuato come %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Errore</string> <string name="error_generic">Error</string>
<string name="error_loading">Caricamento</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Nessun progetto trovato</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Nessun membro trovato</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Nessuna bolletta trovata</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Almeno un membro richiesto</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Il server è in modalità manutenzione</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 Richiesta errata</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Non Autorizzato</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Vietato</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Non Trovato</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Sincronizzazione non riuscita: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Login non valido: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Nome utente o password errati</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Risposta server non valida</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Richiesta fallita</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">E-mail non valida</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">ID progetto non valido</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Titolo progetto non valido</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Nome fattura non valido</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Data fattura non valida</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Pagatore richiesto</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Proprietari richiesti</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Nessuna connessione di rete</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Errore del server</string> <string name="error_server">Server error</string>
<string name="error_io">Connessione al server interrotta</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Impossibile condividere questo progetto</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Connetti all\'account Nextcloud</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Ultima sincronizzazione: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Annulla</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes"></string> <string name="simple_yes">Yes</string>
<string name="simple_no">No</string> <string name="simple_no">No</string>
<string name="simple_close">Chiudi</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Aspetto</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Rete</string> <string name="settings_network">Network</string>
<string name="settings_other">Altro</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Tema</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Modalità offline</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Sincronizza solo manualmente.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Colore personalizzato</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Selezione Colore</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Mostra progetti archiviati</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Caratteristiche Beta</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Abilita le funzioni sperimentali. Usa a tuo rischio.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">ATTENZIONE: \"http\" non è sicuro. Usa \"국\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Scegli Colore</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">Sistema</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">Manuale</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">Chiaro</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">Scuro</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">Segui sistema</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Nessuna ripetizione</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Giornaliero</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Settimanale</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Quindici</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Mensile</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Annuale</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Nessuno</string>
<string name="payment_mode_all">Tutti</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Carta di credito</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Contanti</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Controlla</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Trasferisci</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">Nessuno</string>
<string name="category_all">Tutti</string> <string name="category_none">None</string>
<string name="category_all_except_reimbursement">Tutti tranne il rimborso</string> <string name="category_all">All</string>
<string name="category_groceries">Alimentari</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_groceries">Grocery</string>
<string name="category_leisure">Bar/Party</string> <string name="category_leisure">Bar/Party</string>
<string name="category_rent">Affitto</string> <string name="category_rent">Rent</string>
<string name="category_bills">Fattura</string> <string name="category_bills">Bill</string>
<string name="category_excursion">Escursione/Cultura</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_health">Salute</string> <string name="category_health">Health</string>
<string name="category_shopping">Shopping</string> <string name="category_shopping">Shopping</string>
<string name="category_reimbursement">Rimborso</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_restaurant">Ristorante</string> <string name="category_restaurant">Restaurant</string>
<string name="category_accomodation">Alloggio</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Trasporti</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Cosa</string> <string name="new_project_action">What</string>
<string name="new_project_where">Dove</string> <string name="new_project_where">Where</string>
<string name="where_local">Solo locale</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Unisciti al progetto esistente</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Crea nuovo progetto</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Importa da file</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Scegli progetto</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Nessun progetto trovato su questo account.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Progetto</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Progetto aggiunto con successo.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Non hai ancora alcun progetto.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Configura account Nextcloud</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Aggiunge manualmente il progetto</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Nessun membro in questo progetto.</string>
<string name="no_bills_text">Nessuna bolletta trovata.</string>
<string name="member_already_exists">Membro già esistente.</string>
<string name="activity_dialog_title">Progetto: %1$s</string>
<string name="remove_project_confirmation">Project %1$s removed.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="file_saved_success">File salvato: %1$s</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="import_error_header">Importazione fallita alla riga %d</string> <string name="import_error_header">Import failed at row %d</string>
<string name="import_error_date">Formato data non valido alla riga %d</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="import_error_owers">Guanti non validi alla riga %d</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="add_member_dialog_title">Aggiungi Membro</string> <string name="add_member_dialog_title">Add Member</string>
<string name="edit_member_dialog_title">Modifica Membro</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Elimina</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">Nessuna modifica da salvare.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Nessuno (ottimale)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Chi paga</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">A chi</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Importo</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Condividi</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Crea bollette</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Regolamento</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Scegli Valuta (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Nessuno</string> <string name="setting_none">None</string>
<string name="setting_all">Tutti</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Impostazioni valuta salvate.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Valuta Principale</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Categorie Suggerite</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Salta</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">Da</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">A</string> <string name="stats_date_max">To</string>
<string name="stats_who">Membro</string> <string name="stats_who">Member</string>
<string name="stats_paid">Pagato</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Speso</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Saldo</string> <string name="stats_balance">Balance</string>
<string name="total">Totale: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Connessione non riuscita: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creazione fallita: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Errore nell\'aggiornare il progetto remoto: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Rete non disponibile per operazioni remote.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Analisi del codice QR non riuscita.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Token di autenticazione non corrisponde. Effettua nuovamente il login.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Non hai i permessi per eseguire questa azione.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Elimina Etichetta</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Sei sicuro di voler eliminare questa etichetta?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Versione %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Responsabile</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Licenza</string> <string name="about_license_title">License</string>
<string name="about_source_title">Codice sorgente</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Condividi %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+39 -8
View File
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">New bill</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Add project</string> <string name="action_add_project">Add project</string>
@@ -8,7 +15,11 @@
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_open_menu">Open menu</string>
<string name="action_close_search">Close search</string>
<string name="action_clear_search">Clear search</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="simple_back">Back</string>
<string name="action_archive">Archive</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string> <string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string> <string name="action_export">Export</string>
@@ -23,6 +34,7 @@
<string name="action_members">Members</string> <string name="action_members">Members</string>
<string name="action_labels">Labels</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Currencies</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistics</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Edit project</string> <string name="title_edit_project">Edit project</string>
@@ -38,6 +50,7 @@
<string name="title_share_web">Web link</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Are you sure?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">All bills</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categories</string> <string name="label_categories">Categories</string>
@@ -61,6 +74,7 @@
<string name="label_project_id">Project ID/name</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project title</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Use Nextcloud App Account</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Unsaved changes</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Save changes before leaving?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
@@ -81,6 +95,7 @@
<string name="msg_stats_intro">Stats for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Member (Paid | Spent | Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Error</string> <string name="error_generic">Error</string>
<string name="error_loading">Loading</string> <string name="error_loading">Loading</string>
@@ -109,6 +124,7 @@
<string name="error_server">Server error</string> <string name="error_server">Server error</string>
<string name="error_io">Server connection broken</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Cannot share this project</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Connect to Nextcloud account</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
@@ -117,6 +133,7 @@
<string name="simple_yes">Yes</string> <string name="simple_yes">Yes</string>
<string name="simple_no">No</string> <string name="simple_no">No</string>
<string name="simple_close">Close</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Appearance</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Network</string> <string name="settings_network">Network</string>
@@ -129,15 +146,23 @@
<string name="settings_show_archived">Show archived projects</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WARNING: \"http\" is unsafe. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string> <string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string> <string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">No repeat</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Daily</string> <string name="repeat_day">Daily</string>
@@ -145,6 +170,7 @@
<string name="repeat_fortnight">Fortnightly</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Monthly</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Yearly</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">None</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_all">All</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_credit_card">Credit card</string> <string name="payment_mode_credit_card">Credit card</string>
@@ -152,6 +178,7 @@
<string name="payment_mode_check">Check</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">None</string> <string name="category_none">None</string>
<string name="category_all">All</string> <string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
@@ -167,17 +194,14 @@
<string name="category_accomodation">Accommodation</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">Where</string> <string name="new_project_where">Where</string>
<string name="where_local">Local only</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Join existing project</string> <string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string> <string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string> <string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string> <string name="no_projects_text">You have no projects yet.</string>
@@ -196,6 +220,7 @@
<string name="edit_member_dialog_title">Edit Member</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Delete</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">No changes to save.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">None (Optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Who pays</string> <string name="settle_who">Who pays</string>
@@ -204,12 +229,14 @@
<string name="simple_settle_share">Share</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Create bills</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Settlement</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Choose Currency (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">None</string> <string name="setting_none">None</string>
<string name="setting_all">All</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Currency settings saved.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Main Currency</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Suggested Categories</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Skip</string> <string name="label_bills_skip">Skip</string>
@@ -220,6 +247,7 @@
<string name="stats_spent">Spent</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Balance</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Connection failed: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
@@ -230,12 +258,15 @@
<string name="insufficient_access_level">You don\'t have permission to perform this action.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Delete Label</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Maintainer</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">License</string> <string name="about_license_title">License</string>
<string name="about_source_title">Source code</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Share %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+247 -216
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">新しい請求書</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">プロジェクトを追加</string> <string name="action_add_project">Add project</string>
<string name="action_save">保存</string> <string name="action_save">Save</string>
<string name="action_edit">編集</string> <string name="action_edit">Edit</string>
<string name="action_share">共有</string> <string name="action_share">Share</string>
<string name="action_search">検索</string> <string name="action_search">Search</string>
<string name="action_delete">削除</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">アーカイブ</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">アーカイブ解除</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">エクスポート</string> <string name="action_delete">Delete</string>
<string name="action_stats">統計</string> <string name="simple_back">Back</string>
<string name="action_settle">決済する</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">設定</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">ラベル不足しているカテゴリ</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">ログアウト</string> <string name="action_logout">Logout</string>
<string name="action_connect">接続する</string> <string name="action_connect">Connect</string>
<string name="action_discard">破棄する</string> <string name="action_discard">Discard</string>
<string name="action_members">メンバー</string> <string name="action_members">Members</string>
<string name="action_labels">ラベル</string> <string name="action_labels">Labels</string>
<string name="action_currencies">通貨</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">統計情報</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">プロジェクトを編集</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">請求書のラベル</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">ラベルの管理</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">About</string> <string name="title_about">About</string>
<string name="title_settle">プロジェクトを決済する</string> <string name="title_settle">Settle Project</string>
<string name="title_share">プロジェクトを共有</string> <string name="title_share">Share Project</string>
<string name="title_add_project">プロジェクトを追加</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">カテゴリを追加</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">支払いモードを追加</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Nextcloudアカウント</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">ウェブリンク</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">よろしいですか?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">すべての請求書</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">カテゴリ</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">支払いモード</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">名前</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color"></string> <string name="label_color">Color</string>
<string name="label_weight">重量</string> <string name="label_weight">Weight</string>
<string name="label_activated">アクティベート済み</string> <string name="label_activated">Activated</string>
<string name="label_password">パスワード</string> <string name="label_password">Password</string>
<string name="label_email">電子メール</string> <string name="label_email">E-mail</string>
<string name="label_url">サーバーアドレス</string> <string name="label_url">Server address</string>
<string name="label_username">ユーザー名</string> <string name="label_username">Username</string>
<string name="label_comment">コメント</string> <string name="label_comment">Comment</string>
<string name="label_what">何?</string> <string name="label_what">What?</string>
<string name="label_payer">誰が支払ったのですか?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">誰のために?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">繰り返します</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">モード</string> <string name="label_mode">Mode</string>
<string name="label_category">カテゴリ</string> <string name="label_category">Category</string>
<string name="label_project_id">プロジェクト ID/名前</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">プロジェクトのタイトル</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Nextcloudアプリアカウントを使用する</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">保存されていない変更</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">脱退する前に変更を保存しますか?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">リモートプロジェクトは削除されません。</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">同期エラー</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">%1$sの同期に失敗しました。\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">費用はすでに均衡しています。</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">プロジェクト %1$s が追加されました</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">すべての請求書がラベル付けされました</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">候補なし</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Cospend v0.3.4以上が必要です。</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">リンクをクリップボードにコピーしました</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">QRコードをスキャンするか、リンクを共有して参加してください。</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">ウェブブラウザへのアクセスのためのリンク。</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Cowspent ユーザーとこのリンクを共有します。</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">%1$sの決済:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s %3$.2f %2$sに借りています</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">%1$s の統計:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">メンバー (ペイド | 使用済み)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">%1$s としてログイン中</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">エラー</string> <string name="error_generic">Error</string>
<string name="error_loading">読み込み中</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">プロジェクトが見つかりません</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">メンバーが見つかりませんでした</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">請求書が見つかりません</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">少なくとも1人のメンバーが必要です</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">サーバーはメンテナンスモードです</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400件の不正なリクエスト</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Unauthorized</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 禁止されました</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 が見つかりません</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">同期失敗: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">無効なログイン: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">ユーザー名またはパスワードが間違っています</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">無効なサーバー応答</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">リクエストに失敗しました</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">無効なメールアドレス</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">無効なプロジェクト ID</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">無効なプロジェクトのタイトル</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">無効な請求書名</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">請求書の日付が無効</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">支払者が必要です</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">所有者が必要</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">ネットワーク接続がありません</string> <string name="error_no_network">No network connection</string>
<string name="error_server">サーバーエラー</string> <string name="error_server">Server error</string>
<string name="error_io">サーバー接続が切断されました</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">このプロジェクトを共有できません</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Nextcloudアカウントに接続</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">最終同期: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">キャンセル</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">OK</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">はい</string> <string name="simple_yes">Yes</string>
<string name="simple_no">いいえ</string> <string name="simple_no">No</string>
<string name="simple_close">閉じる</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">外観</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">ネットワーク</string> <string name="settings_network">Network</string>
<string name="settings_other">その他</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">テーマ</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">オフラインモード</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">手動同期のみ。</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">カスタムカラー</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">色の選択</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">アーカイブされたプロジェクトを表示</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">ベータ版の機能</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">実験的な機能を有効にします。自己責任で使用してください。</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">警告: \"http\"は安全ではありません。\"https\"を使用してください。</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">色を選択</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">システム</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Nextcloud:</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">マニュアル</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">ライト</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">ダーク</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">システムをフォロー</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">繰り返しなし</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">毎日</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Weekly</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">四十夜</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">月ごと</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">年ごと</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">なし</string>
<string name="payment_mode_all">すべて</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">クレジットカード</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">現金</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">チェック</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">オンライン</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">送金</string> <string name="payment_mode_online">Online</string>
<string name="category_none">なし</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">すべて</string>
<string name="category_all_except_reimbursement">払い戻し以外のすべて</string> <string name="category_none">None</string>
<string name="category_groceries">食料品店</string> <string name="category_all">All</string>
<string name="category_leisure">バー/パーティー</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_rent">レンタル</string> <string name="category_groceries">Grocery</string>
<string name="category_bills">請求書:</string> <string name="category_leisure">Bar/Party</string>
<string name="category_excursion">エクスカーション/文化</string> <string name="category_rent">Rent</string>
<string name="category_health">健康</string> <string name="category_bills">Bill</string>
<string name="category_shopping">ショッピング</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_reimbursement">払い戻し額</string> <string name="category_health">Health</string>
<string name="category_restaurant">レストラン</string> <string name="category_shopping">Shopping</string>
<string name="category_accomodation">宿泊施設</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_transport">交通</string> <string name="category_restaurant">Restaurant</string>
<string name="category_sport">スポーツ</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string>
<string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">場所</string> <string name="new_project_where">Where</string>
<string name="where_local">ローカルのみ</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">既存のプロジェクトに参加</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">新しいプロジェクトを作成</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">ファイルからインポート</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">プロジェクトを選択</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">このアカウントにはプロジェクトが見つかりません。</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">プロジェクト</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">プロジェクトが正常に追加されました。</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">プロジェクトはまだありません。</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Nextcloudアカウントの設定</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">プロジェクトを手動で追加</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">このプロジェクトにはメンバーがいません。</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">請求書が見つかりません。</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">メンバーは既に存在します。</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">プロジェクト: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">プロジェクト %1$s が削除されました。</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">ファイルを保存しました: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">%d 行目のインポートに失敗しました</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">%d 行目に不正な日付形式があります</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">行 %d に無効な所有者がいます</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">メンバーを追加</string>
<string name="edit_member_dialog_title">メンバーを編集</string>
<string name="member_edit_delete">削除</string>
<string name="project_edition_no_change">保存する変更はありません。</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">なし (最適)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">誰が支払うか</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">誰に</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">金額</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">共有</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">請求書を作成</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">受領日</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">通貨を選択 (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">なし</string> <string name="setting_none">None</string>
<string name="setting_all">すべて</string> <string name="setting_all">All</string>
<string name="currency_saved_success">通貨設定を保存しました。</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">主な通貨</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">おすすめのカテゴリ</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">スキップ</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">差出人:</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">終了日</string> <string name="stats_date_max">To</string>
<string name="stats_who">メンバー</string> <string name="stats_who">Member</string>
<string name="stats_paid">支払い済み</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">使用済み:</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">残高</string> <string name="stats_balance">Balance</string>
<string name="total">合計: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">接続に失敗しました: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">作成失敗: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">リモートプロジェクトの更新中にエラーが発生しました: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">リモート操作でネットワークを利用できません。</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">QRコードの解析に失敗しました。</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">認証トークンが一致しません。もう一度ログインしてください。</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">このアクションを実行する権限がありません。</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">ラベルを削除</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">このラベルを削除してもよろしいですか?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">バージョン %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">メンテナー</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">ライセンス</string> <string name="about_license_title">License</string>
<string name="about_source_title">ソース コード</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">プロジェクト %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">%1$sを共有</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+39 -8
View File
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">New bill</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Add project</string> <string name="action_add_project">Add project</string>
@@ -8,7 +15,11 @@
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_open_menu">Open menu</string>
<string name="action_close_search">Close search</string>
<string name="action_clear_search">Clear search</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="simple_back">Back</string>
<string name="action_archive">Archive</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string> <string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string> <string name="action_export">Export</string>
@@ -23,6 +34,7 @@
<string name="action_members">Members</string> <string name="action_members">Members</string>
<string name="action_labels">Labels</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Currencies</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistics</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Edit project</string> <string name="title_edit_project">Edit project</string>
@@ -38,6 +50,7 @@
<string name="title_share_web">Web link</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Are you sure?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">All bills</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categories</string> <string name="label_categories">Categories</string>
@@ -61,6 +74,7 @@
<string name="label_project_id">Project ID/name</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project title</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Use Nextcloud App Account</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Unsaved changes</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Save changes before leaving?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
@@ -81,6 +95,7 @@
<string name="msg_stats_intro">Stats for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Member (Paid | Spent | Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Error</string> <string name="error_generic">Error</string>
<string name="error_loading">Loading</string> <string name="error_loading">Loading</string>
@@ -109,6 +124,7 @@
<string name="error_server">Server error</string> <string name="error_server">Server error</string>
<string name="error_io">Server connection broken</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Cannot share this project</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Connect to Nextcloud account</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
@@ -117,6 +133,7 @@
<string name="simple_yes">Yes</string> <string name="simple_yes">Yes</string>
<string name="simple_no">No</string> <string name="simple_no">No</string>
<string name="simple_close">Close</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Appearance</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Network</string> <string name="settings_network">Network</string>
@@ -129,15 +146,23 @@
<string name="settings_show_archived">Show archived projects</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WARNING: \"http\" is unsafe. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string> <string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string> <string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">No repeat</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Daily</string> <string name="repeat_day">Daily</string>
@@ -145,6 +170,7 @@
<string name="repeat_fortnight">Fortnightly</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Monthly</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Yearly</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">None</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_all">All</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_credit_card">Credit card</string> <string name="payment_mode_credit_card">Credit card</string>
@@ -152,6 +178,7 @@
<string name="payment_mode_check">Check</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">None</string> <string name="category_none">None</string>
<string name="category_all">All</string> <string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
@@ -167,17 +194,14 @@
<string name="category_accomodation">Accommodation</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">Where</string> <string name="new_project_where">Where</string>
<string name="where_local">Local only</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Join existing project</string> <string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string> <string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string> <string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string> <string name="no_projects_text">You have no projects yet.</string>
@@ -196,6 +220,7 @@
<string name="edit_member_dialog_title">Edit Member</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Delete</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">No changes to save.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">None (Optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Who pays</string> <string name="settle_who">Who pays</string>
@@ -204,12 +229,14 @@
<string name="simple_settle_share">Share</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Create bills</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Settlement</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Choose Currency (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">None</string> <string name="setting_none">None</string>
<string name="setting_all">All</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Currency settings saved.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Main Currency</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Suggested Categories</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Skip</string> <string name="label_bills_skip">Skip</string>
@@ -220,6 +247,7 @@
<string name="stats_spent">Spent</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Balance</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Connection failed: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
@@ -230,12 +258,15 @@
<string name="insufficient_access_level">You don\'t have permission to perform this action.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Delete Label</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Maintainer</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">License</string> <string name="about_license_title">License</string>
<string name="about_source_title">Source code</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Share %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+244 -213
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Gekocht</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Nieuwe rekening</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Project toevoegen</string> <string name="action_add_project">Add project</string>
<string name="action_save">Opslaan</string> <string name="action_save">Save</string>
<string name="action_edit">Bewerken</string> <string name="action_edit">Edit</string>
<string name="action_share">Delen</string> <string name="action_share">Share</string>
<string name="action_search">Zoeken</string> <string name="action_search">Search</string>
<string name="action_delete">Verwijderen</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Archief</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Dearchiveren</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Exporteren</string> <string name="action_delete">Delete</string>
<string name="action_stats">Statistieken</string> <string name="simple_back">Back</string>
<string name="action_settle">Schikken</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Instellingen</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Label ontbrekende categorieën</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Afmelden</string> <string name="action_logout">Logout</string>
<string name="action_connect">Verbinden</string> <string name="action_connect">Connect</string>
<string name="action_discard">Weggooien</string> <string name="action_discard">Discard</string>
<string name="action_members">leden</string> <string name="action_members">Members</string>
<string name="action_labels">Labels</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Valuta\'s</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistieken</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Bewerk project</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Label rekeningen</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Labels beheren</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">Informatie</string> <string name="title_about">About</string>
<string name="title_settle">Project schikken</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Project delen</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Project toevoegen</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Categorie toevoegen</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Betalingsmodus toevoegen</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Nextcloud account</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Weblink</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Weet je het zeker?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Alle rekeningen</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categoriechar@@0n</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Betalings modi</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">naam</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Kleur</string> <string name="label_color">Color</string>
<string name="label_weight">Gewicht</string> <string name="label_weight">Weight</string>
<string name="label_activated">Geactiveerd</string> <string name="label_activated">Activated</string>
<string name="label_password">Wachtwoord</string> <string name="label_password">Password</string>
<string name="label_email">E-mailadres</string> <string name="label_email">E-mail</string>
<string name="label_url">Server adres</string> <string name="label_url">Server address</string>
<string name="label_username">Gebruikersnaam</string> <string name="label_username">Username</string>
<string name="label_comment">Opmerking</string> <string name="label_comment">Comment</string>
<string name="label_what">Wat?</string> <string name="label_what">What?</string>
<string name="label_payer">Wie heeft betaald?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Voor wie?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Herhaal elke</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Modus</string> <string name="label_mode">Mode</string>
<string name="label_category">categorie</string> <string name="label_category">Category</string>
<string name="label_project_id">Project ID/naam</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project titel</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Gebruik Nextcloud account</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Niet-opgeslagen wijzigingen</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Wijzigingen opslaan voor verlaten?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Het externe project wordt niet verwijderd.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Synchronisatie fout</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Synchronisatie mislukt voor %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Uitgaven zijn al in evenwicht.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Project %1$s toegevoegd</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Alle contracten gelabeld</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Geen suggesties</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Vereist Cospend-v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Link gekopieerd naar klembord</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Scan QR-code of deel de link om je aan te sluiten.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Link voor toegang tot de webbrowser.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Deel deze link met een Cowspent gebruiker.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Afwikkeling voor %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s is %3$.2f verschuldigd aan %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Statistieken voor %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Lid ((Paid →Besteed Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Ingelogd als %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Foutmelding</string> <string name="error_generic">Error</string>
<string name="error_loading">Laden...</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Geen projecten gevonden</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Geen deelnemers gevonden</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Geen contracten gevonden</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Ten minste één lid vereist</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Server is in onderhoudsmodus</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 Slechte aanvraag</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Ongeautoriseerd</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Verboden</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 niet gevonden</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Synchronisatie mislukt: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Ongeldige login: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Verkeerde gebruikersnaam of wachtwoord</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Ongeldige serverreactie</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Verzoek mislukt</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Ongeldig e-mailadres</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Ongeldig project ID</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Ongeldige projecttitel</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Ongeldige rekeningnaam</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Ongeldige rekeningdatum</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Betaler vereist</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Owers vereist</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Geen netwerkverbinding</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Server fout</string> <string name="error_server">Server error</string>
<string name="error_io">Verbinding met server verbroken</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Kan dit project niet delen</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Verbinding maken met Nextcloud account</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Laatste synchronisatie: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">annuleren</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">OK</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">ja</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Neen</string> <string name="simple_no">No</string>
<string name="simple_close">Afsluiten</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Uiterlijk</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Netwerk</string> <string name="settings_network">Network</string>
<string name="settings_other">anders</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Thema</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Offline modus</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Alleen handmatig synchroniseren.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Aangepaste kleur</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Kleur Selectie</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Gearchiveerde projecten weergeven</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Functies</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Experimentele functies inschakelen. Gebruik op eigen risico.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WAARSCHUWING: \"http\" is onveilig. Gebruik \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Kies kleur</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">Systeem</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">Handleiding</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">Licht</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">Donker</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">Volg systeem</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Geen herhaling</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Dagelijks</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">wekelijks</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Tweewekelijks</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">maandelijks</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Jaarlijks</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">geen</string>
<string name="payment_mode_all">Allemaal</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Creditcard bestellen</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Contant</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Controleer</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Overschrijving</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">geen</string>
<string name="category_all">Allemaal</string> <string name="category_none">None</string>
<string name="category_all_except_reimbursement">Alles behalve terugbetaling</string> <string name="category_all">All</string>
<string name="category_groceries">Kruidenier</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_leisure">Bar/Feest</string> <string name="category_groceries">Grocery</string>
<string name="category_rent">Huur</string> <string name="category_leisure">Bar/Party</string>
<string name="category_bills">Rekening</string> <string name="category_rent">Rent</string>
<string name="category_excursion">Excursie/cultuur</string> <string name="category_bills">Bill</string>
<string name="category_health">Gezondheid</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_shopping">Winkelen</string> <string name="category_health">Health</string>
<string name="category_reimbursement">Vergoeding</string> <string name="category_shopping">Shopping</string>
<string name="category_reimbursement">Reimbursement</string>
<string name="category_restaurant">Restaurant</string> <string name="category_restaurant">Restaurant</string>
<string name="category_accomodation">Accommodatie</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Vervoer</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Wat</string> <string name="new_project_action">What</string>
<string name="new_project_where">Waar</string> <string name="new_project_where">Where</string>
<string name="where_local">Alleen lokaal</string> <string name="where_local">Local only</string>
<string name="where_cospend">Coderen</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Deelnemen aan bestaand project</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Nieuw project aanmaken</string>
<string name="import_tooltip">Importeren uit bestand</string>
<string name="choose_account_project_dialog_title">Kies project</string>
<string name="choose_account_project_dialog_impossible">Geen projecten gevonden op dit account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project succesvol toegevoegd.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">U heeft nog geen projecten.</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="configure_account_choice">Configureer Nextcloud account</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="add_project_choice">Project handmatig toevoegen</string> <string name="add_project_choice">Add project manually</string>
<string name="no_members_text">Geen deelnemers in dit project.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_bills_text">Geen contracten gevonden.</string> <string name="no_bills_text">No bills found.</string>
<string name="member_already_exists">Lid bestaat al.</string> <string name="member_already_exists">Member already exists.</string>
<string name="activity_dialog_title">Project: %1$s</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="remove_project_confirmation">Project %1$s verwijderd.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="file_saved_success">Bestand opgeslagen: %1$s</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="import_error_header">Importeren mislukt op rij %d</string> <string name="import_error_header">Import failed at row %d</string>
<string name="import_error_date">Ongeldige datumnotatie op rij %d</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="import_error_owers">Ongeldige owers op rij %d</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="add_member_dialog_title">Lid toevoegen</string> <string name="add_member_dialog_title">Add Member</string>
<string name="edit_member_dialog_title">Lid bewerken</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Verwijderen</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">Geen wijzigingen om op te slaan.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Geen (Optimaal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Wie betaalt</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">Naar wie</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Hoeveelheid</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Delen</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Rekeningen aanmaken</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Afwikkeling</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Kies valuta (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">geen</string> <string name="setting_none">None</string>
<string name="setting_all">Allemaal</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Valuta-instellingen opgeslagen.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Belangrijkste valuta</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Voorgestelde categorieën</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Overslaan</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">van</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">tot</string> <string name="stats_date_max">To</string>
<string name="stats_who">Lid</string> <string name="stats_who">Member</string>
<string name="stats_paid">Betaald</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Uitgegeven</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Saldo</string> <string name="stats_balance">Balance</string>
<string name="total">Totaal: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Verbinding mislukt: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Aanmaken mislukt: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Fout bij het bijwerken van extern project: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Netwerk niet beschikbaar voor operatie op afstand.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Fout bij het verwerken van QR-code.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Authenticatie token komt niet overeen. Log opnieuw in.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Je hebt geen toestemming om deze actie uit te voeren.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Label verwijderen</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Weet u zeker dat u dit label wilt verwijderen?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Versie %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Beheerder</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Licentie</string> <string name="about_license_title">License</string>
<string name="about_source_title">Bron code</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Delen %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+246 -215
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Kowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Ny regning</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Legg til prosjekt</string> <string name="action_add_project">Add project</string>
<string name="action_save">Lagre</string> <string name="action_save">Save</string>
<string name="action_edit">Rediger</string> <string name="action_edit">Edit</string>
<string name="action_share">Del</string> <string name="action_share">Share</string>
<string name="action_search">Søk</string> <string name="action_search">Search</string>
<string name="action_delete">Slett</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Arkiv</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Avarkiver</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Eksporter</string> <string name="action_delete">Delete</string>
<string name="action_stats">Statistikk</string> <string name="simple_back">Back</string>
<string name="action_settle">Betal</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Innstillinger</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Etiketten mangler kategorier</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Logg</string> <string name="action_logout">Logout</string>
<string name="action_connect">Nettverk</string> <string name="action_connect">Connect</string>
<string name="action_discard">Forkast</string> <string name="action_discard">Discard</string>
<string name="action_members">Medlemmer</string> <string name="action_members">Members</string>
<string name="action_labels">Etiketter</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Valutaer</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistikk</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Endre prosjekt</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Etikett regninger</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Administrer etiketter</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">Om</string> <string name="title_about">About</string>
<string name="title_settle">Oppgjør Prosjekt</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Del prosjeket</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Legg til prosjekt</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Legg til kategori</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Legg til betalingsmodus</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Nextcloud konto</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Nettlenke</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Er du sikker?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Alle regninger</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Kategorier</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Betalings modus</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Navn</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Farge</string> <string name="label_color">Color</string>
<string name="label_weight">Vekt</string> <string name="label_weight">Weight</string>
<string name="label_activated">Aktivert</string> <string name="label_activated">Activated</string>
<string name="label_password">Passord</string> <string name="label_password">Password</string>
<string name="label_email">E-post</string> <string name="label_email">E-mail</string>
<string name="label_url">Server adresse</string> <string name="label_url">Server address</string>
<string name="label_username">Brukernavn</string> <string name="label_username">Username</string>
<string name="label_comment">Kommentar</string> <string name="label_comment">Comment</string>
<string name="label_what">Hva?</string> <string name="label_what">What?</string>
<string name="label_payer">Hvem betalt?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">For hvem?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Gjenta hver</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Modus</string> <string name="label_mode">Mode</string>
<string name="label_category">Kategori</string> <string name="label_category">Category</string>
<string name="label_project_id">Prosjektets ID/navn</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Tittel på prosjektet</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Bruk Nextcloud App-konto</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Ulagrede endringer</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Lagre endringer før du drar?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Det eksterne prosjektet vil ikke bli slettet.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Feil med synkronisering</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Synkronisering feilet for %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Utgifter er allerede balanserte.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Prosjekt %1$s lagt til</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Alle regninger merket</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Ingen forslag</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Krever Cospend v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Kobling kopiert til utklippstavlen</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Skann QR-kode eller del lenken for å bli med.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Lenke for tilgang til nettleser.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Del denne lenken med en bruker i nærområdet.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Avgjøring for %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Statistikk for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Medlem (hjelpemiddel for sprøytestatistikk Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logget inn som %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Feil</string> <string name="error_generic">Error</string>
<string name="error_loading">Laster</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Ingen prosjekter funnet</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Ingen medlemmer funnet</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Ingen regninger funnet</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Minst ett medlem som kreves</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Serveren er i vedlikeholdsmodus</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 ugyldig forespørsel</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Uautorisert</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 forbudt</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 ikke funnet</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Synkronisering feilet: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Ugyldig innlogging: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Feil brukernavn eller passord</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Ugyldig svar fra tjeneren</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Forespørselen mislyktes</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Ugyldig e-post</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Ugyldig prosjekt-ID</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Ugyldig prosjekttittel</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Ugyldig faktureringsnavn</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Ugyldig faktureringsdato</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Betalingsgiver kreves</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Eier kreves</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Ingen nettverkstilkobling</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Server feil</string> <string name="error_server">Server error</string>
<string name="error_io">Server-tilkobling ødelagt</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Kan ikke dele dette prosjektet</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Koble til Nextcloud konto</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Siste synkronisering: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Avbryt</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">OK</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Ja</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Nei</string> <string name="simple_no">No</string>
<string name="simple_close">Lukk</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Utseende</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Nettverk</string> <string name="settings_network">Network</string>
<string name="settings_other">Annet</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Tema</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Frakoblet modus</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Bare synkroniser manuelt.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Tilpasset farge</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Farge Valg</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Vis arkiverte prosjekter</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta-funksjoner</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Aktiver eksperimentelle funksjoner. Bruk på eget ansvar.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">ADVARSEL: «http» er usikkert. Bruk «https».</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Velg farge</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">Systemadministrasjon</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">Manuell</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">Lys</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">Mørk</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">Følg system</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Ingen gjentakelse</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Daglig</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Ukentlig</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Nattlig</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Månedlig</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Årlig</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Ingen</string>
<string name="payment_mode_all">Alle</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Kredittkort</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Kontant</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Sjekk</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">Pålogget</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">Overfør</string> <string name="payment_mode_online">Online</string>
<string name="category_none">Ingen</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">Alle</string>
<string name="category_all_except_reimbursement">Alt unntatt refusjon</string> <string name="category_none">None</string>
<string name="category_groceries">Dagligvare</string> <string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_groceries">Grocery</string>
<string name="category_leisure">Bar/Party</string> <string name="category_leisure">Bar/Party</string>
<string name="category_rent">Lei</string> <string name="category_rent">Rent</string>
<string name="category_bills">Regning</string> <string name="category_bills">Bill</string>
<string name="category_excursion">Eksurering/Kultur</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_health">Helse</string> <string name="category_health">Health</string>
<string name="category_shopping">Handling</string> <string name="category_shopping">Shopping</string>
<string name="category_reimbursement">Refusjon</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_restaurant">Resturant</string> <string name="category_restaurant">Restaurant</string>
<string name="category_accomodation">Overnatting</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transporter</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Hva</string> <string name="new_project_action">What</string>
<string name="new_project_where">Hvor</string> <string name="new_project_where">Where</string>
<string name="where_local">Kun lokalt</string> <string name="where_local">Local only</string>
<string name="where_cospend">evangeliet</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHatePenger</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Delta i eksisterende prosjekt</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Opprett nytt prosjekt</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Importer fra fil</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Velg prosjekt</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Ingen prosjekter ble funnet på denne kontoen.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Prosjekt</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Prosjektet ble lagt til.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Du har ingen prosjekter ennå.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Konfigurer Nextcloud konto</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Legg til prosjekt manuelt</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Ingen medlemmer i dette prosjektet.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Ingen regninger funnet.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Medlem finnes allerede.</string>
<string name="activity_dialog_title">Prosjekt: %1$s</string>
<string name="remove_project_confirmation">Prosjektet %1$s fjernet.</string>
<string name="file_saved_success">Fil lagret: %1$s</string>
<string name="import_error_header">Import failed at row %d</string> <string name="import_error_header">Import failed at row %d</string>
<string name="import_error_date">Ugyldig dato format ved rad %d</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="import_error_owers">Ugyldige doser på rad %d</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="add_member_dialog_title">Legg til medlem</string> <string name="add_member_dialog_title">Add Member</string>
<string name="edit_member_dialog_title">Rediger medlem</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Slett</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">Ingen endringer å lagre.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Ingen (optimalt)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Hvem betaler</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">Til hvem</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Beløp</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Del</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Opprett regninger</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Oppgjør</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Velg valuta (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Ingen</string> <string name="setting_none">None</string>
<string name="setting_all">Alle</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Valuta innstillinger lagret.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Hoved valuta</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Foreslåtte kategorier</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Hopp</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">Fra</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">Til</string> <string name="stats_date_max">To</string>
<string name="stats_who">Medlem</string> <string name="stats_who">Member</string>
<string name="stats_paid">Betalt</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Brukt</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Balanse</string> <string name="stats_balance">Balance</string>
<string name="total">Totalt: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Tilkobling mislyktes: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Feil ved oppdatering av fjernprosjektet: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Nettverk er ikke tilgjengelig for ekstern operasjon.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Kunne ikke analysere QR-kode.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Feil ved godkjenningstoken. Vennligst logg inn på nytt.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Du har ikke tillatelse til å gjøre denne handlingen.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Slett etikett</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Er du sikker på at du vil slette dette merket?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Versjon %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Vedlikeholdere</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Lisens</string> <string name="about_license_title">License</string>
<string name="about_source_title">Kildekode</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Prosjekt %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Del %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+246 -215
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Krowy wydane</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Nowy rachunek</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Dodaj projekt</string> <string name="action_add_project">Add project</string>
<string name="action_save">Zapisz</string> <string name="action_save">Save</string>
<string name="action_edit">Edytuj</string> <string name="action_edit">Edit</string>
<string name="action_share">Udostępnij</string> <string name="action_share">Share</string>
<string name="action_search">Szukaj</string> <string name="action_search">Search</string>
<string name="action_delete">Usuń</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Archiwum</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Usuń z archiwum</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Eksportuj</string> <string name="action_delete">Delete</string>
<string name="action_stats">Statystyki</string> <string name="simple_back">Back</string>
<string name="action_settle">Utrata</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Ustawienia</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Brakujące kategorie etykiet</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Wyloguj się</string> <string name="action_logout">Logout</string>
<string name="action_connect">Połącz</string> <string name="action_connect">Connect</string>
<string name="action_discard">Odrzuć</string> <string name="action_discard">Discard</string>
<string name="action_members">Członkowie</string> <string name="action_members">Members</string>
<string name="action_labels">Etykiety</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Waluty</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statystyki</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Edytuj projekt</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Etykiety rachunków</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Zarządzaj etykietami</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">O programie</string> <string name="title_about">About</string>
<string name="title_settle">Ustawiony projekt</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Udostępnij projekt</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Dodaj projekt</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Dodaj kategor</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Dodaj tryb płatności</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Konto Nextcloud</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Link internetowy</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Jesteś pewien?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Wszystkie rachunki</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Kategorie</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Tryby płatności</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Nazwisko</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Kolor</string> <string name="label_color">Color</string>
<string name="label_weight">Waga</string> <string name="label_weight">Weight</string>
<string name="label_activated">Aktywowano</string> <string name="label_activated">Activated</string>
<string name="label_password">Hasło</string> <string name="label_password">Password</string>
<string name="label_email">E-mail</string> <string name="label_email">E-mail</string>
<string name="label_url">Adres serwera</string> <string name="label_url">Server address</string>
<string name="label_username">Nazwa użytkownika</string> <string name="label_username">Username</string>
<string name="label_comment">Komentarz</string> <string name="label_comment">Comment</string>
<string name="label_what">Co?</string> <string name="label_what">What?</string>
<string name="label_payer">Kto zapłacił?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Dla kogo?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Powtarzaj co</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Tryb</string> <string name="label_mode">Mode</string>
<string name="label_category">Kategoria</string> <string name="label_category">Category</string>
<string name="label_project_id">Identyfikator/nazwa projektu</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Tytuł projektu</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Użyj konta aplikacji Nextcloud</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Niezapisane zmiany</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Zapisać zmiany przed wyjściem?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Zdalny projekt nie zostanie usunięty.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Błąd synchronizacji</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Synchronizacja %1$snie powiodła się.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Wydatki są już zrównoważone.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Projekt %1$s dodany</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Wszystkie rachunki oznaczone</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Brak sugestii</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Wymaga Dołączyć v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Link skopiowany do schowka</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Zeskanuj kod QR lub udostępnij link, aby dołączyć.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Link dostępu do przeglądarki internetowej.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Udostępnij ten link użytkownikowi Cowspent</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Rozliczenie dla %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s jest winny %3$.2f do %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Statystyki dla %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Członek (Pomoc | Wydano | Saldo)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Zalogowano jako %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Błąd</string> <string name="error_generic">Error</string>
<string name="error_loading">Ładowanie</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Nie znaleziono projektów</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Nie znaleziono członków</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Nie znaleziono rachunków</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Wymagany co najmniej jeden członek</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Serwer jest w trybie konserwacji</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 błędnych żądań</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Nieautoryzowany</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Zabronione</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Nie znaleziono</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Synchronizacja nie powiodła się: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Nieprawidłowy login: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Nieprawidłowa nazwa użytkownika lub hasło</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Nieprawidłowa odpowiedź serwera</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Żądanie nie powiodło się</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Nieprawidłowy adres e-mail</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Nieprawidłowy identyfikator projektu</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Nieprawidłowy tytuł projektu</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Nieprawidłowa nazwa rachunku</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Nieprawidłowa data rozliczenia</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Wymagany płatnik</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Wymagane jest posiadanie</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Brak połączenia sieciowego</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Błąd serwera</string> <string name="error_server">Server error</string>
<string name="error_io">Połączenie z serwerem przerwane</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Nie można udostępnić tego projektu</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Połącz z kontem Nextcloud</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Ostatnia synchronizacja: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Anuluj</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Tak</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Nie</string> <string name="simple_no">No</string>
<string name="simple_close">Zamknij</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Wygląd</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Sieć</string> <string name="settings_network">Network</string>
<string name="settings_other">Inne</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Motyw</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Tryb offline</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Synchronizuj tylko ręcznie.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Własny kolor</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Wybór koloru</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Pokaż zarchiwizowane projekty</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Funkcje Beta</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Włącz funkcje eksperymentalne. Używaj na własne ryzyko.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">OSTRZEŻENIE: \"http\" jest niebezpieczny. Użyj \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Wybierz kolor</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_color_manual">Ręcznie</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_light">Światło</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_dark">Ciemny</string> <string name="pref_value_theme_system">Follow system</string>
<string name="pref_value_theme_system">Śledź system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Brak powtórzeń</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Codziennie</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Tygodniowo</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Co dwa tygodnie</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Miesięczny</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Rocznie</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Brak</string>
<string name="payment_mode_all">Wszystkie</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Karta kredytowa</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Gotówka</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Sprawdzanie</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">Dostępny</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">Przelew</string> <string name="payment_mode_online">Online</string>
<string name="category_none">Brak</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">Wszystkie</string>
<string name="category_all_except_reimbursement">Wszystkie z wyjątkiem zwrotu</string> <string name="category_none">None</string>
<string name="category_groceries">Żywność</string> <string name="category_all">All</string>
<string name="category_leisure">Pasek/Impreza</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_rent">Wynajem</string> <string name="category_groceries">Grocery</string>
<string name="category_bills">Rachunek</string> <string name="category_leisure">Bar/Party</string>
<string name="category_excursion">Eksploatacja/kultura</string> <string name="category_rent">Rent</string>
<string name="category_health">Zdrowie</string> <string name="category_bills">Bill</string>
<string name="category_shopping">Zakupy</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_reimbursement">Zwrot kosztów</string> <string name="category_health">Health</string>
<string name="category_restaurant">Restauracja</string> <string name="category_shopping">Shopping</string>
<string name="category_accomodation">Zakwaterowanie</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_restaurant">Restaurant</string>
<string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Co</string> <string name="new_project_action">What</string>
<string name="new_project_where">Gdzie</string> <string name="new_project_where">Where</string>
<string name="where_local">Tylko lokalne</string> <string name="where_local">Local only</string>
<string name="where_cospend">Dołącz</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Dołącz do istniejącego projektu</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Utwórz nowy projekt</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Importuj z pliku</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Wybierz projekt</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Nie znaleziono projektów na tym koncie.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Projekt</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Projekt dodany pomyślnie.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Nie masz jeszcze żadnych projektów.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Konfiguruj konto Nextcloud</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Dodaj projekt ręcznie</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Brak członków w tym projekcie.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Nie znaleziono rachunków.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Użytkownik już istnieje.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">Projekt: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">Projekt %1$s usunięty.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">Plik zapisany: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">Importowanie nie powiodło się w wierszu %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">Nieprawidłowy format daty w wierszu %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">Niepoprawne owce w wierszu %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">Dodaj członka</string>
<string name="edit_member_dialog_title">Edytuj członka</string>
<string name="member_edit_delete">Usuń</string>
<string name="project_edition_no_change">Brak zmian do zapisu.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Brak (Optymalny)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Kto płaci</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">Do kogo</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Kwota</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Udostępnij</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Utwórz rachunki</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Rozliczenie</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Wybierz walutę (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Brak</string> <string name="setting_none">None</string>
<string name="setting_all">Wszystkie</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Zapisano ustawienia waluty.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Waluta główna</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Sugerowane kategorie</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Pomiń</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">Od</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">Do</string> <string name="stats_date_max">To</string>
<string name="stats_who">Członek</string> <string name="stats_who">Member</string>
<string name="stats_paid">Zapłacone</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Wydano</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Saldo</string> <string name="stats_balance">Balance</string>
<string name="total">Razem: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Połączenie nie powiodło się: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Utworzenie nie powiodło się: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Błąd podczas aktualizacji zdalnego projektu: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Sieć niedostępna dla zdalnej operacji.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Nie udało się przetworzyć kodu QR.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Nieprawidłowy token uwierzytelniania. Zaloguj się ponownie.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Nie masz uprawnień do wykonania tej czynności.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Usuń etykietę</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Czy na pewno chcesz usunąć tę etykietę?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Wersja %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Opiekun</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Licencja</string> <string name="about_license_title">License</string>
<string name="about_source_title">Kod źródłowy</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Projekt %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Udostępnij %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+250 -219
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Covarde</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Nova fatura</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Adicionar projeto</string> <string name="action_add_project">Add project</string>
<string name="action_save">Guardar</string> <string name="action_save">Save</string>
<string name="action_edit">Alterar</string> <string name="action_edit">Edit</string>
<string name="action_share">Compartilhar</string> <string name="action_share">Share</string>
<string name="action_search">Pesquisa</string> <string name="action_search">Search</string>
<string name="action_delete">excluir</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Arquivo</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Desarquivar</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Exportação</string> <string name="action_delete">Delete</string>
<string name="action_stats">Estatísticas</string> <string name="simple_back">Back</string>
<string name="action_settle">Liquidar</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Confirgurações</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Categorias faltando</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Desconectar</string> <string name="action_logout">Logout</string>
<string name="action_connect">Conectar</string> <string name="action_connect">Connect</string>
<string name="action_discard">Descartar</string> <string name="action_discard">Discard</string>
<string name="action_members">membros</string> <string name="action_members">Members</string>
<string name="action_labels">Marcadores</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Moedas</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">estatísticas</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Editar projeto</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Rótulo de Faturas</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Gerenciar Marcadores</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">SOBRE</string> <string name="title_about">About</string>
<string name="title_settle">Resolver o Projeto</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Compartilhar Projeto</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Adicionar Projeto</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Adicionar Categoria</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Adicionar modo de pagamento</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Conta Nextcloud</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Link da Web</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Você tem certeza?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Todas as contas</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">categorias</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Modos de Pagamento</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Nome:</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Cor</string> <string name="label_color">Color</string>
<string name="label_weight">Peso</string> <string name="label_weight">Weight</string>
<string name="label_activated">Ativado</string> <string name="label_activated">Activated</string>
<string name="label_password">Palavra-passe</string> <string name="label_password">Password</string>
<string name="label_email">e-mail</string> <string name="label_email">E-mail</string>
<string name="label_url">Endereço do servidor</string> <string name="label_url">Server address</string>
<string name="label_username">Usuário:</string> <string name="label_username">Username</string>
<string name="label_comment">Comentar</string> <string name="label_comment">Comment</string>
<string name="label_what">Quê?</string> <string name="label_what">What?</string>
<string name="label_payer">Quem pagou?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Para quem?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Repita a cada</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Modo</string> <string name="label_mode">Mode</string>
<string name="label_category">categoria</string> <string name="label_category">Category</string>
<string name="label_project_id">ID/nome do projeto</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Título do projeto</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Usar Conta do App Nextcloud</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Alterações não salvas</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Salvar as alterações antes de sair?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">O projeto remoto não será excluído.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Erro de sincronização</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">A sincronização falhou para %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">As despesas já estão equilibradas.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Projeto %1$s adicionado</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Todas as faturas rotuladas</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Não sugestões</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Requer Cospend v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Link copiado para área de transferência</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Escaneie o código QR ou compartilhe o link para entrar.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Link para acesso ao navegador web.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Compartilhe este link com um usuário CowGed.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Assentamento para %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s deve %3$.2f a %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Estatísticas para %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Membro (Ajuda-Gasto Balanço)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Sessão iniciada como %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">ERRO</string> <string name="error_generic">Error</string>
<string name="error_loading">Carregando...</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Nenhum projeto encontrado</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Nenhum membro encontrado</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Nenhuma conta encontrada</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Pelo menos um membro é obrigatório</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">O servidor está em modo de manutenção</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">Solicitação inválida</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Não Autorizado</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Proibido</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Não Encontrado</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Falha de sincronização: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Login inválido: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Nome de usuário ou senha incorretos</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Resposta do servidor inválida</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Falha na solicitação</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">E-mail inválido</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">ID do projeto inválido</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Título do projeto inválido</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Nome de conta inválido</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Data de fatura inválida</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Pagador necessário</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Proprietários obrigatórios</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Nenhuma conexão de rede</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Erro no servidor</string> <string name="error_server">Server error</string>
<string name="error_io">Conexão com o servidor interrompida</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Não é possível compartilhar este projeto</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Conectar à conta da Nextcloud</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Última sincronização: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">cancelar</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">OK</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">sim</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Não</string> <string name="simple_no">No</string>
<string name="simple_close">FECHAR</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Aparência</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Rede</string> <string name="settings_network">Network</string>
<string name="settings_other">Outros</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Tema</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Modo offline</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Sincronizar apenas manualmente.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Cor personalizada</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Seleção de Cor</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Mostrar projetos arquivados</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Recursos Beta</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Habilite recursos experimentais. Use a seu próprio risco.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">AVISO: \"http\" não é seguro. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Escolha a cor</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">SISTEMA</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">Manualmente</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">Fino</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">Escuro</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">Seguir sistema</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Não repetir</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Diariamente</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Semanalmente</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Quinzenal</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Mensual</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Anualmente</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Nenhuma</string>
<string name="payment_mode_all">TODOS</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Cartão de crédito</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Dinheiro</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Verificar</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">Disponível</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">Transferência</string> <string name="payment_mode_online">Online</string>
<string name="category_none">Nenhuma</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">TODOS</string>
<string name="category_all_except_reimbursement">Todos, exceto o reembolso</string> <string name="category_none">None</string>
<string name="category_groceries">Mercearia</string> <string name="category_all">All</string>
<string name="category_leisure">Barra/Party</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_rent">Aluguel</string> <string name="category_groceries">Grocery</string>
<string name="category_bills">Faturar</string> <string name="category_leisure">Bar/Party</string>
<string name="category_excursion">Excursão/Cultura</string> <string name="category_rent">Rent</string>
<string name="category_health">Vida</string> <string name="category_bills">Bill</string>
<string name="category_shopping">Compras</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_reimbursement">Reembolso</string> <string name="category_health">Health</string>
<string name="category_restaurant">Restaurante</string> <string name="category_shopping">Shopping</string>
<string name="category_accomodation">Acomodação</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_transport">Transporte</string> <string name="category_restaurant">Restaurant</string>
<string name="category_sport">Esporte</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string>
<string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">O</string> <string name="new_project_action">What</string>
<string name="new_project_where">Onde</string> <string name="new_project_where">Where</string>
<string name="where_local">Apenas local</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cosdar</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">Dinheiro</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Junte-se ao projeto existente</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Criar novo projeto</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Importar do arquivo</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Escolher projeto</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Nenhum projeto encontrado nesta conta.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Projecto</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Projeto adicionado com sucesso.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Você ainda não tem nenhum projeto.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Configurar conta Nextcloud</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Adicionar projeto manualmente</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Nenhum membro neste projeto.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Nenhuma conta encontrada.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Membro já existe.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">Projeto: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">Projeto %1$s removido.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">Arquivo salvo: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">Importação falhou na linha %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">Formato de data inválido na linha %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">Linhas inválidas na linha %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">Adicionar Membro</string>
<string name="edit_member_dialog_title">Editar Membro</string>
<string name="member_edit_delete">excluir</string>
<string name="project_edition_no_change">Sem alterações para salvar.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Nenhum (Profissional)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Quem paga</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">A quem</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Quantidade</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Compartilhar</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Criar faturas</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Liquidação</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Escolher Moeda (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Nenhuma</string> <string name="setting_none">None</string>
<string name="setting_all">TODOS</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Configurações de moeda salvas.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Moeda Principal</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Categorias Sugeridas</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Ignorar</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">De</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">Para</string> <string name="stats_date_max">To</string>
<string name="stats_who">Membro</string> <string name="stats_who">Member</string>
<string name="stats_paid">Paga</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Gasto</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Saldo</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">A conexão falhou: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Falha na criação: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Erro ao atualizar projeto remoto: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Rede indisponível para operação remota.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Falha ao analisar o código QR.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Token de autenticação incompatível. Por favor, faça login novamente.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Você não tem permissão para executar esta ação</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Excluir etiqueta</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Você tem certeza que deseja excluir este marcador?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Versão %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Mantenedor</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Tipo:</string> <string name="about_license_title">License</string>
<string name="about_source_title">Código fonte</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Projeto %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Compartilhar %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+250 -219
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Covarde</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Nova fatura</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Adicionar projeto</string> <string name="action_add_project">Add project</string>
<string name="action_save">Guardar</string> <string name="action_save">Save</string>
<string name="action_edit">Alterar</string> <string name="action_edit">Edit</string>
<string name="action_share">Compartilhar</string> <string name="action_share">Share</string>
<string name="action_search">Pesquisa</string> <string name="action_search">Search</string>
<string name="action_delete">excluir</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Arquivo</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Desarquivar</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Exportação</string> <string name="action_delete">Delete</string>
<string name="action_stats">Estatísticas</string> <string name="simple_back">Back</string>
<string name="action_settle">Liquidar</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Confirgurações</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Categorias faltando</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Desconectar</string> <string name="action_logout">Logout</string>
<string name="action_connect">Conectar</string> <string name="action_connect">Connect</string>
<string name="action_discard">Descartar</string> <string name="action_discard">Discard</string>
<string name="action_members">membros</string> <string name="action_members">Members</string>
<string name="action_labels">Marcadores</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Moedas</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">estatísticas</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Editar projeto</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Rótulo de Faturas</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Gerenciar Marcadores</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">SOBRE</string> <string name="title_about">About</string>
<string name="title_settle">Resolver o Projeto</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Compartilhar Projeto</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Adicionar Projeto</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Adicionar Categoria</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Adicionar modo de pagamento</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Conta Nextcloud</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Link da Web</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Você tem certeza?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Todas as contas</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">categorias</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Modos de Pagamento</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Nome:</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Cor</string> <string name="label_color">Color</string>
<string name="label_weight">Peso</string> <string name="label_weight">Weight</string>
<string name="label_activated">Ativado</string> <string name="label_activated">Activated</string>
<string name="label_password">Palavra-passe</string> <string name="label_password">Password</string>
<string name="label_email">e-mail</string> <string name="label_email">E-mail</string>
<string name="label_url">Endereço do servidor</string> <string name="label_url">Server address</string>
<string name="label_username">Usuário:</string> <string name="label_username">Username</string>
<string name="label_comment">Comentar</string> <string name="label_comment">Comment</string>
<string name="label_what">Quê?</string> <string name="label_what">What?</string>
<string name="label_payer">Quem pagou?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Para quem?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Repita a cada</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Modo</string> <string name="label_mode">Mode</string>
<string name="label_category">categoria</string> <string name="label_category">Category</string>
<string name="label_project_id">ID/nome do projeto</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Título do projeto</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Usar Conta do App Nextcloud</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Alterações não salvas</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Salvar as alterações antes de sair?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">O projeto remoto não será excluído.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Erro de sincronização</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">A sincronização falhou para %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">As despesas já estão equilibradas.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Projeto %1$s adicionado</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Todas as faturas rotuladas</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Não sugestões</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Requer Cospend v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Link copiado para área de transferência</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Escaneie o código QR ou compartilhe o link para entrar.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Link para acesso ao navegador web.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Compartilhe este link com um usuário CowGed.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Assentamento para %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s deve %3$.2f a %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Estatísticas para %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Membro (Ajuda-Gasto Balanço)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Sessão iniciada como %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">ERRO</string> <string name="error_generic">Error</string>
<string name="error_loading">Carregando...</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Nenhum projeto encontrado</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Nenhum membro encontrado</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Nenhuma conta encontrada</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Pelo menos um membro é obrigatório</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">O servidor está em modo de manutenção</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">Solicitação inválida</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Não Autorizado</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Proibido</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Não Encontrado</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Falha de sincronização: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Login inválido: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Nome de usuário ou senha incorretos</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Resposta do servidor inválida</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Falha na solicitação</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">E-mail inválido</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">ID do projeto inválido</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Título do projeto inválido</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Nome de conta inválido</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Data de fatura inválida</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Pagador necessário</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Proprietários obrigatórios</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Nenhuma conexão de rede</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Erro no servidor</string> <string name="error_server">Server error</string>
<string name="error_io">Conexão com o servidor interrompida</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Não é possível compartilhar este projeto</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Conectar à conta da Nextcloud</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Última sincronização: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">cancelar</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">OK</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">sim</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Não</string> <string name="simple_no">No</string>
<string name="simple_close">FECHAR</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Aparência</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Rede</string> <string name="settings_network">Network</string>
<string name="settings_other">Outros</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Tema</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Modo offline</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Sincronizar apenas manualmente.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Cor personalizada</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Seleção de Cor</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Mostrar projetos arquivados</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Recursos Beta</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Habilite recursos experimentais. Use a seu próprio risco.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">AVISO: \"http\" não é seguro. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Escolha a cor</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">SISTEMA</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">Manualmente</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">Fino</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">Escuro</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">Seguir sistema</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Não repetir</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Diariamente</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Semanalmente</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Quinzenal</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Mensual</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Anualmente</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Nenhuma</string>
<string name="payment_mode_all">TODOS</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Cartão de crédito</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Dinheiro</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Verificar</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">Disponível</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">Transferência</string> <string name="payment_mode_online">Online</string>
<string name="category_none">Nenhuma</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">TODOS</string>
<string name="category_all_except_reimbursement">Todos, exceto o reembolso</string> <string name="category_none">None</string>
<string name="category_groceries">Mercearia</string> <string name="category_all">All</string>
<string name="category_leisure">Barra/Party</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_rent">Aluguel</string> <string name="category_groceries">Grocery</string>
<string name="category_bills">Faturar</string> <string name="category_leisure">Bar/Party</string>
<string name="category_excursion">Excursão/Cultura</string> <string name="category_rent">Rent</string>
<string name="category_health">Vida</string> <string name="category_bills">Bill</string>
<string name="category_shopping">Compras</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_reimbursement">Reembolso</string> <string name="category_health">Health</string>
<string name="category_restaurant">Restaurante</string> <string name="category_shopping">Shopping</string>
<string name="category_accomodation">Acomodação</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_transport">Transporte</string> <string name="category_restaurant">Restaurant</string>
<string name="category_sport">Esporte</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string>
<string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">O</string> <string name="new_project_action">What</string>
<string name="new_project_where">Onde</string> <string name="new_project_where">Where</string>
<string name="where_local">Apenas local</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cosdar</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">Dinheiro</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Junte-se ao projeto existente</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Criar novo projeto</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Importar do arquivo</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Escolher projeto</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Nenhum projeto encontrado nesta conta.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Projecto</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Projeto adicionado com sucesso.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Você ainda não tem nenhum projeto.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Configurar conta Nextcloud</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Adicionar projeto manualmente</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Nenhum membro neste projeto.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Nenhuma conta encontrada.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Membro já existe.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">Projeto: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">Projeto %1$s removido.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">Arquivo salvo: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">Importação falhou na linha %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">Formato de data inválido na linha %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">Linhas inválidas na linha %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">Adicionar Membro</string>
<string name="edit_member_dialog_title">Editar Membro</string>
<string name="member_edit_delete">excluir</string>
<string name="project_edition_no_change">Sem alterações para salvar.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Nenhum (Profissional)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Quem paga</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">A quem</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Quantidade</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Compartilhar</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Criar faturas</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Liquidação</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Escolher Moeda (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Nenhuma</string> <string name="setting_none">None</string>
<string name="setting_all">TODOS</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Configurações de moeda salvas.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Moeda Principal</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Categorias Sugeridas</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Ignorar</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">De</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">Para</string> <string name="stats_date_max">To</string>
<string name="stats_who">Membro</string> <string name="stats_who">Member</string>
<string name="stats_paid">Paga</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Gasto</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Saldo</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">A conexão falhou: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Falha na criação: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Erro ao atualizar projeto remoto: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Rede indisponível para operação remota.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Falha ao analisar o código QR.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Token de autenticação incompatível. Por favor, faça login novamente.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Você não tem permissão para executar esta ação</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Excluir etiqueta</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Você tem certeza que deseja excluir este marcador?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Versão %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Mantenedor</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Tipo:</string> <string name="about_license_title">License</string>
<string name="about_source_title">Código fonte</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Projeto %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Compartilhar %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+242 -211
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Coafă</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Factură nouă</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Adaugă proiect</string> <string name="action_add_project">Add project</string>
<string name="action_save">Salvează</string> <string name="action_save">Save</string>
<string name="action_edit">Editare</string> <string name="action_edit">Edit</string>
<string name="action_share">Distribuie</string> <string name="action_share">Share</string>
<string name="action_search">Caută</string> <string name="action_search">Search</string>
<string name="action_delete">Ștergere</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Arhivează</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Dezarhivare</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Exportă</string> <string name="action_delete">Delete</string>
<string name="action_stats">Statistici</string> <string name="simple_back">Back</string>
<string name="action_settle">Setare</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Setări</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Categorii lipsă etichetă</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Deconectare</string> <string name="action_logout">Logout</string>
<string name="action_connect">Conectează-te</string> <string name="action_connect">Connect</string>
<string name="action_discard">Renunțați</string> <string name="action_discard">Discard</string>
<string name="action_members">Membri</string> <string name="action_members">Members</string>
<string name="action_labels">Etichete</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Monede</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistici</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Editare proiect</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Etichetă factură</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Gestionare etichete</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">Despre</string> <string name="title_about">About</string>
<string name="title_settle">Settle Project</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Partajează proiect</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Adaugă Proiect</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Adaugă Categorie</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Adaugă Mod de Plată</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Cont Nextcloud</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Link web</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Ești sigur?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Toate facturile</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categorii</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Moduri de plată</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Nume</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Culoare</string> <string name="label_color">Color</string>
<string name="label_weight">Greutate</string> <string name="label_weight">Weight</string>
<string name="label_activated">Activat</string> <string name="label_activated">Activated</string>
<string name="label_password">Parolă</string> <string name="label_password">Password</string>
<string name="label_email">E-mail</string> <string name="label_email">E-mail</string>
<string name="label_url">Adresa serverului</string> <string name="label_url">Server address</string>
<string name="label_username">Nume</string> <string name="label_username">Username</string>
<string name="label_comment">Comentariu</string> <string name="label_comment">Comment</string>
<string name="label_what">Ce?</string> <string name="label_what">What?</string>
<string name="label_payer">Cine a plătit?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Pentru cine?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Repetă fiecare</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Mod</string> <string name="label_mode">Mode</string>
<string name="label_category">Categorie</string> <string name="label_category">Category</string>
<string name="label_project_id">ID/nume proiect</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Titlul proiectului</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Utilizați contul de Nextcloud App</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Modificări nesalvate</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Salvați modificările înainte de a pleca?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Proiectul la distanță nu va fi șters.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Eroare de sincronizare</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Sincronizarea a eșuat pentru %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Cheltuielile sunt deja echilibrate.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Proiectul %1$s a fost adăugat</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Toate facturile etichetate</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Fără sugestii</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Necesită Cospend v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Link copiat în clipboard</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Scanați codul QR sau partajați link-ul pentru a vă alătura.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Link pentru accesul browser-ului web.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Partajează acest link cu un utilizator Cowcheltuit.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Decontare pentru %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s datorează %3$.2f la %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Statistici pentru %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Membru (Ajutor = Balans cheltuit)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Autentificat ca %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Eroare</string> <string name="error_generic">Error</string>
<string name="error_loading">Încărcare</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Niciun proiect găsit</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Niciun membru găsit</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Nicio factură găsită</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Cel puţin un membru este necesar</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Serverul este în modul de mentenanță</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">Cerere invalidă 400</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Neautorizat</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Interzis</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Nu a fost găsit</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Sincronizare esuata: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Autentificare invalidă: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Nume utilizator sau parolă greșite</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Răspuns server nevalid</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Solicitare eșuată</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">E-mail invalid</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Identificator proiect invalid</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Titlu proiect nevalid</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Nume factură nevalid</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Data facturii invalidă</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Plătitor necesar</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Proprietari necesari</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Nicio conexiune la rețea</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Eroare server</string> <string name="error_server">Server error</string>
<string name="error_io">Conexiunea serverului este întreruptă</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Nu se poate partaja acest proiect</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Conectare la contul Nextcloud</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Ultima sincronizare: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Anulează</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Da</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Nr</string> <string name="simple_no">No</string>
<string name="simple_close">Inchide</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Aspectul</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Rețea</string> <string name="settings_network">Network</string>
<string name="settings_other">Altele</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Tema</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Mod offline</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Sincronizează doar manual.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Culoare personalizată</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Selectare culoare</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Arată proiectele arhivate</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Caracteristici Beta</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Activați funcțiile experimentale. Utilizați pe propriul risc.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">AVERTISMENT: \"http\" nu este sigur. Utilizaţi \"http\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Alege culoare</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">Sistem</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Lumină</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Întunecat</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Urmăriți sistemul</string> <string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Fără repetare</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Zilnic</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Săptămânal</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Fortăreaţă</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Lunar</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Anual</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Niciunul</string>
<string name="payment_mode_all">Toate</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Card de credit</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Numerar</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Verifică</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">Niciunul</string>
<string name="category_all">Toate</string> <string name="category_none">None</string>
<string name="category_all_except_reimbursement">Toate cu excepția rambursării</string> <string name="category_all">All</string>
<string name="category_groceries">Mărfuri</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_leisure">Barie/petrecere</string> <string name="category_groceries">Grocery</string>
<string name="category_rent">Chirie</string> <string name="category_leisure">Bar/Party</string>
<string name="category_bills">Factură</string> <string name="category_rent">Rent</string>
<string name="category_excursion">Excursie/Cultură</string> <string name="category_bills">Bill</string>
<string name="category_health">Sănătate</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_shopping">Cumpărături</string> <string name="category_health">Health</string>
<string name="category_reimbursement">Rambursare</string> <string name="category_shopping">Shopping</string>
<string name="category_reimbursement">Reimbursement</string>
<string name="category_restaurant">Restaurant</string> <string name="category_restaurant">Restaurant</string>
<string name="category_accomodation">Cazare</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transportul</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Ce</string> <string name="new_project_action">What</string>
<string name="new_project_where">Unde</string> <string name="new_project_where">Where</string>
<string name="where_local">Doar local</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cocheltuiește</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Alătură-te proiectului existent</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Creează un proiect nou</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Importă din fișier</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Alege proiect</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Nu au fost găsite proiecte pe acest cont.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Proiect</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Proiect adăugat cu succes.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Încă nu aveți proiecte.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Configurare cont Nextcloud</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Adăugați proiectul manual</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Niciun membru în acest proiect.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Nicio factură găsită.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Membrul există deja.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">Proiect: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">Proiectul %1$s a fost eliminat.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">Fișier salvat: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">Importul a eșuat la rândul %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">Format de dată nevalid la rândul %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">Ceară nevalidă la rândul %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">Adaugă Membru</string>
<string name="edit_member_dialog_title">Editează Membru</string>
<string name="member_edit_delete">Ștergere</string>
<string name="project_edition_no_change">Nicio modificare de salvat.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Niciunul (Optim)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Cine plătește</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">Cui îi este</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Sumă</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Distribuie</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Creați facturi</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Decontare</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Alege moneda (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Niciunul</string> <string name="setting_none">None</string>
<string name="setting_all">Toate</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Setări valută salvate.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Moneda principală</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Categorii sugerate</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Omitere</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">De la</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">La</string> <string name="stats_date_max">To</string>
<string name="stats_who">Membru</string> <string name="stats_who">Member</string>
<string name="stats_paid">Plătit</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Cheltuit</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Sold</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Conexiune eșuată: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Crearea a eșuat: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Eroare la actualizarea proiectului la distanță: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Rețea indisponibilă pentru operarea la distanță.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Nu s-a putut analiza codul QR.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Nepotrivire simbol de autentificare. Vă rugăm să vă autentificați din nou.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Nu aveţi permisiunea de a efectua această acţiune.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Ștergere etichetă</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Sunteţi sigur că doriţi să ştergeţi această etichetă?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Versiunea %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Responsabil</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Licenta</string> <string name="about_license_title">License</string>
<string name="about_source_title">Cod sursă</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Proiectul %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Distribuie %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+251 -220
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Тратить</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Новый счет</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Добавить проект</string> <string name="action_add_project">Add project</string>
<string name="action_save">Сохранить</string> <string name="action_save">Save</string>
<string name="action_edit">Редактирование</string> <string name="action_edit">Edit</string>
<string name="action_share">Поделиться</string> <string name="action_share">Share</string>
<string name="action_search">Искать</string> <string name="action_search">Search</string>
<string name="action_delete">Удалить</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Архивировать</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Разархивировать</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Экспорт</string> <string name="action_delete">Delete</string>
<string name="action_stats">Статистика</string> <string name="simple_back">Back</string>
<string name="action_settle">Загадать</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Настройки</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Отсутствуют категории меток</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Выйти</string> <string name="action_logout">Logout</string>
<string name="action_connect">Подключиться</string> <string name="action_connect">Connect</string>
<string name="action_discard">Сбросить</string> <string name="action_discard">Discard</string>
<string name="action_members">Члены Комитета</string> <string name="action_members">Members</string>
<string name="action_labels">Метки</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Валюты</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Статистика</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Редактировать проект</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Счета меток</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Управление ярлыками</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">О программе</string> <string name="title_about">About</string>
<string name="title_settle">Установленный проект</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Поделиться проектом</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Добавить проект</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Добавить категорию</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Добавить режим оплаты</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Аккаунт следующего облака</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Веб-ссылка</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Вы уверены?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Все счета</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Категории</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Способы оплаты</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Наименование</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Цвет</string> <string name="label_color">Color</string>
<string name="label_weight">Вес</string> <string name="label_weight">Weight</string>
<string name="label_activated">Активирован</string> <string name="label_activated">Activated</string>
<string name="label_password">Пароль</string> <string name="label_password">Password</string>
<string name="label_email">Эл. почта</string> <string name="label_email">E-mail</string>
<string name="label_url">Адрес сервера</string> <string name="label_url">Server address</string>
<string name="label_username">Имя пользователя</string> <string name="label_username">Username</string>
<string name="label_comment">Комментарий</string> <string name="label_comment">Comment</string>
<string name="label_what">Что?</string> <string name="label_what">What?</string>
<string name="label_payer">Кто платит?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Для кого?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Повторять каждые</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Режим</string> <string name="label_mode">Mode</string>
<string name="label_category">Категория</string> <string name="label_category">Category</string>
<string name="label_project_id">ID/имя проекта</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Название проекта</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Использовать учётную запись Nextcloud</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Несохраненные изменения</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Сохранить изменения перед выходом?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Удаленный проект не будет удален.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Ошибка синхронизации</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Сбой синхронизации для %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Расходы уже сбалансированы.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Добавлен проект %1$s</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Все счета помечены</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Нет предложений</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Требуется расходы v0.3.4 +.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Ссылка скопирована в буфер обмена</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Отсканируйте QR-код или поделитесь ссылкой, чтобы присоединиться.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Ссылка для доступа к веб-браузеру.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Поделитесь этой ссылкой с пользователем, потраченным на разговор.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Расчет для %1$s</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s обязана %3$.2f %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Статистика для %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Член (платные | Расходы | Баланс)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Вы вошли как %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Ошибка</string> <string name="error_generic">Error</string>
<string name="error_loading">Загрузка</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Проектов не найдено</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Участников не найдено</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Счетов не найдено</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Требуется хотя бы один участник</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Сервер находится в режиме обслуживания</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 Плохой запрос</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 не авторизован</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 запрещено</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Не найдено</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Сбой синхронизации: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Неверный логин: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Неверное имя пользователя или пароль</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Неправильный ответ сервера</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Запрос не удался</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Неверный e-mail</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Неверный ID проекта</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Неверное название проекта</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Неверное имя счета</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Неверная дата счета</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Требуется плательщик</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Требуется владельцы</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Нет подключения к сети</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Ошибка сервера</string> <string name="error_server">Server error</string>
<string name="error_io">Соединение с сервером прервано</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Не удается поделиться этим проектом</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Подключение к учётной записи Nextcloud</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Последняя синхронизация: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Отмена</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">Ок</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Да</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Нет</string> <string name="simple_no">No</string>
<string name="simple_close">Закрыть</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Внешний вид</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Сеть</string> <string name="settings_network">Network</string>
<string name="settings_other">Прочие вопросы</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Тема</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Автономный режим</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Синхронизировать только вручную.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Пользовательский цвет</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Выбор цвета</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Показать архивные проекты</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Функции бета-версии</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Включить экспериментальные функции. Используйте на свой страх и риск.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">ВНИМАНИЕ: «http» небезопасен. Используйте «https».</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Выберите цвет</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">Система</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Следующее облако</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">Ручной</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">Светлая</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">Тёмная</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">Следовать за системой</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Не повторять</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Ежедневно</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Еженедельно</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Счастливая ночь</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Ежемесячно</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Ежегодно</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Нет</string>
<string name="payment_mode_all">Все</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Кредитная карта</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Наличные</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Проверить</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">Онлайн</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">Перевод</string> <string name="payment_mode_online">Online</string>
<string name="category_none">Нет</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">Все</string>
<string name="category_all_except_reimbursement">Все кроме возмещения</string> <string name="category_none">None</string>
<string name="category_groceries">Бакалея</string> <string name="category_all">All</string>
<string name="category_leisure">Бар/вечеринка</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_rent">Аренда</string> <string name="category_groceries">Grocery</string>
<string name="category_bills">Счет</string> <string name="category_leisure">Bar/Party</string>
<string name="category_excursion">Экскурсия/Культура</string> <string name="category_rent">Rent</string>
<string name="category_health">Здоровье</string> <string name="category_bills">Bill</string>
<string name="category_shopping">Покупки</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_reimbursement">Возмещение</string> <string name="category_health">Health</string>
<string name="category_restaurant">Ресторан</string> <string name="category_shopping">Shopping</string>
<string name="category_accomodation">Проживание</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_transport">Транспорт</string> <string name="category_restaurant">Restaurant</string>
<string name="category_sport">Спорт</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string>
<string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Что</string> <string name="new_project_action">What</string>
<string name="new_project_where">Где</string> <string name="new_project_where">Where</string>
<string name="where_local">Только локальные</string> <string name="where_local">Local only</string>
<string name="where_cospend">Костюд</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Присоединиться к существующему проекту</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Создать новый проект</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Импортировать из файла</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Выберите проект</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Не найдено проектов для этой учетной записи.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Проект</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Проект успешно добавлен.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">У вас пока нет проектов.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Настроить аккаунт Nextcloud</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Добавить проект вручную</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">В этом проекте нет участников.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Счета не найдены.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Участник уже существует.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">Проект: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">Проект %1$s удален.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">Файл сохранён: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">Ошибка импорта в строке %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">Недопустимый формат даты в строке %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">Недопустимые владельцы в строке %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">Добавить участника</string>
<string name="edit_member_dialog_title">Изменить участника</string>
<string name="member_edit_delete">Удалить</string>
<string name="project_edition_no_change">Нет изменений для сохранения.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Нет (оптимально)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Кто платит</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">Кому</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Сумма</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Поделиться</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Создать счета</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Расчет</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Выберите валюту (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Нет</string> <string name="setting_none">None</string>
<string name="setting_all">Все</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Настройки валюты сохранены.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Основная валюта</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Предлагаемые категории</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Пропустить</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">От</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">Кому</string> <string name="stats_date_max">To</string>
<string name="stats_who">Участник</string> <string name="stats_who">Member</string>
<string name="stats_paid">Оплачено</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Потрачено</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Баланс</string> <string name="stats_balance">Balance</string>
<string name="total">Всего: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Ошибка соединения: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Создание не удалось: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Ошибка при обновлении удаленного проекта: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Сеть недоступна для удаленной операции.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Не удалось проанализировать QR-код.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Токен аутентификации не совпадает. Пожалуйста, войдите снова.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">У вас нет разрешения на выполнение этого действия.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Удалить метку</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Вы уверены, что хотите удалить этот ярлык?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Версия %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Сопровождающий</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Лицензия</string> <string name="about_license_title">License</string>
<string name="about_source_title">Исходный код</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Проект %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Поделиться %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+39 -8
View File
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">New bill</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Add project</string> <string name="action_add_project">Add project</string>
@@ -8,7 +15,11 @@
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_open_menu">Open menu</string>
<string name="action_close_search">Close search</string>
<string name="action_clear_search">Clear search</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="simple_back">Back</string>
<string name="action_archive">Archive</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string> <string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string> <string name="action_export">Export</string>
@@ -23,6 +34,7 @@
<string name="action_members">Members</string> <string name="action_members">Members</string>
<string name="action_labels">Labels</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Currencies</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistics</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Edit project</string> <string name="title_edit_project">Edit project</string>
@@ -38,6 +50,7 @@
<string name="title_share_web">Web link</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Are you sure?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">All bills</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categories</string> <string name="label_categories">Categories</string>
@@ -61,6 +74,7 @@
<string name="label_project_id">Project ID/name</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project title</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Use Nextcloud App Account</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Unsaved changes</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Save changes before leaving?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
@@ -81,6 +95,7 @@
<string name="msg_stats_intro">Stats for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Member (Paid | Spent | Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Error</string> <string name="error_generic">Error</string>
<string name="error_loading">Loading</string> <string name="error_loading">Loading</string>
@@ -109,6 +124,7 @@
<string name="error_server">Server error</string> <string name="error_server">Server error</string>
<string name="error_io">Server connection broken</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Cannot share this project</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Connect to Nextcloud account</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
@@ -117,6 +133,7 @@
<string name="simple_yes">Yes</string> <string name="simple_yes">Yes</string>
<string name="simple_no">No</string> <string name="simple_no">No</string>
<string name="simple_close">Close</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Appearance</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Network</string> <string name="settings_network">Network</string>
@@ -129,15 +146,23 @@
<string name="settings_show_archived">Show archived projects</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WARNING: \"http\" is unsafe. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string> <string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string> <string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">No repeat</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Daily</string> <string name="repeat_day">Daily</string>
@@ -145,6 +170,7 @@
<string name="repeat_fortnight">Fortnightly</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Monthly</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Yearly</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">None</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_all">All</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_credit_card">Credit card</string> <string name="payment_mode_credit_card">Credit card</string>
@@ -152,6 +178,7 @@
<string name="payment_mode_check">Check</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">None</string> <string name="category_none">None</string>
<string name="category_all">All</string> <string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
@@ -167,17 +194,14 @@
<string name="category_accomodation">Accommodation</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">Where</string> <string name="new_project_where">Where</string>
<string name="where_local">Local only</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Join existing project</string> <string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string> <string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string> <string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string> <string name="no_projects_text">You have no projects yet.</string>
@@ -196,6 +220,7 @@
<string name="edit_member_dialog_title">Edit Member</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Delete</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">No changes to save.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">None (Optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Who pays</string> <string name="settle_who">Who pays</string>
@@ -204,12 +229,14 @@
<string name="simple_settle_share">Share</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Create bills</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Settlement</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Choose Currency (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">None</string> <string name="setting_none">None</string>
<string name="setting_all">All</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Currency settings saved.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Main Currency</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Suggested Categories</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Skip</string> <string name="label_bills_skip">Skip</string>
@@ -220,6 +247,7 @@
<string name="stats_spent">Spent</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Balance</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Connection failed: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
@@ -230,12 +258,15 @@
<string name="insufficient_access_level">You don\'t have permission to perform this action.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Delete Label</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Maintainer</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">License</string> <string name="about_license_title">License</string>
<string name="about_source_title">Source code</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Share %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+245 -214
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Ny räkning</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Lägg till projekt</string> <string name="action_add_project">Add project</string>
<string name="action_save">Spara</string> <string name="action_save">Save</string>
<string name="action_edit">Redigera</string> <string name="action_edit">Edit</string>
<string name="action_share">Dela</string> <string name="action_share">Share</string>
<string name="action_search">Sök</string> <string name="action_search">Search</string>
<string name="action_delete">Radera</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Arkivera</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Avarkivera</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Exportera</string> <string name="action_delete">Delete</string>
<string name="action_stats">Statistik</string> <string name="simple_back">Back</string>
<string name="action_settle">Bosättning</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Inställningar</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Etikett saknade kategorier</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Utloggning</string> <string name="action_logout">Logout</string>
<string name="action_connect">Anslut</string> <string name="action_connect">Connect</string>
<string name="action_discard">Ignorera</string> <string name="action_discard">Discard</string>
<string name="action_members">Medlemmar</string> <string name="action_members">Members</string>
<string name="action_labels">Etiketter</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Valutor</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistik</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Redigera projekt</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Etikett räkningar</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Hantera etiketter</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">Om</string> <string name="title_about">About</string>
<string name="title_settle">Fastställ projekt</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Dela projekt</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Lägg till projekt</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Lägg till kategori</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Lägg till betalningsläge</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Nextcloud-konto</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Webblänk</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Är du säker?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Alla räkningar</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Kategorier</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Betalningslägen</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Namn</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Färg</string> <string name="label_color">Color</string>
<string name="label_weight">Vikt</string> <string name="label_weight">Weight</string>
<string name="label_activated">Aktiverad</string> <string name="label_activated">Activated</string>
<string name="label_password">Lösenord</string> <string name="label_password">Password</string>
<string name="label_email">E-post</string> <string name="label_email">E-mail</string>
<string name="label_url">Serverns adress</string> <string name="label_url">Server address</string>
<string name="label_username">Användarnamn</string> <string name="label_username">Username</string>
<string name="label_comment">Kommentar</string> <string name="label_comment">Comment</string>
<string name="label_what">Vad?</string> <string name="label_what">What?</string>
<string name="label_payer">Vem betalade?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">För vem?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Upprepa varje</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Läge</string> <string name="label_mode">Mode</string>
<string name="label_category">Kategori</string> <string name="label_category">Category</string>
<string name="label_project_id">Projektets ID/namn</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Projektets titel</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Använd Nextcloud App Konto</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Osparade ändringar</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Spara ändringar innan du lämnar?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Fjärrprojektet kommer inte att raderas.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Synkronisera fel</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Synkronisering misslyckades för %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Kostnaderna är redan balanserade.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Projekt %1$s tillagt</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Alla räkningar märkta</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Inga förslag</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Kräver Cospend v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Länk kopierad till urklipp</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Skanna QR-koden eller dela länken för att gå med.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Länk för åtkomst till webbläsaren.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Dela denna länk med en Cowspent användare.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Avräkning för %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s är skyldig %3$.2f till %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Statistik för %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Medlem (Betald &lt;unk&gt; Spenderad &lt;unk&gt; Balans)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Inloggad som %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Fel</string> <string name="error_generic">Error</string>
<string name="error_loading">Laddar</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Inga projekt hittades</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Inga medlemmar hittades</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Inga räkningar hittades</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Minst en medlem krävs</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Servern är i underhållsläge</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 Felaktig begäran</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Obehörig</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Förbjuden</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 hittades inte</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Synkronisering misslyckades: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Ogiltig inloggning: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Fel användarnamn eller lösenord</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Ogiltigt serversvar</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Begäran misslyckades</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Ogiltig e-post</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Ogiltigt projekt-ID</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Ogiltig projekttitel</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Ogiltigt räkningsnamn</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Ogiltigt faktureringsdatum</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Betalare krävs</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Ägare krävs</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Ingen nätverksanslutning</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Serverfel</string> <string name="error_server">Server error</string>
<string name="error_io">Serveranslutning är trasig</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Kan inte dela detta projekt</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Anslut till Nextcloud-konto</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Senaste synkronisering: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Avbryt</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">OK</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Ja</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Nej</string> <string name="simple_no">No</string>
<string name="simple_close">Stäng</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Utseende</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Nätverk</string> <string name="settings_network">Network</string>
<string name="settings_other">Annat</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Tema</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Offline läge</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Synkronisera endast manuellt.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Anpassad färg</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Färgval</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Visa arkiverade projekt</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta funktioner</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Aktivera experimentella funktioner. Använd på egen risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">VARNING: \"http\" är osäkra. Använd \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Välj färg</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nästamoln</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_color_manual">Manuell</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_light">Ljus</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_dark">Mörk</string> <string name="pref_value_theme_system">Follow system</string>
<string name="pref_value_theme_system">Följ systemet</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Ingen upprepning</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Dagligen</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Veckovis</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Fyrkantig</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Månadsvis</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Årligen</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Ingen</string>
<string name="payment_mode_all">Alla</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Kreditkort</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Kontant</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Kontrollera</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Överföring</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">Ingen</string>
<string name="category_all">Alla</string> <string name="category_none">None</string>
<string name="category_all_except_reimbursement">Alla utom ersättning</string> <string name="category_all">All</string>
<string name="category_groceries">Livsmedelsaffär</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_leisure">Fest/Fest</string> <string name="category_groceries">Grocery</string>
<string name="category_rent">Hyra</string> <string name="category_leisure">Bar/Party</string>
<string name="category_bills">Räkning</string> <string name="category_rent">Rent</string>
<string name="category_excursion">Utflykt/kultur</string> <string name="category_bills">Bill</string>
<string name="category_health">Hälsa</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_health">Health</string>
<string name="category_shopping">Shopping</string> <string name="category_shopping">Shopping</string>
<string name="category_reimbursement">Ersättning</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_restaurant">Restaurang</string> <string name="category_restaurant">Restaurant</string>
<string name="category_accomodation">Boende</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Vad</string> <string name="new_project_action">What</string>
<string name="new_project_where">Var</string> <string name="new_project_where">Where</string>
<string name="where_local">Endast lokalt</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Anslut till befintligt projekt</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Skapa nytt projekt</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Importera från fil</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Välj projekt</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">Inga projekt hittades på detta konto.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Projekt</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Projektet lades till.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">Du har inga projekt än.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Konfigurera Nextcloud konto</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Lägg till projekt manuellt</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Inga medlemmar i detta projekt.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Inga räkningar hittades.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Medlemmen finns redan.</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">Projekt: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">Projekt %1$s borttaget.</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">Fil sparad: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">Importen misslyckades vid rad %d</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">Ogiltigt datumformat på rad %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">Ogiltiga owers på rad %d</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">Lägg till medlem</string>
<string name="edit_member_dialog_title">Redigera medlem</string>
<string name="member_edit_delete">Radera</string>
<string name="project_edition_no_change">Inga ändringar att spara.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Ingen (optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Vem betalar</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">Till vem</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Belopp</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Dela</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Skapa räkningar</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Avräkning</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Välj valuta (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Ingen</string> <string name="setting_none">None</string>
<string name="setting_all">Alla</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Valutainställningar sparade.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Huvudvaluta</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Föreslagna kategorier</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Hoppa</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">Från</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">Till</string> <string name="stats_date_max">To</string>
<string name="stats_who">Medlem</string> <string name="stats_who">Member</string>
<string name="stats_paid">Betald</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Spenderade</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Saldo</string> <string name="stats_balance">Balance</string>
<string name="total">Totalt: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Anslutning misslyckades: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Skapandet misslyckades: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Fel vid uppdatering av fjärrprojekt: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Nätverket är inte tillgängligt för fjärrstyrning.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Det gick inte att tolka QR-koden.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Autentiseringstoken matchar inte. Logga in igen.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">Du har inte behörighet att utföra denna åtgärd.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Ta bort etikett</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Är du säker på att du vill ta bort denna etikett?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Underhållare</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Licens</string> <string name="about_license_title">License</string>
<string name="about_source_title">Källkod</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Projekt %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Dela %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+39 -8
View File
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">New bill</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Add project</string> <string name="action_add_project">Add project</string>
@@ -8,7 +15,11 @@
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_open_menu">Open menu</string>
<string name="action_close_search">Close search</string>
<string name="action_clear_search">Clear search</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="simple_back">Back</string>
<string name="action_archive">Archive</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string> <string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string> <string name="action_export">Export</string>
@@ -23,6 +34,7 @@
<string name="action_members">Members</string> <string name="action_members">Members</string>
<string name="action_labels">Labels</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Currencies</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistics</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Edit project</string> <string name="title_edit_project">Edit project</string>
@@ -38,6 +50,7 @@
<string name="title_share_web">Web link</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Are you sure?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">All bills</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categories</string> <string name="label_categories">Categories</string>
@@ -61,6 +74,7 @@
<string name="label_project_id">Project ID/name</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project title</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Use Nextcloud App Account</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Unsaved changes</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Save changes before leaving?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
@@ -81,6 +95,7 @@
<string name="msg_stats_intro">Stats for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Member (Paid | Spent | Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Error</string> <string name="error_generic">Error</string>
<string name="error_loading">Loading</string> <string name="error_loading">Loading</string>
@@ -109,6 +124,7 @@
<string name="error_server">Server error</string> <string name="error_server">Server error</string>
<string name="error_io">Server connection broken</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Cannot share this project</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Connect to Nextcloud account</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
@@ -117,6 +133,7 @@
<string name="simple_yes">Yes</string> <string name="simple_yes">Yes</string>
<string name="simple_no">No</string> <string name="simple_no">No</string>
<string name="simple_close">Close</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Appearance</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Network</string> <string name="settings_network">Network</string>
@@ -129,15 +146,23 @@
<string name="settings_show_archived">Show archived projects</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WARNING: \"http\" is unsafe. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string> <string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string> <string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">No repeat</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Daily</string> <string name="repeat_day">Daily</string>
@@ -145,6 +170,7 @@
<string name="repeat_fortnight">Fortnightly</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Monthly</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Yearly</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">None</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_all">All</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_credit_card">Credit card</string> <string name="payment_mode_credit_card">Credit card</string>
@@ -152,6 +178,7 @@
<string name="payment_mode_check">Check</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">None</string> <string name="category_none">None</string>
<string name="category_all">All</string> <string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
@@ -167,17 +194,14 @@
<string name="category_accomodation">Accommodation</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">Where</string> <string name="new_project_where">Where</string>
<string name="where_local">Local only</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Join existing project</string> <string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string> <string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string> <string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string> <string name="no_projects_text">You have no projects yet.</string>
@@ -196,6 +220,7 @@
<string name="edit_member_dialog_title">Edit Member</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Delete</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">No changes to save.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">None (Optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Who pays</string> <string name="settle_who">Who pays</string>
@@ -204,12 +229,14 @@
<string name="simple_settle_share">Share</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Create bills</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Settlement</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Choose Currency (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">None</string> <string name="setting_none">None</string>
<string name="setting_all">All</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Currency settings saved.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Main Currency</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Suggested Categories</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Skip</string> <string name="label_bills_skip">Skip</string>
@@ -220,6 +247,7 @@
<string name="stats_spent">Spent</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Balance</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Connection failed: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
@@ -230,12 +258,15 @@
<string name="insufficient_access_level">You don\'t have permission to perform this action.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Delete Label</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Maintainer</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">License</string> <string name="about_license_title">License</string>
<string name="about_source_title">Source code</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Share %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+244 -213
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Ковтаг</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">Нових рахунок до оплати</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Додати проект</string> <string name="action_add_project">Add project</string>
<string name="action_save">Зберегти</string> <string name="action_save">Save</string>
<string name="action_edit">Редагувати</string> <string name="action_edit">Edit</string>
<string name="action_share">Поділитись</string> <string name="action_share">Share</string>
<string name="action_search">Пошук</string> <string name="action_search">Search</string>
<string name="action_delete">Видалити</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">Архів</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">Видобути з архіву</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">Експорт</string> <string name="action_delete">Delete</string>
<string name="action_stats">Статистика</string> <string name="simple_back">Back</string>
<string name="action_settle">Сетле</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">Налаштування</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">Ярлик відсутні категорії</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">Вихід із системи</string> <string name="action_logout">Logout</string>
<string name="action_connect">Підключитися</string> <string name="action_connect">Connect</string>
<string name="action_discard">Відкинути</string> <string name="action_discard">Discard</string>
<string name="action_members">Члени</string> <string name="action_members">Members</string>
<string name="action_labels">Мітки</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Валюти</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Статистика</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Редагувати проект</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">Мітки</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">Керувати мітками</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">Про програму</string> <string name="title_about">About</string>
<string name="title_settle">Врегулювати проект</string> <string name="title_settle">Settle Project</string>
<string name="title_share">Поділитися проектом</string> <string name="title_share">Share Project</string>
<string name="title_add_project">Додати проект</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">Додати Категорію</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">Додати режим оплати</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">Обліковий запис Nextcloud</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">Веб-посилання</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Ви впевнені?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">Усі рахунки</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Категорії</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">Режими оплати</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">Ім\'я</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">Колір</string> <string name="label_color">Color</string>
<string name="label_weight">Вага</string> <string name="label_weight">Weight</string>
<string name="label_activated">Активовано</string> <string name="label_activated">Activated</string>
<string name="label_password">Пароль</string> <string name="label_password">Password</string>
<string name="label_email">Ел. пошта</string> <string name="label_email">E-mail</string>
<string name="label_url">Адреса сервера</string> <string name="label_url">Server address</string>
<string name="label_username">Ім\'я користувача</string> <string name="label_username">Username</string>
<string name="label_comment">Коментар</string> <string name="label_comment">Comment</string>
<string name="label_what">А що?</string> <string name="label_what">What?</string>
<string name="label_payer">Хто заплатив?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">Для кого?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">Повторювати кожні</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">Режим</string> <string name="label_mode">Mode</string>
<string name="label_category">Категорія</string> <string name="label_category">Category</string>
<string name="label_project_id">ID проекту/ім\'я</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Заголовок проекту</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Використовувати обліковий запис Nextcloud App</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Незбережені зміни</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Зберегти зміни перед відходом?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">Віддалений проект не буде видалено.</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">Помилка синхронізації</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">Витрати вже врівноважені.</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">Проект %1$s додано</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">Всі рахунки позначені</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">Немає припущень</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">Потребує спорядження v0.3.4+.</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">Посилання скопійовано до буфера обміну</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">Скануйте QR-код або поділіться посиланням, щоб приєднатися.</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">Посилання для доступу до веб-браузера.</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">Поділитися цим посиланням з користувачем Cowspent користувача.</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">Settlement for %1$s:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">Статистика для %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Член (Paid | Витрачено | Баланс)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Ви увійшли як %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Помилка</string> <string name="error_generic">Error</string>
<string name="error_loading">Завантаження</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">Проектів не знайдено</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">Учасників не знайдено</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">Рахунків не знайдено</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">Принаймні одного учасника необхідно</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">Сервер знаходиться в режимі обслуговування</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 поганий запит</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 Неавторизовано</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 Заборонено</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404 Не знайдено</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">Помилка синхронізації: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">Invalid login: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">Неправильне ім\'я користувача або пароль</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">Неправильна відповідь від сервера</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">Не вдалося виконати запит</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">Некоректна e-mail адреса</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">Недійсний ID проекту</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">Недійсна назва проекту</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">Некоректна назва рахунку</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">Некоректна дата рахунку</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">Потрібен платник</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">Власники необхідні</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">Немає з’єднання з мережею</string> <string name="error_no_network">No network connection</string>
<string name="error_server">Помилка сервера</string> <string name="error_server">Server error</string>
<string name="error_io">З\'єднання з сервером розірвано</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Неможливо поділитися цим проектом</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Підключити до облікового запису Nextcloud</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">Скасувати</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">Гаразд</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes">Так</string> <string name="simple_yes">Yes</string>
<string name="simple_no">Ні</string> <string name="simple_no">No</string>
<string name="simple_close">Закрити</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Зовнішній вигляд</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Мережа</string> <string name="settings_network">Network</string>
<string name="settings_other">Інше</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">Тема</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">Автономний режим</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">Синхронізувати тільки вручну.</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">Власний колір</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">Вибір кольору</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">Показати архівовані проекти</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Можливості Бета</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Увімкнення експериментальних функцій. Використовуйте на свій страх і ризик.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">ПОПЕРЕДЖЕННЯ: \"http\" небезпечний. Використовуйте \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">Вибрати колір</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">Система</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">Наступна хмара</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">Вручну</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">Світла</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">Темна</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">Наслідувати систему</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">Без повторень</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Щоденно</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">Щотижня</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">Фортечна</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Щомісячно</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">За рік</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">Без ефекту</string>
<string name="payment_mode_all">Всі</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">Кредитна картка</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">Готівкою</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">Перевірити</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">Онлайн</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">Переказ</string> <string name="payment_mode_online">Online</string>
<string name="category_none">Без ефекту</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">Всі</string>
<string name="category_all_except_reimbursement">Усі крім відшкодування</string> <string name="category_none">None</string>
<string name="category_groceries">Ґросері</string> <string name="category_all">All</string>
<string name="category_leisure">Бар/З групою</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_rent">Оренда</string> <string name="category_groceries">Grocery</string>
<string name="category_bills">Рахунок</string> <string name="category_leisure">Bar/Party</string>
<string name="category_excursion">Екскурсія/Культура</string> <string name="category_rent">Rent</string>
<string name="category_health">Здоров\'я</string> <string name="category_bills">Bill</string>
<string name="category_shopping">Шопінг</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_reimbursement">Реімбурсація</string> <string name="category_health">Health</string>
<string name="category_restaurant">Ресторан</string> <string name="category_shopping">Shopping</string>
<string name="category_accomodation">Акомодація</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_transport">Транспорт</string> <string name="category_restaurant">Restaurant</string>
<string name="category_sport">Спорт</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string>
<string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">Що</string> <string name="new_project_action">What</string>
<string name="new_project_where">Де</string> <string name="new_project_where">Where</string>
<string name="where_local">Лише локально</string> <string name="where_local">Local only</string>
<string name="where_cospend">Косменда</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">Ігатегрошима</string> <string name="todo_create">Create new project</string>
<string name="todo_join">Приєднатися до існуючого проекту</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">Створити новий проект</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">Імпортувати з файлу</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">Вибрати проект</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">В цьому обліковому записі не знайдено жодних проектів.</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">Проект</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">Проект успішно доданий.</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">У вас поки що немає проектів.</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">Налаштування облікового запису Nextcloud</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">Додати проект вручну</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">Немає учасників в цьому проекті.</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">Рахунків не знайдено.</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">Участь вже існує.</string>
<string name="activity_dialog_title">Проект: %1$s</string>
<string name="remove_project_confirmation">Проект %1$s видалений.</string>
<string name="file_saved_success">Файл збережено: %1$s</string>
<string name="import_error_header">Import failed at row %d</string> <string name="import_error_header">Import failed at row %d</string>
<string name="import_error_date">Неприпустимий формат дати у рядку %d</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="import_error_owers">Недійсні рядки у рядку %d</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="add_member_dialog_title">Додати учасника</string> <string name="add_member_dialog_title">Add Member</string>
<string name="edit_member_dialog_title">Редагувати учасника</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Видалити</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">Зміни для збереження відсутні.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">Немає (оптимально)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Хто платить</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">Кому</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">Сума</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">Поділитись</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Створити рахунки</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Поселення</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Оберіть валюту (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">Без ефекту</string> <string name="setting_none">None</string>
<string name="setting_all">Всі</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Налаштування валют збережено.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Основна валюта</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Пропоновані категорії</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Пропустити</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">Від</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">На</string> <string name="stats_date_max">To</string>
<string name="stats_who">Гравець</string> <string name="stats_who">Member</string>
<string name="stats_paid">Сплачено</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">Витрачено</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Баланс</string> <string name="stats_balance">Balance</string>
<string name="total">Всього: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Помилка з’єднання: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Помилка при створенні %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">Помилка оновлення віддаленого проекту: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">Мережа недоступна для дистанційної операції.</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">Не вдалося обробити QR-код.</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">Токен автентифікації не збігається. Будь ласка, увійдіть знову.</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">У вас немає дозволу на виконання цієї дії.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Видалити мітку</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Ви впевнені, що хочете видалити цю мітку?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Версія %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Підтримка моделі</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">Ліцензія</string> <string name="about_license_title">License</string>
<string name="about_source_title">Початковий код</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Поділитися %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+39 -8
View File
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">New bill</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Add project</string> <string name="action_add_project">Add project</string>
@@ -8,7 +15,11 @@
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_open_menu">Open menu</string>
<string name="action_close_search">Close search</string>
<string name="action_clear_search">Clear search</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="simple_back">Back</string>
<string name="action_archive">Archive</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string> <string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string> <string name="action_export">Export</string>
@@ -23,6 +34,7 @@
<string name="action_members">Members</string> <string name="action_members">Members</string>
<string name="action_labels">Labels</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Currencies</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistics</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Edit project</string> <string name="title_edit_project">Edit project</string>
@@ -38,6 +50,7 @@
<string name="title_share_web">Web link</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Are you sure?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">All bills</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categories</string> <string name="label_categories">Categories</string>
@@ -61,6 +74,7 @@
<string name="label_project_id">Project ID/name</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project title</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Use Nextcloud App Account</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Unsaved changes</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Save changes before leaving?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
@@ -81,6 +95,7 @@
<string name="msg_stats_intro">Stats for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Member (Paid | Spent | Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Error</string> <string name="error_generic">Error</string>
<string name="error_loading">Loading</string> <string name="error_loading">Loading</string>
@@ -109,6 +124,7 @@
<string name="error_server">Server error</string> <string name="error_server">Server error</string>
<string name="error_io">Server connection broken</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Cannot share this project</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Connect to Nextcloud account</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
@@ -117,6 +133,7 @@
<string name="simple_yes">Yes</string> <string name="simple_yes">Yes</string>
<string name="simple_no">No</string> <string name="simple_no">No</string>
<string name="simple_close">Close</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Appearance</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Network</string> <string name="settings_network">Network</string>
@@ -129,15 +146,23 @@
<string name="settings_show_archived">Show archived projects</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WARNING: \"http\" is unsafe. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string> <string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string> <string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">No repeat</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Daily</string> <string name="repeat_day">Daily</string>
@@ -145,6 +170,7 @@
<string name="repeat_fortnight">Fortnightly</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Monthly</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Yearly</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">None</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_all">All</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_credit_card">Credit card</string> <string name="payment_mode_credit_card">Credit card</string>
@@ -152,6 +178,7 @@
<string name="payment_mode_check">Check</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">None</string> <string name="category_none">None</string>
<string name="category_all">All</string> <string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
@@ -167,17 +194,14 @@
<string name="category_accomodation">Accommodation</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">Where</string> <string name="new_project_where">Where</string>
<string name="where_local">Local only</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Join existing project</string> <string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string> <string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string> <string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string> <string name="no_projects_text">You have no projects yet.</string>
@@ -196,6 +220,7 @@
<string name="edit_member_dialog_title">Edit Member</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Delete</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">No changes to save.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">None (Optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Who pays</string> <string name="settle_who">Who pays</string>
@@ -204,12 +229,14 @@
<string name="simple_settle_share">Share</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Create bills</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Settlement</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Choose Currency (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">None</string> <string name="setting_none">None</string>
<string name="setting_all">All</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Currency settings saved.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Main Currency</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Suggested Categories</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Skip</string> <string name="label_bills_skip">Skip</string>
@@ -220,6 +247,7 @@
<string name="stats_spent">Spent</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Balance</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Connection failed: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
@@ -230,12 +258,15 @@
<string name="insufficient_access_level">You don\'t have permission to perform this action.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Delete Label</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Maintainer</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">License</string> <string name="about_license_title">License</string>
<string name="about_source_title">Source code</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Share %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+250 -219
View File
@@ -1,241 +1,272 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">花了</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">新建账单</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">添加项目</string> <string name="action_add_project">Add project</string>
<string name="action_save">保存</string> <string name="action_save">Save</string>
<string name="action_edit">编辑</string> <string name="action_edit">Edit</string>
<string name="action_share">分享</string> <string name="action_share">Share</string>
<string name="action_search">搜索</string> <string name="action_search">Search</string>
<string name="action_delete">删除</string> <string name="action_open_menu">Open menu</string>
<string name="action_archive">存档</string> <string name="action_close_search">Close search</string>
<string name="action_unarchive">取消存档</string> <string name="action_clear_search">Clear search</string>
<string name="action_export">导出</string> <string name="action_delete">Delete</string>
<string name="action_stats">统计信息</string> <string name="simple_back">Back</string>
<string name="action_settle">解决</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string>
<string name="action_stats">Stats</string>
<string name="action_settle">Settle</string>
<string name="action_scan_qrcode">Scan QR Code</string> <string name="action_scan_qrcode">Scan QR Code</string>
<string name="action_settings">设置</string> <string name="action_settings">Settings</string>
<string name="action_label_bills">标签缺少类别</string> <string name="action_label_bills">Label missing categories</string>
<string name="action_logout">注销</string> <string name="action_logout">Logout</string>
<string name="action_connect">连接</string> <string name="action_connect">Connect</string>
<string name="action_discard">放弃...</string> <string name="action_discard">Discard</string>
<string name="action_members">成员</string> <string name="action_members">Members</string>
<string name="action_labels">标签</string> <string name="action_labels">Labels</string>
<string name="action_currencies">货币</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">统计</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">编辑项目</string> <string name="title_edit_project">Edit project</string>
<string name="title_label_bills">标签计费</string> <string name="title_label_bills">Label Bills</string>
<string name="title_labels">管理标签</string> <string name="title_labels">Manage Labels</string>
<string name="title_about">关于</string> <string name="title_about">About</string>
<string name="title_settle">Settle 项目</string> <string name="title_settle">Settle Project</string>
<string name="title_share">分享项目</string> <string name="title_share">Share Project</string>
<string name="title_add_project">添加项目</string> <string name="title_add_project">Add Project</string>
<string name="title_add_category">添加类别</string> <string name="title_add_category">Add Category</string>
<string name="title_add_payment_mode">添加支付模式</string> <string name="title_add_payment_mode">Add Payment Mode</string>
<string name="title_account">下次云帐户</string> <string name="title_account">Nextcloud Account</string>
<string name="title_share_web">友情链接</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">您确定吗?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">所有账单</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">类别管理</string> <string name="label_categories">Categories</string>
<string name="label_payment_modes">支付方式</string> <string name="label_payment_modes">Payment Modes</string>
<string name="label_name">名称</string> <string name="label_name">Name</string>
<string name="label_icon">Icon / Emoji</string> <string name="label_icon">Icon / Emoji</string>
<string name="label_color">颜色</string> <string name="label_color">Color</string>
<string name="label_weight">权重</string> <string name="label_weight">Weight</string>
<string name="label_activated">已激活</string> <string name="label_activated">Activated</string>
<string name="label_password">密码</string> <string name="label_password">Password</string>
<string name="label_email">电子邮箱</string> <string name="label_email">E-mail</string>
<string name="label_url">服务器地址</string> <string name="label_url">Server address</string>
<string name="label_username">用户名</string> <string name="label_username">Username</string>
<string name="label_comment">评论</string> <string name="label_comment">Comment</string>
<string name="label_what">什么?</string> <string name="label_what">What?</string>
<string name="label_payer">谁付款?</string> <string name="label_payer">Who paid?</string>
<string name="label_owers">给谁?</string> <string name="label_owers">For whom?</string>
<string name="label_repeat">重复每</string> <string name="label_repeat">Repeat every</string>
<string name="label_mode">模式</string> <string name="label_mode">Mode</string>
<string name="label_category">类别</string> <string name="label_category">Category</string>
<string name="label_project_id">项目 ID/名称</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">项目标题</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">使用 Nextcloud App 帐户</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">未保存的更改</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">离开前保存更改吗?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
<string name="dialog_confirm_remove_project_msg">远程项目将不会被删除。</string> <string name="dialog_confirm_remove_project_msg">The remote project will not be deleted.</string>
<string name="dialog_sync_error_title">同步错误</string> <string name="dialog_sync_error_title">Sync error</string>
<string name="dialog_sync_error_msg">%1$s同步失败。\n\n%2$s</string> <string name="dialog_sync_error_msg">Sync failed for %1$s.\n\n%2$s</string>
<string name="dialog_balanced_msg">支出已经平衡。</string> <string name="dialog_balanced_msg">Expenses are already balanced.</string>
<string name="msg_project_added">项目 %1$s 已添加</string> <string name="msg_project_added">Project %1$s added</string>
<string name="msg_bill_labeled_done">所有已标记的账单</string> <string name="msg_bill_labeled_done">All bills labeled</string>
<string name="msg_no_suggestions">没有建议</string> <string name="msg_no_suggestions">No suggestions</string>
<string name="msg_auth_warning">需要花费v0.3.4+</string> <string name="msg_auth_warning">Requires Cospend v0.3.4+.</string>
<string name="msg_link_copied">链接已复制到剪贴板</string> <string name="msg_link_copied">Link copied to clipboard</string>
<string name="msg_share_qr">扫描二维码或共享链接以加入。</string> <string name="msg_share_qr">Scan QR code or share the link to join.</string>
<string name="msg_share_web">网页浏览器访问链接。</string> <string name="msg_share_web">Link for web browser access.</string>
<string name="msg_share_qr_warn">与一个花费的用户共享此链接。</string> <string name="msg_share_qr_warn">Share this link with a Cowspent user.</string>
<string name="msg_settle_intro">%1$s结算:</string> <string name="msg_settle_intro">Settlement for %1$s:</string>
<string name="msg_settle_sentence">%1$s %3$.2f %2$s</string> <string name="msg_settle_sentence">%1$s owes %3$.2f to %2$s</string>
<string name="msg_stats_intro">%1$s 的统计信息:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">会员 (Paid | 花了 | 余额)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">以 %1$s 身份登录</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">错误</string> <string name="error_generic">Error</string>
<string name="error_loading">正在加载</string> <string name="error_loading">Loading</string>
<string name="error_no_projects">未找到项目</string> <string name="error_no_projects">No projects found</string>
<string name="error_no_members">未找到成员</string> <string name="error_no_members">No members found</string>
<string name="error_no_bills">未找到账单</string> <string name="error_no_bills">No bills found</string>
<string name="error_no_member">至少需要一个成员</string> <string name="error_no_member">At least one member required</string>
<string name="error_maintenance_mode">服务器处于维护模式</string> <string name="error_maintenance_mode">Server is in maintenance mode</string>
<string name="error_400">400 个错误请求</string> <string name="error_400">400 Bad request</string>
<string name="error_401">401 未授权</string> <string name="error_401">401 Unauthorized</string>
<string name="error_403">403 禁止</string> <string name="error_403">403 Forbidden</string>
<string name="error_404">404未找到</string> <string name="error_404">404 Not Found</string>
<string name="error_sync">同步失败: %1$s</string> <string name="error_sync">Sync failed: %1$s</string>
<string name="error_invalid_login">无效登录名: %1$s</string> <string name="error_invalid_login">Invalid login: %1$s</string>
<string name="error_auth">用户名或密码错误</string> <string name="error_auth">Wrong username or password</string>
<string name="error_json">服务器响应无效</string> <string name="error_json">Invalid server response</string>
<string name="error_req_failed">请求失败</string> <string name="error_req_failed">Request failed</string>
<string name="error_invalid_email">无效的电子邮件</string> <string name="error_invalid_email">Invalid e-mail</string>
<string name="error_invalid_project_id">无效的项目 ID</string> <string name="error_invalid_project_id">Invalid project ID</string>
<string name="error_invalid_project_name">无效的项目标题</string> <string name="error_invalid_project_name">Invalid project title</string>
<string name="error_invalid_bill_name">无效的账单名称</string> <string name="error_invalid_bill_name">Invalid bill name</string>
<string name="error_invalid_bill_date">无效的账单日期</string> <string name="error_invalid_bill_date">Invalid bill date</string>
<string name="error_invalid_bill_payer">需要付款人</string> <string name="error_invalid_bill_payer">Payer required</string>
<string name="error_invalid_bill_owers">需要所有者</string> <string name="error_invalid_bill_owers">Owers required</string>
<string name="error_no_network">没有网络连接</string> <string name="error_no_network">No network connection</string>
<string name="error_server">服务器错误</string> <string name="error_server">Server error</string>
<string name="error_io">服务器连接已损坏</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">无法分享此项目</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">连接到下一个云账户</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">上次同步: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
<string name="simple_cancel">取消</string> <string name="simple_cancel">Cancel</string>
<string name="simple_ok" tools:ignore="ButtonCase,Typos">好的</string> <string name="simple_ok" tools:ignore="ButtonCase,Typos">Ok</string>
<string name="simple_yes"></string> <string name="simple_yes">Yes</string>
<string name="simple_no"></string> <string name="simple_no">No</string>
<string name="simple_close">关闭</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">外观</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">网络</string> <string name="settings_network">Network</string>
<string name="settings_other">其他</string> <string name="settings_other">Other</string>
<string name="settings_night_mode">主题</string> <string name="settings_night_mode">Theme</string>
<string name="settings_offline_mode">离线模式</string> <string name="settings_offline_mode">Offline mode</string>
<string name="settings_offline_mode_summary">只手动同步</string> <string name="settings_offline_mode_summary">Only sync manually.</string>
<string name="settings_color_custom">自定义颜色</string> <string name="settings_color_custom">Custom color</string>
<string name="settings_color_mode">颜色选择</string> <string name="settings_color_mode">Color Selection</string>
<string name="settings_show_archived">显示存档项目</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">测试版功能</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">启用实验功能。请自行承担使用风险。</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">警告:\"http\"不安全。请使用“https://”。</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_colorpicker_title">选择颜色</string> <string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="pref_value_color_system">系统</string> <string name="settings_auto_sync_on_open">Sync interval</string>
<string name="pref_value_color_server">下个云端</string> <string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_color_manual">手动模式</string> <string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_theme_light">亮色的</string> <string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_theme_dark">深色</string> <string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_theme_system">关注系统</string> <string name="pref_value_sync_1d">1 day</string>
<!-- Constants (Do not translate) --> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string>
<string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string>
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">不重复</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">每天</string> <string name="repeat_day">Daily</string>
<string name="repeat_week">每周的</string> <string name="repeat_week">Weekly</string>
<string name="repeat_fortnight">每两周一次</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">每月的</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">每年一次</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none"></string>
<string name="payment_mode_all">所有的</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_credit_card">信用卡</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_cash">现金</string> <string name="payment_mode_credit_card">Credit card</string>
<string name="payment_mode_check">检查</string> <string name="payment_mode_cash">Cash</string>
<string name="payment_mode_online">在线</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_transfer">转移</string> <string name="payment_mode_online">Online</string>
<string name="category_none"></string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_all">所有的</string>
<string name="category_all_except_reimbursement">除偿还费用外的所有费用</string> <string name="category_none">None</string>
<string name="category_groceries">杂货店</string> <string name="category_all">All</string>
<string name="category_leisure">酒吧/Party</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
<string name="category_groceries">Grocery</string>
<string name="category_leisure">Bar/Party</string>
<string name="category_rent">Rent</string> <string name="category_rent">Rent</string>
<string name="category_bills">账单</string> <string name="category_bills">Bill</string>
<string name="category_excursion">游览/文化活动</string> <string name="category_excursion">Excursion/Culture</string>
<string name="category_health">保健</string> <string name="category_health">Health</string>
<string name="category_shopping">购物</string> <string name="category_shopping">Shopping</string>
<string name="category_reimbursement">补偿</string> <string name="category_reimbursement">Reimbursement</string>
<string name="category_restaurant">餐厅</string> <string name="category_restaurant">Restaurant</string>
<string name="category_accomodation">住宿</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">运输</string> <string name="category_transport">Transport</string>
<string name="category_sport">运动</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">什么</string> <string name="new_project_action">What</string>
<string name="new_project_where">位置</string> <string name="new_project_where">Where</string>
<string name="where_local">仅本地的</string> <string name="where_local">Local only</string>
<string name="where_cospend">费用</string> <string name="todo_join">Join existing project</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="todo_create">Create new project</string>
<string name="todo_join">加入现有的项目</string> <string name="import_tooltip">Import from file</string>
<string name="todo_create">创建新项目</string> <string name="choose_project_management_action">Project</string>
<string name="import_tooltip">从文件导入</string> <string name="project_added_success">Project added successfully.</string>
<string name="choose_account_project_dialog_title">选择项目</string> <string name="no_projects_text">You have no projects yet.</string>
<string name="choose_account_project_dialog_impossible">此帐户上没有找到项目。</string> <string name="configure_account_choice">Configure Nextcloud account</string>
<string name="choose_project_management_action">项目</string> <string name="add_project_choice">Add project manually</string>
<string name="project_added_success">项目添加成功。</string> <string name="no_members_text">No members in this project.</string>
<string name="no_projects_text">您还没有项目。</string> <string name="no_bills_text">No bills found.</string>
<string name="configure_account_choice">配置 Nextcloud 帐户</string> <string name="member_already_exists">Member already exists.</string>
<string name="add_project_choice">手动添加项目</string> <string name="activity_dialog_title">Project: %1$s</string>
<string name="no_members_text">此项目中没有成员。</string> <string name="remove_project_confirmation">Project %1$s removed.</string>
<string name="no_bills_text">未找到账单。</string> <string name="file_saved_success">File saved: %1$s</string>
<string name="member_already_exists">成员已经存在。</string> <string name="import_error_header">Import failed at row %d</string>
<string name="activity_dialog_title">项目: %1$s</string> <string name="import_error_date">Invalid date format at row %d</string>
<string name="remove_project_confirmation">项目 %1$s 已删除。</string> <string name="import_error_owers">Invalid owers at row %d</string>
<string name="file_saved_success">文件已保存: %1$s</string> <string name="add_member_dialog_title">Add Member</string>
<string name="import_error_header">在行 %d 导入失败</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="import_error_date">无效的日期格式在行 %d</string> <string name="member_edit_delete">Delete</string>
<string name="import_error_owers">在行 %d 上无效的owers</string> <string name="project_edition_no_change">No changes to save.</string>
<string name="add_member_dialog_title">添加成员</string>
<string name="edit_member_dialog_title">编辑成员</string>
<string name="member_edit_delete">删除</string>
<string name="project_edition_no_change">没有要保存的更改。</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">无 (最佳)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">谁支付</string> <string name="settle_who">Who pays</string>
<string name="settle_to_whom">给谁的</string> <string name="settle_to_whom">To whom</string>
<string name="settle_how_much">金额</string> <string name="settle_how_much">Amount</string>
<string name="simple_settle_share">分享</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">创建帐单</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">结算方式</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">选择货币 (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none"></string> <string name="setting_none">None</string>
<string name="setting_all">所有的</string> <string name="setting_all">All</string>
<string name="currency_saved_success">货币设置已保存。</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">主要货币</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">建议的类别</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">跳过</string> <string name="label_bills_skip">Skip</string>
<string name="stats_date_min">来自</string> <string name="stats_date_min">From</string>
<string name="stats_date_max">收件人</string> <string name="stats_date_max">To</string>
<string name="stats_who">成员</string> <string name="stats_who">Member</string>
<string name="stats_paid">已支付</string> <string name="stats_paid">Paid</string>
<string name="stats_spent">已使用</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">余额</string> <string name="stats_balance">Balance</string>
<string name="total">总计: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">连接失败: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">创建失败: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
<string name="error_edit_remote_project_helper">更新远程项目时出错: %1$s</string> <string name="error_edit_remote_project_helper">Error updating remote project: %1$s</string>
<string name="remote_project_operation_no_network">网络不可用于远程操作。</string> <string name="remote_project_operation_no_network">Network unavailable for remote operation.</string>
<string name="error_scanning_bill_qr_code">解析二维码失败。</string> <string name="error_scanning_bill_qr_code">Failed to parse QR code.</string>
<string name="error_token_mismatch">验证令牌不匹配。请重新登录。</string> <string name="error_token_mismatch">Authentication token mismatch. Please log in again.</string>
<string name="insufficient_access_level">您没有权限执行此操作。</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">删除标签</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">您确定要删除此标签吗?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">%1$s 版本</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">维护者</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">许可协议</string> <string name="about_license_title">License</string>
<string name="about_source_title">源代码</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">项目 %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">分享 %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+39 -8
View File
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string>
<!--
Untranslated: these are the English strings, kept here so a translation can be
contributed by simply replacing the values. Strings marked translatable="false" in
values/strings.xml (app and product names, preference keys) are deliberately absent
and must not be added.
-->
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">New bill</string> <string name="action_new_bill">New bill</string>
<string name="action_add_project">Add project</string> <string name="action_add_project">Add project</string>
@@ -8,7 +15,11 @@
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_open_menu">Open menu</string>
<string name="action_close_search">Close search</string>
<string name="action_clear_search">Clear search</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="simple_back">Back</string>
<string name="action_archive">Archive</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string> <string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string> <string name="action_export">Export</string>
@@ -23,6 +34,7 @@
<string name="action_members">Members</string> <string name="action_members">Members</string>
<string name="action_labels">Labels</string> <string name="action_labels">Labels</string>
<string name="action_currencies">Currencies</string> <string name="action_currencies">Currencies</string>
<!-- Titles --> <!-- Titles -->
<string name="title_stats">Statistics</string> <string name="title_stats">Statistics</string>
<string name="title_edit_project">Edit project</string> <string name="title_edit_project">Edit project</string>
@@ -38,6 +50,7 @@
<string name="title_share_web">Web link</string> <string name="title_share_web">Web link</string>
<string name="title_share_qr">Cowspent link</string> <string name="title_share_qr">Cowspent link</string>
<string name="title_confirm">Are you sure?</string> <string name="title_confirm">Are you sure?</string>
<!-- Labels and Fields --> <!-- Labels and Fields -->
<string name="label_all_bills">All bills</string> <string name="label_all_bills">All bills</string>
<string name="label_categories">Categories</string> <string name="label_categories">Categories</string>
@@ -61,6 +74,7 @@
<string name="label_project_id">Project ID/name</string> <string name="label_project_id">Project ID/name</string>
<string name="label_project_title">Project title</string> <string name="label_project_title">Project title</string>
<string name="label_use_sso">Use Nextcloud App Account</string> <string name="label_use_sso">Use Nextcloud App Account</string>
<!-- Dialogs and Messages --> <!-- Dialogs and Messages -->
<string name="dialog_unsaved_changes_title">Unsaved changes</string> <string name="dialog_unsaved_changes_title">Unsaved changes</string>
<string name="dialog_unsaved_changes_msg">Save changes before leaving?</string> <string name="dialog_unsaved_changes_msg">Save changes before leaving?</string>
@@ -81,6 +95,7 @@
<string name="msg_stats_intro">Stats for %1$s:</string> <string name="msg_stats_intro">Stats for %1$s:</string>
<string name="msg_stats_header">Member (Paid | Spent | Balance)</string> <string name="msg_stats_header">Member (Paid | Spent | Balance)</string>
<string name="msg_logged_in_as">Logged in as %1$s</string> <string name="msg_logged_in_as">Logged in as %1$s</string>
<!-- Errors --> <!-- Errors -->
<string name="error_generic">Error</string> <string name="error_generic">Error</string>
<string name="error_loading">Loading</string> <string name="error_loading">Loading</string>
@@ -109,6 +124,7 @@
<string name="error_server">Server error</string> <string name="error_server">Server error</string>
<string name="error_io">Server connection broken</string> <string name="error_io">Server connection broken</string>
<string name="error_share_impossible">Cannot share this project</string> <string name="error_share_impossible">Cannot share this project</string>
<!-- Drawer / Common UI --> <!-- Drawer / Common UI -->
<string name="drawer_no_account">Connect to Nextcloud account</string> <string name="drawer_no_account">Connect to Nextcloud account</string>
<string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string> <string name="drawer_last_sync">Last sync: %1$02d:%2$02d</string>
@@ -117,6 +133,7 @@
<string name="simple_yes">Yes</string> <string name="simple_yes">Yes</string>
<string name="simple_no">No</string> <string name="simple_no">No</string>
<string name="simple_close">Close</string> <string name="simple_close">Close</string>
<!-- Settings --> <!-- Settings -->
<string name="settings_appearance">Appearance</string> <string name="settings_appearance">Appearance</string>
<string name="settings_network">Network</string> <string name="settings_network">Network</string>
@@ -129,15 +146,23 @@
<string name="settings_show_archived">Show archived projects</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_url_warn_http">WARNING: \"http\" is unsafe. Use \"https\".</string> <string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string> <string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string> <string name="pref_value_theme_dark">Dark</string>
<string name="pref_value_theme_system">Follow system</string> <string name="pref_value_theme_system">Follow system</string>
<!-- Constants (Do not translate) -->
<!-- Enums and Lists --> <!-- Enums and Lists -->
<string name="repeat_no">No repeat</string> <string name="repeat_no">No repeat</string>
<string name="repeat_day">Daily</string> <string name="repeat_day">Daily</string>
@@ -145,6 +170,7 @@
<string name="repeat_fortnight">Fortnightly</string> <string name="repeat_fortnight">Fortnightly</string>
<string name="repeat_month">Monthly</string> <string name="repeat_month">Monthly</string>
<string name="repeat_year">Yearly</string> <string name="repeat_year">Yearly</string>
<string name="payment_mode_none">None</string> <string name="payment_mode_none">None</string>
<string name="payment_mode_all">All</string> <string name="payment_mode_all">All</string>
<string name="payment_mode_credit_card">Credit card</string> <string name="payment_mode_credit_card">Credit card</string>
@@ -152,6 +178,7 @@
<string name="payment_mode_check">Check</string> <string name="payment_mode_check">Check</string>
<string name="payment_mode_online">Online</string> <string name="payment_mode_online">Online</string>
<string name="payment_mode_transfer">Transfer</string> <string name="payment_mode_transfer">Transfer</string>
<string name="category_none">None</string> <string name="category_none">None</string>
<string name="category_all">All</string> <string name="category_all">All</string>
<string name="category_all_except_reimbursement">All except reimbursement</string> <string name="category_all_except_reimbursement">All except reimbursement</string>
@@ -167,17 +194,14 @@
<string name="category_accomodation">Accommodation</string> <string name="category_accomodation">Accommodation</string>
<string name="category_transport">Transport</string> <string name="category_transport">Transport</string>
<string name="category_sport">Sport</string> <string name="category_sport">Sport</string>
<!-- Project specific --> <!-- Project specific -->
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">Where</string> <string name="new_project_where">Where</string>
<string name="where_local">Local only</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string>
<string name="todo_join">Join existing project</string> <string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string> <string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string> <string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string> <string name="no_projects_text">You have no projects yet.</string>
@@ -196,6 +220,7 @@
<string name="edit_member_dialog_title">Edit Member</string> <string name="edit_member_dialog_title">Edit Member</string>
<string name="member_edit_delete">Delete</string> <string name="member_edit_delete">Delete</string>
<string name="project_edition_no_change">No changes to save.</string> <string name="project_edition_no_change">No changes to save.</string>
<!-- Settlement --> <!-- Settlement -->
<string name="center_none">None (Optimal)</string> <string name="center_none">None (Optimal)</string>
<string name="settle_who">Who pays</string> <string name="settle_who">Who pays</string>
@@ -204,12 +229,14 @@
<string name="simple_settle_share">Share</string> <string name="simple_settle_share">Share</string>
<string name="simple_create_bills">Create bills</string> <string name="simple_create_bills">Create bills</string>
<string name="settle_bill_what">Settlement</string> <string name="settle_bill_what">Settlement</string>
<!-- Currencies --> <!-- Currencies -->
<string name="currency_dialog_title">Choose Currency (%s)</string> <string name="currency_dialog_title">Choose Currency (%s)</string>
<string name="setting_none">None</string> <string name="setting_none">None</string>
<string name="setting_all">All</string> <string name="setting_all">All</string>
<string name="currency_saved_success">Currency settings saved.</string> <string name="currency_saved_success">Currency settings saved.</string>
<string name="main_currency">Main Currency</string> <string name="main_currency">Main Currency</string>
<!-- Statistics --> <!-- Statistics -->
<string name="label_bills_suggested">Suggested Categories</string> <string name="label_bills_suggested">Suggested Categories</string>
<string name="label_bills_skip">Skip</string> <string name="label_bills_skip">Skip</string>
@@ -220,6 +247,7 @@
<string name="stats_spent">Spent</string> <string name="stats_spent">Spent</string>
<string name="stats_balance">Balance</string> <string name="stats_balance">Balance</string>
<string name="total">Total: %1$s</string> <string name="total">Total: %1$s</string>
<!-- Errors Extra --> <!-- Errors Extra -->
<string name="error_project_connect_check">Connection failed: %1$s</string> <string name="error_project_connect_check">Connection failed: %1$s</string>
<string name="error_create_remote_project_helper">Creation failed: %1$s</string> <string name="error_create_remote_project_helper">Creation failed: %1$s</string>
@@ -230,12 +258,15 @@
<string name="insufficient_access_level">You don\'t have permission to perform this action.</string> <string name="insufficient_access_level">You don\'t have permission to perform this action.</string>
<string name="delete_label_confirmation_title">Delete Label</string> <string name="delete_label_confirmation_title">Delete Label</string>
<string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string> <string name="delete_label_confirmation_message">Are you sure you want to delete this label?</string>
<!-- About --> <!-- About -->
<string name="about_version">Version %1$s</string> <string name="about_version">Version %1$s</string>
<string name="about_maintainer_title">Maintainer</string> <string name="about_maintainer_title">Maintainer</string>
<string name="about_license_title">License</string> <string name="about_license_title">License</string>
<string name="about_source_title">Source code</string> <string name="about_source_title">Source code</string>
<!-- New constants for backward compatibility or shared use --> <!-- New constants for backward compatibility or shared use -->
<string name="share_intent_title">Project %1$s</string> <string name="share_intent_title">Project %1$s</string>
<string name="share_chooser_title">Share %1$s</string> <string name="share_chooser_title">Share %1$s</string>
</resources> </resources>
+21 -6
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Cowspent</string> <string name="app_name" translatable="false">Cowspent</string>
<!-- Actions --> <!-- Actions -->
<string name="action_new_bill">New bill</string> <string name="action_new_bill">New bill</string>
@@ -10,7 +10,11 @@
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="action_search">Search</string> <string name="action_search">Search</string>
<string name="action_open_menu">Open menu</string>
<string name="action_close_search">Close search</string>
<string name="action_clear_search">Clear search</string>
<string name="action_delete">Delete</string> <string name="action_delete">Delete</string>
<string name="simple_back">Back</string>
<string name="action_archive">Archive</string> <string name="action_archive">Archive</string>
<string name="action_unarchive">Unarchive</string> <string name="action_unarchive">Unarchive</string>
<string name="action_export">Export</string> <string name="action_export">Export</string>
@@ -137,11 +141,20 @@
<string name="settings_show_archived">Show archived projects</string> <string name="settings_show_archived">Show archived projects</string>
<string name="settings_beta_features">Beta Features</string> <string name="settings_beta_features">Beta Features</string>
<string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string> <string name="settings_beta_features_summary">Enable experimental features. Use at your own risk.</string>
<string name="settings_fill_new_bill_from_last">Auto-fill from last bill</string>
<string name="settings_fill_new_bill_from_last_summary">Pre-fill payer, category, mode and owers from the last bill created in the project.</string>
<string name="settings_stats_include_deactivated">Include deactivated members in stats</string>
<string name="settings_auto_sync_on_open">Sync interval</string>
<string name="settings_auto_sync_on_open_summary">How often to refresh the account and all projects when opening the app.</string>
<string name="pref_value_sync_1m">1 minute</string>
<string name="pref_value_sync_10m">10 minutes</string>
<string name="pref_value_sync_1h">1 hour</string>
<string name="pref_value_sync_1d">1 day</string>
<string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string> <string name="settings_url_warn_http">WARNING: "http" is unsafe. Use "https".</string>
<string name="settings_colorpicker_title">Choose Color</string> <string name="settings_colorpicker_title">Choose Color</string>
<string name="pref_value_color_system">System</string> <string name="pref_value_color_system">System</string>
<string name="pref_value_color_server">Nextcloud</string> <string name="pref_value_color_server" translatable="false">Nextcloud</string>
<string name="pref_value_color_manual">Manual</string> <string name="pref_value_color_manual">Manual</string>
<string name="pref_value_theme_light">Light</string> <string name="pref_value_theme_light">Light</string>
<string name="pref_value_theme_dark">Dark</string> <string name="pref_value_theme_dark">Dark</string>
@@ -158,6 +171,10 @@
<string name="pref_key_offline_mode" translatable="false">offlineMode</string> <string name="pref_key_offline_mode" translatable="false">offlineMode</string>
<string name="pref_key_show_archived" translatable="false">showArchived</string> <string name="pref_key_show_archived" translatable="false">showArchived</string>
<string name="pref_key_beta_features" translatable="false">betaFeatures</string> <string name="pref_key_beta_features" translatable="false">betaFeatures</string>
<string name="pref_key_stats_include_deactivated" translatable="false">statsIncludeDeactivated</string>
<string name="pref_key_auto_sync_on_open" translatable="false">autoSyncOnOpen</string>
<string name="pref_key_last_account_sync_timestamp" translatable="false">lastAccountSyncTimestamp</string>
<string name="pref_key_fill_new_bill_from_last" translatable="false">fillNewBillFromLast</string>
<string name="pref_value_night_mode_no" translatable="false">1</string> <string name="pref_value_night_mode_no" translatable="false">1</string>
<string name="pref_value_night_mode_yes" translatable="false">2</string> <string name="pref_value_night_mode_yes" translatable="false">2</string>
<string name="pref_value_night_mode_system" translatable="false">-1</string> <string name="pref_value_night_mode_system" translatable="false">-1</string>
@@ -198,13 +215,11 @@
<string name="new_project_action">What</string> <string name="new_project_action">What</string>
<string name="new_project_where">Where</string> <string name="new_project_where">Where</string>
<string name="where_local">Local only</string> <string name="where_local">Local only</string>
<string name="where_cospend">Cospend</string> <string name="where_cospend" translatable="false">Cospend</string>
<string name="where_ihatemoney">IHateMoney</string> <string name="where_ihatemoney" translatable="false">IHateMoney</string>
<string name="todo_join">Join existing project</string> <string name="todo_join">Join existing project</string>
<string name="todo_create">Create new project</string> <string name="todo_create">Create new project</string>
<string name="import_tooltip">Import from file</string> <string name="import_tooltip">Import from file</string>
<string name="choose_account_project_dialog_title">Choose project</string>
<string name="choose_account_project_dialog_impossible">No projects found on this account.</string>
<string name="choose_project_management_action">Project</string> <string name="choose_project_management_action">Project</string>
<string name="project_added_success">Project added successfully.</string> <string name="project_added_success">Project added successfully.</string>
<string name="no_projects_text">You have no projects yet.</string> <string name="no_projects_text">You have no projects yet.</string>
@@ -0,0 +1,39 @@
package net.helcel.cowspent
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.InternalComposeUiApi
import androidx.compose.ui.platform.InfiniteAnimationPolicy
import androidx.compose.ui.platform.WindowRecomposerFactory
import androidx.compose.ui.platform.WindowRecomposerPolicy
import androidx.compose.ui.platform.createLifecycleAwareWindowRecomposer
import kotlinx.coroutines.CancellationException
import org.junit.rules.TestWatcher
import org.junit.runner.Description
/**
* Robolectric's paused looper only goes idle once nothing is left to run, but a Compose infinite
* animation (the pull-to-refresh spinner, for instance) keeps requesting frames forever. Any test
* that launches an activity whose UI shows one then burns minutes of CPU inside
* ActivityScenario.launch() before it gives up.
*
* ComposeTestRule solves this by installing an InfiniteAnimationPolicy that cancels those
* animations; this rule does the same for tests driving an activity directly.
*/
@OptIn(ExperimentalComposeUiApi::class, InternalComposeUiApi::class)
class NoInfiniteAnimationsRule : TestWatcher() {
private object CancelInfiniteAnimations : InfiniteAnimationPolicy {
override suspend fun <R> onInfiniteOperation(block: suspend () -> R): R =
throw CancellationException("Infinite animations are disabled in unit tests")
}
override fun starting(description: Description) {
WindowRecomposerPolicy.setFactory { view ->
view.createLifecycleAwareWindowRecomposer(CancelInfiniteAnimations)
}
}
override fun finished(description: Description) {
WindowRecomposerPolicy.setFactory(WindowRecomposerFactory.LifecycleAware)
}
}
@@ -0,0 +1,86 @@
package net.helcel.cowspent.android
import androidx.compose.runtime.Composable
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.*
import net.helcel.cowspent.NoInfiniteAnimationsRule
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
/**
* Every `@Preview` in the app, rendered once.
*
* Previews are compiled into the release APK and are the only caller of some composables with
* awkward argument shapes, so a preview that throws is a real compile-time-clean runtime break that
* nothing else would catch. This is a smoke test: it asserts the tree composed, not what it looks
* like the behaviour of each screen is covered by that screen's own tests.
*/
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [34], qualifiers = "w1080dp-h2400dp")
class PreviewsTest {
@get:Rule
val composeTestRule = createComposeRule()
@get:Rule
val noInfiniteAnimations = NoInfiniteAnimationsRule()
private fun renders(preview: @Composable () -> Unit) {
composeTestRule.setContent { preview() }
composeTestRule.waitForIdle()
composeTestRule.onRoot().assertExists()
}
@Test fun testBillItemRow() = renders { net.helcel.cowspent.android.main.BillItemRowPreview() }
@Test fun testSectionHeader() = renders { net.helcel.cowspent.android.main.SectionHeaderPreview() }
@Test fun testEmptyProjectsState() = renders { net.helcel.cowspent.android.main.EmptyProjectsStatePreview() }
@Test fun testEmptyMembersState() = renders { net.helcel.cowspent.android.main.EmptyMembersStatePreview() }
@Test fun testEmptyBillsState() = renders { net.helcel.cowspent.android.main.EmptyBillsStatePreview() }
@Test fun testEditBillScreen() = renders { net.helcel.cowspent.android.bill_edit.EditBillScreenPreview() }
@Test fun testEditBillScreenWeighted() = renders { net.helcel.cowspent.android.bill_edit.EditBillScreenWeightedPreview() }
@Test fun testEditBillScreenCustom() = renders { net.helcel.cowspent.android.bill_edit.EditBillScreenCustomPreview() }
@Test fun testEditBillScreenPercent() = renders { net.helcel.cowspent.android.bill_edit.EditBillScreenPercentPreview() }
@Test fun testUserAvatar() = renders { net.helcel.cowspent.android.helper.UserAvatarPreview() }
@Test fun testUserAvatarCustomColor() = renders { net.helcel.cowspent.android.helper.UserAvatarCustomColorPreview() }
@Test fun testUserAvatarDisabled() = renders { net.helcel.cowspent.android.helper.UserAvatarDisabledPreview() }
@Test fun testProjectSettlementUI() = renders { net.helcel.cowspent.android.project.settle.ProjectSettlementUIPreview() }
@Test fun testProjectSettlementUIBalanced() = renders { net.helcel.cowspent.android.project.settle.ProjectSettlementUIBalancedPreview() }
@Test fun testLabelManagementCategories() = renders { net.helcel.cowspent.android.label.LabelManagementCategoriesPreview() }
@Test fun testLabelManagementPaymentModes() = renders { net.helcel.cowspent.android.label.LabelManagementPaymentModesPreview() }
@Test fun testDrawerItem() = renders { net.helcel.cowspent.android.drawer.DrawerItemPreview() }
@Test fun testDrawer() = renders { net.helcel.cowspent.android.drawer.DrawerPreview() }
@Test fun testCurrencyRow() = renders { net.helcel.cowspent.android.currencies.CurrencyRowPreview() }
@Test fun testManageCurrenciesScreen() = renders { net.helcel.cowspent.android.currencies.ManageCurrenciesScreenPreview() }
@Test fun testProjectStatisticsTable() = renders { net.helcel.cowspent.android.statistics.ProjectStatisticsTablePreview() }
@Test fun testProjectSpendingGraph() = renders { net.helcel.cowspent.android.statistics.ProjectSpendingGraphPreview() }
@Test fun testProjectSankeyDiagram() = renders { net.helcel.cowspent.android.statistics.ProjectSankeyDiagramPreview() }
@Test fun testProjectShareDialogContent() = renders { net.helcel.cowspent.android.project.ProjectShareDialogContentPreview() }
@Test fun testMemberManagementScreen() = renders { net.helcel.cowspent.android.project.member.MemberManagementScreenPreview() }
@Test fun testMemberEditDialogContent() = renders { net.helcel.cowspent.android.project.member.MemberEditDialogContentPreview() }
@Test fun testMemberAddDialogContent() = renders { net.helcel.cowspent.android.project.member.MemberAddDialogContentPreview() }
@Test fun testEditProjectScreen() = renders { net.helcel.cowspent.android.project.edit.EditProjectScreenPreview() }
@Test fun testNewProjectScreen() = renders { net.helcel.cowspent.android.project.create.NewProjectScreenPreview() }
@Test fun testColorPicker() = renders { net.helcel.cowspent.android.helper.ColorPickerPreview() }
@Test fun testLabelBillsScreen() = renders { net.helcel.cowspent.android.bill_label.LabelBillsScreenPreview() }
@Test fun testAccountScreen() = renders { net.helcel.cowspent.android.account.AccountScreenPreview() }
@Test fun testAboutScreen() = renders { net.helcel.cowspent.android.about.AboutScreenPreview() }
@Test fun testSimpleAlertDialog() = renders { net.helcel.cowspent.android.helper.SimpleAlertDialogPreview() }
@Test fun testConfirmationDialog() = renders { net.helcel.cowspent.android.helper.ConfirmationDialogPreview() }
@Test fun testListDialogWithIcons() = renders { net.helcel.cowspent.android.helper.ListDialogWithIconsPreview() }
/** Opens a real database, so it is the one preview that needs a Robolectric context to exist. */
@Test fun testBillsListScreen() = renders { net.helcel.cowspent.android.main.BillsListScreenPreview() }
}
+4 -2
View File
@@ -19,10 +19,12 @@ org.gradle.dependency.verification.console=verbose
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit # This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true org.gradle.parallel=true
android.useAndroidX=true android.useAndroidX=true
android.nonTransitiveRClass=false android.nonTransitiveRClass=false
org.gradle.warning.mode=all org.gradle.warning.mode=all
android.uniquePackageNames=false android.uniquePackageNames=false
android.dependency.useConstraints=false android.dependency.useConstraints=false
android.r8.strictFullModeForKeepRules=false android.r8.strictFullModeForKeepRules=false
# Enabled parallel sync for Gradle 9.4+
org.gradle.tooling.parallel=true
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip
networkTimeout=10000 networkTimeout=10000
retries=0 retries=0
retryBackOffMs=500 retryBackOffMs=500
Vendored
+5 -8
View File
@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# Copyright © 2015-2021 the original authors. # Copyright © 2015 the original authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
############################################################################## ##############################################################################
# #
# Gradle start up script for POSIX generated by Gradle. # gradlew start up script for POSIX generated by Gradle.
# #
# Important for running: # Important for running:
# #
@@ -29,7 +29,7 @@
# bash, then to run this script, type that shell name before the whole # bash, then to run this script, type that shell name before the whole
# command line, like: # command line, like:
# #
# ksh Gradle # ksh gradlew
# #
# Busybox and similar reduced shells will NOT work, because this script # Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features: # requires all of these POSIX shell features:
@@ -57,7 +57,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@@ -114,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;; NONSTOP* ) nonstop=true ;;
esac esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
@@ -172,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" ) JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -212,8 +210,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
org.gradle.wrapper.GradleWrapperMain \
"$@" "$@"
# Stop when "xargs" is not available. # Stop when "xargs" is not available.
Vendored
+12 -24
View File
@@ -19,12 +19,12 @@
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem gradlew startup script for Windows
@rem @rem
@rem ########################################################################## @rem ##########################################################################
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables, and ensure extensions are enabled
if "%OS%"=="Windows_NT" setlocal setlocal EnableExtensions
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@@ -51,7 +51,7 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2 echo location of your Java installation. 1>&2
goto fail "%COMSPEC%" /c exit 1
:findJavaFromJavaHome :findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
@@ -65,30 +65,18 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2 echo location of your Java installation. 1>&2
goto fail "%COMSPEC%" /c exit 1
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute gradlew
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* @rem endlocal doesn't take effect until after the line is parsed and variables are expanded
@rem which allows us to clear the local environment before executing the java command
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
:end :exitWithErrorLevel
@rem End local scope for the variables with windows NT shell @rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
if %ERRORLEVEL% equ 0 goto mainEnd "%COMSPEC%" /c exit %ERRORLEVEL%
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
+3
View File
@@ -6,6 +6,9 @@ pluginManagement {
maven { url = 'https://jitpack.io' } maven { url = 'https://jitpack.io' }
} }
} }
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
}
dependencyResolutionManagement { dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories { repositories {