mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2025-12-25 08:07:56 -05:00
Compare commits
318 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ca4d29a36 | ||
|
|
2efb666fae | ||
|
|
89dce1068f | ||
|
|
9854125af9 | ||
|
|
6e307ab1f0 | ||
|
|
c4f0d1bef6 | ||
|
|
5201788818 | ||
|
|
8472bc9755 | ||
|
|
ce0f531831 | ||
|
|
18e9c3ccb5 | ||
|
|
19afe8e69c | ||
|
|
8e5bace7cc | ||
|
|
1ca85e9d7b | ||
|
|
eb24af8266 | ||
|
|
12ba01eb87 | ||
|
|
a0e30bdccc | ||
|
|
4663e22128 | ||
|
|
7bd1d16d24 | ||
|
|
fd838cfd43 | ||
|
|
1eca79b4cb | ||
|
|
1d694f5f2c | ||
|
|
96a046b165 | ||
|
|
5ff9c9c469 | ||
|
|
836cdd87bc | ||
|
|
0af6dd4d44 | ||
|
|
034d62a643 | ||
|
|
417224602e | ||
|
|
c711aeae7f | ||
|
|
1f12543e3e | ||
|
|
dc31175b5d | ||
|
|
719b8112eb | ||
|
|
f19a3c507b | ||
|
|
2416ec396a | ||
|
|
d1fe92e967 | ||
|
|
ff5fd49b89 | ||
|
|
1015e0d94e | ||
|
|
d872828e7d | ||
|
|
8f6ad6d1bd | ||
|
|
05fd629ad4 | ||
|
|
efdb0dd6bb | ||
|
|
2e0482beef | ||
|
|
0f25743da4 | ||
|
|
e970bf185a | ||
|
|
60f3547b01 | ||
|
|
ae09db428b | ||
|
|
ebca7ca150 | ||
|
|
b6ef6806a0 | ||
|
|
20a9cb30c4 | ||
|
|
a43112f469 | ||
|
|
2a95b2f530 | ||
|
|
cb979bfbec | ||
|
|
feabe353b0 | ||
|
|
7987932100 | ||
|
|
e496c69e15 | ||
|
|
e0300f8f21 | ||
|
|
64cbcb2ef7 | ||
|
|
7e24f02a73 | ||
|
|
ed89eab782 | ||
|
|
17863e8920 | ||
|
|
6e82e6fc5d | ||
|
|
64b1103f13 | ||
|
|
e4274df941 | ||
|
|
c786b4b5a7 | ||
|
|
95405270cb | ||
|
|
9ef8eb2934 | ||
|
|
4f70b06edb | ||
|
|
5677aa2b38 | ||
|
|
44997e1bbd | ||
|
|
a96c569314 | ||
|
|
5545220d53 | ||
|
|
4f47ee30ba | ||
|
|
4f9f318960 | ||
|
|
5dcfcf0ad0 | ||
|
|
eb809974c4 | ||
|
|
815b037be7 | ||
|
|
3eff150835 | ||
|
|
e191e8bbe6 | ||
|
|
5aaf135325 | ||
|
|
6fd4f617e5 | ||
|
|
621e4ce162 | ||
|
|
bf07e8935f | ||
|
|
e69d6a453b | ||
|
|
579c2fc640 | ||
|
|
ba870481dd | ||
|
|
0c10936e75 | ||
|
|
26cf4250ad | ||
|
|
a8d5f38d5c | ||
|
|
5e1bac4bcf | ||
|
|
6df8b7b1ea | ||
|
|
964c603405 | ||
|
|
f64eea6470 | ||
|
|
aa97ad49d2 | ||
|
|
6221da72f8 | ||
|
|
fe8ec38bf3 | ||
|
|
7324353d74 | ||
|
|
c5f0ee3a66 | ||
|
|
a8b4b25afb | ||
|
|
9744ede674 | ||
|
|
43505d427d | ||
|
|
65e54c63ef | ||
|
|
31b306d432 | ||
|
|
25bd1de09d | ||
|
|
c82e0d82a9 | ||
|
|
6625488d84 | ||
|
|
a1f632ace3 | ||
|
|
b9ea7fd1ed | ||
|
|
8dff8d392e | ||
|
|
b10d50d5a0 | ||
|
|
0b54d87f4f | ||
|
|
a9568d6adb | ||
|
|
18c5aa4707 | ||
|
|
f53c61bbec | ||
|
|
25c9c67ca2 | ||
|
|
2efbf664c9 | ||
|
|
44023969a7 | ||
|
|
0e5216b010 | ||
|
|
f258506936 | ||
|
|
8bad342374 | ||
|
|
476a219bec | ||
|
|
24e19e26ba | ||
|
|
3cb16ae3e9 | ||
|
|
c7ddf957fa | ||
|
|
0de8cd93ad | ||
|
|
614e5bac2d | ||
|
|
e76bd9363c | ||
|
|
97c508c920 | ||
|
|
0f178c1cac | ||
|
|
8eab852e1a | ||
|
|
539f8846d8 | ||
|
|
fb239b6974 | ||
|
|
85b553e17b | ||
|
|
f085f1e9e6 | ||
|
|
56b387c725 | ||
|
|
daf0cdaa71 | ||
|
|
6a7bebdbcd | ||
|
|
7f72c3bcaf | ||
|
|
52bff53756 | ||
|
|
73743b7f1e | ||
|
|
acfcd3d2d2 | ||
|
|
24e8d12b73 | ||
|
|
28068dcddc | ||
|
|
3e5ab76636 | ||
|
|
3dceec8ec0 | ||
|
|
0cc409d087 | ||
|
|
346acfa3f5 | ||
|
|
8d48da431e | ||
|
|
b913fad847 | ||
|
|
c900642f8e | ||
|
|
c7d0da9e20 | ||
|
|
f66b368cc2 | ||
|
|
4dad96472f | ||
|
|
01bb4f0fc4 | ||
|
|
9ae5d74c7c | ||
|
|
5af6d9b61c | ||
|
|
eb89a04c72 | ||
|
|
1019e40987 | ||
|
|
175d860885 | ||
|
|
de8aa6b6fd | ||
|
|
a5a7be02f6 | ||
|
|
14b7f8af81 | ||
|
|
62d01abf92 | ||
|
|
a328fa8f4a | ||
|
|
9e55271db1 | ||
|
|
e09ba941b8 | ||
|
|
7562b662b7 | ||
|
|
ce65163377 | ||
|
|
da445255ec | ||
|
|
fb36aecf42 | ||
|
|
3d624eae97 | ||
|
|
0a05676a87 | ||
|
|
bce6ae0da6 | ||
|
|
2268465d2e | ||
|
|
7a9953cfee | ||
|
|
ecc11c120b | ||
|
|
f4d4e3d6fb | ||
|
|
929633e4dd | ||
|
|
eec7359603 | ||
|
|
4168ec3b43 | ||
|
|
6568ebb01c | ||
|
|
99e2a75d46 | ||
|
|
43ae42c7c5 | ||
|
|
a7aa3e9e0e | ||
|
|
5a9f0a44fd | ||
|
|
4a1858e47b | ||
|
|
d8d8a59707 | ||
|
|
b027beea35 | ||
|
|
b4d0651e99 | ||
|
|
b40380dff6 | ||
|
|
b1a0a98004 | ||
|
|
044d363f47 | ||
|
|
35d659be31 | ||
|
|
8bc1e2d321 | ||
|
|
b8811ba053 | ||
|
|
cbaf172e9d | ||
|
|
78c831cb68 | ||
|
|
279e775fb6 | ||
|
|
e5b30c9528 | ||
|
|
eb9732658f | ||
|
|
5feb59612d | ||
|
|
09bd9b3882 | ||
|
|
beb619000c | ||
|
|
72425dd39e | ||
|
|
a93d240d9a | ||
|
|
d380e284b1 | ||
|
|
cbbb434aae | ||
|
|
6dc8490b5e | ||
|
|
b2c57258b3 | ||
|
|
fe0ae4049b | ||
|
|
0517a7514e | ||
|
|
39544ac853 | ||
|
|
f46e1d09ba | ||
|
|
6421f09eab | ||
|
|
45663065f9 | ||
|
|
67328724fa | ||
|
|
55373e82a5 | ||
|
|
acdb5d6fe7 | ||
|
|
d9461c476a | ||
|
|
deee5f6aa2 | ||
|
|
efd2b1ffe1 | ||
|
|
a87d8bbfe4 | ||
|
|
a1d5275063 | ||
|
|
e327306955 | ||
|
|
9469ae37e1 | ||
|
|
9e2d65b2cd | ||
|
|
d509c06815 | ||
|
|
70faa7636a | ||
|
|
4072bc7607 | ||
|
|
eced502985 | ||
|
|
47441dbb9a | ||
|
|
e7729d9763 | ||
|
|
df40b72f77 | ||
|
|
1a1c028565 | ||
|
|
5cd77c3a25 | ||
|
|
369631d00c | ||
|
|
350031624c | ||
|
|
846f4d4904 | ||
|
|
5081eb2dce | ||
|
|
e964fda54a | ||
|
|
aaa4fc1ef3 | ||
|
|
93331e1a27 | ||
|
|
3251a6266b | ||
|
|
d3f8399cbe | ||
|
|
7c805128a7 | ||
|
|
a40c4841da | ||
|
|
768ac795ff | ||
|
|
e8460d52ec | ||
|
|
03a7efb52e | ||
|
|
48b60d8b4d | ||
|
|
562b830e5a | ||
|
|
ac810a0c6f | ||
|
|
27a90615a9 | ||
|
|
f894427247 | ||
|
|
8b7df8dabe | ||
|
|
d66903f972 | ||
|
|
7834a93394 | ||
|
|
572378de85 | ||
|
|
26e0c50a13 | ||
|
|
cd638a96f3 | ||
|
|
4e043edb64 | ||
|
|
1067d09773 | ||
|
|
d347cdde3e | ||
|
|
b704a7492e | ||
|
|
4c28d5d181 | ||
|
|
47e50de063 | ||
|
|
3777abc2a3 | ||
|
|
01554381b2 | ||
|
|
09ca9c47ab | ||
|
|
6751befe5d | ||
|
|
91661f1059 | ||
|
|
afe47f1b84 | ||
|
|
9bcbfc6d81 | ||
|
|
89a40a789d | ||
|
|
e60814d6f3 | ||
|
|
ed8028a22b | ||
|
|
bb106f185e | ||
|
|
18c4dd4dc9 | ||
|
|
72672e99c2 | ||
|
|
73067d1fe8 | ||
|
|
5e6a4c8184 | ||
|
|
310228fb5e | ||
|
|
5aef382b68 | ||
|
|
9fa78a4ea8 | ||
|
|
400867b03f | ||
|
|
b06c6bc94d | ||
|
|
d6c48bdf6e | ||
|
|
4d11391f8a | ||
|
|
8b0490fdf3 | ||
|
|
6ec23d976b | ||
|
|
11ed56ee11 | ||
|
|
4ded73f78e | ||
|
|
588f8ef677 | ||
|
|
3d70095862 | ||
|
|
410309ebd2 | ||
|
|
b9e646a25d | ||
|
|
81c1ec9199 | ||
|
|
4498d08afb | ||
|
|
963789db25 | ||
|
|
902fbc505d | ||
|
|
9889678e53 | ||
|
|
ac551ed93f | ||
|
|
ec63931396 | ||
|
|
d29d6ddf4a | ||
|
|
38aac76144 | ||
|
|
30de0a8266 | ||
|
|
0016b40256 | ||
|
|
aa3588dbfe | ||
|
|
bf7ddc023d | ||
|
|
e50cf66bca | ||
|
|
85c30185e8 | ||
|
|
5bce259445 | ||
|
|
8504109399 | ||
|
|
e182857e1b | ||
|
|
981c0b9ca6 | ||
|
|
925f62b633 | ||
|
|
cceb1207ae | ||
|
|
2e633b19dc | ||
|
|
b8b1074a46 | ||
|
|
bea65793f0 |
3
.github/workflows/android.yml
vendored
3
.github/workflows/android.yml
vendored
@@ -13,6 +13,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
- name: set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
@@ -27,7 +28,7 @@ jobs:
|
||||
run: ./gradlew spotbugsRelease
|
||||
- name: Archive test results
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: test-results
|
||||
path: app/build/reports
|
||||
|
||||
73
CHANGELOG.md
73
CHANGELOG.md
@@ -1,5 +1,78 @@
|
||||
# Changelog
|
||||
|
||||
## v2.0.4 (2021-07-27)
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix shortcut creation
|
||||
- Generate card-specific shortcut icon
|
||||
- Fix ability to change loyalty card colour
|
||||
|
||||
## v2.0.3 (2021-07-25)
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix loading photos when editing existing card
|
||||
|
||||
## v2.0.2 (2021-07-25)
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix inability to configure photos in new loyalty card
|
||||
|
||||
## v2.0.1 (2021-07-21)
|
||||
|
||||
Changes:
|
||||
|
||||
- Several minor translation and UI fixes
|
||||
- Fix crash in import/sharing loyalty card on Android 6
|
||||
|
||||
## v2.0 (2021-07-14)
|
||||
|
||||
Breaking changes:
|
||||
- The backup format changed, see https://github.com/TheLastProject/Catima/wiki/Export-format
|
||||
- The URL sharing format changed, see https://github.com/TheLastProject/Catima/wiki/Card-sharing-URL-format
|
||||
|
||||
Changes:
|
||||
|
||||
- Make it possible to enable or disable the flashlight while scanning
|
||||
- Add UPC-E support
|
||||
- Support adding a front and back photo to each card
|
||||
- Support importing password-protected zip files
|
||||
- Support importing from Stocard (Beta)
|
||||
- Fix useless whitespace in notes from Fidme import
|
||||
- Support new Voucher Vault export format
|
||||
- Fix Floating Action Buttons being behind other UI elements on Android 4
|
||||
- Fix loyalty card viewer appbar top margin
|
||||
|
||||
## v1.14.1 (2021-06-14)
|
||||
|
||||
Changes:
|
||||
|
||||
- Add missing barcode ID to export
|
||||
- Don't show update barcode dialog if value is the same as card ID
|
||||
- Add Finnish translation
|
||||
|
||||
## v1.14 (2021-06-07)
|
||||
|
||||
Changes:
|
||||
|
||||
- Support new PDF417 export from Voucher Vault
|
||||
- Support copying multiple barcodes at once
|
||||
- Support sharing multiple loyalty cards at once
|
||||
- Ask to update barcode value if card ID changes
|
||||
|
||||
## v1.13 (2021-04-10)
|
||||
|
||||
Changes:
|
||||
|
||||
- Add option to set a separate barcode value from card ID
|
||||
- Simplify font sizing configuration
|
||||
- Several small UI fixes
|
||||
- Use letter icon for shortcuts too
|
||||
- Always show all barcode types in manual entry
|
||||
- Remove privacy policy first start dialog
|
||||
|
||||
## v1.12 (2021-03-30)
|
||||
|
||||
Changes:
|
||||
|
||||
@@ -2,7 +2,7 @@ GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.2)
|
||||
addressable (2.7.0)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.1.0)
|
||||
|
||||
@@ -11,15 +11,15 @@ spotbugs {
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "me.hackerchick.catima"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 66
|
||||
versionName "1.12"
|
||||
targetSdkVersion 30
|
||||
versionCode 74
|
||||
versionName "2.0.4"
|
||||
|
||||
vectorDrawables.useSupportLibrary true
|
||||
}
|
||||
@@ -47,6 +47,12 @@ android {
|
||||
"MissingTranslation", "MissingPrefix"
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
test {
|
||||
resources.srcDirs += ['src/test/res']
|
||||
}
|
||||
}
|
||||
|
||||
// Starting with Android Studio 3 Robolectric is unable to find resources.
|
||||
// The following allows it to find the resources.
|
||||
testOptions {
|
||||
@@ -63,24 +69,29 @@ android {
|
||||
|
||||
dependencies {
|
||||
// AndroidX
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation 'androidx.preference:preference:1.1.1'
|
||||
implementation 'com.google.android.material:material:1.2.1'
|
||||
implementation 'io.wcm.tooling.spotbugs:io.wcm.tooling.spotbugs.annotations:1.0.0'
|
||||
implementation 'com.google.android.material:material:1.4.0'
|
||||
|
||||
// Third-party
|
||||
implementation 'com.journeyapps:zxing-android-embedded:4.1.0@aar'
|
||||
implementation 'com.google.zxing:core:3.3.3' // Do not upgrade past 3.3.3! Causes a crash on versions before Android 7
|
||||
// Do not upgrade past 3.3.3! Causes a crash on versions before Android Nougat
|
||||
//noinspection GradleDependency
|
||||
implementation 'com.google.zxing:core:3.3.3'
|
||||
implementation 'org.apache.commons:commons-csv:1.8'
|
||||
implementation 'com.jaredrummler:colorpicker:1.1.0'
|
||||
implementation 'com.google.guava:guava:30.1-jre'
|
||||
implementation 'com.github.invissvenska:NumberPickerPreference:1.0.1'
|
||||
implementation 'com.google.guava:guava:30.1.1-jre'
|
||||
implementation 'com.github.invissvenska:NumberPickerPreference:1.0.2'
|
||||
implementation 'net.lingala.zip4j:zip4j:2.8.0'
|
||||
|
||||
// SpotBugs
|
||||
implementation 'io.wcm.tooling.spotbugs:io.wcm.tooling.spotbugs.annotations:1.0.0'
|
||||
|
||||
// Testing
|
||||
testImplementation 'androidx.test:core:1.0.0'
|
||||
testImplementation 'junit:junit:4.13.1'
|
||||
testImplementation 'androidx.test:core:1.4.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.robolectric:robolectric:4.4'
|
||||
}
|
||||
|
||||
|
||||
@@ -60,13 +60,16 @@
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<!-- Accepts URIs that begin with "https://github.com/brarcher/loyalty-card-locker/” -->
|
||||
<!-- Listen to known card sharing URIs -->
|
||||
<data android:scheme="https"
|
||||
android:host="@string/intent_import_card_from_url_host"
|
||||
android:pathPrefix="@string/intent_import_card_from_url_path_prefix" />
|
||||
android:host="@string/intent_import_card_from_url_host_catima_app"
|
||||
android:pathPrefix="@string/intent_import_card_from_url_path_prefix_catima_app" />
|
||||
<data android:scheme="https"
|
||||
android:host="@string/intent_import_card_from_url_host_old"
|
||||
android:pathPrefix="@string/intent_import_card_from_url_path_prefix_old" />
|
||||
android:host="@string/intent_import_card_from_url_host_thelastproject"
|
||||
android:pathPrefix="@string/intent_import_card_from_url_path_prefix_thelastproject" />
|
||||
<data android:scheme="https"
|
||||
android:host="@string/intent_import_card_from_url_host_brarcher"
|
||||
android:pathPrefix="@string/intent_import_card_from_url_path_prefix_brarcher" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
|
||||
@@ -8,10 +8,9 @@ import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
@@ -35,30 +34,28 @@ public class AboutActivity extends AppCompatActivity
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
final Map<String, String> USED_LIBRARIES = new ImmutableMap.Builder<String, String>()
|
||||
.put("Commons CSV", "https://commons.apache.org/proper/commons-csv/")
|
||||
.put("Guava", "https://github.com/google/guava")
|
||||
.put("ZXing", "https://github.com/zxing/zxing")
|
||||
.put("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded")
|
||||
.put("Color Picker", "https://github.com/jaredrummler/ColorPicker")
|
||||
.put("NumberPickerPreference", "https://github.com/invissvenska/NumberPickerPreference")
|
||||
.build();
|
||||
final List<ThirdPartyInfo> USED_LIBRARIES = new ArrayList<>();
|
||||
USED_LIBRARIES.add(new ThirdPartyInfo("Color Picker", "https://github.com/jaredrummler/ColorPicker", "Apache 2.0"));
|
||||
USED_LIBRARIES.add(new ThirdPartyInfo("Commons CSV", "https://commons.apache.org/proper/commons-csv/", "Apache 2.0"));
|
||||
USED_LIBRARIES.add(new ThirdPartyInfo("Guava", "https://github.com/google/guava", "Apache 2.0"));
|
||||
USED_LIBRARIES.add(new ThirdPartyInfo("NumberPickerPreference", "https://github.com/invissvenska/NumberPickerPreference", "GNU LGPL 3.0"));
|
||||
USED_LIBRARIES.add(new ThirdPartyInfo("Zip4j", "https://github.com/srikanth-lingala/zip4j", "Apache 2.0"));
|
||||
USED_LIBRARIES.add(new ThirdPartyInfo("ZXing", "https://github.com/zxing/zxing", "Apache 2.0"));
|
||||
USED_LIBRARIES.add(new ThirdPartyInfo("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded", "Apache 2.0"));
|
||||
|
||||
final Map<String, String> USED_ASSETS = ImmutableMap.of
|
||||
(
|
||||
"Android icons", "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
);
|
||||
final List<ThirdPartyInfo> USED_ASSETS = new ArrayList<>();
|
||||
USED_ASSETS.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0"));
|
||||
|
||||
StringBuilder libs = new StringBuilder().append("<br/>");
|
||||
for (Map.Entry<String, String> entry : USED_LIBRARIES.entrySet())
|
||||
for (ThirdPartyInfo entry : USED_LIBRARIES)
|
||||
{
|
||||
libs.append("<br/><a href=\"").append(entry.getValue()).append("\">").append(entry.getKey()).append("</a><br/>");
|
||||
libs.append("<br/><a href=\"").append(entry.url()).append("\">").append(entry.name()).append("</a> (").append(entry.license()).append(")<br/>");
|
||||
}
|
||||
|
||||
StringBuilder resources = new StringBuilder().append("<br/>");
|
||||
for (Map.Entry<String, String> entry : USED_ASSETS.entrySet())
|
||||
for (ThirdPartyInfo entry : USED_ASSETS)
|
||||
{
|
||||
resources.append("<br/><a href=\"").append(entry.getValue()).append("\">").append(entry.getKey()).append("</a><br/>");
|
||||
resources.append("<br/><a href=\"").append(entry.url()).append("\">").append(entry.name()).append("</a> (").append(entry.license()).append(")<br/>");
|
||||
}
|
||||
|
||||
String appName = getString(R.string.app_name);
|
||||
@@ -91,9 +88,9 @@ public class AboutActivity extends AppCompatActivity
|
||||
"<br/><br/>" +
|
||||
getString(R.string.app_license) +
|
||||
"<br/><br/>" +
|
||||
String.format(getString(R.string.app_libraries), appName, libs.toString()) +
|
||||
String.format(getString(R.string.app_libraries), libs.toString()) +
|
||||
"<br/><br/>" +
|
||||
String.format(getString(R.string.app_resources), appName, resources.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT));
|
||||
String.format(getString(R.string.app_resources), resources.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT));
|
||||
aboutTextView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
|
||||
@@ -108,4 +105,4 @@ public class AboutActivity extends AppCompatActivity
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@@ -23,6 +25,9 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
{
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
private static final int IS_VALID = 999;
|
||||
private boolean isSuccesful;
|
||||
|
||||
// When drawn in a smaller window 1D barcodes for some reason end up
|
||||
// squished, whereas 2D barcodes look fine.
|
||||
private static final int MAX_WIDTH_1D = 1500;
|
||||
@@ -30,14 +35,20 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
|
||||
private final WeakReference<ImageView> imageViewReference;
|
||||
private final WeakReference<TextView> textViewReference;
|
||||
private final String cardId;
|
||||
private String cardId;
|
||||
private final BarcodeFormat format;
|
||||
private final int imageHeight;
|
||||
private final int imageWidth;
|
||||
private final boolean showFallback;
|
||||
private final Runnable callback;
|
||||
|
||||
BarcodeImageWriterTask(ImageView imageView, String cardIdString,
|
||||
BarcodeFormat barcodeFormat, TextView textView)
|
||||
BarcodeFormat barcodeFormat, TextView textView,
|
||||
boolean showFallback, Runnable callback)
|
||||
{
|
||||
isSuccesful = true;
|
||||
this.callback = callback;
|
||||
|
||||
// Use a WeakReference to ensure the ImageView can be garbage collected
|
||||
imageViewReference = new WeakReference<>(imageView);
|
||||
textViewReference = new WeakReference<>(textView);
|
||||
@@ -59,11 +70,8 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
double ratio = (double)MAX_WIDTH / (double)imageView.getWidth();
|
||||
imageHeight = (int)(imageView.getHeight() * ratio);
|
||||
}
|
||||
}
|
||||
|
||||
BarcodeImageWriterTask(ImageView imageView, String cardIdString, BarcodeFormat barcodeFormat)
|
||||
{
|
||||
this(imageView, cardIdString, barcodeFormat, null);
|
||||
this.showFallback = showFallback;
|
||||
}
|
||||
|
||||
private int getMaxWidth(BarcodeFormat format)
|
||||
@@ -96,7 +104,43 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
}
|
||||
}
|
||||
|
||||
public Bitmap doInBackground(Void... params)
|
||||
private String getFallbackString(BarcodeFormat format)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
// 2D barcodes
|
||||
case AZTEC:
|
||||
return "AZTEC";
|
||||
case DATA_MATRIX:
|
||||
return "DATA_MATRIX";
|
||||
case PDF_417:
|
||||
return "PDF_417";
|
||||
case QR_CODE:
|
||||
return "QR_CODE";
|
||||
|
||||
// 1D barcodes:
|
||||
case CODABAR:
|
||||
return "C0C";
|
||||
case CODE_39:
|
||||
return "CODE_39";
|
||||
case CODE_128:
|
||||
return "CODE_128";
|
||||
case EAN_8:
|
||||
return "32123456";
|
||||
case EAN_13:
|
||||
return "5901234123457";
|
||||
case ITF:
|
||||
return "1003";
|
||||
case UPC_A:
|
||||
return "123456789012";
|
||||
case UPC_E:
|
||||
return "0123456";
|
||||
default:
|
||||
throw new IllegalArgumentException("No fallback known for this barcode type");
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap generate()
|
||||
{
|
||||
if (cardId.isEmpty())
|
||||
{
|
||||
@@ -165,13 +209,30 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
catch(OutOfMemoryError e)
|
||||
{
|
||||
Log.w(TAG, "Insufficient memory to render barcode, "
|
||||
+ imageWidth + "x" + imageHeight + ", " + format.name()
|
||||
+ ", length=" + cardId.length(), e);
|
||||
+ imageWidth + "x" + imageHeight + ", " + format.name()
|
||||
+ ", length=" + cardId.length(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Bitmap doInBackground(Void... params)
|
||||
{
|
||||
Bitmap bitmap = generate();
|
||||
|
||||
if (bitmap == null) {
|
||||
isSuccesful = false;
|
||||
|
||||
if (showFallback) {
|
||||
Log.i(TAG, "Barcode generation failed, generating fallback...");
|
||||
cardId = getFallbackString(format);
|
||||
bitmap = generate();
|
||||
}
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Bitmap result)
|
||||
{
|
||||
Log.i(TAG, "Finished generating barcode image of type " + format + ": " + cardId);
|
||||
@@ -182,6 +243,8 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
return;
|
||||
}
|
||||
|
||||
imageView.setTag(isSuccesful);
|
||||
|
||||
imageView.setImageBitmap(result);
|
||||
TextView textView = textViewReference.get();
|
||||
|
||||
@@ -190,6 +253,12 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
Log.i(TAG, "Displaying barcode");
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
|
||||
if (isSuccesful) {
|
||||
imageView.setColorFilter(null);
|
||||
} else {
|
||||
imageView.setColorFilter(Color.LTGRAY, PorterDuff.Mode.LIGHTEN);
|
||||
}
|
||||
|
||||
if (textView != null) {
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
textView.setText(format.name());
|
||||
@@ -203,5 +272,9 @@ class BarcodeImageWriterTask extends AsyncTask<Void, Void, Bitmap>
|
||||
textView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,6 @@ import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
@@ -17,6 +14,7 @@ import android.view.ViewTreeObserver;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
@@ -27,6 +25,10 @@ import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
/**
|
||||
* This activity is callable and will allow a user to enter
|
||||
* barcode data and generate all barcodes possible for
|
||||
@@ -56,7 +58,8 @@ public class BarcodeSelectorActivity extends AppCompatActivity
|
||||
BarcodeFormat.ITF.name(),
|
||||
BarcodeFormat.PDF_417.name(),
|
||||
BarcodeFormat.QR_CODE.name(),
|
||||
BarcodeFormat.UPC_A.name()
|
||||
BarcodeFormat.UPC_A.name(),
|
||||
BarcodeFormat.UPC_E.name()
|
||||
));
|
||||
|
||||
private Map<String, Pair<Integer, Integer>> barcodeViewMap;
|
||||
@@ -88,6 +91,7 @@ public class BarcodeSelectorActivity extends AppCompatActivity
|
||||
.put(BarcodeFormat.PDF_417.name(), new Pair<>(R.id.pdf417Barcode, R.id.pdf417BarcodeText))
|
||||
.put(BarcodeFormat.QR_CODE.name(), new Pair<>(R.id.qrcodeBarcode, R.id.qrcodeBarcodeText))
|
||||
.put(BarcodeFormat.UPC_A.name(), new Pair<>(R.id.upcaBarcode, R.id.upcaBarcodeText))
|
||||
.put(BarcodeFormat.UPC_E.name(), new Pair<>(R.id.upceBarcode, R.id.upceBarcodeText))
|
||||
.build();
|
||||
|
||||
EditText cardId = findViewById(R.id.cardId);
|
||||
@@ -104,20 +108,7 @@ public class BarcodeSelectorActivity extends AppCompatActivity
|
||||
{
|
||||
Log.d(TAG, "Entered text: " + s);
|
||||
|
||||
// Stop any async tasks which may not have been started yet
|
||||
for(AsyncTask task : barcodeGeneratorTasks)
|
||||
{
|
||||
task.cancel(false);
|
||||
}
|
||||
barcodeGeneratorTasks.clear();
|
||||
|
||||
// Update barcodes
|
||||
for(String key : barcodeViewMap.keySet())
|
||||
{
|
||||
ImageView image = findViewById(barcodeViewMap.get(key).first);
|
||||
TextView text = findViewById(barcodeViewMap.get(key).second);
|
||||
createBarcodeOption(image, key, s.toString(), text);
|
||||
}
|
||||
generateBarcodes(s.toString());
|
||||
|
||||
View noBarcodeButtonView = findViewById(R.id.noBarcode);
|
||||
setButtonListener(noBarcodeButtonView, s.toString());
|
||||
@@ -137,6 +128,25 @@ public class BarcodeSelectorActivity extends AppCompatActivity
|
||||
if(initialCardId != null)
|
||||
{
|
||||
cardId.setText(initialCardId);
|
||||
} else {
|
||||
generateBarcodes("");
|
||||
}
|
||||
}
|
||||
|
||||
private void generateBarcodes(String value) {
|
||||
// Stop any async tasks which may not have been started yet
|
||||
for(AsyncTask task : barcodeGeneratorTasks)
|
||||
{
|
||||
task.cancel(false);
|
||||
}
|
||||
barcodeGeneratorTasks.clear();
|
||||
|
||||
// Update barcodes
|
||||
for(Map.Entry<String, Pair<Integer, Integer>> entry : barcodeViewMap.entrySet())
|
||||
{
|
||||
ImageView image = findViewById(entry.getValue().first);
|
||||
TextView text = findViewById(entry.getValue().second);
|
||||
createBarcodeOption(image, entry.getKey(), value, text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +181,12 @@ public class BarcodeSelectorActivity extends AppCompatActivity
|
||||
public void onClick(View v)
|
||||
{
|
||||
Log.d(TAG, "Selected barcode type " + formatType);
|
||||
|
||||
if (!((boolean) image.getTag())) {
|
||||
Toast.makeText(BarcodeSelectorActivity.this, getString(R.string.wrongValueForBarcodeType), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Intent result = new Intent();
|
||||
result.putExtra(BARCODE_FORMAT, formatType);
|
||||
result.putExtra(BARCODE_CONTENTS, cardId);
|
||||
@@ -193,7 +209,7 @@ public class BarcodeSelectorActivity extends AppCompatActivity
|
||||
image.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
|
||||
Log.d(TAG, "Generating barcode for type " + formatType);
|
||||
BarcodeImageWriterTask task = new BarcodeImageWriterTask(image, cardId, format, text);
|
||||
BarcodeImageWriterTask task = new BarcodeImageWriterTask(image, cardId, format, text, true, null);
|
||||
barcodeGeneratorTasks.add(task);
|
||||
task.execute();
|
||||
}
|
||||
@@ -202,7 +218,7 @@ public class BarcodeSelectorActivity extends AppCompatActivity
|
||||
else
|
||||
{
|
||||
Log.d(TAG, "Generating barcode for type " + formatType);
|
||||
BarcodeImageWriterTask task = new BarcodeImageWriterTask(image, cardId, format, text);
|
||||
BarcodeImageWriterTask task = new BarcodeImageWriterTask(image, cardId, format, text, true, null);
|
||||
barcodeGeneratorTasks.add(task);
|
||||
task.execute();
|
||||
}
|
||||
|
||||
87
app/src/main/java/protect/card_locker/BaseCursorAdapter.java
Normal file
87
app/src/main/java/protect/card_locker/BaseCursorAdapter.java
Normal file
@@ -0,0 +1,87 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public abstract class BaseCursorAdapter<V extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<V>
|
||||
{
|
||||
private Cursor mCursor;
|
||||
private boolean mDataValid;
|
||||
private int mRowIDColumn;
|
||||
|
||||
public BaseCursorAdapter(Cursor inputCursor)
|
||||
{
|
||||
setHasStableIds(true);
|
||||
swapCursor(inputCursor);
|
||||
}
|
||||
|
||||
public abstract void onBindViewHolder(V inputHolder, Cursor inputCursor);
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(V inputHolder, int inputPosition)
|
||||
{
|
||||
if (!mDataValid)
|
||||
{
|
||||
throw new IllegalStateException("Cannot bind view holder when cursor is in invalid state.");
|
||||
}
|
||||
|
||||
if (!mCursor.moveToPosition(inputPosition))
|
||||
{
|
||||
throw new IllegalStateException("Could not move cursor to position " + inputPosition + " when trying to bind view holder");
|
||||
}
|
||||
|
||||
onBindViewHolder(inputHolder, mCursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount()
|
||||
{
|
||||
if (mDataValid)
|
||||
{
|
||||
return mCursor.getCount();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int inputPosition)
|
||||
{
|
||||
if (!mDataValid)
|
||||
{
|
||||
throw new IllegalStateException("Cannot lookup item id when cursor is in invalid state.");
|
||||
}
|
||||
|
||||
if (!mCursor.moveToPosition(inputPosition))
|
||||
{
|
||||
throw new IllegalStateException("Could not move cursor to position " + inputPosition + " when trying to get an item id");
|
||||
}
|
||||
|
||||
return mCursor.getLong(mRowIDColumn);
|
||||
}
|
||||
|
||||
public void swapCursor(Cursor inputCursor)
|
||||
{
|
||||
if (inputCursor == mCursor)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputCursor != null)
|
||||
{
|
||||
mCursor = inputCursor;
|
||||
mDataValid = true;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
notifyItemRangeRemoved(0, getItemCount());
|
||||
mCursor = null;
|
||||
mRowIDColumn = -1;
|
||||
mDataValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,26 +2,30 @@ package protect.card_locker;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* The configuration screen for creating a shortcut.
|
||||
*/
|
||||
public class CardShortcutConfigure extends AppCompatActivity
|
||||
public class CardShortcutConfigure extends AppCompatActivity implements LoyaltyCardCursorAdapter.CardAdapterListener
|
||||
{
|
||||
static final String TAG = "Catima";
|
||||
final DBHelper mDb = new DBHelper(this);
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle bundle)
|
||||
{
|
||||
public void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
|
||||
// Set the result to CANCELED. This will cause nothing to happen if the
|
||||
@@ -32,52 +36,72 @@ public class CardShortcutConfigure extends AppCompatActivity
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
toolbar.setVisibility(View.GONE);
|
||||
|
||||
// Hide new button because it won't work here anyway
|
||||
FloatingActionButton newFab = findViewById(R.id.fabAdd);
|
||||
newFab.setVisibility(View.GONE);
|
||||
|
||||
final DBHelper db = new DBHelper(this);
|
||||
|
||||
// If there are no cards, bail
|
||||
if(db.getLoyaltyCardCount() == 0)
|
||||
{
|
||||
if (db.getLoyaltyCardCount() == 0) {
|
||||
Toast.makeText(this, R.string.noCardsMessage, Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
}
|
||||
|
||||
final ListView cardList = findViewById(R.id.list);
|
||||
final RecyclerView cardList = findViewById(R.id.list);
|
||||
|
||||
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
|
||||
cardList.setLayoutManager(mLayoutManager);
|
||||
cardList.setItemAnimator(new DefaultItemAnimator());
|
||||
|
||||
cardList.setVisibility(View.VISIBLE);
|
||||
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor();
|
||||
|
||||
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor);
|
||||
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor, this);
|
||||
cardList.setAdapter(adapter);
|
||||
}
|
||||
|
||||
cardList.setOnItemClickListener(new AdapterView.OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
Cursor selected = (Cursor) parent.getItemAtPosition(position);
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
|
||||
private void onClickAction(int position) {
|
||||
Cursor selected = mDb.getLoyaltyCardCursor();
|
||||
selected.moveToPosition(position);
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
|
||||
|
||||
Log.d(TAG, "Creating shortcut for card " + loyaltyCard.store + "," + loyaltyCard.id);
|
||||
Log.d(TAG, "Creating shortcut for card " + loyaltyCard.store + "," + loyaltyCard.id);
|
||||
|
||||
Intent shortcutIntent = new Intent(CardShortcutConfigure.this, LoyaltyCardViewActivity.class);
|
||||
shortcutIntent.setAction(Intent.ACTION_MAIN);
|
||||
// Prevent instances of the view activity from piling up; if one exists let this
|
||||
// one replace it.
|
||||
shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("id", loyaltyCard.id);
|
||||
bundle.putBoolean("view", true);
|
||||
shortcutIntent.putExtras(bundle);
|
||||
Intent shortcutIntent = new Intent(CardShortcutConfigure.this, LoyaltyCardViewActivity.class);
|
||||
shortcutIntent.setAction(Intent.ACTION_MAIN);
|
||||
// Prevent instances of the view activity from piling up; if one exists let this
|
||||
// one replace it.
|
||||
shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("id", loyaltyCard.id);
|
||||
bundle.putBoolean("view", true);
|
||||
shortcutIntent.putExtras(bundle);
|
||||
|
||||
Parcelable icon = Intent.ShortcutIconResource.fromContext(CardShortcutConfigure.this, R.mipmap.ic_launcher);
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, loyaltyCard.store);
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
|
||||
setResult(RESULT_OK, intent);
|
||||
Bitmap iconBitmap = Utils.generateIcon(CardShortcutConfigure.this, loyaltyCard, true).getLetterTile();
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, loyaltyCard.store);
|
||||
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, iconBitmap);
|
||||
setResult(RESULT_OK, intent);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIconClicked(int inputPosition) {
|
||||
onClickAction(inputPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRowClicked(int inputPosition) {
|
||||
onClickAction(inputPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRowLongClicked(int inputPosition) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,19 +6,21 @@ import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DBHelper extends SQLiteOpenHelper
|
||||
{
|
||||
public static final String DATABASE_NAME = "Catima.db";
|
||||
public static final int ORIGINAL_DATABASE_VERSION = 1;
|
||||
public static final int DATABASE_VERSION = 8;
|
||||
public static final int DATABASE_VERSION = 10;
|
||||
|
||||
public static class LoyaltyCardDbGroups
|
||||
{
|
||||
@@ -39,6 +41,7 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
public static final String HEADER_COLOR = "headercolor";
|
||||
public static final String HEADER_TEXT_COLOR = "headertextcolor";
|
||||
public static final String CARD_ID = "cardid";
|
||||
public static final String BARCODE_ID = "barcodeid";
|
||||
public static final String BARCODE_TYPE = "barcodetype";
|
||||
public static final String STAR_STATUS = "starstatus";
|
||||
}
|
||||
@@ -50,9 +53,13 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
public static final String groupID = "groupId";
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
|
||||
public DBHelper(Context context)
|
||||
{
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,10 +80,10 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
LoyaltyCardDbIds.BALANCE + " TEXT not null DEFAULT '0'," +
|
||||
LoyaltyCardDbIds.BALANCE_TYPE + " TEXT," +
|
||||
LoyaltyCardDbIds.HEADER_COLOR + " INTEGER," +
|
||||
LoyaltyCardDbIds.HEADER_TEXT_COLOR + " INTEGER," +
|
||||
LoyaltyCardDbIds.CARD_ID + " TEXT not null," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " TEXT not null," +
|
||||
LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0' )");
|
||||
LoyaltyCardDbIds.BARCODE_ID + " TEXT," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " TEXT," +
|
||||
LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0')");
|
||||
|
||||
// create associative table for cards in groups
|
||||
db.execSQL("create table " + LoyaltyCardDbIdsGroups.TABLE + "(" +
|
||||
@@ -143,12 +150,113 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbIds.BALANCE_TYPE + " TEXT");
|
||||
}
|
||||
|
||||
if(oldVersion < 9 && newVersion >= 9)
|
||||
{
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbIds.BARCODE_ID + " TEXT");
|
||||
}
|
||||
|
||||
if(oldVersion < 10 && newVersion >= 10)
|
||||
{
|
||||
// SQLite doesn't support modify column
|
||||
// So we need to create a temp column to make barcode type nullable
|
||||
// Let's drop header text colour too while we're at it
|
||||
// https://www.sqlite.org/faq.html#q11
|
||||
db.beginTransaction();
|
||||
|
||||
db.execSQL("CREATE TEMPORARY TABLE tmp (" +
|
||||
LoyaltyCardDbIds.ID + " INTEGER primary key autoincrement," +
|
||||
LoyaltyCardDbIds.STORE + " TEXT not null," +
|
||||
LoyaltyCardDbIds.NOTE + " TEXT not null," +
|
||||
LoyaltyCardDbIds.EXPIRY + " INTEGER," +
|
||||
LoyaltyCardDbIds.BALANCE + " TEXT not null DEFAULT '0'," +
|
||||
LoyaltyCardDbIds.BALANCE_TYPE + " TEXT," +
|
||||
LoyaltyCardDbIds.HEADER_COLOR + " INTEGER," +
|
||||
LoyaltyCardDbIds.CARD_ID + " TEXT not null," +
|
||||
LoyaltyCardDbIds.BARCODE_ID + " TEXT," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " TEXT," +
|
||||
LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0' )");
|
||||
|
||||
db.execSQL("INSERT INTO tmp (" +
|
||||
LoyaltyCardDbIds.ID + " ," +
|
||||
LoyaltyCardDbIds.STORE + " ," +
|
||||
LoyaltyCardDbIds.NOTE + " ," +
|
||||
LoyaltyCardDbIds.EXPIRY + " ," +
|
||||
LoyaltyCardDbIds.BALANCE + " ," +
|
||||
LoyaltyCardDbIds.BALANCE_TYPE + " ," +
|
||||
LoyaltyCardDbIds.HEADER_COLOR + " ," +
|
||||
LoyaltyCardDbIds.CARD_ID + " ," +
|
||||
LoyaltyCardDbIds.BARCODE_ID + " ," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " ," +
|
||||
LoyaltyCardDbIds.STAR_STATUS + ")" +
|
||||
" SELECT " +
|
||||
LoyaltyCardDbIds.ID + " ," +
|
||||
LoyaltyCardDbIds.STORE + " ," +
|
||||
LoyaltyCardDbIds.NOTE + " ," +
|
||||
LoyaltyCardDbIds.EXPIRY + " ," +
|
||||
LoyaltyCardDbIds.BALANCE + " ," +
|
||||
LoyaltyCardDbIds.BALANCE_TYPE + " ," +
|
||||
LoyaltyCardDbIds.HEADER_COLOR + " ," +
|
||||
LoyaltyCardDbIds.CARD_ID + " ," +
|
||||
LoyaltyCardDbIds.BARCODE_ID + " ," +
|
||||
" NULLIF(" + LoyaltyCardDbIds.BARCODE_TYPE + ",'') ," +
|
||||
LoyaltyCardDbIds.STAR_STATUS +
|
||||
" FROM " + LoyaltyCardDbIds.TABLE);
|
||||
|
||||
db.execSQL("DROP TABLE " + LoyaltyCardDbIds.TABLE);
|
||||
|
||||
db.execSQL("create table " + LoyaltyCardDbIds.TABLE + "(" +
|
||||
LoyaltyCardDbIds.ID + " INTEGER primary key autoincrement," +
|
||||
LoyaltyCardDbIds.STORE + " TEXT not null," +
|
||||
LoyaltyCardDbIds.NOTE + " TEXT not null," +
|
||||
LoyaltyCardDbIds.EXPIRY + " INTEGER," +
|
||||
LoyaltyCardDbIds.BALANCE + " TEXT not null DEFAULT '0'," +
|
||||
LoyaltyCardDbIds.BALANCE_TYPE + " TEXT," +
|
||||
LoyaltyCardDbIds.HEADER_COLOR + " INTEGER," +
|
||||
LoyaltyCardDbIds.CARD_ID + " TEXT not null," +
|
||||
LoyaltyCardDbIds.BARCODE_ID + " TEXT," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " TEXT," +
|
||||
LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0' )");
|
||||
|
||||
db.execSQL("INSERT INTO " + LoyaltyCardDbIds.TABLE + "(" +
|
||||
LoyaltyCardDbIds.ID + " ," +
|
||||
LoyaltyCardDbIds.STORE + " ," +
|
||||
LoyaltyCardDbIds.NOTE + " ," +
|
||||
LoyaltyCardDbIds.EXPIRY + " ," +
|
||||
LoyaltyCardDbIds.BALANCE + " ," +
|
||||
LoyaltyCardDbIds.BALANCE_TYPE + " ," +
|
||||
LoyaltyCardDbIds.HEADER_COLOR + " ," +
|
||||
LoyaltyCardDbIds.CARD_ID + " ," +
|
||||
LoyaltyCardDbIds.BARCODE_ID + " ," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " ," +
|
||||
LoyaltyCardDbIds.STAR_STATUS + ")" +
|
||||
" SELECT " +
|
||||
LoyaltyCardDbIds.ID + " ," +
|
||||
LoyaltyCardDbIds.STORE + " ," +
|
||||
LoyaltyCardDbIds.NOTE + " ," +
|
||||
LoyaltyCardDbIds.EXPIRY + " ," +
|
||||
LoyaltyCardDbIds.BALANCE + " ," +
|
||||
LoyaltyCardDbIds.BALANCE_TYPE + " ," +
|
||||
LoyaltyCardDbIds.HEADER_COLOR + " ," +
|
||||
LoyaltyCardDbIds.CARD_ID + " ," +
|
||||
LoyaltyCardDbIds.BARCODE_ID + " ," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " ," +
|
||||
LoyaltyCardDbIds.STAR_STATUS +
|
||||
" FROM tmp");
|
||||
|
||||
db.execSQL("DROP TABLE tmp");
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
public long insertLoyaltyCard(final String store, final String note, final Date expiry,
|
||||
final BigDecimal balance, final Currency balanceType,
|
||||
final String cardId, final String barcodeType,
|
||||
final Integer headerColor, final int starStatus)
|
||||
final String cardId, final String barcodeId,
|
||||
final BarcodeFormat barcodeType, final Integer headerColor,
|
||||
final int starStatus)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
@@ -158,19 +266,19 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
contentValues.put(LoyaltyCardDbIds.BALANCE, balance.toString());
|
||||
contentValues.put(LoyaltyCardDbIds.BALANCE_TYPE, balanceType != null ? balanceType.getCurrencyCode() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_ID, barcodeId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType != null ? barcodeType.toString() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_TEXT_COLOR, Color.WHITE);
|
||||
contentValues.put(LoyaltyCardDbIds.STAR_STATUS, starStatus);
|
||||
final long newId = db.insert(LoyaltyCardDbIds.TABLE, null, contentValues);
|
||||
return newId;
|
||||
}
|
||||
|
||||
public boolean insertLoyaltyCard(final SQLiteDatabase db, final String store,
|
||||
public long insertLoyaltyCard(final SQLiteDatabase db, final String store,
|
||||
final String note, final Date expiry, final BigDecimal balance,
|
||||
final Currency balanceType, final String cardId,
|
||||
final String barcodeType, final Integer headerColor,
|
||||
final int starStatus)
|
||||
final String barcodeId, final BarcodeFormat barcodeType,
|
||||
final Integer headerColor, final int starStatus)
|
||||
{
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbIds.STORE, store);
|
||||
@@ -179,19 +287,19 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
contentValues.put(LoyaltyCardDbIds.BALANCE, balance.toString());
|
||||
contentValues.put(LoyaltyCardDbIds.BALANCE_TYPE, balanceType != null ? balanceType.getCurrencyCode() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_ID, barcodeId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType != null ? barcodeType.toString() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_TEXT_COLOR, Color.WHITE);
|
||||
contentValues.put(LoyaltyCardDbIds.STAR_STATUS,starStatus);
|
||||
final long newId = db.insert(LoyaltyCardDbIds.TABLE, null, contentValues);
|
||||
return (newId != -1);
|
||||
return newId;
|
||||
}
|
||||
|
||||
public boolean insertLoyaltyCard(final SQLiteDatabase db, final int id, final String store,
|
||||
public long insertLoyaltyCard(final SQLiteDatabase db, final int id, final String store,
|
||||
final String note, final Date expiry, final BigDecimal balance,
|
||||
final Currency balanceType, final String cardId,
|
||||
final String barcodeType, final Integer headerColor,
|
||||
final int starStatus)
|
||||
final String barcodeId, final BarcodeFormat barcodeType,
|
||||
final Integer headerColor, final int starStatus)
|
||||
{
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbIds.ID, id);
|
||||
@@ -201,18 +309,19 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
contentValues.put(LoyaltyCardDbIds.BALANCE, balance.toString());
|
||||
contentValues.put(LoyaltyCardDbIds.BALANCE_TYPE, balanceType != null ? balanceType.getCurrencyCode() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_ID, barcodeId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType != null ? barcodeType.toString() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_TEXT_COLOR, Color.WHITE);
|
||||
contentValues.put(LoyaltyCardDbIds.STAR_STATUS,starStatus);
|
||||
final long newId = db.insert(LoyaltyCardDbIds.TABLE, null, contentValues);
|
||||
return (newId != -1);
|
||||
return newId;
|
||||
}
|
||||
|
||||
public boolean updateLoyaltyCard(final int id, final String store, final String note,
|
||||
final Date expiry, final BigDecimal balance,
|
||||
final Currency balanceType, final String cardId,
|
||||
final String barcodeType, final Integer headerColor)
|
||||
final String barcodeId, final BarcodeFormat barcodeType,
|
||||
final Integer headerColor)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
@@ -222,9 +331,9 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
contentValues.put(LoyaltyCardDbIds.BALANCE, balance.toString());
|
||||
contentValues.put(LoyaltyCardDbIds.BALANCE_TYPE, balanceType != null ? balanceType.getCurrencyCode() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_ID, barcodeId);
|
||||
contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType != null ? barcodeType.toString() : null);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_COLOR, headerColor);
|
||||
contentValues.put(LoyaltyCardDbIds.HEADER_TEXT_COLOR, Color.WHITE);
|
||||
int rowsUpdated = db.update(LoyaltyCardDbIds.TABLE, contentValues,
|
||||
LoyaltyCardDbIds.ID + "=?",
|
||||
new String[]{Integer.toString(id)});
|
||||
@@ -322,7 +431,7 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
}
|
||||
}
|
||||
|
||||
public boolean deleteLoyaltyCard (final int id)
|
||||
public boolean deleteLoyaltyCard(final int id)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
// Delete card
|
||||
@@ -335,6 +444,14 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
LoyaltyCardDbIdsGroups.cardID + " = ? ",
|
||||
new String[]{String.format("%d", id)});
|
||||
|
||||
// Also wipe card images associated with this card
|
||||
try {
|
||||
Utils.saveCardImage(mContext, null, id, true);
|
||||
Utils.saveCardImage(mContext, null, id, false);
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return (rowsDeleted == 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class GroupCursorAdapter extends CursorAdapter
|
||||
|
||||
countField.setText(context.getResources().getQuantityString(R.plurals.groupCardCount, groupCardCount, groupCardCount));
|
||||
|
||||
nameField.setTextSize(settings.getCardTitleListFontSize());
|
||||
countField.setTextSize(settings.getCardNoteListFontSize());
|
||||
nameField.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
|
||||
countField.setTextSize(settings.getFontSizeMax(settings.getSmallFont()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,19 +8,12 @@ import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import android.provider.ContactsContract;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
@@ -29,7 +22,17 @@ import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import protect.card_locker.importexport.DataFormat;
|
||||
import protect.card_locker.importexport.ImportExportResult;
|
||||
|
||||
public class ImportExportActivity extends AppCompatActivity
|
||||
{
|
||||
@@ -75,8 +78,8 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
// Check that there is a file manager available
|
||||
final Intent intentCreateDocumentAction = new Intent(Intent.ACTION_CREATE_DOCUMENT);
|
||||
intentCreateDocumentAction.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intentCreateDocumentAction.setType("text/csv");
|
||||
intentCreateDocumentAction.putExtra(Intent.EXTRA_TITLE, "Catima.csv");
|
||||
intentCreateDocumentAction.setType("application/zip");
|
||||
intentCreateDocumentAction.putExtra(Intent.EXTRA_TITLE, "catima.zip");
|
||||
|
||||
Button exportButton = findViewById(R.id.exportButton);
|
||||
exportButton.setOnClickListener(new View.OnClickListener()
|
||||
@@ -118,9 +121,22 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
}
|
||||
|
||||
private void chooseImportType(Intent baseIntent) {
|
||||
List<CharSequence> betaImportOptions = new ArrayList<>();
|
||||
betaImportOptions.add("Fidme");
|
||||
betaImportOptions.add("Stocard");
|
||||
List<CharSequence> importOptions = new ArrayList<>();
|
||||
|
||||
for (String importOption : getResources().getStringArray(R.array.import_types_array)) {
|
||||
if (betaImportOptions.contains(importOption)) {
|
||||
importOption = importOption + " (BETA)";
|
||||
}
|
||||
|
||||
importOptions.add(importOption);
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.chooseImportType)
|
||||
.setItems(R.array.import_types_array, (dialog, which) -> {
|
||||
.setItems(importOptions.toArray(new CharSequence[importOptions.size()]), (dialog, which) -> {
|
||||
switch (which) {
|
||||
// Catima
|
||||
case 0:
|
||||
@@ -140,8 +156,14 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
importAlertMessage = getString(R.string.importLoyaltyCardKeychainMessage);
|
||||
importDataFormat = DataFormat.Catima;
|
||||
break;
|
||||
// Voucher Vault
|
||||
// Stocard
|
||||
case 3:
|
||||
importAlertTitle = getString(R.string.importStocard);
|
||||
importAlertMessage = getString(R.string.importStocardMessage);
|
||||
importDataFormat = DataFormat.Stocard;
|
||||
break;
|
||||
// Voucher Vault
|
||||
case 4:
|
||||
importAlertTitle = getString(R.string.importVoucherVault);
|
||||
importAlertMessage = getString(R.string.importVoucherVaultMessage);
|
||||
importDataFormat = DataFormat.VoucherVault;
|
||||
@@ -165,19 +187,19 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void startImport(final InputStream target, final Uri targetUri, final DataFormat dataFormat)
|
||||
private void startImport(final InputStream target, final Uri targetUri, final DataFormat dataFormat, final char[] password)
|
||||
{
|
||||
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener()
|
||||
{
|
||||
@Override
|
||||
public void onTaskComplete(boolean success)
|
||||
public void onTaskComplete(ImportExportResult result, DataFormat dataFormat)
|
||||
{
|
||||
onImportComplete(success, targetUri);
|
||||
onImportComplete(result, targetUri, dataFormat);
|
||||
}
|
||||
};
|
||||
|
||||
importExporter = new ImportExportTask(ImportExportActivity.this,
|
||||
dataFormat, target, listener);
|
||||
dataFormat, target, password, listener);
|
||||
importExporter.execute();
|
||||
}
|
||||
|
||||
@@ -186,9 +208,9 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
ImportExportTask.TaskCompleteListener listener = new ImportExportTask.TaskCompleteListener()
|
||||
{
|
||||
@Override
|
||||
public void onTaskComplete(boolean success)
|
||||
public void onTaskComplete(ImportExportResult result, DataFormat dataFormat)
|
||||
{
|
||||
onExportComplete(success, targetUri);
|
||||
onExportComplete(result, targetUri);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -198,23 +220,20 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
|
||||
{
|
||||
if(requestCode == PERMISSIONS_EXTERNAL_STORAGE)
|
||||
{
|
||||
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
if (requestCode == PERMISSIONS_EXTERNAL_STORAGE) {
|
||||
// If request is cancelled, the result arrays are empty.
|
||||
boolean success = grantResults.length > 0;
|
||||
|
||||
for(int grant : grantResults)
|
||||
{
|
||||
if(grant != PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
for (int grant : grantResults) {
|
||||
if (grant != PackageManager.PERMISSION_GRANTED) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(success == false)
|
||||
{
|
||||
if (!success) {
|
||||
// External storage permission rejected, inform user that
|
||||
// import/export is prevented
|
||||
Toast.makeText(getApplicationContext(), R.string.noExternalStoragePermissionError,
|
||||
@@ -248,20 +267,43 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void onImportComplete(boolean success, Uri path)
|
||||
{
|
||||
private void retryWithPassword(DataFormat dataFormat, Uri uri) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.passwordRequired);
|
||||
|
||||
final EditText input = new EditText(this);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
|
||||
activityResultParser(IMPORT, RESULT_OK, uri, input.getText().toString().toCharArray());
|
||||
});
|
||||
builder.setNegativeButton(R.string.cancel, (dialogInterface, i) -> dialogInterface.cancel());
|
||||
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void onImportComplete(ImportExportResult result, Uri path, DataFormat dataFormat) {
|
||||
if (result == ImportExportResult.BadPassword) {
|
||||
retryWithPassword(dataFormat, path);
|
||||
return;
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
|
||||
if(success)
|
||||
int messageId;
|
||||
|
||||
if (result == ImportExportResult.Success)
|
||||
{
|
||||
builder.setTitle(R.string.importSuccessfulTitle);
|
||||
messageId = R.string.importSuccessful;
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.setTitle(R.string.importFailedTitle);
|
||||
messageId = R.string.importFailed;
|
||||
}
|
||||
|
||||
int messageId = success ? R.string.importSuccessful : R.string.importFailed;
|
||||
final String message = getResources().getString(messageId);
|
||||
|
||||
builder.setMessage(message);
|
||||
@@ -277,53 +319,44 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
private void onExportComplete(boolean success, final Uri path)
|
||||
private void onExportComplete(ImportExportResult result, final Uri path)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
|
||||
if(success)
|
||||
int messageId;
|
||||
|
||||
if(result == ImportExportResult.Success)
|
||||
{
|
||||
builder.setTitle(R.string.exportSuccessfulTitle);
|
||||
messageId = R.string.exportSuccessful;
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.setTitle(R.string.exportFailedTitle);
|
||||
messageId = R.string.exportFailed;
|
||||
}
|
||||
|
||||
int messageId = success ? R.string.exportSuccessful : R.string.exportFailed;
|
||||
final String message = getResources().getString(messageId);
|
||||
|
||||
builder.setMessage(message);
|
||||
builder.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setNeutralButton(R.string.ok, (dialog, which) -> dialog.dismiss());
|
||||
|
||||
if(success)
|
||||
if(result == ImportExportResult.Success)
|
||||
{
|
||||
final CharSequence sendLabel = ImportExportActivity.this.getResources().getText(R.string.sendLabel);
|
||||
|
||||
builder.setPositiveButton(sendLabel, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
Intent sendIntent = new Intent(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, path);
|
||||
sendIntent.setType("text/csv");
|
||||
builder.setPositiveButton(sendLabel, (dialog, which) -> {
|
||||
Intent sendIntent = new Intent(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, path);
|
||||
sendIntent.setType("text/csv");
|
||||
|
||||
// set flag to give temporary permission to external app to use the FileProvider
|
||||
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
// set flag to give temporary permission to external app to use the FileProvider
|
||||
sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
|
||||
ImportExportActivity.this.startActivity(Intent.createChooser(sendIntent,
|
||||
sendLabel));
|
||||
ImportExportActivity.this.startActivity(Intent.createChooser(sendIntent,
|
||||
sendLabel));
|
||||
|
||||
dialog.dismiss();
|
||||
}
|
||||
dialog.dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -343,18 +376,13 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
private void activityResultParser(int requestCode, int resultCode, Uri uri, char[] password) {
|
||||
if (resultCode != RESULT_OK)
|
||||
{
|
||||
Log.w(TAG, "Failed onActivityResult(), result=" + resultCode);
|
||||
return;
|
||||
}
|
||||
|
||||
Uri uri = data.getData();
|
||||
if(uri == null)
|
||||
{
|
||||
Log.e(TAG, "Activity returned a NULL URI");
|
||||
@@ -392,7 +420,7 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
|
||||
Log.e(TAG, "Starting file import with: " + uri.toString());
|
||||
|
||||
startImport(reader, uri, importDataFormat);
|
||||
startImport(reader, uri, importDataFormat, password);
|
||||
}
|
||||
}
|
||||
catch(FileNotFoundException e)
|
||||
@@ -400,12 +428,26 @@ public class ImportExportActivity extends AppCompatActivity
|
||||
Log.e(TAG, "Failed to import/export file: " + uri.toString(), e);
|
||||
if (requestCode == CHOOSE_EXPORT_LOCATION)
|
||||
{
|
||||
onExportComplete(false, uri);
|
||||
onExportComplete(ImportExportResult.GenericFailure, uri);
|
||||
}
|
||||
else
|
||||
{
|
||||
onImportComplete(false, uri);
|
||||
onImportComplete(ImportExportResult.GenericFailure, uri, importDataFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if(data == null)
|
||||
{
|
||||
Log.e(TAG, "Activity returned NULL data");
|
||||
return;
|
||||
}
|
||||
|
||||
activityResultParser(requestCode, resultCode, data.getData(), null);
|
||||
}
|
||||
}
|
||||
@@ -2,21 +2,23 @@ package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import protect.card_locker.importexport.DataFormat;
|
||||
import protect.card_locker.importexport.ImportExportResult;
|
||||
import protect.card_locker.importexport.MultiFormatExporter;
|
||||
import protect.card_locker.importexport.MultiFormatImporter;
|
||||
|
||||
class ImportExportTask extends AsyncTask<Void, Void, Boolean>
|
||||
class ImportExportTask extends AsyncTask<Void, Void, ImportExportResult>
|
||||
{
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
@@ -25,6 +27,7 @@ class ImportExportTask extends AsyncTask<Void, Void, Boolean>
|
||||
private DataFormat format;
|
||||
private OutputStream outputStream;
|
||||
private InputStream inputStream;
|
||||
private char[] password;
|
||||
private TaskCompleteListener listener;
|
||||
|
||||
private ProgressDialog progress;
|
||||
@@ -46,7 +49,7 @@ class ImportExportTask extends AsyncTask<Void, Void, Boolean>
|
||||
/**
|
||||
* Constructor which will setup a task for importing from the given InputStream.
|
||||
*/
|
||||
ImportExportTask(Activity activity, DataFormat format, InputStream input,
|
||||
ImportExportTask(Activity activity, DataFormat format, InputStream input, char[] password,
|
||||
TaskCompleteListener listener)
|
||||
{
|
||||
super();
|
||||
@@ -54,29 +57,27 @@ class ImportExportTask extends AsyncTask<Void, Void, Boolean>
|
||||
this.doImport = true;
|
||||
this.format = format;
|
||||
this.inputStream = input;
|
||||
this.password = password;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
private boolean performImport(InputStream stream, DBHelper db)
|
||||
private ImportExportResult performImport(Context context, InputStream stream, DBHelper db, char[] password)
|
||||
{
|
||||
boolean result = false;
|
||||
ImportExportResult importResult = MultiFormatImporter.importData(context, db, stream, format, password);
|
||||
|
||||
Log.i(TAG, "Import result: " + importResult.name());
|
||||
|
||||
result = MultiFormatImporter.importData(db, stream, format);
|
||||
|
||||
Log.i(TAG, "Import result: " + result);
|
||||
|
||||
return result;
|
||||
return importResult;
|
||||
}
|
||||
|
||||
private boolean performExport(OutputStream stream, DBHelper db)
|
||||
private ImportExportResult performExport(Context context, OutputStream stream, DBHelper db)
|
||||
{
|
||||
boolean result = false;
|
||||
ImportExportResult result = ImportExportResult.GenericFailure;
|
||||
|
||||
try
|
||||
{
|
||||
OutputStreamWriter writer = new OutputStreamWriter(stream, Charset.forName("UTF-8"));
|
||||
result = MultiFormatExporter.exportData(db, writer, format);
|
||||
OutputStreamWriter writer = new OutputStreamWriter(stream, StandardCharsets.UTF_8);
|
||||
result = MultiFormatExporter.exportData(context, db, stream, format);
|
||||
writer.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
@@ -106,26 +107,26 @@ class ImportExportTask extends AsyncTask<Void, Void, Boolean>
|
||||
progress.show();
|
||||
}
|
||||
|
||||
protected Boolean doInBackground(Void... nothing)
|
||||
protected ImportExportResult doInBackground(Void... nothing)
|
||||
{
|
||||
final DBHelper db = new DBHelper(activity);
|
||||
boolean result;
|
||||
ImportExportResult result;
|
||||
|
||||
if(doImport)
|
||||
{
|
||||
result = performImport(inputStream, db);
|
||||
result = performImport(activity.getApplicationContext(), inputStream, db, password);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = performExport(outputStream, db);
|
||||
result = performExport(activity.getApplicationContext(), outputStream, db);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Boolean result)
|
||||
protected void onPostExecute(ImportExportResult result)
|
||||
{
|
||||
listener.onTaskComplete(result);
|
||||
listener.onTaskComplete(result, format);
|
||||
|
||||
progress.dismiss();
|
||||
Log.i(TAG, (doImport ? "Import" : "Export") + " Complete");
|
||||
@@ -138,7 +139,7 @@ class ImportExportTask extends AsyncTask<Void, Void, Boolean>
|
||||
}
|
||||
interface TaskCompleteListener
|
||||
{
|
||||
void onTaskComplete(boolean success);
|
||||
void onTaskComplete(ImportExportResult result, DataFormat format);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,10 +3,19 @@ package protect.card_locker;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ImportURIHelper {
|
||||
private static final String STORE = DBHelper.LoyaltyCardDbIds.STORE;
|
||||
@@ -15,28 +24,36 @@ public class ImportURIHelper {
|
||||
private static final String BALANCE = DBHelper.LoyaltyCardDbIds.BALANCE;
|
||||
private static final String BALANCE_TYPE = DBHelper.LoyaltyCardDbIds.BALANCE_TYPE;
|
||||
private static final String CARD_ID = DBHelper.LoyaltyCardDbIds.CARD_ID;
|
||||
private static final String BARCODE_ID = DBHelper.LoyaltyCardDbIds.BARCODE_ID;
|
||||
private static final String BARCODE_TYPE = DBHelper.LoyaltyCardDbIds.BARCODE_TYPE;
|
||||
|
||||
private static final String HEADER_COLOR = DBHelper.LoyaltyCardDbIds.HEADER_COLOR;
|
||||
|
||||
private final Context context;
|
||||
private final String host;
|
||||
private final String path;
|
||||
private final String oldHost;
|
||||
private final String oldPath;
|
||||
private final String[] hosts = new String[3];
|
||||
private final String[] paths = new String[3];
|
||||
private final String shareText;
|
||||
private final String shareMultipleText;
|
||||
|
||||
public ImportURIHelper(Context context) {
|
||||
this.context = context;
|
||||
host = context.getResources().getString(R.string.intent_import_card_from_url_host);
|
||||
path = context.getResources().getString(R.string.intent_import_card_from_url_path_prefix);
|
||||
oldHost = "brarcher.github.io";
|
||||
oldPath = "/loyalty-card-locker/share";
|
||||
hosts[0] = context.getResources().getString(R.string.intent_import_card_from_url_host_catima_app);
|
||||
paths[0] = context.getResources().getString(R.string.intent_import_card_from_url_path_prefix_catima_app);
|
||||
hosts[1] = context.getResources().getString(R.string.intent_import_card_from_url_host_thelastproject);
|
||||
paths[1] = context.getResources().getString(R.string.intent_import_card_from_url_path_prefix_thelastproject);
|
||||
hosts[2] = context.getResources().getString(R.string.intent_import_card_from_url_host_brarcher);
|
||||
paths[2] = context.getResources().getString(R.string.intent_import_card_from_url_path_prefix_brarcher);
|
||||
shareText = context.getResources().getString(R.string.intent_import_card_from_url_share_text);
|
||||
shareMultipleText = context.getResources().getString(R.string.intent_import_card_from_url_share_multiple_text);
|
||||
}
|
||||
|
||||
private boolean isImportUri(Uri uri) {
|
||||
return (uri.getHost().equals(host) && uri.getPath().equals(path)) || (uri.getHost().equals(oldHost) && uri.getPath().equals(oldPath));
|
||||
for (int i = 0; i < hosts.length; i++) {
|
||||
if (uri.getHost().equals(hosts[i]) && uri.getPath().equals(paths[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public LoyaltyCard parse(Uri uri) throws InvalidObjectException {
|
||||
@@ -46,82 +63,146 @@ public class ImportURIHelper {
|
||||
|
||||
try {
|
||||
// These values are allowed to be null
|
||||
BarcodeFormat barcodeType = null;
|
||||
Date expiry = null;
|
||||
BigDecimal balance = new BigDecimal("0");
|
||||
Currency balanceType = null;
|
||||
Integer headerColor = null;
|
||||
Integer headerTextColor = null;
|
||||
|
||||
String store = uri.getQueryParameter(STORE);
|
||||
String note = uri.getQueryParameter(NOTE);
|
||||
String cardId = uri.getQueryParameter(CARD_ID);
|
||||
String barcodeType = uri.getQueryParameter(BARCODE_TYPE);
|
||||
if (store == null || note == null || cardId == null || barcodeType == null) throw new InvalidObjectException("Not a valid import URI");
|
||||
// Store everything in a simple key/value hashmap
|
||||
HashMap<String, String> kv = new HashMap<>();
|
||||
|
||||
String unparsedBalance = uri.getQueryParameter(BALANCE);
|
||||
// First, grab all query parameters (backwards compatibility)
|
||||
for (String key : uri.getQueryParameterNames()) {
|
||||
kv.put(key, uri.getQueryParameter(key));
|
||||
}
|
||||
|
||||
// Then, parse the new and more private fragment part
|
||||
// Overriding old format entries if they exist
|
||||
String fragment = uri.getFragment();
|
||||
if (fragment != null) {
|
||||
for (String fragmentPart : fragment.split("&")) {
|
||||
String[] fragmentData = fragmentPart.split("=", 2);
|
||||
kv.put(fragmentData[0], URLDecoder.decode(fragmentData[1], StandardCharsets.UTF_8.name()));
|
||||
}
|
||||
}
|
||||
|
||||
// Then use all values we care about
|
||||
String store = kv.get(STORE);
|
||||
String note = kv.get(NOTE);
|
||||
String cardId = kv.get(CARD_ID);
|
||||
String barcodeId = kv.get(BARCODE_ID);
|
||||
if (store == null || note == null || cardId == null) throw new InvalidObjectException("Not a valid import URI: " + uri.toString());
|
||||
|
||||
String unparsedBarcodeType = kv.get(BARCODE_TYPE);
|
||||
if(unparsedBarcodeType != null && !unparsedBarcodeType.equals(""))
|
||||
{
|
||||
barcodeType = BarcodeFormat.valueOf(unparsedBarcodeType);
|
||||
}
|
||||
|
||||
String unparsedBalance = kv.get(BALANCE);
|
||||
if(unparsedBalance != null && !unparsedBalance.equals(""))
|
||||
{
|
||||
balance = new BigDecimal(unparsedBalance);
|
||||
}
|
||||
String unparsedBalanceType = uri.getQueryParameter(BALANCE_TYPE);
|
||||
String unparsedBalanceType = kv.get(BALANCE_TYPE);
|
||||
if (unparsedBalanceType != null && !unparsedBalanceType.equals(""))
|
||||
{
|
||||
balanceType = Currency.getInstance(unparsedBalanceType);
|
||||
}
|
||||
String unparsedExpiry = uri.getQueryParameter(EXPIRY);
|
||||
String unparsedExpiry = kv.get(EXPIRY);
|
||||
if(unparsedExpiry != null && !unparsedExpiry.equals(""))
|
||||
{
|
||||
expiry = new Date(Long.parseLong(unparsedExpiry));
|
||||
}
|
||||
|
||||
String unparsedHeaderColor = uri.getQueryParameter(HEADER_COLOR);
|
||||
String unparsedHeaderColor = kv.get(HEADER_COLOR);
|
||||
if(unparsedHeaderColor != null)
|
||||
{
|
||||
headerColor = Integer.parseInt(unparsedHeaderColor);
|
||||
}
|
||||
|
||||
return new LoyaltyCard(-1, store, note, expiry, balance, balanceType, cardId, barcodeType, headerColor, headerTextColor, 0);
|
||||
} catch (NullPointerException | NumberFormatException ex) {
|
||||
return new LoyaltyCard(-1, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, 0);
|
||||
} catch (NullPointerException | NumberFormatException | UnsupportedEncodingException ex) {
|
||||
throw new InvalidObjectException("Not a valid import URI");
|
||||
}
|
||||
}
|
||||
|
||||
private StringBuilder appendFragment(StringBuilder fragment, String key, String value) throws UnsupportedEncodingException {
|
||||
if (fragment.length() > 0) {
|
||||
fragment.append("&");
|
||||
}
|
||||
|
||||
// Double-encode the value to make sure it can't accidentally contain symbols that'll break the parser
|
||||
fragment.append(key).append("=").append(URLEncoder.encode(value, StandardCharsets.UTF_8.name()));
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
// Protected for usage in tests
|
||||
protected Uri toUri(LoyaltyCard loyaltyCard) {
|
||||
protected Uri toUri(LoyaltyCard loyaltyCard) throws UnsupportedEncodingException {
|
||||
Uri.Builder uriBuilder = new Uri.Builder();
|
||||
uriBuilder.scheme("https");
|
||||
uriBuilder.authority(host);
|
||||
uriBuilder.path(path);
|
||||
uriBuilder.appendQueryParameter(STORE, loyaltyCard.store);
|
||||
uriBuilder.appendQueryParameter(NOTE, loyaltyCard.note);
|
||||
uriBuilder.appendQueryParameter(BALANCE, loyaltyCard.balance.toString());
|
||||
uriBuilder.authority(hosts[0]);
|
||||
uriBuilder.path(paths[0]);
|
||||
|
||||
// Use fragment instead of QueryParameter to not leak this data to the server
|
||||
StringBuilder fragment = new StringBuilder();
|
||||
|
||||
fragment = appendFragment(fragment, STORE, loyaltyCard.store);
|
||||
fragment = appendFragment(fragment, NOTE, loyaltyCard.note);
|
||||
fragment = appendFragment(fragment, BALANCE, loyaltyCard.balance.toString());
|
||||
if (loyaltyCard.balanceType != null) {
|
||||
uriBuilder.appendQueryParameter(BALANCE_TYPE, loyaltyCard.balanceType.getCurrencyCode());
|
||||
fragment = appendFragment(fragment, BALANCE_TYPE, loyaltyCard.balanceType.getCurrencyCode());
|
||||
}
|
||||
if (loyaltyCard.expiry != null) {
|
||||
uriBuilder.appendQueryParameter(EXPIRY, String.valueOf(loyaltyCard.expiry.getTime()));
|
||||
fragment = appendFragment(fragment, EXPIRY, String.valueOf(loyaltyCard.expiry.getTime()));
|
||||
}
|
||||
uriBuilder.appendQueryParameter(CARD_ID, loyaltyCard.cardId);
|
||||
uriBuilder.appendQueryParameter(BARCODE_TYPE, loyaltyCard.barcodeType);
|
||||
if(loyaltyCard.headerColor != null)
|
||||
{
|
||||
uriBuilder.appendQueryParameter(HEADER_COLOR, loyaltyCard.headerColor.toString());
|
||||
fragment = appendFragment(fragment, CARD_ID, loyaltyCard.cardId);
|
||||
if(loyaltyCard.barcodeId != null) {
|
||||
fragment = appendFragment(fragment, BARCODE_ID, loyaltyCard.barcodeId);
|
||||
}
|
||||
//StarStatus will not be exported
|
||||
|
||||
if(loyaltyCard.barcodeType != null) {
|
||||
fragment = appendFragment(fragment, BARCODE_TYPE, loyaltyCard.barcodeType.toString());
|
||||
}
|
||||
if(loyaltyCard.headerColor != null) {
|
||||
fragment = appendFragment(fragment, HEADER_COLOR, loyaltyCard.headerColor.toString());
|
||||
}
|
||||
// Star status will not be exported
|
||||
// Front and back pictures are often too big to fit into a message in base64 nicely, not sharing either...
|
||||
|
||||
uriBuilder.fragment(fragment.toString());
|
||||
return uriBuilder.build();
|
||||
}
|
||||
|
||||
private void startShareIntent(Uri uri) {
|
||||
public void startShareIntent(List<LoyaltyCard> loyaltyCards) throws UnsupportedEncodingException {
|
||||
int loyaltyCardCount = loyaltyCards.size();
|
||||
|
||||
StringBuilder text = new StringBuilder();
|
||||
if (loyaltyCardCount == 1) {
|
||||
text.append(shareText);
|
||||
} else {
|
||||
text.append(shareMultipleText);
|
||||
}
|
||||
text.append("\n\n");
|
||||
|
||||
for (int i = 0; i < loyaltyCardCount; i++) {
|
||||
LoyaltyCard loyaltyCard = loyaltyCards.get(i);
|
||||
|
||||
text.append(loyaltyCard.store + ": " + toUri(loyaltyCard));
|
||||
|
||||
if (i < (loyaltyCardCount - 1)) {
|
||||
text.append("\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, shareText + "\n" + uri.toString());
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, text.toString());
|
||||
sendIntent.setType("text/plain");
|
||||
|
||||
Intent shareIntent = Intent.createChooser(sendIntent, null);
|
||||
context.startActivity(shareIntent);
|
||||
}
|
||||
|
||||
public void startShareIntent(LoyaltyCard loyaltyCard) {
|
||||
startShareIntent(toUri(loyaltyCard));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,15 @@ package protect.card_locker;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class LoyaltyCard
|
||||
{
|
||||
public class LoyaltyCard {
|
||||
public final int id;
|
||||
public final String store;
|
||||
public final String note;
|
||||
@@ -17,19 +18,20 @@ public class LoyaltyCard
|
||||
public final BigDecimal balance;
|
||||
public final Currency balanceType;
|
||||
public final String cardId;
|
||||
public final String barcodeType;
|
||||
|
||||
@Nullable
|
||||
public final String barcodeId;
|
||||
|
||||
public final BarcodeFormat barcodeType;
|
||||
|
||||
@Nullable
|
||||
public final Integer headerColor;
|
||||
|
||||
@Nullable
|
||||
public final Integer headerTextColor;
|
||||
|
||||
public final int starStatus;
|
||||
|
||||
public LoyaltyCard(final int id, final String store, final String note, final Date expiry,
|
||||
final BigDecimal balance, final Currency balanceType, final String cardId,
|
||||
final String barcodeType, final Integer headerColor, final Integer headerTextColor,
|
||||
final String barcodeId, final BarcodeFormat barcodeType, final Integer headerColor,
|
||||
final int starStatus)
|
||||
{
|
||||
this.id = id;
|
||||
@@ -39,9 +41,9 @@ public class LoyaltyCard
|
||||
this.balance = balance;
|
||||
this.balanceType = balanceType;
|
||||
this.cardId = cardId;
|
||||
this.barcodeId = barcodeId;
|
||||
this.barcodeType = barcodeType;
|
||||
this.headerColor = headerColor;
|
||||
this.headerTextColor = headerTextColor;
|
||||
this.starStatus = starStatus;
|
||||
}
|
||||
|
||||
@@ -53,17 +55,22 @@ public class LoyaltyCard
|
||||
long expiryLong = cursor.getLong(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.EXPIRY));
|
||||
BigDecimal balance = new BigDecimal(cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BALANCE)));
|
||||
String cardId = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.CARD_ID));
|
||||
String barcodeType = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE));
|
||||
String barcodeId = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ID));
|
||||
int starred = cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS));
|
||||
|
||||
int barcodeTypeColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE);
|
||||
int balanceTypeColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BALANCE_TYPE);
|
||||
int headerColorColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR);
|
||||
int headerTextColorColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_TEXT_COLOR);
|
||||
|
||||
BarcodeFormat barcodeType = null;
|
||||
Currency balanceType = null;
|
||||
Date expiry = null;
|
||||
Integer headerColor = null;
|
||||
Integer headerTextColor = null;
|
||||
|
||||
if (cursor.isNull(barcodeTypeColumn) == false)
|
||||
{
|
||||
barcodeType = BarcodeFormat.valueOf(cursor.getString(barcodeTypeColumn));
|
||||
}
|
||||
|
||||
if (cursor.isNull(balanceTypeColumn) == false)
|
||||
{
|
||||
@@ -80,11 +87,6 @@ public class LoyaltyCard
|
||||
headerColor = cursor.getInt(headerColorColumn);
|
||||
}
|
||||
|
||||
if(cursor.isNull(headerTextColorColumn) == false)
|
||||
{
|
||||
headerTextColor = cursor.getInt(headerTextColorColumn);
|
||||
}
|
||||
|
||||
return new LoyaltyCard(id, store, note, expiry, balance, balanceType, cardId, barcodeType, headerColor, headerTextColor, starred);
|
||||
return new LoyaltyCard(id, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, starred);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.animation.AnimatorInflater;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
|
||||
public class LoyaltyCardAnimator {
|
||||
|
||||
private static AnimatorSet selectedViewIn, defaultViewOut, selectedViewOut, defaultViewIn;
|
||||
|
||||
public static void flipView(Context inputContext, final View inputSelectedView, final View inputDefaultView, boolean inputItemSelected) {
|
||||
|
||||
selectedViewIn = (AnimatorSet) AnimatorInflater.loadAnimator(inputContext, R.animator.flip_left_in);
|
||||
defaultViewOut = (AnimatorSet) AnimatorInflater.loadAnimator(inputContext, R.animator.flip_right_out);
|
||||
selectedViewOut = (AnimatorSet) AnimatorInflater.loadAnimator(inputContext, R.animator.flip_left_out);
|
||||
defaultViewIn = (AnimatorSet) AnimatorInflater.loadAnimator(inputContext, R.animator.flip_right_in);
|
||||
|
||||
final AnimatorSet showFrontAnim = new AnimatorSet();
|
||||
final AnimatorSet showBackAnim = new AnimatorSet();
|
||||
|
||||
selectedViewIn.setTarget(inputSelectedView);
|
||||
defaultViewOut.setTarget(inputDefaultView);
|
||||
showFrontAnim.playTogether(selectedViewIn, defaultViewOut);
|
||||
|
||||
selectedViewOut.setTarget(inputSelectedView);
|
||||
defaultViewIn.setTarget(inputDefaultView);
|
||||
showBackAnim.playTogether(defaultViewIn, selectedViewOut);
|
||||
|
||||
if (inputItemSelected) {
|
||||
showFrontAnim.start();
|
||||
} else {
|
||||
showBackAnim.start();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,97 +2,296 @@ package protect.card_locker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CursorAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import protect.card_locker.preferences.Settings;
|
||||
|
||||
class LoyaltyCardCursorAdapter extends CursorAdapter
|
||||
public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCursorAdapter.LoyaltyCardListItemViewHolder>
|
||||
{
|
||||
Settings settings;
|
||||
private static int mCurrentSelectedIndex = -1;
|
||||
private Cursor mCursor;
|
||||
Settings mSettings;
|
||||
boolean mDarkModeEnabled;
|
||||
private Context mContext;
|
||||
private CardAdapterListener mListener;
|
||||
private SparseBooleanArray mSelectedItems;
|
||||
private SparseBooleanArray mAnimationItemsIndex;
|
||||
private boolean mReverseAllAnimations = false;
|
||||
|
||||
public LoyaltyCardCursorAdapter(Context context, Cursor cursor)
|
||||
public LoyaltyCardCursorAdapter(Context inputContext, Cursor inputCursor, CardAdapterListener inputListener)
|
||||
{
|
||||
super(context, cursor, 0);
|
||||
settings = new Settings(context);
|
||||
super(inputCursor);
|
||||
mSettings = new Settings(inputContext);
|
||||
mCursor = inputCursor;
|
||||
mContext = inputContext;
|
||||
mListener = inputListener;
|
||||
mSelectedItems = new SparseBooleanArray();
|
||||
mAnimationItemsIndex = new SparseBooleanArray();
|
||||
|
||||
mDarkModeEnabled = MainActivity.isDarkModeEnabled(inputContext);
|
||||
}
|
||||
|
||||
// The newView method is used to inflate a new view and return it,
|
||||
// you don't bind any data to the view at this point.
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup parent)
|
||||
public LoyaltyCardListItemViewHolder onCreateViewHolder(ViewGroup inputParent, int inputViewType)
|
||||
{
|
||||
return LayoutInflater.from(context).inflate(R.layout.loyalty_card_layout, parent, false);
|
||||
View itemView = LayoutInflater.from(inputParent.getContext()).inflate(R.layout.loyalty_card_layout, inputParent, false);
|
||||
return new LoyaltyCardListItemViewHolder(itemView);
|
||||
}
|
||||
|
||||
// The bindView method is used to bind all data to a given view
|
||||
// such as setting the text on a TextView.
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor)
|
||||
public Cursor getCursor()
|
||||
{
|
||||
// Find fields to populate in inflated template
|
||||
ImageView thumbnail = view.findViewById(R.id.thumbnail);
|
||||
TextView storeField = view.findViewById(R.id.store);
|
||||
TextView noteField = view.findViewById(R.id.note);
|
||||
TextView balanceField = view.findViewById(R.id.balance);
|
||||
TextView expiryField = view.findViewById(R.id.expiry);
|
||||
ImageView star = view.findViewById(R.id.star);
|
||||
return mCursor;
|
||||
}
|
||||
|
||||
// Extract properties from cursor
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
|
||||
|
||||
// Populate fields with extracted properties
|
||||
storeField.setText(loyaltyCard.store);
|
||||
|
||||
storeField.setTextSize(settings.getCardTitleListFontSize());
|
||||
|
||||
if(!loyaltyCard.note.isEmpty())
|
||||
{
|
||||
noteField.setVisibility(View.VISIBLE);
|
||||
noteField.setText(loyaltyCard.note);
|
||||
noteField.setTextSize(settings.getCardNoteListFontSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
noteField.setVisibility(View.GONE);
|
||||
public void onBindViewHolder(LoyaltyCardListItemViewHolder inputHolder, Cursor inputCursor) {
|
||||
if (mDarkModeEnabled) {
|
||||
inputHolder.mStarIcon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
|
||||
}
|
||||
|
||||
if(!loyaltyCard.balance.equals(new BigDecimal("0"))) {
|
||||
balanceField.setVisibility(View.VISIBLE);
|
||||
balanceField.setText(context.getString(R.string.balanceSentence, Utils.formatBalance(context, loyaltyCard.balance, loyaltyCard.balanceType)));
|
||||
}
|
||||
else
|
||||
{
|
||||
balanceField.setVisibility(View.GONE);
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(inputCursor);
|
||||
|
||||
inputHolder.mStoreField.setText(loyaltyCard.store);
|
||||
inputHolder.mStoreField.setTextSize(mSettings.getFontSizeMax(mSettings.getMediumFont()));
|
||||
if (!loyaltyCard.note.isEmpty()) {
|
||||
inputHolder.mNoteField.setVisibility(View.VISIBLE);
|
||||
inputHolder.mNoteField.setText(loyaltyCard.note);
|
||||
inputHolder.mNoteField.setTextSize(mSettings.getFontSizeMax(mSettings.getSmallFont()));
|
||||
} else {
|
||||
inputHolder.mNoteField.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(loyaltyCard.expiry != null)
|
||||
if (!loyaltyCard.balance.equals(new BigDecimal("0"))) {
|
||||
inputHolder.mBalanceField.setVisibility(View.VISIBLE);
|
||||
inputHolder.mBalanceField.setText(mContext.getString(R.string.balanceSentence, Utils.formatBalance(mContext, loyaltyCard.balance, loyaltyCard.balanceType)));
|
||||
inputHolder.mBalanceField.setTextSize(mSettings.getFontSizeMax(mSettings.getSmallFont()));
|
||||
} else {
|
||||
inputHolder.mBalanceField.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (loyaltyCard.expiry != null)
|
||||
{
|
||||
expiryField.setVisibility(View.VISIBLE);
|
||||
inputHolder.mExpiryField.setVisibility(View.VISIBLE);
|
||||
int expiryString = R.string.expiryStateSentence;
|
||||
if(Utils.hasExpired(loyaltyCard.expiry)) {
|
||||
expiryString = R.string.expiryStateSentenceExpired;
|
||||
expiryField.setTextColor(context.getResources().getColor(R.color.alert));
|
||||
inputHolder.mExpiryField.setTextColor(mContext.getResources().getColor(R.color.alert));
|
||||
}
|
||||
inputHolder.mExpiryField.setText(mContext.getString(expiryString, DateFormat.getDateInstance(DateFormat.LONG).format(loyaltyCard.expiry)));
|
||||
inputHolder.mExpiryField.setTextSize(mSettings.getFontSizeMax(mSettings.getSmallFont()));
|
||||
} else {
|
||||
inputHolder.mExpiryField.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
inputHolder.mStarIcon.setVisibility((loyaltyCard.starStatus != 0) ? View.VISIBLE : View.GONE);
|
||||
inputHolder.mCardIcon.setImageBitmap(Utils.generateIcon(mContext, loyaltyCard.store, loyaltyCard.headerColor).getLetterTile());
|
||||
|
||||
inputHolder.itemView.setActivated(mSelectedItems.get(inputCursor.getPosition(), false));
|
||||
applyIconAnimation(inputHolder, inputCursor.getPosition());
|
||||
applyClickEvents(inputHolder, inputCursor.getPosition());
|
||||
|
||||
}
|
||||
|
||||
private void applyClickEvents(LoyaltyCardListItemViewHolder inputHolder, final int inputPosition)
|
||||
{
|
||||
inputHolder.mThumbnailContainer.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View inputView)
|
||||
{
|
||||
mListener.onIconClicked(inputPosition);
|
||||
}
|
||||
});
|
||||
|
||||
inputHolder.mRow.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View inputView)
|
||||
{
|
||||
mListener.onRowClicked(inputPosition);
|
||||
}
|
||||
});
|
||||
|
||||
inputHolder.mInformationContainer.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View inputView)
|
||||
{
|
||||
mListener.onRowClicked(inputPosition);
|
||||
}
|
||||
});
|
||||
|
||||
inputHolder.mRow.setOnLongClickListener(new View.OnLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onLongClick(View inputView)
|
||||
{
|
||||
mListener.onRowLongClicked(inputPosition);
|
||||
inputView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
inputHolder.mInformationContainer.setOnLongClickListener(new View.OnLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onLongClick(View inputView)
|
||||
{
|
||||
mListener.onRowLongClicked(inputPosition);
|
||||
inputView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void applyIconAnimation(LoyaltyCardListItemViewHolder inputHolder, int inputPosition)
|
||||
{
|
||||
if (mSelectedItems.get(inputPosition, false))
|
||||
{
|
||||
inputHolder.mThumbnailFrontContainer.setVisibility(View.GONE);
|
||||
resetIconYAxis(inputHolder.mThumbnailBackContainer);
|
||||
inputHolder.mThumbnailBackContainer.setVisibility(View.VISIBLE);
|
||||
inputHolder.mThumbnailBackContainer.setAlpha(1);
|
||||
if (mCurrentSelectedIndex == inputPosition)
|
||||
{
|
||||
LoyaltyCardAnimator.flipView(mContext, inputHolder.mThumbnailBackContainer, inputHolder.mThumbnailFrontContainer, true);
|
||||
resetCurrentIndex();
|
||||
}
|
||||
expiryField.setText(context.getString(expiryString, DateFormat.getDateInstance(DateFormat.LONG).format(loyaltyCard.expiry)));
|
||||
expiryField.setTextSize(settings.getCardNoteListFontSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
expiryField.setVisibility(View.GONE);
|
||||
inputHolder.mThumbnailBackContainer.setVisibility(View.GONE);
|
||||
resetIconYAxis(inputHolder.mThumbnailFrontContainer);
|
||||
inputHolder.mThumbnailFrontContainer.setVisibility(View.VISIBLE);
|
||||
inputHolder.mThumbnailFrontContainer.setAlpha(1);
|
||||
if ((mReverseAllAnimations && mAnimationItemsIndex.get(inputPosition, false)) || mCurrentSelectedIndex == inputPosition)
|
||||
{
|
||||
LoyaltyCardAnimator.flipView(mContext, inputHolder.mThumbnailBackContainer, inputHolder.mThumbnailFrontContainer, false);
|
||||
resetCurrentIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetIconYAxis(View inputView)
|
||||
{
|
||||
if (inputView.getRotationY() != 0)
|
||||
{
|
||||
inputView.setRotationY(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void resetAnimationIndex()
|
||||
{
|
||||
mReverseAllAnimations = false;
|
||||
mAnimationItemsIndex.clear();
|
||||
}
|
||||
|
||||
@SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
|
||||
public void toggleSelection(int inputPosition)
|
||||
{
|
||||
mCurrentSelectedIndex = inputPosition;
|
||||
if (mSelectedItems.get(inputPosition, false))
|
||||
{
|
||||
mSelectedItems.delete(inputPosition);
|
||||
mAnimationItemsIndex.delete(inputPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSelectedItems.put(inputPosition, true);
|
||||
mAnimationItemsIndex.put(inputPosition, true);
|
||||
}
|
||||
notifyItemChanged(inputPosition);
|
||||
}
|
||||
|
||||
public void clearSelections()
|
||||
{
|
||||
mReverseAllAnimations = true;
|
||||
mSelectedItems.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int getSelectedItemCount()
|
||||
{
|
||||
return mSelectedItems.size();
|
||||
}
|
||||
|
||||
public ArrayList<LoyaltyCard> getSelectedItems()
|
||||
{
|
||||
|
||||
ArrayList<LoyaltyCard> result = new ArrayList<>();
|
||||
|
||||
int i;
|
||||
for(i = 0; i < mSelectedItems.size(); i++)
|
||||
{
|
||||
mCursor.moveToPosition(mSelectedItems.keyAt(i));
|
||||
result.add(LoyaltyCard.toLoyaltyCard(mCursor));
|
||||
}
|
||||
|
||||
if (loyaltyCard.starStatus!=0) star.setVisibility(View.VISIBLE);
|
||||
else star.setVisibility(View.GONE);
|
||||
|
||||
thumbnail.setImageBitmap(Utils.generateIcon(context, loyaltyCard.store, loyaltyCard.headerColor).getLetterTile());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private void resetCurrentIndex()
|
||||
{
|
||||
mCurrentSelectedIndex = -1;
|
||||
}
|
||||
|
||||
public interface CardAdapterListener
|
||||
{
|
||||
void onIconClicked(int inputPosition);
|
||||
void onRowClicked(int inputPosition);
|
||||
void onRowLongClicked(int inputPosition);
|
||||
}
|
||||
|
||||
public class LoyaltyCardListItemViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener
|
||||
{
|
||||
|
||||
public TextView mStoreField, mNoteField, mBalanceField, mExpiryField;
|
||||
public LinearLayout mInformationContainer;
|
||||
public ImageView mCardIcon, mStarIcon;
|
||||
public CardView mThumbnailContainer;
|
||||
public ConstraintLayout mRow;
|
||||
public RelativeLayout mThumbnailFrontContainer, mThumbnailBackContainer;
|
||||
|
||||
public LoyaltyCardListItemViewHolder(View inputView)
|
||||
{
|
||||
super(inputView);
|
||||
mThumbnailContainer = inputView.findViewById(R.id.thumbnail_container);
|
||||
mRow = inputView.findViewById(R.id.row);
|
||||
mThumbnailFrontContainer = inputView.findViewById(R.id.thumbnail_front);
|
||||
mThumbnailBackContainer = inputView.findViewById(R.id.thumbnail_back);
|
||||
mInformationContainer = inputView.findViewById(R.id.information_container);
|
||||
mStoreField = inputView.findViewById(R.id.store);
|
||||
mNoteField = inputView.findViewById(R.id.note);
|
||||
mBalanceField = inputView.findViewById(R.id.balance);
|
||||
mExpiryField = inputView.findViewById(R.id.expiry);
|
||||
mCardIcon = inputView.findViewById(R.id.thumbnail);
|
||||
mStarIcon = inputView.findViewById(R.id.star);
|
||||
inputView.setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View inputView)
|
||||
{
|
||||
mListener.onRowLongClicked(getAdapterPosition());
|
||||
inputView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
15
app/src/main/java/protect/card_locker/LoyaltyCardField.java
Normal file
15
app/src/main/java/protect/card_locker/LoyaltyCardField.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package protect.card_locker;
|
||||
|
||||
public enum LoyaltyCardField {
|
||||
id,
|
||||
store,
|
||||
note,
|
||||
expiry,
|
||||
balance,
|
||||
balanceType,
|
||||
cardId,
|
||||
barcodeId,
|
||||
barcodeType,
|
||||
headerColor,
|
||||
starStatus
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.Application;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import protect.card_locker.preferences.Settings;
|
||||
|
||||
public class LoyaltyCardLockerApplication extends Application {
|
||||
|
||||
@@ -3,33 +3,23 @@ package protect.card_locker;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.constraintlayout.widget.Guideline;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.core.widget.TextViewCompat;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
@@ -39,10 +29,20 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.constraintlayout.widget.Guideline;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.core.widget.TextViewCompat;
|
||||
import protect.card_locker.preferences.Settings;
|
||||
|
||||
public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
@@ -52,7 +52,12 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
TextView cardIdFieldView;
|
||||
BottomSheetBehavior behavior;
|
||||
View bottomSheet;
|
||||
View bottomSheetContentWrapper;
|
||||
ImageView bottomSheetButton;
|
||||
View frontImageView;
|
||||
ImageView frontImage;
|
||||
View backImageView;
|
||||
ImageView backImage;
|
||||
TextView noteView;
|
||||
TextView groupsView;
|
||||
TextView balanceView;
|
||||
@@ -71,6 +76,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
Settings settings;
|
||||
|
||||
String cardIdString;
|
||||
String barcodeIdString;
|
||||
BarcodeFormat format;
|
||||
|
||||
FloatingActionButton editButton;
|
||||
@@ -78,9 +84,20 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
Guideline centerGuideline;
|
||||
SeekBar barcodeScaler;
|
||||
|
||||
Bitmap frontImageBitmap;
|
||||
Bitmap backImageBitmap;
|
||||
|
||||
boolean starred;
|
||||
boolean backgroundNeedsDarkIcons;
|
||||
boolean barcodeIsFullscreen = false;
|
||||
FullscreenType fullscreenType = FullscreenType.NONE;
|
||||
boolean isBarcodeSupported = true;
|
||||
|
||||
enum FullscreenType {
|
||||
NONE,
|
||||
BARCODE,
|
||||
IMAGE_FRONT,
|
||||
IMAGE_BACK
|
||||
}
|
||||
|
||||
private void extractIntentFields(Intent intent)
|
||||
{
|
||||
@@ -122,7 +139,12 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
|
||||
cardIdFieldView = findViewById(R.id.cardIdView);
|
||||
bottomSheet = findViewById(R.id.bottom_sheet);
|
||||
bottomSheetContentWrapper = findViewById(R.id.bottomSheetContentWrapper);
|
||||
bottomSheetButton = findViewById(R.id.bottomSheetButton);
|
||||
frontImageView = findViewById(R.id.frontImageView);
|
||||
frontImage = findViewById(R.id.frontImage);
|
||||
backImageView = findViewById(R.id.backImageView);
|
||||
backImage = findViewById(R.id.backImage);
|
||||
noteView = findViewById(R.id.noteView);
|
||||
groupsView = findViewById(R.id.groupsView);
|
||||
balanceView = findViewById(R.id.balanceView);
|
||||
@@ -146,7 +168,9 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
float scale = (float) progress / (float) barcodeScaler.getMax();
|
||||
Log.d(TAG, "Scaling to " + scale);
|
||||
|
||||
redrawBarcodeAfterResize();
|
||||
if (fullscreenType == FullscreenType.BARCODE) {
|
||||
redrawBarcodeAfterResize();
|
||||
}
|
||||
centerGuideline.setGuidelinePercent(0.5f * scale);
|
||||
}
|
||||
|
||||
@@ -164,18 +188,29 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
rotationEnabled = true;
|
||||
|
||||
// Allow making barcode fullscreen on tap
|
||||
maximizeButton.setOnClickListener(v -> setFullscreen(true));
|
||||
maximizeButton.setOnClickListener(v -> setFullscreen(FullscreenType.BARCODE));
|
||||
barcodeImage.setOnClickListener(view -> {
|
||||
if (barcodeIsFullscreen)
|
||||
{
|
||||
setFullscreen(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
setFullscreen(true);
|
||||
if (fullscreenType != FullscreenType.NONE) {
|
||||
setFullscreen(FullscreenType.NONE);
|
||||
} else {
|
||||
setFullscreen(FullscreenType.BARCODE);
|
||||
}
|
||||
});
|
||||
minimizeButton.setOnClickListener(v -> setFullscreen(false));
|
||||
frontImageView.setOnClickListener(view -> {
|
||||
if (fullscreenType != FullscreenType.IMAGE_FRONT) {
|
||||
setFullscreen(FullscreenType.IMAGE_FRONT);
|
||||
} else {
|
||||
setFullscreen(FullscreenType.NONE);
|
||||
}
|
||||
});
|
||||
backImageView.setOnClickListener(view -> {
|
||||
if (fullscreenType != FullscreenType.IMAGE_BACK) {
|
||||
setFullscreen(FullscreenType.IMAGE_BACK);
|
||||
} else {
|
||||
setFullscreen(FullscreenType.NONE);
|
||||
}
|
||||
});
|
||||
minimizeButton.setOnClickListener(v -> setFullscreen(FullscreenType.NONE));
|
||||
|
||||
editButton = findViewById(R.id.fabEdit);
|
||||
editButton.setOnClickListener(v -> {
|
||||
@@ -187,6 +222,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
startActivity(intent);
|
||||
finish();
|
||||
});
|
||||
editButton.bringToFront();
|
||||
|
||||
behavior = BottomSheetBehavior.from(bottomSheet);
|
||||
behavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
|
||||
@@ -199,7 +235,12 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
editButton.hide();
|
||||
} else if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
|
||||
bottomSheetButton.setImageResource(R.drawable.ic_baseline_arrow_drop_up_24);
|
||||
editButton.show();
|
||||
if (fullscreenType == FullscreenType.NONE) {
|
||||
editButton.show();
|
||||
}
|
||||
|
||||
// Scroll bottomsheet content back to top
|
||||
bottomSheetContentWrapper.setScrollY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,6 +255,25 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
||||
}
|
||||
});
|
||||
|
||||
// Fix bottom sheet content sizing
|
||||
ViewTreeObserver viewTreeObserver = bottomSheet.getViewTreeObserver();
|
||||
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
bottomSheet.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
|
||||
int height = displayMetrics.heightPixels;
|
||||
int maxHeight = height - appBarLayout.getHeight() - bottomSheetButton.getHeight();
|
||||
Log.d(TAG, "Button sheet should be " + maxHeight + " pixels high");
|
||||
bottomSheetContentWrapper.setLayoutParams(
|
||||
new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
maxHeight
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -268,19 +328,36 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
|
||||
setupOrientation();
|
||||
|
||||
String formatString = loyaltyCard.barcodeType;
|
||||
format = !formatString.isEmpty() ? BarcodeFormat.valueOf(formatString) : null;
|
||||
format = loyaltyCard.barcodeType;
|
||||
cardIdString = loyaltyCard.cardId;
|
||||
barcodeIdString = loyaltyCard.barcodeId;
|
||||
|
||||
cardIdFieldView.setText(loyaltyCard.cardId);
|
||||
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(cardIdFieldView,
|
||||
getResources().getInteger(R.integer.settings_card_id_min_font_size_sp)-1, settings.getCardIdFontSize(),
|
||||
settings.getFontSizeMin(settings.getLargeFont()), settings.getFontSizeMax(settings.getLargeFont()),
|
||||
1, TypedValue.COMPLEX_UNIT_SP);
|
||||
|
||||
frontImageBitmap = Utils.retrieveCardImage(this, loyaltyCard.id, true);
|
||||
if (frontImageBitmap != null) {
|
||||
frontImageView.setVisibility(View.VISIBLE);
|
||||
frontImage.setImageBitmap(frontImageBitmap);
|
||||
} else {
|
||||
frontImageView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
backImageBitmap = Utils.retrieveCardImage(this, loyaltyCard.id, false);
|
||||
if (backImageBitmap != null) {
|
||||
backImageView.setVisibility(View.VISIBLE);
|
||||
backImage.setImageBitmap(backImageBitmap);
|
||||
} else {
|
||||
backImageView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(loyaltyCard.note.length() > 0)
|
||||
{
|
||||
noteView.setVisibility(View.VISIBLE);
|
||||
noteView.setText(loyaltyCard.note);
|
||||
noteView.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -298,6 +375,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
|
||||
groupsView.setVisibility(View.VISIBLE);
|
||||
groupsView.setText(getString(R.string.groupsList, groupsString.toString()));
|
||||
groupsView.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -307,6 +385,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
if(!loyaltyCard.balance.equals(new BigDecimal(0))) {
|
||||
balanceView.setVisibility(View.VISIBLE);
|
||||
balanceView.setText(getString(R.string.balanceSentence, Utils.formatBalance(this, loyaltyCard.balance, loyaltyCard.balanceType)));
|
||||
balanceView.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -322,6 +401,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
expiryView.setTextColor(getResources().getColor(R.color.alert));
|
||||
}
|
||||
expiryView.setText(getString(expiryString, DateFormat.getDateInstance(DateFormat.LONG).format(loyaltyCard.expiry)));
|
||||
expiryView.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -329,12 +409,12 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
}
|
||||
expiryView.setTag(loyaltyCard.expiry);
|
||||
|
||||
if (!barcodeIsFullscreen) {
|
||||
if (fullscreenType == FullscreenType.NONE) {
|
||||
makeBottomSheetVisibleIfUseful();
|
||||
}
|
||||
|
||||
storeName.setText(loyaltyCard.store);
|
||||
storeName.setTextSize(settings.getCardTitleFontSize());
|
||||
storeName.setTextSize(settings.getFontSizeMax(settings.getLargeFont()));
|
||||
|
||||
int backgroundHeaderColor;
|
||||
if(loyaltyCard.headerColor != null)
|
||||
@@ -382,9 +462,15 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
// Set shadow colour of store text so even same color on same color would be readable
|
||||
storeName.setShadowLayer(1, 1, 1, backgroundNeedsDarkIcons ? Color.BLACK : Color.WHITE);
|
||||
|
||||
if(format != null)
|
||||
if (format != null && !BarcodeSelectorActivity.SUPPORTED_BARCODE_TYPES.contains(format.name())) {
|
||||
isBarcodeSupported = false;
|
||||
|
||||
Toast.makeText(this, getString(R.string.unsupportedBarcodeType), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
if(format != null && isBarcodeSupported)
|
||||
{
|
||||
if (!barcodeIsFullscreen) {
|
||||
if (fullscreenType == FullscreenType.NONE) {
|
||||
maximizeButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
barcodeImage.setVisibility(View.VISIBLE);
|
||||
@@ -398,11 +484,18 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
else
|
||||
{
|
||||
Log.d(TAG, "ImageView size known known, creating barcode");
|
||||
new BarcodeImageWriterTask(barcodeImage, cardIdString, format).execute();
|
||||
new BarcodeImageWriterTask(
|
||||
barcodeImage,
|
||||
barcodeIdString != null ? barcodeIdString : cardIdString,
|
||||
format,
|
||||
null,
|
||||
false,
|
||||
null)
|
||||
.execute();
|
||||
}
|
||||
|
||||
// Force redraw fullscreen state
|
||||
setFullscreen(barcodeIsFullscreen);
|
||||
setFullscreen(fullscreenType);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -413,9 +506,9 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (barcodeIsFullscreen)
|
||||
if (fullscreenType != FullscreenType.NONE)
|
||||
{
|
||||
setFullscreen(false);
|
||||
setFullscreen(FullscreenType.NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -471,7 +564,12 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
break;
|
||||
|
||||
case R.id.action_share:
|
||||
importURIHelper.startShareIntent(loyaltyCard);
|
||||
try {
|
||||
importURIHelper.startShareIntent(Arrays.asList(loyaltyCard));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
Toast.makeText(LoyaltyCardViewActivity.this, R.string.failedGeneratingShareURL, Toast.LENGTH_LONG).show();
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
|
||||
case R.id.action_lock_unlock:
|
||||
@@ -549,7 +647,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
|
||||
private void makeBottomSheetVisibleIfUseful()
|
||||
{
|
||||
if (noteView.getVisibility() == View.VISIBLE || groupsView.getVisibility() == View.VISIBLE || balanceView.getVisibility() == View.VISIBLE || expiryView.getVisibility() == View.VISIBLE) {
|
||||
if (frontImageView.getVisibility() == View.VISIBLE || backImageView.getVisibility() == View.VISIBLE || noteView.getVisibility() == View.VISIBLE || groupsView.getVisibility() == View.VISIBLE || balanceView.getVisibility() == View.VISIBLE || expiryView.getVisibility() == View.VISIBLE) {
|
||||
bottomSheet.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else
|
||||
@@ -568,7 +666,14 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
barcodeImage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
|
||||
Log.d(TAG, "ImageView size now known");
|
||||
new BarcodeImageWriterTask(barcodeImage, cardIdString, format).execute();
|
||||
new BarcodeImageWriterTask(
|
||||
barcodeImage,
|
||||
barcodeIdString != null ? barcodeIdString : cardIdString,
|
||||
format,
|
||||
null,
|
||||
false,
|
||||
null)
|
||||
.execute();
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -580,14 +685,22 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
* The purpose of this function is to make sure the barcode can be scanned from the phone
|
||||
* by machines which offer no space to insert the complete device.
|
||||
*/
|
||||
private void setFullscreen(boolean enable)
|
||||
private void setFullscreen(FullscreenType fullscreenType)
|
||||
{
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(enable)
|
||||
{
|
||||
Log.d(TAG, "Move into of fullscreen");
|
||||
// Prepare redraw after size change
|
||||
redrawBarcodeAfterResize();
|
||||
if (fullscreenType != FullscreenType.NONE) {
|
||||
Log.d(TAG, "Move into fullscreen");
|
||||
|
||||
if (fullscreenType == FullscreenType.IMAGE_FRONT) {
|
||||
barcodeImage.setImageBitmap(frontImageBitmap);
|
||||
barcodeImage.setVisibility(View.VISIBLE);
|
||||
} else if (fullscreenType == FullscreenType.IMAGE_BACK) {
|
||||
barcodeImage.setImageBitmap(backImageBitmap);
|
||||
barcodeImage.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
// Prepare redraw after size change
|
||||
redrawBarcodeAfterResize();
|
||||
}
|
||||
|
||||
// Hide maximize and show minimize button and scaler
|
||||
maximizeButton.setVisibility(View.GONE);
|
||||
@@ -606,7 +719,6 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
// Or the barcode will be centered instead of on top of the screen
|
||||
// Don't ask me why...
|
||||
appBarLayout.setVisibility(View.INVISIBLE);
|
||||
appBarLayout.setPadding(0, 0, 0, 0);
|
||||
collapsingToolbarLayout.setVisibility(View.GONE);
|
||||
findViewById(R.id.toolbar_landscape).setVisibility(View.GONE);
|
||||
|
||||
@@ -622,11 +734,8 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
);
|
||||
|
||||
// Set current state
|
||||
barcodeIsFullscreen = true;
|
||||
}
|
||||
else if(!enable)
|
||||
else
|
||||
{
|
||||
Log.d(TAG, "Move out of fullscreen");
|
||||
|
||||
@@ -634,10 +743,16 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
barcodeScaler.setProgress(100);
|
||||
|
||||
// Prepare redraw after size change
|
||||
redrawBarcodeAfterResize();
|
||||
if (format != null && isBarcodeSupported) {
|
||||
redrawBarcodeAfterResize();
|
||||
} else {
|
||||
barcodeImage.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Show maximize and hide minimize button and scaler
|
||||
maximizeButton.setVisibility(View.VISIBLE);
|
||||
if (format != null && isBarcodeSupported) {
|
||||
maximizeButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
minimizeButton.setVisibility(View.GONE);
|
||||
barcodeScaler.setVisibility(View.GONE);
|
||||
|
||||
@@ -652,7 +767,6 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
appBarLayout.setVisibility(View.VISIBLE);
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
appBarLayout.setPadding(0, (int) Math.ceil(metrics.density * 24), 0, 0);
|
||||
setupOrientation();
|
||||
|
||||
// Show other UI elements
|
||||
@@ -666,9 +780,8 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
& ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
& ~View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
);
|
||||
|
||||
// Set current state
|
||||
barcodeIsFullscreen = false;
|
||||
}
|
||||
|
||||
this.fullscreenType = fullscreenType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +1,163 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.SearchManager;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.view.ActionMode;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import protect.card_locker.preferences.SettingsActivity;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener
|
||||
public class MainActivity extends AppCompatActivity implements LoyaltyCardCursorAdapter.CardAdapterListener, GestureDetector.OnGestureListener
|
||||
{
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
private Menu menu;
|
||||
private GestureDetector gestureDetector;
|
||||
protected String filter = "";
|
||||
private final DBHelper mDB = new DBHelper(this);
|
||||
private LoyaltyCardCursorAdapter mAdapter;
|
||||
private ActionMode mCurrentActionMode;
|
||||
private Menu mMenu;
|
||||
private GestureDetector mGestureDetector;
|
||||
protected String mFilter = "";
|
||||
protected int selectedTab = 0;
|
||||
private RecyclerView mCardList;
|
||||
|
||||
private ActionMode.Callback mCurrentActionModeCallback = new ActionMode.Callback()
|
||||
{
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode inputMode, Menu inputMenu)
|
||||
{
|
||||
inputMode.getMenuInflater().inflate(R.menu.card_longclick_menu, inputMenu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode inputMode, Menu inputMenu)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode inputMode, MenuItem inputItem)
|
||||
{
|
||||
if (inputItem.getItemId() == R.id.action_copy_to_clipboard)
|
||||
{
|
||||
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
|
||||
String clipboardData;
|
||||
int cardCount = mAdapter.getSelectedItemCount();
|
||||
|
||||
if (cardCount == 1) {
|
||||
clipboardData = mAdapter.getSelectedItems().get(0).cardId;
|
||||
} else {
|
||||
StringBuilder cardIds = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < cardCount; i++) {
|
||||
LoyaltyCard loyaltyCard = mAdapter.getSelectedItems().get(i);
|
||||
|
||||
cardIds.append(loyaltyCard.store + ": " + loyaltyCard.cardId);
|
||||
if (i < (cardCount - 1)) {
|
||||
cardIds.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
clipboardData = cardIds.toString();
|
||||
}
|
||||
|
||||
ClipData clip = ClipData.newPlainText(getString(R.string.card_ids_copied), clipboardData);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
Toast.makeText(MainActivity.this, cardCount > 1 ? R.string.copy_to_clipboard_multiple_toast : R.string.copy_to_clipboard_toast, Toast.LENGTH_LONG).show();
|
||||
inputMode.finish();
|
||||
return true;
|
||||
}
|
||||
else if (inputItem.getItemId() == R.id.action_share)
|
||||
{
|
||||
final ImportURIHelper importURIHelper = new ImportURIHelper(MainActivity.this);
|
||||
try {
|
||||
importURIHelper.startShareIntent(mAdapter.getSelectedItems());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
Toast.makeText(MainActivity.this, R.string.failedGeneratingShareURL, Toast.LENGTH_LONG).show();
|
||||
e.printStackTrace();
|
||||
}
|
||||
inputMode.finish();
|
||||
return true;
|
||||
}
|
||||
else if(inputItem.getItemId() == R.id.action_edit)
|
||||
{
|
||||
if (mAdapter.getSelectedItemCount() != 1) {
|
||||
throw new IllegalArgumentException("Cannot edit more than 1 card at a time");
|
||||
}
|
||||
|
||||
Intent intent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt("id", mAdapter.getSelectedItems().get(0).id);
|
||||
bundle.putBoolean("update", true);
|
||||
intent.putExtras(bundle);
|
||||
startActivity(intent);
|
||||
inputMode.finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode inputMode)
|
||||
{
|
||||
mAdapter.clearSelections();
|
||||
mCurrentActionMode = null;
|
||||
mCardList.post(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
mAdapter.resetAnimationIndex();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
protected void onCreate(Bundle inputSavedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
super.onCreate(inputSavedInstanceState);
|
||||
setContentView(R.layout.main_activity);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
updateLoyaltyCardList(filter, null);
|
||||
updateLoyaltyCardList(mFilter, null);
|
||||
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
groupsTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
selectedTab = tab.getPosition();
|
||||
updateLoyaltyCardList(filter, tab.getTag());
|
||||
updateLoyaltyCardList(mFilter, tab.getTag());
|
||||
|
||||
// Store active tab in Shared Preference to restore next app launch
|
||||
SharedPreferences activeTabPref = getApplicationContext().getSharedPreferences(
|
||||
@@ -79,12 +179,12 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
}
|
||||
});
|
||||
|
||||
gestureDetector = new GestureDetector(this, this);
|
||||
mGestureDetector = new GestureDetector(this, this);
|
||||
|
||||
View.OnTouchListener gestureTouchListener = new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(final View v, final MotionEvent event){
|
||||
return gestureDetector.onTouchEvent(event);
|
||||
return mGestureDetector.onTouchEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -96,11 +196,18 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
noMatchingCardsText.setOnTouchListener(gestureTouchListener);
|
||||
list.setOnTouchListener(gestureTouchListener);
|
||||
|
||||
/*
|
||||
* This was added for Huawei, but Huawei is just too much of a fucking pain.
|
||||
* Just leaving this commented out if needed for the future idk
|
||||
* https://twitter.com/SylvieLorxu/status/1379437902741012483
|
||||
*
|
||||
|
||||
// Show privacy policy on first run
|
||||
SharedPreferences privacyPolicyShownPref = getApplicationContext().getSharedPreferences(
|
||||
getString(R.string.sharedpreference_privacy_policy_shown),
|
||||
Context.MODE_PRIVATE);
|
||||
|
||||
|
||||
if (privacyPolicyShownPref.getInt(getString(R.string.sharedpreference_privacy_policy_shown), 0) == 0) {
|
||||
SharedPreferences.Editor privacyPolicyShownPrefEditor = privacyPolicyShownPref.edit();
|
||||
privacyPolicyShownPrefEditor.putInt(getString(R.string.sharedpreference_privacy_policy_shown), 1);
|
||||
@@ -117,19 +224,28 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
})
|
||||
.setIcon(android.R.drawable.ic_dialog_info)
|
||||
.show();
|
||||
};
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
|
||||
if (menu != null)
|
||||
if(mCurrentActionMode != null)
|
||||
{
|
||||
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
|
||||
mAdapter.clearSelections();
|
||||
mCurrentActionMode.finish();
|
||||
}
|
||||
|
||||
if (!searchView.isIconified()) {
|
||||
filter = searchView.getQuery().toString();
|
||||
if (mMenu != null)
|
||||
{
|
||||
SearchView searchView = (SearchView) mMenu.findItem(R.id.action_search).getActionView();
|
||||
|
||||
if (!searchView.isIconified())
|
||||
{
|
||||
mFilter = searchView.getQuery().toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,17 +271,15 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
assert tab != null;
|
||||
group = tab.getTag();
|
||||
}
|
||||
updateLoyaltyCardList(filter, group);
|
||||
updateLoyaltyCardList(mFilter, group);
|
||||
// End of active tab logic
|
||||
|
||||
FloatingActionButton addButton = findViewById(R.id.fabAdd);
|
||||
addButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent i = new Intent(getApplicationContext(), ScanActivity.class);
|
||||
startActivityForResult(i, Utils.BARCODE_SCAN);
|
||||
}
|
||||
addButton.setOnClickListener(v -> {
|
||||
Intent i = new Intent(getApplicationContext(), ScanActivity.class);
|
||||
startActivityForResult(i, Utils.BARCODE_SCAN);
|
||||
});
|
||||
addButton.bringToFront();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,14 +289,12 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
if (requestCode == Utils.MAIN_REQUEST) {
|
||||
// We're coming back from another view so clear the search
|
||||
// We only do this now to prevent a flash of all entries right after picking one
|
||||
filter = "";
|
||||
if (menu != null)
|
||||
mFilter = "";
|
||||
if (mMenu != null)
|
||||
{
|
||||
MenuItem searchItem = menu.findItem(R.id.action_search);
|
||||
MenuItem searchItem = mMenu.findItem(R.id.action_search);
|
||||
searchItem.collapseActionView();
|
||||
}
|
||||
|
||||
// In case the theme changed
|
||||
recreate();
|
||||
|
||||
return;
|
||||
@@ -201,16 +313,18 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (menu == null)
|
||||
public void onBackPressed()
|
||||
{
|
||||
if (mMenu == null)
|
||||
{
|
||||
super.onBackPressed();
|
||||
return;
|
||||
}
|
||||
|
||||
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
|
||||
SearchView searchView = (SearchView) mMenu.findItem(R.id.action_search).getActionView();
|
||||
|
||||
if (!searchView.isIconified()) {
|
||||
if (!searchView.isIconified())
|
||||
{
|
||||
searchView.setIconified(true);
|
||||
} else {
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
@@ -231,21 +345,29 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
group = (Group) tag;
|
||||
}
|
||||
|
||||
final ListView cardList = findViewById(R.id.list);
|
||||
mCardList = findViewById(R.id.list);
|
||||
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
|
||||
mCardList.setLayoutManager(mLayoutManager);
|
||||
mCardList.setItemAnimator(new DefaultItemAnimator());
|
||||
|
||||
final TextView helpText = findViewById(R.id.helpText);
|
||||
final TextView noMatchingCardsText = findViewById(R.id.noMatchingCardsText);
|
||||
final DBHelper db = new DBHelper(this);
|
||||
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor(filterText, group);
|
||||
Cursor cardCursor = mDB.getLoyaltyCardCursor(filterText, group);
|
||||
|
||||
if(db.getLoyaltyCardCount() > 0)
|
||||
mAdapter = new LoyaltyCardCursorAdapter(this, cardCursor, this);
|
||||
mCardList.setAdapter(mAdapter);
|
||||
|
||||
registerForContextMenu(mCardList);
|
||||
|
||||
if(mDB.getLoyaltyCardCount() > 0)
|
||||
{
|
||||
// We want the cardList to be visible regardless of the filtered match count
|
||||
// to ensure that the noMatchingCardsText doesn't end up being shown below
|
||||
// the keyboard
|
||||
cardList.setVisibility(View.VISIBLE);
|
||||
mCardList.setVisibility(View.VISIBLE);
|
||||
helpText.setVisibility(View.GONE);
|
||||
if(cardCursor.getCount() > 0)
|
||||
if(mAdapter.getItemCount() > 0)
|
||||
{
|
||||
noMatchingCardsText.setVisibility(View.GONE);
|
||||
}
|
||||
@@ -256,35 +378,14 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
}
|
||||
else
|
||||
{
|
||||
cardList.setVisibility(View.GONE);
|
||||
mCardList.setVisibility(View.GONE);
|
||||
helpText.setVisibility(View.VISIBLE);
|
||||
noMatchingCardsText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor);
|
||||
cardList.setAdapter(adapter);
|
||||
|
||||
registerForContextMenu(cardList);
|
||||
|
||||
cardList.setOnItemClickListener(new AdapterView.OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
Cursor selected = (Cursor) parent.getItemAtPosition(position);
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
|
||||
|
||||
Intent i = new Intent(view.getContext(), LoyaltyCardViewActivity.class);
|
||||
i.setAction("");
|
||||
final Bundle b = new Bundle();
|
||||
b.putInt("id", loyaltyCard.id);
|
||||
i.putExtras(b);
|
||||
|
||||
ShortcutHelper.updateShortcuts(MainActivity.this, loyaltyCard, i);
|
||||
|
||||
startActivityForResult(i, Utils.MAIN_REQUEST);
|
||||
}
|
||||
});
|
||||
if (mCurrentActionMode != null) {
|
||||
mCurrentActionMode.finish();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateTabGroups(TabLayout groupsTabLayout)
|
||||
@@ -319,86 +420,48 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
private void openPrivacyPolicy() {
|
||||
Intent browserIntent = new Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse("https://thelastproject.github.io/Catima/privacy-policy")
|
||||
Uri.parse("https://catima.app/privacy-policy")
|
||||
);
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
|
||||
public boolean onCreateOptionsMenu(Menu inputMenu)
|
||||
{
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
if (v.getId()==R.id.list)
|
||||
{
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.card_longclick_menu, menu);
|
||||
}
|
||||
}
|
||||
this.mMenu = inputMenu;
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item)
|
||||
{
|
||||
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
|
||||
ListView listView = findViewById(R.id.list);
|
||||
|
||||
Cursor cardCursor = (Cursor)listView.getItemAtPosition(info.position);
|
||||
LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cardCursor);
|
||||
|
||||
if(item.getItemId() == R.id.action_clipboard)
|
||||
{
|
||||
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText(card.store, card.cardId);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
|
||||
Toast.makeText(this, R.string.copy_to_clipboard_toast, Toast.LENGTH_LONG).show();
|
||||
return true;
|
||||
}
|
||||
else if(item.getItemId() == R.id.action_share)
|
||||
{
|
||||
final ImportURIHelper importURIHelper = new ImportURIHelper(this);
|
||||
importURIHelper.startShareIntent(card);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
this.menu = menu;
|
||||
|
||||
getMenuInflater().inflate(R.menu.main_menu, menu);
|
||||
getMenuInflater().inflate(R.menu.main_menu, inputMenu);
|
||||
|
||||
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
|
||||
if (searchManager != null) {
|
||||
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
|
||||
if (searchManager != null)
|
||||
{
|
||||
SearchView searchView = (SearchView) inputMenu.findItem(R.id.action_search).getActionView();
|
||||
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
|
||||
searchView.setSubmitButtonEnabled(false);
|
||||
|
||||
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
|
||||
@Override
|
||||
public boolean onClose() {
|
||||
invalidateOptionsMenu();
|
||||
return false;
|
||||
}
|
||||
searchView.setOnCloseListener(() -> {
|
||||
invalidateOptionsMenu();
|
||||
return false;
|
||||
});
|
||||
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
|
||||
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
public boolean onQueryTextSubmit(String query)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
filter = newText;
|
||||
public boolean onQueryTextChange(String newText)
|
||||
{
|
||||
mFilter = newText;
|
||||
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
TabLayout.Tab currentTab = groupsTabLayout.getTabAt(groupsTabLayout.getSelectedTabPosition());
|
||||
|
||||
updateLoyaltyCardList(
|
||||
newText,
|
||||
mFilter,
|
||||
currentTab != null ? currentTab.getTag() : null
|
||||
);
|
||||
|
||||
@@ -406,14 +469,13 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
return super.onCreateOptionsMenu(inputMenu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
public boolean onOptionsItemSelected(MenuItem inputItem)
|
||||
{
|
||||
int id = item.getItemId();
|
||||
int id = inputItem.getItemId();
|
||||
|
||||
if (id == R.id.action_manage_groups)
|
||||
{
|
||||
@@ -422,14 +484,14 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
return true;
|
||||
}
|
||||
|
||||
if(id == R.id.action_import_export)
|
||||
if (id == R.id.action_import_export)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), ImportExportActivity.class);
|
||||
startActivityForResult(i, Utils.MAIN_REQUEST);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(id == R.id.action_settings)
|
||||
if (id == R.id.action_settings)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), SettingsActivity.class);
|
||||
startActivityForResult(i, Utils.MAIN_REQUEST);
|
||||
@@ -442,14 +504,14 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
return true;
|
||||
}
|
||||
|
||||
if(id == R.id.action_about)
|
||||
if (id == R.id.action_about)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), AboutActivity.class);
|
||||
startActivityForResult(i, Utils.MAIN_REQUEST);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
return super.onOptionsItemSelected(inputItem);
|
||||
}
|
||||
|
||||
protected static boolean isDarkModeEnabled(Context inputContext)
|
||||
@@ -528,4 +590,79 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRowLongClicked(int inputPosition)
|
||||
{
|
||||
enableActionMode(inputPosition);
|
||||
}
|
||||
|
||||
private void enableActionMode(int inputPosition)
|
||||
{
|
||||
if (mCurrentActionMode == null)
|
||||
{
|
||||
mCurrentActionMode = startSupportActionMode(mCurrentActionModeCallback);
|
||||
}
|
||||
toggleSelection(inputPosition);
|
||||
}
|
||||
|
||||
private void toggleSelection(int inputPosition)
|
||||
{
|
||||
mAdapter.toggleSelection(inputPosition);
|
||||
int count = mAdapter.getSelectedItemCount();
|
||||
|
||||
if (count == 0) {
|
||||
mCurrentActionMode.finish();
|
||||
} else {
|
||||
mCurrentActionMode.setTitle(getResources().getQuantityString(R.plurals.selectedCardCount, count, count));
|
||||
|
||||
MenuItem editItem = mCurrentActionMode.getMenu().findItem(R.id.action_edit);
|
||||
if (count == 1) {
|
||||
editItem.setVisible(true);
|
||||
editItem.setEnabled(true);
|
||||
} else {
|
||||
editItem.setVisible(false);
|
||||
editItem.setEnabled(false);
|
||||
}
|
||||
|
||||
mCurrentActionMode.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIconClicked(int inputPosition)
|
||||
{
|
||||
if (mCurrentActionMode == null)
|
||||
{
|
||||
mCurrentActionMode = startSupportActionMode(mCurrentActionModeCallback);
|
||||
}
|
||||
|
||||
toggleSelection(inputPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRowClicked(int inputPosition)
|
||||
{
|
||||
|
||||
if (mAdapter.getSelectedItemCount() > 0)
|
||||
{
|
||||
enableActionMode(inputPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cursor selected = mAdapter.getCursor();
|
||||
selected.moveToPosition(inputPosition);
|
||||
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
|
||||
|
||||
Intent i = new Intent(this, LoyaltyCardViewActivity.class);
|
||||
i.setAction("");
|
||||
final Bundle b = new Bundle();
|
||||
b.putInt("id", loyaltyCard.id);
|
||||
i.putExtras(b);
|
||||
|
||||
ShortcutHelper.updateShortcuts(MainActivity.this, loyaltyCard, i);
|
||||
|
||||
startActivityForResult(i, Utils.MAIN_REQUEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,12 +52,8 @@ public class ManageGroupsActivity extends AppCompatActivity
|
||||
updateGroupList();
|
||||
|
||||
FloatingActionButton addButton = findViewById(R.id.fabAdd);
|
||||
addButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
createGroup();
|
||||
}
|
||||
});
|
||||
addButton.setOnClickListener(v -> createGroup());
|
||||
addButton.bringToFront();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,9 +2,11 @@ package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
@@ -34,6 +36,7 @@ public class ScanActivity extends AppCompatActivity {
|
||||
private DecoratedBarcodeView barcodeScannerView;
|
||||
|
||||
private String cardId;
|
||||
private boolean torch = false;
|
||||
|
||||
private void extractIntentFields(Intent intent) {
|
||||
final Bundle b = intent.getExtras();
|
||||
@@ -114,6 +117,18 @@ public class ScanActivity extends AppCompatActivity {
|
||||
return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
|
||||
getMenuInflater().inflate(R.menu.scan_menu, menu);
|
||||
}
|
||||
|
||||
barcodeScannerView.setTorchOff();
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
@@ -122,6 +137,19 @@ public class ScanActivity extends AppCompatActivity {
|
||||
setResult(Activity.RESULT_CANCELED);
|
||||
finish();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_toggle_flashlight)
|
||||
{
|
||||
if (torch) {
|
||||
torch = false;
|
||||
barcodeScannerView.setTorchOff();
|
||||
item.setTitle(R.string.turn_flashlight_on);
|
||||
item.setIcon(R.drawable.ic_flashlight_off_white_24dp);
|
||||
} else {
|
||||
torch = true;
|
||||
barcodeScannerView.setTorchOn();
|
||||
item.setTitle(R.string.turn_flashlight_off);
|
||||
item.setIcon(R.drawable.ic_flashlight_on_white_24dp);
|
||||
}
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Build;
|
||||
|
||||
@@ -37,6 +38,8 @@ class ShortcutHelper
|
||||
ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
|
||||
LinkedList<ShortcutInfo> list = new LinkedList<>(shortcutManager.getDynamicShortcuts());
|
||||
|
||||
DBHelper dbHelper = new DBHelper(context);
|
||||
|
||||
String shortcutId = Integer.toString(card.id);
|
||||
|
||||
// Sort the shortcuts by rank, so working with the relative order will be easier.
|
||||
@@ -105,6 +108,14 @@ class ShortcutHelper
|
||||
|
||||
Intent shortcutIntent = prevShortcut.getIntent();
|
||||
|
||||
Bitmap iconBitmap = Utils.generateIcon(context, dbHelper.getLoyaltyCard(Integer.parseInt(prevShortcut.getId())), true).getLetterTile();
|
||||
Icon icon;
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
icon = Icon.createWithAdaptiveBitmap(iconBitmap);
|
||||
} else {
|
||||
icon = Icon.createWithBitmap(iconBitmap);
|
||||
}
|
||||
|
||||
// Prevent instances of the view activity from piling up; if one exists let this
|
||||
// one replace it.
|
||||
shortcutIntent.setFlags(shortcutIntent.getFlags() | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
@@ -113,7 +124,7 @@ class ShortcutHelper
|
||||
.setShortLabel(prevShortcut.getShortLabel())
|
||||
.setLongLabel(prevShortcut.getLongLabel())
|
||||
.setIntent(shortcutIntent)
|
||||
.setIcon(Icon.createWithResource(context, R.drawable.circle))
|
||||
.setIcon(icon)
|
||||
.setRank(index)
|
||||
.build();
|
||||
|
||||
|
||||
25
app/src/main/java/protect/card_locker/ThirdPartyInfo.java
Normal file
25
app/src/main/java/protect/card_locker/ThirdPartyInfo.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package protect.card_locker;
|
||||
|
||||
public class ThirdPartyInfo {
|
||||
private final String mName;
|
||||
private final String mUrl;
|
||||
private final String mLicense;
|
||||
|
||||
public ThirdPartyInfo(String name, String url, String license) {
|
||||
mName = name;
|
||||
mUrl = url;
|
||||
mLicense = license;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public String url() {
|
||||
return mUrl;
|
||||
}
|
||||
|
||||
public String license() {
|
||||
return mLicense;
|
||||
}
|
||||
}
|
||||
@@ -4,22 +4,14 @@ import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.media.ExifInterface;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.LuminanceSource;
|
||||
import com.google.zxing.MultiFormatReader;
|
||||
@@ -28,6 +20,21 @@ import com.google.zxing.RGBLuminanceSource;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
public class Utils {
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
@@ -36,15 +43,35 @@ public class Utils {
|
||||
public static final int SELECT_BARCODE_REQUEST = 2;
|
||||
public static final int BARCODE_SCAN = 3;
|
||||
public static final int BARCODE_IMPORT_FROM_IMAGE_FILE = 4;
|
||||
public static final int CARD_IMAGE_FROM_CAMERA_FRONT = 5;
|
||||
public static final int CARD_IMAGE_FROM_CAMERA_BACK = 6;
|
||||
public static final int CARD_IMAGE_FROM_FILE_FRONT = 7;
|
||||
public static final int CARD_IMAGE_FROM_FILE_BACK = 8;
|
||||
|
||||
static final double LUMINANCE_MIDPOINT = 0.5;
|
||||
|
||||
static final int BITMAP_SIZE_BIG = 512;
|
||||
|
||||
static public LetterBitmap generateIcon(Context context, LoyaltyCard loyaltyCard, boolean forShortcut) {
|
||||
return generateIcon(context, loyaltyCard.store, loyaltyCard.headerColor, forShortcut);
|
||||
}
|
||||
|
||||
static public LetterBitmap generateIcon(Context context, String store, Integer backgroundColor) {
|
||||
return generateIcon(context, store, backgroundColor, false);
|
||||
}
|
||||
|
||||
static public LetterBitmap generateIcon(Context context, String store, Integer backgroundColor, boolean forShortcut) {
|
||||
if (store.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int tileLetterFontSize = context.getResources().getDimensionPixelSize(R.dimen.tileLetterFontSize);
|
||||
int tileLetterFontSize;
|
||||
if (forShortcut) {
|
||||
tileLetterFontSize = context.getResources().getDimensionPixelSize(R.dimen.tileLetterFontSizeForShortcut);
|
||||
} else {
|
||||
tileLetterFontSize = context.getResources().getDimensionPixelSize(R.dimen.tileLetterFontSize);
|
||||
}
|
||||
|
||||
int pixelSize = context.getResources().getDimensionPixelSize(R.dimen.cardThumbnailSize);
|
||||
|
||||
if (backgroundColor == null) {
|
||||
@@ -199,4 +226,121 @@ public class Utils {
|
||||
// Parse as BigDecimal
|
||||
return new BigDecimal(value);
|
||||
}
|
||||
|
||||
static public byte[] bitmapToByteArray(Bitmap bitmap) {
|
||||
if (bitmap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
|
||||
return bos.toByteArray();
|
||||
}
|
||||
|
||||
static public Bitmap resizeBitmap(Bitmap bitmap) {
|
||||
if (bitmap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer maxSize = BITMAP_SIZE_BIG;
|
||||
|
||||
Integer width = bitmap.getWidth();
|
||||
Integer height = bitmap.getHeight();
|
||||
|
||||
if (height > width) {
|
||||
Integer scale = height / maxSize;
|
||||
height = maxSize;
|
||||
width = width / scale;
|
||||
} else if (width > height) {
|
||||
Integer scale = width / maxSize;
|
||||
width = maxSize;
|
||||
height = height / scale;
|
||||
} else {
|
||||
height = maxSize;
|
||||
width = maxSize;
|
||||
}
|
||||
|
||||
return Bitmap.createScaledBitmap(bitmap, width, height, true);
|
||||
}
|
||||
|
||||
static public Bitmap rotateBitmap(Bitmap bitmap, ExifInterface exifInterface) {
|
||||
switch (exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)) {
|
||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||||
return rotateBitmap(bitmap, 90f);
|
||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||||
return rotateBitmap(bitmap, 180f);
|
||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||||
return rotateBitmap(bitmap, 270f);
|
||||
default:
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
static public Bitmap rotateBitmap(Bitmap bitmap, float rotation) {
|
||||
if (rotation == 0) {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postRotate(rotation);
|
||||
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
}
|
||||
|
||||
static public String getCardImageFileName(int loyaltyCardId, boolean front) {
|
||||
StringBuilder cardImageFileNameBuilder = new StringBuilder();
|
||||
|
||||
cardImageFileNameBuilder.append("card_");
|
||||
cardImageFileNameBuilder.append(loyaltyCardId);
|
||||
cardImageFileNameBuilder.append("_");
|
||||
if (front) {
|
||||
cardImageFileNameBuilder.append("front");
|
||||
} else {
|
||||
cardImageFileNameBuilder.append("back");
|
||||
}
|
||||
cardImageFileNameBuilder.append(".png");
|
||||
|
||||
return cardImageFileNameBuilder.toString();
|
||||
}
|
||||
|
||||
static public void saveCardImage(Context context, Bitmap bitmap, String fileName) throws FileNotFoundException {
|
||||
if (bitmap == null) {
|
||||
context.deleteFile(fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
FileOutputStream out = context.openFileOutput(fileName, Context.MODE_PRIVATE);
|
||||
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
}
|
||||
|
||||
static public void saveCardImage(Context context, Bitmap bitmap, int loyaltyCardId, boolean front) throws FileNotFoundException {
|
||||
saveCardImage(context, bitmap, getCardImageFileName(loyaltyCardId, front));
|
||||
}
|
||||
|
||||
static public Bitmap retrieveCardImage(Context context, String fileName) {
|
||||
FileInputStream in;
|
||||
try {
|
||||
in = context.openFileInput(fileName);
|
||||
} catch (FileNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return BitmapFactory.decodeStream(in);
|
||||
}
|
||||
|
||||
static public Bitmap retrieveCardImage(Context context, int loyaltyCardId, boolean front) {
|
||||
return retrieveCardImage(context, getCardImageFileName(loyaltyCardId, front));
|
||||
}
|
||||
|
||||
static public Object hashmapGetOrDefault(HashMap hashMap, Object key, Object defaultValue, Class keyType) {
|
||||
Object value = hashMap.get(keyType.cast(key));
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static public Object hashmapGetOrDefault(HashMap hashMap, String key, Object defaultValue) {
|
||||
return hashmapGetOrDefault(hashMap, key, defaultValue, String.class);
|
||||
}
|
||||
}
|
||||
|
||||
35
app/src/main/java/protect/card_locker/ZipUtils.java
Normal file
35
app/src/main/java/protect/card_locker/ZipUtils.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
import net.lingala.zip4j.io.inputstream.ZipInputStream;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class ZipUtils {
|
||||
static public String read(ZipInputStream zipInputStream) throws IOException {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
Reader reader = new BufferedReader(new InputStreamReader(zipInputStream, StandardCharsets.UTF_8));
|
||||
int c;
|
||||
while ((c = reader.read()) != -1) {
|
||||
stringBuilder.append((char) c);
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
static public Bitmap readImage(ZipInputStream zipInputStream) {
|
||||
return BitmapFactory.decodeStream(zipInputStream);
|
||||
}
|
||||
|
||||
static public JSONObject readJSON(ZipInputStream zipInputStream) throws IOException, JSONException {
|
||||
return new JSONObject(read(zipInputStream));
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,92 @@
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import net.lingala.zip4j.io.outputstream.ZipOutputStream;
|
||||
import net.lingala.zip4j.model.ZipParameters;
|
||||
import net.lingala.zip4j.util.InternalZipConstants;
|
||||
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVPrinter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import protect.card_locker.DBHelper;
|
||||
import protect.card_locker.Group;
|
||||
import protect.card_locker.LoyaltyCard;
|
||||
import protect.card_locker.Utils;
|
||||
|
||||
/**
|
||||
* Class for exporting the database into CSV (Comma Separate Values)
|
||||
* format.
|
||||
*/
|
||||
public class CsvDatabaseExporter implements DatabaseExporter
|
||||
public class CatimaExporter implements Exporter
|
||||
{
|
||||
public void exportData(DBHelper db, OutputStreamWriter output) throws IOException, InterruptedException
|
||||
public void exportData(Context context, DBHelper db, OutputStream output) throws IOException, InterruptedException
|
||||
{
|
||||
// Necessary vars
|
||||
int readLen;
|
||||
byte[] readBuffer = new byte[InternalZipConstants.BUFF_SIZE];
|
||||
|
||||
// Create zip output stream
|
||||
ZipOutputStream zipOutputStream = new ZipOutputStream(output);
|
||||
|
||||
// Generate CSV
|
||||
ByteArrayOutputStream catimaOutputStream = new ByteArrayOutputStream();
|
||||
OutputStreamWriter catimaOutputStreamWriter = new OutputStreamWriter(catimaOutputStream, StandardCharsets.UTF_8);
|
||||
writeCSV(db, catimaOutputStreamWriter);
|
||||
|
||||
// Add CSV to zip file
|
||||
ZipParameters csvZipParameters = new ZipParameters();
|
||||
csvZipParameters.setFileNameInZip("catima.csv");
|
||||
zipOutputStream.putNextEntry(csvZipParameters);
|
||||
InputStream csvInputStream = new ByteArrayInputStream(catimaOutputStream.toByteArray());
|
||||
while ((readLen = csvInputStream.read(readBuffer)) != -1) {
|
||||
zipOutputStream.write(readBuffer, 0, readLen);
|
||||
}
|
||||
zipOutputStream.closeEntry();
|
||||
|
||||
// Loop over all cards again
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor();
|
||||
while(cardCursor.moveToNext())
|
||||
{
|
||||
// For each card
|
||||
LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cardCursor);
|
||||
|
||||
// Prepare looping over both front and back image
|
||||
boolean[] frontValues = new boolean[2];
|
||||
frontValues[0] = true;
|
||||
frontValues[1] = false;
|
||||
|
||||
// For each image
|
||||
for (boolean front : frontValues) {
|
||||
// If it exists, add to the .zip file
|
||||
Bitmap image = Utils.retrieveCardImage(context, card.id, front);
|
||||
if (image != null) {
|
||||
ZipParameters imageZipParameters = new ZipParameters();
|
||||
imageZipParameters.setFileNameInZip(Utils.getCardImageFileName(card.id, front));
|
||||
zipOutputStream.putNextEntry(imageZipParameters);
|
||||
InputStream imageInputStream = new ByteArrayInputStream(Utils.bitmapToByteArray(image));
|
||||
while ((readLen = imageInputStream.read(readBuffer)) != -1) {
|
||||
zipOutputStream.write(readBuffer, 0, readLen);
|
||||
}
|
||||
zipOutputStream.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zipOutputStream.close();
|
||||
}
|
||||
|
||||
private void writeCSV(DBHelper db, OutputStreamWriter output) throws IOException, InterruptedException {
|
||||
CSVPrinter printer = new CSVPrinter(output, CSVFormat.RFC4180);
|
||||
|
||||
// Print the version
|
||||
@@ -57,8 +124,9 @@ public class CsvDatabaseExporter implements DatabaseExporter
|
||||
DBHelper.LoyaltyCardDbIds.BALANCE,
|
||||
DBHelper.LoyaltyCardDbIds.BALANCE_TYPE,
|
||||
DBHelper.LoyaltyCardDbIds.CARD_ID,
|
||||
DBHelper.LoyaltyCardDbIds.HEADER_COLOR,
|
||||
DBHelper.LoyaltyCardDbIds.BARCODE_ID,
|
||||
DBHelper.LoyaltyCardDbIds.BARCODE_TYPE,
|
||||
DBHelper.LoyaltyCardDbIds.HEADER_COLOR,
|
||||
DBHelper.LoyaltyCardDbIds.STAR_STATUS);
|
||||
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor();
|
||||
@@ -74,8 +142,9 @@ public class CsvDatabaseExporter implements DatabaseExporter
|
||||
card.balance,
|
||||
card.balanceType,
|
||||
card.cardId,
|
||||
card.headerColor,
|
||||
card.barcodeId,
|
||||
card.barcodeType,
|
||||
card.headerColor,
|
||||
card.starStatus);
|
||||
|
||||
if(Thread.currentThread().isInterrupted())
|
||||
@@ -1,31 +1,35 @@
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import net.lingala.zip4j.io.inputstream.ZipInputStream;
|
||||
import net.lingala.zip4j.model.LocalFileHeader;
|
||||
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringReader;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.ParseException;
|
||||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import protect.card_locker.DBHelper;
|
||||
import protect.card_locker.FormatException;
|
||||
import protect.card_locker.Group;
|
||||
import protect.card_locker.Utils;
|
||||
import protect.card_locker.ZipUtils;
|
||||
|
||||
/**
|
||||
* Class for importing a database from CSV (Comma Separate Values)
|
||||
@@ -34,10 +38,36 @@ import protect.card_locker.Group;
|
||||
* The database's loyalty cards are expected to appear in the CSV data.
|
||||
* A header is expected for the each table showing the names of the columns.
|
||||
*/
|
||||
public class CsvDatabaseImporter implements DatabaseImporter
|
||||
public class CatimaImporter implements Importer
|
||||
{
|
||||
public void importData(DBHelper db, InputStream input) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
public void importData(Context context, DBHelper db, InputStream input, char[] password) throws IOException, FormatException, InterruptedException {
|
||||
InputStream bufferedInputStream = new BufferedInputStream(input);
|
||||
bufferedInputStream.mark(100);
|
||||
|
||||
// First, check if this is a zip file
|
||||
ZipInputStream zipInputStream = new ZipInputStream(bufferedInputStream);
|
||||
LocalFileHeader localFileHeader = zipInputStream.getNextEntry();
|
||||
|
||||
if (localFileHeader == null) {
|
||||
// This is not a zip file, try importing as bare CSV
|
||||
bufferedInputStream.reset();
|
||||
importCSV(context, db, bufferedInputStream);
|
||||
return;
|
||||
}
|
||||
|
||||
importZipFile(context, db, zipInputStream, localFileHeader);
|
||||
}
|
||||
|
||||
public void importZipFile(Context context, DBHelper db, ZipInputStream input, LocalFileHeader localFileHeader) throws IOException, FormatException, InterruptedException {
|
||||
String fileName = localFileHeader.getFileName();
|
||||
if (fileName.equals("catima.csv")) {
|
||||
importCSV(context, db, new ByteArrayInputStream(ZipUtils.read(input).getBytes(StandardCharsets.UTF_8)));
|
||||
} else {
|
||||
Utils.saveCardImage(context, ZipUtils.readImage(input), fileName);
|
||||
}
|
||||
}
|
||||
|
||||
public void importCSV(Context context, DBHelper db, InputStream input) throws IOException, FormatException, InterruptedException {
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
|
||||
|
||||
bufferedReader.mark(100);
|
||||
@@ -54,10 +84,10 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
|
||||
switch (version) {
|
||||
case 1:
|
||||
parseV1(db, bufferedReader);
|
||||
parseV1(context, db, bufferedReader);
|
||||
break;
|
||||
case 2:
|
||||
parseV2(db, bufferedReader);
|
||||
parseV2(context, db, bufferedReader);
|
||||
break;
|
||||
default:
|
||||
throw new FormatException(String.format("No code to parse version %s", version));
|
||||
@@ -66,7 +96,7 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
bufferedReader.close();
|
||||
}
|
||||
|
||||
public void parseV1(DBHelper db, BufferedReader input) throws IOException, FormatException, InterruptedException
|
||||
public void parseV1(Context context, DBHelper db, BufferedReader input) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
final CSVParser parser = new CSVParser(input, CSVFormat.RFC4180.withHeader());
|
||||
|
||||
@@ -77,7 +107,7 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
{
|
||||
for (CSVRecord record : parser)
|
||||
{
|
||||
importLoyaltyCard(database, db, record);
|
||||
importLoyaltyCard(context, database, db, record);
|
||||
|
||||
if(Thread.currentThread().isInterrupted())
|
||||
{
|
||||
@@ -99,7 +129,7 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
}
|
||||
}
|
||||
|
||||
public void parseV2(DBHelper db, BufferedReader input) throws IOException, FormatException, InterruptedException
|
||||
public void parseV2(Context context, DBHelper db, BufferedReader input) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
SQLiteDatabase database = db.getWritableDatabase();
|
||||
database.beginTransaction();
|
||||
@@ -120,7 +150,7 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
parseV2Groups(db, database, stringPart);
|
||||
break;
|
||||
case 2:
|
||||
parseV2Cards(db, database, stringPart);
|
||||
parseV2Cards(context, db, database, stringPart);
|
||||
break;
|
||||
case 3:
|
||||
parseV2CardGroups(db, database, stringPart);
|
||||
@@ -168,14 +198,14 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
}
|
||||
}
|
||||
|
||||
public void parseV2Cards(DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
public void parseV2Cards(Context context, DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
// Parse cards
|
||||
final CSVParser cardParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.withHeader());
|
||||
|
||||
try {
|
||||
for (CSVRecord record : cardParser) {
|
||||
importLoyaltyCard(database, db, record);
|
||||
importLoyaltyCard(context, database, db, record);
|
||||
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
@@ -212,7 +242,7 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
* Import a single loyalty card into the database using the given
|
||||
* session.
|
||||
*/
|
||||
private void importLoyaltyCard(SQLiteDatabase database, DBHelper helper, CSVRecord record)
|
||||
private void importLoyaltyCard(Context context, SQLiteDatabase database, DBHelper helper, CSVRecord record)
|
||||
throws IOException, FormatException
|
||||
{
|
||||
int id = CSVHelpers.extractInt(DBHelper.LoyaltyCardDbIds.ID, record, false);
|
||||
@@ -250,7 +280,18 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
throw new FormatException("No card ID listed, but is required");
|
||||
}
|
||||
|
||||
String barcodeType = CSVHelpers.extractString(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE, record, "");
|
||||
String barcodeId = CSVHelpers.extractString(DBHelper.LoyaltyCardDbIds.BARCODE_ID, record, "");
|
||||
if(barcodeId.isEmpty())
|
||||
{
|
||||
barcodeId = null;
|
||||
}
|
||||
|
||||
BarcodeFormat barcodeType = null;
|
||||
String unparsedBarcodeType = CSVHelpers.extractString(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE, record, "");
|
||||
if(!unparsedBarcodeType.isEmpty())
|
||||
{
|
||||
barcodeType = BarcodeFormat.valueOf(unparsedBarcodeType);
|
||||
}
|
||||
|
||||
Integer headerColor = null;
|
||||
|
||||
@@ -263,11 +304,12 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
try {
|
||||
starStatus = CSVHelpers.extractInt(DBHelper.LoyaltyCardDbIds.STAR_STATUS, record, false);
|
||||
} catch (FormatException _e ) {
|
||||
// This field did not exist in versions 0.28 and before
|
||||
// This field did not exist in versions 0.278 and before
|
||||
// We catch this exception so we can still import old backups
|
||||
}
|
||||
if (starStatus != 1) starStatus = 0;
|
||||
helper.insertLoyaltyCard(database, id, store, note, expiry, balance, balanceType, cardId, barcodeType, headerColor, starStatus);
|
||||
|
||||
helper.insertLoyaltyCard(database, id, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, starStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1,9 +1,10 @@
|
||||
package protect.card_locker;
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
public enum DataFormat
|
||||
{
|
||||
Catima,
|
||||
Fidme,
|
||||
Stocard,
|
||||
VoucherVault
|
||||
;
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import protect.card_locker.DBHelper;
|
||||
|
||||
@@ -9,11 +11,11 @@ import protect.card_locker.DBHelper;
|
||||
* Interface for a class which can export the contents of the database
|
||||
* in a given format.
|
||||
*/
|
||||
public interface DatabaseExporter
|
||||
public interface Exporter
|
||||
{
|
||||
/**
|
||||
* Export the database to the output stream in a given format.
|
||||
* @throws IOException
|
||||
*/
|
||||
void exportData(DBHelper db, OutputStreamWriter output) throws IOException, InterruptedException;
|
||||
void exportData(Context context, DBHelper db, OutputStream output) throws IOException, InterruptedException;
|
||||
}
|
||||
@@ -1,34 +1,24 @@
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import net.lingala.zip4j.io.inputstream.ZipInputStream;
|
||||
import net.lingala.zip4j.model.LocalFileHeader;
|
||||
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringReader;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Currency;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import protect.card_locker.DBHelper;
|
||||
import protect.card_locker.FormatException;
|
||||
@@ -40,20 +30,20 @@ import protect.card_locker.FormatException;
|
||||
* The database's loyalty cards are expected to appear in the CSV data.
|
||||
* A header is expected for the each table showing the names of the columns.
|
||||
*/
|
||||
public class FidmeImporter implements DatabaseImporter
|
||||
public class FidmeImporter implements Importer
|
||||
{
|
||||
public void importData(DBHelper db, InputStream input) throws IOException, FormatException, JSONException, ParseException {
|
||||
public void importData(Context context, DBHelper db, InputStream input, char[] password) throws IOException, FormatException, JSONException, ParseException {
|
||||
// We actually retrieve a .zip file
|
||||
ZipInputStream zipInputStream = new ZipInputStream(input);
|
||||
ZipInputStream zipInputStream = new ZipInputStream(input, password);
|
||||
|
||||
StringBuilder loyaltyCards = new StringBuilder();
|
||||
byte[] buffer = new byte[1024];
|
||||
int read = 0;
|
||||
|
||||
ZipEntry zipEntry;
|
||||
LocalFileHeader localFileHeader;
|
||||
|
||||
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
|
||||
if (zipEntry.getName().equals("loyalty_programs.csv")) {
|
||||
while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
|
||||
if (localFileHeader.getFileName().equals("loyalty_programs.csv")) {
|
||||
while ((read = zipInputStream.read(buffer, 0, 1024)) >= 0) {
|
||||
loyaltyCards.append(new String(buffer, 0, read, StandardCharsets.UTF_8));
|
||||
}
|
||||
@@ -114,18 +104,18 @@ public class FidmeImporter implements DatabaseImporter
|
||||
}
|
||||
|
||||
// There seems to be no note field in the CSV? So let's combine other fields instead...
|
||||
String program = CSVHelpers.extractString("Program", record, "");
|
||||
String addedAt = CSVHelpers.extractString("Added At", record, "");
|
||||
String firstName = CSVHelpers.extractString("Firstname", record, "");
|
||||
String lastName = CSVHelpers.extractString("Lastname", record, "");
|
||||
String program = CSVHelpers.extractString("Program", record, "").trim();
|
||||
String addedAt = CSVHelpers.extractString("Added At", record, "").trim();
|
||||
String firstName = CSVHelpers.extractString("Firstname", record, "").trim();
|
||||
String lastName = CSVHelpers.extractString("Lastname", record, "").trim();
|
||||
|
||||
String combinedName = String.format("%s %s", firstName, lastName);
|
||||
String combinedName = String.format("%s %s", firstName, lastName).trim();
|
||||
|
||||
StringBuilder noteBuilder = new StringBuilder();
|
||||
if (!program.isEmpty()) noteBuilder.append(program).append('\n');
|
||||
if (!addedAt.isEmpty()) noteBuilder.append(addedAt).append('\n');
|
||||
if (!combinedName.isEmpty()) noteBuilder.append(combinedName).append('\n');
|
||||
String note = noteBuilder.toString();
|
||||
String note = noteBuilder.toString().trim();
|
||||
|
||||
// The ID is called reference
|
||||
String cardId = CSVHelpers.extractString("Reference", record, "");
|
||||
@@ -137,11 +127,13 @@ public class FidmeImporter implements DatabaseImporter
|
||||
// Sadly, Fidme exports don't contain the card type
|
||||
// I guess they have an online DB of all the different companies and what type they use
|
||||
// TODO: Hook this into our own loyalty card DB if we ever get one
|
||||
String barcodeType = "";
|
||||
BarcodeFormat barcodeType = null;
|
||||
|
||||
// No favourite data in the export either
|
||||
int starStatus = 0;
|
||||
|
||||
helper.insertLoyaltyCard(database, store, note, null, BigDecimal.valueOf(0), null, cardId, barcodeType, null, starStatus);
|
||||
// TODO: Front and back image
|
||||
|
||||
helper.insertLoyaltyCard(database, store, note, null, BigDecimal.valueOf(0), null, cardId, null, barcodeType, null, starStatus);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
public enum ImportExportResult
|
||||
{
|
||||
Success,
|
||||
GenericFailure,
|
||||
BadPassword
|
||||
;
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.ParseException;
|
||||
|
||||
import protect.card_locker.DBHelper;
|
||||
@@ -15,7 +15,7 @@ import protect.card_locker.FormatException;
|
||||
* Interface for a class which can import the contents of a stream
|
||||
* into the database.
|
||||
*/
|
||||
public interface DatabaseImporter
|
||||
public interface Importer
|
||||
{
|
||||
/**
|
||||
* Import data from the input stream in a given format into
|
||||
@@ -23,5 +23,5 @@ public interface DatabaseImporter
|
||||
* @throws IOException
|
||||
* @throws FormatException
|
||||
*/
|
||||
void importData(DBHelper db, InputStream input) throws IOException, FormatException, InterruptedException, JSONException, ParseException;
|
||||
void importData(Context context, DBHelper db, InputStream input, char[] password) throws IOException, FormatException, InterruptedException, JSONException, ParseException;
|
||||
}
|
||||
@@ -1,14 +1,12 @@
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import protect.card_locker.DBHelper;
|
||||
import protect.card_locker.DataFormat;
|
||||
import protect.card_locker.importexport.CsvDatabaseExporter;
|
||||
import protect.card_locker.importexport.DatabaseExporter;
|
||||
|
||||
public class MultiFormatExporter
|
||||
{
|
||||
@@ -20,18 +18,18 @@ public class MultiFormatExporter
|
||||
*
|
||||
* The output stream is closed on success.
|
||||
*
|
||||
* @return true if the database was successfully exported,
|
||||
* false otherwise. If false, partial data may have been
|
||||
* @return ImportExportResult.Success if the database was successfully exported,
|
||||
* another ImportExportResult otherwise. If not Success, partial data may have been
|
||||
* written to the output stream, and it should be discarded.
|
||||
*/
|
||||
public static boolean exportData(DBHelper db, OutputStreamWriter output, DataFormat format)
|
||||
public static ImportExportResult exportData(Context context, DBHelper db, OutputStream output, DataFormat format)
|
||||
{
|
||||
DatabaseExporter exporter = null;
|
||||
Exporter exporter = null;
|
||||
|
||||
switch(format)
|
||||
{
|
||||
case Catima:
|
||||
exporter = new CsvDatabaseExporter();
|
||||
exporter = new CatimaExporter();
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Failed to export data, unknown format " + format.name());
|
||||
@@ -42,8 +40,8 @@ public class MultiFormatExporter
|
||||
{
|
||||
try
|
||||
{
|
||||
exporter.exportData(db, output);
|
||||
return true;
|
||||
exporter.exportData(context, db, output);
|
||||
return ImportExportResult.Success;
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
@@ -54,12 +52,12 @@ public class MultiFormatExporter
|
||||
Log.e(TAG, "Failed to export data", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
return ImportExportResult.GenericFailure;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.e(TAG, "Unsupported data format exported: " + format.name());
|
||||
return false;
|
||||
return ImportExportResult.GenericFailure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import net.lingala.zip4j.exception.ZipException;
|
||||
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.ParseException;
|
||||
|
||||
import protect.card_locker.DBHelper;
|
||||
import protect.card_locker.DataFormat;
|
||||
import protect.card_locker.FormatException;
|
||||
import protect.card_locker.importexport.CsvDatabaseImporter;
|
||||
import protect.card_locker.importexport.DatabaseImporter;
|
||||
|
||||
public class MultiFormatImporter
|
||||
{
|
||||
@@ -26,22 +25,25 @@ public class MultiFormatImporter
|
||||
* The input stream is not closed, and doing so is the
|
||||
* responsibility of the caller.
|
||||
*
|
||||
* @return true if the database was successfully imported,
|
||||
* false otherwise. If false, no data was written to
|
||||
* @return ImportExportResult.Success if the database was successfully imported,
|
||||
* or another result otherwise. If no Success, no data was written to
|
||||
* the database.
|
||||
*/
|
||||
public static boolean importData(DBHelper db, InputStream input, DataFormat format)
|
||||
public static ImportExportResult importData(Context context, DBHelper db, InputStream input, DataFormat format, char[] password)
|
||||
{
|
||||
DatabaseImporter importer = null;
|
||||
Importer importer = null;
|
||||
|
||||
switch(format)
|
||||
{
|
||||
case Catima:
|
||||
importer = new CsvDatabaseImporter();
|
||||
importer = new CatimaImporter();
|
||||
break;
|
||||
case Fidme:
|
||||
importer = new FidmeImporter();
|
||||
break;
|
||||
case Stocard:
|
||||
importer = new StocardImporter();
|
||||
break;
|
||||
case VoucherVault:
|
||||
importer = new VoucherVaultImporter();
|
||||
break;
|
||||
@@ -51,10 +53,14 @@ public class MultiFormatImporter
|
||||
{
|
||||
try
|
||||
{
|
||||
importer.importData(db, input);
|
||||
return true;
|
||||
importer.importData(context, db, input, password);
|
||||
return ImportExportResult.Success;
|
||||
}
|
||||
catch(IOException | FormatException | InterruptedException | JSONException | ParseException e)
|
||||
catch(ZipException e)
|
||||
{
|
||||
return ImportExportResult.BadPassword;
|
||||
}
|
||||
catch(IOException | FormatException | InterruptedException | JSONException | ParseException | NullPointerException e)
|
||||
{
|
||||
Log.e(TAG, "Failed to import data", e);
|
||||
}
|
||||
@@ -64,6 +70,7 @@ public class MultiFormatImporter
|
||||
{
|
||||
Log.e(TAG, "Unsupported data format imported: " + format.name());
|
||||
}
|
||||
return false;
|
||||
|
||||
return ImportExportResult.GenericFailure;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import net.lingala.zip4j.io.inputstream.ZipInputStream;
|
||||
import net.lingala.zip4j.model.LocalFileHeader;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import protect.card_locker.DBHelper;
|
||||
import protect.card_locker.FormatException;
|
||||
import protect.card_locker.Utils;
|
||||
import protect.card_locker.ZipUtils;
|
||||
|
||||
/**
|
||||
* Class for importing a database from CSV (Comma Separate Values)
|
||||
* formatted data.
|
||||
*
|
||||
* The database's loyalty cards are expected to appear in the CSV data.
|
||||
* A header is expected for the each table showing the names of the columns.
|
||||
*/
|
||||
public class StocardImporter implements Importer
|
||||
{
|
||||
public void importData(Context context, DBHelper db, InputStream input, char[] password) throws IOException, FormatException, JSONException, ParseException {
|
||||
HashMap<String, HashMap<String, Object>> loyaltyCardHashMap = new HashMap<>();
|
||||
HashMap<String, String> providers = new HashMap<>();
|
||||
|
||||
ZipInputStream zipInputStream = new ZipInputStream(input, password);
|
||||
|
||||
String[] providersFileName = null;
|
||||
String[] cardBaseName = null;
|
||||
String cardName = "";
|
||||
LocalFileHeader localFileHeader;
|
||||
while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
|
||||
String fileName = localFileHeader.getFileName();
|
||||
String[] nameParts = fileName.split("/");
|
||||
|
||||
if (providersFileName == null) {
|
||||
providersFileName = new String[] {
|
||||
nameParts[0],
|
||||
"sync",
|
||||
"data",
|
||||
"users",
|
||||
nameParts[0],
|
||||
"analytics-properties.json"
|
||||
};
|
||||
cardBaseName = new String[] {
|
||||
nameParts[0],
|
||||
"sync",
|
||||
"data",
|
||||
"users",
|
||||
nameParts[0],
|
||||
"loyalty-cards"
|
||||
};
|
||||
}
|
||||
|
||||
if (startsWith(nameParts, providersFileName, 0) && !localFileHeader.isDirectory()) {
|
||||
providers = parseProviders(zipInputStream);
|
||||
} else if (startsWith(nameParts, cardBaseName, 1)) {
|
||||
// Extract cardName
|
||||
cardName = nameParts[cardBaseName.length].split("\\.", 2)[0];
|
||||
|
||||
// This is the card itself
|
||||
if (nameParts.length == cardBaseName.length + 1) {
|
||||
// Ignore the .txt file
|
||||
if (fileName.endsWith(".json")) {
|
||||
JSONObject jsonObject = ZipUtils.readJSON(zipInputStream);
|
||||
|
||||
loyaltyCardHashMap = appendToLoyaltyCardHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"cardId",
|
||||
jsonObject.getString("input_id")
|
||||
);
|
||||
loyaltyCardHashMap = appendToLoyaltyCardHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"_providerId",
|
||||
jsonObject
|
||||
.getJSONObject("input_provider_reference")
|
||||
.getString("identifier")
|
||||
.substring("/loyalty-card-providers/".length())
|
||||
);
|
||||
|
||||
try {
|
||||
loyaltyCardHashMap = appendToLoyaltyCardHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"barcodeType",
|
||||
jsonObject.getString("input_barcode_format")
|
||||
);
|
||||
} catch (JSONException ignored) {}
|
||||
}
|
||||
} else if (fileName.endsWith("notes/default.json")) {
|
||||
loyaltyCardHashMap = appendToLoyaltyCardHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"note",
|
||||
ZipUtils.readJSON(zipInputStream)
|
||||
.getString("content")
|
||||
);
|
||||
} else if (fileName.endsWith("/images/front.png")) {
|
||||
loyaltyCardHashMap = appendToLoyaltyCardHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"frontImage",
|
||||
ZipUtils.readImage(zipInputStream)
|
||||
);
|
||||
} else if (fileName.endsWith("/images/back.png")) {
|
||||
loyaltyCardHashMap = appendToLoyaltyCardHashMap(
|
||||
loyaltyCardHashMap,
|
||||
cardName,
|
||||
"backImage",
|
||||
ZipUtils.readImage(zipInputStream)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (loyaltyCardHashMap.keySet().size() == 0) {
|
||||
throw new FormatException("Couldn't find any loyalty cards in this Stocard export.");
|
||||
}
|
||||
|
||||
SQLiteDatabase database = db.getWritableDatabase();
|
||||
database.beginTransaction();
|
||||
|
||||
for (HashMap<String, Object> loyaltyCardData : loyaltyCardHashMap.values()) {
|
||||
String store = providers.get(loyaltyCardData.get("_providerId").toString());
|
||||
String note = (String) Utils.hashmapGetOrDefault(loyaltyCardData, "note", "");
|
||||
String cardId = (String) loyaltyCardData.get("cardId");
|
||||
String barcodeTypeString = (String) Utils.hashmapGetOrDefault(loyaltyCardData, "barcodeType", null);
|
||||
BarcodeFormat barcodeType = null;
|
||||
if (barcodeTypeString != null) {
|
||||
if (barcodeTypeString.equals("RSS_DATABAR_EXPANDED")) {
|
||||
barcodeType = BarcodeFormat.RSS_EXPANDED;
|
||||
} else {
|
||||
barcodeType = BarcodeFormat.valueOf(barcodeTypeString);
|
||||
}
|
||||
}
|
||||
|
||||
long loyaltyCardInternalId = db.insertLoyaltyCard(database, store, note, null, BigDecimal.valueOf(0), null, cardId, null, barcodeType, null, 0);
|
||||
|
||||
if (loyaltyCardData.containsKey("frontImage")) {
|
||||
Utils.saveCardImage(context, (Bitmap) loyaltyCardData.get("frontImage"), (int) loyaltyCardInternalId, true);
|
||||
}
|
||||
if (loyaltyCardData.containsKey("backImage")) {
|
||||
Utils.saveCardImage(context, (Bitmap) loyaltyCardData.get("backImage"), (int) loyaltyCardInternalId, false);
|
||||
}
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful();
|
||||
database.endTransaction();
|
||||
database.close();
|
||||
|
||||
zipInputStream.close();
|
||||
}
|
||||
|
||||
private boolean startsWith(String[] full, String[] start, int minExtraLength) {
|
||||
if (full.length - minExtraLength < start.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < start.length; i++) {
|
||||
if (!start[i].contentEquals(full[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private HashMap<String, HashMap<String, Object>> appendToLoyaltyCardHashMap(HashMap<String, HashMap<String, Object>> loyaltyCardHashMap, String cardID, String key, Object value) {
|
||||
HashMap<String, Object> loyaltyCardData = loyaltyCardHashMap.get(cardID);
|
||||
if (loyaltyCardData == null) {
|
||||
loyaltyCardData = new HashMap<>();
|
||||
}
|
||||
|
||||
loyaltyCardData.put(key, value);
|
||||
loyaltyCardHashMap.put(cardID, loyaltyCardData);
|
||||
|
||||
return loyaltyCardHashMap;
|
||||
}
|
||||
|
||||
private HashMap<String, String> parseProviders(ZipInputStream zipInputStream) throws IOException, JSONException {
|
||||
// FIXME: This is probably completely wrong, but it works for the one and only test file I have
|
||||
JSONObject jsonObject = ZipUtils.readJSON(zipInputStream);
|
||||
|
||||
JSONArray providerIdList = jsonObject.getJSONArray("provider_id_list");
|
||||
JSONArray providerList = jsonObject.getJSONArray("provider_list");
|
||||
|
||||
// Resort, put IDs with - in them after IDs without any -
|
||||
List<String> providerIds = new ArrayList<>();
|
||||
List<String> customProviderIds = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < providerIdList.length(); i++) {
|
||||
String providerId = providerIdList.get(i).toString();
|
||||
if (providerId.contains("-")) {
|
||||
customProviderIds.add(providerId);
|
||||
} else {
|
||||
providerIds.add(providerId);
|
||||
}
|
||||
}
|
||||
providerIds.addAll(customProviderIds);
|
||||
|
||||
HashMap<String, String> providers = new HashMap<>();
|
||||
for (int i = 0; i < jsonObject.getInt("number_of_cards"); i++) {
|
||||
providers.put(providerIds.get(i), providerList.get(i).toString());
|
||||
}
|
||||
|
||||
return providers;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package protect.card_locker.importexport;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Color;
|
||||
|
||||
@@ -32,9 +33,9 @@ import protect.card_locker.FormatException;
|
||||
* The database's loyalty cards are expected to appear in the CSV data.
|
||||
* A header is expected for the each table showing the names of the columns.
|
||||
*/
|
||||
public class VoucherVaultImporter implements DatabaseImporter
|
||||
public class VoucherVaultImporter implements Importer
|
||||
{
|
||||
public void importData(DBHelper db, InputStream input) throws IOException, FormatException, JSONException, ParseException {
|
||||
public void importData(Context context, DBHelper db, InputStream input, char[] password) throws IOException, FormatException, JSONException, ParseException {
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@@ -60,32 +61,37 @@ public class VoucherVaultImporter implements DatabaseImporter
|
||||
expiry = dateFormat.parse(jsonCard.getString("expires"));
|
||||
}
|
||||
|
||||
BigDecimal balance;
|
||||
if (!jsonCard.isNull("balance")) {
|
||||
BigDecimal balance = new BigDecimal("0");
|
||||
if (jsonCard.has("balanceMilliunits")) {
|
||||
if (!jsonCard.isNull("balanceMilliunits")) {
|
||||
balance = new BigDecimal(String.valueOf(jsonCard.getInt("balanceMilliunits") / 1000.0));
|
||||
}
|
||||
} else if (!jsonCard.isNull("balance")) {
|
||||
balance = new BigDecimal(String.valueOf(jsonCard.getDouble("balance")));
|
||||
} else {
|
||||
balance = new BigDecimal("0");
|
||||
}
|
||||
|
||||
Currency balanceType = Currency.getInstance("USD");
|
||||
|
||||
String cardId = jsonCard.getString("code");
|
||||
|
||||
String barcodeType = null;
|
||||
BarcodeFormat barcodeType = null;
|
||||
|
||||
String codeTypeFromJSON = jsonCard.getString("codeType");
|
||||
switch (codeTypeFromJSON) {
|
||||
case "CODE128":
|
||||
barcodeType = BarcodeFormat.CODE_128.name();
|
||||
barcodeType = BarcodeFormat.CODE_128;
|
||||
break;
|
||||
case "CODE39":
|
||||
barcodeType = BarcodeFormat.CODE_39.name();
|
||||
barcodeType = BarcodeFormat.CODE_39;
|
||||
break;
|
||||
case "EAN13":
|
||||
barcodeType = BarcodeFormat.EAN_13.name();
|
||||
barcodeType = BarcodeFormat.EAN_13;
|
||||
break;
|
||||
case "PDF417":
|
||||
barcodeType = BarcodeFormat.PDF_417;
|
||||
break;
|
||||
case "QR":
|
||||
barcodeType = BarcodeFormat.QR_CODE.name();
|
||||
barcodeType = BarcodeFormat.QR_CODE;
|
||||
break;
|
||||
case "TEXT":
|
||||
break;
|
||||
@@ -119,10 +125,10 @@ public class VoucherVaultImporter implements DatabaseImporter
|
||||
headerColor = Color.YELLOW;
|
||||
break;
|
||||
default:
|
||||
throw new FormatException("Unknown colour type foun: " + colorFromJSON);
|
||||
throw new FormatException("Unknown colour type found: " + colorFromJSON);
|
||||
}
|
||||
|
||||
db.insertLoyaltyCard(store, "", expiry, balance, balanceType, cardId, barcodeType, headerColor, 0);
|
||||
db.insertLoyaltyCard(store, "", expiry, balance, balanceType, cardId, null, barcodeType, headerColor, 0);
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful();
|
||||
|
||||
@@ -2,11 +2,11 @@ package protect.card_locker.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import androidx.annotation.IntegerRes;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
import protect.card_locker.R;
|
||||
|
||||
public class Settings
|
||||
@@ -61,24 +61,34 @@ public class Settings
|
||||
return AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
||||
}
|
||||
|
||||
public int getCardTitleListFontSize()
|
||||
public double getFontSizeScale()
|
||||
{
|
||||
return getInt(R.string.settings_key_card_title_list_font_size, R.integer.settings_card_title_list_font_size_sp);
|
||||
return getInt(R.string.settings_key_max_font_size_scale, R.integer.settings_max_font_size_scale_pct) / 100.0;
|
||||
}
|
||||
|
||||
public int getCardNoteListFontSize()
|
||||
public int getSmallFont()
|
||||
{
|
||||
return getInt(R.string.settings_key_card_note_list_font_size, R.integer.settings_card_note_list_font_size_sp);
|
||||
return 14;
|
||||
}
|
||||
|
||||
public int getCardTitleFontSize()
|
||||
public int getMediumFont()
|
||||
{
|
||||
return getInt(R.string.settings_key_card_title_font_size, R.integer.settings_card_title_font_size_sp);
|
||||
return 28;
|
||||
}
|
||||
|
||||
public int getCardIdFontSize()
|
||||
public int getLargeFont()
|
||||
{
|
||||
return getInt(R.string.settings_key_card_id_font_size, R.integer.settings_card_id_font_size_sp);
|
||||
return 40;
|
||||
}
|
||||
|
||||
public int getFontSizeMin(int fontSize)
|
||||
{
|
||||
return (int) (Math.round(fontSize / 2.0) - 1);
|
||||
}
|
||||
|
||||
public int getFontSizeMax(int fontSize)
|
||||
{
|
||||
return (int) Math.round(fontSize * getFontSizeScale());
|
||||
}
|
||||
|
||||
public boolean useMaxBrightnessDisplayingBarcode()
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package protect.card_locker.preferences;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import nl.invissvenska.numberpickerpreference.NumberDialogPreference;
|
||||
import nl.invissvenska.numberpickerpreference.NumberPickerPreferenceDialogFragment;
|
||||
import protect.card_locker.R;
|
||||
@@ -20,6 +20,7 @@ public class SettingsActivity extends AppCompatActivity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.settings_activity);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
@@ -29,7 +30,7 @@ public class SettingsActivity extends AppCompatActivity
|
||||
|
||||
// Display the fragment as the main content.
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(android.R.id.content, new SettingsFragment())
|
||||
.replace(R.id.settings_container, new SettingsFragment())
|
||||
.commit();
|
||||
}
|
||||
|
||||
@@ -96,6 +97,7 @@ public class SettingsActivity extends AppCompatActivity
|
||||
dialogPreference.getKey(),
|
||||
dialogPreference.getMinValue(),
|
||||
dialogPreference.getMaxValue(),
|
||||
dialogPreference.getStepValue(),
|
||||
dialogPreference.getUnitText()
|
||||
);
|
||||
dialogFragment.setTargetFragment(this, 0);
|
||||
|
||||
22
app/src/main/res/animator/flip_left_in.xml
Normal file
22
app/src/main/res/animator/flip_left_in.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:duration="0"
|
||||
android:propertyName="alpha"
|
||||
android:valueFrom="1.0"
|
||||
android:valueTo="0.0" />
|
||||
|
||||
<objectAnimator
|
||||
android:duration="@integer/full_rotation_duration"
|
||||
android:interpolator="@android:interpolator/accelerate_decelerate"
|
||||
android:propertyName="rotationY"
|
||||
android:valueFrom="-180"
|
||||
android:valueTo="0" />
|
||||
|
||||
<objectAnimator
|
||||
android:duration="1"
|
||||
android:propertyName="alpha"
|
||||
android:startOffset="@integer/half_rotation_duration"
|
||||
android:valueFrom="0.0"
|
||||
android:valueTo="1.0" />
|
||||
</set>
|
||||
16
app/src/main/res/animator/flip_left_out.xml
Normal file
16
app/src/main/res/animator/flip_left_out.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:duration="@integer/full_rotation_duration"
|
||||
android:interpolator="@android:interpolator/accelerate_decelerate"
|
||||
android:propertyName="rotationY"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="180" />
|
||||
|
||||
<objectAnimator
|
||||
android:duration="1"
|
||||
android:propertyName="alpha"
|
||||
android:startOffset="@integer/half_rotation_duration"
|
||||
android:valueFrom="1.0"
|
||||
android:valueTo="0.0" />
|
||||
</set>
|
||||
22
app/src/main/res/animator/flip_right_in.xml
Normal file
22
app/src/main/res/animator/flip_right_in.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:duration="0"
|
||||
android:propertyName="alpha"
|
||||
android:valueFrom="1.0"
|
||||
android:valueTo="0.0" />
|
||||
|
||||
<objectAnimator
|
||||
android:duration="@integer/full_rotation_duration"
|
||||
android:interpolator="@android:interpolator/accelerate_decelerate"
|
||||
android:propertyName="rotationY"
|
||||
android:valueFrom="180"
|
||||
android:valueTo="0" />
|
||||
|
||||
<objectAnimator
|
||||
android:duration="1"
|
||||
android:propertyName="alpha"
|
||||
android:startOffset="@integer/half_rotation_duration"
|
||||
android:valueFrom="0.0"
|
||||
android:valueTo="1.0" />
|
||||
</set>
|
||||
16
app/src/main/res/animator/flip_right_out.xml
Normal file
16
app/src/main/res/animator/flip_right_out.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:duration="@integer/full_rotation_duration"
|
||||
android:interpolator="@android:interpolator/accelerate_decelerate"
|
||||
android:propertyName="rotationY"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="-180" />
|
||||
|
||||
<objectAnimator
|
||||
android:duration="1"
|
||||
android:propertyName="alpha"
|
||||
android:startOffset="@integer/half_rotation_duration"
|
||||
android:valueFrom="1.0"
|
||||
android:valueTo="0.0" />
|
||||
</set>
|
||||
@@ -1,66 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="192dp"
|
||||
android:height="192dp"
|
||||
android:viewportWidth="50.8"
|
||||
android:viewportHeight="50.8">
|
||||
<path
|
||||
android:pathData="M14.3354,20.1954l20.7318,-9.2304l5.7612,12.9398l-20.7318,9.2304z"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.529167"
|
||||
android:fillColor="#f0f0f0"
|
||||
android:strokeColor="#c80000"/>
|
||||
<path
|
||||
android:pathData="M14.8755,10.9648l23.2041,10.3311l-6.8874,15.4694l-23.2041,-10.3311z"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.529167"
|
||||
android:fillColor="#f0f0f0"
|
||||
android:strokeColor="#c80000"/>
|
||||
<path
|
||||
android:pathData="M16.5599,16.1348l26.5459,7.6119l-4.5489,15.8639l-26.5459,-7.6119z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="1.5875"
|
||||
android:fillColor="#c80000"
|
||||
android:strokeColor="#c80000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M12.011,15.4955h27.6157v16.5032h-27.6157z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="1.5875"
|
||||
android:fillColor="#ff0000"
|
||||
android:strokeColor="#ff0000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M7.8471,23.7471a4.3659,8.5899 0,1 0,8.7317 0a4.3659,8.5899 0,1 0,-8.7317 0z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.91078"
|
||||
android:fillColor="#ff0000"
|
||||
android:strokeColor="#ff0000"/>
|
||||
<path
|
||||
android:pathData="m24.4983,25.781a1.6711,1.6711 0,0 1,-1.3809 1.6457,1.6711 1.6711,0 0,1 -1.8605,-1.0741"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.529167"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#f0f0f0"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="m27.7991,26.333a1.6711,1.6711 0,0 1,-1.8605 1.0741,1.6711 1.6711,0 0,1 -1.3809,-1.6457"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.529167"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#f0f0f0"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="m16.0606,22.271 l2.6458,-2.6458 2.6458,2.6458"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.529167"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#f0f0f0"
|
||||
android:strokeLineCap="butt"/>
|
||||
<path
|
||||
android:pathData="m27.7023,22.271 l2.6458,-2.6458 2.6458,2.6458"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeWidth="0.529167"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#f0f0f0"
|
||||
android:strokeLineCap="butt"/>
|
||||
</vector>
|
||||
@@ -1,5 +0,0 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M20,3h-1L19,1h-2v2L7,3L7,1L5,1v2L4,3c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,5c0,-1.1 -0.9,-2 -2,-2zM20,21L4,21L4,8h16v13z"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable/ic_close.xml
Normal file
10
app/src/main/res/drawable/ic_close.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_copy.xml
Normal file
9
app/src/main/res/drawable/ic_copy.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable/ic_done.xml
Normal file
10
app/src/main/res/drawable/ic_done.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="@color/colorPrimary"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable/ic_edit.xml
Normal file
10
app/src/main/res/drawable/ic_edit.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
|
||||
</vector>
|
||||
15
app/src/main/res/drawable/ic_flashlight_off_white_24dp.xml
Normal file
15
app/src/main/res/drawable/ic_flashlight_off_white_24dp.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M18,5l0,-3l-12,0l0,1.17l1.83,1.83z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M16,11l2,-3l0,-1l-8.17,0l6.17,6.17z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M2.81,2.81L1.39,4.22L8,10.83V22h8v-3.17l3.78,3.78l1.41,-1.41L2.81,2.81z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
</vector>
|
||||
12
app/src/main/res/drawable/ic_flashlight_on_white_24dp.xml
Normal file
12
app/src/main/res/drawable/ic_flashlight_on_white_24dp.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M6,2h12v3h-12z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M6,7v1l2,3v11h8V11l2,-3V7H6zM12,15.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5s1.5,0.67 1.5,1.5S12.83,15.5 12,15.5z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable/ic_share.xml
Normal file
10
app/src/main/res/drawable/ic_share.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
|
||||
</vector>
|
||||
4
app/src/main/res/drawable/list_row.xml
Normal file
4
app/src/main/res/drawable/list_row.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@color/listItemHighlight" android:state_activated="true" />
|
||||
</selector>
|
||||
@@ -26,7 +26,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/aboutText"
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
android:labelFor="@+id/cardId"
|
||||
android:text="@string/cardId" />
|
||||
<EditText android:id="@+id/cardId"
|
||||
android:hint="AB1234"
|
||||
android:importantForAutofill="no"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -303,6 +304,27 @@
|
||||
android:textStyle="bold"
|
||||
android:layout_weight="1.0" />
|
||||
</LinearLayout>
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:padding="10.0dp"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/barcode_disp_height"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:id="@+id/upceBarcode"
|
||||
android:contentDescription="@string/barcodeImageDescription"
|
||||
android:layout_weight="1.0"/>
|
||||
<TextView
|
||||
android:id="@+id/upceBarcodeText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10.0dip"
|
||||
android:gravity="center"
|
||||
android:textSize="@dimen/text_size_medium"
|
||||
android:textStyle="bold"
|
||||
android:layout_weight="1.0" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
@@ -27,9 +27,11 @@
|
||||
android:text="@string/noMatchingGiftCards"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ListView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:visibility="gone"/>
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
@@ -38,6 +39,10 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/barcode"/>
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/photos"/>
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
@@ -96,6 +101,30 @@
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Card ID -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
android:paddingTop="@dimen/inputPadding"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/cardIdField"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/cardId">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/cardIdView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Note -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -212,7 +241,7 @@
|
||||
android:id="@+id/barcodePart"
|
||||
android:visibility="gone">
|
||||
|
||||
<!-- Card ID -->
|
||||
<!-- Barcode ID -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -220,26 +249,26 @@
|
||||
android:paddingTop="@dimen/inputPadding"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!-- Card ID -->
|
||||
<!-- Barcode ID -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/cardIdField"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:id="@+id/barcodeIdView"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1.0"
|
||||
android:hint="@string/cardId"
|
||||
android:labelFor="@+id/cardIdView">
|
||||
android:hint="@string/barcodeId"
|
||||
android:labelFor="@+id/barcodeIdView">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/cardIdView"
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/barcodeIdField"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
android:inputType="none"/>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Barcode ID -->
|
||||
<!-- Barcode type -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -302,6 +331,84 @@
|
||||
android:layout_weight="1.0"/>
|
||||
</LinearLayout>
|
||||
</TableLayout>
|
||||
|
||||
<TableLayout
|
||||
android:id="@+id/picturesPart"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<!-- Front image -->
|
||||
<LinearLayout
|
||||
android:id="@+id/frontImageHolder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
android:paddingTop="@dimen/inputPadding">
|
||||
|
||||
<!-- Front image -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/activity_margin"
|
||||
android:layout_marginTop="@dimen/activity_margin"
|
||||
android:layout_marginEnd="@dimen/activity_margin"
|
||||
android:layout_marginBottom="@dimen/activity_margin"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/frontImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:minHeight="50dp"
|
||||
android:background="@color/colorPrimary"
|
||||
android:contentDescription="@string/frontImageDescription"
|
||||
android:scaleType="fitCenter"
|
||||
app:srcCompat="@drawable/ic_camera_white" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Back image -->
|
||||
<LinearLayout
|
||||
android:id="@+id/backImageHolder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
android:paddingTop="@dimen/inputPadding">
|
||||
|
||||
<!-- Back image -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/activity_margin"
|
||||
android:layout_marginTop="@dimen/activity_margin"
|
||||
android:layout_marginEnd="@dimen/activity_margin"
|
||||
android:layout_marginBottom="@dimen/activity_margin"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/backImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:minHeight="50dp"
|
||||
android:background="@color/colorPrimary"
|
||||
android:contentDescription="@string/backImageDescription"
|
||||
android:scaleType="fitCenter"
|
||||
app:srcCompat="@drawable/ic_camera_white" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
</LinearLayout>
|
||||
</TableLayout>
|
||||
</TableLayout>
|
||||
</ScrollView>
|
||||
|
||||
|
||||
@@ -1,80 +1,118 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/row"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:baselineAligned="false"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="0.5dp"
|
||||
android:background="@drawable/list_row"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="@dimen/activity_margin">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_marginEnd="@dimen/activity_margin"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/thumbnail"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:contentDescription="@string/thumbnailDescription"
|
||||
android:src="@mipmap/ic_launcher"/>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="0dip"
|
||||
android:id="@+id/information_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
android:layout_marginStart="@dimen/activity_margin"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
android:layout_toEndOf="@+id/thumbnail_container"
|
||||
android:layout_toRightOf="@+id/thumbnail_container"
|
||||
android:layout_weight="1"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/thumbnail_container"
|
||||
app:layout_constraintEnd_toStartOf="@+id/star"
|
||||
app:layout_constraintStart_toEndOf="@+id/thumbnail_container"
|
||||
app:layout_constraintTop_toTopOf="@+id/thumbnail_container">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/valueLayout"
|
||||
<TextView
|
||||
android:id="@+id/store"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="visible" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/store"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/storeNameTextSize"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
</LinearLayout>
|
||||
android:textSize="@dimen/storeNameTextSize"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/note"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textSize="@dimen/noteTextSize"/>
|
||||
android:lines="1"
|
||||
android:textSize="@dimen/noteTextSize" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/balance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textSize="@dimen/noteTextSize"/>
|
||||
android:lines="1"
|
||||
android:textSize="@dimen/noteTextSize" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/expiry"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textSize="@dimen/noteTextSize"/>
|
||||
android:lines="1"
|
||||
android:textSize="@dimen/noteTextSize" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/thumbnail_container"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/thumbnail_front"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/thumbnail"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:contentDescription="@string/thumbnailDescription"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/thumbnail_back"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:contentDescription="@string/thumbnailDescription"
|
||||
app:srcCompat="@drawable/ic_done" />
|
||||
|
||||
</RelativeLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/star"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_marginStart="@dimen/activity_margin"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
app:srcCompat="@drawable/ic_starred_white"
|
||||
app:tint="@color/iconColor"
|
||||
android:contentDescription="@string/starImage"/>
|
||||
</LinearLayout>
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="@dimen/activity_margin"
|
||||
android:contentDescription="@string/starImage"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="#000000" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -53,7 +53,7 @@
|
||||
android:padding="0dp"
|
||||
app:srcCompat="@drawable/ic_baseline_arrow_drop_up_24"
|
||||
android:contentDescription="@string/moveBarcodeToTopOfScreen"
|
||||
android:tint="@android:color/white"
|
||||
app:tint="#ffffff"
|
||||
android:background="@color/colorPrimary"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/barcode"
|
||||
@@ -84,7 +84,7 @@
|
||||
android:padding="0dp"
|
||||
app:srcCompat="@drawable/ic_baseline_arrow_drop_down_24"
|
||||
android:contentDescription="@string/moveBarcodeToCenterOfScreen"
|
||||
android:tint="@android:color/white"
|
||||
app:tint="#ffffff"
|
||||
android:background="@color/colorPrimary"
|
||||
app:layout_constraintTop_toBottomOf="@+id/barcode"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
@@ -134,60 +134,122 @@
|
||||
android:id="@+id/bottom_sheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/inputBackground"
|
||||
android:fitsSystemWindows="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp"
|
||||
android:visibility="gone"
|
||||
app:behavior_hideable="false"
|
||||
app:behavior_peekHeight="104dp"
|
||||
app:behavior_peekHeight="80dp"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
|
||||
tools:visibility="visible"
|
||||
android:fitsSystemWindows="true">
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/bottomSheetButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:layout_gravity="top|start"
|
||||
android:background="@color/colorPrimary"
|
||||
android:scaleType="fitCenter"
|
||||
android:layout_gravity="top|start"
|
||||
android:tint="@android:color/white"
|
||||
app:tint="#ffffff"
|
||||
app:srcCompat="@drawable/ic_baseline_arrow_drop_up_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/noteView"
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/bottomSheetContentWrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/inputBackground"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
android:textSize="@dimen/singleCardNoteTextSizeMin" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/groupsView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/inputBackground"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
android:textSize="@dimen/singleCardNoteTextSizeMin" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/balanceView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/inputBackground"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
android:textSize="@dimen/singleCardNoteTextSizeMin" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/expiryView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/inputBackground"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
android:textSize="@dimen/singleCardNoteTextSizeMin" />
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/frontImageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/activity_margin"
|
||||
android:layout_marginTop="@dimen/activity_margin"
|
||||
android:layout_marginEnd="@dimen/activity_margin"
|
||||
android:layout_marginBottom="@dimen/activity_margin"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
android:layout_weight="1"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/frontImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@string/frontImageDescription"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/backImageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="@dimen/activity_margin"
|
||||
android:layout_marginTop="@dimen/activity_margin"
|
||||
android:layout_marginEnd="@dimen/activity_margin"
|
||||
android:layout_marginBottom="@dimen/activity_margin"
|
||||
android:paddingHorizontal="@dimen/inputPadding"
|
||||
android:layout_weight="1"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/backImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@string/backImageDescription"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/noteView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
android:textSize="@dimen/singleCardNoteTextSizeMin" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/groupsView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
android:textSize="@dimen/singleCardNoteTextSizeMin" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/balanceView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
android:textSize="@dimen/singleCardNoteTextSizeMin" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/expiryView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="20dp"
|
||||
android:textSize="@dimen/singleCardNoteTextSizeMin" />
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
@@ -197,7 +259,6 @@
|
||||
android:clipToPadding="false"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="24dp"
|
||||
android:weightSum="1.0"
|
||||
android:fitsSystemWindows="true">
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
@@ -243,6 +304,7 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="?actionBarSize"
|
||||
app:contentInsetStart="72.0dip"
|
||||
app:layout_collapseMode="pin" />
|
||||
app:layout_collapseMode="pin"
|
||||
android:paddingTop="6dp" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
12
app/src/main/res/layout/settings_activity.xml
Normal file
12
app/src/main/res/layout/settings_activity.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/settings_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<menu>
|
||||
</menu>
|
||||
@@ -3,11 +3,24 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_clipboard"
|
||||
android:id="@+id/action_copy_to_clipboard"
|
||||
android:title="@string/copy_to_clipboard"
|
||||
android:icon="@drawable/ic_copy"
|
||||
android:titleCondensed="@string/copy_to_clipboard"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_share"
|
||||
android:title="@string/share"
|
||||
android:icon="@drawable/ic_share"
|
||||
android:titleCondensed="@string/share"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_edit"
|
||||
android:icon="@drawable/ic_edit"
|
||||
android:title="@string/editCardTitle"
|
||||
android:titleCondensed="@string/editCardTitle"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
</menu>
|
||||
@@ -17,7 +17,7 @@
|
||||
android:id="@+id/action_import_export"
|
||||
android:icon="@drawable/ic_import_export_white_24dp"
|
||||
android:title="@string/importExport"
|
||||
app:showAsAction="ifRoom"/>
|
||||
app:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:title="@string/settings"
|
||||
|
||||
9
app/src/main/res/menu/scan_menu.xml
Normal file
9
app/src/main/res/menu/scan_menu.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_toggle_flashlight"
|
||||
android:icon="@drawable/ic_flashlight_off_white_24dp"
|
||||
android:title="@string/turn_flashlight_on"
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
||||
170
app/src/main/res/values-bg/strings.xml
Normal file
170
app/src/main/res/values-bg/strings.xml
Normal file
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="action_add">Добавяне</string>
|
||||
<string name="action_search">Търсене</string>
|
||||
<string name="leaveWithoutSaveTitle">Изход</string>
|
||||
<string name="confirm">Потвърждаване</string>
|
||||
<string name="delete">Премахване</string>
|
||||
<string name="edit">Редактиране</string>
|
||||
<string name="save">Запазване</string>
|
||||
<string name="cancel">Отказ</string>
|
||||
<string name="unstar">Премахва от любими</string>
|
||||
<string name="star">Добавя към любими</string>
|
||||
<string name="noBarcode">Без щрихкод</string>
|
||||
<string name="barcodeNoBarcode">Картата няма щрихкод</string>
|
||||
<string name="barcodeType">Вид на щрихкод</string>
|
||||
<string name="cardId">Идентификатор на карта</string>
|
||||
<string name="note">Бележка</string>
|
||||
<string name="storeName">Наименование</string>
|
||||
<string name="noMatchingGiftCards">Няма резултати. Променете критериите за търсене.</string>
|
||||
<string name="noGiftCards">Докоснете бутона +, за да добавите карта или внесете от менюто ⋮.</string>
|
||||
<string name="all">Всички</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> карта</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> карти</item>
|
||||
</plurals>
|
||||
<string name="failedOpeningFileManager">Инсталирайте приложение за управление на файлове.</string>
|
||||
<string name="app_license">Свободен софтуер с авторски права, лицензиран под GPLv3+.</string>
|
||||
<string name="frontImageDescription">Снимка на предната страна на карта</string>
|
||||
<string name="backImageDescription">Снимка на задната страна на карта</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> не изглежда истинска наличност.</string>
|
||||
<string name="barcodeImageDescription">Изображение на щрихкода на картата</string>
|
||||
<string name="no">Не</string>
|
||||
<string name="yes">Да</string>
|
||||
<string name="setBackImage">Снимка на задната страна</string>
|
||||
<string name="setFrontImage">Снимка на предната страна</string>
|
||||
<string name="photos">Снимки</string>
|
||||
<string name="importOptionApplicationExplanation">Изберете файл чрез друго приложение.</string>
|
||||
<string name="noExternalStoragePermissionError">Дайте разрешение за достъп до хранилището, за да работи внасянето и изнасянето</string>
|
||||
<string name="noCardExistsError">Картата не е намерена</string>
|
||||
<string name="updateBarcodeQuestionText">Идентификаторът е променен. Желаете ли с неговата стойност да бъде променен и щрихкода\?</string>
|
||||
<string name="updateBarcodeQuestionTitle">Обновяване на щрихкода\?</string>
|
||||
<string name="noCardIdError">Не е въведен идентификатор</string>
|
||||
<string name="noCardsMessage">Добавете карта</string>
|
||||
<string name="cardShortcut">Пряк път до карта</string>
|
||||
<string name="addCardTitle">Добавяне на карта</string>
|
||||
<string name="removeImage">Премахване на изображение</string>
|
||||
<string name="takePhoto">Снимане</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">Идентификаторите са копирани в междинната памет</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Искам да споделя тези карти с вас</string>
|
||||
<string name="wrongValueForBarcodeType">Стойността е невалидна за избрания вид щрихкод</string>
|
||||
<string name="setBarcodeId">Задаване на стойност</string>
|
||||
<string name="sameAsCardId">Същата като идентификатора</string>
|
||||
<string name="barcodeId">Стойност на щрихкода</string>
|
||||
<string name="importLoyaltyCardKeychain">Внасяне от Loyalty Card Keychain</string>
|
||||
<string name="importFidmeMessage">Изберете файла <i>fidme-export-request-xxxxxx.zip</i>, предварително изнесен от FidMe и ръчно изберете вида на щрихкодовете.
|
||||
\nИли създайте такъв файл от Data Protection в менюто на профила във FidMe и изберете „Extract my data“.</string>
|
||||
<string name="importFidme">Внасяне от FidMe</string>
|
||||
<string name="exportOptionExplanation">Данните ще бъдат запазени на място по ваш избор.</string>
|
||||
<string name="accept">Приемане</string>
|
||||
<string name="privacy_policy_popup_text">Политика за личните данни (необходима от някои магазини за приложения):
|
||||
\n
|
||||
\nНЕ СЕ СЪБИРАТ ИЗОБЩО НИКАКВИ ДАННИ, което може да бъде потвърдено, защото приложението е със свободен код.</string>
|
||||
<string name="privacy_policy">Политика за личните данни</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="turn_flashlight_off">Изключва светкавицата</string>
|
||||
<string name="turn_flashlight_on">Включва светкавицата</string>
|
||||
<string name="passwordRequired">Въведете паролата</string>
|
||||
<string name="points">Точки</string>
|
||||
<string name="currency">Валута</string>
|
||||
<string name="balance">Наличност</string>
|
||||
<string name="errorReadingImage">Изображението е нечетимо</string>
|
||||
<string name="noBarcodeFound">Не е намерен щрихкод</string>
|
||||
<string name="moveBarcodeToCenterOfScreen">Премества щрихкода в центъра на екрана</string>
|
||||
<string name="moveBarcodeToTopOfScreen">Премества щрихкода най-горе на екрана</string>
|
||||
<string name="never">Не изтича</string>
|
||||
<string name="chooseExpiryDate">Дата на изтичане</string>
|
||||
<string name="expiryDate">Валидност</string>
|
||||
<string name="editBarcode">Редактиране на щрихкод</string>
|
||||
<string name="barcode">Щрихкод</string>
|
||||
<string name="card">Карта</string>
|
||||
<string name="groupsList">Списъци: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Валидност: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Изтекла: <xliff:g>%s</xliff:g></string>
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> точки</string>
|
||||
<string name="balanceSentence">Наличност: <xliff:g>%s</xliff:g></string>
|
||||
<string name="noGroups">Докоснете бутона +, за да добавите списък.</string>
|
||||
<string name="noStoreError">Не е въведено наименование</string>
|
||||
<string name="groups">Списъци</string>
|
||||
<string name="enter_group_name">Въведете име на списък</string>
|
||||
<string name="intent_import_card_from_url_share_text">Искам да споделя тази карта с вас</string>
|
||||
<string name="settings_display_barcode_max_brightness">Увеличаване на яркостта при видим щрихкод</string>
|
||||
<string name="settings_lock_barcode_orientation">Спиране на завъртането на щрихкода</string>
|
||||
<string name="settings_keep_screen_on">Поддържане на екрана включен</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Предотвратяване на заключване на екрана</string>
|
||||
<string name="settings_max_font_size_scale">Максимален размер на шрифта</string>
|
||||
<string name="settings_dark_theme">Тъмна</string>
|
||||
<string name="settings_light_theme">Светла</string>
|
||||
<string name="settings_system_theme">Системна</string>
|
||||
<string name="settings_theme">Тема</string>
|
||||
<string name="settings_category_title_ui">Потребителски интерфейс</string>
|
||||
<string name="settings">Настройки</string>
|
||||
<string name="starImage">Звезда за любимо</string>
|
||||
<string name="thumbnailDescription">Миниатюра на картата</string>
|
||||
<string name="copy_to_clipboard_toast">Идентификаторът на картата е копиран в междинната памет</string>
|
||||
<string name="enterBarcodeInstructions">Въведете идентификатор на картата или като изберете вида на щрихкода или докоснете бутона „Картата няма щрихкод“.</string>
|
||||
<string name="selectBarcodeTitle">Избиране на щрихкод</string>
|
||||
<string name="importOptionApplicationButton">Избиране чрез приложение</string>
|
||||
<string name="importing">Внасяне…</string>
|
||||
<string name="exporting">Изнасяне…</string>
|
||||
<string name="exportFailed">Картите не могат да бъдат изнесени</string>
|
||||
<string name="exportFailedTitle">Грешка при изнасяне</string>
|
||||
<string name="importFailed">Картите не могат да бъдат внесени</string>
|
||||
<string name="importFailedTitle">Грешка при внасяне</string>
|
||||
<string name="exportSuccessfulTitle">Резултат от изнасяне</string>
|
||||
<string name="importSuccessfulTitle">Резултат от внасяне</string>
|
||||
<string name="importExportHelp">Резервните копия на картите ви дават възможност да ги преместите на друго устройство.</string>
|
||||
<string name="exportName">Изнасяне</string>
|
||||
<string name="importExport">Внасяне/изнасяне</string>
|
||||
<string name="sendLabel">Изпращане…</string>
|
||||
<string name="scanCardBarcode">Сканиране на щрихкод от карта</string>
|
||||
<string name="editCardTitle">Редактиране на карта</string>
|
||||
<string name="share">Споделя</string>
|
||||
<string name="copy_to_clipboard">Копира идентификатора в междинната памет</string>
|
||||
<string name="ok">Добре</string>
|
||||
<string name="deleteConfirmation">Потвърдете премахване на карта</string>
|
||||
<string name="deleteTitle">Премахване на карта</string>
|
||||
<string name="importSuccessful">Картите са внесени успешно</string>
|
||||
<string name="chooseImportType">От къде ще внесете\?</string>
|
||||
<string name="importCatimaMessage">Изберете файла <i>catima.zip</i>, предварително изнесен от Catima.
|
||||
\nИли създайте такъв файл от меню Внасяне/изнасяне от друго устройство със Catima като изберете Изнасяне.</string>
|
||||
<string name="importOptionApplicationTitle">От друго приложение</string>
|
||||
<string name="importOptionFilesystemButton">Избиране от файлова система</string>
|
||||
<string name="importOptionFilesystemExplanation">Изберете определен файл от файловата система.</string>
|
||||
<string name="app_resources">Свободни ресурси: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Свободни библиотеки: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Компилация: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Издание: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="about_title_fmt">Относно <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Всички права запазени © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="app_copyright_old">На основата на Loyalty Card Keychain
|
||||
\nвсички права запазени © 2016–2020 Branden Archer.</string>
|
||||
<string name="about">Относно</string>
|
||||
<string name="importOptionFilesystemTitle">Внасяне от файловата система</string>
|
||||
<string name="importCatima">Внасяне от Catima</string>
|
||||
<string name="exportSuccessful">Картите са изнесени успешно</string>
|
||||
<string name="unlockScreen">Разрешава автоматичното завъртане</string>
|
||||
<string name="lockScreen">Спира автоматичното завъртане</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="one">Избрана <xliff:g>%d</xliff:g> карта</item>
|
||||
<item quantity="other">Избрани <xliff:g>%d</xliff:g> карти</item>
|
||||
</plurals>
|
||||
<string name="deleteConfirmationGroup">Изтриване на група\?</string>
|
||||
<string name="moveDown">Преместване надолу</string>
|
||||
<string name="moveUp">Преместване нагоре</string>
|
||||
<string name="addFromImage">Избор от галерията</string>
|
||||
<string name="addManually">Ръчно въвеждане</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Оставяте промените незапазени\?</string>
|
||||
<string name="unsupportedBarcodeType">Щрихкод от този вид не може да бъде показан. Може да бъде поддържан в следващо издание.</string>
|
||||
<string name="importStocard">Внасяне от Stocard</string>
|
||||
<string name="importVoucherVault">Внасяне от Voucher Vault</string>
|
||||
<string name="importVoucherVaultMessage">Изберете файла <i>vouchervault.json</i>, предварително изнесен от Voucher Vault.
|
||||
\nИли създайте такъв файл от меню Изнасяне от Voucher Vault.</string>
|
||||
<string name="importStocardMessage">Изберете файла <i>***-sync.zip</i>, предварително изнесен от Stocard и ръчно изберете вида на щрихкодовете.
|
||||
\nИли получете такъв файл като пишете до support@stocardapp.com с молба за копие от вашата информация.</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Изберете файла <i>LoyaltyCardKeychain.csv</i>, предварително изнесен от Loyalty Card Keychain.
|
||||
\nИли създайте такъв файл от меню Внасяне/изнасяне от друго устройство със Loyalty Card Keychain като изберете Изнасяне.</string>
|
||||
<string name="failedParsingImportUriError">Препратката не може да бъде анализирана за внасяне</string>
|
||||
<string name="card_ids_copied">[не превеждай този низ, https://github.com/TheLastProject/Catima/issues/278]</string>
|
||||
<string name="failedGeneratingShareURL">Неуспешно генериране на адрес за споделяне. Докладвайте за тази грешка!</string>
|
||||
</resources>
|
||||
@@ -48,7 +48,6 @@
|
||||
<string name="about_title_fmt">O aplikaci <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Verze: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Revizní informace: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> používá tyto knihovny třetích stran: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Vyberte čárový kód</string>
|
||||
<string name="copy_to_clipboard_toast">ID karty zkopírováno do schránky</string>
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="action_search">Suchen</string>
|
||||
<string name="action_add">Hinzufügen</string>
|
||||
<string name="noGiftCards">Klicken Sie auf die Schaltfläche + (plus), um zuerst eine Karte hinzuzufügen.
|
||||
\n
|
||||
\nCatima trägt Ihre Karten auf dem Gerät, so dass sie immer in Reichweite sind.</string>
|
||||
<string name="noGiftCards">Klicken Sie auf das Pluszeichen +, um eine Karte hinzuzufügen, oder importieren Sie zunächst einige aus dem ⋮ Menü.</string>
|
||||
<string name="noMatchingGiftCards">Nichts gefunden. Versuchen Sie, Ihre Suche zu ändern.</string>
|
||||
<string name="storeName">Geschäft</string>
|
||||
<string name="storeName">Name</string>
|
||||
<string name="note">Notiz</string>
|
||||
<string name="cardId">Kartennummer</string>
|
||||
<string name="cancel">Abbrechen</string>
|
||||
@@ -19,7 +17,7 @@
|
||||
<string name="star">Zu den Favoriten hinzufügen</string>
|
||||
<string name="unstar">Aus der Favoritenliste entfernen</string>
|
||||
<string name="deleteTitle">Karte entfernen</string>
|
||||
<string name="deleteConfirmation">Bitte bestätigen Sie, dass diese Karte gelöscht werden soll.</string>
|
||||
<string name="deleteConfirmation">Diese Karte löschen\?</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Nummer in die Zwischenablage kopieren</string>
|
||||
<string name="sendLabel">Senden …</string>
|
||||
@@ -29,7 +27,7 @@
|
||||
<string name="cardShortcut">Shortcut zu einer Karte</string>
|
||||
<string name="noCardsMessage">Fügen Sie zuerst eine Karte hinzu</string>
|
||||
<string name="barcodeImageDescription">Bild des Strichcodes</string>
|
||||
<string name="noStoreError">Kein Geschäft angegeben</string>
|
||||
<string name="noStoreError">Kein Name eingegeben</string>
|
||||
<string name="noCardIdError">Keine Kartennummer angegeben</string>
|
||||
<string name="noCardExistsError">Karte konnte nicht gefunden werden</string>
|
||||
<string name="importExport">Import/Export</string>
|
||||
@@ -47,25 +45,19 @@
|
||||
<string name="importOptionFilesystemTitle">Importiere aus Dateisystem</string>
|
||||
<string name="importOptionFilesystemExplanation">Wähle eine Datei aus dem Speicher aus.</string>
|
||||
<string name="importOptionFilesystemButton">Aus Dateisystem</string>
|
||||
<string name="importOptionApplicationTitle">Externe Anwendung verwenden</string>
|
||||
<string name="importOptionApplicationTitle">Andere Anwendung verwenden</string>
|
||||
<string name="importOptionApplicationExplanation">Verwenden Sie eine beliebige Anwendung oder Ihren bevorzugten Dateiverwaltungsprogramm, um eine Datei zu öffnen.</string>
|
||||
<string name="importOptionApplicationButton">Externe Anwendung nutzen</string>
|
||||
<string name="importOptionApplicationButton">Andere Anwendung verwenden</string>
|
||||
<string name="about">Über</string>
|
||||
<string name="app_license">Freie Software, lizensiert unter der GPLv3+.</string>
|
||||
<string name="about_title_fmt">Über <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Version: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Informationen zu dieser Version: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> benutzt die folgenden Fremdbibliotheken: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> verwendet folgenden Dritt-Ressourcen: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Strichcode auswählen</string>
|
||||
<string name="copy_to_clipboard_toast">Nummer in die Zwischenablage kopiert</string>
|
||||
<string name="thumbnailDescription">Vorschaubild für die Karte</string>
|
||||
<string name="settings">Einstellungen</string>
|
||||
<string name="settings_category_title_ui">Benutzeroberfläche</string>
|
||||
<string name="settings_card_title_list_font_size">Schriftgröße des Kartentitels (Listenmodus)</string>
|
||||
<string name="settings_card_note_list_font_size">Schriftgröße der Kartennotiz (Listenmodus)</string>
|
||||
<string name="settings_card_title_font_size">Schriftgröße des Kartentitels (Vorschau)</string>
|
||||
<string name="settings_card_id_font_size">Schriftgröße der Kartennummer</string>
|
||||
<string name="settings_display_barcode_max_brightness">Helligkeit bei Strichcode Ansicht erhöhen</string>
|
||||
<string name="settings_lock_barcode_orientation">Strichcodeausrichtung sperren</string>
|
||||
<string name="exportSuccessful">Kartendaten exportiert</string>
|
||||
@@ -75,36 +67,35 @@
|
||||
<string name="settings_light_theme">Hell</string>
|
||||
<string name="settings_system_theme">System</string>
|
||||
<string name="settings_theme">Design</string>
|
||||
<string name="enterBarcodeInstructions">Geben Sie die Karten-ID ein und wählen Sie das Bild aus, das den Strichcode darstellt, den Sie verwenden möchten, oder wählen Sie „Diese Karte hat keinen Strichcode“, um keinen Strichcode zu verwenden.</string>
|
||||
<string name="app_copyright_old">Basiert auf Loyalty Card Keychain, Copyright 2016–2020 Branden Archer.</string>
|
||||
<string name="enterBarcodeInstructions">Geben Sie die Karten-ID ein und wählen Sie unten entweder den Strichcodetyp oder „Diese Karte hat keinen Strichcode“.</string>
|
||||
<string name="app_copyright_old">Basierend auf Loyalty Card Keychain
|
||||
\nCopyright © 2016-2020 Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">Die Daten werden an einen Ort Ihrer Wahl geschrieben.</string>
|
||||
<string name="failedParsingImportUriError">Der Import-URI konnte nicht analysiert werden</string>
|
||||
<string name="share">Teilen</string>
|
||||
<string name="barcodeNoBarcode">Diese Karte hat keinen Strichcode</string>
|
||||
<string name="barcodeType">Strichcode-Typ</string>
|
||||
<string name="starImage">Favoritenstern</string>
|
||||
<string name="deleteConfirmationGroup">Bitte bestätigen Sie, dass Sie diese Gruppe löschen möchten</string>
|
||||
<string name="deleteConfirmationGroup">Gruppe löschen\?</string>
|
||||
<string name="all">Alle</string>
|
||||
<string name="noGroups">Klicken Sie auf die Schaltfläche + (plus), um zuerst Gruppen hinzuzufügen.
|
||||
\n
|
||||
\nGruppen machen es einfacher, Dinge zu finden.</string>
|
||||
<string name="noGroups">Klicken Sie auf das Pluszeichen +, um zunächst Gruppen zur Kategorisierung hinzuzufügen.</string>
|
||||
<string name="groups">Gruppen</string>
|
||||
<string name="enter_group_name">Geben Sie den Gruppennamen ein</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Sind Sie sicher, dass Sie diesen Bildschirm verlassen wollen\? Vorgenommene Änderungen werden nicht gespeichert.</string>
|
||||
<string name="leaveWithoutSaveTitle">Beenden ohne zu speichern</string>
|
||||
<string name="failedOpeningFileManager">Fehler beim Öffnen eines Dateiverwaltungsprogrammes. Stellen Sie sicher, dass eine installiert ist.</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Beenden ohne zu speichern\?</string>
|
||||
<string name="leaveWithoutSaveTitle">Beenden</string>
|
||||
<string name="failedOpeningFileManager">Installieren Sie zunächst ein Dateiverwaltungsprogramm.</string>
|
||||
<string name="noBarcode">Kein Strichcode</string>
|
||||
<string name="addManually">Die Karten-ID manuell eingeben</string>
|
||||
<string name="moveDown">In der Liste nach unten verschieben</string>
|
||||
<string name="moveUp">In der Liste nach oben verschieben</string>
|
||||
<string name="moveDown">Nach unten verschieben</string>
|
||||
<string name="moveUp">Nach oben verschieben</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> Karte</item>
|
||||
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> Karten</item>
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> Karte</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> Karten</item>
|
||||
</plurals>
|
||||
<string name="groupsList">Gruppen: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="chooseImportType">Aus welcher App Daten importieren\?</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> scheint kein gültiges Guthaben zu sein.</string>
|
||||
<string name="groupsList">Gruppen: <xliff:g>%s</xliff:g></string>
|
||||
<string name="app_loyalty_card_keychain">Bonuskartenschlüsselring</string>
|
||||
<string name="chooseImportType">Daten importieren aus\?</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> scheint kein gültiges Guthaben zu sein.</string>
|
||||
<string name="points">Punkte</string>
|
||||
<string name="currency">Währung</string>
|
||||
<string name="balance">Guthaben</string>
|
||||
@@ -116,33 +107,64 @@
|
||||
<string name="editBarcode">Strichcode bearbeiten</string>
|
||||
<string name="barcode">Strichcode</string>
|
||||
<string name="card">Karte</string>
|
||||
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> Punkte</string>
|
||||
<string name="balanceSentence">Guthaben: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Abgelaufen: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Läuft ab: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Sperrbildschirm deaktivieren während eine Karte angesehen wird</string>
|
||||
<string name="settings_keep_screen_on">Bildschirm anlassen während eine Karte angesehen wird</string>
|
||||
<string name="privacy_policy_popup_text">Es wird oft verlangt, dass Anwendungen beim ersten Start ihre Datenschutzrichtlinien anzeigen. Hier ist unsere:
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> Punkte</string>
|
||||
<string name="balanceSentence">Guthaben: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Abgelaufen: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Läuft ab: <xliff:g>%s</xliff:g></string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Sperrbildschirm verhindern</string>
|
||||
<string name="settings_keep_screen_on">Bildschirm eingeschaltet halten</string>
|
||||
<string name="privacy_policy_popup_text">Hinweis zum Datenschutz (oft gefordert):
|
||||
\n
|
||||
\nWir sammeln KEINE DATEN und unsere Anwendung ist quelloffen, sodass jeder bestätigen kann, dass dies wahr ist.</string>
|
||||
\nKEINE DATEN WERDEN GESAMMELT, was jeder bestätigen kann, da unsere Anwendung eine freie Software ist.</string>
|
||||
<string name="accept">Annehmen</string>
|
||||
<string name="privacy_policy">Datenschutzrichtlinie</string>
|
||||
<string name="importVoucherVaultMessage">Bitte wählen Sie Ihre Voucher Vault-Exportdatei aus. Es heißt höchstwahrscheinlich vouchervault.json.
|
||||
\n
|
||||
\nEine Voucher Vault-Exportdatei kann durch Drücken von Exportieren erstellt werden.</string>
|
||||
<string name="importVoucherVaultMessage">Wählen Sie Ihren <i>vouchervault.json</i>-Export aus Voucher Vault zum Importieren aus.
|
||||
\nOder erstellen Sie ihn, indem Sie zuerst auf Export in Voucher Vault drücken.</string>
|
||||
<string name="importVoucherVault">Aus Voucher Vault importieren</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Bitte wählen Sie Ihre Loyalty Card Keychain-Exportdatei aus. Es heißt höchstwahrscheinlich LoyaltyCardKeychain.csv.
|
||||
\n
|
||||
\nEine Loyalty Card Keychain-Exportdatei kann erstellt werden, indem Sie im Menü Import/Export auf Exportieren klicken.</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Wählen Sie Ihren <i>LoyaltyCardKeychain.csv</i>-Export aus Loyalty Card Keychain zum Importieren aus.
|
||||
\nOder erstellen Sie ihn über das Menü Import/Export in Loyalty Card Keychain, indem Sie dort zuerst auf Export drücken.</string>
|
||||
<string name="importLoyaltyCardKeychain">Aus Loyalty Card Keychain importieren</string>
|
||||
<string name="importFidmeMessage">Bitte wählen Sie Ihre Fidme-Exportdatei aus. Es wird höchstwahrscheinlich so etwas wie fidme-export-request-xxxxxx.zip genannt.
|
||||
\n
|
||||
\nEine Fidme-Exportdatei kann in der Fidme-Anwendung erstellt werden, indem Sie zu Ihrem Profil gehen, Datenschutz auswählen und dann auf Meine Daten extrahieren klicken.
|
||||
\n
|
||||
\nBitte beachten Sie, dass Fidme den Strichcode-Typ nicht in den Exportdaten speichert, sodass Sie die importierten Karten manuell bearbeiten müssen.</string>
|
||||
<string name="importFidme">Aus Fidme importieren</string>
|
||||
<string name="importCatimaMessage">Bitte wählen Sie Ihre Catima-Exportdatei aus. Es heißt höchstwahrscheinlich Catima.csv.
|
||||
\n
|
||||
\nEine Catima-Exportdatei kann erstellt werden, indem Sie im Menü Import/Export auf Exportieren klicken.</string>
|
||||
<string name="importFidmeMessage">Wählen Sie Ihren <i>fidme-export-request-xxxxxx.zip</i>-Export aus FidMe zum Importieren aus und wählen Sie anschließend die Strichcodetypen manuell aus.
|
||||
\nOder erstellen Sie ihn aus Ihrem FidMe-Profil, indem Sie Datenschutz wählen und dann zuerst auf Meine Daten extrahieren drücken.</string>
|
||||
<string name="importFidme">Aus FidMe importieren</string>
|
||||
<string name="importCatimaMessage">Wählen Sie Ihren <i>catima.zip</i>-Export aus Catima zum Importieren aus.
|
||||
\nOder erstellen Sie ihn aus dem Import/Export-Menü einer anderen Catima-Anwendung, indem Sie dort zuerst Export drücken.</string>
|
||||
<string name="importCatima">Aus Catima importieren</string>
|
||||
<string name="setBarcodeId">Strichcodewert setzen</string>
|
||||
<string name="sameAsCardId">Gleich wie Karten-ID</string>
|
||||
<string name="barcodeId">Strichcodewert</string>
|
||||
<string name="errorReadingImage">Das Bild konnte nicht gelesen werden</string>
|
||||
<string name="noBarcodeFound">Kein Strichcode gefunden</string>
|
||||
<string name="addFromImage">Bild aus der Galerie auswählen</string>
|
||||
<string name="settings_max_font_size_scale">Max. Schriftgröße</string>
|
||||
<string name="unsupportedBarcodeType">Dieser Strichcodetyp kann noch nicht angezeigt werden. Er wird möglicherweise in einer späteren Version der Anwendung unterstützt.</string>
|
||||
<string name="wrongValueForBarcodeType">Der Wert ist für den gewählten Strichcodetyp nicht gültig</string>
|
||||
<string name="app_resources">Freie Ressourcen von Drittanbietern: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Freie Bibliotheken von Drittanbietern: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Ich möchte Karten mit dir teilen</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">Kartennummern in die Zwischenablage kopiert</string>
|
||||
<string name="card_ids_copied">Kartennummer(n) kopiert</string>
|
||||
<string name="no">Nein</string>
|
||||
<string name="yes">Ja</string>
|
||||
<string name="updateBarcodeQuestionText">Sie haben die Karten-ID geändert. Möchten Sie auch den Strichcode aktualisieren, um denselben Wert zu verwenden\?</string>
|
||||
<string name="updateBarcodeQuestionTitle">Strichcodewert aktualisieren\?</string>
|
||||
<string name="takePhoto">Foto aufnehmen</string>
|
||||
<string name="removeImage">Bild entfernen</string>
|
||||
<string name="setBackImage">Rückseitenbild einstellen</string>
|
||||
<string name="setFrontImage">Vorderseitenbild einstellen</string>
|
||||
<string name="photos">Fotos</string>
|
||||
<string name="frontImageDescription">Bild der Kartenvorderseite</string>
|
||||
<string name="backImageDescription">Bild der Kartenrückseite</string>
|
||||
<string name="passwordRequired">Bitte geben Sie das Passwort ein</string>
|
||||
<string name="importStocardMessage">Wählen Sie Ihren <i>***-sync.zip</i>-Export aus Stocard zum Importieren aus, und wählen Sie anschließend die Strichcodetypen manuell aus.
|
||||
\nOder Sie erhalten ihn, indem Sie eine E-Mail an support@stocardapp.com senden und um einen Export Ihrer Daten bitten.</string>
|
||||
<string name="importStocard">Von Stocard importieren</string>
|
||||
<string name="turn_flashlight_off">Taschenlampe ausschalten</string>
|
||||
<string name="turn_flashlight_on">Taschenlampe einschalten</string>
|
||||
<string name="failedGeneratingShareURL">Fehler beim Generieren der Freigabe-URL. Bitte melden Sie diesen Fehler!</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="one">Ausgewählt: <xliff:g>%d</xliff:g> Karte</item>
|
||||
<item quantity="other">Ausgewählt: <xliff:g>%d</xliff:g> Karten</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -49,17 +49,11 @@
|
||||
<string name="about_title_fmt">Σχετικά με <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Έκδοση: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Πληροφορίες Αναθεώρησης: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries">Το <xliff:g id="app_name">%s</xliff:g> χρησιμοποιεί τις ακόλουθες βιβλιοθήκες τρίτων: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources">Το <xliff:g id="app_name">%s</xliff:g> χρησιμοποιεί τους παρακάτω πόρους τρίτων: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Επιλέξτε Barcode</string>
|
||||
<string name="copy_to_clipboard_toast">Ο κωδικός της κάρτας αντιγράφτηκε στο πρόχειρο</string>
|
||||
<string name="thumbnailDescription">Μικρογραφία κάρτας</string>
|
||||
<string name="settings">Ρυθμίσεις</string>
|
||||
<string name="settings_category_title_ui">Διεπαφή χρήστη</string>
|
||||
<string name="settings_card_title_list_font_size">Μέγεθος κειμένου λίστας καρτών</string>
|
||||
<string name="settings_card_note_list_font_size">Μέγεθος κειμένου λίστας σημειώσεων καρτών</string>
|
||||
<string name="settings_card_title_font_size">Μέγεθος κειμένου τίτλου κάρτας</string>
|
||||
<string name="settings_card_id_font_size">Μέγεθος κειμένου κωδικού κάρτας</string>
|
||||
<string name="settings_dark_theme">Σκοτεινό</string>
|
||||
<string name="settings_light_theme">Φωτεινό</string>
|
||||
<string name="settings_system_theme">Σύστημα</string>
|
||||
|
||||
55
app/src/main/res/values-eo/strings.xml
Normal file
55
app/src/main/res/values-eo/strings.xml
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="deleteConfirmation">Ĉu forigi ĉi tiun karton\?</string>
|
||||
<string name="deleteTitle">Forigi karton</string>
|
||||
<string name="barcodeNoBarcode">Strekokodo mankas al karto</string>
|
||||
<string name="delete">Forigi</string>
|
||||
<string name="noBarcode">Sen strekokodo</string>
|
||||
<string name="barcodeType">Tipo de strekokodo</string>
|
||||
<string name="cardId">Identigilo de karto</string>
|
||||
<string name="settings_category_title_ui">Fasado</string>
|
||||
<string name="settings">Agordoj</string>
|
||||
<string name="selectBarcodeTitle">Elekti strekokodon</string>
|
||||
<string name="debug_version_fmt">Versio: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="about_title_fmt">Pri <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Kopirajto © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="importOptionFilesystemButton">El dosiersistemo</string>
|
||||
<string name="importOptionFilesystemTitle">Enporti el dosiersistemo</string>
|
||||
<string name="exportFailedTitle">Elportado malsukcesis</string>
|
||||
<string name="exportSuccessfulTitle">Elportado sukcesis</string>
|
||||
<string name="importFailedTitle">Enportado malsukcesis</string>
|
||||
<string name="importSuccessfulTitle">Enportado sukcesis</string>
|
||||
<string name="exporting">Elportante…</string>
|
||||
<string name="importing">Enportante…</string>
|
||||
<string name="exportName">Elporti</string>
|
||||
<string name="importExport">Enporti/elporti</string>
|
||||
<string name="addCardTitle">Aldoni karton</string>
|
||||
<string name="editCardTitle">Redakti karton</string>
|
||||
<string name="sendLabel">Sendi…</string>
|
||||
<string name="takePhoto">Foti</string>
|
||||
<string name="no">Ne</string>
|
||||
<string name="yes">Jes</string>
|
||||
<string name="photos">Fotoj</string>
|
||||
<string name="points">Poentoj</string>
|
||||
<string name="currency">Valuto</string>
|
||||
<string name="editBarcode">Redakti strekokodon</string>
|
||||
<string name="barcode">Strekokodo</string>
|
||||
<string name="card">Karto</string>
|
||||
<string name="never">Neniam</string>
|
||||
<string name="groupsList">Grupoj: <xliff:g>%s</xliff:g></string>
|
||||
<string name="groups">Grupoj</string>
|
||||
<string name="settings_dark_theme">Malhela</string>
|
||||
<string name="settings_light_theme">Hela</string>
|
||||
<string name="settings_system_theme">Sistema</string>
|
||||
<string name="settings_theme">Etoso</string>
|
||||
<string name="about">Pri</string>
|
||||
<string name="note">Noto</string>
|
||||
<string name="storeName">Nomo</string>
|
||||
<string name="confirm">Konfirmi</string>
|
||||
<string name="ok">Bone</string>
|
||||
<string name="edit">Redakti</string>
|
||||
<string name="save">Konservi</string>
|
||||
<string name="cancel">Nuligi</string>
|
||||
<string name="action_add">Aldoni</string>
|
||||
<string name="action_search">Serĉi</string>
|
||||
</resources>
|
||||
@@ -1,10 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="action_add">Añadir</string>
|
||||
<string name="noGiftCards">Pulse el botón «+» para añadir una nueva tarjeta.
|
||||
\n
|
||||
\nCatima guarda sus tarjetas en el dispositivo, para que estén siempre a su alcance.</string>
|
||||
<string name="storeName">Tienda</string>
|
||||
<string name="noGiftCards">Pulse el botón «+» para añadir una tarjeta, o importe algunas del menú ⋮.</string>
|
||||
<string name="storeName">Nombre</string>
|
||||
<string name="note">Nota</string>
|
||||
<string name="cardId">Id. de tarjeta</string>
|
||||
<string name="cancel">Cancelar</string>
|
||||
@@ -12,10 +10,10 @@
|
||||
<string name="edit">Editar</string>
|
||||
<string name="delete">Eliminar</string>
|
||||
<string name="confirm">Confirmar</string>
|
||||
<string name="lockScreen">Bloquear rotación</string>
|
||||
<string name="unlockScreen">Desbloquear rotación</string>
|
||||
<string name="lockScreen">Bloquear giro</string>
|
||||
<string name="unlockScreen">Desbloquear giro</string>
|
||||
<string name="deleteTitle">Eliminar tarjeta</string>
|
||||
<string name="deleteConfirmation">Por favor, confirme que quiere eliminar esta tarjeta.</string>
|
||||
<string name="deleteConfirmation">¿Quiere eliminar esta tarjeta\?</string>
|
||||
<string name="ok">Aceptar</string>
|
||||
<string name="copy_to_clipboard">Copiar id. en portapapeles</string>
|
||||
<string name="sendLabel">Enviar…</string>
|
||||
@@ -25,12 +23,12 @@
|
||||
<string name="cardShortcut">Atajo de tarjeta</string>
|
||||
<string name="noCardsMessage">Añada una tarjeta primero</string>
|
||||
<string name="barcodeImageDescription">Imagen del código de barras de la tarjeta</string>
|
||||
<string name="noStoreError">Establecimiento no especificado</string>
|
||||
<string name="noStoreError">No se proporcionó ningún nombre</string>
|
||||
<string name="noCardIdError">Id. de tarjeta no especificado</string>
|
||||
<string name="noCardExistsError">No se ha podido encontrar la tarjeta</string>
|
||||
<string name="importExport">Importar/exportar</string>
|
||||
<string name="exportName">Exportar</string>
|
||||
<string name="importExportHelp">La copia de respaldo le permite transferir sus tarjetas a otro dispositivo.</string>
|
||||
<string name="importExportHelp">El respaldo le permite transferir sus tarjetas a otro dispositivo.</string>
|
||||
<string name="importSuccessfulTitle">Importado</string>
|
||||
<string name="importFailedTitle">Falló la importación</string>
|
||||
<string name="importFailed">No se han podido importar tarjetas</string>
|
||||
@@ -43,30 +41,27 @@
|
||||
<string name="importOptionFilesystemTitle">Importar desde el sistema de archivos</string>
|
||||
<string name="importOptionFilesystemExplanation">Elegir un archivo concreto del sistema de archivos.</string>
|
||||
<string name="importOptionFilesystemButton">Desde el sistema de archivos</string>
|
||||
<string name="importOptionApplicationTitle">Utilizar aplicación externa</string>
|
||||
<string name="importOptionApplicationTitle">Utilizar otra aplicación</string>
|
||||
<string name="importOptionApplicationExplanation">Use una aplicación o su gestor de archivos favoritos para abrir un archivo.</string>
|
||||
<string name="importOptionApplicationButton">Utilizar aplicación externa</string>
|
||||
<string name="importOptionApplicationButton">Utilizar otra aplicación</string>
|
||||
<string name="about">Acerca de</string>
|
||||
<string name="app_license">Software libre con copyleft, disponible bajo la licencia GPLv3+.</string>
|
||||
<string name="app_license">Programa libre con «copyleft», disponible en virtud de la licencia GPLv3+.</string>
|
||||
<string name="about_title_fmt">Acerca de <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versión: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="settings">Configuración</string>
|
||||
<string name="settings">Ajustes</string>
|
||||
<string name="settings_category_title_ui">Interfaz de usuario</string>
|
||||
<string name="settings_card_title_list_font_size">Tamaño de fuente del título de la tarjeta (modo lista)</string>
|
||||
<string name="settings_card_note_list_font_size">Tamaño de fuente de las notas de la tarjeta (modo lista)</string>
|
||||
<string name="settings_card_title_font_size">Tamaño de fuente del título de la tarjeta (vista previa)</string>
|
||||
<string name="settings_card_id_font_size">Tamaño de la letra para el ID de la tarjeta</string>
|
||||
<string name="settings_display_barcode_max_brightness">Iluminar vista del código de barras</string>
|
||||
<string name="exportSuccessful">Datos de las tarjetas exportados</string>
|
||||
<string name="importSuccessful">Datos de las tarjetas importados</string>
|
||||
<string name="intent_import_card_from_url_share_text">Quiero compartirle una tarjeta</string>
|
||||
<string name="settings_lock_barcode_orientation">Bloquear orientación del código de barras</string>
|
||||
<string name="intent_import_card_from_url_share_text">Quiero compartirte una tarjeta</string>
|
||||
<string name="settings_lock_barcode_orientation">Bloquear giro en el código de barras</string>
|
||||
<string name="settings_dark_theme">Oscuro</string>
|
||||
<string name="settings_light_theme">Claro</string>
|
||||
<string name="settings_system_theme">Sistema</string>
|
||||
<string name="settings_theme">Tema</string>
|
||||
<string name="enterBarcodeInstructions">Introduzca el identificador de tarjeta y seleccione la imagen que represente el código de barras que se utilizará, o bien, elija «Esta tarjeta no tiene código de barras» para no utilizar ninguno.</string>
|
||||
<string name="app_copyright_old">Basado en Loyalty Card Keychain, derechos de autor 2016–2020 de Branden Archer.</string>
|
||||
<string name="enterBarcodeInstructions">Introduzca el identificador de tarjeta y seleccione el código de barras que se utilizará, o de lo contrario, elija «Esta tarjeta no tiene código de barras».</string>
|
||||
<string name="app_copyright_old">Basado en Loyalty Card Keychain
|
||||
\nderechos de autor © 2016-2020 de Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">Los datos se guardarán en la ubicación que elija.</string>
|
||||
<string name="failedParsingImportUriError">No se pudo procesar el URI de importación</string>
|
||||
<string name="share">Compartir</string>
|
||||
@@ -74,44 +69,102 @@
|
||||
<string name="barcodeType">Tipo de código de barras</string>
|
||||
<string name="noMatchingGiftCards">No se ha encontrado nada. Pruebe a modificar su búsqueda.</string>
|
||||
<string name="action_search">Buscar</string>
|
||||
<string name="app_libraries"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> usa las siguientes librerías de terceros: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Información de la revisión: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="noGroups">Pulse el botón «+» para añadir grupos.
|
||||
\n
|
||||
\nLos grupos permiten encontrar cosas fácilmente.</string>
|
||||
<string name="app_revision_fmt">Información de la revisión: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="noGroups">Primero pulse en el botón «+» para añadir grupos de categorización.</string>
|
||||
<string name="starImage">Favorito</string>
|
||||
<string name="thumbnailDescription">Miniatura de la tarjeta</string>
|
||||
<string name="copy_to_clipboard_toast">Id. de la tarjeta copiado al portapapeles</string>
|
||||
<string name="copy_to_clipboard_toast">Se copió la id. de tarjeta en el portapapeles</string>
|
||||
<string name="selectBarcodeTitle">Seleccionar el código de barras</string>
|
||||
<string name="app_resources"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> usa los siguientes recursos de terceros: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="unstar">Eliminar de favoritos</string>
|
||||
<string name="noBarcode">Sin código de barras</string>
|
||||
<string name="enter_group_name">Introducir nombre del grupo</string>
|
||||
<string name="groups">Grupos</string>
|
||||
<string name="groupsList">Grupos: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="groupsList">Grupos: <xliff:g>%s</xliff:g></string>
|
||||
<string name="addManually">Introducir el id. de la tarjeta manualmente</string>
|
||||
<string name="leaveWithoutSaveConfirmation">¿Está seguro de querer abandonar esta página\? Los cambios no se guardarán.</string>
|
||||
<string name="leaveWithoutSaveTitle">Salir sin guardar</string>
|
||||
<string name="moveDown">Bajar en la lista</string>
|
||||
<string name="moveUp">Subir en la lista</string>
|
||||
<string name="failedOpeningFileManager">Fallo al abrir el gestor de archivos. Por favor, asegúrese de que haya uno instalado.</string>
|
||||
<string name="deleteConfirmationGroup">Por favor, confirme que desea eliminar este grupo</string>
|
||||
<string name="leaveWithoutSaveConfirmation">¿Quiere abandonar sin guardar\?</string>
|
||||
<string name="leaveWithoutSaveTitle">Salir</string>
|
||||
<string name="moveDown">Bajar</string>
|
||||
<string name="moveUp">Subir</string>
|
||||
<string name="failedOpeningFileManager">Instale un gestor de archivos primero.</string>
|
||||
<string name="deleteConfirmationGroup">¿Quiere eliminar el grupo\?</string>
|
||||
<string name="all">Todo</string>
|
||||
<string name="star">Añadir a favoritos</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> tarjeta</item>
|
||||
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> tarjetas</item>
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> tarjeta</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> tarjetas</item>
|
||||
</plurals>
|
||||
<string name="points">Puntos</string>
|
||||
<string name="moveBarcodeToCenterOfScreen">Centrar el código de barras en la pantalla</string>
|
||||
<string name="moveBarcodeToTopOfScreen">Mover el código de barras a la zona superior de la pantalla</string>
|
||||
<string name="moveBarcodeToCenterOfScreen">Centre el código de barras en la pantalla</string>
|
||||
<string name="moveBarcodeToTopOfScreen">Mueva el código de barras a la zona superior de la pantalla</string>
|
||||
<string name="chooseExpiryDate">Elegir fecha de caducidad</string>
|
||||
<string name="never">Nunca</string>
|
||||
<string name="expiryDate">Fecha de caducidad</string>
|
||||
<string name="editBarcode">Editar el código de barras</string>
|
||||
<string name="barcode">Código de barras</string>
|
||||
<string name="card">Tarjeta</string>
|
||||
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> puntos</string>
|
||||
<string name="expiryStateSentenceExpired">Expirado: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Expira: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
</resources>
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> puntos</string>
|
||||
<string name="expiryStateSentenceExpired">Expirado: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Expira: <xliff:g>%s</xliff:g></string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Derechos de autor © 2019-<xliff:g>%d</xliff:g> de Sylvia van Os.</string>
|
||||
<string name="app_resources">Recursos de terceros libres: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Bibliotecas de terceros libres: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="settings_max_font_size_scale">Tam. de fuente máximo</string>
|
||||
<string name="importCatimaMessage">Seleccione su <i>catima.zip</i> exportado desde Catima para importarlo.
|
||||
\nO créalo primero desde el menú Importar/Exportar de otra app de Catima al presionar Exportar desde allí.</string>
|
||||
<string name="importFidmeMessage">Seleccione su <i>fidme-export-request-xxxxxx.zip</i> exportado desde FidMe para importar, y luego escoja los tipos de códigos de barras manualmente.
|
||||
\nO créalo primero desde tu perfil de FidMe eligiendo Protección de datos y pulsa Extraer mis datos.</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Seleccione su <i>LoyaltyCardKeychain.csv</i> exportado desde Loyalty Card Keychain para importarlo.
|
||||
\nO créalo primero desde el menú Importar/Exportar en Loyalty Card Keychain pulsando Exportar desde allí.</string>
|
||||
<string name="importStocardMessage">Seleccione su <i>*-sync.zip</i> exportado de Stocard para importarla, y selecciona los tipos de códigos de barras manualmente después.
|
||||
\nO consígalo enviando un correo electrónico a support@stocardapp.com solicitando una exportación de sus datos.</string>
|
||||
<string name="importVoucherVaultMessage">Seleccione su <i>vouchervault.json</i> exportado desde Voucher Vault para importarlo.
|
||||
\nO créalo pulsando primero Exportar en Voucher Vault.</string>
|
||||
<string name="failedGeneratingShareURL">Error al generar la URL compartida. Por favor, ¡reporte este error!</string>
|
||||
<string name="passwordRequired">Por favor, introduzca la contraseña</string>
|
||||
<string name="updateBarcodeQuestionText">Ha cambiado la Id. de la tarjeta. ¿Desea actualizar también el código de barras para usar el mismo valor\?</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Quiero compartirte algunas tarjetas</string>
|
||||
<string name="setBackImage">Establecer imagen anversa</string>
|
||||
<string name="card_ids_copied">Id. de tarjetas copiadas</string>
|
||||
<string name="turn_flashlight_off">Apagar linterna</string>
|
||||
<string name="turn_flashlight_on">Encender linterna</string>
|
||||
<string name="no">No</string>
|
||||
<string name="yes">Sí</string>
|
||||
<string name="updateBarcodeQuestionTitle">¿Actualizar valor de código de barras\?</string>
|
||||
<string name="takePhoto">Tomar una foto</string>
|
||||
<string name="removeImage">Quitar imagen</string>
|
||||
<string name="setFrontImage">Establecer imagen frontal</string>
|
||||
<string name="photos">Fotos</string>
|
||||
<string name="backImageDescription">Imagen del reverso de la tarjeta</string>
|
||||
<string name="frontImageDescription">Imagen frontal de la tarjeta</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">ID de tarjetas copiadas al portapapeles</string>
|
||||
<string name="wrongValueForBarcodeType">El valor no es válido para el tipo de código de barras seleccionado</string>
|
||||
<string name="unsupportedBarcodeType">Este tipo de código de barras todavía no se puede visualizar. Es posible que se admita en una futura versión de la aplicación.</string>
|
||||
<string name="setBarcodeId">Establecer valor de código de barra</string>
|
||||
<string name="sameAsCardId">Igual que la ID de tarjeta</string>
|
||||
<string name="barcodeId">Valor de código de barra</string>
|
||||
<string name="importVoucherVault">Importar desde Voucher Vault</string>
|
||||
<string name="importStocard">Importar desde Stocard</string>
|
||||
<string name="importLoyaltyCardKeychain">Importar desde Loyalty Card Keychain</string>
|
||||
<string name="importFidme">Importar desde FidMe</string>
|
||||
<string name="importCatima">Importar desde Catima</string>
|
||||
<string name="accept">Aceptar</string>
|
||||
<string name="privacy_policy_popup_text">Aviso de política de privacidad (requerido por algunas tiendas de apps):
|
||||
\n
|
||||
\nNINGÚN DATO SE RECOPILA, cualquiera puede confirmar ya que nuestra aplicación es software libre.</string>
|
||||
<string name="privacy_policy">Política de privacidad</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="chooseImportType">¿De dónde importar datos\?</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> no tendría un saldo válido.</string>
|
||||
<string name="currency">Moneda</string>
|
||||
<string name="balance">Saldo</string>
|
||||
<string name="errorReadingImage">No se pudo leer la imagen</string>
|
||||
<string name="noBarcodeFound">No se encontró código de barras</string>
|
||||
<string name="balanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
|
||||
<string name="addFromImage">Selecciona imagen desde galería</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Evitar bloqueo de pantalla</string>
|
||||
<string name="settings_keep_screen_on">Mantener pantalla encendida</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="one">Seleccionadas: <xliff:g>%d</xliff:g> tarjeta</item>
|
||||
<item quantity="other">Seleccionadas: <xliff:g>%d</xliff:g> tarjetas</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
159
app/src/main/res/values-fi/strings.xml
Normal file
159
app/src/main/res/values-fi/strings.xml
Normal file
@@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="noExternalStoragePermissionError">Salli käyttöoikeus ulkoisen tallennustilan käyttöön voidaksesi tuoda tai viedä kortteja</string>
|
||||
<string name="no">Ei</string>
|
||||
<string name="yes">Kyllä</string>
|
||||
<string name="updateBarcodeQuestionText">Vaihdoit kortin ID-tunnuksen. Haluatko päivittää myös viivakoodin käyttämään samaa arvoa\?</string>
|
||||
<string name="updateBarcodeQuestionTitle">Päivitä viivakoodin arvo\?</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Haluan jakaa joitain kortteja kanssasi</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">Kopioitiin korttitunnukset leikepöydälle</string>
|
||||
<string name="wrongValueForBarcodeType">Arvo ei ole kelvollinen valitulle viivakoodityypille</string>
|
||||
<string name="unsupportedBarcodeType">Tätä viivakoodityyppiä ei voi vielä näyttää. Sitä saatetaan tukea sovelluksen uudemmassa versiossa.</string>
|
||||
<string name="setBarcodeId">Aseta viivakoodin arvo</string>
|
||||
<string name="sameAsCardId">Sama kuin kortin ID-tunnus</string>
|
||||
<string name="barcodeId">Viivakoodin arvo</string>
|
||||
<string name="importVoucherVaultMessage">Etsi tiedostoa joka on todennäköisesti nimetty nimellä <i>vouchervault.json</i> tuotavaksi.
|
||||
\nTai luo se Vie toiminnolla Voucher Vault sovelluksessa.</string>
|
||||
<string name="importVoucherVault">Tuo Voucher Vault varmuuskopiotiedostosta</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Etsi tiedostoa joka on todennäköisesti nimetty nimellä <i>LoyaltyCardKeychain.csv</i> tuotavaksi.
|
||||
\nTai luo se Tuo/Vie toiminnolla Loyalty Card Keychain sovelluksessa, valitsemalla valikosta Vie.</string>
|
||||
<string name="importLoyaltyCardKeychain">Tuo Loyalty Card Keychain varmuuskopiotiedostosta</string>
|
||||
<string name="importFidmeMessage">Etsi tiedostoa joka on todennäköisesti nimetty nimellä <i>fidme-export-request-xxxxxx.zip</i> tuotavaksi ja valitse viivakoodityypit manuaalisesti jälkeenpäin.
|
||||
\nTai luo se Tuo/Vie toiminnolla FidMe profiilistasi, valitsemalla Tietotosuoja ja sitten valitsemalla Vie tietoni.</string>
|
||||
<string name="importFidme">Tuo FidMe varmuuskopiotiedostosta</string>
|
||||
<string name="importCatimaMessage">Etsi tiedostoa joka on todennäköisesti nimetty nimellä <i>Catima.csv</i> tuotavaksi.
|
||||
\nTai luo se Tuo/Vie toiminnolla Catima sovelluksessa, valitsemalla valikosta Vie.</string>
|
||||
<string name="importCatima">Tuo Catima varmuuskopiotiedostosta</string>
|
||||
<string name="accept">Hyväksy</string>
|
||||
<string name="privacy_policy_popup_text">Tietosuojaseloste (joidenkin sovelluskauppojen vaatimus):
|
||||
\n
|
||||
\nMITÄÄN TIETOJA EI KERÄTÄ LAINKAAN, minkä kuka tahansa voi vahvistaa, koska sovelluksemma on vapaa ohjelmisto.</string>
|
||||
<string name="privacy_policy">Tietosuojakäytäntö</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="chooseImportType">Tuo tietoja kohteesta\?</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> ei vaikuta olevan kelvollinen saldo.</string>
|
||||
<string name="points">Pisteet</string>
|
||||
<string name="currency">Valuutta</string>
|
||||
<string name="balance">Saldo</string>
|
||||
<string name="errorReadingImage">Kuvaa ei voitu lukea</string>
|
||||
<string name="noBarcodeFound">Viivakoodia ei löytynyt</string>
|
||||
<string name="moveBarcodeToCenterOfScreen">Keskitä viivakoodi näytölle</string>
|
||||
<string name="moveBarcodeToTopOfScreen">Siirrä viivakoodi näytön yläosaan</string>
|
||||
<string name="chooseExpiryDate">Valitse viimeinen voimassaolopäivä</string>
|
||||
<string name="never">Ei koskaan</string>
|
||||
<string name="expiryDate">Viimeinen voimassaolopäivä</string>
|
||||
<string name="editBarcode">Muokkaa viivakoodia</string>
|
||||
<string name="barcode">Viivakoodi</string>
|
||||
<string name="card">Kortti</string>
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> pistettä</string>
|
||||
<string name="balanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Vanhentunut: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Vanhenee: <xliff:g>%s</xliff:g></string>
|
||||
<string name="groupsList">Ryhmät: <xliff:g>%s</xliff:g></string>
|
||||
<string name="addFromImage">Valitse kuva galleriasta</string>
|
||||
<string name="addManually">Anna kortin ID-tunnus manuaalisesti</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Poistu tallentamatta\?</string>
|
||||
<string name="leaveWithoutSaveTitle">Poistu</string>
|
||||
<string name="moveDown">Siirrä alaspäin</string>
|
||||
<string name="moveUp">Siirrä ylöspäin</string>
|
||||
<string name="failedOpeningFileManager">Asenna ensin tiedostonhallintaohjelma.</string>
|
||||
<string name="deleteConfirmationGroup">Poista ryhmä\?</string>
|
||||
<string name="all">Kaikki</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> kortti</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> kortit</item>
|
||||
</plurals>
|
||||
<string name="noGroups">Napsauta + plus-painiketta lisätäksesi ensin ryhmät luokittelua varten.</string>
|
||||
<string name="groups">Ryhmät</string>
|
||||
<string name="enter_group_name">Anna ryhmän nimi</string>
|
||||
<string name="exportSuccessful">Korttitietojen vienti valmis</string>
|
||||
<string name="importSuccessful">Korttitietojen tuonti valmis</string>
|
||||
<string name="intent_import_card_from_url_share_text">Haluan jakaa kortin kanssasi</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Estä lukitusnäyttö</string>
|
||||
<string name="settings_keep_screen_on">Pidä näyttö päällä</string>
|
||||
<string name="settings_lock_barcode_orientation">Lukitse viivakoodin suunta</string>
|
||||
<string name="settings_display_barcode_max_brightness">Kirkasta viivakoodinäkymää</string>
|
||||
<string name="settings_max_font_size_scale">Fontin enimmäiskoko</string>
|
||||
<string name="settings_dark_theme">Tumma</string>
|
||||
<string name="settings_light_theme">Vaalea</string>
|
||||
<string name="settings_system_theme">Järjestelmän oletus</string>
|
||||
<string name="settings_theme">Teema</string>
|
||||
<string name="settings_category_title_ui">Käyttöliittymä</string>
|
||||
<string name="settings">Asetukset</string>
|
||||
<string name="starImage">Suosikki tähti</string>
|
||||
<string name="thumbnailDescription">Kortin pikkukuva</string>
|
||||
<string name="copy_to_clipboard_toast">Kortin ID-tunnus kopioitu leikepöydälle</string>
|
||||
<string name="enterBarcodeInstructions">Syötä kortin ID-tunnus ja valitse sen viivakoodityyppi, tai valitse \"Tällä kortilla ei ole viivakoodia\".</string>
|
||||
<string name="selectBarcodeTitle">Valitse viivakoodi</string>
|
||||
<string name="app_resources">Kolmannen osapuolen vapaat resurssit: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Kolmannen osapuolen vapaat kirjastot: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Muutostiedot: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versio: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="about_title_fmt">Tietoja <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="app_license">Copyleft (käyttäjänoikeus) - vapaa ohjelmisto, lisenssi GPLv3+.</string>
|
||||
<string name="app_copyright_old">Perustuu Loyalty Card Keychain sovellukseen
|
||||
\ntekijänoikeus © 2016–2020 Branden Archer.</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Tekijänoikeus © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="about">Tietoja</string>
|
||||
<string name="importOptionApplicationButton">Käytä toista sovellusta</string>
|
||||
<string name="importOptionApplicationExplanation">Käytä mitä tahansa sovellusta tai suosikkitiedostonhallintaasi tiedoston avaamiseen.</string>
|
||||
<string name="importOptionApplicationTitle">Käytä toista sovellusta</string>
|
||||
<string name="importOptionFilesystemButton">Tiedostojärjestelmästä</string>
|
||||
<string name="importOptionFilesystemExplanation">Valitse tietty tiedosto tiedostojärjestelmästä.</string>
|
||||
<string name="importOptionFilesystemTitle">Tuo tiedostojärjestelmästä</string>
|
||||
<string name="exportOptionExplanation">Tiedot kirjoitetaan valitsemaasi sijaintiin.</string>
|
||||
<string name="exporting">Viedään…</string>
|
||||
<string name="importing">Tuodaan…</string>
|
||||
<string name="exportFailed">Kortteja ei voitu viedä</string>
|
||||
<string name="exportFailedTitle">Vienti epäonnistui</string>
|
||||
<string name="exportSuccessfulTitle">Vienti valmis</string>
|
||||
<string name="importFailed">Kortteja ei voitu tuoda</string>
|
||||
<string name="importFailedTitle">Tuonti epäonnistui</string>
|
||||
<string name="importSuccessfulTitle">Tuonti valmis</string>
|
||||
<string name="importExportHelp">Varmuuskopioimalla korttisi, voit siirtää ne toiseen laitteeseen.</string>
|
||||
<string name="exportName">Vie</string>
|
||||
<string name="importExport">Tuo/Vie</string>
|
||||
<string name="failedParsingImportUriError">Tuonnin URI: n jäsentäminen epäonnistui</string>
|
||||
<string name="noCardExistsError">Korttia ei löytynyt</string>
|
||||
<string name="noCardIdError">Kortin ID-tunnusta ei annettu</string>
|
||||
<string name="noStoreError">Nimeä ei annettu</string>
|
||||
<string name="barcodeImageDescription">Kuva kortin viivakoodista</string>
|
||||
<string name="card_ids_copied">Kopioidut korttitunnukset</string>
|
||||
<string name="noCardsMessage">Lisää ensin kortti</string>
|
||||
<string name="cardShortcut">Kortin pikakuvake</string>
|
||||
<string name="scanCardBarcode">Skannaa kortin viivakoodi</string>
|
||||
<string name="addCardTitle">Lisää kortti</string>
|
||||
<string name="editCardTitle">Muokkaa korttia</string>
|
||||
<string name="sendLabel">Lähetä…</string>
|
||||
<string name="share">Jaa</string>
|
||||
<string name="copy_to_clipboard">Kopioi ID-tunnus leikepöydälle</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="deleteConfirmation">Poista tämä kortti\?</string>
|
||||
<string name="deleteTitle">Poista kortti</string>
|
||||
<string name="unlockScreen">Poista kierron esto</string>
|
||||
<string name="lockScreen">Estä kierto</string>
|
||||
<string name="confirm">Vahvista</string>
|
||||
<string name="delete">Poista</string>
|
||||
<string name="edit">Muokkaa</string>
|
||||
<string name="save">Tallenna</string>
|
||||
<string name="cancel">Peruuta</string>
|
||||
<string name="unstar">Poista suosikeista</string>
|
||||
<string name="star">Lisää suosikkeihin</string>
|
||||
<string name="noBarcode">Ei viivakoodia</string>
|
||||
<string name="barcodeNoBarcode">Tällä kortilla ei ole viivakoodia</string>
|
||||
<string name="barcodeType">Viivakoodin tyyppi</string>
|
||||
<string name="cardId">Kortin ID-tunnus</string>
|
||||
<string name="note">Lisätieto</string>
|
||||
<string name="storeName">Nimi</string>
|
||||
<string name="noMatchingGiftCards">Ei hakutuloksia, kokeile toisella hakutermillä.</string>
|
||||
<string name="noGiftCards">Lisää ensin kortti napsauttamalla + plus-painiketta, tai mene ⋮ valikkoon tuodaksesi varmuuskopiosta.</string>
|
||||
<string name="action_add">Lisää</string>
|
||||
<string name="action_search">Hae</string>
|
||||
<string name="takePhoto">Ota valokuva</string>
|
||||
<string name="removeImage">Poista kuva</string>
|
||||
<string name="setBackImage">Aseta takakuva</string>
|
||||
<string name="setFrontImage">Aseta etukuva</string>
|
||||
<string name="photos">Valokuvat</string>
|
||||
<string name="backImageDescription">Kortin takakuva</string>
|
||||
<string name="frontImageDescription">Kortin etukuva</string>
|
||||
</resources>
|
||||
@@ -1,10 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="action_add">Ajouter</string>
|
||||
<string name="noGiftCards">Appuyez d\'abord sur le bouton \"+\" (plus) pour ajouter une carte.
|
||||
\n
|
||||
\nCatima enregistre vos cartes sur votre appareil, pour toujours les avoir à portée de main.</string>
|
||||
<string name="storeName">Magasin</string>
|
||||
<string name="noGiftCards">Cliquez sur le bouton + plus pour ajouter une carte, ou importez-en d’abord depuis le menu ⋮</string>
|
||||
<string name="storeName">Nom</string>
|
||||
<string name="note">Notes</string>
|
||||
<string name="cardId">Numéro</string>
|
||||
<string name="cancel">Annuler</string>
|
||||
@@ -15,7 +13,7 @@
|
||||
<string name="lockScreen">Désactiver la rotation</string>
|
||||
<string name="unlockScreen">Activer la rotation</string>
|
||||
<string name="deleteTitle">Supprimer la carte de fidélité</string>
|
||||
<string name="deleteConfirmation">Confirmez la suppression de cette carte.</string>
|
||||
<string name="deleteConfirmation">Supprimer cette carte \?</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Copier le numéro dans le presse-papier</string>
|
||||
<string name="sendLabel">Envoyer…</string>
|
||||
@@ -25,7 +23,7 @@
|
||||
<string name="cardShortcut">Raccourci de carte</string>
|
||||
<string name="noCardsMessage">Ajoutez d\'abord une carte</string>
|
||||
<string name="barcodeImageDescription">Image du code-barres</string>
|
||||
<string name="noStoreError">Aucun nom de magasin saisi</string>
|
||||
<string name="noStoreError">Aucun nom saisi</string>
|
||||
<string name="noCardIdError">Aucun numéro de carte saisi</string>
|
||||
<string name="noCardExistsError">Aucune carte trouvée</string>
|
||||
<string name="importExport">Importer/Exporter</string>
|
||||
@@ -43,25 +41,19 @@
|
||||
<string name="importOptionFilesystemTitle">Importer depuis le système de fichiers</string>
|
||||
<string name="importOptionFilesystemExplanation">Choisissez le fichier à importer.</string>
|
||||
<string name="importOptionFilesystemButton">Système de fichiers</string>
|
||||
<string name="importOptionApplicationTitle">Utiliser une application externe</string>
|
||||
<string name="importOptionApplicationTitle">Utiliser une autre application</string>
|
||||
<string name="importOptionApplicationExplanation">Utilisez le gestionnaire de fichiers de votre choix pour importer un fichier.</string>
|
||||
<string name="importOptionApplicationButton">Utiliser une application externe</string>
|
||||
<string name="importOptionApplicationButton">Utiliser une autre application</string>
|
||||
<string name="about">À propos</string>
|
||||
<string name="app_license">Logiciel libre à copyleft, sous licence GPLv3+.</string>
|
||||
<string name="about_title_fmt">À propos de <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Version : <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Notes de version : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> utilise les bibliothèques-tierces suivantes : <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> utilise les ressources tierces suivantes : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Notes de version : <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Choisissez le code-barres</string>
|
||||
<string name="copy_to_clipboard_toast">Numéro de carte copié dans le presse-papier</string>
|
||||
<string name="thumbnailDescription">Miniature de la carte</string>
|
||||
<string name="settings">Paramètres</string>
|
||||
<string name="settings_category_title_ui">Interface utilisateur</string>
|
||||
<string name="settings_card_title_list_font_size">Taille du nom des cartes (mode liste)</string>
|
||||
<string name="settings_card_note_list_font_size">Taille de la description (mode liste)</string>
|
||||
<string name="settings_card_title_font_size">Taille du nom de la carte (aperçu)</string>
|
||||
<string name="settings_card_id_font_size">Taille des numéros de carte</string>
|
||||
<string name="settings_display_barcode_max_brightness">Augmenter la luminosité du code-barres</string>
|
||||
<string name="settings_lock_barcode_orientation">Verrouiller l\'orientation du code-barres</string>
|
||||
<string name="exportSuccessful">Carte exportée avec succès</string>
|
||||
@@ -71,9 +63,10 @@
|
||||
<string name="settings_light_theme">Clair</string>
|
||||
<string name="settings_system_theme">Système</string>
|
||||
<string name="settings_theme">Thème</string>
|
||||
<string name="enterBarcodeInstructions">Entrez l\'identifiant de la carte puis sélectionnez l\'image qui représente le code-barres que vous souhaitez utiliser, ou sélectionnez « Cette carte n\'a pas de code-barres » pour ne pas utiliser de code-barres.</string>
|
||||
<string name="app_copyright_old">Basé sur Loyalty Card Keychain, copyright 2016–2020 Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">Les données seront eportées vers l\'emplacement de votre choix.</string>
|
||||
<string name="enterBarcodeInstructions">Entrez l’identifiant de la carte et choisissez le type de code-barres ci-dessous, ou « Cette carte n’a pas de code-barres ».</string>
|
||||
<string name="app_copyright_old">Basé sur Loyalty Card Keychain
|
||||
\ncopyright © 2016-2020 Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">Les données seront exportées vers l\'emplacement de votre choix.</string>
|
||||
<string name="failedParsingImportUriError">Impossible d\'analyser l\'URI d\'importation</string>
|
||||
<string name="share">Partager</string>
|
||||
<string name="barcodeNoBarcode">Cette carte n\'a pas de code-barres</string>
|
||||
@@ -83,33 +76,31 @@
|
||||
<string name="unstar">Retirer des favoris</string>
|
||||
<string name="star">Ajouter aux favoris</string>
|
||||
<string name="starImage">Étoile favorite</string>
|
||||
<string name="deleteConfirmationGroup">Confirmez que vous voulez supprimer ce groupe</string>
|
||||
<string name="deleteConfirmationGroup">Supprimer le groupe \?</string>
|
||||
<string name="all">Tous</string>
|
||||
<string name="noGroups">Cliquez d\'abord sur le bouton \"+\" (plus) pour ajouter un groupe.
|
||||
\n
|
||||
\nLes groupes permettent de facilement retrouver vos cartes.</string>
|
||||
<string name="noGroups">Cliquez sur le bouton + pour ajouter des groupes à catégoriser.</string>
|
||||
<string name="groups">Groupes</string>
|
||||
<string name="enter_group_name">Entrez le nom du groupe</string>
|
||||
<string name="noBarcode">Aucun code-barres</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Voulez-vous quitter la page \? Toutes vos modifications seront perdues.</string>
|
||||
<string name="leaveWithoutSaveTitle">Quitter sans enregistrer</string>
|
||||
<string name="failedOpeningFileManager">Gestionnaire de fichiers introuvable. Installez-en un si nécessaire.</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Quitter sans enregistrer \?</string>
|
||||
<string name="leaveWithoutSaveTitle">Quitter</string>
|
||||
<string name="failedOpeningFileManager">Installez d’abord un gestionnaire de fichiers.</string>
|
||||
<string name="addManually">Entrer manuellement l\'identifiant de la carte</string>
|
||||
<string name="moveDown">Descendre dans la liste</string>
|
||||
<string name="moveUp">Monter dans la liste</string>
|
||||
<string name="moveDown">Descendre</string>
|
||||
<string name="moveUp">Monter</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> carte</item>
|
||||
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> cartes</item>
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> carte</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> cartes</item>
|
||||
</plurals>
|
||||
<string name="groupsList">Groupes : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="groupsList">Groupes : <xliff:g>%s</xliff:g></string>
|
||||
<string name="accept">Accepter</string>
|
||||
<string name="privacy_policy_popup_text">De nombreux magasins d\'applications exigent que les applications affichent leur politique de confidentialité au premier démarrage. Voici la nôtre :
|
||||
<string name="privacy_policy_popup_text">Avis sur la politique de confidentialité (exigé par certains magasins d\'applications) :
|
||||
\n
|
||||
\nNous ne collectons AUCUNE DONNÉE et le code source de notre application est ouvert afin que tout le monde puisse le confirmer.</string>
|
||||
\nAUCUNE DONNÉE N’EST COLLECTÉE, ce que tout le monde peut confirmer puisque notre application est un logiciel libre.</string>
|
||||
<string name="privacy_policy">Politique de confidentialité</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="chooseImportType">Importer des données à partir de quelle application \?</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">%s</xliff:g> ne semble pas être un solde valide.</string>
|
||||
<string name="chooseImportType">Importer les données depuis \?</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> ne semble pas être un solde valide.</string>
|
||||
<string name="points">Points</string>
|
||||
<string name="currency">Monnaie</string>
|
||||
<string name="balance">Solde</string>
|
||||
@@ -121,31 +112,59 @@
|
||||
<string name="editBarcode">Modifier le code-barres</string>
|
||||
<string name="barcode">Code-barres</string>
|
||||
<string name="card">Carte</string>
|
||||
<string name="balancePoints"><xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">%s</xliff:g> points</string>
|
||||
<string name="balanceSentence">Solde : <xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Expiré : <xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Expire : <xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">%s</xliff:g></string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Désactiver l\'écran de verrouillage pendant l\'affichage d\'une carte</string>
|
||||
<string name="settings_keep_screen_on">Garder l\'écran allumé pendant l\'affichage d\'une carte</string>
|
||||
<string name="importVoucherVaultMessage">Veuillez sélectionner votre fichier d\'exportation Voucher Vault. Il est probablement nommé vouchervault.json.
|
||||
\n
|
||||
\nUn fichier d\'exportation Voucher Vault peut être créé en appuyant sur Exporter.</string>
|
||||
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> points</string>
|
||||
<string name="balanceSentence">Solde : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Expiré : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Expire : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Empêcher le verrouillage de l’écran</string>
|
||||
<string name="settings_keep_screen_on">Garder l’écran allumé</string>
|
||||
<string name="importVoucherVaultMessage">Sélectionnez votre exportation <i>vouchervault.json</i> de Voucher Vault à importer.
|
||||
\nOu créez-la en appuyant d’abord sur Exporter dans Voucher Vault.</string>
|
||||
<string name="importVoucherVault">Importer depuis Voucher Vault</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Veuillez sélectionner votre fichier d\'exportation Loyalty Card Keychain . Il s\'appelle très probablement LoyaltyCardKeychain.csv.
|
||||
\n
|
||||
\nUn fichier d\'exportation Loyalty Card Keychain peut être créé en allant dans le menu Importer/Exporter et en appuyant sur Exporter.</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Sélectionnez votre exportation <i>LoyaltyCardKeychain.csv</i> à partir de Loyalty Card Keychain pour l’importer.
|
||||
\nOu créez-la à partir du menu Importer/Exporter du Loyalty Card Keychain en appuyant d’abord sur Exporter.</string>
|
||||
<string name="importLoyaltyCardKeychain">Importer depuis Loyalty Card Keychain</string>
|
||||
<string name="importFidmeMessage">Veuillez sélectionner votre fichier d\'exportation Fidme. Il est très probablement nommé quelque chose comme fidme-export-request-xxxxxx.zip.
|
||||
\n
|
||||
\nUn fichier d\'exportation Fidme peut être créé dans l\'application Fidme en accédant à votre profil, en choisissant Protection des données, puis en appuyant sur Extraire mes données.
|
||||
\n
|
||||
\nVeuillez noter que Fidme ne stocke pas le type de code-barres dans les données d\'exportation, vous devrez donc éditer les cartes importées manuellement.</string>
|
||||
<string name="importFidme">Importer depuis Fidme</string>
|
||||
<string name="importCatimaMessage">Veuillez sélectionner votre fichier d\'exportation Catima. Il est probablement nommé Catima.csv.
|
||||
\n
|
||||
\nUn fichier d\'exportation Catima peut être créé en allant dans le menu Importer/Exporter et en appuyant sur Exporter.</string>
|
||||
<string name="importFidmeMessage">Sélectionnez votre exportation <i>fidme-export-request-xxxxxx.zip</i> de FidMe pour l’importer, puis sélectionnez manuellement les types de codes-barres.
|
||||
\nOu créez-la à partir de votre profil FidMe en choisissant Protection des données, puis en cliquant sur Extraire mes données d’abord.</string>
|
||||
<string name="importFidme">Importer depuis FidMe</string>
|
||||
<string name="importCatimaMessage">Sélectionnez votre exportation <i>catima.zip</i> depuis Catima à importer.
|
||||
\nOu créez-la à partir du menu Importer/Exporter d’une autre application Catima en appuyant d’abord sur Exporter.</string>
|
||||
<string name="importCatima">Importer depuis Catima</string>
|
||||
<string name="addFromImage">Sélectionner dans la galerie</string>
|
||||
<string name="errorReadingImage">Erreur lors de la lecture de l\'image</string>
|
||||
<string name="errorReadingImage">Impossible de lire l\'image</string>
|
||||
<string name="noBarcodeFound">Aucun code-barres n\'a été trouvé</string>
|
||||
<string name="setBarcodeId">Définir la valeur du code-barres</string>
|
||||
<string name="sameAsCardId">Identique à l’identifiant de la carte</string>
|
||||
<string name="barcodeId">Valeur du code-barres</string>
|
||||
<string name="settings_max_font_size_scale">Taille max. de la police</string>
|
||||
<string name="unsupportedBarcodeType">Ce type de code-barres ne peut pas encore être affiché. Il sera peut-être pris en charge dans une version ultérieure de l’application.</string>
|
||||
<string name="wrongValueForBarcodeType">La valeur n\'est pas valide pour le type de code-barres sélectionné</string>
|
||||
<string name="app_resources">Ressources tierces libres : <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Bibliothèques tierces libres : <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Je veux partager des cartes avec vous</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">Identifiants des cartes copiés dans le presse-papiers</string>
|
||||
<string name="card_ids_copied">Num. de la carte copié(s)</string>
|
||||
<string name="updateBarcodeQuestionText">Vous avez changé l\'identifiant de la carte. Voulez-vous également mettre à jour le code-barres pour utiliser la même valeur \?</string>
|
||||
<string name="no">Non</string>
|
||||
<string name="yes">Oui</string>
|
||||
<string name="updateBarcodeQuestionTitle">Mettre à jour la valeur du code-barres \?</string>
|
||||
<string name="takePhoto">Prendre une photo</string>
|
||||
<string name="removeImage">Retirer l’image</string>
|
||||
<string name="setBackImage">Définir l’image verso</string>
|
||||
<string name="setFrontImage">Définir l’image recto</string>
|
||||
<string name="photos">Photos</string>
|
||||
<string name="backImageDescription">Image verso de la carte</string>
|
||||
<string name="frontImageDescription">Image recto de la carte</string>
|
||||
<string name="passwordRequired">Veuillez entrer le mot de passe</string>
|
||||
<string name="importStocardMessage">Sélectionnez votre exportation <i>***-sync.zip</i> de Stocard pour l’importer, et sélectionnez les types de codes-barres manuellement par la suite.
|
||||
\nVous pouvez aussi l’obtenir en envoyant un courriel à support@stocardapp.com pour demander une exportation de vos données.</string>
|
||||
<string name="importStocard">Importer depuis Stocard</string>
|
||||
<string name="turn_flashlight_off">Éteindre la lampe de poche</string>
|
||||
<string name="turn_flashlight_on">Allumer la lampe de poche</string>
|
||||
<string name="failedGeneratingShareURL">Échec de la génération de l’URL de partage. Veuillez signaler ce problème !</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="one">Sélectionnée : <xliff:g>%d</xliff:g> carte</item>
|
||||
<item quantity="other">Sélectionnées : <xliff:g>%d</xliff:g> cartes</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -1,12 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="action_search">Cerca</string>
|
||||
<string name="action_add">Aggiungi</string>
|
||||
<string name="noGiftCards">Fai clic sul pulsante + (più) per aggiungere prima una carta.
|
||||
\n
|
||||
\nCatima trasporta le tue carte sul dispositivo, quindi sono sempre a portata di mano.</string>
|
||||
<string name="noGiftCards">Clicca il pulsante + più per aggiungere una carta, o importane alcune dal menù ⋮ prima.</string>
|
||||
<string name="noMatchingGiftCards">Non ho trovato niente. Prova a cambiare la tua ricerca.</string>
|
||||
<string name="storeName">Negozio</string>
|
||||
<string name="storeName">Nome</string>
|
||||
<string name="note">Note</string>
|
||||
<string name="cardId">Codice</string>
|
||||
<string name="barcodeNoBarcode">Questa carta non ha un codice a barre</string>
|
||||
@@ -18,7 +16,7 @@
|
||||
<string name="lockScreen">Blocca rotazione</string>
|
||||
<string name="unlockScreen">Sblocca rotazione</string>
|
||||
<string name="deleteTitle">Rimuovi carta fedeltà</string>
|
||||
<string name="deleteConfirmation">Conferma di voler eliminare questa carta.</string>
|
||||
<string name="deleteConfirmation">Eliminare questa carta\?</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Copia ID negli appunti</string>
|
||||
<string name="share">Condividi</string>
|
||||
@@ -29,7 +27,7 @@
|
||||
<string name="cardShortcut">Scorciatoia per la carta</string>
|
||||
<string name="noCardsMessage">Aggiungi prima una carta</string>
|
||||
<string name="barcodeImageDescription">Immagine del codice della carta</string>
|
||||
<string name="noStoreError">Nessun negozio inserito</string>
|
||||
<string name="noStoreError">Nessun nome inserito</string>
|
||||
<string name="noCardIdError">Nessun codice carta inserito</string>
|
||||
<string name="noCardExistsError">Impossibile trovare la carta</string>
|
||||
<string name="failedParsingImportUriError">Impossibile analizzare l\'URI</string>
|
||||
@@ -48,19 +46,17 @@
|
||||
<string name="importOptionFilesystemTitle">Importa dal file system</string>
|
||||
<string name="importOptionFilesystemExplanation">Scegli un file dal file system.</string>
|
||||
<string name="importOptionFilesystemButton">Dal file system</string>
|
||||
<string name="importOptionApplicationTitle">Usa un\'applicazione esterna</string>
|
||||
<string name="importOptionApplicationTitle">Usa un’altra app</string>
|
||||
<string name="importOptionApplicationExplanation">Usa qualsiasi app o il tuo gestore di file preferito per aprire un file.</string>
|
||||
<string name="importOptionApplicationButton">Usa un\'applicazione esterna</string>
|
||||
<string name="importOptionApplicationButton">Usa un’altra app</string>
|
||||
<string name="about">Informazioni</string>
|
||||
<string name="app_license">Software libero con copyleft, licenza GPLv3+.</string>
|
||||
<string name="about_title_fmt">Informazioni su <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versione: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Informazioni sulla revisione: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url"> %s </xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> usa le seguenti librerie di terze parti: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> usa le seguenti risorse di terze parti: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Informazioni sulla revisione: <xliff:g id="app_revision_url"> %s </xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Seleziona codice a barre</string>
|
||||
<string name="enterBarcodeInstructions">Immettere l\'ID della carta, quindi selezionare l\'immagine che rappresenta il codice a barre desiderato oppure selezionare «Questa carta non ha un codice a barre» per non valorizzare il dato.</string>
|
||||
<string name="copy_to_clipboard_toast">ID della carta copiato negli appunti</string>
|
||||
<string name="enterBarcodeInstructions">Inserisci l’ID della carta, e scegli il suo tipo di codice a barre qui sotto, oppure «Questa carta non ha codice a barre».</string>
|
||||
<string name="copy_to_clipboard_toast">Numero della carta copiato negli appunti</string>
|
||||
<string name="thumbnailDescription">Miniatura carta</string>
|
||||
<string name="settings">Impostazioni</string>
|
||||
<string name="settings_category_title_ui">Interfaccia utente</string>
|
||||
@@ -68,41 +64,36 @@
|
||||
<string name="settings_system_theme">Sistema</string>
|
||||
<string name="settings_light_theme">Chiaro</string>
|
||||
<string name="settings_dark_theme">Scuro</string>
|
||||
<string name="settings_card_title_list_font_size">Dimensione caratteri del titolo della carta (modalità elenco)</string>
|
||||
<string name="settings_card_note_list_font_size">Dimensione caratteri nota della carta (modalità elenco)</string>
|
||||
<string name="settings_card_title_font_size">Dimensione caratteri del titolo della carta (anteprima)</string>
|
||||
<string name="settings_card_id_font_size">Dimensione testo dell\'ID carta</string>
|
||||
<string name="settings_display_barcode_max_brightness">Aumenta luminosità dello schermo quando apro un codice a barre</string>
|
||||
<string name="settings_lock_barcode_orientation">Blocca orientamento del codice a barre</string>
|
||||
<string name="intent_import_card_from_url_share_text">Voglio condividere una carta fedeltà con te</string>
|
||||
<string name="exportSuccessful">Dati della carta importati</string>
|
||||
<string name="importSuccessful">Dati della carta importati</string>
|
||||
<string name="app_copyright_old">Basato su Loyalty Card Keychain, copyright 2016–2020 Branden Archer.</string>
|
||||
<string name="app_copyright_old">Basato su Loyalty Card Keychain
|
||||
\ncopyright © 2016–2020 Branden Archer.</string>
|
||||
<string name="exportOptionExplanation">I dati verranno scritti in una posizione a tua scelta.</string>
|
||||
<string name="barcodeType">Tipo di codice a barre</string>
|
||||
<string name="unstar">Rimuovi dai preferiti</string>
|
||||
<string name="star">Aggiungi ai preferiti</string>
|
||||
<string name="starImage">Stella preferita</string>
|
||||
<string name="deleteConfirmationGroup">Conferma di voler eliminare questo gruppo</string>
|
||||
<string name="deleteConfirmationGroup">Eliminare il gruppo\?</string>
|
||||
<string name="all">Tutti</string>
|
||||
<string name="noGroups">Fai clic sul pulsante + (più) per aggiungere prima i gruppi.
|
||||
\n
|
||||
\nI gruppi rendono le cose più facili da trovare.</string>
|
||||
<string name="noGroups">Clicca sul pulsante + più per aggiungere prima i gruppi per la categorizzazione.</string>
|
||||
<string name="groups">Gruppi</string>
|
||||
<string name="enter_group_name">Inserisci il nome del gruppo</string>
|
||||
<string name="groupsList">Gruppi: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="groupsList">Gruppi: <xliff:g>%s</xliff:g></string>
|
||||
<string name="addManually">Inserisci manualmente l\'ID della carta</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Sei sicuro/a di voler uscire da questa schermata\? Le modifiche apportate non verranno salvate.</string>
|
||||
<string name="leaveWithoutSaveTitle">Esci senza salvare</string>
|
||||
<string name="moveDown">Sposta in basso nell\'elenco</string>
|
||||
<string name="moveUp">Sposta in alto nell\'elenco</string>
|
||||
<string name="failedOpeningFileManager">Apertura di un gestore di file non riuscita. Assicurati che ne sia installato uno.</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Uscire senza salvare\?</string>
|
||||
<string name="leaveWithoutSaveTitle">Esci</string>
|
||||
<string name="moveDown">Sposta in basso</string>
|
||||
<string name="moveUp">Sposta in alto</string>
|
||||
<string name="failedOpeningFileManager">Installa prima un gestore di file.</string>
|
||||
<string name="noBarcode">Nessun codice a barre</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> carta</item>
|
||||
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> carte</item>
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> carta</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> carte</item>
|
||||
</plurals>
|
||||
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">%s</xliff:g> non sembra un saldo corretto.</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> non sembra un saldo corretto.</string>
|
||||
<string name="points">Punti</string>
|
||||
<string name="currency">Valuta</string>
|
||||
<string name="balance">Saldo</string>
|
||||
@@ -114,35 +105,66 @@
|
||||
<string name="editBarcode">Modifica il codice a barre</string>
|
||||
<string name="barcode">Codice a barre</string>
|
||||
<string name="card">Carta</string>
|
||||
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> punti</string>
|
||||
<string name="balanceSentence">Saldo: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Scaduta: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Scade: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="settings_keep_screen_on">Mantieni schermo acceso durante la visualizzazione di una carta</string>
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> punti</string>
|
||||
<string name="balanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Scaduta: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Scade: <xliff:g>%s</xliff:g></string>
|
||||
<string name="settings_keep_screen_on">Tieni schermo attivo</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="chooseImportType">Da quale app vuoi importare i dati\?</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Mantieni schermo attivo mentre visualizzi una carta</string>
|
||||
<string name="chooseImportType">Importare i dati da\?</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Impedisci blocco schermo</string>
|
||||
<string name="accept">Accetta</string>
|
||||
<string name="privacy_policy_popup_text">È spesso richiesto alle applicazioni di mostrare la loro politica sulla riservatezza al primo avvio. Ecco la nostra:
|
||||
<string name="privacy_policy_popup_text">Informativa sulla riservatezza (spesso richiesta):
|
||||
\n
|
||||
\nNon raccogliamo ALCUN DATO e il codice sorgente della nostra applicazione è aperto, quindi chiunque può confermare che ciò sia vero.</string>
|
||||
\nNESSUN DATO VIENE RACCOLTO, cosa che chiunque può confermare dato che la nostra applicazione è un software libero.</string>
|
||||
<string name="privacy_policy">Informativa sulla riservatezza</string>
|
||||
<string name="importVoucherVaultMessage">Seleziona il tuo file di esportazione Voucher Vault. Molto probabilmente si chiama vouchervault.json.
|
||||
\n
|
||||
\nÈ possibile creare un file di esportazione Voucher Vault premendo Esporta.</string>
|
||||
<string name="importVoucherVaultMessage">Seleziona la tua esportazione <i>vouchervault.json</i> da Voucher Vault da importare.
|
||||
\nOppure crealo premendo prima Esporta in Voucher Vault.</string>
|
||||
<string name="importVoucherVault">Importa da Voucher Vault</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Seleziona il file di esportazione Loyalty Card Keychain . Molto probabilmente si chiama LoyaltyCardKeychain.csv.
|
||||
\n
|
||||
\nÈ possibile creare un file di esportazione Loyalty Card Keychain accedendo al menu Importa / Esporta e premendo Esporta.</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Seleziona la tua esportazione <i>LoyaltyCardKeychain.csv</i> da Loyalty Card Keychain per importarla.
|
||||
\nOppure createlo dal menù Importazione/Esportazione in Loyalty Card Keychain premendo prima su Esporta.</string>
|
||||
<string name="importLoyaltyCardKeychain">Importa da Loyalty Card Keychain</string>
|
||||
<string name="importFidmeMessage">Seleziona il tuo file di esportazione Fidme. Molto probabilmente si chiama qualcosa come fidme-export-request-xxxxxx.zip.
|
||||
\n
|
||||
\nUn file di esportazione Fidme può essere creato nell\'app Fidme andando sul tuo profilo, scegliendo Protezione dati e quindi premendo Estrai i miei dati.
|
||||
\n
|
||||
\nTieni presente che Fidme non memorizza il tipo di codice a barre nei dati di esportazione, quindi dovrai modificare manualmente le carte importate.</string>
|
||||
<string name="importFidme">Importa da Fidme</string>
|
||||
<string name="importCatimaMessage">Seleziona il tuo file di esportazione Catima. Molto probabilmente si chiama Catima.csv.
|
||||
\n
|
||||
\nÈ possibile creare un file di esportazione Catima andando nel menu Importa / Esporta e premendo Esporta.</string>
|
||||
<string name="importFidmeMessage">Seleziona la tua esportazione <i>fidme-export-request-xxxxxx.zip</i> da FidMe per importare, e seleziona i tipi di codice a barre manualmente dopo.
|
||||
\nOppure crearlo dal tuo profilo FidMe scegliendo Protezione Dati e poi premendo Estrai i miei dati prima.</string>
|
||||
<string name="importFidme">Importa da FidMe</string>
|
||||
<string name="importCatimaMessage">Seleziona la tua esportazione <i>catima.zip</i> da Catima per importarla.
|
||||
\nOppure crealo dal menù Importazione/Esportazione di un\'altra applicazione Catima premendo prima Esporta.</string>
|
||||
<string name="importCatima">Importa da Catima</string>
|
||||
<string name="setBarcodeId">Imposta il valore del codice a barre</string>
|
||||
<string name="sameAsCardId">Uguale all\'ID della carta</string>
|
||||
<string name="barcodeId">Valore del codice a barre</string>
|
||||
<string name="errorReadingImage">Impossibile leggere l\'immagine</string>
|
||||
<string name="noBarcodeFound">Nessun codice a barre trovato</string>
|
||||
<string name="addFromImage">Seleziona immagine dalla galleria</string>
|
||||
<string name="settings_max_font_size_scale">Dimensione mass. caratteri</string>
|
||||
<string name="unsupportedBarcodeType">Questo tipo di codice a barre non può ancora essere visualizzato. Potrebbe essere supportato in una versione successiva dell\'applicazione.</string>
|
||||
<string name="wrongValueForBarcodeType">Il valore non è valido per il tipo di codice a barre selezionato</string>
|
||||
<string name="app_resources">Risorse libre di terze parti: <xliff:g id="app_resources_list"> %s </xliff:g></string>
|
||||
<string name="app_libraries">Librerie libre di terze parti: <xliff:g id="app_libraries_list"> %s </xliff:g></string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Voglio condividere alcune carte con te</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">Numeri delle carte copiati negli appunti</string>
|
||||
<string name="card_ids_copied">Numero/i della carta copiato/i</string>
|
||||
<string name="no">No</string>
|
||||
<string name="yes">Sì</string>
|
||||
<string name="updateBarcodeQuestionText">Hai cambiato l\'ID della carta. Vuoi anche aggiornare il codice a barre per usare lo stesso valore\?</string>
|
||||
<string name="updateBarcodeQuestionTitle">Aggiornare il valore del codice a barre\?</string>
|
||||
<string name="takePhoto">Scatta una foto</string>
|
||||
<string name="removeImage">Rimuovi l’immagine</string>
|
||||
<string name="setBackImage">Imposta immagine posteriore</string>
|
||||
<string name="setFrontImage">Imposta immagine frontale</string>
|
||||
<string name="photos">Foto</string>
|
||||
<string name="backImageDescription">Immagine posteriore della carta</string>
|
||||
<string name="frontImageDescription">Immagine frontale della carta</string>
|
||||
<string name="passwordRequired">Si prega di inserire la password</string>
|
||||
<string name="importStocardMessage">Seleziona la tua esportazione <i>***-sync.zip</i> da Stocard per importare, e seleziona i tipi di codice a barre manualmente dopo.
|
||||
\nOppure ottenerlo inviando un\'e-mail a support@stocardapp.com chiedendo un\'esportazione dei tuoi dati.</string>
|
||||
<string name="importStocard">Importa da Stocard</string>
|
||||
<string name="turn_flashlight_off">Spegni la torcia</string>
|
||||
<string name="turn_flashlight_on">Accendi la torcia</string>
|
||||
<string name="failedGeneratingShareURL">Impossibile generare l\'URL di condivisione. Si prega di segnalare questo errore!</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="one">Selezionata: <xliff:g>%d</xliff:g> carta</item>
|
||||
<item quantity="other">Selezionate: <xliff:g>%d</xliff:g> carte</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
168
app/src/main/res/values-ja/strings.xml
Normal file
168
app/src/main/res/values-ja/strings.xml
Normal file
@@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="wrongValueForBarcodeType">選択したバーコード形式ではこの番号は使用できません</string>
|
||||
<string name="unsupportedBarcodeType">このバーコード形式は表示できません。将来のアップデートにより対応するかもしれません。</string>
|
||||
<string name="setBarcodeId">バーコード番号を設定</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">インポートするにはLoyalty Card Keychainでエクスポートした <i>LoyaltyCardKeychain.csv</i>ファイルを選択してください。
|
||||
\nファイルがない場合、 Loyalty Card Keychainアプリからファイルをエクスポートしてください。</string>
|
||||
<string name="importLoyaltyCardKeychain">Loyalty Card Keychainからインポート</string>
|
||||
<string name="importFidmeMessage">インポートするにはFindMeでエクスポートした <i>fidme-export-request-xxxxxx.zip</i>ファイルを選択してください。そのあと手動でバーコード形式を選択してください。
|
||||
\nファイルがない場合、FidMeでファイルを作成してください。</string>
|
||||
<string name="importFidme">FidMeからインポート</string>
|
||||
<string name="importCatimaMessage">インポートするにはCatimaでエクスポートした<i>Catima.zip</i>ファイルを選択してください。
|
||||
\nファイルがない場合、他のCatimaアプリでファイルをエクスポートしてください。</string>
|
||||
<string name="importCatima">Catimaからインポート</string>
|
||||
<string name="accept">承認</string>
|
||||
<string name="privacy_policy_popup_text">プライバシーポリシーの案内:
|
||||
\n
|
||||
\nこのアプリはユーザーのデータを一切収集しません。</string>
|
||||
<string name="privacy_policy">プライバシーポリシー</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="chooseImportType">インポート元を選択</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> は有効な残高ではないようです。</string>
|
||||
<string name="points">ポイント</string>
|
||||
<string name="currency">通貨</string>
|
||||
<string name="balance">残高</string>
|
||||
<string name="errorReadingImage">画像が読み込めませんでした</string>
|
||||
<string name="noBarcodeFound">バーコードが見つかりませんでした</string>
|
||||
<string name="moveBarcodeToCenterOfScreen">バーコードを画面の中央に配置</string>
|
||||
<string name="moveBarcodeToTopOfScreen">バーコードを画面の上部に移動</string>
|
||||
<string name="chooseExpiryDate">有効期限を選択</string>
|
||||
<string name="never">なし</string>
|
||||
<string name="expiryDate">有効期限</string>
|
||||
<string name="editBarcode">バーコードの編集</string>
|
||||
<string name="barcode">バーコード</string>
|
||||
<string name="card">カード</string>
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> ポイント</string>
|
||||
<string name="balanceSentence">残高: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">期限切れ: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">期限: <xliff:g>%s</xliff:g></string>
|
||||
<string name="groupsList">グループ: <xliff:g>%s</xliff:g></string>
|
||||
<string name="addFromImage">ギャラリーから画像を選択</string>
|
||||
<string name="addManually">カード番号を手動で入力</string>
|
||||
<string name="leaveWithoutSaveConfirmation">保存せずに終了しますか?</string>
|
||||
<string name="leaveWithoutSaveTitle">終了する</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> 枚</item>
|
||||
</plurals>
|
||||
<string name="moveDown">下に移動</string>
|
||||
<string name="moveUp">上に移動</string>
|
||||
<string name="failedOpeningFileManager">ファイルマネージャーをインストールしてください。</string>
|
||||
<string name="deleteConfirmationGroup">グループを削除しますか?</string>
|
||||
<string name="all">すべて</string>
|
||||
<string name="noGroups">+ボタンを押してグループを追加してください。</string>
|
||||
<string name="groups">グループ</string>
|
||||
<string name="enter_group_name">グループ名を入力</string>
|
||||
<string name="exportSuccessful">カードのデータがエクスポートされました</string>
|
||||
<string name="importSuccessful">カードのデータがインポートされました</string>
|
||||
<string name="intent_import_card_from_url_share_text">カード共有をしましょう</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">バーコード表示中は画面をロックしない</string>
|
||||
<string name="settings_keep_screen_on">バーコード表示中は画面を消灯しない</string>
|
||||
<string name="settings_lock_barcode_orientation">バーコード表示画面を自動回転しない</string>
|
||||
<string name="settings_display_barcode_max_brightness">バーコード表示画面を明るくする</string>
|
||||
<string name="settings_max_font_size_scale">最大のフォントサイズ</string>
|
||||
<string name="settings_dark_theme">ダーク</string>
|
||||
<string name="settings_light_theme">ライト</string>
|
||||
<string name="settings_system_theme">システムに従う</string>
|
||||
<string name="settings_theme">テーマ</string>
|
||||
<string name="settings_category_title_ui">外観</string>
|
||||
<string name="settings">設定</string>
|
||||
<string name="starImage">お気に入りのスター</string>
|
||||
<string name="thumbnailDescription">カードのサムネイル</string>
|
||||
<string name="copy_to_clipboard_toast">カード番号をクリップボードにコピーしました</string>
|
||||
<string name="enterBarcodeInstructions">カード番号を入力し、バーコード形式を選択してください。</string>
|
||||
<string name="selectBarcodeTitle">バーコード選択</string>
|
||||
<string name="app_libraries">Libre third-party libraries: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Revision Info: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Version: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="about_title_fmt">About <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="app_license">Copylefted libre software, licensed GPLv3+.</string>
|
||||
<string name="app_copyright_old">Based on Loyalty Card Keychain
|
||||
\ncopyright © 2016–2020 Branden Archer.</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="app_resources">Libre third-party resources: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="about">Catimaについて</string>
|
||||
<string name="importOptionApplicationButton">外部のアプリを使う</string>
|
||||
<string name="importOptionApplicationExplanation">任意のアプリやお気に入りのファイルマネージャーからファイルを開く。</string>
|
||||
<string name="importOptionApplicationTitle">外部アプリを使う</string>
|
||||
<string name="importOptionFilesystemButton">ファイルを選択</string>
|
||||
<string name="importOptionFilesystemExplanation">ストレージからファイルを選択してください。</string>
|
||||
<string name="importOptionFilesystemTitle">ストレージからインポート</string>
|
||||
<string name="exportOptionExplanation">選択した場所にデータを出力します。</string>
|
||||
<string name="noExternalStoragePermissionError">カードをインポート/エクスポートするために外部ストレージへのアクセスを許可してください</string>
|
||||
<string name="exporting">エクスポート中…</string>
|
||||
<string name="importing">インポート中…</string>
|
||||
<string name="exportFailed">カードをエクスポートできませんでした</string>
|
||||
<string name="exportFailedTitle">エクスポートに失敗しました</string>
|
||||
<string name="exportSuccessfulTitle">エクスポートしました</string>
|
||||
<string name="sameAsCardId">カードの表記と同一</string>
|
||||
<string name="barcodeId">バーコード番号</string>
|
||||
<string name="importVoucherVaultMessage">Voucher Vaultでエクスポートした <i>vouchervault.json</i>ファイルを選択してください。
|
||||
\nファイルがない場合、Voucher Vaultでファイルをエクスポートしてください。</string>
|
||||
<string name="importVoucherVault">Voucher Vaultからインポート</string>
|
||||
<string name="importFailed">カードをインポートできません</string>
|
||||
<string name="importFailedTitle">インポートに失敗しました</string>
|
||||
<string name="importSuccessfulTitle">インポートしました</string>
|
||||
<string name="importExportHelp">カードをバックアップすると、他のデバイスにカードを移すことができます。</string>
|
||||
<string name="exportName">エクスポート</string>
|
||||
<string name="importExport">インポート/エクスポート</string>
|
||||
<string name="failedParsingImportUriError">インポートURIを解析できません</string>
|
||||
<string name="noCardExistsError">カードが見つかりません</string>
|
||||
<string name="noCardIdError">カード番号が入力されていません</string>
|
||||
<string name="noStoreError">名前が入力されていません</string>
|
||||
<string name="barcodeImageDescription">バーコードの画像</string>
|
||||
<string name="noCardsMessage">カードを追加</string>
|
||||
<string name="cardShortcut">カードのショートカット</string>
|
||||
<string name="scanCardBarcode">カードのバーコードをスキャン</string>
|
||||
<string name="addCardTitle">カードの追加</string>
|
||||
<string name="editCardTitle">カードの編集</string>
|
||||
<string name="sendLabel">送信先を選択…</string>
|
||||
<string name="share">共有</string>
|
||||
<string name="copy_to_clipboard">カード番号をクリップボードにコピーする</string>
|
||||
<string name="ok">確定</string>
|
||||
<string name="deleteConfirmation">このカードを削除しますか?</string>
|
||||
<string name="deleteTitle">カードの削除</string>
|
||||
<string name="unlockScreen">自動回転を無効にしない</string>
|
||||
<string name="lockScreen">自動回転を無効にする</string>
|
||||
<string name="confirm">確認</string>
|
||||
<string name="delete">削除</string>
|
||||
<string name="edit">編集</string>
|
||||
<string name="save">保存</string>
|
||||
<string name="cancel">取り消し</string>
|
||||
<string name="unstar">お気に入りから削除</string>
|
||||
<string name="star">お気に入りに追加</string>
|
||||
<string name="noBarcode">バーコードなし</string>
|
||||
<string name="barcodeNoBarcode">バーコード指定なし</string>
|
||||
<string name="barcodeType">バーコード形式</string>
|
||||
<string name="cardId">カード番号</string>
|
||||
<string name="note">メモ</string>
|
||||
<string name="storeName">名前</string>
|
||||
<string name="noMatchingGiftCards">該当なし</string>
|
||||
<string name="noGiftCards">まず初めに+ボタンを押してカードを追加するか、メニューから以前のカードをインポートしてください。</string>
|
||||
<string name="action_add">追加</string>
|
||||
<string name="action_search">検索</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">カードを共有しましょう</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">カード番号をクリップボードにコピーしました</string>
|
||||
<string name="card_ids_copied">コピーしたカード</string>
|
||||
<string name="turn_flashlight_off">ライトをオフにする</string>
|
||||
<string name="turn_flashlight_on">ライトをオンにする</string>
|
||||
<string name="failedGeneratingShareURL">共有URLの生成に失敗しました。バグを報告してください。</string>
|
||||
<string name="passwordRequired">パスワードを入力してください</string>
|
||||
<string name="no">いいえ</string>
|
||||
<string name="yes">はい</string>
|
||||
<string name="updateBarcodeQuestionText">カード番号を変更しました。バーコード番号も同じ値に変更しますか?</string>
|
||||
<string name="updateBarcodeQuestionTitle">バーコードの番号を変更しますか?</string>
|
||||
<string name="takePhoto">写真を撮影する</string>
|
||||
<string name="removeImage">画像を削除</string>
|
||||
<string name="setBackImage">裏面の画像を設定</string>
|
||||
<string name="setFrontImage">表面の画像を設定</string>
|
||||
<string name="photos">フォト</string>
|
||||
<string name="backImageDescription">裏面</string>
|
||||
<string name="frontImageDescription">表面</string>
|
||||
<string name="importStocardMessage">Stocardでエクスポートした<i>***-sync.zip</i>ファイルを選択し、手動でバーコード形式を選択してください。
|
||||
\nファイルがない場合、e-mailing support@stocardapp.comにデータのエクスポートを要求してください。</string>
|
||||
<string name="importStocard">Stocardからインポート</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="other">選択済み: <xliff:g>%d</xliff:g> 枚</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -6,10 +6,6 @@
|
||||
<string name="groups">그룹</string>
|
||||
<string name="enter_group_name">그룹 이름 입력</string>
|
||||
<string name="settings_lock_barcode_orientation">바코드 회전 잠금</string>
|
||||
<string name="settings_card_id_font_size">카드 ID 글꼴 크기</string>
|
||||
<string name="settings_card_title_font_size">카드 제목 글꼴 크기 (미리 보기)</string>
|
||||
<string name="settings_card_note_list_font_size">카드 노트 글꼴 크기 (목록 모드)</string>
|
||||
<string name="settings_card_title_list_font_size">카드 제목 글꼴 크기 (목록 모드)</string>
|
||||
<string name="settings_dark_theme">어두움</string>
|
||||
<string name="settings_light_theme">밝음</string>
|
||||
<string name="debug_version_fmt">버전: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="version">%s</xliff:g></string>
|
||||
@@ -18,10 +14,8 @@
|
||||
<string name="settings_theme">테마</string>
|
||||
<string name="settings_category_title_ui">사용자 인터페이스</string>
|
||||
<string name="settings">설정</string>
|
||||
<string name="enterBarcodeInstructions">카드 ID를 입력하고 카드에서 사용하는 바코드 이미지를 선택하세요. 바코드를 사용하지 않는 경우 \"이 카드는 바코드가 없음\"을 선택하세요.</string>
|
||||
<string name="app_resources"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> 앱은 다음 서드 파티 리소스를 사용합니다: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> 앱은 다음 서드 파티 라이브러리를 사용합니다: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">리비전 정보: <xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\" id=\"app_revision_url\">%s</xliff:g></string>
|
||||
<string name="enterBarcodeInstructions">카드 ID를 입력하고 카드에서 사용하는 바코드 이미지를 선택하세요. 바코드를 사용하지 않는 경우 “이 카드는 바코드가 없음”을 선택하세요.</string>
|
||||
<string name="app_revision_fmt">리비전 정보: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">바코드 선택</string>
|
||||
<string name="about">정보</string>
|
||||
<string name="exporting">내보내는 중…</string>
|
||||
@@ -84,4 +78,4 @@
|
||||
<string name="starImage">즐겨찾기 별</string>
|
||||
<string name="settings_display_barcode_max_brightness">바코드를 표시할 때 화면 밝기 높이기</string>
|
||||
<string name="barcode">바코드</string>
|
||||
</resources>
|
||||
</resources>
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="action_add">Pridėti</string>
|
||||
|
||||
<string name="noGiftCards">Šiuo metu neturite nė vienos įvestos lojalumo kortelės. Paspauskite "+" (pliuso) pliuso mygtuką, kad pradėtumėte.\n\nLoyalty Card Locker leidžia Jums visada nešiotis lojalumo kortelių informaciją savo telefone ar planšetėje, taip jos visada pasiekiamos.</string>
|
||||
<string name="storeName">Parduotuvė</string>
|
||||
<string name="noGiftCards">Norėdami pridėti kortelę, spustelėkite mygtuką + plius arba pirmiausia importuokite kortelę iš ⋮ meniu.</string>
|
||||
<string name="storeName">Pavadinimas</string>
|
||||
<string name="note">Užrašas</string>
|
||||
<string name="cardId">Kortelės ID</string>
|
||||
<string name="cancel">Atšaukti</string>
|
||||
@@ -13,30 +11,162 @@
|
||||
<string name="delete">Ištrinti</string>
|
||||
<string name="confirm">Patvirtinti</string>
|
||||
<string name="deleteTitle">Panaikinti lojalumo kortelę</string>
|
||||
<string name="deleteConfirmation">Prašome patvirtinti jog Jūs norite panaikinti šią lojalumo kortelę.</string>
|
||||
<string name="deleteConfirmation">Ištrinti šią kortelę\?</string>
|
||||
<string name="ok">Gerai</string>
|
||||
<string name="copy_to_clipboard">Nukopijuoti ID į iškarpinę</string>
|
||||
<string name="editCardTitle">Redaguoti lojalumo kortelę</string>
|
||||
<string name="addCardTitle">Pridėti lojalumo kortelę</string>
|
||||
<string name="scanCardBarcode">Nuskanuokite kortelės brūkšninį kodą</string>
|
||||
<string name="barcodeImageDescription">Kortelės brūkšninio kodo paveikslėlis</string>
|
||||
|
||||
<string name="noStoreError">Parduotuvė neįvesta</string>
|
||||
<string name="scanCardBarcode">Skenuoti kortelės brūkšninį kodą</string>
|
||||
<string name="barcodeImageDescription">Kortelės brūkšninio kodo vaizdas</string>
|
||||
<string name="noStoreError">Neįvestas pavadinimas</string>
|
||||
<string name="noCardIdError">Neįvestas kortelės ID</string>
|
||||
<string name="importExport">Importuoti/Exportuoti</string>
|
||||
<string name="exportName">Exportuoti</string>
|
||||
<string name="importFailed">Nepavyko importuoti</string>
|
||||
<string name="exportFailed">Nepavyko eksportuoti</string>
|
||||
<string name="importing">Importuoja…</string>
|
||||
<string name="exporting">Eksportuoja…</string>
|
||||
<string name="noExternalStoragePermissionError">Negalima importuoti/eksportuoti kortelių be išorinės atminties leidimo</string>
|
||||
<string name="importFailed">Nepavyko importuoti kortelių</string>
|
||||
<string name="exportFailed">Nepavyko eksportuoti kortelių</string>
|
||||
<string name="importing">Importuoja…</string>
|
||||
<string name="exporting">Eksportuoja…</string>
|
||||
<string name="noExternalStoragePermissionError">Pirmiausia suteikite išorinės saugyklos leidimą, kad galėtumėte importuoti arba eksportuoti korteles</string>
|
||||
<string name="about">Apie</string>
|
||||
<string name="app_license">Licenzijuota pagal GPLv3.</string>
|
||||
<string name="app_license">Copylefted libre programinė įranga, licencijuota GPLv3+.</string>
|
||||
<string name="about_title_fmt">Apie <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versija: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Revizijos informacija: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> naudoja šias trečiosios šalies bibliotekas: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Revizijos info: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Pasirinkite brūkšninį kodą</string>
|
||||
<string name="copy_to_clipboard_toast">Kortelės ID nukopijuota į iškarpinę</string>
|
||||
|
||||
</resources>
|
||||
<string name="card_ids_copied">Nukopijuotos kortelės ID</string>
|
||||
<string name="noCardsMessage">Pirmiausia pridėkite kortelę</string>
|
||||
<string name="sendLabel">Siųsti…</string>
|
||||
<string name="unlockScreen">Atblokuoti pasukimą</string>
|
||||
<string name="lockScreen">Blokuoti pasukimą</string>
|
||||
<string name="unstar">Pašalinti iš mėgstamiausių</string>
|
||||
<string name="star">Pridėti prie mėgstamiausių</string>
|
||||
<string name="noBarcode">Nėra brūkšninio kodo</string>
|
||||
<string name="barcodeNoBarcode">Ši kortelė neturi brūkšninio kodo</string>
|
||||
<string name="barcodeType">Brūkšninio kodo tipas</string>
|
||||
<string name="noMatchingGiftCards">Nieko nerasta. Pabandykite pakeisti paiešką.</string>
|
||||
<string name="action_search">Ieškoti</string>
|
||||
<string name="cardShortcut">Kortelės sparčioji nuoroda</string>
|
||||
<string name="importVoucherVaultMessage">Pasirinkite savo <i>vouchervault.json</i> eksportą iš Voucher Vault, kurį norite importuoti.
|
||||
\nArba sukurkite jį pirmiausia paspausdami Eksportuoti Voucher Vault.</string>
|
||||
<string name="importVoucherVault">Importuoti iš Voucher Vault</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Pasirinkite savo <i> LoyaltyCardKeychain.csv</i> eksportą iš Loyalty Card Keychain, kurį norite importuoti.
|
||||
\nArba sukurkite jį iš Loyalty Card Keychain meniu Importas/Eksportas, pirmiausia paspausdami Eksportuoti.</string>
|
||||
<string name="importLoyaltyCardKeychain">Importuoti iš Loyalty Card Keychain</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="parsingBalanceFailed">Panašu, kad <xliff:g> %s </xliff:g> reikšmė nėra tinkama.</string>
|
||||
<string name="moveBarcodeToCenterOfScreen">Centruoti brūkšninį kodą ekrane</string>
|
||||
<string name="moveBarcodeToTopOfScreen">Perkelti brūkšninį kodą į ekrano viršų</string>
|
||||
<string name="settings_display_barcode_max_brightness">Šviesinti brūkšninio kodo rodinį</string>
|
||||
<string name="failedParsingImportUriError">Nepavyko iššifruoti importo URI</string>
|
||||
<string name="turn_flashlight_off">Išjunkti žibintuvėlį</string>
|
||||
<string name="turn_flashlight_on">Įjunkti žibintuvėlį</string>
|
||||
<string name="failedGeneratingShareURL">Nepavyko sugeneruoti bendrinamo URL. Praneškite apie šią klaidą!</string>
|
||||
<string name="passwordRequired">Įveskite slaptažodį</string>
|
||||
<string name="no">Ne</string>
|
||||
<string name="yes">Taip</string>
|
||||
<string name="updateBarcodeQuestionText">Pakeitėte kortelės ID. Ar norite atnaujinti ir brūkšninį kodą, kad būtų naudojama ta pati reikšmė\?</string>
|
||||
<string name="updateBarcodeQuestionTitle">Atnaujinti brūkšninio kodo reikšmę\?</string>
|
||||
<string name="takePhoto">Nufotografuoti</string>
|
||||
<string name="removeImage">Pašalinti vaizdą</string>
|
||||
<string name="setBackImage">Nustatyti galinį vaizdą</string>
|
||||
<string name="setFrontImage">Nustatyti priekinį vaizdą</string>
|
||||
<string name="photos">Nuotraukos</string>
|
||||
<string name="backImageDescription">Kortelės galinis vaizdas</string>
|
||||
<string name="frontImageDescription">Kortelės priekinis vaizdas</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Noriu su jumis pasidalyti keliomis kortelėmis</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">Kortelės ID nukopijuotas į iškarpinę</string>
|
||||
<string name="wrongValueForBarcodeType">Vertė netinkama pasirinktam brūkšninio kodo tipui</string>
|
||||
<string name="unsupportedBarcodeType">Šio brūkšninio kodo tipo dar negalima rodyti. Galbūt jis bus palaikomas vėlesnėje programėlės versijoje.</string>
|
||||
<string name="setBarcodeId">Nustatyti brūkšninio kodo reikšmę</string>
|
||||
<string name="sameAsCardId">Tokia pat kaip kortelės ID</string>
|
||||
<string name="barcodeId">Brūkšninio kodo reikšmė</string>
|
||||
<string name="importStocardMessage">Pasirinkite <i>***-sync.zip</i> eksportą iš Stocard, kad galėtumėte importuoti, o vėliau brūkšninių kodų tipus pasirinkite rankiniu būdu.
|
||||
\nArba gaukite susisiekę el. paštu support@stocardapp.com, prašydami eksportuoti jūsų duomenis.</string>
|
||||
<string name="importStocard">Importuoti iš Stocard</string>
|
||||
<string name="importFidmeMessage">Pasirinkite <i>fidme-export-request-xxxxxx.zip</i> eksportą iš FidMe, kurį norite importuoti, ir po to brūkšninių kodų tipus pasirinkite rankiniu būdu.
|
||||
\nArba sukurkite jį iš savo FidMe profilio, pasirinkę Duomenų apsauga ir pirmiausia paspaudę Išgauti mano duomenis.</string>
|
||||
<string name="importFidme">Importuoti iš FidMe</string>
|
||||
<string name="importCatimaMessage">Norėdami importuoti, pasirinkite savo <i> catima.zip </i> eksportą iš Catima.
|
||||
\nArba sukurkite ją iš kitos Catima programos importavimo / eksportavimo meniu, pirmiausia paspausdami Eksportuoti ten.</string>
|
||||
<string name="importCatima">Importuoti iš Catima</string>
|
||||
<string name="accept">Priimti</string>
|
||||
<string name="privacy_policy_popup_text">Privatumo politikos pranešimas (kurio reikalaujama kai kuriose programėlių parduotuvėse):
|
||||
\n
|
||||
\nJOKIE DUOMENYS NĖRA RENKAMI, o tai gali patvirtinti bet kas, nes mūsų programėlė yra libre programinė įranga.</string>
|
||||
<string name="privacy_policy">Privatumo politika</string>
|
||||
<string name="chooseImportType">Importuoti duomenis iš\?</string>
|
||||
<string name="points">Taškai</string>
|
||||
<string name="currency">Valiuta</string>
|
||||
<string name="balance">Balansas</string>
|
||||
<string name="errorReadingImage">Nepavyko nuskaityti paveikslėlio</string>
|
||||
<string name="noBarcodeFound">Nerastas joks brūkšninis kodas</string>
|
||||
<string name="chooseExpiryDate">Pasirinkite galiojimo datą</string>
|
||||
<string name="never">Niekada</string>
|
||||
<string name="expiryDate">Galiojimo data</string>
|
||||
<string name="editBarcode">Redaguoti brūkšninį kodą</string>
|
||||
<string name="barcode">Brūkšninis kodas</string>
|
||||
<string name="card">Kortelė</string>
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> taškai</string>
|
||||
<string name="balanceSentence">Balansas: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Galiojimas baigėsi: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Nustoja galioti: <xliff:g>%s</xliff:g></string>
|
||||
<string name="groupsList">Grupės: <xliff:g> %s </xliff:g></string>
|
||||
<string name="addFromImage">Pasirinkti vaizdą iš galerijos</string>
|
||||
<string name="addManually">Rankiniu būdu įvesti kortelės ID</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Išeiti neišsaugojus\?</string>
|
||||
<string name="leaveWithoutSaveTitle">Išeiti</string>
|
||||
<string name="moveDown">Judėti žemyn</string>
|
||||
<string name="moveUp">Judėti aukštyn</string>
|
||||
<string name="failedOpeningFileManager">Pirmiausia įdiekite failų tvarkyklę.</string>
|
||||
<string name="deleteConfirmationGroup">Ištrinti grupę\?</string>
|
||||
<string name="all">Visos</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> kortelę</item>
|
||||
<item quantity="few"><xliff:g>%d</xliff:g> kortelės</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> kortelių</item>
|
||||
</plurals>
|
||||
<string name="noGroups">Spustelėkite + pliuso mygtuką, kad pirmiausia pridėtumėte grupes kategorizavimui.</string>
|
||||
<string name="groups">Grupės</string>
|
||||
<string name="enter_group_name">Įvesti grupės pavadinimą</string>
|
||||
<string name="exportSuccessful">Kortelės duomenys eksportuoti</string>
|
||||
<string name="importSuccessful">Kortelės duomenys importuoti</string>
|
||||
<string name="intent_import_card_from_url_share_text">Noriu pasidalyti su jumis kortele</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Neleisti užrakinti ekrano</string>
|
||||
<string name="settings_keep_screen_on">Laikyti ekraną įjungtą</string>
|
||||
<string name="settings_lock_barcode_orientation">Užrakinti brūkšninio kodo orientaciją</string>
|
||||
<string name="settings_max_font_size_scale">Didžiausias šrifto dydis</string>
|
||||
<string name="settings_dark_theme">Tamsi</string>
|
||||
<string name="settings_light_theme">Šviesi</string>
|
||||
<string name="settings_system_theme">Sistema</string>
|
||||
<string name="settings_theme">Tema</string>
|
||||
<string name="settings_category_title_ui">Vartotojo sąsaja</string>
|
||||
<string name="settings">Nustatymai</string>
|
||||
<string name="starImage">Mėgstamiausia žvaigždė</string>
|
||||
<string name="thumbnailDescription">Kortelės miniatiūra</string>
|
||||
<string name="enterBarcodeInstructions">Įveskite kortelės ID ir toliau pasirinkite jos brūkšninio kodo tipą arba \"Ši kortelė neturi brūkšninio kodo\".</string>
|
||||
<string name="app_resources">Libre trečiųjų šalių ištekliai: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Libre trečiųjų šalių bibliotekos: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_copyright_old">Paremta Loyalty Card Keychain
|
||||
\nautorinės teisės © 2016–2020 Branden Archer.</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Autorinės teisės © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="importOptionApplicationButton">Naudoti kitą programą</string>
|
||||
<string name="importOptionApplicationExplanation">Norėdami atidaryti failą, naudokite bet kurią programą arba mėgstamą failų tvarkyklę.</string>
|
||||
<string name="importOptionApplicationTitle">Naudoti kitą programą</string>
|
||||
<string name="importOptionFilesystemButton">Iš failų sistemos</string>
|
||||
<string name="importOptionFilesystemExplanation">Pasirinkite konkretų failą iš failų sistemos.</string>
|
||||
<string name="importOptionFilesystemTitle">Importuoti iš failų sistemos</string>
|
||||
<string name="exportOptionExplanation">Duomenys bus įrašyti į jūsų pasirinktą vietą.</string>
|
||||
<string name="exportFailedTitle">Eksportuoti nepavyko</string>
|
||||
<string name="exportSuccessfulTitle">Eksportuota</string>
|
||||
<string name="importFailedTitle">Importuoti nepavyko</string>
|
||||
<string name="importSuccessfulTitle">Importuota</string>
|
||||
<string name="importExportHelp">Atsarginių kopijų darymas leidžia perkelti korteles į kitą įrenginį.</string>
|
||||
<string name="noCardExistsError">Nepavyko rasti kortelės</string>
|
||||
<string name="share">Dalintis</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="one">Pasirinkta: <xliff:g>%d</xliff:g> kortelė</item>
|
||||
<item quantity="few">Pasirinktos: <xliff:g>%d</xliff:g> kortelės</item>
|
||||
<item quantity="other">Pasirinkta: <xliff:g>%d</xliff:g> kortelių</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -1,10 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="action_add">Legg til</string>
|
||||
<string name="noGiftCards">Klikk på \"+\" (pluss)-knappen for å legge til et kort først.
|
||||
\n
|
||||
\nDa har du dem alltid hendig.</string>
|
||||
<string name="storeName">Butikk</string>
|
||||
<string name="noGiftCards">Klikk på «+» (pluss)-knappen for å legge til eller importer kort fra «⋮»-menyen først.</string>
|
||||
<string name="storeName">Navn</string>
|
||||
<string name="note">Merknad</string>
|
||||
<string name="cardId">Kort-ID</string>
|
||||
<string name="barcodeType">Strekkodetype</string>
|
||||
@@ -16,7 +14,7 @@
|
||||
<string name="lockScreen">Ingen rotering</string>
|
||||
<string name="unlockScreen">Skru på rotering</string>
|
||||
<string name="deleteTitle">Fjern kundekort</string>
|
||||
<string name="deleteConfirmation">Bekreft at du ønsker å slette dette kortet.</string>
|
||||
<string name="deleteConfirmation">Slett dette kortet\?</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Kopier ID til utklippstavle</string>
|
||||
<string name="sendLabel">Send…</string>
|
||||
@@ -26,7 +24,7 @@
|
||||
<string name="cardShortcut">Kort-snarvei</string>
|
||||
<string name="noCardsMessage">Legg til et kort først</string>
|
||||
<string name="barcodeImageDescription">Bilde av kortets strekkode</string>
|
||||
<string name="noStoreError">Ingen butikk angitt</string>
|
||||
<string name="noStoreError">Navn ikke angitt</string>
|
||||
<string name="noCardIdError">Ingen kort-ID innskrevet</string>
|
||||
<string name="noCardExistsError">Kunne ikke finne kort</string>
|
||||
<string name="importExport">Import/eksport</string>
|
||||
@@ -45,26 +43,20 @@
|
||||
<string name="importOptionFilesystemTitle">Importer fra filsystem</string>
|
||||
<string name="importOptionFilesystemExplanation">Velg spesifikk fil fra filsystemet.</string>
|
||||
<string name="importOptionFilesystemButton">Fra filsystem</string>
|
||||
<string name="importOptionApplicationTitle">Bruk eksternt program</string>
|
||||
<string name="importOptionApplicationTitle">Bruk et annet program</string>
|
||||
<string name="importOptionApplicationExplanation">Bruk hvilket som helst program, eller din favoritt-filutforsker for å åpne en fil.</string>
|
||||
<string name="importOptionApplicationButton">Bruk eksternt program</string>
|
||||
<string name="importOptionApplicationButton">Bruk et annet program</string>
|
||||
<string name="about">Om</string>
|
||||
<string name="app_license">Gemenhetslig fri programvare, lisensiert GPLv3+.</string>
|
||||
<string name="about_title_fmt">Om <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versjon: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="version">%s</xliff:g></string>
|
||||
<string name="about_title_fmt">Om <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versjon: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Utgivelsesinfo: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> brukfer følgende tredjepartsbibliotek: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> bruker følgende tredjepartsressurser: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Velg strekkode</string>
|
||||
<string name="enterBarcodeInstructions">Skriv inn strekkodeverdien og velg så bildet som representerer strekkoden du ønsker å bruke.</string>
|
||||
<string name="enterBarcodeInstructions">Skriv inn kortets ID, og enten velg dens strekkode nedenfor, eller «Dette kortet har ingen strekkode».</string>
|
||||
<string name="copy_to_clipboard_toast">Kort-ID kopiert til utklippstavle</string>
|
||||
<string name="thumbnailDescription">Miniatyrbilde for kort</string>
|
||||
<string name="settings">Innstillinger</string>
|
||||
<string name="settings_category_title_ui">Brukergrensesnitt</string>
|
||||
<string name="settings_card_title_list_font_size">Korttittelskriftstørrelse (listemodus)</string>
|
||||
<string name="settings_card_note_list_font_size">Skriftstørrelse for kortmerknadsliste (listemodus)</string>
|
||||
<string name="settings_card_title_font_size">Skriftstørrelse for korttittel (forhåndsvisning)</string>
|
||||
<string name="settings_card_id_font_size">Skriftstørrelse for kort-ID</string>
|
||||
<string name="settings_display_barcode_max_brightness">Lysere strekkodevisning</string>
|
||||
<string name="settings_lock_barcode_orientation">Lås strekkodesideretning</string>
|
||||
<string name="exportSuccessful">Kortdata eksportert</string>
|
||||
@@ -74,7 +66,8 @@
|
||||
<string name="settings_light_theme">Lys</string>
|
||||
<string name="settings_system_theme">System</string>
|
||||
<string name="settings_theme">Drakt</string>
|
||||
<string name="app_copyright_old">Basert på Kundekortknippe, opphavsrett 2016–2020 Branden Archer.</string>
|
||||
<string name="app_copyright_old">Basert på Kundekortknippe
|
||||
\nopphavsrett 2016–2020 Branden Archer.</string>
|
||||
<string name="failedParsingImportUriError">Kunne ikke tolke importerings-URI</string>
|
||||
<string name="share">Del</string>
|
||||
<string name="barcodeNoBarcode">Dette kortet har ingen strekkode</string>
|
||||
@@ -83,48 +76,89 @@
|
||||
<string name="starImage">Favorittstjerne</string>
|
||||
<string name="unstar">Fjern fra favoritter</string>
|
||||
<string name="star">Legg til i favoritter</string>
|
||||
<string name="noGroups">Klikk på «+»-tegnet for å legge til grupper først.
|
||||
\n
|
||||
\nGrupper gjør ting enklere å finne.</string>
|
||||
<string name="deleteConfirmationGroup">Bekreft at du ønsker å slette denne gruppen</string>
|
||||
<string name="noGroups">Klikk på «+»- (pluss)-tegnet for å legge til grupper for kategorisering først.</string>
|
||||
<string name="deleteConfirmationGroup">Slett gruppe\?</string>
|
||||
<string name="all">Alle</string>
|
||||
<string name="groups">Grupper</string>
|
||||
<string name="enter_group_name">Skriv inn gruppenavn</string>
|
||||
<string name="noBarcode">Ingen strekkode</string>
|
||||
<string name="failedOpeningFileManager">Klarte ikke å åpne noen filbehandler. Forsikre deg om at du har installert en.</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Er du sikker på at du vil forlate denne skjermen\? Endringer vil ikke bli lagret.</string>
|
||||
<string name="leaveWithoutSaveTitle">Forlat uten å lagre</string>
|
||||
<string name="failedOpeningFileManager">Installer en filbehandler først.</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Forlat uten å lagre\?</string>
|
||||
<string name="leaveWithoutSaveTitle">Avslutt</string>
|
||||
<string name="addManually">Skriv inn kort-ID manuelt</string>
|
||||
<string name="moveDown">Flytt nedover i listen</string>
|
||||
<string name="moveUp">Flytt oppover i listen</string>
|
||||
<string name="moveDown">Flytt nedover</string>
|
||||
<string name="moveUp">Flytt oppover</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> kort</item>
|
||||
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> kort</item>
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> kort</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> kort</item>
|
||||
</plurals>
|
||||
<string name="groupsList">Grupper: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="groupsList">Grupper: <xliff:g>%s</xliff:g></string>
|
||||
<string name="editBarcode">Rediger strekkode</string>
|
||||
<string name="barcode">Strekkode</string>
|
||||
<string name="card">Kort</string>
|
||||
<string name="expiryStateSentence">Utløper: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Utløper: <xliff:g>%s</xliff:g></string>
|
||||
<string name="chooseExpiryDate">Velg utløpsdato</string>
|
||||
<string name="never">Aldri</string>
|
||||
<string name="expiryDate">Utløpsdato</string>
|
||||
<string name="expiryStateSentenceExpired">Utløpt: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Utløpt: <xliff:g>%s</xliff:g></string>
|
||||
<string name="moveBarcodeToCenterOfScreen">Sentrer strekkoden på skjermen</string>
|
||||
<string name="moveBarcodeToTopOfScreen">Flytt strekkoden til toppen av skjermen</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> ser ikke ut til å være en gyldig saldo.</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> ser ikke ut til å være en gyldig saldo.</string>
|
||||
<string name="points">Poeng</string>
|
||||
<string name="currency">Valuta</string>
|
||||
<string name="balance">Saldo</string>
|
||||
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> poeng</string>
|
||||
<string name="balanceSentence">Saldo: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="chooseImportType">Hvilket program vil du importere data fra\?</string>
|
||||
<string name="app_loyalty_card_keychain">Kundekortsknippe</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Skru av låseskjerm under kortvisning</string>
|
||||
<string name="settings_keep_screen_on">Behold skjerm påslått under kortvisning</string>
|
||||
<string name="privacy_policy_popup_text">Mange programbutikker krever at programmer viser personvernspraksisen sin ved første oppstart. Her er vår:
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> poeng</string>
|
||||
<string name="balanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
|
||||
<string name="chooseImportType">Importer data fra\?</string>
|
||||
<string name="app_loyalty_card_keychain">Kundekortknippe</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Forhindre skjermlås</string>
|
||||
<string name="settings_keep_screen_on">Behold skjerm påslått</string>
|
||||
<string name="privacy_policy_popup_text">Personvernspraksis-notis (påkrevd av noen programbutikker):
|
||||
\n
|
||||
\nVi SAMLER IKKE IN NOEN DATA overhodet, og programmet vårt er fri programvare, så alle kan bekrefte at dette stemmer.</string>
|
||||
\nINGEN DATA SAMLES INN, noe alle kan bekreftes siden programmet vårt er fri programvare.</string>
|
||||
<string name="accept">Godta</string>
|
||||
<string name="privacy_policy">Personvernspraksis</string>
|
||||
<string name="importFidme">Importer fra FidMe</string>
|
||||
<string name="importCatima">Importer fra Catima</string>
|
||||
<string name="errorReadingImage">Klarte ikke å lese bildet</string>
|
||||
<string name="noBarcodeFound">Fant ingen strekkode</string>
|
||||
<string name="addFromImage">Velg bilde fra galleri</string>
|
||||
<string name="unsupportedBarcodeType">Denne strekkodetypen kan ikke vises for øyeblikket. Støtte kan bli lagt til i en senere versjon av programmet.</string>
|
||||
<string name="setBarcodeId">Sett strekkodeverdi</string>
|
||||
<string name="sameAsCardId">Samme som kort-ID</string>
|
||||
<string name="barcodeId">Strekkodeverdi</string>
|
||||
<string name="importVoucherVaultMessage">Finn en fil som antagelig heter <i>voucher.vault.json</i> å importere.
|
||||
\nEller opprett den ved å trykke «Eksport» i Voucher Vault først.</string>
|
||||
<string name="importVoucherVault">Importer fra Voucher Vault</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Finn en fil som antagelig heter <i>LoyaltyCardKeychain.csv</i> å importere.
|
||||
\nEller opprett den i Import/eksport-menyen i Kundekortknippe ved å trykke «Eksporter» der først.</string>
|
||||
<string name="importLoyaltyCardKeychain">Importer fra Kundekortknippe</string>
|
||||
<string name="importFidmeMessage">Finn en fil som antagelig heter <i>fidme.export-request-xxxxx.zip</i> å importere, for så å velge strekkodetypene manuelt etterpå-
|
||||
\nEller opprett den i din FidMe-profil ved å velge «Databeskyttelse», for så å trykke «Pakk ut dataen min» først.</string>
|
||||
<string name="importCatimaMessage">Finn en fil som antagelig heter <i>Catima.csv</i> å importere.
|
||||
\nEller opprett den i Import/eksport-menyen i et annet Catima-program ved å trykke «Eksporter» der først.</string>
|
||||
<string name="settings_max_font_size_scale">Maksimal skriftstørrelse</string>
|
||||
<string name="wrongValueForBarcodeType">Verdien er ikke gyldig for valgt strekkodetype</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Jeg ønsker å dele noen kort med deg</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">Kopierte kort-ID-er til utklippstavle</string>
|
||||
<string name="app_resources">Frie tredjepartsressurser: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Frie tredjepartsbibliotek: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="card_ids_copied">Kopierte kort-ID(er)</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Opphavsrett © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="updateBarcodeQuestionText">Du har endret kortets ID. Ønsker du å også oppdatere strekkoden til samme verdi\?</string>
|
||||
<string name="no">Nei</string>
|
||||
<string name="yes">Ja</string>
|
||||
<string name="updateBarcodeQuestionTitle">Oppdater strekkodeverdi\?</string>
|
||||
<string name="takePhoto">Ta et bilde</string>
|
||||
<string name="removeImage">Fjern bilde</string>
|
||||
<string name="setBackImage">Sett bakside</string>
|
||||
<string name="setFrontImage">Sett forside</string>
|
||||
<string name="photos">Bilder</string>
|
||||
<string name="backImageDescription">Kortets bakside</string>
|
||||
<string name="frontImageDescription">Kortets forside</string>
|
||||
<string name="importStocardMessage">Finn din Stocard.zip-fil å importere, og velg strekkodetypene manuelt etterpå.
|
||||
\nEller få den ved å sende e-post til support@stocardapp.com der du etterspør eksport av dataen din.</string>
|
||||
<string name="passwordRequired">Skriv inn passordet</string>
|
||||
<string name="importStocard">Importer fra Stocard</string>
|
||||
<string name="failedGeneratingShareURL">Klarte ikke å lage delingsnettadresse. Rapporter denne feilen.</string>
|
||||
</resources>
|
||||
@@ -11,6 +11,8 @@
|
||||
<color name="colorPrimaryText">#000000</color>
|
||||
<color name="colorSecondaryText">#ffffff</color>
|
||||
|
||||
<color name="listItemHighlight">#88000000</color>
|
||||
|
||||
<color name="inputContrastBackground">#070707</color>
|
||||
<color name="inputBackground">#000000</color>
|
||||
<color name="inputBorder">#222222</color>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="action_search">Zoeken</string>
|
||||
<string name="action_add">Toevoegen</string>
|
||||
<string name="noGiftCards">Druk op de knop \'+\' (plus) om een kaart toe te voegen.
|
||||
\n
|
||||
\nMet Catima heb je je klantenkaarten altijd binnen handbereik, gewoon op je apparaat.</string>
|
||||
<string name="noMatchingGiftCards">Geen zoekresultaten. Probeer een andere zoekopdracht.</string>
|
||||
<string name="storeName">Winkel</string>
|
||||
<string name="noGiftCards">Druk op de plusknop (‘+’) om een kaart toe te voegen of importeer kaarten via het ⋮-menu.</string>
|
||||
<string name="noMatchingGiftCards">Geen zoekresultaten - probeer een andere zoekopdracht.</string>
|
||||
<string name="storeName">Naam</string>
|
||||
<string name="note">Aantekening</string>
|
||||
<string name="cardId">Kaartnummer</string>
|
||||
<string name="barcodeType">Soort barcode</string>
|
||||
@@ -19,7 +17,7 @@
|
||||
<string name="lockScreen">Draaien niet toestaan</string>
|
||||
<string name="unlockScreen">Draaien toestaan</string>
|
||||
<string name="deleteTitle">Kaart verwijderen</string>
|
||||
<string name="deleteConfirmation">Bevestig dat je deze kaart wilt verwijderen.</string>
|
||||
<string name="deleteConfirmation">Kaart verwijderen\?</string>
|
||||
<string name="ok">Oké</string>
|
||||
<string name="copy_to_clipboard">Kaartnummer kopiëren naar klembord</string>
|
||||
<string name="share">Delen</string>
|
||||
@@ -30,7 +28,7 @@
|
||||
<string name="cardShortcut">Kaartsnelkoppeling</string>
|
||||
<string name="noCardsMessage">Voeg eerst een kaart toe</string>
|
||||
<string name="barcodeImageDescription">Afbeelding van barcode</string>
|
||||
<string name="noStoreError">Geen winkelnaam ingevoerd</string>
|
||||
<string name="noStoreError">Geen naam ingevoerd</string>
|
||||
<string name="noCardIdError">Geen kaartnummer ingevoerd</string>
|
||||
<string name="noCardExistsError">De kaart is niet aangetroffen</string>
|
||||
<string name="failedParsingImportUriError">Kan de import-uri niet verwerken</string>
|
||||
@@ -45,24 +43,22 @@
|
||||
<string name="exportFailed">Het exporteren is mislukt</string>
|
||||
<string name="importing">Bezig met importeren…</string>
|
||||
<string name="exporting">Bezig met exporteren…</string>
|
||||
<string name="noExternalStoragePermissionError">Verleen het recht \'externe opslag\' om kaarten te kunnen im- of exporteren</string>
|
||||
<string name="noExternalStoragePermissionError">Verleen het recht ‘externe opslag’ om kaarten te kunnen im- of exporteren</string>
|
||||
<string name="exportOptionExplanation">De gegevens worden weggeschreven op een locatie naar keuze.</string>
|
||||
<string name="importOptionFilesystemTitle">Importeren uit bestandssysteem</string>
|
||||
<string name="importOptionFilesystemExplanation">Kies een specifiek bestand vanop het bestandssysteem.</string>
|
||||
<string name="importOptionFilesystemButton">Van bestandssysteem</string>
|
||||
<string name="importOptionApplicationTitle">Externe app gebruiken</string>
|
||||
<string name="importOptionApplicationTitle">Andere app gebruiken</string>
|
||||
<string name="importOptionApplicationExplanation">Open een bestand middels een app of je favoriete bestandsbeheerder.</string>
|
||||
<string name="importOptionApplicationButton">Externe app gebruiken</string>
|
||||
<string name="importOptionApplicationButton">Andere app gebruiken</string>
|
||||
<string name="about">Over</string>
|
||||
<string name="app_license">Vrije software, uitgebracht onder de GPLv3-licentie.</string>
|
||||
<string name="about_title_fmt">Over <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Versie: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Versie-informatie: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> gebruikt de volgende bibliotheken van externe partijen: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> gebruikt de volgende bronnen van externe partijen: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Barcode toevoegen</string>
|
||||
<string name="enterBarcodeInstructions">Voer de barcode in en kies daarna de afbeelding van de barcode die je wilt gebruiken of druk op “Deze kaart heeft geen barcode” om geen barcode te gebruiken.</string>
|
||||
<string name="copy_to_clipboard_toast">Kaartnummer is gekopieerd naar het klembord</string>
|
||||
<string name="enterBarcodeInstructions">Voer de kaart-id in en kies daarna het soort barcode druk op “Deze kaart heeft geen barcode”.</string>
|
||||
<string name="copy_to_clipboard_toast">De kaart-id is gekopieerd naar het klembord</string>
|
||||
<string name="thumbnailDescription">Miniatuurvoorbeeld van kaart</string>
|
||||
<string name="settings">Instellingen</string>
|
||||
<string name="settings_category_title_ui">Vormgeving</string>
|
||||
@@ -70,82 +66,105 @@
|
||||
<string name="settings_system_theme">Systeem</string>
|
||||
<string name="settings_light_theme">Licht</string>
|
||||
<string name="settings_dark_theme">Donker</string>
|
||||
<string name="settings_card_title_list_font_size">Lettergrootte van kaartnamen (lijstmodus)</string>
|
||||
<string name="settings_card_note_list_font_size">Lettergrootte van aantekeningen (lijstmodus)</string>
|
||||
<string name="settings_card_title_font_size">Lettergrootte van kaartnamen (voorvertoning)</string>
|
||||
<string name="settings_card_id_font_size">Lettergrootte van kaartnummer</string>
|
||||
<string name="settings_display_barcode_max_brightness">Scherm helderder maken bij tonen van barcode</string>
|
||||
<string name="settings_lock_barcode_orientation">Barcode-oriëntatie vergrendelen</string>
|
||||
<string name="intent_import_card_from_url_share_text">Ik wil een klantenkaart met je delen</string>
|
||||
<string name="all">Alles</string>
|
||||
<string name="importSuccessful">De kaartgegevens zijn geïmporteerd</string>
|
||||
<string name="deleteConfirmationGroup">Bevestig dat je deze groep wilt verwijderen</string>
|
||||
<string name="noGroups">Druk op de knop \'+\' (plus) om een groep toe te voegen.
|
||||
\n
|
||||
\nDoor kaarten te groeperen vind je ze makkelijker terug.</string>
|
||||
<string name="deleteConfirmationGroup">Groep verwijderen\?</string>
|
||||
<string name="noGroups">Druk op de plusknop (‘+’) om een groep toe te voegen.</string>
|
||||
<string name="exportSuccessful">De kaartgegevens zijn geëxporteerd</string>
|
||||
<string name="groups">Groepen</string>
|
||||
<string name="enter_group_name">Voer een groepsnaam in</string>
|
||||
<string name="starImage">Favoriete ster</string>
|
||||
<string name="app_copyright_old">Gebaseerd op Loyalty Card Keychain, copyright 2016–2020 Branden Archer.</string>
|
||||
<string name="app_copyright_old">Gebaseerd op Loyalty Card Keychain,
|
||||
\ncopyright ©2016–2020 Branden Archer.</string>
|
||||
<string name="unstar">Verwijderen uit favorieten</string>
|
||||
<string name="star">Toevoegen aan favorieten</string>
|
||||
<string name="addManually">Kaartnummer handmatig invoeren</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Weet je zeker dat je dit wilt\? Hierdoor worden je aanpassingen niet opgeslagen.</string>
|
||||
<string name="leaveWithoutSaveTitle">Afbreken zonder opslaan</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Weet je zeker dat je niet wilt opslaan\?</string>
|
||||
<string name="leaveWithoutSaveTitle">Afsluiten</string>
|
||||
<string name="moveDown">Omlaag verplaatsen</string>
|
||||
<string name="moveUp">Omhoog verplaatsen</string>
|
||||
<string name="failedOpeningFileManager">Kan de bestandsbeheerder niet openen - zorg dat je er een hebt geïnstalleerd.</string>
|
||||
<string name="failedOpeningFileManager">Installeer een bestandsbeheerder.</string>
|
||||
<string name="noBarcode">Geen barcode</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> kaart</item>
|
||||
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> kaarten</item>
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> kaart</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> kaarten</item>
|
||||
</plurals>
|
||||
<string name="groupsList">Groepen: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="groupsList">Groepen: <xliff:g>%s</xliff:g></string>
|
||||
<string name="editBarcode">Barcode aanpassen</string>
|
||||
<string name="barcode">Barcode</string>
|
||||
<string name="card">Kaart</string>
|
||||
<string name="chooseExpiryDate">Kies een vervaldatum</string>
|
||||
<string name="never">Nooit</string>
|
||||
<string name="expiryDate">Vervaldatum</string>
|
||||
<string name="expiryStateSentence">Vervalt op <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Verlopen: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Vervalt op <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Verlopen: <xliff:g>%s</xliff:g></string>
|
||||
<string name="moveBarcodeToCenterOfScreen">Barcode verplaatsen naar midden van scherm</string>
|
||||
<string name="moveBarcodeToTopOfScreen">Barcode verplaatsen naar bovenkant van scherm</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> lijkt geen geldig saldo te zijn.</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> lijkt geen geldig saldo te zijn.</string>
|
||||
<string name="points">Aantal punten</string>
|
||||
<string name="currency">Valuta</string>
|
||||
<string name="balance">Saldo</string>
|
||||
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> punten</string>
|
||||
<string name="balanceSentence">Saldo: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="chooseImportType">Uit welke app wil je gegevens importeren\?</string>
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> punten</string>
|
||||
<string name="balanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
|
||||
<string name="chooseImportType">Gegevens importeren uit…\?</string>
|
||||
<string name="app_loyalty_card_keychain">Klantenkaartkluis</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Vergrendelscherm uitschakelen tijdens tonen van kaart</string>
|
||||
<string name="settings_keep_screen_on">Scherm niet uitschakelen tijdens tonen van kaart</string>
|
||||
<string name="privacy_policy_popup_text">Veel appwinkels vereisen dat apps na de eerste keer opstarten hun privacybeleid tonen. Dat van ons is eenvoudig:
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Vergrendelscherm uitschakelen</string>
|
||||
<string name="settings_keep_screen_on">Scherm niet uitschakelen</string>
|
||||
<string name="privacy_policy_popup_text">Privacybeleid (vereist door sommige appwinkels):
|
||||
\n
|
||||
\nWe verzamelen HELEMAAL NIKS. Bovendien is onze app open source, zodat een ieder met eigen ogen kan zien wat de app wel of niet doet.</string>
|
||||
\nER WORDEN GEEN GEGEVENS VERZAMELD. Bovendien is onze app open source, zodat een ieder met eigen ogen kan zien wat de app wel of niet doet.</string>
|
||||
<string name="privacy_policy">Privacybeleid</string>
|
||||
<string name="accept">Accepteren</string>
|
||||
<string name="importVoucherVaultMessage">Kies het gewenste Voucher Vault-exportbestand - normaliter heet dit bestand \'vouchervault.json\'.
|
||||
\n
|
||||
\nGa naar het Exportmenu om een Voucher Vault-exportbestand samen te stellen.</string>
|
||||
<string name="importVoucherVaultMessage">Kies het te importeren <i>vouchervault.json</i>-exportbestand.
|
||||
\nOf ga naar het exportmenu van Voucher Vault om een exportbestand samen te stellen.</string>
|
||||
<string name="importVoucherVault">Importeren uit Voucher Vault</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Kies het gewenste Klantenkaartkluis-exportbestand - normaliter heet dit bestand \'LoyaltyCardKeychain.csv\'.
|
||||
\n
|
||||
\nGa naar het Import-/Exportmenu om een Klantenkaartkluis-exportbestand samen te stellen.</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Kies het te importeren genaamd <i>LoyaltyCardKeychain.csv</i>-exportbestand.
|
||||
\nOf ga naar het import-/exportmenu van Klantenkaartkluis om een exportbestand samen te stellen.</string>
|
||||
<string name="importLoyaltyCardKeychain">Importeren uit Klantenkaartkluis</string>
|
||||
<string name="importFidmeMessage">Kies het gewenste Fidme-exportbestand - normaliter heet dit bestand \'fidme-export-request-xxxxxx.zip\'.
|
||||
\n
|
||||
\nOpen de Fidme-app, ga naar je profiel en druk op \'Gegevensbescherming\' om een exportbestand samen te stellen.
|
||||
\n
|
||||
\nLet op: Fidme slaat de soorten barcodes niet op in het exportbestand, dus dat moet je na achteraf nog instellen.</string>
|
||||
<string name="importCatimaMessage">Kies het gewenste Catima-exportbestand - normaliter heet dit bestand \'Catima.csv\'.
|
||||
\n
|
||||
\nGa naar het Import-/Exportmenu om een Catima-exportbestand samen te stellen.</string>
|
||||
<string name="importFidme">Importeren uit Fidme</string>
|
||||
<string name="importFidmeMessage">Kies het te importeren <i>fidme-export-request-xxxxxx.zip</i>-exportbestand en kies nadien de juiste barcodes.
|
||||
\nOf ga naar je FidMe-profiel en druk op ‘Gegevensbescherming’ om een exportbestand samen te stellen.</string>
|
||||
<string name="importCatimaMessage">Kies het te importeren <i>Catima.zip</i>-exportbestand.
|
||||
\nOf ga naar het import-/exportmenu van Catima op een ander apparaat om een exportbestand samen te stellen.</string>
|
||||
<string name="importFidme">Importeren uit FidMe</string>
|
||||
<string name="importCatima">Importeren uit Catima</string>
|
||||
<string name="errorReadingImage">De afbeelding kan niet worden uitgelezen</string>
|
||||
<string name="noBarcodeFound">Geen barcode aangetroffen</string>
|
||||
<string name="addFromImage">Afbeelding kiezen uit galerij</string>
|
||||
<string name="setBarcodeId">Barcodewaarde instellen</string>
|
||||
<string name="sameAsCardId">Gelijk aan kaart-id</string>
|
||||
<string name="barcodeId">Barcodewaarde</string>
|
||||
<string name="settings_max_font_size_scale">Max. tekstgrootte</string>
|
||||
<string name="unsupportedBarcodeType">Dit type barcode kan nog niet worden getoond - we hopen hiervoor in een nieuwere versie ondersteuning toe te voegen.</string>
|
||||
<string name="wrongValueForBarcodeType">Deze waarde komt niet overeen met het gekozen barcodetype</string>
|
||||
<string name="app_resources">Vrije externe bronnen: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Vrije externe bibliotheken: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Auteursrecht © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Ik wil kaarten met je delen</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">De kaart-id\'s zijn gekopieerd naar het klembord</string>
|
||||
<string name="card_ids_copied">De kaart-id‘s zijn gekopieerd</string>
|
||||
<string name="no">Nee</string>
|
||||
<string name="yes">Ja</string>
|
||||
<string name="updateBarcodeQuestionText">Je hebt de kaart-id aangepast. Wil je dezelfde waarde toekennen aan de barcode\?</string>
|
||||
<string name="updateBarcodeQuestionTitle">Barcodewaarde bijwerken\?</string>
|
||||
<string name="takePhoto">Foto maken</string>
|
||||
<string name="removeImage">Afbeelding verwijderen</string>
|
||||
<string name="setFrontImage">Voorzijde kiezen</string>
|
||||
<string name="setBackImage">Achterzijde kiezen</string>
|
||||
<string name="photos">Afbeeldingen</string>
|
||||
<string name="backImageDescription">Achterzijde van de kaart</string>
|
||||
<string name="frontImageDescription">Voorzijde van de kaart</string>
|
||||
<string name="passwordRequired">Voer het wachtwoord in</string>
|
||||
<string name="importStocardMessage">Kies het te importeren Stocard-exportbestand genaamd <i>***-sync.zip</i> en kies nadien de juiste barcodes.
|
||||
\nOf stuur een e-mail naar support@stocardapp.com waarin je vraagt om een exportbestand.</string>
|
||||
<string name="importStocard">Importeren uit Stocard</string>
|
||||
<string name="failedGeneratingShareURL">De te delen link kan niet worden gegenereerd. Meld deze bug!</string>
|
||||
<string name="turn_flashlight_off">Zaklamp uitzetten</string>
|
||||
<string name="turn_flashlight_on">Zaklamp aanzetten</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> kaart geselecteerd</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> kaarten geselecteerd</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
41
app/src/main/res/values-oc/strings.xml
Normal file
41
app/src/main/res/values-oc/strings.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="exporting">Exportacion…</string>
|
||||
<string name="importing">Importacion…</string>
|
||||
<string name="exportFailed">Exportacion pas possibla</string>
|
||||
<string name="exportSuccessfulTitle">Exportat</string>
|
||||
<string name="importFailed">Importacion de vòstras cartas impossibla</string>
|
||||
<string name="importFailedTitle">Fracàs de l’importacion</string>
|
||||
<string name="importSuccessfulTitle">Importat</string>
|
||||
<string name="importExportHelp">Exportar vòstras cartas vos permet de las recuperar sus un autre aparelh.</string>
|
||||
<string name="exportName">Exportar</string>
|
||||
<string name="importExport">Importar/Exportar</string>
|
||||
<string name="failedParsingImportUriError">Analisi impossibla l’URI d’importacion</string>
|
||||
<string name="noCardExistsError">Cap de carta pas trobada</string>
|
||||
<string name="noCardIdError">Cap de numèro de carta pas picat</string>
|
||||
<string name="noStoreError">Cap de nom pas picat</string>
|
||||
<string name="barcodeImageDescription">Imatge del còdi de barras</string>
|
||||
<string name="card_ids_copied">Num. de la carta copiada</string>
|
||||
<string name="noCardsMessage">Apondètz d’en primièr una carta</string>
|
||||
<string name="cardShortcut">Acorchi de carta</string>
|
||||
<string name="scanCardBarcode">Numerizar lo còdi de barras</string>
|
||||
<string name="addCardTitle">Apondre una carta</string>
|
||||
<string name="editCardTitle">Modificar la carta</string>
|
||||
<string name="sendLabel">Enviar…</string>
|
||||
<string name="share">Partejar</string>
|
||||
<string name="unlockScreen">Activar la rotacion</string>
|
||||
<string name="lockScreen">Desactivar la rotacion</string>
|
||||
<string name="confirm">Confirmar</string>
|
||||
<string name="delete">Suprimir</string>
|
||||
<string name="edit">Modificar</string>
|
||||
<string name="save">Enregistrar</string>
|
||||
<string name="cancel">Anullar</string>
|
||||
<string name="unstar">Tirar dels favorits</string>
|
||||
<string name="star">Apondre als favorits</string>
|
||||
<string name="barcodeType">Tipe còdi de barras</string>
|
||||
<string name="cardId">Numèro</string>
|
||||
<string name="note">Nòta</string>
|
||||
<string name="storeName">Nom</string>
|
||||
<string name="action_add">Apondre</string>
|
||||
<string name="action_search">Recercar</string>
|
||||
</resources>
|
||||
@@ -54,10 +54,8 @@
|
||||
<string name="about_title_fmt">O <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Wersja: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Info o wydaniu: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> wykorzystuje następujące biblioteki osób trzecich: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> wykorzystuje następujące zasoby osób trzecich: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Wybierz kod kreskowy</string>
|
||||
<string name="enterBarcodeInstructions">Wprowadź identyfikator karty, a następnie wybierz obraz reprezentujący kod kreskowy, którego chcesz użyć, lub wybierz “Ta karta nie ma kodu kreskowego”, aby nie używać kodu kreskowego.</string>
|
||||
<string name="enterBarcodeInstructions">Wprowadź identyfikator karty, a następnie wybierz obraz reprezentujący kod kreskowy, którego chcesz użyć, lub wybierz „Ta karta nie ma kodu kreskowego”, aby nie używać kodu kreskowego.</string>
|
||||
<string name="copy_to_clipboard_toast">Skopiowano identyfikator karty do schowka</string>
|
||||
<string name="thumbnailDescription">Miniaturka karty</string>
|
||||
<string name="settings">Ustawienia</string>
|
||||
@@ -66,10 +64,6 @@
|
||||
<string name="settings_system_theme">Systemowy</string>
|
||||
<string name="settings_light_theme">Jasny</string>
|
||||
<string name="settings_dark_theme">Ciemny</string>
|
||||
<string name="settings_card_title_list_font_size">Rozmiar czcionki listy tytułów kart</string>
|
||||
<string name="settings_card_note_list_font_size">Rozmiar czcionki listy kart</string>
|
||||
<string name="settings_card_title_font_size">Rozmiar czcionki tytułu karty</string>
|
||||
<string name="settings_card_id_font_size">Rozmiar czcionki identyfikatora karty</string>
|
||||
<string name="settings_display_barcode_max_brightness">Rozjaśnij widok kodu kreskowego</string>
|
||||
<string name="settings_lock_barcode_orientation">Zablokuj autoobracanie kodów kreskowych</string>
|
||||
<string name="intent_import_card_from_url_share_text">Chcę udostępnić Ci kartę lojalnościową</string>
|
||||
@@ -89,4 +83,4 @@
|
||||
<string name="star">Dodaj do ulubionych</string>
|
||||
<string name="noBarcode">Brak kodu kreskowego</string>
|
||||
<string name="barcodeType">Typ kodu kreskowego</string>
|
||||
</resources>
|
||||
</resources>
|
||||
@@ -1,12 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="action_search">Поиск</string>
|
||||
<string name="action_add">Добавить</string>
|
||||
<string name="noGiftCards">Нажмите кнопку + (плюс), чтобы добавить карту.
|
||||
\n
|
||||
\nCatima хранит ваши карты на устройстве, поэтому они всегда под рукой.</string>
|
||||
<string name="noGiftCards">Нажмите кнопку \"+\" для добавления карты или используйте меню \"⋮\" для импортирования.</string>
|
||||
<string name="noMatchingGiftCards">Ничего не найдено. Попробуйте изменить поисковый запрос.</string>
|
||||
<string name="storeName">Магазин</string>
|
||||
<string name="storeName">Название</string>
|
||||
<string name="note">Примечание</string>
|
||||
<string name="cardId">Номер карты</string>
|
||||
<string name="barcodeType">Тип штрих-кода</string>
|
||||
@@ -19,7 +17,7 @@
|
||||
<string name="lockScreen">Блокировать поворот экрана</string>
|
||||
<string name="unlockScreen">Автоповорот экрана</string>
|
||||
<string name="deleteTitle">Удаление карты</string>
|
||||
<string name="deleteConfirmation">Подтвердите удаление карты.</string>
|
||||
<string name="deleteConfirmation">Удалить карту\?</string>
|
||||
<string name="ok">ОК</string>
|
||||
<string name="copy_to_clipboard">Копировать номер карты</string>
|
||||
<string name="share">Переслать</string>
|
||||
@@ -30,7 +28,7 @@
|
||||
<string name="cardShortcut">Ярлык карты</string>
|
||||
<string name="noCardsMessage">Сначала добавьте карту</string>
|
||||
<string name="barcodeImageDescription">Изображение штрих-кода карты</string>
|
||||
<string name="noStoreError">Название магазина не указано</string>
|
||||
<string name="noStoreError">Название не указано</string>
|
||||
<string name="noCardIdError">Номер карты не указан</string>
|
||||
<string name="noCardExistsError">Карта не найдена</string>
|
||||
<string name="failedParsingImportUriError">Невозможно разобрать импортируемый URI</string>
|
||||
@@ -55,13 +53,11 @@
|
||||
<string name="importOptionApplicationButton">Использовать другое приложение</string>
|
||||
<string name="about">О приложении</string>
|
||||
<string name="app_license">Авторское лево свободного программного обеспечения, лицензия GPLv3+.</string>
|
||||
<string name="about_title_fmt">О приложении <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g></string>
|
||||
<string name="about_title_fmt">О приложении <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Версия: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Информация о версиях: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> использует следующие сторонние библиотеки: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> использует следующие сторонние ресурсы: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Информация о версиях: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="selectBarcodeTitle">Выбор штрих-кода</string>
|
||||
<string name="enterBarcodeInstructions">Введите номер карты и выберите тип штрих-кода.</string>
|
||||
<string name="enterBarcodeInstructions">Введите номер карты и выберите тип штрих-кода. Или выберите \"Эта карта без штрих-кода\".</string>
|
||||
<string name="copy_to_clipboard_toast">Номер карты скопирован в буфер обмена</string>
|
||||
<string name="thumbnailDescription">Логотип карты</string>
|
||||
<string name="settings">Настройки</string>
|
||||
@@ -70,43 +66,38 @@
|
||||
<string name="settings_system_theme">Системная</string>
|
||||
<string name="settings_light_theme">Светлая</string>
|
||||
<string name="settings_dark_theme">Тёмная</string>
|
||||
<string name="settings_card_title_list_font_size">Размер шрифта названия карты (список)</string>
|
||||
<string name="settings_card_note_list_font_size">Размер шрифта примечания (список)</string>
|
||||
<string name="settings_card_title_font_size">Размер шрифта названия карты (просмотр)</string>
|
||||
<string name="settings_card_id_font_size">Размер шрифта номера карты</string>
|
||||
<string name="settings_display_barcode_max_brightness">Максимальная яркость при показе карты</string>
|
||||
<string name="settings_lock_barcode_orientation">Портретная ориентация экрана при показе карты</string>
|
||||
<string name="intent_import_card_from_url_share_text">Я хочу поделиться картой с вами</string>
|
||||
<string name="intent_import_card_from_url_share_text">Я хочу поделиться с вами картой</string>
|
||||
<string name="exportSuccessful">Данные карт успешно экспортированы</string>
|
||||
<string name="all">Все</string>
|
||||
<string name="noGroups">Нажмите кнопку + (плюс), чтобы добавить группы.
|
||||
\n
|
||||
\nГруппы упрощают поиск.</string>
|
||||
<string name="noGroups">Нажмите кнопку \"+\", чтобы добавить группы для упорядочивания записей.</string>
|
||||
<string name="groups">Группы</string>
|
||||
<string name="enter_group_name">Введите название группы</string>
|
||||
<string name="importSuccessful">Данные карт успешно импортированы</string>
|
||||
<string name="starImage">Звезда избранного</string>
|
||||
<string name="app_copyright_old">На основе Loyalty Card Keychain, авторские права 2016–2020 Branden Archer.</string>
|
||||
<string name="app_copyright_old">На основе Loyalty Card Keychain
|
||||
\nавторские права © 2016–2020 Branden Archer.</string>
|
||||
<string name="unstar">Удалить из избранного</string>
|
||||
<string name="star">Добавить в избранное</string>
|
||||
<string name="noBarcode">Нет штрих-кода</string>
|
||||
<string name="deleteConfirmationGroup">Подтвердите, что хотите удалить эту группу</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Вы уверены, что хотите покинуть этот экран\? Изменения не будут сохранены.</string>
|
||||
<string name="leaveWithoutSaveTitle">Выйти без сохранения</string>
|
||||
<string name="failedOpeningFileManager">Невозможно открыть файловый менеджер. Убедитесь, что он установлен.</string>
|
||||
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> баллов</string>
|
||||
<string name="balanceSentence">Баланс: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Истёк срок действия: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Истекает срок действия: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="deleteConfirmationGroup">Удалить группу\?</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Выйти без сохранения\?</string>
|
||||
<string name="leaveWithoutSaveTitle">Выход</string>
|
||||
<string name="failedOpeningFileManager">Требуется файловый менеджер.</string>
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> баллов</string>
|
||||
<string name="balanceSentence">Баланс: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Срок действия истёк: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Срок действия истекает: <xliff:g>%s</xliff:g></string>
|
||||
<string name="points">Баллы</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> не похож на правильный баланс.</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> не похож на правильный баланс.</string>
|
||||
<string name="addManually">Ручной ввод номера карты</string>
|
||||
<string name="privacy_policy_popup_text">Многие магазины приложений требуют, чтобы приложение показывало свою политику конфиденциальности при первом запуске. Вот наша:
|
||||
<string name="privacy_policy_popup_text">Уведомление о политике конфиденциальности (требуется некоторыми магазинами приложений):
|
||||
\n
|
||||
\nМы НЕ собираем НИКАКИХ ДАННЫХ и наше приложение имеет открытый исходный код, так что любой может убедиться в том, что это правда.</string>
|
||||
\nНИКАКИЕ ДАННЫЕ НЕ СОБИРАЮТСЯ ВООБЩЕ, что может подтвердить любой, так как наше приложение является свободным программным обеспечением.</string>
|
||||
<string name="privacy_policy">Политика конфиденциальности</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="chooseImportType">Из какого приложения импортировать данные\?</string>
|
||||
<string name="chooseImportType">Откуда импортировать данные\?</string>
|
||||
<string name="balance">Баланс</string>
|
||||
<string name="moveBarcodeToTopOfScreen">Переместить штрих-код в верхнюю часть экрана</string>
|
||||
<string name="moveBarcodeToCenterOfScreen">Центрировать штрих-код на экране</string>
|
||||
@@ -117,37 +108,67 @@
|
||||
<string name="editBarcode">Изменить штрих-код</string>
|
||||
<string name="barcode">Штрих-код</string>
|
||||
<string name="card">Карта</string>
|
||||
<string name="groupsList">Группы: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
|
||||
<string name="moveDown">Переместить ниже в вписке</string>
|
||||
<string name="moveUp">Переместить выше в вписке</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Не блокировать экран при показе карты</string>
|
||||
<string name="settings_keep_screen_on">Не отключать экран при показе карты</string>
|
||||
<string name="groupsList">Группы: <xliff:g>%s</xliff:g></string>
|
||||
<string name="moveDown">Переместить ниже</string>
|
||||
<string name="moveUp">Переместить выше</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Не давать блокировать экран</string>
|
||||
<string name="settings_keep_screen_on">Не отключать экран</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> карта</item>
|
||||
<item quantity="few"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> карты</item>
|
||||
<item quantity="many"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> карт</item>
|
||||
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> карт</item>
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> карта</item>
|
||||
<item quantity="few"><xliff:g>%d</xliff:g> карты</item>
|
||||
<item quantity="many"><xliff:g>%d</xliff:g> карт</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> карт</item>
|
||||
</plurals>
|
||||
<string name="accept">Принять</string>
|
||||
<string name="importVoucherVaultMessage">Выберите файл экспорта Voucher Vault. Обычно он называется \"vouchervault.json\".
|
||||
\n
|
||||
\nФайл экспорта Voucher Vault можно создать, нажав кнопку \"Экспорт\".</string>
|
||||
<string name="importVoucherVaultMessage">Выберите файл для импортирования, именуемый <i>vouchervault.json</i>.
|
||||
\nФайл экспорта можно создать в приложении Voucher Vault, нажав кнопку \"Экспорт\".</string>
|
||||
<string name="importVoucherVault">Импорт из Voucher Vault</string>
|
||||
<string name="importFidmeMessage">Выберите файл экспорта Fidme. Обычно он называется как-то вроде \"fidme-export-request-xxxxxx.zip\".
|
||||
\n
|
||||
\nФайл экспорта Fidme можно создать в приложении Fidme, перейдя в свой профиль, выбрав функцию \"Защита данных\", и затем нажав кнопку \"Извлечь мои данные\".
|
||||
\n
|
||||
\nОбратите внимание, что Fidme не сохраняет тип штрих-кода в экспортированных данных, поэтому вам придётся редактировать импортированные данные карт вручную.</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Выберите файл экспорта Loyalty Card Keychain. Обычно он называется \"LoyaltyCardKeychain.csv\".
|
||||
\n
|
||||
\nФайл экспорта Loyalty Card Keychain можно создать, перейдя в меню \"Импорт/Экспорт\" и нажав кнопку \"Экспорт\".</string>
|
||||
<string name="importFidmeMessage">Выберите файл для импортирования, именуемый <i>fidme-export-request-xxxxxx.zip</i>, а затем вручную укажите типы штрих-кодов.
|
||||
\nФайл экспорта можно создать в приложении FidMe, перейдя в свой профиль, выбрав функцию \"Защита данных\", и затем нажав кнопку \"Извлечь мои данные\".</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Выберите файл экспорта, именуемый <i>LoyaltyCardKeychain.csv</i>.
|
||||
\nФайл экспорта можно создать в приложении Loyalty Card Keychain, перейдя в меню \"Импорт/Экспорт\" и нажав кнопку \"Экспорт\".</string>
|
||||
<string name="importLoyaltyCardKeychain">Импорт из Loyalty Card Keychain</string>
|
||||
<string name="importCatimaMessage">Выберите файл экспорта Catima. Обычно он называется \"Catima.csv\".
|
||||
\n
|
||||
\nФайл экспорта Catima можно создать, перейдя в меню \"Импорт/Экспорт\" и нажав кнопку \"Экспорт\".</string>
|
||||
<string name="importFidme">Импорт из Fidme</string>
|
||||
<string name="importCatimaMessage">Выберите файл для импортирования, именуемый <i>Catima.zip</i>.
|
||||
\nФайл экспорта можно создать в другой копии Catima, перейдя в меню \"Импорт/Экспорт\" и нажав кнопку \"Экспорт\".</string>
|
||||
<string name="importFidme">Импорт из FidMe</string>
|
||||
<string name="importCatima">Импорт из Catima</string>
|
||||
<string name="errorReadingImage">Ошибка при чтении изображения</string>
|
||||
<string name="errorReadingImage">Невозможно считать изображение</string>
|
||||
<string name="noBarcodeFound">Штрих-код не найден</string>
|
||||
<string name="addFromImage">Выбрать изображение из галереи</string>
|
||||
<string name="setBarcodeId">Указать значение</string>
|
||||
<string name="sameAsCardId">Как номер карты</string>
|
||||
<string name="barcodeId">Значение штрих-кода</string>
|
||||
<string name="settings_max_font_size_scale">Максимальный размер шрифта</string>
|
||||
<string name="unsupportedBarcodeType">В настоящее время данный тип штрих-кодов не отображается. Его поддержка может быть добавлена в следующих версиях приложения.</string>
|
||||
<string name="wrongValueForBarcodeType">Недопустимое значение для выбранного типа штрих-кода</string>
|
||||
<string name="app_resources">Свободные сторонние ресурсы: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Свободные сторонние библиотеки: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Авторские права © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Поделиться картами</string>
|
||||
<string name="card_ids_copied">Скопированные номера карт</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">Номера карт скопированы в буфер обмена</string>
|
||||
<string name="updateBarcodeQuestionText">Вы изменили номер карты. Обновить также значение штрих-кода, чтобы использовалось одинаковое значение\?</string>
|
||||
<string name="no">Нет</string>
|
||||
<string name="yes">Да</string>
|
||||
<string name="updateBarcodeQuestionTitle">Обновить значение штрих-кода\?</string>
|
||||
<string name="setBackImage">Изображение задней стороны</string>
|
||||
<string name="setFrontImage">Изображение лицевой стороны</string>
|
||||
<string name="takePhoto">Сфотографировать</string>
|
||||
<string name="removeImage">Удалить изображение</string>
|
||||
<string name="backImageDescription">Задняя сторона карты</string>
|
||||
<string name="frontImageDescription">Лицевая сторона карты</string>
|
||||
<string name="photos">Фотографии</string>
|
||||
<string name="importStocardMessage">Выберите файл <i>***-sync.zip</i> для импортирования, а затем вручную укажите типы штрих-кодов.
|
||||
\nЭтот файл можно получить по электронной почте от support@stocardapp.com, предварительно запросив экспорт ваших данных.</string>
|
||||
<string name="passwordRequired">Введите пароль</string>
|
||||
<string name="importStocard">Импорт из Stocard</string>
|
||||
<string name="failedGeneratingShareURL">Невозможно создать URL для обмена. Пожалуйста, сообщите об ошибке!</string>
|
||||
<string name="turn_flashlight_off">Отключить вспышку</string>
|
||||
<string name="turn_flashlight_on">Включить вспышку</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="one">Выбрано: <xliff:g>%d</xliff:g> карта</item>
|
||||
<item quantity="few">Выбрано: <xliff:g>%d</xliff:g> карты</item>
|
||||
<item quantity="many">Выбрано: <xliff:g>%d</xliff:g> карт</item>
|
||||
<item quantity="other">Выбрано: <xliff:g>%d</xliff:g> карт</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -54,8 +54,6 @@
|
||||
<string name="about_title_fmt">O <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Verzia: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Informácia pri revízii: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> používa nasledujúce knižnice tretej strany: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> používa tieto knižnice tretích strán: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
|
||||
<string name="selectBarcodeTitle">Vyberte čiarový kód</string>
|
||||
<string name="copy_to_clipboard_toast">ID karty skopírované do schránky</string>
|
||||
@@ -64,10 +62,6 @@
|
||||
|
||||
<string name="settings">Nastavenia</string>
|
||||
<string name="settings_category_title_ui">Používateľské prostredie</string>
|
||||
<string name="settings_card_title_list_font_size">Veľkosť názvu karty v zozname</string>
|
||||
<string name="settings_card_note_list_font_size">Veľkosť poznámky v zozname</string>
|
||||
<string name="settings_card_title_font_size">Veľkosť názvu karty</string>
|
||||
<string name="settings_card_id_font_size">Veľkosť ID karty pod čiarovým kódom</string>
|
||||
<string name="settings_display_barcode_max_brightness">Zvýšiť jas pri zobrazení čiarového kódu </string>
|
||||
<string name="settings_lock_barcode_orientation">Uzamkni orientáciu čiarového kódu</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="action_add">Dodaj</string>
|
||||
|
||||
<string name="noGiftCards">Trenutno nimate shranjene nobene kartice zvestobe. Kliknite \"+\" (plus) na vrhu, da jih dodate.\n\n Aplikacija Kartice zvestobe Vam omogoča, da imate kartice zvestobe shranjene na Vašem telefonu in vedno v dosegu roke.</string>
|
||||
<string name="storeName">Shrani</string>
|
||||
<string name="note">Zabeležka</string>
|
||||
@@ -18,15 +16,13 @@
|
||||
<string name="deleteConfirmation">Prosim potrdite, če želite izbrisati to kartico.</string>
|
||||
<string name="ok">Vredu</string>
|
||||
<string name="copy_to_clipboard">Kopirajte številko kartice</string>
|
||||
<string name="sendLabel">Pošlji#8230;</string>
|
||||
<string name="sendLabel">Pošlji…</string>
|
||||
<string name="editCardTitle">Uredi kartico zvestobe</string>
|
||||
<string name="addCardTitle">Dodaj kartico zvestobe</string>
|
||||
<string name="scanCardBarcode">Skeniraj črtno kodo</string>
|
||||
<string name="cardShortcut">Bližnjica do kartice</string>
|
||||
<string name="noCardsMessage">Trenutno ni na voljo nobene kartice. Najprej jih je potrebno dodati.</string>
|
||||
|
||||
<string name="barcodeImageDescription">Slika črtne kode na kartici</string>
|
||||
|
||||
<string name="noStoreError">Ime trgovine ni bilo vnešeno</string>
|
||||
<string name="noCardIdError">Številka kartice ni bila vnešena</string>
|
||||
<string name="noCardExistsError">Te kartice zvestobe ni bilo moč najti</string>
|
||||
@@ -39,8 +35,8 @@
|
||||
<string name="exportSuccessfulTitle">Izvoz je uspel</string>
|
||||
<string name="exportFailedTitle">Izvoz ni uspel</string>
|
||||
<string name="exportFailed">Napaka pri izvozu</string>
|
||||
<string name="importing">Uvažanje…</string>
|
||||
<string name="exporting">Izvažanje…</string>
|
||||
<string name="importing">Uvažanje…</string>
|
||||
<string name="exporting">Izvažanje…</string>
|
||||
<string name="noExternalStoragePermissionError">Izvažanje in uvažanje je nemogoče brez omogočenega dostopa do zunanje shrambe</string>
|
||||
<string name="importOptionFilesystemTitle">Uvozi iz datotečnega sistema</string>
|
||||
<string name="importOptionFilesystemExplanation">Izberite specifično datoteko iz datotečnega sistema</string>
|
||||
@@ -48,26 +44,16 @@
|
||||
<string name="importOptionApplicationTitle">Uporabi zunanjo aplikacijo</string>
|
||||
<string name="importOptionApplicationExplanation">Uporabi zunanjo aplikacijo, kot npr. Dropbox, Google Drive ali ostale upravljalnike datotek, za odpiranje datoteko.</string>
|
||||
<string name="importOptionApplicationButton">Uporabi zunanjo aplikacijo</string>
|
||||
|
||||
<string name="about">Več o aplikaciji</string>
|
||||
<string name="app_license">Licencirano s skladu z GPLv3.</string>
|
||||
<string name="about_title_fmt">Več o <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Verzija: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Informacije o popravkih: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> uporablja sledeče zunanje knjižnice: <xliff:g id="app_libraries_list">%s</xliff:g> </string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g>uporablja sledeče zunanje vire: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
|
||||
<string name="selectBarcodeTitle">Izberite črtno kodo</string>
|
||||
<string name="copy_to_clipboard_toast">Številka kartice je bila kopirana v odložišče</string>
|
||||
|
||||
<string name="thumbnailDescription">Ikona kartice</string>
|
||||
|
||||
<string name="settings">Nastavitve</string>
|
||||
<string name="settings_category_title_ui">Uporabniški vmesnik</string>
|
||||
<string name="settings_card_title_list_font_size">Velikost pisave seznama naslovov kartic</string>
|
||||
<string name="settings_card_note_list_font_size">Velikost pisave seznama zabeležk </string>
|
||||
<string name="settings_card_title_font_size">Velikost pisave imen kartic</string>
|
||||
<string name="settings_card_id_font_size">Velikost pisave številke kartice</string>
|
||||
<string name="settings_display_barcode_max_brightness">Povečaj osvetljenost prikaza črtne kode</string>
|
||||
<string name="settings_lock_barcode_orientation">Zakleni orientacijo črtne kode</string>
|
||||
</resources>
|
||||
</resources>
|
||||
@@ -1,4 +1,174 @@
|
||||
<resources
|
||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
|
||||
</resources>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="privacy_policy_popup_text">Політика конфіденційності (вимагається деякими магазинами):
|
||||
\n
|
||||
\nЖОДНОЇ ІНФОРМАЦІЇ НЕ ЗБИРАЄТЬСЯ, що може підтвердити будь-хто, адже наша програма це вільне програмне забезпечення.</string>
|
||||
<string name="noGiftCards">Натисніть + щоб додати карту чи спочатку імпортуйте з ⋮ меню.</string>
|
||||
<string name="settings_display_barcode_max_brightness">Яскравіший штрих-код</string>
|
||||
<string name="enterBarcodeInstructions">Введіть ID карти та оберіть тип штрих-коду чи \"Ця карта не має штрих-коду\".</string>
|
||||
<string name="selectBarcodeTitle">Оберіть штрих-код</string>
|
||||
<string name="barcodeImageDescription">Зображення штрих-коду карти</string>
|
||||
<string name="scanCardBarcode">Відсканувати штрих-код карти</string>
|
||||
<string name="noBarcode">Без штрих-коду</string>
|
||||
<string name="barcodeNoBarcode">Ця карта не має штрих-коду</string>
|
||||
<string name="barcodeType">Тип штрих-коду</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> картка</item>
|
||||
<item quantity="few"><xliff:g>%d</xliff:g> карток</item>
|
||||
<item quantity="many"><xliff:g>%d</xliff:g> картки</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> картки</item>
|
||||
</plurals>
|
||||
<string name="no">НІ</string>
|
||||
<string name="yes">Так</string>
|
||||
<string name="updateBarcodeQuestionText">Ви змінили ID картки. Чи ви бажаєте оновити штрих-код для використання цього ж значення\?</string>
|
||||
<string name="updateBarcodeQuestionTitle">Оновити значення штрих-коду\?</string>
|
||||
<string name="wrongValueForBarcodeType">Значення не дійсне для обраного типу штрих-коду</string>
|
||||
<string name="unsupportedBarcodeType">Цей тип штрих-коду поки що не відображається. Підтримку може бути додано в подальших версіях програми.</string>
|
||||
<string name="setBarcodeId">Встановіть значення штрих-коду</string>
|
||||
<string name="sameAsCardId">Таке ж як ID картки</string>
|
||||
<string name="barcodeId">Значення штрих-коду</string>
|
||||
<string name="importVoucherVaultMessage">Оберіть Voucher Vault експорт-файл названий <i>vouchervault.json</i> для імпортування.
|
||||
\nЧи створіть його натиснувши \"Експорт\" у Voucher Vault.</string>
|
||||
<string name="importVoucherVault">Імпорт з Voucher Vault</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Знайдіть файл названий <i>LoyaltyCardKeychain.csv</i> для імпортування.
|
||||
\nЧи створіть його у меню імпорту/експорту Loyalty Card Keychain натиснувши \"Експорт\".</string>
|
||||
<string name="importCatimaMessage">Оберіть експорт-файл названий <i>catima.zip</i> для імпортування.
|
||||
\nЧи створіть його з меню імпорту/експорту у іншій Catima, натиснувши \"Експорт\".</string>
|
||||
<string name="importLoyaltyCardKeychain">Імпорт з Loyalty Card Keychain</string>
|
||||
<string name="importFidmeMessage">Оберіть FidMe експорт-файл названий <i>fidme-export-request-xxxxxx.zip</i> для імпортування і оберіть типи штрих-кодів вручну пізніше.
|
||||
\nЧи створіть його у вашому FidMe профілі обравши \"Захист даних -> Витяг даних\".</string>
|
||||
<string name="importFidme">Імпорт з FidMe</string>
|
||||
<string name="importCatima">Імпорт з Catima</string>
|
||||
<string name="accept">Прийняти</string>
|
||||
<string name="privacy_policy">Політика конфіденційності</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="chooseImportType">Імпортувати дані з\?</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> здається, не є дійсним залишком.</string>
|
||||
<string name="points">Бали</string>
|
||||
<string name="currency">Валюта</string>
|
||||
<string name="balance">Баланс</string>
|
||||
<string name="errorReadingImage">Неможливо прочитати зображення</string>
|
||||
<string name="noBarcodeFound">Жодного штрих-коду не знайдено</string>
|
||||
<string name="moveBarcodeToCenterOfScreen">Відцентрувати штрих-код на екрані</string>
|
||||
<string name="moveBarcodeToTopOfScreen">Посунути штрих-код наверх екрану</string>
|
||||
<string name="chooseExpiryDate">Оберіть дату закінчення терміну дії</string>
|
||||
<string name="never">Ніколи</string>
|
||||
<string name="expiryDate">Дата закінчення терміну дії</string>
|
||||
<string name="editBarcode">Редагувати штрих-код</string>
|
||||
<string name="barcode">Штрих-код</string>
|
||||
<string name="card">Картка</string>
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g> балів</string>
|
||||
<string name="balanceSentence">Баланс: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">Термін дії закінчився: <xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">Термін дії закінчується: <xliff:g>%s</xliff:g></string>
|
||||
<string name="groupsList">Групи: <xliff:g>%s</xliff:g></string>
|
||||
<string name="addFromImage">Оберіть зображення з галереї</string>
|
||||
<string name="addManually">Ввести ID карти вручну</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Вийти без збереження\?</string>
|
||||
<string name="leaveWithoutSaveTitle">Вихід</string>
|
||||
<string name="moveDown">Посунути донизу</string>
|
||||
<string name="moveUp">Посунути вгору</string>
|
||||
<string name="failedOpeningFileManager">Спочатку встановіть файловий менеджер.</string>
|
||||
<string name="deleteConfirmationGroup">Видалити групу\?</string>
|
||||
<string name="all">Усі</string>
|
||||
<string name="noGroups">Спочатку натисніть + щоб додати групи для категоризації.</string>
|
||||
<string name="groups">Групи</string>
|
||||
<string name="enter_group_name">Введіть ім\'я групи</string>
|
||||
<string name="exportSuccessful">Дані картки/карток експортовано</string>
|
||||
<string name="importSuccessful">Дані картки/карток імпортовано</string>
|
||||
<string name="intent_import_card_from_url_share_text">Я хочу поділитися картою з тобою</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Не блокувати екран</string>
|
||||
<string name="settings_keep_screen_on">Не вимикати екран</string>
|
||||
<string name="settings_lock_barcode_orientation">Заблокувати орієнтацію штрих-коду</string>
|
||||
<string name="settings_max_font_size_scale">Макс. розмір шрифту</string>
|
||||
<string name="settings_dark_theme">Темна</string>
|
||||
<string name="settings_light_theme">Світла</string>
|
||||
<string name="settings_system_theme">Система</string>
|
||||
<string name="settings_theme">Тема</string>
|
||||
<string name="settings_category_title_ui">Інтерфейс користувача</string>
|
||||
<string name="settings">Налаштування</string>
|
||||
<string name="starImage">Улюблена зірка</string>
|
||||
<string name="thumbnailDescription">Ескіз для карти</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">Я хочу поділитися деякими картами з тобою</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">ID карток скопійовано до буферу обміну</string>
|
||||
<string name="copy_to_clipboard_toast">ID карти скопійовано до буферу обміну</string>
|
||||
<string name="app_resources">Вільні ресурси третіх сторін: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Вільні бібліотеки третіх сторін: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Інформація про випуск: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Версія: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="about_title_fmt">Про <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="app_license">Копілефт вільне програмне забезпечення, ліцензоване під GPLv3+.</string>
|
||||
<string name="app_copyright_old">Створено на основі Loyalty Card Keychain
|
||||
\nавторські права © 2016–2020 Branden Archer.</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Авторські права © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="about">Про програму</string>
|
||||
<string name="importOptionApplicationButton">Використайте іншу програму</string>
|
||||
<string name="importOptionApplicationExplanation">Використайте іншу програму чи ваш улюблений файл-менеджер для відкриття файлу.</string>
|
||||
<string name="importOptionApplicationTitle">Використати іншу програму</string>
|
||||
<string name="importOptionFilesystemButton">З провідника</string>
|
||||
<string name="importOptionFilesystemExplanation">Оберіть конкретний файл у провіднику.</string>
|
||||
<string name="importOptionFilesystemTitle">Імпорт з провідника</string>
|
||||
<string name="exportOptionExplanation">Дані буде записано до локації обраної вами.</string>
|
||||
<string name="noExternalStoragePermissionError">Надайте дозвіл на доступ до пам\'яті пристрою для імпорту чи експорту карток</string>
|
||||
<string name="exporting">Експортуємо…</string>
|
||||
<string name="importing">Імпортуємо…</string>
|
||||
<string name="exportFailed">Неможливо експортувати картки</string>
|
||||
<string name="exportFailedTitle">Помилка експорту</string>
|
||||
<string name="exportSuccessfulTitle">Експортовано</string>
|
||||
<string name="importFailed">Неможливо імпортувати картки</string>
|
||||
<string name="importFailedTitle">Помилка імпорту</string>
|
||||
<string name="importSuccessfulTitle">Імпортовано</string>
|
||||
<string name="importExportHelp">Створення резервної копії ваших карток дозволяє перемістити їх до іншого пристрою.</string>
|
||||
<string name="exportName">Експорт</string>
|
||||
<string name="importExport">Імпорт/Експорт</string>
|
||||
<string name="failedParsingImportUriError">Неможливо опрацювати імпорт-URI</string>
|
||||
<string name="noCardExistsError">Карту не знайдено</string>
|
||||
<string name="noCardIdError">ID карти не введено</string>
|
||||
<string name="noStoreError">Ім\'я не введено</string>
|
||||
<string name="card_ids_copied">ID карти скопійовано</string>
|
||||
<string name="noCardsMessage">Спочатку додайте карту</string>
|
||||
<string name="cardShortcut">Швидкий виклик карти</string>
|
||||
<string name="addCardTitle">Додати карту</string>
|
||||
<string name="editCardTitle">Редагувати карту</string>
|
||||
<string name="sendLabel">Відправити…</string>
|
||||
<string name="share">Поділитися</string>
|
||||
<string name="copy_to_clipboard">Копіювати ID до буферу обміну</string>
|
||||
<string name="ok">ОК</string>
|
||||
<string name="deleteConfirmation">Бажаєте видалити карту\?</string>
|
||||
<string name="deleteTitle">Видалити карту</string>
|
||||
<string name="unlockScreen">Розблокувати обертання</string>
|
||||
<string name="lockScreen">Блокувати обертання</string>
|
||||
<string name="confirm">Підтвердити</string>
|
||||
<string name="delete">Видалити</string>
|
||||
<string name="edit">Редагувати</string>
|
||||
<string name="save">Зберегти</string>
|
||||
<string name="cancel">Відмінити</string>
|
||||
<string name="unstar">Видалити з улюблених</string>
|
||||
<string name="star">Додати до улюблених</string>
|
||||
<string name="cardId">ID картки</string>
|
||||
<string name="note">Замітка</string>
|
||||
<string name="storeName">Ім\'я</string>
|
||||
<string name="noMatchingGiftCards">Збігів не знайдено. Спробуйте змінити параметри пошуку.</string>
|
||||
<string name="action_add">Додати</string>
|
||||
<string name="action_search">Пошук</string>
|
||||
<string name="turn_flashlight_off">Вимкнути спалах</string>
|
||||
<string name="turn_flashlight_on">Увімкнути спалах</string>
|
||||
<string name="failedGeneratingShareURL">Збій створення URL обміну. Будь ласка повідомте про цю помилку!</string>
|
||||
<string name="passwordRequired">Будь ласка введіть пароль</string>
|
||||
<string name="takePhoto">Зробити фото</string>
|
||||
<string name="removeImage">Видалити зображення</string>
|
||||
<string name="setBackImage">Встановити зображення тильної сторони</string>
|
||||
<string name="setFrontImage">Встановити зображення лицьової сторони</string>
|
||||
<string name="photos">Фотографії</string>
|
||||
<string name="backImageDescription">Тильна сторона карти</string>
|
||||
<string name="frontImageDescription">Лицьова сторона карти</string>
|
||||
<string name="importStocardMessage">Оберіть Stocard експорт-файл, названий <i>***-sync.zip</i> для імпортування і оберіть типи штрих-кодів вручну пізніше.
|
||||
\nЧи отримайте його надіславши електронного листа із запитом на експортування ваших даних до support@stocardapp.com.</string>
|
||||
<string name="importStocard">Імпорт із Stocard</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="one">Обрано: <xliff:g>%d</xliff:g> карта</item>
|
||||
<item quantity="few">Обрано: <xliff:g>%d</xliff:g> карти</item>
|
||||
<item quantity="many">Обрано: <xliff:g>%d</xliff:g> карт</item>
|
||||
<item quantity="other">Обрано: <xliff:g>%d</xliff:g> карт</item>
|
||||
</plurals>
|
||||
</resources>
|
||||
@@ -1,8 +1,9 @@
|
||||
<resources>>
|
||||
<resources>
|
||||
|
||||
<style name="AppTheme.NoActionBar" parent="AppTheme">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
146
app/src/main/res/values-zh-rCN/strings.xml
Normal file
146
app/src/main/res/values-zh-rCN/strings.xml
Normal file
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
|
||||
<string name="app_revision_fmt">更新日志: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="groupsList">组:<xliff:g>%s</xliff:g></string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> 卡片</item>
|
||||
</plurals>
|
||||
<string name="app_libraries">第三方自由程序库: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">版本: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="about_title_fmt">关于 <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="barcode">条形码</string>
|
||||
<string name="card">卡片</string>
|
||||
<string name="addManually">手动输入卡号</string>
|
||||
<string name="settings_system_theme">系统设置</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="importOptionApplicationButton">使用其他应用</string>
|
||||
<string name="importOptionFilesystemButton">从文件系统</string>
|
||||
<string name="barcodeImageDescription">卡片二维码图像</string>
|
||||
<string name="unstar">从收藏中删除</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">我想和你分享一些卡片</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">已将卡号复制到剪贴板</string>
|
||||
<string name="wrongValueForBarcodeType">该值对所选条形码类型无效</string>
|
||||
<string name="unsupportedBarcodeType">此条形码类型尚无法显示。较新版本的应用程序可能提供支持。</string>
|
||||
<string name="setBarcodeId">设置条形码值</string>
|
||||
<string name="sameAsCardId">与卡号相同</string>
|
||||
<string name="barcodeId">条形码值</string>
|
||||
<string name="importVoucherVaultMessage">找到一个可能名为<i>vouchervault.json</i>的文件进行导入。
|
||||
\n或者先在Voucher Vault中按下导出键来创建导出。</string>
|
||||
<string name="importVoucherVault">从 Voucher Vault 导入</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">找到一个很可能名为<i>LoyaltyCardKeychain.csv</i>的文件来导入。
|
||||
\n或者先从Loyalty Card Keychain的Import/Export菜单中选择Export来导出。</string>
|
||||
<string name="importLoyaltyCardKeychain">从 Loyalty Card Keychain 导入</string>
|
||||
<string name="importFidmeMessage">找到一个可能名为<i>fidme-export-request-xxxxxx.zip</i>的文件进行导入,之后再手动选择条码类型。
|
||||
\n或者从你的FidMe配置文件中选择数据保护,然后按提取我的数据来创建导出。</string>
|
||||
<string name="importFidme">从 FidMe 导入</string>
|
||||
<string name="importCatimaMessage">找到一个可能名为<i>Catima.csv</i>的文件来导入。
|
||||
\n或者先从另一个Catima应用程序的导入/导出菜单中,来创建导出。</string>
|
||||
<string name="importCatima">从 Catima 导入</string>
|
||||
<string name="accept">接受</string>
|
||||
<string name="privacy_policy_popup_text">隐私政策通知(一些应用程序商店要求)。
|
||||
\n
|
||||
\n本应用没有收集任何数据,任何人都可以查阅源码来确认,因为本软件是自由软件。</string>
|
||||
<string name="privacy_policy">隐私政策</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
<string name="chooseImportType">导入数据?</string>
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g>似乎不是有效的余额。</string>
|
||||
<string name="points">积分</string>
|
||||
<string name="currency">货币</string>
|
||||
<string name="balance">余额</string>
|
||||
<string name="errorReadingImage">无法读取图像</string>
|
||||
<string name="noBarcodeFound">未找到条形码</string>
|
||||
<string name="moveBarcodeToCenterOfScreen">将条形码居中显示</string>
|
||||
<string name="moveBarcodeToTopOfScreen">将条形码移到屏幕的顶部</string>
|
||||
<string name="chooseExpiryDate">选择到期日</string>
|
||||
<string name="never">从不</string>
|
||||
<string name="expiryDate">过期时间</string>
|
||||
<string name="editBarcode">编辑条形码</string>
|
||||
<string name="balancePoints"><xliff:g>%s</xliff:g>分</string>
|
||||
<string name="balanceSentence">余额:<xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentenceExpired">过期:<xliff:g>%s</xliff:g></string>
|
||||
<string name="expiryStateSentence">过期: <xliff:g>%s</xliff:g></string>
|
||||
<string name="addFromImage">从相册中选择图片</string>
|
||||
<string name="leaveWithoutSaveConfirmation">不保存就离开吗?</string>
|
||||
<string name="leaveWithoutSaveTitle">退出</string>
|
||||
<string name="moveDown">向下移</string>
|
||||
<string name="moveUp">向上移</string>
|
||||
<string name="failedOpeningFileManager">请先安装文件管理器。</string>
|
||||
<string name="deleteConfirmationGroup">删除群组?</string>
|
||||
<string name="all">全部</string>
|
||||
<string name="noGroups">点击 \"+\" 按钮,先添加组进行分类。</string>
|
||||
<string name="enter_group_name">输入组名</string>
|
||||
<string name="groups">组</string>
|
||||
<string name="exportSuccessful">已导出卡片数据</string>
|
||||
<string name="importSuccessful">已导入卡片数据</string>
|
||||
<string name="intent_import_card_from_url_share_text">我想和你分享一张卡</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">禁用锁屏</string>
|
||||
<string name="settings_keep_screen_on">保持屏幕常亮</string>
|
||||
<string name="settings_lock_barcode_orientation">锁定条码方向</string>
|
||||
<string name="settings_display_barcode_max_brightness">提高条码界面亮度</string>
|
||||
<string name="settings_max_font_size_scale">最大字体大小</string>
|
||||
<string name="settings_dark_theme">暗色</string>
|
||||
<string name="settings_light_theme">浅色</string>
|
||||
<string name="settings_theme">主题</string>
|
||||
<string name="settings_category_title_ui">用户界面</string>
|
||||
<string name="settings">设置</string>
|
||||
<string name="thumbnailDescription">卡片缩略图</string>
|
||||
<string name="copy_to_clipboard_toast">已复制卡号到剪贴板</string>
|
||||
<string name="enterBarcodeInstructions">输入卡号,并从下面选择其条码类型,或选择\"此卡片没有条码\"。</string>
|
||||
<string name="selectBarcodeTitle">选择条码</string>
|
||||
<string name="app_resources">第三方自由资源:<xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_license">本软件为自由软件,使用 GPLv3+ 许可.</string>
|
||||
<string name="app_copyright_old">基于 Loyalty Card Keychain
|
||||
\ncopyright © 2016–2020 Branden Archer.</string>
|
||||
<string name="about">关于</string>
|
||||
<string name="importOptionApplicationExplanation">使用任何应用程序或您喜欢的文件管理器打开文件。</string>
|
||||
<string name="importOptionApplicationTitle">使用其他应用</string>
|
||||
<string name="importOptionFilesystemExplanation">请从文件系统选择文件.</string>
|
||||
<string name="importOptionFilesystemTitle">从文件系统导入</string>
|
||||
<string name="exportOptionExplanation">导出的数据将储存至你选择的位置.</string>
|
||||
<string name="noExternalStoragePermissionError">在导入导出前需要获得外部储存权限</string>
|
||||
<string name="exporting">导出中…</string>
|
||||
<string name="importing">导入中…</string>
|
||||
<string name="exportFailed">无法导出卡片</string>
|
||||
<string name="exportFailedTitle">导出失败</string>
|
||||
<string name="exportSuccessfulTitle">导出成功</string>
|
||||
<string name="importFailed">无法导入卡片</string>
|
||||
<string name="importFailedTitle">导入失败</string>
|
||||
<string name="importSuccessfulTitle">导入成功</string>
|
||||
<string name="importExportHelp">备份卡片后你可以让你将它们转移到其他设备。</string>
|
||||
<string name="exportName">导出</string>
|
||||
<string name="importExport">导入/导出</string>
|
||||
<string name="failedParsingImportUriError">无法解析导入的URI</string>
|
||||
<string name="noCardExistsError">无法到卡片</string>
|
||||
<string name="noCardIdError">未输入卡号</string>
|
||||
<string name="noStoreError">未输入卡片名称</string>
|
||||
<string name="card_ids_copied">复制卡号</string>
|
||||
<string name="noCardsMessage">请先添加一张卡片</string>
|
||||
<string name="cardShortcut">卡片快捷键</string>
|
||||
<string name="editCardTitle">编辑卡片</string>
|
||||
<string name="addCardTitle">添加卡片</string>
|
||||
<string name="scanCardBarcode">扫描卡片条码</string>
|
||||
<string name="sendLabel">发送…</string>
|
||||
<string name="share">分享</string>
|
||||
<string name="copy_to_clipboard">复制卡号到剪贴板</string>
|
||||
<string name="ok">确定</string>
|
||||
<string name="deleteConfirmation">删除此卡?</string>
|
||||
<string name="deleteTitle">移除卡片</string>
|
||||
<string name="unlockScreen">解除旋转锁定</string>
|
||||
<string name="lockScreen">锁定旋转</string>
|
||||
<string name="confirm">确认</string>
|
||||
<string name="delete">删除</string>
|
||||
<string name="edit">编辑</string>
|
||||
<string name="save">保存</string>
|
||||
<string name="cancel">取消</string>
|
||||
<string name="star">添加到收藏</string>
|
||||
<string name="noBarcode">无条形码</string>
|
||||
<string name="barcodeNoBarcode">此卡无条形码</string>
|
||||
<string name="barcodeType">条形码类型</string>
|
||||
<string name="cardId">卡号</string>
|
||||
<string name="note">备注</string>
|
||||
<string name="storeName">名称</string>
|
||||
<string name="noMatchingGiftCards">没有找到任何东西。尝试改变你的搜索。</string>
|
||||
<string name="noGiftCards">点击 \"+\"加号按钮来添加卡片,或者先从⋮菜单中导入一些。</string>
|
||||
<string name="action_add">添加</string>
|
||||
<string name="action_search">搜索</string>
|
||||
</resources>
|
||||
@@ -4,6 +4,7 @@
|
||||
<item>Catima</item>
|
||||
<item>Fidme</item>
|
||||
<item>@string/app_loyalty_card_keychain</item>
|
||||
<item>Stocard</item>
|
||||
<item>Voucher Vault</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -10,6 +10,8 @@
|
||||
<color name="colorPrimaryText">#ffffff</color>
|
||||
<color name="colorSecondaryText">#000000</color>
|
||||
|
||||
<color name="listItemHighlight">#44000000</color>
|
||||
|
||||
<color name="inputContrastBackground">#F8F8F8</color>
|
||||
<color name="inputBackground">#FFFFFF</color>
|
||||
<color name="inputBorder">#DDDDDD</color>
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
<resources>
|
||||
<string name="app_revision_url" translatable="false">https://github.com/TheLastProject/Catima/releases</string>
|
||||
<string name="app_webpage_url" translatable="false">https://github.com/TheLastProject/Catima</string>
|
||||
<integer name="full_rotation_duration">100</integer>
|
||||
<integer name="half_rotation_duration">50</integer>
|
||||
</resources>
|
||||
@@ -34,5 +34,6 @@
|
||||
|
||||
<!-- The default letter tile text size -->
|
||||
<dimen name="tileLetterFontSize">33sp</dimen>
|
||||
<dimen name="tileLetterFontSizeForShortcut">24dp</dimen>
|
||||
<dimen name="cardViewLetterFontSize">100sp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -24,18 +24,9 @@
|
||||
</array>
|
||||
|
||||
<!-- Default values -->
|
||||
<integer name="settings_card_title_list_font_size_sp">28</integer>
|
||||
<integer name="settings_card_note_list_font_size_sp">14</integer>
|
||||
<integer name="settings_card_title_font_size_sp">40</integer>
|
||||
<integer name="settings_card_id_font_size_sp">50</integer>
|
||||
<integer name="settings_max_font_size_scale_pct">100</integer>
|
||||
|
||||
<!-- Constraints -->
|
||||
<integer name="settings_card_title_list_max_font_size_sp">40</integer>
|
||||
<integer name="settings_card_title_list_min_font_size_sp">16</integer>
|
||||
<integer name="settings_card_note_list_max_font_size_sp">25</integer>
|
||||
<integer name="settings_card_note_list_min_font_size_sp">10</integer>
|
||||
<integer name="settings_card_title_max_font_size_sp">50</integer>
|
||||
<integer name="settings_card_title_min_font_size_sp">16</integer>
|
||||
<integer name="settings_card_id_max_font_size_sp">50</integer>
|
||||
<integer name="settings_card_id_min_font_size_sp">16</integer>
|
||||
<integer name="settings_max_font_size_scale_pct_min">50</integer>
|
||||
<integer name="settings_max_font_size_scale_pct_max">200</integer>
|
||||
</resources>
|
||||
@@ -4,11 +4,15 @@
|
||||
|
||||
<string name="action_search">Search</string>
|
||||
<string name="action_add">Add</string>
|
||||
<plurals name="selectedCardCount">
|
||||
<item quantity="one">Selected: <xliff:g>%d</xliff:g> card</item>
|
||||
<item quantity="other">Selected: <xliff:g>%d</xliff:g> cards</item>
|
||||
</plurals>
|
||||
|
||||
<string name="noGiftCards">Click the "+" (plus) button to add a card first.\n\nCatima carries your cards on the device, so they are always within reach.</string>
|
||||
<string name="noGiftCards">Click the + plus button to add a card, or import some from the ⋮ menu first.</string>
|
||||
<string name="noMatchingGiftCards">Didn\'t find anything. Try changing your search.</string>
|
||||
|
||||
<string name="storeName">Store</string>
|
||||
<string name="storeName">Name</string>
|
||||
<string name="note">Note</string>
|
||||
<string name="cardId">Card ID</string>
|
||||
<string name="barcodeType">Barcode type</string>
|
||||
@@ -26,7 +30,7 @@
|
||||
<string name="lockScreen">Block Rotation</string>
|
||||
<string name="unlockScreen">Unblock Rotation</string>
|
||||
<string name="deleteTitle">Remove Card</string>
|
||||
<string name="deleteConfirmation">Please confirm you want to delete this card.</string>
|
||||
<string name="deleteConfirmation">Delete this card?</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="copy_to_clipboard">Copy ID to clipboard</string>
|
||||
<string name="share">Share</string>
|
||||
@@ -36,10 +40,11 @@
|
||||
<string name="scanCardBarcode">Scan Card Barcode</string>
|
||||
<string name="cardShortcut">Card Shortcut</string>
|
||||
<string name="noCardsMessage">Add a card first</string>
|
||||
<string name="card_ids_copied">Copied Card ID(s)</string>
|
||||
|
||||
<string name="barcodeImageDescription">Image of card barcode</string>
|
||||
|
||||
<string name="noStoreError">No store entered</string>
|
||||
<string name="noStoreError">No name entered</string>
|
||||
<string name="noCardIdError">No card ID entered</string>
|
||||
<string name="noCardExistsError">Could not find card</string>
|
||||
<string name="failedParsingImportUriError">Could not parse the import URI</string>
|
||||
@@ -59,22 +64,22 @@
|
||||
<string name="importOptionFilesystemTitle">Import from filesystem</string>
|
||||
<string name="importOptionFilesystemExplanation">Choose a specific file from the filesystem.</string>
|
||||
<string name="importOptionFilesystemButton">From filesystem</string>
|
||||
<string name="importOptionApplicationTitle">Use external app</string>
|
||||
<string name="importOptionApplicationTitle">Use another app</string>
|
||||
<string name="importOptionApplicationExplanation">Use any app or your favorite file manager to open a file.</string>
|
||||
<string name="importOptionApplicationButton">Use external app</string>
|
||||
<string name="importOptionApplicationButton">Use another app</string>
|
||||
|
||||
<string name="about">About</string>
|
||||
<string name="app_copyright_fmt" translatable="false" tools:ignore="PluralsCandidate">Copyright 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="app_copyright_old">Based on Loyalty Card Keychain, copyright 2016–2020 Branden Archer.</string>
|
||||
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019–<xliff:g>%d</xliff:g> Sylvia van Os.</string>
|
||||
<string name="app_copyright_old">Based on Loyalty Card Keychain\ncopyright © 2016–2020 Branden Archer.</string>
|
||||
<string name="app_license">Copylefted libre software, licensed GPLv3+.</string>
|
||||
<string name="about_title_fmt">About <xliff:g id="app_name">%s</xliff:g></string>
|
||||
<string name="debug_version_fmt">Version: <xliff:g id="version">%s</xliff:g></string>
|
||||
<string name="app_revision_fmt">Revision Info: <xliff:g id="app_revision_url">%s</xliff:g></string>
|
||||
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> uses the following third-party libraries: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> uses the following third-party resources: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
<string name="app_libraries">Libre third-party libraries: <xliff:g id="app_libraries_list">%s</xliff:g></string>
|
||||
<string name="app_resources">Libre third-party resources: <xliff:g id="app_resources_list">%s</xliff:g></string>
|
||||
|
||||
<string name="selectBarcodeTitle">Select Barcode</string>
|
||||
<string name="enterBarcodeInstructions">Enter the card ID then select the image which represents the barcode you want to use, or select “This card has no barcode” to not use a barcode.</string>
|
||||
<string name="enterBarcodeInstructions">Enter the card ID, and either pick its barcode type below, or “This card has no barcode”.</string>
|
||||
|
||||
<string name="copy_to_clipboard_toast">Card ID copied to clipboard</string>
|
||||
|
||||
@@ -91,49 +96,46 @@
|
||||
<string name="settings_key_light_theme" translatable="false">light</string>
|
||||
<string name="settings_dark_theme">Dark</string>
|
||||
<string name="settings_key_dark_theme" translatable="false">dark</string>
|
||||
<string name="settings_card_title_list_font_size">Card title font size (list mode)</string>
|
||||
<string name="settings_key_card_title_list_font_size" translatable="false">pref_card_title_list_font_size_sp</string>
|
||||
<string name="settings_card_note_list_font_size">Card note font size (list mode)</string>
|
||||
<string name="settings_key_card_note_list_font_size" translatable="false">pref_card_note_list_font_size_sp</string>
|
||||
<string name="settings_card_title_font_size">Card title font size (preview)</string>
|
||||
<string name="settings_key_card_title_font_size" translatable="false">pref_card_title_font_size_sp</string>
|
||||
<string name="settings_card_id_font_size">Card ID font size</string>
|
||||
<string name="settings_key_card_id_font_size" translatable="false">pref_card_id_font_size_sp</string>
|
||||
<string name="settings_key_max_font_size_scale" translatable="false">pref_max_font_size_scale</string>
|
||||
<string name="settings_max_font_size_scale">Max. font size</string>
|
||||
|
||||
<string name="settings_display_barcode_max_brightness">Brighten barcode view</string>
|
||||
<string name="settings_key_display_barcode_max_brightness" translatable="false">pref_display_card_max_brightness</string>
|
||||
<string name="settings_lock_barcode_orientation">Lock barcode orientation</string>
|
||||
<string name="settings_key_lock_barcode_orientation" translatable="false">pref_lock_barcode_orientation</string>
|
||||
<string name="settings_keep_screen_on">Keep screen on while viewing a card</string>
|
||||
<string name="settings_keep_screen_on">Keep screen on</string>
|
||||
<string name="settings_key_keep_screen_on" translatable="false">pref_keep_screen_on</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Disable lock screen while viewing a card</string>
|
||||
<string name="settings_disable_lockscreen_while_viewing_card">Prevent lock screen</string>
|
||||
<string name="settings_key_disable_lockscreen_while_viewing_card" translatable="false">pref_disable_lockscreen_while_viewing_card</string>
|
||||
|
||||
<string name="sharedpreference_active_tab" translatable="false">sharedpreference_active_tab</string>
|
||||
<string name="sharedpreference_privacy_policy_shown" translatable="false">sharedpreference_privacy_policy_shown</string>
|
||||
|
||||
<string name="intent_import_card_from_url_share_text">I want to share a card with you</string>
|
||||
<string name="intent_import_card_from_url_host" translatable="false">thelastproject.github.io</string>
|
||||
<string name="intent_import_card_from_url_path_prefix" translatable="false">/Catima/share</string>
|
||||
<string name="intent_import_card_from_url_host_old" translatable="false">brarcher.github.io</string>
|
||||
<string name="intent_import_card_from_url_path_prefix_old" translatable="false">/loyalty-card-locker/share</string>
|
||||
<string name="intent_import_card_from_url_host_catima_app" translatable="false">catima.app</string>
|
||||
<string name="intent_import_card_from_url_path_prefix_catima_app" translatable="false">/share</string>
|
||||
<string name="intent_import_card_from_url_host_thelastproject" translatable="false">thelastproject.github.io</string>
|
||||
<string name="intent_import_card_from_url_path_prefix_thelastproject" translatable="false">/Catima/share</string>
|
||||
<string name="intent_import_card_from_url_host_brarcher" translatable="false">brarcher.github.io</string>
|
||||
<string name="intent_import_card_from_url_path_prefix_brarcher" translatable="false">/loyalty-card-locker/share</string>
|
||||
<string name="importSuccessful">Card data imported</string>
|
||||
<string name="exportSuccessful">Card data exported</string>
|
||||
|
||||
<string name="enter_group_name">Enter group name</string>
|
||||
<string name="groups">Groups</string>
|
||||
<string name="noGroups">Click the "+" (plus) button to add groups first.\n\nGroups make things easier to find.</string>
|
||||
<string name="noGroups">Click the + plus button to add groups for categorization first.</string>
|
||||
<plurals name="groupCardCount">
|
||||
<item quantity="one"><xliff:g>%d</xliff:g> card</item>
|
||||
<item quantity="other"><xliff:g>%d</xliff:g> cards</item>
|
||||
</plurals>
|
||||
|
||||
<string name="all">All</string>
|
||||
<string name="deleteConfirmationGroup">Please confirm you want to delete this group</string>
|
||||
<string name="failedOpeningFileManager">Failed opening a file manager. Please make sure one is installed.</string>
|
||||
<string name="moveUp">Move up in list</string>
|
||||
<string name="moveDown">Move down in list</string>
|
||||
<string name="leaveWithoutSaveTitle">Leave without saving</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Are you sure you want to leave this screen? Changed made will not be saved.</string>
|
||||
<string name="deleteConfirmationGroup">Delete group?</string>
|
||||
<string name="failedOpeningFileManager">Install a file manager first.</string>
|
||||
<string name="moveUp">Move upwards</string>
|
||||
<string name="moveDown">Move downwards</string>
|
||||
<string name="leaveWithoutSaveTitle">Exit</string>
|
||||
<string name="leaveWithoutSaveConfirmation">Leave without saving?</string>
|
||||
<string name="addManually">Manually enter card ID</string>
|
||||
<string name="addFromImage">Select image from gallery</string>
|
||||
<string name="groupsList">Groups: <xliff:g>%s</xliff:g></string>
|
||||
@@ -152,25 +154,49 @@
|
||||
<string name="moveBarcodeToCenterOfScreen">Center the barcode on the screen</string>
|
||||
|
||||
<string name="noBarcodeFound">No barcode was found</string>
|
||||
<string name="errorReadingImage">Error reading image</string>
|
||||
<string name="errorReadingImage">Could not read the image</string>
|
||||
|
||||
<string name="balance">Balance</string>
|
||||
<string name="currency">Currency</string>
|
||||
<string name="points">Points</string>
|
||||
|
||||
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> does not seem to be a valid balance.</string>
|
||||
<string name="chooseImportType">Import data from which app?</string>
|
||||
<string name="chooseImportType">Import data from?</string>
|
||||
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
|
||||
|
||||
<string name="privacy_policy">Privacy Policy</string>
|
||||
<string name="privacy_policy_popup_text">Many app stores require apps to show their privacy policy on first start. Here is ours:\n\nWe collect NO DATA AT ALL and our app is Open Source so anyone can confirm this to be true.</string>
|
||||
<string name="privacy_policy_popup_text">Privacy policy notice (required by some app stores):\n\nNO DATA IS COLLECTED AT ALL, which anyone can confirm since our app is libre software.</string>
|
||||
<string name="accept">Accept</string>
|
||||
<string name="importCatima">Import from Catima</string>
|
||||
<string name="importCatimaMessage">Please select your Catima export file. It is most likely named Catima.csv.\n\nA Catima export file can be created by going to the Import/Export menu and pressing "Export".</string>
|
||||
<string name="importFidme">Import from Fidme</string>
|
||||
<string name="importFidmeMessage">Please select your Fidme export file. It is most likely named something like fidme-export-request-xxxxxx.zip.\n\nA Fidme export file can be created in the Fidme app by going to your profile, choosing "Data Protection" and then pressing "Extract my data".\n\nPlease note that Fidme does not store the barcode type in the export data so you will have to edit the imported cards manually.</string>
|
||||
<string name="importCatimaMessage">Select your <i>catima.zip</i> export from Catima to import.\nOr create it from the "Import/Export" menu of another Catima app by pressing "Export" there first.</string>
|
||||
<string name="importFidme">Import from FidMe</string>
|
||||
<string name="importFidmeMessage">Select your <i>fidme-export-request-xxxxxx.zip</i> export from FidMe to import, and select the barcode types manually afterwards.\nOr create it from your FidMe profile by choosing "Data Protection" and then pressing "Extract my data" first.</string>
|
||||
<string name="importLoyaltyCardKeychain">Import from Loyalty Card Keychain</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Please select your Loyalty Card Keychain export file. It is most likely named LoyaltyCardKeychain.csv.\n\nA Loyalty Card Keychain export file can be created by going to the Import/Export menu and pressing "Export".</string>
|
||||
<string name="importLoyaltyCardKeychainMessage">Select your <i>LoyaltyCardKeychain.csv</i> export from Loyalty Card Keychain to import.\nOr create it from the "Import/Export" menu in Loyalty Card Keychain by pressing "Export" there first.</string>
|
||||
<string name="importStocard">Import from Stocard</string>
|
||||
<string name="importStocardMessage">Select your <i>***-sync.zip</i> export from Stocard to import, and select the barcode types manually afterwards.\nOr get it by e-mailing support@stocardapp.com asking for an export of your data.</string>
|
||||
<string name="importVoucherVault">Import from Voucher Vault</string>
|
||||
<string name="importVoucherVaultMessage">Please select your Voucher Vault export file. It is most likely named vouchervault.json.\n\nA Voucher Vault export file can be created by pressing "Export".</string>
|
||||
<string name="importVoucherVaultMessage">Select your <i>vouchervault.json</i> export from Voucher Vault to import.\nOr create it by pressing "Export" in Voucher Vault first.</string>
|
||||
<string name="barcodeId">Barcode value</string>
|
||||
<string name="sameAsCardId">Same as card ID</string>
|
||||
<string name="setBarcodeId">Set barcode value</string>
|
||||
<string name="unsupportedBarcodeType">This barcode type can\'t yet be displayed. It may be supported in a later version of the app.</string>
|
||||
<string name="wrongValueForBarcodeType">The value is not valid for the selected barcode type</string>
|
||||
<string name="copy_to_clipboard_multiple_toast">Card IDs copied to clipboard</string>
|
||||
<string name="intent_import_card_from_url_share_multiple_text">I want to share some cards with you</string>
|
||||
<string name="frontImageDescription">Card\'s front image</string>
|
||||
<string name="backImageDescription">Card\'s back image</string>
|
||||
<string name="photos">Photos</string>
|
||||
<string name="setFrontImage">Set front image</string>
|
||||
<string name="setBackImage">Set back image</string>
|
||||
<string name="removeImage">Remove image</string>
|
||||
<string name="takePhoto">Take a photo</string>
|
||||
<string name="updateBarcodeQuestionTitle">Update barcode value?</string>
|
||||
<string name="updateBarcodeQuestionText">You changed the card ID. Do you want to also update the barcode to use the same value?</string>
|
||||
<string name="yes">Yes</string>
|
||||
<string name="no">No</string>
|
||||
<string name="passwordRequired">Please enter the password</string>
|
||||
<string name="failedGeneratingShareURL">Failed generating share URL. Please report this bug!</string>
|
||||
<string name="turn_flashlight_on">Turn flashlight on</string>
|
||||
<string name="turn_flashlight_off">Turn flashlight off</string>
|
||||
</resources>
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorSecondary">@color/colorSecondary</item>
|
||||
<item name="colorAccent">@color/colorSecondary</item>
|
||||
<item name="actionModeBackground">@color/colorPrimary</item>
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="actionModeCloseDrawable">@drawable/ic_close</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar" parent="AppTheme">
|
||||
|
||||
@@ -13,63 +13,47 @@
|
||||
android:defaultValue="@string/settings_key_system_theme"
|
||||
android:entries="@array/theme_value_strings"
|
||||
android:entryValues="@array/theme_values"
|
||||
app:iconSpaceReserved="false" />
|
||||
app:iconSpaceReserved="false"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<nl.invissvenska.numberpickerpreference.NumberDialogPreference
|
||||
android:key="@string/settings_key_card_title_list_font_size"
|
||||
android:title="@string/settings_card_title_list_font_size"
|
||||
app:defaultValue="@integer/settings_card_title_list_font_size_sp"
|
||||
app:numberPickerPreference_maxValue="@integer/settings_card_title_list_max_font_size_sp"
|
||||
app:numberPickerPreference_minValue="@integer/settings_card_title_list_min_font_size_sp"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<nl.invissvenska.numberpickerpreference.NumberDialogPreference
|
||||
android:key="@string/settings_key_card_note_list_font_size"
|
||||
android:title="@string/settings_card_note_list_font_size"
|
||||
app:defaultValue="@integer/settings_card_note_list_font_size_sp"
|
||||
app:numberPickerPreference_maxValue="@integer/settings_card_note_list_max_font_size_sp"
|
||||
app:numberPickerPreference_minValue="@integer/settings_card_note_list_min_font_size_sp"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<nl.invissvenska.numberpickerpreference.NumberDialogPreference
|
||||
android:key="@string/settings_key_card_title_font_size"
|
||||
android:title="@string/settings_card_title_font_size"
|
||||
app:defaultValue="@integer/settings_card_title_font_size_sp"
|
||||
app:numberPickerPreference_maxValue="@integer/settings_card_title_max_font_size_sp"
|
||||
app:numberPickerPreference_minValue="@integer/settings_card_title_min_font_size_sp"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<nl.invissvenska.numberpickerpreference.NumberDialogPreference
|
||||
android:key="@string/settings_key_card_id_font_size"
|
||||
android:title="@string/settings_card_id_font_size"
|
||||
app:defaultValue="@integer/settings_card_id_font_size_sp"
|
||||
app:numberPickerPreference_maxValue="@integer/settings_card_id_max_font_size_sp"
|
||||
app:numberPickerPreference_minValue="@integer/settings_card_id_min_font_size_sp"
|
||||
app:iconSpaceReserved="false" />
|
||||
android:key="@string/settings_key_max_font_size_scale"
|
||||
android:title="@string/settings_max_font_size_scale"
|
||||
app:defaultValue="@integer/settings_max_font_size_scale_pct"
|
||||
app:numberPickerPreference_maxValue="@integer/settings_max_font_size_scale_pct_max"
|
||||
app:numberPickerPreference_minValue="@integer/settings_max_font_size_scale_pct_min"
|
||||
app:numberPickerPreference_stepValue="10"
|
||||
app:numberPickerPreference_unitText="%"
|
||||
app:iconSpaceReserved="false"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="@string/settings_key_display_barcode_max_brightness"
|
||||
android:title="@string/settings_display_barcode_max_brightness"
|
||||
app:iconSpaceReserved="false" />
|
||||
app:iconSpaceReserved="false"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="@string/settings_key_lock_barcode_orientation"
|
||||
android:title="@string/settings_lock_barcode_orientation"
|
||||
app:iconSpaceReserved="false" />
|
||||
app:iconSpaceReserved="false"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="@string/settings_key_keep_screen_on"
|
||||
android:title="@string/settings_keep_screen_on"
|
||||
app:iconSpaceReserved="false" />
|
||||
app:iconSpaceReserved="false"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="@string/settings_key_disable_lockscreen_while_viewing_card"
|
||||
android:title="@string/settings_disable_lockscreen_while_viewing_card"
|
||||
app:iconSpaceReserved="false" />
|
||||
app:iconSpaceReserved="false"
|
||||
app:singleLineTitle="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -38,14 +38,14 @@ public class DatabaseTest
|
||||
public void setUp()
|
||||
{
|
||||
Activity activity = Robolectric.setupActivity(MainActivity.class);
|
||||
db = new DBHelper(activity);
|
||||
db = TestHelpers.getEmptyDb(activity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addRemoveOneGiftCard()
|
||||
{
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
long id = db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, 0);
|
||||
long id = db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, DEFAULT_HEADER_COLOR, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
@@ -58,8 +58,10 @@ public class DatabaseTest
|
||||
assertEquals(new BigDecimal("0"), loyaltyCard.balance);
|
||||
assertEquals(null, loyaltyCard.balanceType);
|
||||
assertEquals("cardId", loyaltyCard.cardId);
|
||||
assertEquals(null, loyaltyCard.barcodeId);
|
||||
assertEquals(BarcodeFormat.UPC_A, loyaltyCard.barcodeType);
|
||||
assertEquals(DEFAULT_HEADER_COLOR, loyaltyCard.headerColor);
|
||||
assertEquals(0, loyaltyCard.starStatus);
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), loyaltyCard.barcodeType);
|
||||
|
||||
result = db.deleteLoyaltyCard(1);
|
||||
assertTrue(result);
|
||||
@@ -70,12 +72,12 @@ public class DatabaseTest
|
||||
@Test
|
||||
public void updateGiftCard()
|
||||
{
|
||||
long id = db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, 0);
|
||||
long id = db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, DEFAULT_HEADER_COLOR, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
result = db.updateLoyaltyCard(1, "store1", "note1", null, new BigDecimal("10.00"), Currency.getInstance("EUR"), "cardId1", BarcodeFormat.AZTEC.toString(), DEFAULT_HEADER_COLOR);
|
||||
result = db.updateLoyaltyCard(1, "store1", "note1", null, new BigDecimal("10.00"), Currency.getInstance("EUR"), "cardId1", null, BarcodeFormat.AZTEC, DEFAULT_HEADER_COLOR);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
@@ -87,14 +89,16 @@ public class DatabaseTest
|
||||
assertEquals(new BigDecimal("10.00"), loyaltyCard.balance);
|
||||
assertEquals(Currency.getInstance("EUR"), loyaltyCard.balanceType);
|
||||
assertEquals("cardId1", loyaltyCard.cardId);
|
||||
assertEquals(null, loyaltyCard.barcodeId);
|
||||
assertEquals(BarcodeFormat.AZTEC, loyaltyCard.barcodeType);
|
||||
assertEquals(DEFAULT_HEADER_COLOR, loyaltyCard.headerColor);
|
||||
assertEquals(0, loyaltyCard.starStatus);
|
||||
assertEquals(BarcodeFormat.AZTEC.toString(), loyaltyCard.barcodeType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateGiftCardOnlyStar()
|
||||
{
|
||||
long id = db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, 0);
|
||||
long id = db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, DEFAULT_HEADER_COLOR, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
@@ -111,8 +115,10 @@ public class DatabaseTest
|
||||
assertEquals(new BigDecimal("0"), loyaltyCard.balance);
|
||||
assertEquals(null, loyaltyCard.balanceType);
|
||||
assertEquals("cardId", loyaltyCard.cardId);
|
||||
assertEquals(null, loyaltyCard.barcodeId);
|
||||
assertEquals(BarcodeFormat.UPC_A, loyaltyCard.barcodeType);
|
||||
assertEquals(DEFAULT_HEADER_COLOR, loyaltyCard.headerColor);
|
||||
assertEquals(1, loyaltyCard.starStatus);
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), loyaltyCard.barcodeType);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -121,7 +127,7 @@ public class DatabaseTest
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
|
||||
boolean result = db.updateLoyaltyCard(1, "store1", "note1", null, new BigDecimal("0"), null, "cardId1",
|
||||
BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR);
|
||||
null, BarcodeFormat.UPC_A, DEFAULT_HEADER_COLOR);
|
||||
assertEquals(false, result);
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
}
|
||||
@@ -129,7 +135,7 @@ public class DatabaseTest
|
||||
@Test
|
||||
public void emptyGiftCardValues()
|
||||
{
|
||||
long id = db.insertLoyaltyCard("", "", null, new BigDecimal("0"), null, "", "", null, 0);
|
||||
long id = db.insertLoyaltyCard("", "", null, new BigDecimal("0"), null, "", null, null, null, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
@@ -142,7 +148,10 @@ public class DatabaseTest
|
||||
assertEquals(new BigDecimal("0"), loyaltyCard.balance);
|
||||
assertEquals(null, loyaltyCard.balanceType);
|
||||
assertEquals("", loyaltyCard.cardId);
|
||||
assertEquals("", loyaltyCard.barcodeType);
|
||||
assertEquals(null, loyaltyCard.barcodeId);
|
||||
assertEquals(null, loyaltyCard.barcodeType);
|
||||
// headerColor is randomly generated when not given, so skip
|
||||
assertEquals(0, loyaltyCard.starStatus);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -155,7 +164,7 @@ public class DatabaseTest
|
||||
for(int index = CARDS_TO_ADD-1; index >= 0; index--)
|
||||
{
|
||||
long id = db.insertLoyaltyCard("store" + index, "note" + index, null, new BigDecimal("0"), null, "cardId" + index,
|
||||
BarcodeFormat.UPC_A.toString(), index, 0);
|
||||
null, BarcodeFormat.UPC_A, index, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
}
|
||||
@@ -177,9 +186,10 @@ public class DatabaseTest
|
||||
assertEquals("0", cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BALANCE)));
|
||||
assertEquals(null, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BALANCE_TYPE)));
|
||||
assertEquals("cardId"+index, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.CARD_ID)));
|
||||
assertEquals(null, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ID)));
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE)));
|
||||
assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
|
||||
assertEquals(index, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR)));
|
||||
assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
|
||||
|
||||
cursor.moveToNext();
|
||||
}
|
||||
@@ -200,12 +210,12 @@ public class DatabaseTest
|
||||
{
|
||||
if (index == CARDS_TO_ADD-1) {
|
||||
id = db.insertLoyaltyCard("store" + index, "note" + index, null, new BigDecimal("0"), null, "cardId" + index,
|
||||
BarcodeFormat.UPC_A.toString(), index, 1);
|
||||
null, BarcodeFormat.UPC_A, index, 1);
|
||||
}
|
||||
|
||||
else {
|
||||
id = db.insertLoyaltyCard("store" + index, "note" + index, null, new BigDecimal("0"), null, "cardId" + index,
|
||||
BarcodeFormat.UPC_A.toString(), index, 0);
|
||||
null, BarcodeFormat.UPC_A, index, 0);
|
||||
}
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
@@ -226,9 +236,10 @@ public class DatabaseTest
|
||||
assertEquals("0", cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BALANCE)));
|
||||
assertEquals(null, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BALANCE_TYPE)));
|
||||
assertEquals("cardId"+index, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.CARD_ID)));
|
||||
assertEquals(null, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ID)));
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE)));
|
||||
assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
|
||||
assertEquals(index, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR)));
|
||||
assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
|
||||
|
||||
cursor.moveToNext();
|
||||
|
||||
@@ -240,9 +251,10 @@ public class DatabaseTest
|
||||
assertEquals("0", cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BALANCE)));
|
||||
assertEquals(null, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BALANCE_TYPE)));
|
||||
assertEquals("cardId"+index, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.CARD_ID)));
|
||||
assertEquals(null, cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_ID)));
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BARCODE_TYPE)));
|
||||
assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
|
||||
assertEquals(index, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR)));
|
||||
assertEquals(0, cursor.getInt(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.STAR_STATUS)));
|
||||
|
||||
cursor.moveToNext();
|
||||
}
|
||||
@@ -304,7 +316,7 @@ public class DatabaseTest
|
||||
{
|
||||
// Create card
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
long id = db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, 0);
|
||||
long id = db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, DEFAULT_HEADER_COLOR, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
@@ -421,7 +433,7 @@ public class DatabaseTest
|
||||
{
|
||||
// Create card
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
long id = db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, 0);
|
||||
long id = db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, DEFAULT_HEADER_COLOR, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
@@ -473,6 +485,7 @@ public class DatabaseTest
|
||||
|
||||
// Insert a budget and transaction
|
||||
int newCardId = insertCardVersion1(database, "store", "cardId", BarcodeFormat.UPC_A.toString());
|
||||
int newCardId2 = insertCardVersion1(database, "store", "cardId", "");
|
||||
|
||||
// Upgrade database
|
||||
db.onUpgrade(database, DBHelper.ORIGINAL_DATABASE_VERSION, DBHelper.DATABASE_VERSION);
|
||||
@@ -480,14 +493,28 @@ public class DatabaseTest
|
||||
// Determine that the entries are queryable and the fields are correct
|
||||
LoyaltyCard card = db.getLoyaltyCard(newCardId);
|
||||
assertEquals("store", card.store);
|
||||
assertEquals("", card.note);
|
||||
assertEquals(null, card.expiry);
|
||||
assertEquals(new BigDecimal("0"), card.balance);
|
||||
assertEquals(null, card.balanceType);
|
||||
assertEquals("cardId", card.cardId);
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), card.barcodeType);
|
||||
assertEquals("", card.note);
|
||||
assertEquals(null, card.barcodeId);
|
||||
assertEquals(BarcodeFormat.UPC_A, card.barcodeType);
|
||||
assertEquals(null, card.headerColor);
|
||||
assertEquals(null, card.headerTextColor);
|
||||
assertEquals(0, card.starStatus);
|
||||
|
||||
// Determine that the entries are queryable and the fields are correct
|
||||
LoyaltyCard card2 = db.getLoyaltyCard(newCardId2);
|
||||
assertEquals("store", card2.store);
|
||||
assertEquals("", card2.note);
|
||||
assertEquals(null, card2.expiry);
|
||||
assertEquals(new BigDecimal("0"), card2.balance);
|
||||
assertEquals(null, card2.balanceType);
|
||||
assertEquals("cardId", card2.cardId);
|
||||
assertEquals(null, card2.barcodeId);
|
||||
assertEquals(null, card2.barcodeType); // Empty string should've become null
|
||||
assertEquals(null, card2.headerColor);
|
||||
assertEquals(0, card2.starStatus);
|
||||
|
||||
database.close();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
@@ -10,6 +7,7 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.view.View;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.Robolectric;
|
||||
@@ -17,6 +15,9 @@ import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(sdk = 23)
|
||||
public class ImportExportActivityTest
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user