Compare commits

..

1 Commits

Author SHA1 Message Date
Sylvia van Os
65d8d45018 WIP 2022-10-05 21:48:31 +02:00
517 changed files with 1706 additions and 3647 deletions

73
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,73 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches:
- master
pull_request:
# The branches below must be a subset of the branches above
branches:
- master
schedule:
- cron: '33 1 * * 4'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'java' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@@ -1,16 +1,8 @@
# Changelog
## v2.21.1 - 116
- Fix quick spend dialog not allowing , separator
- Support loading image from file manager
## v2.21.0 - 115
## Unreleased - 115
- Open image in gallery on long-press
- Apply Material style to dialogs
- Support creating card by sharing an image to Catima
- Add quick spend button to card screen
## v2.20.0 - 114

View File

@@ -1,9 +1,7 @@
import com.github.spotbugs.snom.SpotBugsTask
plugins {
id 'com.android.application'
id 'com.github.spotbugs'
}
apply plugin: 'com.android.application'
apply plugin: 'com.github.spotbugs'
spotbugs {
ignoreFailures = false
@@ -13,14 +11,15 @@ spotbugs {
}
android {
compileSdk 31
compileSdkVersion 31
buildToolsVersion "31.0.0"
defaultConfig {
applicationId "me.hackerchick.catima"
minSdk 21
targetSdk 31
versionCode 116
versionName "2.21.1"
minSdkVersion 21
targetSdkVersion 31
versionCode 114
versionName "2.20.0"
vectorDrawables.useSupportLibrary true
multiDexEnabled true
@@ -38,10 +37,6 @@ android {
}
}
buildFeatures {
viewBinding true
}
bundle {
language {
enableSplit = false
@@ -59,7 +54,8 @@ android {
}
lintOptions {
lintConfig file("lint.xml")
disable "GoogleAppIndexingWarning", "ButtonStyle", "AlwaysShowAction",
"MissingTranslation", "MissingPrefix"
}
sourceSets {
@@ -98,7 +94,7 @@ dependencies {
// Third-party
implementation 'com.journeyapps:zxing-android-embedded:4.3.0@aar'
implementation 'com.google.zxing:core:3.5.1'
implementation 'com.google.zxing:core:3.5.0'
implementation 'org.apache.commons:commons-csv:1.9.0'
implementation 'com.jaredrummler:colorpicker:1.1.0'
implementation 'com.github.invissvenska:NumberPickerPreference:1.0.4'

View File

@@ -6,8 +6,5 @@
<Match>
<Class name="~.*Manifest\$.*"/>
</Match>
<Match>
<Class name="~.*Binding" />
</Match>
</FindBugsFilter>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="AlwaysShowAction" severity="ignore" />
<issue id="ButtonStyle" severity="ignore" />
<issue id="GoogleAppIndexingWarning" severity="ignore" />
<issue id="MissingTranslation" severity="ignore" />
<issue id="MissingPrefix" severity="ignore" />
</lint>

View File

@@ -33,12 +33,6 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
<activity
android:name=".AboutActivity"
@@ -108,39 +102,7 @@
<activity
android:name=".ImportExportActivity"
android:label="@string/importExport"
android:exported="true"
android:theme="@style/AppTheme.NoActionBar">
<!-- ZIP Intent Filter -->
<intent-filter
android:label="@string/importCards">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/zip" />
<data android:scheme="content"/>
<data android:host="*"/>
</intent-filter>
<!-- JSON Intent Filter -->
<intent-filter
android:label="@string/importCards">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/json" />
<data android:scheme="content"/>
<data android:host="*"/>
</intent-filter>
<!-- CSV Intent Filter -->
<intent-filter
android:label="@string/importCards">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="content"/>
<data android:host="*" />
<data android:mimeType="text/comma-separated-values" />
</intent-filter>
</activity>
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".CardShortcutConfigure"
android:exported="true"

View File

@@ -1,46 +1,138 @@
package protect.card_locker;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.text.HtmlCompat;
import protect.card_locker.databinding.AboutActivityBinding;
public class AboutActivity extends CatimaAppCompatActivity {
public class AboutActivity extends CatimaAppCompatActivity implements View.OnClickListener {
private static final String TAG = "Catima";
private AboutActivityBinding binding;
private AboutContent content;
ConstraintLayout version_history, translate, license, repo, privacy, error, credits, rate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = AboutActivityBinding.inflate(getLayoutInflater());
content = new AboutContent(this);
setTitle(content.getPageTitle());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
enableToolbarBackButton();
setTitle(R.string.about);
setContentView(R.layout.about_activity);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
TextView copyright = binding.creditsSub;
copyright.setText(content.getCopyright());
TextView versionHistory = binding.versionHistorySub;
versionHistory.setText(content.getVersionHistory());
StringBuilder contributors = new StringBuilder().append("<br/>");
binding.versionHistory.setTag("https://catima.app/changelog/");
binding.translate.setTag("https://hosted.weblate.org/engage/catima/");
binding.license.setTag("https://github.com/CatimaLoyalty/Android/blob/master/LICENSE");
binding.repo.setTag("https://github.com/CatimaLoyalty/Android/");
binding.privacy.setTag("https://catima.app/privacy-policy/");
binding.reportError.setTag("https://github.com/CatimaLoyalty/Android/issues");
binding.rate.setTag("https://play.google.com/store/apps/details?id=me.hackerchick.catima");
BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.contributors), StandardCharsets.UTF_8));
bindClickListeners();
try {
while (true) {
String tmp = reader.readLine();
if (tmp == null || tmp.isEmpty()) {
reader.close();
break;
}
contributors.append("<br/>");
contributors.append(tmp);
}
} catch (IOException ignored) {
}
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("NumberPickerPreference", "https://github.com/invissvenska/NumberPickerPreference", "GNU LGPL 3.0"));
USED_LIBRARIES.add(new ThirdPartyInfo("uCrop", "https://github.com/Yalantis/uCrop", "Apache 2.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 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 (ThirdPartyInfo entry : USED_LIBRARIES) {
libs.append("<br/><a href=\"").append(entry.url()).append("\">").append(entry.name()).append("</a> (").append(entry.license()).append(")");
}
StringBuilder resources = new StringBuilder().append("<br/>");
for (ThirdPartyInfo entry : USED_ASSETS) {
resources.append("<br/><a href=\"").append(entry.url()).append("\">").append(entry.name()).append("</a> (").append(entry.license()).append(")");
}
String appName = getString(R.string.app_name);
int year = Calendar.getInstance().get(Calendar.YEAR);
String version = "?";
try {
PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0);
version = pi.versionName;
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Package name not found", e);
}
TextView copyright = findViewById(R.id.credits_sub);
copyright.setText(String.format(getString(R.string.app_copyright_fmt), year));
TextView vHistory = findViewById(R.id.version_history_sub);
vHistory.setText(String.format(getString(R.string.debug_version_fmt), version));
setTitle(String.format(getString(R.string.about_title_fmt), appName));
version_history = findViewById(R.id.version_history);
translate = findViewById(R.id.translate);
license = findViewById(R.id.license);
repo = findViewById(R.id.repo);
privacy = findViewById(R.id.privacy);
error = findViewById(R.id.report_error);
credits = findViewById(R.id.credits);
rate = findViewById(R.id.rate);
version_history.setOnClickListener(this);
translate.setOnClickListener(this);
license.setOnClickListener(this);
repo.setOnClickListener(this);
privacy.setOnClickListener(this);
error.setOnClickListener(this);
rate.setOnClickListener(this);
StringBuilder contributorInfo = new StringBuilder();
contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_contributors), contributors.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT));
contributorInfo.append("\n\n");
contributorInfo.append(getString(R.string.app_copyright_old));
contributorInfo.append("\n\n");
contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_libraries), libs.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT));
contributorInfo.append("\n\n");
contributorInfo.append(HtmlCompat.fromHtml(String.format(getString(R.string.app_resources), resources.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT));
credits.setOnClickListener(view -> new AlertDialog.Builder(this)
.setTitle(R.string.credits)
.setMessage(contributorInfo.toString())
.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
})
.show());
}
@Override
@@ -53,47 +145,36 @@ public class AboutActivity extends CatimaAppCompatActivity {
}
@Override
protected void onDestroy() {
super.onDestroy();
content.destroy();
clearClickListeners();
binding = null;
public void onClick(View view) {
int id = view.getId();
String url;
if (id == R.id.version_history) {
url = "https://catima.app/changelog/";
} else if (id == R.id.translate) {
url = "https://hosted.weblate.org/engage/catima/";
} else if (id == R.id.license) {
url = "https://github.com/CatimaLoyalty/Android/blob/master/LICENSE";
} else if (id == R.id.repo) {
url = "https://github.com/CatimaLoyalty/Android/";
} else if (id == R.id.privacy) {
url = "https://catima.app/privacy-policy/";
} else if (id == R.id.report_error) {
url = "https://github.com/CatimaLoyalty/Android/issues";
} else if (id == R.id.rate) {
url = "https://play.google.com/store/apps/details?id=me.hackerchick.catima";
} else {
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.failedToOpenUrl, Toast.LENGTH_LONG).show();
Log.e(TAG, "No activity found to handle intent", e);
}
}
private void bindClickListeners() {
View.OnClickListener openExternalBrowser = view -> {
Object tag = view.getTag();
if (tag instanceof String && ((String) tag).startsWith("https://")) {
(new OpenWebLinkHandler()).openBrowser(this, (String) tag);
}
};
binding.versionHistory.setOnClickListener(openExternalBrowser);
binding.translate.setOnClickListener(openExternalBrowser);
binding.license.setOnClickListener(openExternalBrowser);
binding.repo.setOnClickListener(openExternalBrowser);
binding.privacy.setOnClickListener(openExternalBrowser);
binding.reportError.setOnClickListener(openExternalBrowser);
binding.rate.setOnClickListener(openExternalBrowser);
binding.credits.setOnClickListener(view -> showCredits());
}
private void clearClickListeners() {
binding.versionHistory.setOnClickListener(null);
binding.translate.setOnClickListener(null);
binding.license.setOnClickListener(null);
binding.repo.setOnClickListener(null);
binding.privacy.setOnClickListener(null);
binding.reportError.setOnClickListener(null);
binding.rate.setOnClickListener(null);
binding.credits.setOnClickListener(null);
}
private void showCredits() {
new MaterialAlertDialogBuilder(this)
.setTitle(R.string.credits)
.setMessage(content.getContributorInfo())
.setPositiveButton(R.string.ok, null)
.show();
}
}

View File

@@ -1,111 +0,0 @@
package protect.card_locker;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import androidx.core.text.HtmlCompat;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class AboutContent {
public static final String TAG = "Catima";
public Context context;
public AboutContent(Context context) {
this.context = context;
}
public void destroy() {
this.context = null;
}
public String getPageTitle() {
return String.format(context.getString(R.string.about_title_fmt), context.getString(R.string.app_name));
}
public String getAppVersion() {
String version = "?";
try {
PackageInfo pi = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
version = pi.versionName;
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Package name not found", e);
}
return version;
}
public int getCurrentYear() {
return Calendar.getInstance().get(Calendar.YEAR);
}
public String getCopyright() {
return String.format(context.getString(R.string.app_copyright_fmt), getCurrentYear());
}
public String getContributors() {
String contributors;
try {
contributors = "<br/>" + Utils.readTextFile(context, R.raw.contributors);
} catch (IOException ignored) {
return "";
}
return contributors.replace("\n", "<br />");
}
public String getThirdPartyLibraries() {
final List<ThirdPartyInfo> usedLibraries = new ArrayList<>();
usedLibraries.add(new ThirdPartyInfo("Color Picker", "https://github.com/jaredrummler/ColorPicker", "Apache 2.0"));
usedLibraries.add(new ThirdPartyInfo("Commons CSV", "https://commons.apache.org/proper/commons-csv/", "Apache 2.0"));
usedLibraries.add(new ThirdPartyInfo("NumberPickerPreference", "https://github.com/invissvenska/NumberPickerPreference", "GNU LGPL 3.0"));
usedLibraries.add(new ThirdPartyInfo("uCrop", "https://github.com/Yalantis/uCrop", "Apache 2.0"));
usedLibraries.add(new ThirdPartyInfo("Zip4j", "https://github.com/srikanth-lingala/zip4j", "Apache 2.0"));
usedLibraries.add(new ThirdPartyInfo("ZXing", "https://github.com/zxing/zxing", "Apache 2.0"));
usedLibraries.add(new ThirdPartyInfo("ZXing Android Embedded", "https://github.com/journeyapps/zxing-android-embedded", "Apache 2.0"));
StringBuilder result = new StringBuilder("<br/>");
for (ThirdPartyInfo entry : usedLibraries) {
result.append("<br/>")
.append(entry.toHtml());
}
return result.toString();
}
public String getUsedThirdPartyAssets() {
final List<ThirdPartyInfo> usedAssets = new ArrayList<>();
usedAssets.add(new ThirdPartyInfo("Android icons", "https://fonts.google.com/icons?selected=Material+Icons", "Apache 2.0"));
StringBuilder result = new StringBuilder().append("<br/>");
for (ThirdPartyInfo entry : usedAssets) {
result.append("<br/>")
.append(entry.toHtml());
}
return result.toString();
}
public String getContributorInfo() {
StringBuilder contributorInfo = new StringBuilder();
contributorInfo.append(HtmlCompat.fromHtml(String.format(context.getString(R.string.app_contributors), getContributors()), HtmlCompat.FROM_HTML_MODE_COMPACT));
contributorInfo.append("\n\n");
contributorInfo.append(context.getString(R.string.app_copyright_old));
contributorInfo.append("\n\n");
contributorInfo.append(HtmlCompat.fromHtml(String.format(context.getString(R.string.app_libraries), getThirdPartyLibraries()), HtmlCompat.FROM_HTML_MODE_COMPACT));
contributorInfo.append("\n\n");
contributorInfo.append(HtmlCompat.fromHtml(String.format(context.getString(R.string.app_resources), getUsedThirdPartyAssets()), HtmlCompat.FROM_HTML_MODE_COMPACT));
return contributorInfo.toString();
}
public String getVersionHistory() {
return String.format(context.getString(R.string.debug_version_fmt), getAppVersion());
}
}

View File

@@ -17,6 +17,7 @@ import com.google.zxing.common.BitMatrix;
import java.lang.ref.WeakReference;
import protect.card_locker.async.CompatCallable;
import protect.card_locker.barcodes.Barcode;
/**
* This task will generate a barcode and load it into an ImageView.
@@ -38,7 +39,7 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private final WeakReference<TextView> textViewReference;
private String cardId;
private final CatimaBarcode format;
private final Barcode format;
private final int imageHeight;
private final int imageWidth;
private final boolean showFallback;
@@ -46,7 +47,7 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
BarcodeImageWriterTask(
Context context, ImageView imageView, String cardIdString,
CatimaBarcode barcodeFormat, TextView textView,
Barcode barcodeFormat, TextView textView,
boolean showFallback, Runnable callback, boolean roundCornerPadding
) {
mContext = context;
@@ -90,68 +91,8 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
this.showFallback = showFallback;
}
private int getMaxWidth(CatimaBarcode format) {
switch (format.format()) {
// 2D barcodes
case AZTEC:
case DATA_MATRIX:
case MAXICODE:
case PDF_417:
case QR_CODE:
return MAX_WIDTH_2D;
// 1D barcodes:
case CODABAR:
case CODE_39:
case CODE_93:
case CODE_128:
case EAN_8:
case EAN_13:
case ITF:
case UPC_A:
case UPC_E:
case RSS_14:
case RSS_EXPANDED:
case UPC_EAN_EXTENSION:
default:
return MAX_WIDTH_1D;
}
}
private String getFallbackString(CatimaBarcode format) {
switch (format.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_93:
return "CODE_93";
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 int getMaxWidth(Barcode format) {
return format.is2D() ? MAX_WIDTH_2D : MAX_WIDTH_1D;
}
private Bitmap generate() {
@@ -227,7 +168,7 @@ public class BarcodeImageWriterTask implements CompatCallable<Bitmap> {
if (showFallback && !Thread.currentThread().isInterrupted()) {
Log.i(TAG, "Barcode generation failed, generating fallback...");
cardId = getFallbackString(format);
cardId = format.exampleValue();
bitmap = generate();
return bitmap;
}

View File

@@ -18,8 +18,9 @@ import java.util.ArrayList;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import protect.card_locker.databinding.BarcodeSelectorActivityBinding;
import protect.card_locker.barcodes.Barcode;
import protect.card_locker.barcodes.BarcodeFactory;
import protect.card_locker.barcodes.BarcodeWithValue;
/**
* This activity is callable and will allow a user to enter
@@ -28,7 +29,6 @@ import protect.card_locker.databinding.BarcodeSelectorActivityBinding;
* data and type will be returned to the caller.
*/
public class BarcodeSelectorActivity extends CatimaAppCompatActivity implements BarcodeSelectorAdapter.BarcodeSelectorListener {
private BarcodeSelectorActivityBinding binding;
private static final String TAG = "Catima";
// Result this activity will return
@@ -43,15 +43,17 @@ public class BarcodeSelectorActivity extends CatimaAppCompatActivity implements
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = BarcodeSelectorActivityBinding.inflate(getLayoutInflater());
setTitle(R.string.selectBarcodeTitle);
setContentView(binding.getRoot());
Toolbar toolbar = binding.toolbar;
setContentView(R.layout.barcode_selector_activity);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
enableToolbarBackButton();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
EditText cardId = binding.cardId;
ListView mBarcodeList = binding.barcodes;
EditText cardId = findViewById(R.id.cardId);
ListView mBarcodeList = findViewById(R.id.barcodes);
mAdapter = new BarcodeSelectorAdapter(this, new ArrayList<>(), this);
mBarcodeList.setAdapter(mAdapter);
@@ -67,7 +69,7 @@ public class BarcodeSelectorActivity extends CatimaAppCompatActivity implements
runOnUiThread(() -> {
generateBarcodes(s.toString());
View noBarcodeButtonView = binding.noBarcode;
View noBarcodeButtonView = findViewById(R.id.noBarcode);
setButtonListener(noBarcodeButtonView, s.toString());
noBarcodeButtonView.setEnabled(s.length() > 0);
});
@@ -87,10 +89,10 @@ public class BarcodeSelectorActivity extends CatimaAppCompatActivity implements
private void generateBarcodes(String value) {
// Update barcodes
ArrayList<CatimaBarcodeWithValue> barcodes = new ArrayList<>();
for (BarcodeFormat barcodeFormat : CatimaBarcode.barcodeFormats) {
CatimaBarcode catimaBarcode = CatimaBarcode.fromBarcode(barcodeFormat);
barcodes.add(new CatimaBarcodeWithValue(catimaBarcode, value));
ArrayList<BarcodeWithValue> barcodes = new ArrayList<>();
for (BarcodeFormat barcodeFormat : BarcodeFactory.getAllFormats()) {
Barcode catimaBarcode = BarcodeFactory.fromBarcode(barcodeFormat);
barcodes.add(new BarcodeWithValue(catimaBarcode, value));
}
mAdapter.setBarcodes(barcodes);
}
@@ -119,7 +121,7 @@ public class BarcodeSelectorActivity extends CatimaAppCompatActivity implements
@Override
public void onRowClicked(int inputPosition, View view) {
CatimaBarcodeWithValue barcodeWithValue = mAdapter.getItem(inputPosition);
BarcodeWithValue barcodeWithValue = mAdapter.getItem(inputPosition);
CatimaBarcode catimaBarcode = barcodeWithValue.catimaBarcode();
if (!mAdapter.isValid(view)) {

View File

@@ -13,9 +13,11 @@ import android.widget.TextView;
import java.util.ArrayList;
import protect.card_locker.async.TaskHandler;
import protect.card_locker.databinding.BarcodeLayoutBinding;
import protect.card_locker.barcodes.Barcode;
import protect.card_locker.barcodes.BarcodeFactory;
import protect.card_locker.barcodes.BarcodeWithValue;
public class BarcodeSelectorAdapter extends ArrayAdapter<CatimaBarcodeWithValue> {
public class BarcodeSelectorAdapter extends ArrayAdapter<BarcodeWithValue> {
private static final String TAG = "Catima";
private final TaskHandler mTasks = new TaskHandler();
@@ -30,12 +32,12 @@ public class BarcodeSelectorAdapter extends ArrayAdapter<CatimaBarcodeWithValue>
void onRowClicked(int inputPosition, View view);
}
public BarcodeSelectorAdapter(Context context, ArrayList<CatimaBarcodeWithValue> barcodes, BarcodeSelectorListener barcodeSelectorListener) {
public BarcodeSelectorAdapter(Context context, ArrayList<BarcodeWithValue> barcodes, BarcodeSelectorListener barcodeSelectorListener) {
super(context, 0, barcodes);
mListener = barcodeSelectorListener;
}
public void setBarcodes(ArrayList<CatimaBarcodeWithValue> barcodes) {
public void setBarcodes(ArrayList<BarcodeWithValue> barcodes) {
clear();
addAll(barcodes);
notifyDataSetChanged();
@@ -44,18 +46,17 @@ public class BarcodeSelectorAdapter extends ArrayAdapter<CatimaBarcodeWithValue>
@Override
public View getView(int position, View convertView, ViewGroup parent) {
CatimaBarcodeWithValue catimaBarcodeWithValue = getItem(position);
CatimaBarcode catimaBarcode = catimaBarcodeWithValue.catimaBarcode();
String value = catimaBarcodeWithValue.value();
BarcodeWithValue barcodeWithValue = getItem(position);
Barcode catimaBarcode = barcodeWithValue.barcode();
String value = barcodeWithValue.value();
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
BarcodeLayoutBinding barcodeLayoutBinding = BarcodeLayoutBinding.inflate(inflater, parent, false);
convertView = barcodeLayoutBinding.getRoot();
viewHolder.image = barcodeLayoutBinding.barcodeImage;
viewHolder.text = barcodeLayoutBinding.barcodeName;
convertView = inflater.inflate(R.layout.barcode_layout, parent, false);
viewHolder.image = convertView.findViewById(R.id.barcodeImage);
viewHolder.text = convertView.findViewById(R.id.barcodeName);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
@@ -75,7 +76,7 @@ public class BarcodeSelectorAdapter extends ArrayAdapter<CatimaBarcodeWithValue>
}
private void createBarcodeOption(final ImageView image, final String formatType, final String cardId, final TextView text) {
final CatimaBarcode format = CatimaBarcode.fromName(formatType);
final Barcode format = BarcodeFactory.fromName(formatType);
image.setImageBitmap(null);
image.setClipToOutline(true);

View File

@@ -14,13 +14,10 @@ import androidx.core.content.pm.ShortcutManagerCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import protect.card_locker.databinding.SimpleToolbarListActivityBinding;
/**
* The configuration screen for creating a shortcut.
*/
public class CardShortcutConfigure extends CatimaAppCompatActivity implements LoyaltyCardCursorAdapter.CardAdapterListener {
private SimpleToolbarListActivityBinding binding;
static final String TAG = "Catima";
private SQLiteDatabase mDatabase;
private LoyaltyCardCursorAdapter mAdapter;
@@ -28,15 +25,15 @@ public class CardShortcutConfigure extends CatimaAppCompatActivity implements Lo
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
binding = SimpleToolbarListActivityBinding.inflate(getLayoutInflater());
mDatabase = new DBHelper(this).getReadableDatabase();
// Set the result to CANCELED. This will cause nothing to happen if the
// aback button is pressed.
setResult(RESULT_CANCELED);
setContentView(binding.getRoot());
Toolbar toolbar = binding.toolbar;
setContentView(R.layout.simple_toolbar_list_activity);
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(R.string.shortcutSelectCard);
setSupportActionBar(toolbar);
@@ -53,7 +50,7 @@ public class CardShortcutConfigure extends CatimaAppCompatActivity implements Lo
finish();
}
final RecyclerView cardList = binding.list;
final RecyclerView cardList = findViewById(R.id.list);
GridLayoutManager layoutManager = (GridLayoutManager) cardList.getLayoutManager();
if (layoutManager != null) {
layoutManager.setSpanCount(getResources().getInteger(R.integer.main_view_card_columns));

View File

@@ -137,7 +137,7 @@ public class CardsOnPowerScreenService extends ControlsProviderService {
closePowerScreenOnAndroid11();
}
@SuppressWarnings({"MissingPermission", "deprecation"})
@SuppressLint({"MissingPermission", "deprecation"})
private void closePowerScreenOnAndroid11() {
// Android 12 will auto-close the power screen, but earlier versions won't
// Lint complains about this but on Android 11 the permission is not needed

View File

@@ -7,9 +7,7 @@ import android.os.Bundle;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.WindowInsetsControllerCompat;
public class CatimaAppCompatActivity extends AppCompatActivity {
@Override
@@ -31,10 +29,8 @@ public class CatimaAppCompatActivity extends AppCompatActivity {
// XXX changing this in onCreate causes issues with the splash screen activity, so doing this here
boolean darkMode = Utils.isDarkModeEnabled(this);
if (Build.VERSION.SDK_INT >= 23) {
View decorView = getWindow().getDecorView();
WindowInsetsControllerCompat wic = new WindowInsetsControllerCompat(getWindow(), decorView);
wic.setAppearanceLightStatusBars(!darkMode);
getWindow().setStatusBarColor(Color.TRANSPARENT);
getWindow().getDecorView().setSystemUiVisibility(darkMode ? 0 : View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
// icons are always white back then
getWindow().setStatusBarColor(darkMode ? Color.TRANSPARENT : Color.argb(127, 0, 0, 0));
@@ -42,11 +38,4 @@ public class CatimaAppCompatActivity extends AppCompatActivity {
// XXX android 9 and below has a nasty rendering bug if the theme was patched earlier
Utils.postPatchColors(this);
}
protected void enableToolbarBackButton() {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
}

View File

@@ -1,97 +0,0 @@
package protect.card_locker;
import com.google.zxing.BarcodeFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class CatimaBarcode {
public static final List<BarcodeFormat> barcodeFormats = Collections.unmodifiableList(Arrays.asList(
BarcodeFormat.AZTEC,
BarcodeFormat.CODE_39,
BarcodeFormat.CODE_93,
BarcodeFormat.CODE_128,
BarcodeFormat.CODABAR,
BarcodeFormat.DATA_MATRIX,
BarcodeFormat.EAN_8,
BarcodeFormat.EAN_13,
BarcodeFormat.ITF,
BarcodeFormat.PDF_417,
BarcodeFormat.QR_CODE,
BarcodeFormat.UPC_A,
BarcodeFormat.UPC_E
));
public static final List<String> barcodePrettyNames = Collections.unmodifiableList(Arrays.asList(
"Aztec",
"Code 39",
"Code 93",
"Code 128",
"Codabar",
"Data Matrix",
"EAN 8",
"EAN 13",
"ITF",
"PDF 417",
"QR Code",
"UPC A",
"UPC E"
));
private final BarcodeFormat mBarcodeFormat;
private CatimaBarcode(BarcodeFormat barcodeFormat) {
mBarcodeFormat = barcodeFormat;
}
public static CatimaBarcode fromBarcode(BarcodeFormat barcodeFormat) {
return new CatimaBarcode(barcodeFormat);
}
public static CatimaBarcode fromName(String name) {
return new CatimaBarcode(BarcodeFormat.valueOf(name));
}
public static CatimaBarcode fromPrettyName(String prettyName) {
try {
return new CatimaBarcode(barcodeFormats.get(barcodePrettyNames.indexOf(prettyName)));
} catch (IndexOutOfBoundsException e) {
throw new IllegalArgumentException("No barcode type with pretty name " + prettyName + " known!");
}
}
public boolean isSupported() {
return barcodeFormats.contains(mBarcodeFormat);
}
public boolean isSquare() {
return mBarcodeFormat == BarcodeFormat.AZTEC
|| mBarcodeFormat == BarcodeFormat.DATA_MATRIX
|| mBarcodeFormat == BarcodeFormat.MAXICODE
|| mBarcodeFormat == BarcodeFormat.QR_CODE;
}
public boolean hasInternalPadding() {
return mBarcodeFormat == BarcodeFormat.PDF_417
|| mBarcodeFormat == BarcodeFormat.QR_CODE;
}
public BarcodeFormat format() {
return mBarcodeFormat;
}
public String name() {
return mBarcodeFormat.name();
}
public String prettyName() {
int index = barcodeFormats.indexOf(mBarcodeFormat);
if (index == -1 || index >= barcodePrettyNames.size()) {
return mBarcodeFormat.name();
}
return barcodePrettyNames.get(index);
}
}

View File

@@ -1,19 +0,0 @@
package protect.card_locker;
public class CatimaBarcodeWithValue {
private final CatimaBarcode mCatimaBarcode;
private final String mValue;
public CatimaBarcodeWithValue(CatimaBarcode catimaBarcode, String value) {
mCatimaBarcode = catimaBarcode;
mValue = value;
}
public CatimaBarcode catimaBarcode() {
return mCatimaBarcode;
}
public String value() {
return mValue;
}
}

View File

@@ -18,6 +18,8 @@ import java.util.Currency;
import java.util.Date;
import java.util.List;
import protect.card_locker.barcodes.Barcode;
public class DBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Catima.db";
public static final int ORIGINAL_DATABASE_VERSION = 1;
@@ -360,7 +362,7 @@ public class DBHelper extends SQLiteOpenHelper {
public static long insertLoyaltyCard(
final SQLiteDatabase database, final String store, final String note, final Date expiry,
final BigDecimal balance, final Currency balanceType, final String cardId,
final String barcodeId, final CatimaBarcode barcodeType, final Integer headerColor,
final String barcodeId, final Barcode barcodeType, final Integer headerColor,
final int starStatus, final Long lastUsed, final int archiveStatus) {
database.beginTransaction();
@@ -392,7 +394,7 @@ public class DBHelper extends SQLiteOpenHelper {
public static long insertLoyaltyCard(
final SQLiteDatabase database, final int id, final String store, final String note,
final Date expiry, final BigDecimal balance, final Currency balanceType,
final String cardId, final String barcodeId, final CatimaBarcode barcodeType,
final String cardId, final String barcodeId, final Barcode barcodeType,
final Integer headerColor, final int starStatus, final Long lastUsed, final int archiveStatus) {
database.beginTransaction();
@@ -425,7 +427,7 @@ public class DBHelper extends SQLiteOpenHelper {
public static boolean updateLoyaltyCard(
SQLiteDatabase database, final int id, final String store, final String note,
final Date expiry, final BigDecimal balance, final Currency balanceType,
final String cardId, final String barcodeId, final CatimaBarcode barcodeType,
final String cardId, final String barcodeId, final Barcode barcodeType,
final Integer headerColor, final int starStatus, final Long lastUsed, final int archiveStatus) {
database.beginTransaction();
@@ -494,15 +496,6 @@ public class DBHelper extends SQLiteOpenHelper {
return (rowsUpdated == 1);
}
public static boolean updateLoyaltyCardBalance(SQLiteDatabase database, final int id, final BigDecimal newBalance) {
ContentValues contentValues = new ContentValues();
contentValues.put(LoyaltyCardDbIds.BALANCE, newBalance.toString());
int rowsUpdated = database.update(LoyaltyCardDbIds.TABLE, contentValues,
whereAttrs(LoyaltyCardDbIds.ID),
withArgs(id));
return (rowsUpdated == 1);
}
public static LoyaltyCard getLoyaltyCard(SQLiteDatabase database, final int id) {
Cursor data = database.query(LoyaltyCardDbIds.TABLE, null, whereAttrs(LoyaltyCardDbIds.ID), withArgs(id), null, null, null);

View File

@@ -7,13 +7,11 @@ import android.database.sqlite.SQLiteDatabase;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatImageButton;
import androidx.recyclerview.widget.RecyclerView;
import protect.card_locker.databinding.GroupLayoutBinding;
import protect.card_locker.preferences.Settings;
public class GroupCursorAdapter extends BaseCursorAdapter<GroupCursorAdapter.GroupListItemViewHolder> {
@@ -35,14 +33,9 @@ public class GroupCursorAdapter extends BaseCursorAdapter<GroupCursorAdapter.Gro
@NonNull
@Override
public GroupCursorAdapter.GroupListItemViewHolder onCreateViewHolder(@NonNull ViewGroup inputParent, int inputViewType) {
return new GroupListItemViewHolder(
GroupLayoutBinding.inflate(
LayoutInflater.from(inputParent.getContext()),
inputParent,
false
)
);
public GroupCursorAdapter.GroupListItemViewHolder onCreateViewHolder(ViewGroup inputParent, int inputViewType) {
View itemView = LayoutInflater.from(inputParent.getContext()).inflate(R.layout.group_layout, inputParent, false);
return new GroupListItemViewHolder(itemView);
}
public void onBindViewHolder(GroupListItemViewHolder inputHolder, Cursor inputCursor) {
@@ -88,16 +81,16 @@ public class GroupCursorAdapter extends BaseCursorAdapter<GroupCursorAdapter.Gro
public static class GroupListItemViewHolder extends RecyclerView.ViewHolder {
public TextView mName, mCardCount;
public ImageButton mMoveUp, mMoveDown, mEdit, mDelete;
public AppCompatImageButton mMoveUp, mMoveDown, mEdit, mDelete;
public GroupListItemViewHolder(GroupLayoutBinding groupLayoutBinding) {
super(groupLayoutBinding.getRoot());
mName = groupLayoutBinding.name;
mCardCount = groupLayoutBinding.cardCount;
mMoveUp = groupLayoutBinding.moveUp;
mMoveDown = groupLayoutBinding.moveDown;
mEdit = groupLayoutBinding.edit;
mDelete = groupLayoutBinding.delete;
public GroupListItemViewHolder(View inputView) {
super(inputView);
mName = inputView.findViewById(R.id.name);
mCardCount = inputView.findViewById(R.id.cardCount);
mMoveUp = inputView.findViewById(R.id.moveUp);
mMoveDown = inputView.findViewById(R.id.moveDown);
mEdit = inputView.findViewById(R.id.edit);
mDelete = inputView.findViewById(R.id.delete);
}
}
}

View File

@@ -24,23 +24,17 @@ import java.util.List;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import protect.card_locker.async.TaskHandler;
import protect.card_locker.databinding.ImportExportActivityBinding;
import protect.card_locker.importexport.DataFormat;
import protect.card_locker.importexport.ImportExportResult;
import protect.card_locker.importexport.ImportExportResultType;
public class ImportExportActivity extends CatimaAppCompatActivity {
private ImportExportActivityBinding binding;
private static final String TAG = "Catima";
private static final int PERMISSIONS_EXTERNAL_STORAGE = 1;
@@ -61,12 +55,14 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ImportExportActivityBinding.inflate(getLayoutInflater());
setTitle(R.string.importExport);
setContentView(binding.getRoot());
Toolbar toolbar = binding.toolbar;
setContentView(R.layout.import_export_activity);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
enableToolbarBackButton();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
// If the application does not have permissions to external
// storage, ask for it now
@@ -81,11 +77,6 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
PERMISSIONS_EXTERNAL_STORAGE);
}
Intent fileIntent = getIntent();
if (fileIntent != null && fileIntent.getType() != null) {
chooseImportType(false, fileIntent.getData());
}
// would use ActivityResultContracts.CreateDocument() but mime type cannot be set
fileCreateLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
Intent intent = result.getData();
@@ -135,9 +126,9 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
intentCreateDocumentAction.setType("application/zip");
intentCreateDocumentAction.putExtra(Intent.EXTRA_TITLE, "catima.zip");
Button exportButton = binding.exportButton;
Button exportButton = findViewById(R.id.exportButton);
exportButton.setOnClickListener(v -> {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(ImportExportActivity.this);
AlertDialog.Builder builder = new AlertDialog.Builder(ImportExportActivity.this);
builder.setTitle(R.string.exportPassword);
FrameLayout container = new FrameLayout(ImportExportActivity.this);
@@ -167,12 +158,12 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
});
// Check that there is a file manager available
Button importFilesystem = binding.importOptionFilesystemButton;
importFilesystem.setOnClickListener(v -> chooseImportType(false, null));
Button importFilesystem = findViewById(R.id.importOptionFilesystemButton);
importFilesystem.setOnClickListener(v -> chooseImportType(false));
// Check that there is an app that data can be imported from
Button importApplication = binding.importOptionApplicationButton;
importApplication.setOnClickListener(v -> chooseImportType(true, null));
Button importApplication = findViewById(R.id.importOptionApplicationButton);
importApplication.setOnClickListener(v -> chooseImportType(true));
}
private void openFileForImport(Uri uri, char[] password) {
@@ -186,9 +177,7 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
}
}
private void chooseImportType(boolean choosePicker,
@Nullable Uri fileData) {
private void chooseImportType(boolean choosePicker) {
List<CharSequence> betaImportOptions = new ArrayList<>();
betaImportOptions.add("Fidme");
betaImportOptions.add("Stocard");
@@ -202,7 +191,7 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
importOptions.add(importOption);
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.chooseImportType)
.setItems(importOptions.toArray(new CharSequence[importOptions.size()]), (dialog, which) -> {
switch (which) {
@@ -240,12 +229,7 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
throw new IllegalArgumentException("Unknown DataFormat");
}
if (fileData != null) {
openFileForImport(fileData, null);
return;
}
new MaterialAlertDialogBuilder(this)
new AlertDialog.Builder(this)
.setTitle(importAlertTitle)
.setMessage(importAlertMessage)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@@ -356,7 +340,7 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
}
private void retryWithPassword(DataFormat dataFormat, Uri uri) {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.passwordRequired);
final EditText input = new EditText(this);
@@ -399,7 +383,7 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
return;
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(resultType == ImportExportResultType.Success ? R.string.importSuccessfulTitle : R.string.importFailedTitle);
builder.setMessage(buildResultDialogMessage(result, true));
builder.setNeutralButton(R.string.ok, (dialog, which) -> dialog.dismiss());
@@ -410,7 +394,7 @@ public class ImportExportActivity extends CatimaAppCompatActivity {
private void onExportComplete(ImportExportResult result, final Uri path) {
ImportExportResultType resultType = result.resultType();
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(resultType == ImportExportResultType.Success ? R.string.exportSuccessfulTitle : R.string.exportFailedTitle);
builder.setMessage(buildResultDialogMessage(result, false));
builder.setNeutralButton(R.string.ok, (dialog, which) -> dialog.dismiss());

View File

@@ -15,6 +15,9 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import protect.card_locker.barcodes.Barcode;
import protect.card_locker.barcodes.BarcodeFactory;
public class ImportURIHelper {
private static final String STORE = DBHelper.LoyaltyCardDbIds.STORE;
private static final String NOTE = DBHelper.LoyaltyCardDbIds.NOTE;
@@ -61,7 +64,7 @@ public class ImportURIHelper {
try {
// These values are allowed to be null
CatimaBarcode barcodeType = null;
Barcode barcodeType = null;
Date expiry = null;
BigDecimal balance = new BigDecimal("0");
Currency balanceType = null;
@@ -95,7 +98,7 @@ public class ImportURIHelper {
String unparsedBarcodeType = kv.get(BARCODE_TYPE);
if (unparsedBarcodeType != null && !unparsedBarcodeType.equals("")) {
barcodeType = CatimaBarcode.fromName(unparsedBarcodeType);
barcodeType = BarcodeFactory.fromName(unparsedBarcodeType);
}
String unparsedBalance = kv.get(BALANCE);

View File

@@ -9,6 +9,8 @@ import java.util.Currency;
import java.util.Date;
import androidx.annotation.Nullable;
import protect.card_locker.barcodes.Barcode;
import protect.card_locker.barcodes.BarcodeFactory;
public class LoyaltyCard implements Parcelable {
public final int id;
@@ -23,7 +25,7 @@ public class LoyaltyCard implements Parcelable {
public final String barcodeId;
@Nullable
public final CatimaBarcode barcodeType;
public final Barcode barcodeType;
@Nullable
public final Integer headerColor;
@@ -35,7 +37,7 @@ public class LoyaltyCard implements Parcelable {
public LoyaltyCard(final int id, final String store, final String note, final Date expiry,
final BigDecimal balance, final Currency balanceType, final String cardId,
@Nullable final String barcodeId, @Nullable final CatimaBarcode barcodeType,
@Nullable final String barcodeId, @Nullable final Barcode barcodeType,
@Nullable final Integer headerColor, final int starStatus,
final long lastUsed, final int zoomLevel, final int archiveStatus) {
this.id = id;
@@ -65,7 +67,7 @@ public class LoyaltyCard implements Parcelable {
cardId = in.readString();
barcodeId = in.readString();
String tmpBarcodeType = in.readString();
barcodeType = !tmpBarcodeType.isEmpty() ? CatimaBarcode.fromName(tmpBarcodeType) : null;
barcodeType = !tmpBarcodeType.isEmpty() ? BarcodeFactory.fromName(tmpBarcodeType) : null;
int tmpHeaderColor = in.readInt();
headerColor = tmpHeaderColor != -1 ? tmpHeaderColor : null;
starStatus = in.readInt();
@@ -109,13 +111,13 @@ public class LoyaltyCard implements Parcelable {
int balanceTypeColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.BALANCE_TYPE);
int headerColorColumn = cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbIds.HEADER_COLOR);
CatimaBarcode barcodeType = null;
Barcode barcodeType = null;
Currency balanceType = null;
Date expiry = null;
Integer headerColor = null;
if (cursor.isNull(barcodeTypeColumn) == false) {
barcodeType = CatimaBarcode.fromName(cursor.getString(barcodeTypeColumn));
barcodeType = BarcodeFactory.fromName(cursor.getString(barcodeTypeColumn));
}
if (cursor.isNull(balanceTypeColumn) == false) {

View File

@@ -17,20 +17,17 @@ import android.widget.ImageView;
import android.widget.TextView;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.color.MaterialColors;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Currency;
import java.util.Date;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.BlendModeColorFilterCompat;
import androidx.core.graphics.BlendModeCompat;
import androidx.recyclerview.widget.RecyclerView;
import protect.card_locker.databinding.LoyaltyCardLayoutBinding;
import protect.card_locker.preferences.Settings;
public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCursorAdapter.LoyaltyCardListItemViewHolder> {
@@ -85,15 +82,10 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
return mShowDetails;
}
@NonNull
@Override
public LoyaltyCardListItemViewHolder onCreateViewHolder(@NonNull ViewGroup inputParent, int inputViewType) {
LoyaltyCardLayoutBinding loyaltyCardLayoutBinding = LoyaltyCardLayoutBinding.inflate(
LayoutInflater.from(inputParent.getContext()),
inputParent,
false
);
return new LoyaltyCardListItemViewHolder(loyaltyCardLayoutBinding, mListener);
public LoyaltyCardListItemViewHolder onCreateViewHolder(ViewGroup inputParent, int inputViewType) {
View itemView = LayoutInflater.from(inputParent.getContext()).inflate(R.layout.loyalty_card_layout, inputParent, false);
return new LoyaltyCardListItemViewHolder(itemView, mListener);
}
public LoyaltyCard getCard(int position) {
@@ -115,15 +107,15 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
}
if (mShowDetails && !loyaltyCard.balance.equals(new BigDecimal("0"))) {
inputHolder.setExtraField(inputHolder.mBalanceField, Utils.formatBalance(mContext, loyaltyCard.balance, loyaltyCard.balanceType), null);
inputHolder.setBalanceField(loyaltyCard.balance, loyaltyCard.balanceType);
} else {
inputHolder.setExtraField(inputHolder.mBalanceField, null, null);
inputHolder.setBalanceField(null, null);
}
if (mShowDetails && loyaltyCard.expiry != null) {
inputHolder.setExtraField(inputHolder.mExpiryField, DateFormat.getDateInstance(DateFormat.LONG).format(loyaltyCard.expiry), Utils.hasExpired(loyaltyCard.expiry) ? Color.RED : null);
inputHolder.setExpiryField(loyaltyCard.expiry);
} else {
inputHolder.setExtraField(inputHolder.mExpiryField, null, null);
inputHolder.setExpiryField(null);
}
setHeaderHeight(inputHolder, mShowDetails);
@@ -245,23 +237,22 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
protected LoyaltyCardListItemViewHolder(LoyaltyCardLayoutBinding loyaltyCardLayoutBinding, CardAdapterListener inputListener) {
super(loyaltyCardLayoutBinding.getRoot());
View inputView = loyaltyCardLayoutBinding.getRoot();
mRow = loyaltyCardLayoutBinding.row;
mDivider = loyaltyCardLayoutBinding.infoDivider;
mStoreField = loyaltyCardLayoutBinding.store;
mNoteField = loyaltyCardLayoutBinding.note;
mBalanceField = loyaltyCardLayoutBinding.balance;
mExpiryField = loyaltyCardLayoutBinding.expiry;
mIconLayout = loyaltyCardLayoutBinding.iconLayout;
mCardIcon = loyaltyCardLayoutBinding.thumbnail;
mStar = loyaltyCardLayoutBinding.star;
mStarBackground = loyaltyCardLayoutBinding.starBackground;
mStarBorder = loyaltyCardLayoutBinding.starBorder;
mArchived = loyaltyCardLayoutBinding.archivedIcon;
mArchivedBackground = loyaltyCardLayoutBinding.archiveBackground;
mTickIcon = loyaltyCardLayoutBinding.selectedThumbnail;
protected LoyaltyCardListItemViewHolder(View inputView, CardAdapterListener inputListener) {
super(inputView);
mRow = inputView.findViewById(R.id.row);
mDivider = inputView.findViewById(R.id.info_divider);
mStoreField = inputView.findViewById(R.id.store);
mNoteField = inputView.findViewById(R.id.note);
mBalanceField = inputView.findViewById(R.id.balance);
mExpiryField = inputView.findViewById(R.id.expiry);
mIconLayout = inputView.findViewById(R.id.icon_layout);
mCardIcon = inputView.findViewById(R.id.thumbnail);
mStar = inputView.findViewById(R.id.star);
mStarBackground = inputView.findViewById(R.id.star_background);
mStarBorder = inputView.findViewById(R.id.star_border);
mArchived = inputView.findViewById(R.id.archivedIcon);
mArchivedBackground = inputView.findViewById(R.id.archive_background);
mTickIcon = inputView.findViewById(R.id.selected_thumbnail);
inputView.setOnLongClickListener(view -> {
inputListener.onRowClicked(getAdapterPosition());
inputView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
@@ -269,41 +260,6 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
});
}
private void setExtraField(TextView field, String text, Integer color) {
// If text is null, hide the field
// If iconColor is null, use the default text and icon color based on theme
if (text == null) {
field.setVisibility(View.GONE);
field.requestLayout();
return;
}
int size = mSettings.getFontSizeMax(mSettings.getSmallFont());
field.setVisibility(View.VISIBLE);
field.setText(text);
field.setTextSize(size);
field.setTextColor(color != null ? color : MaterialColors.getColor(mContext, R.attr.colorSecondary, ContextCompat.getColor(mContext, mDarkModeEnabled ? R.color.md_theme_dark_secondary : R.color.md_theme_light_secondary)));
int drawableSize = dpToPx((size * 24) / 14, mContext);
mDivider.setVisibility(View.VISIBLE);
field.setVisibility(View.VISIBLE);
Drawable icon = field.getCompoundDrawables()[0];
if (icon != null) {
icon.mutate();
icon.setBounds(0, 0, drawableSize, drawableSize);
field.setCompoundDrawablesRelative(icon, null, null, null);
if (color != null) {
icon.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_ATOP));
} else {
icon.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(mDarkModeEnabled ? Color.WHITE : Color.BLACK, BlendModeCompat.SRC_ATOP));
}
}
field.requestLayout();
}
public void setStoreField(String text) {
mStoreField.setText(text);
mStoreField.setTextSize(mSettings.getFontSizeMax(mSettings.getMediumFont()));
@@ -321,6 +277,55 @@ public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCurso
mNoteField.requestLayout();
}
public void setBalanceField(BigDecimal balance, Currency balanceType) {
if (balance == null) {
mBalanceField.setVisibility(View.GONE);
} else {
int size = mSettings.getFontSizeMax(mSettings.getSmallFont());
int drawableSize = dpToPx((size * 24) / 14, mContext);
mDivider.setVisibility(View.VISIBLE);
mBalanceField.setVisibility(View.VISIBLE);
Drawable balanceIcon = mBalanceField.getCompoundDrawables()[0];
if (balanceIcon != null) {
balanceIcon.setBounds(0, 0, drawableSize, drawableSize);
mBalanceField.setCompoundDrawablesRelative(balanceIcon, null, null, null);
if (mDarkModeEnabled) {
balanceIcon.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(Color.WHITE, BlendModeCompat.SRC_ATOP));
}
}
mBalanceField.setText(Utils.formatBalance(mContext, balance, balanceType));
mBalanceField.setTextSize(size);
}
mBalanceField.requestLayout();
}
public void setExpiryField(Date expiry) {
if (expiry == null) {
mExpiryField.setVisibility(View.GONE);
} else {
int size = mSettings.getFontSizeMax(mSettings.getSmallFont());
int drawableSize = dpToPx((size * 24) / 14, mContext);
mDivider.setVisibility(View.VISIBLE);
mExpiryField.setVisibility(View.VISIBLE);
Drawable expiryIcon = mExpiryField.getCompoundDrawables()[0];
if (expiryIcon != null) {
expiryIcon.setBounds(0, 0, drawableSize, drawableSize);
mExpiryField.setCompoundDrawablesRelative(expiryIcon, null, null, null);
if (Utils.hasExpired(expiry)) {
expiryIcon.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(Color.RED, BlendModeCompat.SRC_ATOP));
} else if (mDarkModeEnabled) {
expiryIcon.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(Color.WHITE, BlendModeCompat.SRC_ATOP));
}
}
mExpiryField.setText(DateFormat.getDateInstance(DateFormat.LONG).format(expiry));
if (Utils.hasExpired(expiry)) {
mExpiryField.setTextColor(Color.RED);
}
mExpiryField.setTextSize(size);
}
mExpiryField.requestLayout();
}
public void toggleCardStateIcon(boolean enableStar, boolean enableArchive, boolean colorByTheme) {
/* the below code does not work in android 5! hence the change of drawable instead
boolean needDarkForeground = Utils.needsDarkForeground(mIconBackgroundColor);

View File

@@ -20,7 +20,6 @@ import android.os.LocaleList;
import android.text.Editable;
import android.text.InputType;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -38,7 +37,6 @@ import android.widget.Toast;
import com.google.android.material.chip.Chip;
import com.google.android.material.chip.ChipGroup;
import com.google.android.material.color.MaterialColors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;
@@ -59,7 +57,6 @@ import java.util.Calendar;
import java.util.Collections;
import java.util.Currency;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -80,11 +77,10 @@ import androidx.core.content.FileProvider;
import androidx.exifinterface.media.ExifInterface;
import androidx.fragment.app.DialogFragment;
import protect.card_locker.async.TaskHandler;
import protect.card_locker.databinding.LayoutChipChoiceBinding;
import protect.card_locker.databinding.LoyaltyCardEditActivityBinding;
import protect.card_locker.barcodes.Barcode;
import protect.card_locker.barcodes.BarcodeFactory;
public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
private LoyaltyCardEditActivityBinding binding;
private static final String TAG = "Catima";
private final String STATE_TAB_INDEX = "savedTab";
@@ -210,7 +206,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
(Currency) (fieldName == LoyaltyCardField.balanceType ? value : loyaltyCard.balanceType),
(String) (fieldName == LoyaltyCardField.cardId ? value : loyaltyCard.cardId),
(String) (fieldName == LoyaltyCardField.barcodeId ? value : loyaltyCard.barcodeId),
(CatimaBarcode) (fieldName == LoyaltyCardField.barcodeType ? value : loyaltyCard.barcodeType),
(Barcode) (fieldName == LoyaltyCardField.barcodeType ? value : loyaltyCard.barcodeType),
(Integer) (fieldName == LoyaltyCardField.headerColor ? value : loyaltyCard.headerColor),
(int) (fieldName == LoyaltyCardField.starStatus ? value : loyaltyCard.starStatus),
0, // Unimportant, always set to null in doSave so the DB updates it to the current timestamp
@@ -250,7 +246,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
@Override
public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
tabs = binding.tabs;
tabs = findViewById(R.id.tabs);
savedInstanceState.putInt(STATE_TAB_INDEX, tabs.getSelectedTabPosition());
savedInstanceState.putParcelable(STATE_TEMP_CARD, tempLoyaltyCard);
savedInstanceState.putInt(STATE_REQUESTED_IMAGE, mRequestedImage);
@@ -287,7 +283,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
public void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
tempLoyaltyCard = savedInstanceState.getParcelable(STATE_TEMP_CARD);
super.onRestoreInstanceState(savedInstanceState);
tabs = binding.tabs;
tabs = findViewById(R.id.tabs);
tabs.selectTab(tabs.getTabAt(savedInstanceState.getInt(STATE_TAB_INDEX)));
mRequestedImage = savedInstanceState.getInt(STATE_REQUESTED_IMAGE);
mFrontImageUnsaved = savedInstanceState.getInt(STATE_FRONT_IMAGE_UNSAVED) == 1;
@@ -303,11 +299,14 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = LoyaltyCardEditActivityBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
toolbar = binding.toolbar;
setContentView(R.layout.loyalty_card_edit_activity);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
enableToolbarBackButton();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
mDatabase = new DBHelper(this).getWritableDatabase();
@@ -319,28 +318,28 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
currencies.put(currency.getSymbol(), currency);
}
tabs = binding.tabs;
thumbnail = binding.thumbnail;
thumbnailEditIcon = binding.thumbnailEditIcon;
storeFieldEdit = binding.storeNameEdit;
noteFieldEdit = binding.noteEdit;
groupsChips = binding.groupChips;
expiryField = binding.expiryField;
balanceField = binding.balanceField;
balanceCurrencyField = binding.balanceCurrencyField;
cardIdFieldView = binding.cardIdView;
barcodeIdField = binding.barcodeIdField;
barcodeTypeField = binding.barcodeTypeField;
barcodeImage = binding.barcode;
tabs = findViewById(R.id.tabs);
thumbnail = findViewById(R.id.thumbnail);
thumbnailEditIcon = findViewById(R.id.thumbnailEditIcon);
storeFieldEdit = findViewById(R.id.storeNameEdit);
noteFieldEdit = findViewById(R.id.noteEdit);
groupsChips = findViewById(R.id.groupChips);
expiryField = findViewById(R.id.expiryField);
balanceField = findViewById(R.id.balanceField);
balanceCurrencyField = findViewById(R.id.balanceCurrencyField);
cardIdFieldView = findViewById(R.id.cardIdView);
barcodeIdField = findViewById(R.id.barcodeIdField);
barcodeTypeField = findViewById(R.id.barcodeTypeField);
barcodeImage = findViewById(R.id.barcode);
barcodeImage.setClipToOutline(true);
barcodeImageLayout = binding.barcodeLayout;
barcodeCaptureLayout = binding.barcodeCaptureLayout;
cardImageFrontHolder = binding.frontImageHolder;
cardImageBackHolder = binding.backImageHolder;
cardImageFront = binding.frontImage;
cardImageBack = binding.backImage;
barcodeImageLayout = findViewById(R.id.barcodeLayout);
barcodeCaptureLayout = findViewById(R.id.barcodeCaptureLayout);
cardImageFrontHolder = findViewById(R.id.frontImageHolder);
cardImageBackHolder = findViewById(R.id.backImageHolder);
cardImageFront = findViewById(R.id.frontImage);
cardImageBack = findViewById(R.id.backImage);
enterButton = binding.enterButton;
enterButton = findViewById(R.id.enterButton);
barcodeImageGenerationFinishedCallback = () -> {
if (!(boolean) barcodeImage.getTag()) {
@@ -512,7 +511,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
barcodeIdField.setText(lastValue);
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(LoyaltyCardEditActivity.this);
AlertDialog.Builder builder = new AlertDialog.Builder(LoyaltyCardEditActivity.this);
builder.setTitle(R.string.setBarcodeId);
final EditText input = new EditText(LoyaltyCardEditActivity.this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
@@ -556,13 +555,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
updateTempState(LoyaltyCardField.barcodeType, null);
} else {
try {
CatimaBarcode barcodeFormat = CatimaBarcode.fromPrettyName(s.toString());
updateTempState(LoyaltyCardField.barcodeType, barcodeFormat);
if (!barcodeFormat.isSupported()) {
Toast.makeText(LoyaltyCardEditActivity.this, getString(R.string.unsupportedBarcodeType), Toast.LENGTH_LONG).show();
}
updateTempState(LoyaltyCardField.barcodeType, barcodeTypeField.getTag());
} catch (IllegalArgumentException e) {
}
}
@@ -823,7 +816,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
formatBalanceCurrencyField(tempLoyaltyCard.balanceType);
cardIdFieldView.setText(tempLoyaltyCard.cardId);
barcodeIdField.setText(tempLoyaltyCard.barcodeId != null ? tempLoyaltyCard.barcodeId : getString(R.string.sameAsCardId));
barcodeTypeField.setText(tempLoyaltyCard.barcodeType != null ? tempLoyaltyCard.barcodeType.prettyName() : getString(R.string.noBarcode));
setbarcodeTypeField(tempLoyaltyCard.barcodeType);
if (groupsChips.getChildCount() == 0) {
List<Group> existingGroups = DBHelper.getGroups(mDatabase);
@@ -837,9 +830,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
}
for (Group group : DBHelper.getGroups(mDatabase)) {
LayoutChipChoiceBinding chipChoiceBinding = LayoutChipChoiceBinding
.inflate(LayoutInflater.from(groupsChips.getContext()), groupsChips, false);
Chip chip = chipChoiceBinding.getRoot();
Chip chip = (Chip) getLayoutInflater().inflate(R.layout.layout_chip_choice, groupsChips, false);
chip.setText(group._id);
chip.setTag(group);
@@ -874,9 +865,10 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
// Update from intent
if (barcodeType != null) {
try {
barcodeTypeField.setText(CatimaBarcode.fromName(barcodeType).prettyName());
Barcode barcode = BarcodeFactory.fromName(barcodeType);
setbarcodeTypeField(barcode);
} catch (IllegalArgumentException e) {
barcodeTypeField.setText(getString(R.string.noBarcode));
setbarcodeTypeField(null);
}
}
@@ -911,7 +903,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
cardImageFrontHolder.setOnClickListener(new ChooseCardImage());
cardImageBackHolder.setOnClickListener(new ChooseCardImage());
FloatingActionButton saveButton = binding.fabSave;
FloatingActionButton saveButton = findViewById(R.id.fabSave);
saveButton.setOnClickListener(v -> doSave());
saveButton.bringToFront();
@@ -954,6 +946,11 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
}
}
private void setbarcodeTypeField(Barcode barcode) {
barcodeTypeField.setTag(barcode);
barcodeTypeField.setText(barcode != null ? barcode.prettyName() : getString(R.string.noBarcode));
}
protected static void formatExpiryField(Context context, EditText expiryField, Date expiry) {
expiryField.setTag(expiry);
@@ -1005,7 +1002,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
return;
}
new MaterialAlertDialogBuilder(this)
new AlertDialog.Builder(this)
.setTitle(R.string.updateBarcodeQuestionTitle)
.setMessage(R.string.updateBarcodeQuestionText)
.setPositiveButton(R.string.yes, (dialog, which) -> {
@@ -1039,7 +1036,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
}
if (confirmExitDialog == null) {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.leaveWithoutSaveTitle);
builder.setMessage(R.string.leaveWithoutSaveConfirmation);
builder.setPositiveButton(R.string.confirm, (dialog, which) -> {
@@ -1184,15 +1181,11 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
throw new IllegalArgumentException("Unknown ID type " + v.getId());
}
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
Intent contentIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentIntent.setType("image/*");
Intent chooserIntent = Intent.createChooser(photoPickerIntent, getString(R.string.addFromImage));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { contentIntent });
Intent i = new Intent(Intent.ACTION_PICK);
i.setType("image/*");
try {
mPhotoPickerLauncher.launch(chooserIntent);
mPhotoPickerLauncher.launch(i);
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), R.string.failedLaunchingPhotoPicker, Toast.LENGTH_LONG).show();
Log.e(TAG, "No activity found to handle intent", e);
@@ -1213,7 +1206,7 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
throw new IllegalArgumentException("Unknown ID type " + v.getId());
}
new MaterialAlertDialogBuilder(LoyaltyCardEditActivity.this)
new AlertDialog.Builder(LoyaltyCardEditActivity.this)
.setTitle(getString(titleResource))
.setItems(cardOptions.keySet().toArray(new CharSequence[cardOptions.size()]), (dialog, which) -> {
Iterator<Callable<Void>> callables = cardOptions.values().iterator();
@@ -1277,11 +1270,11 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
}
public void onDateSet(DatePicker view, int year, int month, int day) {
Calendar c = new GregorianCalendar();
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, day);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.HOUR, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
@@ -1507,9 +1500,9 @@ public class LoyaltyCardEditActivity extends CatimaAppCompatActivity {
return;
}
View cardPart = binding.cardPart;
View optionsPart = binding.optionsPart;
View picturesPart = binding.picturesPart;
View cardPart = findViewById(R.id.cardPart);
View optionsPart = findViewById(R.id.optionsPart);
View picturesPart = findViewById(R.id.picturesPart);
if (getString(R.string.card).equals(part)) {
cardPart.setVisibility(View.VISIBLE);

View File

@@ -1,7 +1,6 @@
package protect.card_locker;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.ColorStateList;
@@ -14,11 +13,9 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.method.DigitsKeyListener;
import android.text.style.ForegroundColorSpan;
import android.text.util.Linkify;
import android.util.Log;
@@ -28,14 +25,10 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -56,31 +49,25 @@ import androidx.core.graphics.BlendModeColorFilterCompat;
import androidx.core.graphics.BlendModeCompat;
import androidx.core.graphics.ColorUtils;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.view.WindowInsetsControllerCompat;
import androidx.core.widget.TextViewCompat;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.textfield.TextInputEditText;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Currency;
import java.util.List;
import protect.card_locker.async.TaskHandler;
import protect.card_locker.databinding.LoyaltyCardViewLayoutBinding;
import protect.card_locker.barcodes.Barcode;
import protect.card_locker.preferences.Settings;
public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements GestureDetector.OnGestureListener {
private LoyaltyCardViewLayoutBinding binding;
private static final String TAG = "Catima";
private GestureDetector mGestureDetector;
@@ -92,7 +79,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
ImageButton bottomAppBarInfoButton;
ImageButton bottomAppBarPreviousButton;
ImageButton bottomAppBarNextButton;
ImageButton bottomAppBarUpdateBalanceButton;
AppCompatTextView storeName;
ImageButton maximizeButton;
ImageView mainImage;
@@ -116,7 +102,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
String cardIdString;
String barcodeIdString;
CatimaBarcode format;
Barcode format;
FloatingActionButton editButton;
@@ -132,7 +118,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
int mainImageIndex = 0;
List<ImageType> imageTypes;
private ImageView[] dots;
boolean isBarcodeSupported = true;
static final String STATE_IMAGEINDEX = "imageIndex";
static final String STATE_FULLSCREEN = "isFullscreen";
@@ -201,7 +186,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
.setDataAndType(FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, file), "image/*")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
} catch (ActivityNotFoundException e) {
}
catch (ActivityNotFoundException e) {
// Display a toast message if an image viewer is not installed on device
Toast.makeText(this, R.string.failedLaunchingPhotoPicker, Toast.LENGTH_SHORT).show();
e.printStackTrace();
@@ -325,7 +311,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
}
super.onCreate(savedInstanceState);
binding = LoyaltyCardViewLayoutBinding.inflate(getLayoutInflater());
settings = new Settings(this);
@@ -347,31 +332,30 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
extractIntentFields(getIntent());
setContentView(binding.getRoot());
setContentView(R.layout.loyalty_card_view_layout);
database = new DBHelper(this).getWritableDatabase();
importURIHelper = new ImportURIHelper(this);
coordinatorLayout = binding.coordinatorLayout;
mainLayout = binding.mainLayout;
cardIdFieldView = binding.cardIdView;
storeName = binding.storeName;
maximizeButton = binding.maximizeButton;
mainImage = binding.mainImage;
coordinatorLayout = findViewById(R.id.coordinator_layout);
mainLayout = findViewById(R.id.mainLayout);
cardIdFieldView = findViewById(R.id.cardIdView);
storeName = findViewById(R.id.storeName);
maximizeButton = findViewById(R.id.maximizeButton);
mainImage = findViewById(R.id.mainImage);
mainImage.setClipToOutline(true);
dotIndicator = binding.dotIndicator;
minimizeButton = binding.minimizeButton;
collapsingToolbarLayout = binding.collapsingToolbarLayout;
appBarLayout = binding.appBarLayout;
bottomAppBar = binding.bottomAppBar;
iconImage = binding.iconImage;
portraitToolbar = binding.toolbar;
landscapeToolbar = binding.toolbarLandscape;
dotIndicator = findViewById(R.id.dotIndicator);
minimizeButton = findViewById(R.id.minimizeButton);
collapsingToolbarLayout = findViewById(R.id.collapsingToolbarLayout);
appBarLayout = findViewById(R.id.app_bar_layout);
bottomAppBar = findViewById(R.id.bottom_app_bar);
iconImage = findViewById(R.id.icon_image);
portraitToolbar = findViewById(R.id.toolbar);
landscapeToolbar = findViewById(R.id.toolbar_landscape);
bottomAppBarInfoButton = binding.buttonShowInfo;
bottomAppBarPreviousButton = binding.buttonPrevious;
bottomAppBarNextButton = binding.buttonNext;
bottomAppBarUpdateBalanceButton = binding.buttonUpdateBalance;
bottomAppBarInfoButton = findViewById(R.id.button_show_info);
bottomAppBarPreviousButton = findViewById(R.id.button_previous);
bottomAppBarNextButton = findViewById(R.id.button_next);
barcodeImageGenerationFinishedCallback = () -> {
if (!(boolean) mainImage.getTag()) {
@@ -386,8 +370,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
}
};
centerGuideline = binding.centerGuideline;
barcodeScaler = binding.barcodeScaler;
centerGuideline = findViewById(R.id.centerGuideline);
barcodeScaler = findViewById(R.id.barcodeScaler);
barcodeScaler.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
@@ -425,7 +409,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
maximizeButton.setOnClickListener(v -> setFullscreen(true));
minimizeButton.setOnClickListener(v -> setFullscreen(false));
editButton = binding.fabEdit;
editButton = findViewById(R.id.fabEdit);
editButton.setOnClickListener(v -> {
Intent intent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
Bundle bundle = new Bundle();
@@ -448,7 +432,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
bottomAppBarInfoButton.setOnClickListener(view -> showInfoDialog());
bottomAppBarPreviousButton.setOnClickListener(view -> prevNextCard(false));
bottomAppBarNextButton.setOnClickListener(view -> prevNextCard(true));
bottomAppBarUpdateBalanceButton.setOnClickListener(view -> showBalanceUpdateDialog());
mGestureDetector = new GestureDetector(this, this);
View.OnTouchListener gestureTouchListener = (v, event) -> mGestureDetector.onTouchEvent(event);
@@ -463,7 +446,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
iconImage.setClipBounds(new Rect(left, top, right, bottom));
}
});
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
private SpannableStringBuilder padSpannableString(SpannableStringBuilder spannableStringBuilder) {
@@ -479,29 +461,17 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
}
private void showInfoDialog() {
AlertDialog.Builder infoDialog = new MaterialAlertDialogBuilder(this);
AlertDialog.Builder infoDialog = new AlertDialog.Builder(this);
int dialogContentPadding = getResources().getDimensionPixelSize(R.dimen.alert_dialog_content_padding);
int dialogTitlePadding = getResources().getDimensionPixelSize(R.dimen.alert_dialog_title_padding);
TextView infoTitleView = new TextView(this);
infoTitleView.setPadding(
dialogContentPadding,
dialogContentPadding,
dialogContentPadding,
dialogTitlePadding
);
infoTitleView.setPadding(20, 20, 20, 20);
infoTitleView.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
infoTitleView.setText(loyaltyCard.store);
infoDialog.setCustomTitle(infoTitleView);
infoDialog.setTitle(loyaltyCard.store);
TextView infoTextview = new TextView(this);
infoTextview.setPadding(
dialogContentPadding,
0,
dialogContentPadding,
0
);
infoTextview.setPadding(20, 0, 20, 0);
infoTextview.setAutoLinkMask(Linkify.ALL);
infoTextview.setTextIsSelectable(true);
@@ -546,80 +516,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
infoDialog.create().show();
}
private void showBalanceUpdateDialog() {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(R.string.updateBalanceTitle);
FrameLayout container = new FrameLayout(this);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
int contentPadding = getResources().getDimensionPixelSize(R.dimen.alert_dialog_content_padding);
params.leftMargin = contentPadding;
params.rightMargin = contentPadding;
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
TextView currentTextview = new TextView(this);
currentTextview.setText(getString(R.string.currentBalanceSentence, Utils.formatBalance(this, loyaltyCard.balance, loyaltyCard.balanceType)));
layout.addView(currentTextview);
TextView updateTextView = new TextView(this);
updateTextView.setText(getString(R.string.newBalanceSentence, Utils.formatBalance(this, loyaltyCard.balance, loyaltyCard.balanceType)));
layout.addView(updateTextView);
final TextInputEditText input = new TextInputEditText(this);
Context dialogContext = this;
input.setInputType(InputType.TYPE_CLASS_NUMBER);
input.setKeyListener(DigitsKeyListener.getInstance("0123456789,."));
input.setHint(R.string.updateBalanceHint);
input.addTextChangedListener(new SimpleTextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
BigDecimal newBalance;
try {
newBalance = calculateNewBalance(loyaltyCard.balance, loyaltyCard.balanceType, s.toString());
} catch (ParseException e) {
input.setTag(null);
updateTextView.setText(getString(R.string.newBalanceSentence, Utils.formatBalance(dialogContext, loyaltyCard.balance, loyaltyCard.balanceType)));
return;
}
// Save new balance into this element
input.setTag(newBalance);
updateTextView.setText(getString(R.string.newBalanceSentence, Utils.formatBalance(dialogContext, newBalance, loyaltyCard.balanceType)));
}
});
layout.addView(input);
layout.setLayoutParams(params);
container.addView(layout);
builder.setView(container);
builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
// Grab calculated balance from input field
BigDecimal newBalance = (BigDecimal) input.getTag();
if (newBalance == null) {
return;
}
// Actually update balance
DBHelper.updateLoyaltyCardBalance(database, loyaltyCardId, newBalance);
// Reload UI
this.onResume();
});
builder.setNegativeButton(getString(R.string.cancel), (dialog, which) -> dialog.cancel());
AlertDialog dialog = builder.create();
dialog.show();
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
input.requestFocus();
}
private BigDecimal calculateNewBalance(BigDecimal currentBalance, Currency currency, String unparsedSubtraction) throws ParseException {
BigDecimal subtraction = Utils.parseBalance(unparsedSubtraction, currency);
return currentBalance.subtract(subtraction).max(new BigDecimal(0));
}
private void setBottomAppBarButtonState() {
if (!loyaltyCard.note.isEmpty() || !loyaltyCardGroups.isEmpty() || hasBalance(loyaltyCard) || loyaltyCard.expiry != null) {
bottomAppBarInfoButton.setVisibility(View.VISIBLE);
@@ -634,8 +530,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
bottomAppBarPreviousButton.setVisibility(View.VISIBLE);
bottomAppBarNextButton.setVisibility(View.VISIBLE);
}
bottomAppBarUpdateBalanceButton.setVisibility(hasBalance(loyaltyCard) ? View.VISIBLE : View.GONE);
}
private void prevNextCard(boolean next) {
@@ -712,11 +606,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
}
if (settings.getDisableLockscreenWhileViewingCard()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
} else {
showWhenLockedSdkLessThan27(window);
}
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}
window.setAttributes(attributes);
@@ -808,14 +699,11 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
fixImageButtonColor(bottomAppBarInfoButton);
fixImageButtonColor(bottomAppBarPreviousButton);
fixImageButtonColor(bottomAppBarNextButton);
fixImageButtonColor(bottomAppBarUpdateBalanceButton);
setBottomAppBarButtonState();
// Make notification area light if dark icons are needed
if (Build.VERSION.SDK_INT >= 23) {
View decorView = getWindow().getDecorView();
WindowInsetsControllerCompat wic = new WindowInsetsControllerCompat(getWindow(), decorView);
wic.setAppearanceLightStatusBars(backgroundNeedsDarkIcons);
window.getDecorView().setSystemUiVisibility(backgroundNeedsDarkIcons ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0);
window.setStatusBarColor(Color.TRANSPARENT);
} else {
// Darken statusbar if icons won't be visible otherwise
@@ -825,17 +713,9 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
// 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 && !format.isSupported()) {
isBarcodeSupported = false;
Toast.makeText(this, getString(R.string.unsupportedBarcodeType), Toast.LENGTH_LONG).show();
} else if (format == null) {
isBarcodeSupported = false;
}
imageTypes = new ArrayList<>();
if (isBarcodeSupported) {
if (format != null) {
imageTypes.add(ImageType.BARCODE);
}
@@ -856,12 +736,6 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
DBHelper.updateLoyaltyCardLastUsed(database, loyaltyCard.id);
}
@SuppressWarnings("deprecation")
private void showWhenLockedSdkLessThan27(Window window) {
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}
private void fixImageButtonColor(ImageButton imageButton) {
imageButton.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(backgroundNeedsDarkIcons ? Color.BLACK : Color.WHITE, BlendModeCompat.SRC_ATOP));
}
@@ -958,7 +832,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
return true;
} else if (id == R.id.action_delete) {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.deleteTitle);
builder.setMessage(R.string.deleteConfirmation);
builder.setPositiveButton(R.string.confirm, (dialog, which) -> {
@@ -1004,7 +878,10 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
setSupportActionBar(portraitToolbar);
}
enableToolbarBackButton();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
private void drawBarcode(boolean addPadding) {
@@ -1158,15 +1035,11 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
editButton.setVisibility(View.GONE);
// Set Android to fullscreen mode
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
getWindow().setDecorFitsSystemWindows(false);
if (getWindow().getInsetsController() != null) {
getWindow().getInsetsController().hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
getWindow().getInsetsController().setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}
} else {
setFullscreenModeSdkLessThan30();
}
getWindow().getDecorView().setSystemUiVisibility(
getWindow().getDecorView().getSystemUiVisibility()
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_FULLSCREEN
);
} else {
Log.d(TAG, "Move out of fullscreen");
@@ -1197,34 +1070,13 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
bottomAppBar.setVisibility(View.VISIBLE);
// Unset fullscreen mode
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
getWindow().setDecorFitsSystemWindows(true);
if (getWindow().getInsetsController() != null) {
getWindow().getInsetsController().show(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
}
} else {
unsetFullscreenModeSdkLessThan30();
}
getWindow().getDecorView().setSystemUiVisibility(
getWindow().getDecorView().getSystemUiVisibility()
& ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
& ~View.SYSTEM_UI_FLAG_FULLSCREEN
);
}
Log.d("setFullScreen", "Is full screen enabled? " + enabled + " Zoom Level = " + barcodeScaler.getProgress());
}
@SuppressWarnings("deprecation")
private void unsetFullscreenModeSdkLessThan30() {
getWindow().getDecorView().setSystemUiVisibility(
getWindow().getDecorView().getSystemUiVisibility()
& ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
& ~View.SYSTEM_UI_FLAG_FULLSCREEN
);
}
@SuppressWarnings("deprecation")
private void setFullscreenModeSdkLessThan30() {
getWindow().getDecorView().setSystemUiVisibility(
getWindow().getDecorView().getSystemUiVisibility()
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_FULLSCREEN
);
}
}

View File

@@ -9,56 +9,50 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.database.CursorIndexOutOfBoundsException;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.CheckBox;
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.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.view.ActionMode;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.splashscreen.SplashScreen;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.tabs.TabLayout;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import protect.card_locker.databinding.ArchiveActivityBinding;
import protect.card_locker.databinding.ContentMainBinding;
import protect.card_locker.databinding.MainActivityBinding;
import protect.card_locker.databinding.SortingOptionBinding;
import protect.card_locker.preferences.SettingsActivity;
public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCardCursorAdapter.CardAdapterListener, GestureDetector.OnGestureListener {
private MainActivityBinding binding;
private ArchiveActivityBinding archiveActivityBinding;
private ContentMainBinding contentMainBinding;
private static final String TAG = "Catima";
public static final String RESTART_ACTIVITY_INTENT = "restart_activity_intent";
private static final int MEDIUM_SCALE_FACTOR_DIP = 460;
private SQLiteDatabase mDatabase;
private LoyaltyCardCursorAdapter mAdapter;
private ActionMode mCurrentActionMode;
@@ -74,7 +68,6 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
private View mHelpSection;
private View mNoMatchingCardsText;
private View mNoGroupCardsText;
private TabLayout groupsTabLayout;
private boolean mArchiveMode;
public static final String BUNDLE_ARCHIVE_MODE = "archiveMode";
@@ -148,7 +141,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
inputMode.finish();
return true;
} else if (inputItem.getItemId() == R.id.action_delete) {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(MainActivity.this);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
// The following may seem weird, but it is necessary to give translators enough flexibility.
// For example, in Russian, Android's plural quantity "one" actually refers to "any number ending on 1 but not ending in 11".
// So while in English the extra non-plural form seems unnecessary duplication, it is necessary to give translators enough flexibility.
@@ -170,7 +163,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
ShortcutHelper.removeShortcut(MainActivity.this, loyaltyCard.id);
}
TabLayout.Tab tab = groupsTabLayout.getTabAt(selectedTab);
TabLayout.Tab tab = ((TabLayout) findViewById(R.id.groups)).getTabAt(selectedTab);
mGroup = tab != null ? tab.getTag() : null;
updateLoyaltyCardList(true);
@@ -182,25 +175,28 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
dialog.show();
return true;
} else if (inputItem.getItemId() == R.id.action_archive) {
}
else if(inputItem.getItemId() == R.id.action_archive){
for (LoyaltyCard loyaltyCard : mAdapter.getSelectedItems()) {
Log.d(TAG, "Archiving card: " + loyaltyCard.id);
DBHelper.updateLoyaltyCardArchiveStatus(mDatabase, loyaltyCard.id, 1);
DBHelper.updateLoyaltyCardArchiveStatus(mDatabase, loyaltyCard.id,1);
updateLoyaltyCardList(false);
inputMode.finish();
invalidateOptionsMenu();
}
return true;
} else if (inputItem.getItemId() == R.id.action_unarchive) {
}
else if(inputItem.getItemId() == R.id.action_unarchive){
for (LoyaltyCard loyaltyCard : mAdapter.getSelectedItems()) {
Log.d(TAG, "Unarchiving card: " + loyaltyCard.id);
DBHelper.updateLoyaltyCardArchiveStatus(mDatabase, loyaltyCard.id, 0);
DBHelper.updateLoyaltyCardArchiveStatus(mDatabase, loyaltyCard.id,0);
updateLoyaltyCardList(false);
inputMode.finish();
invalidateOptionsMenu();
}
return true;
} else if (inputItem.getItemId() == R.id.action_star) {
}
else if(inputItem.getItemId() == R.id.action_star){
for (LoyaltyCard loyaltyCard : mAdapter.getSelectedItems()) {
Log.d(TAG, "Starring card: " + loyaltyCard.id);
DBHelper.updateLoyaltyCardStarStatus(mDatabase, loyaltyCard.id, 1);
@@ -208,7 +204,8 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
inputMode.finish();
}
return true;
} else if (inputItem.getItemId() == R.id.action_unstar) {
}
else if(inputItem.getItemId() == R.id.action_unstar){
for (LoyaltyCard loyaltyCard : mAdapter.getSelectedItems()) {
Log.d(TAG, "Unstarring card: " + loyaltyCard.id);
DBHelper.updateLoyaltyCardStarStatus(mDatabase, loyaltyCard.id, 0);
@@ -233,28 +230,28 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
extractIntentFields(getIntent());
SplashScreen.installSplashScreen(this);
super.onCreate(inputSavedInstanceState);
if (!mArchiveMode) {
binding = MainActivityBinding.inflate(getLayoutInflater());
if(!mArchiveMode) {
setTitle(R.string.app_name);
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
groupsTabLayout = binding.groups;
contentMainBinding = ContentMainBinding.bind(binding.include.getRoot());
} else {
archiveActivityBinding = ArchiveActivityBinding.inflate(getLayoutInflater());
setContentView(R.layout.main_activity);
}
else{
setTitle(R.string.archiveList);
setContentView(archiveActivityBinding.getRoot());
setSupportActionBar(archiveActivityBinding.toolbar);
groupsTabLayout = archiveActivityBinding.groups;
contentMainBinding = ContentMainBinding.bind(archiveActivityBinding.include.getRoot());
setContentView(R.layout.archive_activity);
}
if(mArchiveMode) {
enableToolbarBackButton();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if(mArchiveMode){
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
mDatabase = new DBHelper(this).getWritableDatabase();
TabLayout groupsTabLayout = findViewById(R.id.groups);
groupsTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
@@ -286,10 +283,10 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
View.OnTouchListener gestureTouchListener = (v, event) -> mGestureDetector.onTouchEvent(event);
mHelpSection = contentMainBinding.helpSection;
mNoMatchingCardsText = contentMainBinding.noMatchingCardsText;
mNoGroupCardsText = contentMainBinding.noGroupCardsText;
mCardList = contentMainBinding.list;
mHelpSection = findViewById(R.id.helpSection);
mNoMatchingCardsText = findViewById(R.id.noMatchingCardsText);
mNoGroupCardsText = findViewById(R.id.noGroupCardsText);
mCardList = findViewById(R.id.list);
mNoMatchingCardsText.setOnTouchListener(gestureTouchListener);
mCardList.setOnTouchListener(gestureTouchListener);
@@ -334,17 +331,21 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
*/
mBarcodeScannerLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
// Exit early if the user cancelled the scan (pressed back/home)
if (result.getResultCode() != RESULT_OK) {
return;
}
Intent intent = result.getData();
BarcodeValues barcodeValues = Utils.parseSetBarcodeActivityResult(Utils.BARCODE_SCAN, result.getResultCode(), intent, this);
Bundle inputBundle = intent.getExtras();
String group = inputBundle != null ? inputBundle.getString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP) : null;
processBarcodeValues(barcodeValues, group);
if (!barcodeValues.isEmpty()) {
Intent newIntent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
Bundle newBundle = new Bundle();
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_BARCODETYPE, barcodeValues.format());
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_CARDID, barcodeValues.content());
Bundle inputBundle = intent.getExtras();
if (inputBundle != null && inputBundle.getString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP) != null) {
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP, inputBundle.getString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP));
}
newIntent.putExtras(newBundle);
startActivity(newIntent);
}
});
mSettingsLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
@@ -373,6 +374,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
}
// Start of active tab logic
TabLayout groupsTabLayout = findViewById(R.id.groups);
updateTabGroups(groupsTabLayout);
// Restore settings from Shared Preference
@@ -400,15 +402,12 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
groupsTabLayout.selectTab(tab);
assert tab != null;
mGroup = tab.getTag();
} else if (!mArchiveMode) {
scaleScreen();
}
updateLoyaltyCardList(true);
// End of active tab logic
if (!mArchiveMode) {
FloatingActionButton addButton = binding.fabAdd;
FloatingActionButton addButton = findViewById(R.id.fabAdd);
addButton.setOnClickListener(v -> {
Intent intent = new Intent(getApplicationContext(), ScanActivity.class);
@@ -425,7 +424,8 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
@Override
public void onBackPressed() {
if (mSearchView != null && !mSearchView.isIconified()) {
if (!mSearchView.isIconified()) {
mSearchView.setIconified(true);
return;
}
@@ -498,67 +498,9 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
}
}
private void processBarcodeValues(BarcodeValues barcodeValues, String group) {
if (barcodeValues.isEmpty()) {
throw new IllegalArgumentException("barcodesValues may not be empty");
}
Intent newIntent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
Bundle newBundle = new Bundle();
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_BARCODETYPE, barcodeValues.format());
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_CARDID, barcodeValues.content());
if (group != null) {
newBundle.putString(LoyaltyCardEditActivity.BUNDLE_ADDGROUP, group);
}
newIntent.putExtras(newBundle);
startActivity(newIntent);
}
private void onSharedIntent(Intent intent) {
String receivedAction = intent.getAction();
String receivedType = intent.getType();
// Check if an image was shared to us
if (Intent.ACTION_SEND.equals(receivedAction)) {
if (receivedType.startsWith("image/")) {
BarcodeValues barcodeValues;
try {
Bitmap bitmap;
try {
Uri data = intent.getParcelableExtra(Intent.EXTRA_STREAM);
bitmap = Utils.retrieveImageFromUri(this, data);
} catch (IOException e) {
Log.e(TAG, "Error getting data from image file");
e.printStackTrace();
Toast.makeText(this, R.string.errorReadingImage, Toast.LENGTH_LONG).show();
finish();
return;
}
barcodeValues = Utils.getBarcodeFromBitmap(bitmap);
if (barcodeValues.isEmpty()) {
Log.i(TAG, "No barcode found in image file");
Toast.makeText(this, R.string.noBarcodeFound, Toast.LENGTH_LONG).show();
finish();
return;
}
} catch (NullPointerException e) {
Toast.makeText(this, R.string.errorReadingImage, Toast.LENGTH_LONG).show();
finish();
return;
}
processBarcodeValues(barcodeValues, null);
} else {
Log.e(TAG, "Wrong mime-type");
}
}
}
private void extractIntentFields(Intent intent) {
final Bundle b = intent.getExtras();
mArchiveMode = b != null && b.getBoolean(BUNDLE_ARCHIVE_MODE, false);
onSharedIntent(intent);
}
public void updateTabGroups(TabLayout groupsTabLayout) {
@@ -590,9 +532,9 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
@Override
public boolean onCreateOptionsMenu(Menu inputMenu) {
if (!mArchiveMode) {
if(!mArchiveMode)
getMenuInflater().inflate(R.menu.main_menu, inputMenu);
} else {
else{
getMenuInflater().inflate(R.menu.archive_menu, inputMenu);
}
@@ -620,6 +562,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
public boolean onQueryTextChange(String newText) {
mFilter = newText;
TabLayout groupsTabLayout = findViewById(R.id.groups);
TabLayout.Tab currentTab = groupsTabLayout.getTabAt(groupsTabLayout.getSelectedTabPosition());
mGroup = currentTab != null ? currentTab.getTag() : null;
@@ -630,7 +573,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
});
}
if (!mArchiveMode) {
if(!mArchiveMode) {
if (DBHelper.getArchivedCardsCount(mDatabase) == 0) {
inputMenu.findItem(R.id.action_archived).setVisible(false);
} else {
@@ -666,15 +609,13 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
}
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(MainActivity.this);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle(R.string.sort_by);
SortingOptionBinding sortingOptionBinding = SortingOptionBinding
.inflate(LayoutInflater.from(MainActivity.this), null, false);
final View customLayout = sortingOptionBinding.getRoot();
final View customLayout = getLayoutInflater().inflate(R.layout.sorting_option, null);
builder.setView(customLayout);
CheckBox showReversed = sortingOptionBinding.checkBoxReverse;
CheckBox showReversed = (CheckBox) customLayout.findViewById(R.id.checkBox_reverse);
showReversed.setChecked(mOrderDirection == DBHelper.LoyaltyCardOrderDirection.Descending);
@@ -795,6 +736,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
return false;
}
TabLayout groupsTabLayout = findViewById(R.id.groups);
if (groupsTabLayout.getTabCount() < 2) {
return false;
}
@@ -844,16 +786,6 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
toggleSelection(inputPosition);
}
private void scaleScreen() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int screenHeight = displayMetrics.heightPixels;
float mediumSizePx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,MEDIUM_SCALE_FACTOR_DIP,getResources().getDisplayMetrics());
boolean shouldScaleSmaller = screenHeight < mediumSizePx;
binding.include.welcomeIcon.setVisibility(shouldScaleSmaller ? View.GONE : View.VISIBLE);
}
private void toggleSelection(int inputPosition) {
mAdapter.toggleSelection(inputPosition);
int count = mAdapter.getSelectedItemCount();
@@ -872,10 +804,11 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
boolean hasStarred = false;
boolean hasUnstarred = false;
if (!mArchiveMode) {
if(!mArchiveMode) {
unarchiveItem.setVisible(false);
archiveItem.setVisible(true);
} else {
}
else{
unarchiveItem.setVisible(true);
archiveItem.setVisible(false);
}

View File

@@ -13,7 +13,6 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
@@ -26,11 +25,8 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.RecyclerView;
import protect.card_locker.databinding.ActivityManageGroupBinding;
public class ManageGroupActivity extends CatimaAppCompatActivity implements ManageGroupCursorAdapter.CardAdapterListener {
private ActivityManageGroupBinding binding;
private SQLiteDatabase mDatabase;
private ManageGroupCursorAdapter mAdapter;
@@ -47,18 +43,17 @@ public class ManageGroupActivity extends CatimaAppCompatActivity implements Mana
@Override
protected void onCreate(Bundle inputSavedInstanceState) {
super.onCreate(inputSavedInstanceState);
binding = ActivityManageGroupBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
Toolbar toolbar = binding.toolbar;
setContentView(R.layout.activity_manage_group);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDatabase = new DBHelper(this).getWritableDatabase();
noGroupCardsText = binding.include.noGroupCardsText;
mCardList = binding.include.list;
FloatingActionButton saveButton = binding.fabSave;
noGroupCardsText = findViewById(R.id.noGroupCardsText);
mCardList = findViewById(R.id.list);
FloatingActionButton saveButton = findViewById(R.id.fabSave);
mGroupNameText = binding.editTextGroupName;
mGroupNameText = findViewById(R.id.editTextGroupName);
mGroupNameText.addTextChangedListener(new TextWatcher() {
@Override
@@ -110,7 +105,12 @@ public class ManageGroupActivity extends CatimaAppCompatActivity implements Mana
mGroupNameText.setText(inputSavedInstanceState.getString(SAVE_INSTANCE_CURRENT_GROUP_NAME));
}
enableToolbarBackButton();
ActionBar actionBar = getSupportActionBar();
if (actionBar == null) {
throw (new RuntimeException("mActionBar is not expected to be null here"));
}
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
saveButton.setOnClickListener(v -> {
String currentGroupName = mGroupNameText.getText().toString().trim();
@@ -200,7 +200,7 @@ public class ManageGroupActivity extends CatimaAppCompatActivity implements Mana
private void leaveWithoutSaving() {
if (hasChanged()) {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(ManageGroupActivity.this);
AlertDialog.Builder builder = new AlertDialog.Builder(ManageGroupActivity.this);
builder.setTitle(R.string.leaveWithoutSaveTitle);
builder.setMessage(R.string.leaveWithoutSaveConfirmation);
builder.setPositiveButton(R.string.confirm, (dialog, which) -> finish());

View File

@@ -8,14 +8,11 @@ import android.os.Bundle;
import android.text.InputType;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List;
@@ -27,10 +24,7 @@ import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import protect.card_locker.databinding.ManageGroupsActivityBinding;
public class ManageGroupsActivity extends CatimaAppCompatActivity implements GroupCursorAdapter.GroupAdapterListener {
private ManageGroupsActivityBinding binding;
private static final String TAG = "Catima";
private SQLiteDatabase mDatabase;
@@ -41,12 +35,14 @@ public class ManageGroupsActivity extends CatimaAppCompatActivity implements Gro
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ManageGroupsActivityBinding.inflate(getLayoutInflater());
setTitle(R.string.groups);
setContentView(binding.getRoot());
Toolbar toolbar = binding.toolbar;
setContentView(R.layout.manage_groups_activity);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
enableToolbarBackButton();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
mDatabase = new DBHelper(this).getWritableDatabase();
}
@@ -55,12 +51,12 @@ public class ManageGroupsActivity extends CatimaAppCompatActivity implements Gro
protected void onResume() {
super.onResume();
FloatingActionButton addButton = binding.fabAdd;
FloatingActionButton addButton = findViewById(R.id.fabAdd);
addButton.setOnClickListener(v -> createGroup());
addButton.bringToFront();
mGroupList = binding.include.list;
mHelpText = binding.include.helpText;
mGroupList = findViewById(R.id.list);
mHelpText = findViewById(R.id.helpText);
// Init group list
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
@@ -112,60 +108,24 @@ public class ManageGroupsActivity extends CatimaAppCompatActivity implements Gro
return super.onOptionsItemSelected(item);
}
private void setGroupNameError(EditText input) {
String string = sanitizeAddGroupNameField(input.getText());
if (string.length() == 0) {
input.setError(getString(R.string.group_name_is_empty));
return;
}
if (DBHelper.getGroup(mDatabase, string) != null) {
input.setError(getString(R.string.group_name_already_in_use));
return;
}
input.setError(null);
}
private String sanitizeAddGroupNameField(CharSequence s) {
return s.toString().trim();
}
private void createGroup() {
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.enter_group_name);
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
input.addTextChangedListener(new SimpleTextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
setGroupNameError(input);
}
});
setGroupNameError(input);
// Add spacing to EditText
FrameLayout container = new FrameLayout(this);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
params.leftMargin = 50;
params.rightMargin = 50;
input.setLayoutParams(params);
container.addView(input);
builder.setView(container);
builder.setView(input);
builder.setPositiveButton(getString(R.string.ok), (dialog, which) -> {
CharSequence error = input.getError();
if (error != null) {
Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
String inputString = input.getText().toString().trim();
if (inputString.length() == 0) {
Toast.makeText(getApplicationContext(), R.string.group_name_is_empty, Toast.LENGTH_SHORT).show();
return;
}
DBHelper.insertGroup(mDatabase, sanitizeAddGroupNameField(input.getText()));
if (DBHelper.getGroup(mDatabase, inputString) != null) {
Toast.makeText(getApplicationContext(), R.string.group_name_already_in_use, Toast.LENGTH_SHORT).show();
return;
}
DBHelper.insertGroup(mDatabase, inputString);
updateGroupList();
});
builder.setNegativeButton(getString(R.string.cancel), (dialog, which) -> dialog.cancel());
@@ -233,7 +193,7 @@ public class ManageGroupsActivity extends CatimaAppCompatActivity implements Gro
public void onDeleteButtonClicked(View view) {
final String groupName = getGroupName(view);
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.deleteConfirmationGroup);
builder.setMessage(groupName);

View File

@@ -1,29 +0,0 @@
package protect.card_locker;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class OpenWebLinkHandler {
private static final String TAG = "Catima";
public void openBrowser(AppCompatActivity activity, String url) {
if (url == null) {
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
try {
activity.startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(activity, R.string.failedToOpenUrl, Toast.LENGTH_LONG).show();
Log.e(TAG, "No activity found to handle intent", e);
}
}
}

View File

@@ -1,31 +1,17 @@
package protect.card_locker;
import android.Manifest;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.android.Intents;
import com.journeyapps.barcodescanner.BarcodeCallback;
@@ -35,8 +21,10 @@ import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import java.util.List;
import protect.card_locker.databinding.CustomBarcodeScannerBinding;
import protect.card_locker.databinding.ScanActivityBinding;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
/**
* Custom Scannner Activity extending from Activity to display a custom layout form scanner view.
@@ -45,14 +33,8 @@ import protect.card_locker.databinding.ScanActivityBinding;
* originally licensed under Apache 2.0
*/
public class ScanActivity extends CatimaAppCompatActivity {
private ScanActivityBinding binding;
private CustomBarcodeScannerBinding customBarcodeScannerBinding;
private static final String TAG = "Catima";
private static final int MEDIUM_SCALE_FACTOR_DIP = 460;
private static final int COMPAT_SCALE_FACTOR_DIP = 320;
private CaptureManager capture;
private DecoratedBarcodeView barcodeScannerView;
@@ -74,22 +56,23 @@ public class ScanActivity extends CatimaAppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ScanActivityBinding.inflate(getLayoutInflater());
customBarcodeScannerBinding = CustomBarcodeScannerBinding.bind(binding.zxingBarcodeScanner);
setTitle(R.string.scanCardBarcode);
setContentView(binding.getRoot());
Toolbar toolbar = binding.toolbar;
setContentView(R.layout.scan_activity);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
enableToolbarBackButton();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
extractIntentFields(getIntent());
manualAddLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> handleActivityResult(Utils.SELECT_BARCODE_REQUEST, result.getResultCode(), result.getData()));
photoPickerLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> handleActivityResult(Utils.BARCODE_IMPORT_FROM_IMAGE_FILE, result.getResultCode(), result.getData()));
customBarcodeScannerBinding.addFromImage.setOnClickListener(this::addFromImage);
customBarcodeScannerBinding.addManually.setOnClickListener(this::addManually);
findViewById(R.id.add_from_image).setOnClickListener(this::addFromImage);
findViewById(R.id.add_manually).setOnClickListener(this::addManually);
barcodeScannerView = binding.zxingBarcodeScanner;
barcodeScannerView = findViewById(R.id.zxing_barcode_scanner);
// Even though we do the actual decoding with the barcodeScannerView
// CaptureManager needs to be running to show the camera and scanning bar
@@ -126,10 +109,6 @@ public class ScanActivity extends CatimaAppCompatActivity {
protected void onResume() {
super.onResume();
capture.onResume();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
showCameraPermissionMissingText(false);
}
scaleScreen();
}
@Override
@@ -228,56 +207,11 @@ public class ScanActivity extends CatimaAppCompatActivity {
public void addFromImage(View view) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
Intent contentIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentIntent.setType("image/*");
Intent chooserIntent = Intent.createChooser(photoPickerIntent, getString(R.string.addFromImage));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { contentIntent });
try {
photoPickerLauncher.launch(chooserIntent);
photoPickerLauncher.launch(photoPickerIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), R.string.failedLaunchingPhotoPicker, Toast.LENGTH_LONG).show();
Log.e(TAG, "No activity found to handle intent", e);
}
}
private void showCameraPermissionMissingText(boolean show) {
customBarcodeScannerBinding.cameraPermissionDeniedLayout.cameraPermissionDeniedClickableArea.setOnClickListener(show ? v -> {
navigateToSystemPermissionSetting();
} : null);
customBarcodeScannerBinding.cardInputContainer.setBackgroundColor(show ? obtainThemeAttribute(R.attr.colorSurface) : Color.TRANSPARENT);
customBarcodeScannerBinding.cameraPermissionDeniedLayout.getRoot().setVisibility(show ? View.VISIBLE : View.GONE);
}
private void scaleScreen() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int screenHeight = displayMetrics.heightPixels;
float mediumSizePx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,MEDIUM_SCALE_FACTOR_DIP,getResources().getDisplayMetrics());
boolean shouldScaleSmaller = screenHeight < mediumSizePx;
customBarcodeScannerBinding.cameraPermissionDeniedLayout.cameraPermissionDeniedIcon.setVisibility(shouldScaleSmaller ? View.GONE : View.VISIBLE);
customBarcodeScannerBinding.cameraPermissionDeniedLayout.cameraPermissionDeniedTitle.setVisibility(shouldScaleSmaller ? View.GONE : View.VISIBLE);
}
private int obtainThemeAttribute(int attribute) {
TypedValue typedValue = new TypedValue();
getTheme().resolveAttribute(attribute, typedValue, true);
return typedValue.data;
}
private void navigateToSystemPermissionSetting() {
Intent permissionIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package", getPackageName(), null));
permissionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(permissionIntent);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CaptureManager.getCameraPermissionReqCode())
showCameraPermissionMissingText(grantResults[0] != PackageManager.PERMISSION_GRANTED);
}
}

View File

@@ -22,8 +22,4 @@ public class ThirdPartyInfo {
public String license() {
return mLicense;
}
public String toHtml() {
return String.format("<a href=\"%s\">%s</a> (%s)", url(), name(), license());
}
}

View File

@@ -18,7 +18,6 @@ import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import androidx.core.view.WindowInsetsControllerCompat;
public class UCropWrapper extends UCropActivity {
public static final String UCROP_TOOLBAR_TYPEFACE_STYLE = "ucop_toolbar_typeface_style";
@@ -29,9 +28,7 @@ public class UCropWrapper extends UCropActivity {
boolean darkMode = Utils.isDarkModeEnabled(this);
// setup status bar to look like the rest of the app
if (Build.VERSION.SDK_INT >= 23) {
View decorView = getWindow().getDecorView();
WindowInsetsControllerCompat wic = new WindowInsetsControllerCompat(getWindow(), decorView);
wic.setAppearanceLightStatusBars(!darkMode);
getWindow().getDecorView().setSystemUiVisibility(darkMode ? 0 : View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
// icons are always white back then
if (!darkMode) {

View File

@@ -11,7 +11,6 @@ import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.ImageDecoder;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Build;
import android.os.LocaleList;
import android.provider.MediaStore;
@@ -20,13 +19,6 @@ import android.util.TypedValue;
import android.view.MenuItem;
import android.widget.Toast;
import androidx.annotation.RawRes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.graphics.ColorUtils;
import androidx.exifinterface.media.ExifInterface;
import androidx.palette.graphics.Palette;
import com.google.android.material.color.DynamicColors;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
@@ -36,18 +28,13 @@ import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Calendar;
@@ -57,6 +44,11 @@ import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Map;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.graphics.ColorUtils;
import androidx.exifinterface.media.ExifInterface;
import androidx.palette.graphics.Palette;
import protect.card_locker.preferences.Settings;
public class Utils {
@@ -126,8 +118,12 @@ public class Utils {
Bitmap bitmap;
try {
Uri data = intent.getData();
bitmap = retrieveImageFromUri(context, data);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ImageDecoder.Source image_source = ImageDecoder.createSource(context.getContentResolver(), intent.getData());
bitmap = ImageDecoder.decodeBitmap(image_source, (decoder, info, source) -> decoder.setMutableRequired(true));
} else {
bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), intent.getData());
}
} catch (IOException e) {
Log.e(TAG, "Error getting data from image file");
e.printStackTrace();
@@ -167,20 +163,6 @@ public class Utils {
throw new UnsupportedOperationException("Unknown request code for parseSetBarcodeActivityResult");
}
static public Bitmap retrieveImageFromUri(Context context, Uri data) throws IOException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ImageDecoder.Source image_source = ImageDecoder.createSource(context.getContentResolver(), data);
return ImageDecoder.decodeBitmap(image_source, (decoder, info, source) -> decoder.setMutableRequired(true));
} else {
return getBitmapSdkLessThan29(data, context);
}
}
@SuppressWarnings("deprecation")
private static Bitmap getBitmapSdkLessThan29(Uri data, Context context) throws IOException {
return MediaStore.Images.Media.getBitmap(context.getContentResolver(), data);
}
static public BarcodeValues getBarcodeFromBitmap(Bitmap bitmap) {
// This function is vulnerable to OOM, so we try again with a smaller bitmap is we get OOM
for (int i = 0; i < 10; i++) {
@@ -223,11 +205,6 @@ public class Utils {
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);
// Note: In #1083 it was discovered that `DatePickerFragment` may sometimes store the expiryDate
// at 12:00 PM instead of 12:00 AM in the DB. While this has been fixed and the 12-hour difference
// is not a problem for the way the comparison currently works, it's good to keep in mind such
// dates may exist in the DB in case the comparison changes in the future and the new one relies
// on both dates being set at 12:00 AM.
return expiryDate.before(date.getTime());
}
@@ -419,7 +396,8 @@ public class Utils {
Resources res = context.getResources();
Configuration configuration = res.getConfiguration();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
setLocalesSdkLessThan24(chosenLocale, configuration, res);
configuration.locale = chosenLocale != null ? chosenLocale : Locale.getDefault();
res.updateConfiguration(configuration, res.getDisplayMetrics());
return context;
}
@@ -429,12 +407,6 @@ public class Utils {
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static void setLocalesSdkLessThan24(Locale chosenLocale, Configuration configuration, Resources res) {
configuration.locale = chosenLocale != null ? chosenLocale : Locale.getDefault();
res.updateConfiguration(configuration, res.getDisplayMetrics());
}
static public long getUnixTime() {
return System.currentTimeMillis() / 1000;
}
@@ -516,7 +488,7 @@ public class Utils {
} else {
// final catch all in case of invalid theme value from older versions
// also handles R.string.settings_key_system_theme
DynamicColors.applyToActivityIfAvailable(activity);
DynamicColors.applyIfAvailable(activity);
}
if (isDarkModeEnabled(activity) && settings.getOledDark()) {
@@ -556,23 +528,4 @@ public class Utils {
final int color = (int) (Math.random() * colors.length());
return colors.getColor(color, Color.BLACK);
}
public static String readTextFile(Context context, @RawRes int resourceId) throws IOException {
InputStream input = context.getResources().openRawResource(resourceId);
BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
StringBuilder result = new StringBuilder();
while (true) {
String nextLine = reader.readLine();
if (nextLine == null || nextLine.isEmpty()) {
reader.close();
break;
}
result.append("\n");
result.append(nextLine);
}
return result.toString();
}
}

View File

@@ -15,15 +15,7 @@ import java.io.Reader;
import java.nio.charset.StandardCharsets;
public class ZipUtils {
public static Bitmap readImage(ZipInputStream zipInputStream) {
return BitmapFactory.decodeStream(zipInputStream);
}
public static JSONObject readJSON(ZipInputStream zipInputStream) throws IOException, JSONException {
return new JSONObject(read(zipInputStream));
}
private static String read(ZipInputStream zipInputStream) throws IOException {
static public String read(ZipInputStream zipInputStream) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
Reader reader = new BufferedReader(new InputStreamReader(zipInputStream, StandardCharsets.UTF_8));
int c;
@@ -32,4 +24,12 @@ public class ZipUtils {
}
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));
}
}

View File

@@ -0,0 +1,35 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class AztecBarcode extends Barcode {
@Override
public String prettyName() {
return "Aztec";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.AZTEC;
}
@Override
public String exampleValue() {
return "AZTEC";
}
@Override
public boolean isSquare() {
return true;
}
@Override
public boolean is2D() {
return true;
}
@Override
public boolean hasInternalPadding() {
return false;
}
}

View File

@@ -0,0 +1,22 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
/**
* Abstract barcode class
*/
public abstract class Barcode {
public String name() {
return format().name();
};
abstract public String prettyName();
abstract public BarcodeFormat format();
abstract public String exampleValue();
abstract public boolean isSquare();
abstract public boolean is2D();
public boolean hasInternalPadding() {
return false;
};
public boolean isSupported() { return true; };
}

View File

@@ -0,0 +1,62 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class BarcodeFactory {
public static final Map<String, BarcodeFormat> barcodeNames = new HashMap<>() {{
put(BarcodeFormat.AZTEC.name(), BarcodeFormat.AZTEC);
put(BarcodeFormat.CODE_39.name(), BarcodeFormat.CODE_39);
put(BarcodeFormat.CODE_93.name(), BarcodeFormat.CODE_93);
put(BarcodeFormat.CODE_128.name(), BarcodeFormat.CODE_128);
put(BarcodeFormat.CODABAR.name(), BarcodeFormat.CODABAR);
put(BarcodeFormat.DATA_MATRIX.name(), BarcodeFormat.DATA_MATRIX);
put(BarcodeFormat.EAN_8.name(), BarcodeFormat.EAN_8);
put(BarcodeFormat.EAN_13.name(), BarcodeFormat.EAN_13);
put(BarcodeFormat.ITF.name(), BarcodeFormat.ITF);
put(BarcodeFormat.PDF_417.name(), BarcodeFormat.PDF_417);
put(BarcodeFormat.QR_CODE.name(), BarcodeFormat.QR_CODE);
put(BarcodeFormat.UPC_A.name(), BarcodeFormat.UPC_A);
put(BarcodeFormat.UPC_E.name(), BarcodeFormat.UPC_E);
}};
public static Barcode fromBarcode(BarcodeFormat barcodeFormat) {
switch (barcodeFormat) {
case AZTEC: return new AztecBarcode();
case CODE_39: return new Code39Barcode();
case CODE_93: return new Code93Barcode();
case CODE_128: return new Code128Barcode();
case CODABAR: return new CodabarBarcode();
case DATA_MATRIX: return new DataMatrixBarcode();
case EAN_8: return new Ean8Barcode();
case EAN_13: return new Ean13Barcode();
case ITF: return new ItfBarcode();
case PDF_417: return new Pdf417Barcode();
case QR_CODE: return new QrCodeBarcode();
case UPC_A: return new UpcABarcode();
case UPC_E: return new UpcEBarcode();
default: throw new IllegalArgumentException();
}
}
public static Barcode fromName(String name) {
return fromBarcode(Objects.requireNonNull(barcodeNames.get(name)));
}
public static boolean isSupported(BarcodeFormat barcodeFormat) {
return barcodeNames.containsValue(barcodeFormat);
}
public static boolean isSupported(String name) {
return barcodeNames.containsKey(name);
}
public static Collection<BarcodeFormat> getAllFormats() {
return barcodeNames.values();
}
}

View File

@@ -0,0 +1,19 @@
package protect.card_locker.barcodes;
public class BarcodeWithValue {
private final Barcode mBarcode;
private final String mValue;
public BarcodeWithValue(Barcode barcode, String value) {
mBarcode = barcode;
mValue = value;
}
public Barcode barcode() {
return mBarcode;
}
public String value() {
return mValue;
}
}

View File

@@ -0,0 +1,35 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class CodabarBarcode extends Barcode {
@Override
public String prettyName() {
return "Codabar";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.CODABAR;
}
@Override
public String exampleValue() {
return "C0C";
}
@Override
public boolean isSquare() {
return false;
}
@Override
public boolean is2D() {
return false;
}
@Override
public boolean hasInternalPadding() {
return false;
}
}

View File

@@ -0,0 +1,30 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class Code128Barcode extends Barcode {
@Override
public String prettyName() {
return "Code 128";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.CODE_128;
}
@Override
public String exampleValue() {
return "CODE_128";
}
@Override
public boolean isSquare() {
return false;
}
@Override
public boolean is2D() {
return false;
}
}

View File

@@ -0,0 +1,35 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class Code39Barcode extends Barcode {
@Override
public String prettyName() {
return "Code 39";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.CODE_39;
}
@Override
public String exampleValue() {
return "CODE_39";
}
@Override
public boolean isSquare() {
return false;
}
@Override
public boolean is2D() {
return false;
}
@Override
public boolean hasInternalPadding() {
return false;
}
}

View File

@@ -0,0 +1,30 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class Code93Barcode extends Barcode {
@Override
public String prettyName() {
return "Code 93";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.CODE_93;
}
@Override
public String exampleValue() {
return "CODE_93";
}
@Override
public boolean isSquare() {
return false;
}
@Override
public boolean is2D() {
return false;
}
}

View File

@@ -0,0 +1,30 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class DataMatrixBarcode extends Barcode {
@Override
public String prettyName() {
return "Data Matrix";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.DATA_MATRIX;
}
@Override
public String exampleValue() {
return "DATA_MATRIX";
}
@Override
public boolean isSquare() {
return true;
}
@Override
public boolean is2D() {
return true;
}
}

View File

@@ -0,0 +1,30 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class Ean13Barcode extends Barcode {
@Override
public String prettyName() {
return "EAN 13";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.EAN_13;
}
@Override
public String exampleValue() {
return "5901234123457";
}
@Override
public boolean isSquare() {
return false;
}
@Override
public boolean is2D() {
return false;
}
}

View File

@@ -0,0 +1,30 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class Ean8Barcode extends Barcode {
@Override
public String prettyName() {
return "EAN 8";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.EAN_8;
}
@Override
public String exampleValue() {
return "32123456";
}
@Override
public boolean isSquare() {
return false;
}
@Override
public boolean is2D() {
return false;
}
}

View File

@@ -0,0 +1,30 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class ItfBarcode extends Barcode {
@Override
public String prettyName() {
return "ITF";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.ITF;
}
@Override
public String exampleValue() {
return "1003";
}
@Override
public boolean isSquare() {
return false;
}
@Override
public boolean is2D() {
return false;
}
}

View File

@@ -0,0 +1,35 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class Pdf417Barcode extends Barcode {
@Override
public String prettyName() {
return "PDF 417";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.PDF_417;
}
@Override
public String exampleValue() {
return "PDF_417";
}
@Override
public boolean isSquare() {
return false;
}
@Override
public boolean is2D() {
return true;
}
@Override
public boolean hasInternalPadding() {
return true;
}
}

View File

@@ -0,0 +1,35 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class QrCodeBarcode extends Barcode {
@Override
public String prettyName() {
return "QR Code";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.QR_CODE;
}
@Override
public String exampleValue() {
return "QR_CODE";
}
@Override
public boolean isSquare() {
return true;
}
@Override
public boolean is2D() {
return true;
}
@Override
public boolean hasInternalPadding() {
return true;
}
}

View File

@@ -0,0 +1,30 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class UpcABarcode extends Barcode {
@Override
public String prettyName() {
return "UPC A";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.UPC_A;
}
@Override
public String exampleValue() {
return "123456789012";
}
@Override
public boolean isSquare() {
return false;
}
@Override
public boolean is2D() {
return false;
}
}

View File

@@ -0,0 +1,30 @@
package protect.card_locker.barcodes;
import com.google.zxing.BarcodeFormat;
public class UpcEBarcode extends Barcode {
@Override
public String prettyName() {
return "UPC E";
}
@Override
public BarcodeFormat format() {
return BarcodeFormat.UPC_E;
}
@Override
public String exampleValue() {
return "0123456";
}
@Override
public boolean isSquare() {
return false;
}
@Override
public boolean is2D() {
return false;
}
}

View File

@@ -13,6 +13,7 @@ import org.apache.commons.csv.CSVRecord;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -24,7 +25,6 @@ import java.util.Currency;
import java.util.Date;
import java.util.List;
import protect.card_locker.CatimaBarcode;
import protect.card_locker.DBHelper;
import protect.card_locker.FormatException;
import protect.card_locker.Group;
@@ -54,7 +54,7 @@ public class CatimaImporter implements Importer {
String fileName = Uri.parse(localFileHeader.getFileName()).getLastPathSegment();
if (fileName.equals("catima.csv")) {
importCSV(context, database, zipInputStream);
importCSV(context, database, new ByteArrayInputStream(ZipUtils.read(zipInputStream).getBytes(StandardCharsets.UTF_8)));
} else if (fileName.endsWith(".png")) {
Utils.saveCardImage(context, ZipUtils.readImage(zipInputStream), fileName);
} else {
@@ -67,14 +67,23 @@ public class CatimaImporter implements Importer {
bufferedInputStream.reset();
importCSV(context, database, bufferedInputStream);
}
input.close();
}
public void importCSV(Context context, SQLiteDatabase database, InputStream input) throws IOException, FormatException, InterruptedException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
int version = parseVersion(bufferedReader);
bufferedReader.mark(100);
Integer version = 1;
try {
version = Integer.parseInt(bufferedReader.readLine());
} catch (NumberFormatException _e) {
// Assume version 1
}
bufferedReader.reset();
switch (version) {
case 1:
parseV1(context, database, bufferedReader);
@@ -85,6 +94,8 @@ public class CatimaImporter implements Importer {
default:
throw new FormatException(String.format("No code to parse version %s", version));
}
bufferedReader.close();
}
public void parseV1(Context context, SQLiteDatabase database, BufferedReader input) throws IOException, FormatException, InterruptedException {
@@ -106,8 +117,8 @@ public class CatimaImporter implements Importer {
}
public void parseV2(Context context, SQLiteDatabase database, BufferedReader input) throws IOException, FormatException, InterruptedException {
int part = 0;
StringBuilder stringPart = new StringBuilder();
Integer part = 0;
String stringPart = "";
try {
while (true) {
@@ -123,7 +134,7 @@ public class CatimaImporter implements Importer {
break;
case 1:
try {
parseV2Groups(database, stringPart.toString());
parseV2Groups(database, stringPart);
sectionParsed = true;
} catch (FormatException e) {
// We may have a multiline field, try again
@@ -131,7 +142,7 @@ public class CatimaImporter implements Importer {
break;
case 2:
try {
parseV2Cards(context, database, stringPart.toString());
parseV2Cards(context, database, stringPart);
sectionParsed = true;
} catch (FormatException e) {
// We may have a multiline field, try again
@@ -139,7 +150,7 @@ public class CatimaImporter implements Importer {
break;
case 3:
try {
parseV2CardGroups(database, stringPart.toString());
parseV2CardGroups(database, stringPart);
sectionParsed = true;
} catch (FormatException e) {
// We may have a multiline field, try again
@@ -155,12 +166,12 @@ public class CatimaImporter implements Importer {
if (sectionParsed) {
part += 1;
stringPart = new StringBuilder();
stringPart = "";
} else {
stringPart.append(tmp).append('\n');
stringPart += tmp + "\n";
}
} else {
stringPart.append(tmp).append('\n');
stringPart += tmp + "\n";
}
}
} catch (FormatException e) {
@@ -243,35 +254,6 @@ public class CatimaImporter implements Importer {
}
}
/**
* Parse the version number of the import file
*
* @param reader the reader containing the import file
* @return the parsed version number, defaulting to 1 if none is found
* @throws IOException there was a problem reading the file
*/
private int parseVersion(BufferedReader reader) throws IOException {
reader.mark(10); // slightly over the search limit just to be sure
StringBuilder sb = new StringBuilder();
int searchLimit = 5; // gives you version numbers up to 99999
int codePoint;
// search until the next whitespace, indicating the end of the version
while (!Character.isWhitespace(codePoint = reader.read())) {
// we found something that isn't a digit, or we ran out of chars
if (!Character.isDigit(codePoint) || searchLimit <= 0) {
reader.reset();
return 1; // default value
}
sb.append((char) codePoint);
searchLimit--;
}
reader.reset();
if (sb.length() == 0) {
return 1;
}
return Integer.parseInt(sb.toString());
}
/**
* Import a single loyalty card into the database using the given
* session.
@@ -355,7 +337,7 @@ public class CatimaImporter implements Importer {
// We catch this exception so we can still import old backups
}
DBHelper.insertLoyaltyCard(database, id, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, starStatus, lastUsed, archiveStatus);
DBHelper.insertLoyaltyCard(database, id, store, note, expiry, balance, balanceType, cardId, barcodeId, barcodeType, headerColor, starStatus, lastUsed,archiveStatus);
}
/**

View File

@@ -18,7 +18,6 @@ import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import protect.card_locker.CatimaBarcode;
import protect.card_locker.DBHelper;
import protect.card_locker.FormatException;
import protect.card_locker.Utils;

View File

@@ -24,7 +24,6 @@ import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.HashMap;
import protect.card_locker.CatimaBarcode;
import protect.card_locker.DBHelper;
import protect.card_locker.FormatException;
import protect.card_locker.ImageLocationType;

View File

@@ -23,7 +23,6 @@ import java.util.Currency;
import java.util.Date;
import java.util.TimeZone;
import protect.card_locker.CatimaBarcode;
import protect.card_locker.DBHelper;
import protect.card_locker.FormatException;
import protect.card_locker.Utils;

View File

@@ -17,35 +17,32 @@ import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentResultListener;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import kotlin.Suppress;
import nl.invissvenska.numberpickerpreference.NumberDialogPreference;
import nl.invissvenska.numberpickerpreference.NumberPickerPreferenceDialogFragment;
import protect.card_locker.CatimaAppCompatActivity;
import protect.card_locker.MainActivity;
import protect.card_locker.R;
import protect.card_locker.Utils;
import protect.card_locker.databinding.SettingsActivityBinding;
public class SettingsActivity extends CatimaAppCompatActivity {
private SettingsActivityBinding binding;
private final static String RELOAD_MAIN_STATE = "mReloadMain";
private SettingsFragment fragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = SettingsActivityBinding.inflate(getLayoutInflater());
setTitle(R.string.settings);
setContentView(binding.getRoot());
Toolbar toolbar = binding.toolbar;
setContentView(R.layout.settings_activity);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
enableToolbarBackButton();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
// Display the fragment as the main content.
fragment = new SettingsFragment();
@@ -166,11 +163,6 @@ public class SettingsActivity extends CatimaAppCompatActivity {
}
@Override
@SuppressWarnings("deprecation") // setTargetFragment
// androidx.preference.PreferenceDialogFragmentCompat uses the deprecated method
// `getTargetFragment()`, which throws if `setTargetFragment()` isn't used before.
// While this isn't fixed on upstream, suppress the deprecation warning
// https://issuetracker.google.com/issues/181793702
public void onDisplayPreferenceDialog(Preference preference) {
if (preference instanceof NumberDialogPreference) {
NumberDialogPreference dialogPreference = (NumberDialogPreference) preference;

View File

@@ -1,5 +0,0 @@
<vector android:height="24dp" android:tint="#BD0000"
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="M10.94,8.12L7.48,4.66L9,3h6l1.83,2H20c1.1,0 2,0.9 2,2v12c0,0.05 -0.01,0.1 -0.02,0.16l-5.1,-5.1C16.96,13.71 17,13.36 17,13c0,-2.76 -2.24,-5 -5,-5C11.64,8 11.29,8.04 10.94,8.12zM20.49,23.31L18.17,21H4c-1.1,0 -2,-0.9 -2,-2V7c0,-0.59 0.27,-1.12 0.68,-1.49l-2,-2L2.1,2.1l19.8,19.8L20.49,23.31zM14.49,17.32l-1.5,-1.5C12.67,15.92 12.35,16 12,16c-1.66,0 -3,-1.34 -3,-3c0,-0.35 0.08,-0.67 0.19,-0.98l-1.5,-1.5C7.25,11.24 7,12.09 7,13c0,2.76 2.24,5 5,5C12.91,18 13.76,17.75 14.49,17.32z"/>
</vector>

View File

@@ -1,5 +0,0 @@
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
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="M7,18c-1.1,0 -1.99,0.9 -1.99,2S5.9,22 7,22s2,-0.9 2,-2 -0.9,-2 -2,-2zM1,2v2h2l3.6,7.59 -1.35,2.45c-0.16,0.28 -0.25,0.61 -0.25,0.96 0,1.1 0.9,2 2,2h12v-2L7.42,15c-0.14,0 -0.25,-0.11 -0.25,-0.25l0.03,-0.12 0.9,-1.63h7.45c0.75,0 1.41,-0.41 1.75,-1.03l3.58,-6.49c0.08,-0.14 0.12,-0.31 0.12,-0.48 0,-0.55 -0.45,-1 -1,-1L5.21,4l-0.94,-2L1,2zM17,18c-1.1,0 -1.99,0.9 -1.99,2s0.89,2 1.99,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
</vector>

View File

@@ -27,8 +27,6 @@
</com.google.android.material.appbar.AppBarLayout>
<include
android:id="@+id/include"
layout="@layout/content_main" />
<include layout="@layout/content_main"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="protect.card_locker.MainActivity"
tools:showIn="@layout/custom_barcode_scanner">
<LinearLayout
android:id="@+id/camera_permission_denied_clickable_area"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/camera_permission_denied_icon"
android:layout_width="match_parent"
android:layout_height="84dp"
android:scaleType="fitCenter"
android:src="@drawable/camera_permission_denied" />
<TextView
android:id="@+id/camera_permission_denied_title"
style="@style/TextAppearance.Material3.HeadlineLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/cameraPermissionDeniedTitle" />
<TextView
android:id="@+id/camera_permission_denied_message"
style="@style/AppTheme.TextView.NoData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/noCameraPermissionDirectToSystemSetting" />
</LinearLayout>
</RelativeLayout>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -9,21 +10,19 @@
tools:showIn="@layout/main_activity">
<LinearLayout
android:visibility="gone"
android:id="@+id/helpSection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="@+id/welcome_icon"
android:layout_width="match_parent"
android:layout_height="184dp"
android:scaleType="fitCenter"
android:src="@drawable/ic_launcher_foreground" />
<TextView
android:id="@+id/welcome_text"
style="@style/TextAppearance.Material3.HeadlineLarge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -31,40 +30,40 @@
android:text="@string/welcome" />
<TextView
android:id="@+id/add_card_instruction"
style="@style/AppTheme.TextView.NoData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/noGiftCards" />
android:text="@string/noGiftCards"/>
</LinearLayout>
<TextView
android:id="@+id/noMatchingCardsText"
style="@style/AppTheme.TextView.NoData"
android:id="@+id/noMatchingCardsText"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/noMatchingGiftCards"
android:visibility="gone" />
android:visibility="gone"/>
<TextView
android:id="@+id/noGroupCardsText"
style="@style/AppTheme.TextView.NoData"
android:id="@+id/noGroupCardsText"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/noGroupCards"
android:visibility="gone" />
android:visibility="gone"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="@integer/main_view_card_columns"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="80dp"
android:clipToPadding="false"
android:scrollbars="vertical"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="@integer/main_view_card_columns" />
android:visibility="gone"/>
</RelativeLayout>

View File

@@ -1,57 +1,41 @@
<?xml version="1.0" encoding="utf-8"?><!-- Based on https://github.com/journeyapps/zxing-android-embedded/blob/0fdfbce9fb3285e985bad9971c5f7c0a7a334e7b/sample/src/main/res/layout/custom_barcode_scanner.xml originally released under Apache 2.0 -->
<?xml version="1.0" encoding="utf-8"?>
<!-- Based on https://github.com/journeyapps/zxing-android-embedded/blob/0fdfbce9fb3285e985bad9971c5f7c0a7a334e7b/sample/src/main/res/layout/custom_barcode_scanner.xml originally released under Apache 2.0 -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.journeyapps.barcodescanner.BarcodeView
android:id="@+id/zxing_barcode_surface"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:zxing_framing_rect_height="250dp"
app:zxing_framing_rect_width="250dp" />
android:id="@+id/zxing_barcode_surface"
app:zxing_framing_rect_width="250dp"
app:zxing_framing_rect_height="250dp"/>
<com.journeyapps.barcodescanner.ViewfinderView
android:id="@+id/zxing_viewfinder_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/zxing_viewfinder_view"
app:zxing_possible_result_points="@color/zxing_custom_possible_result_points"
app:zxing_result_view="@color/zxing_custom_result_view"
app:zxing_viewfinder_laser="@color/zxing_custom_viewfinder_laser"
app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask" />
app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/card_input_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/activity_scanner_padding">
<include
android:id="@+id/camera_permission_denied_layout"
layout="@layout/camera_permission_failed_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:gravity="center_horizontal"
android:orientation="vertical">
<Button
android:id="@+id/add_from_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/addFromImage"
app:layout_constraintBottom_toTopOf="@+id/add_manually"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/camera_permission_denied_layout"
app:layout_constraintVertical_bias="1.0" />
android:text="@string/addFromImage" />
<Button
android:id="@+id/add_manually"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/addManually"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
android:text="@string/addManually" />
</LinearLayout>
</merge>

View File

@@ -288,7 +288,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:digits="0123456789,." />
android:digits="0123456789.,$" />
</com.google.android.material.textfield.TextInputLayout>

View File

@@ -8,7 +8,6 @@
android:layout_height="fill_parent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="fill_parent"
@@ -265,18 +264,6 @@
android:tooltipText="@string/nextCard"
android:visibility="gone" />
<ImageButton
android:id="@+id/button_update_balance"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:background="@android:color/transparent"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:src="@drawable/ic_baseline_shopping_cart_24"
android:tooltipText="@string/updateBalance"
android:visibility="gone" />
</com.google.android.material.bottomappbar.BottomAppBar>
<com.google.android.material.floatingactionbutton.FloatingActionButton

View File

@@ -36,8 +36,6 @@
</com.google.android.material.appbar.AppBarLayout>
<include
android:id="@+id/include"
layout="@layout/content_main" />
<include layout="@layout/content_main"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -29,8 +29,6 @@
</com.google.android.material.appbar.AppBarLayout>
<include
android:id="@+id/include"
layout="@layout/group_main" />
<include layout="@layout/group_main"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -8,51 +8,39 @@ Oğuz Ersen
Katharine Chui
mondstern
IllusiveMan196
StoyanDimitrov
Altonss
StoyanDimitrov
Petr Novák
Joel A
Michael Moroni
Taco
SlavekB
Gediminas Murauskas
Petr Novák
Michael Moroni
Joel A
Taco
pfaffenrodt
Nyatsuki
laralem
Samantaz Fox
laralem
arno-github
Ankit Tiwari
Sergio Paredes
Aayush Gupta
gallegonovato
huuhaa
arshbeerSingh
Freddo espresso
Quentin PAGÈS
Miha Frangež
Arnis Jaundzeikars
sr093906
Freddo espresso
mdvhimself
Katarzyna
Maciej Błędkowski
Magnitudee
Olivia (Zoe)
betsythefc
Silvério Santos
waffshappen
Robin
Eric
Alexander Ivanov
ati3
Giovanni
Jane Kong
K. Herbert
Lisa A.
Mawuena M. KODZO A.
Max
Magnitudee
Still Hsu
String E. Fighter
Tapu
Yurical
rr-vesp
alajemba-vik
@@ -62,118 +50,87 @@ Alessandro Mandelli
KovalevArtem
Artem M.
Astrohops1
BMN
BootVirtual
Clonewayx
D. Domig
Diego
Evgeniy Khramov
Fede Pujol
Jean-Luc Tibaux
Lukas Grassauer
Marnick L'Eau
Michalis
Michał
Mohamed A. Salah
Neko Nekowazarashi
Rishi Agarwal
Rosdyana Kusuma
umoenks
Simon Rusinov
Mritunjay
Tarik Dzambic
Thomas Bertels
Thomas Cruveilher
Tong Liu
Wanath
Runner
ce i moa
inesre
lgasp
phlostically
Ágata Leuck
BmBKun
Aditya Das
Asier
Kevin Sicong Jiang
Tomer Ben-Rachel
tfuxu
Ahmed Saleh
Airat
Alexander Ivanov
sNiXx
Angela Enogieru
AnimeshChatterjee1
Ashish Yadav
Aya Elsaadany
BMN
Biren
Booc Sylvan
CherryMonster222
Colgrave
Csaba
Mylou53
danieluhrinyi
Kasina Dheeraj
Donno
Eric
Evgeniy Khramov
Flav
Franciszek Stefan
Grzegorz
HowITsDone
Izzy
Jacek
Jacopo Gennaro Esposito
Jean Mareilles
Jean-Baptiste
人工知能
Jean-Luc Tibaux
krkk
Laura Ferraz
Lucas da Costa
Lisa
bittin
Manan Jhaveri
Marco
Mario M. Viscovich
Mattia
Md. Al-Amin
Michael Gangolf
3DN1M
Moi Toi
DivideEtImpera
Nicolas
pbeckmann
Peer Beckmann
Piotr Zet
Quang Nguyen
Ratnesh
Reza
Rohan Babbar
Ronak Upadhyay
Rose Liverman
SKULD
Samarth Asthan
Simone Dotto
Subhashish Anand
TenTraicion
Titas Pažereckas
Tom Sawyer
Tomer Ben-Rachel
Tony C
Tymofii Lytvynenko
Vancha March
Yevgeny M
Yusril A
Avik Kundu
diksha-2911
gbonaspetti
huang ivan
mtrmirez
opsik
polarhun
pooyanazari
psa-jforestier
Robin
sergio
Marcus
techwebpd
Truestorybaby
tygyh
unstartdev
luoyang3
JaeBeom An
JungHee Lee

View File

@@ -2,8 +2,8 @@
<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">اضغط على + الزر الإضافي لاضافة بطاقة, او استورد من ⋮ القائمة.</string>
<string name="noMatchingGiftCards">لا نتائج. حاول تغيير كلمات البحث.</string>
<string name="noGiftCards">اضغط علي زر + لاضافة بطاقة, او استورد بعض منهم من قائمة ال ⋮.</string>
<string name="noMatchingGiftCards">لا نتائج. حاول تغيير بحثك.</string>
<string name="storeName">اسم</string>
<string name="note">مذكرة</string>
<string name="cardId">بطاقة شخصية</string>
@@ -12,17 +12,17 @@
<string name="noBarcode">لا يوجد باركود</string>
<string name="star">اضف الي المفضلة</string>
<string name="unstar">حذف من المفضلة</string>
<string name="cancel">إلغاء</string>
<string name="cancel">الغاء</string>
<string name="save">حفظ</string>
<string name="edit">تعديل</string>
<string name="delete">مسح</string>
<string name="confirm">تأكيد</string>
<string name="deleteConfirmation">مسح هذة البطاقة نهائيا؟</string>
<string name="ok">حسنا</string>
<string name="copy_to_clipboard">نسخ البطاقة الشخصية الى الحافظة</string>
<string name="copy_to_clipboard">نسخ البطاقة الشخصية الي الحافظة</string>
<string name="share">شارك</string>
<string name="sendLabel">ارسل…</string>
<string name="editCardTitle">عدل البطاقة</string>
<string name="editCardTitle">عدل بطاقة</string>
<string name="addCardTitle">اضف بطاقة</string>
<string name="scanCardBarcode">مسح باركود</string>
<string name="cardShortcut">اختصار البطاقة</string>
@@ -31,11 +31,11 @@
<string name="barcodeImageDescriptionWithType">صورة <xliff:g>%s</xliff:g> باركود</string>
<string name="noStoreError">لا يوجد اسم مدخل</string>
<string name="noCardIdError">لا يوجد بطاقة شخصية مدخلة</string>
<string name="noCardExistsError">لا يمكن العثور على هذه البطاقة</string>
<string name="noCardExistsError">لا يمكن العثور علي هذه البطاقة</string>
<string name="failedParsingImportUriError">لا يمكن تحليل الرابط المستورد</string>
<string name="importExport">استيراد/تصدير</string>
<string name="importExportHelp">دعم بياناتك يسمح بنقلها إلى جهاز آخر.</string>
<string name="importFailed">تعذر إجراء الاستيراد</string>
<string name="importExportHelp">عمل نسخ احتطياتي لبياناتك يسمح نقلها لجهاز اخر.</string>
<string name="importFailed">لا يمكن عمل الاستيراد</string>
<string name="exportSuccessfulTitle">متصدر</string>
<string name="exportFailedTitle">فشل التصدير</string>
<string name="exportFailed">لا يمكن عمل التصدير</string>
@@ -85,7 +85,7 @@
<string name="points">نقاط</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> لا يبدو أنه رصيد صالح.</string>
<string name="chooseImportType">استيراد البيانات من</string>
<string name="app_loyalty_card_keychain">سلسلة مفاتيح بطاقة الولاء</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="privacy_policy">سياسة الخصوصية</string>
<string name="accept">قبول</string>
<string name="importCatima">الاستيراد من Catima</string>
@@ -102,7 +102,6 @@
<string name="barcodeId">قيمة الباركود</string>
<string name="sameAsCardId">نفس بطاقة الهوية</string>
<string name="setBarcodeId">قم بتعيين قيمة الباركود</string>
<string name="unsupportedBarcodeType">لا يمكن عرض نوع الباركود هذا. قد يكون مدعومًا في إصدار أحدث من التطبيق.</string>
<string name="wrongValueForBarcodeType">القيمة غير صالحة لنوع الباركود المحدد</string>
<string name="copy_to_clipboard_multiple_toast">تم نسخ بطاقات الهوية إلى الحافظة</string>
<string name="intent_import_card_from_url_share_multiple_text">أريد مشاركة بعض البطاقات معك</string>
@@ -138,7 +137,7 @@
<string name="sort">فرز</string>
<string name="showMoreInfo">اظهر المعلومات</string>
<string name="hideMoreInfo">إخفاء المعلومات</string>
<string name="swipeToSwitchImages">امسح لتبديل الصور, اضغط لفترة طويلة لفتح الصورة في تطبيق المعرض</string>
<string name="swipeToSwitchImages">اسحب أو اضغط لفترة طويلة لتبديل الصور</string>
<string name="sort_by_balance">الرصيد</string>
<string name="reverse">... بترتيب معكوس</string>
<string name="sort_by">صنف حسب</string>
@@ -160,7 +159,7 @@
<string name="unarchived">البطاقة غير مؤرشفة</string>
<string name="archiveList">أرشيف</string>
<string name="failedLaunchingPhotoPicker">تعذر العثور على تطبيق معرض مدعوم</string>
<string name="noGiftCardsGroup">انشئ بعض من البطاقات, و عيينهم لهذه المجموعة.</string>
<string name="noGiftCardsGroup">انشئ بعض من البطاقات, و عيينهم لهذة المجموعة.</string>
<string name="deleteTitle">مسح بطاقة</string>
<plurals name="selectedCardCount">
<item quantity="zero"><xliff:g>%d</xliff:g> محدد</item>
@@ -174,7 +173,7 @@
<string name="exportName">تصدير</string>
<string name="exporting">جار التصدير…</string>
<string name="importSuccessfulTitle">مستورد</string>
<string name="importFailedTitle">فشل بالاستيراد</string>
<string name="importFailedTitle">فشل الاستيراد</string>
<string name="sort_by_most_recently_used">الأكثر أستعمالا مؤخرا</string>
<string name="license">رخصة</string>
<string name="sort_by_name">اسم</string>
@@ -191,18 +190,18 @@
<plurals name="deleteCardsTitle">
<item quantity="zero">مسح <xliff:g>%d</xliff:g> بطاقة</item>
<item quantity="one">مسح <xliff:g>%d</xliff:g> بطاقة</item>
<item quantity="two">مسح <xliff:g>%d</xliff:g> بطاقتين</item>
<item quantity="two">مسح <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>
<plurals name="deleteCardsConfirmation">
<item quantity="zero">مسح هذه <xliff:g>%d</xliff:g> البطاقة نهائيا؟</item>
<item quantity="one">مسح هذه <xliff:g>%d</xliff:g> البطاقة نهائيا؟</item>
<item quantity="two">مسح هذه <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>
<item quantity="zero">مسح هذه <xliff:g>%d</xliff:g> بطاقة نهائيا؟</item>
<item quantity="one">مسح هذه <xliff:g>%d</xliff:g> بطاقة نهائيا؟</item>
<item quantity="two">مسح هذه <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="importOptionFilesystemTitle">الاستيراد من نظام الملفات</string>
<string name="importOptionFilesystemExplanation">اختر ملفًا محددًا من نظام الملفات.</string>
@@ -271,24 +270,4 @@
<string name="settings_theme_color">لون المظهر</string>
<string name="previousCard">السابق</string>
<string name="nextCard">التالي</string>
<string name="failedToRetrieveImageFile">فشل في استخراج ملف الصورة</string>
<string name="barcodeLongPressMessage">يمكن فتح صور فقط في تطبيق معرض الصور</string>
<string name="failedToOpenUrl">ثبت متصفح ويب أولاً</string>
<string name="welcome">مرحبا بك في كاتيما</string>
<string name="updateBalanceTitle">كم أنفقت؟</string>
<string name="currentBalanceSentence">الرصيد الحالي: <xliff:g> %s </xliff:g></string>
<plurals name="viewArchivedCardsWithCount">
<item quantity="zero">عرض الأرشيف (<xliff:g>%1$d</xliff:g> بطاقة)</item>
<item quantity="one">عرض الأرشيف (<xliff:g>%1$d</xliff:g> بطاقة)</item>
<item quantity="two">عرض الأرشيف (<xliff:g>%1$d</xliff:g> بطاقتين)</item>
<item quantity="few">عرض الأرشيف (<xliff:g>%1$d</xliff:g> بطاقات)</item>
<item quantity="many">عرض الأرشيف (<xliff:g>%1$d</xliff:g> بطاقات)</item>
<item quantity="other">عرض الأرشيف (<xliff:g>%1$d</xliff:g> بطاقات)</item>
</plurals>
<string name="importCards">استيراد البطاقات</string>
<string name="newBalanceSentence">الرصيد الجديد: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">تعذر الوصول إلى الكاميرا</string>
<string name="noCameraPermissionDirectToSystemSetting">لمسح الباركود، ستحتاج Catima إلى الوصول إلى الكاميرا. اضغط هنا لتغيير إعدادات الأذونات.</string>
<string name="updateBalance">تحديث الرصيد</string>
<string name="updateBalanceHint">أدخل المبلغ</string>
</resources>

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View File

@@ -148,7 +148,6 @@
<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.
@@ -184,7 +183,7 @@
<string name="settings_locale">Език</string>
<string name="noGroupCards">Групата е празна</string>
<string name="barcodeImageDescriptionWithType">Изображение на щрихкод от вид <xliff:g>%s</xliff:g></string>
<string name="swipeToSwitchImages">За да размените изображенията - плъзнете, а за да ги отворите в галерията - задръжте</string>
<string name="swipeToSwitchImages">Плъзване или задържане за смяна на изображения</string>
<string name="sort_by">Сортиране по</string>
<string name="reverse">…в обратен ред</string>
<string name="sort_by_balance">Наличност</string>
@@ -240,7 +239,7 @@
<string name="unarchived">Карта е извадена от архива</string>
<string name="archiveList">Архив</string>
<string name="noUnarchivedCardsMessage">Няма карти извън архива</string>
<string name="failedLaunchingPhotoPicker">Не е намерено поддържано приложение за галерия</string>
<string name="failedLaunchingPhotoPicker">Не е намерено поддържано приложение за галерия.</string>
<plurals name="groupCardCountWithArchived">
<item quantity="one"><xliff:g>%1$d</xliff:g> карта (<xliff:g id="archivedCount">%2$d</xliff:g> архивирана)</item>
<item quantity="other"><xliff:g>%1$d</xliff:g> карти (<xliff:g id="archivedCount">%2$d</xliff:g> архивирани)</item>
@@ -253,14 +252,4 @@
<item quantity="one">Преглед на архива (<xliff:g>%1$d</xliff:g> карта)</item>
<item quantity="other">Преглед на архива (<xliff:g>%1$d</xliff:g> карти)</item>
</plurals>
<string name="barcodeLongPressMessage">В приложението галерия могат да бъдат отваряни само изображения</string>
<string name="failedToRetrieveImageFile">Не е възможно извличане на изображение</string>
<string name="noCameraPermissionDirectToSystemSetting">За да сканирате щрихкодове с Catima е необходим достъп до камерата. За да промените разрешението докоснете тук.</string>
<string name="updateBalanceTitle">Каква е промяната\?</string>
<string name="updateBalanceHint">Въведете стойност</string>
<string name="newBalanceSentence">Нов баланс: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">Камерата е недостъпна</string>
<string name="currentBalanceSentence">Текущ баланс: <xliff:g>%s</xliff:g></string>
<string name="updateBalance">Обновяване на баланса</string>
<string name="importCards">Внасяне на карти</string>
</resources>

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<resources>
<string name="save">সংরক্ষণ</string>
<string name="cancel">বাতিল</string>
<string name="unstar">তারা মুক্ত</string>
<string name="star">তারা</string>
<string name="barcodeNoBarcode">কোনো বারকোড নেই</string>
<string name="barcodeNoBarcode">বারকোড না বারকোড</string>
<string name="barcodeType">বারকোড ধরন</string>
<string name="note">বিঃদ্রঃ</string>
<string name="storeName">দোকানের নাম</string>
@@ -34,12 +34,11 @@
<string name="barcodeId">বারকোড আইডি</string>
<string name="sameAsCardId">কার্ড আইডির মতো</string>
<string name="setBarcodeId">বারকোড আইডি সেট করুন</string>
<string name="unsupportedBarcodeType">অসমর্থিত বারকোড টাইপ</string>
<string name="wrongValueForBarcodeType">বারকোড টাইপের জন্য ভুল মান</string>
<string name="copy_to_clipboard_multiple_toast">ক্লিপবোর্ড একাধিক টোস্টে অনুলিপি করুন</string>
<string name="intent_import_card_from_url_share_multiple_text">url থেকে ইন্টেন্ট ইম্পোর্ট কার্ড একাধিক টেক্সট শেয়ার করে</string>
<string name="frontImageDescription">সামনের চিত্র</string>
<string name="backImageDescription">পিছনের চিত্র</string>
<string name="frontImageDescription">সামনের চিত্রের বর্ণনা</string>
<string name="backImageDescription">পিছনের চিত্রের বর্ণনা</string>
<string name="photos">ছবি</string>
<string name="setFrontImage">সদর ছবি স্থাপন</string>
<string name="setBackImage">পিছনের ছবি স্থাপন</string>
@@ -71,34 +70,17 @@
<string name="sort_by_expiry">মেয়াদ শেষ করে সাজান</string>
<string name="reverse">বিপরীত</string>
<string name="sort_by">ক্রমানুসার</string>
<string name="noCardExistsError">ার্ডটি পাওয়া যায়নি</string>
<string name="noCardExistsError">োন কার্ড নেই ত্রুটি</string>
<string name="noStoreError">স্টোরেজ ত্রুটি নেই</string>
<string name="card_ids_copied">আইডি কপি করা হয়েছে</string>
<string name="card_ids_copied">কার্ড আইডি কপি করা হয়েছে</string>
<string name="noCardsMessage">কোন কার্ড বার্তা নেই</string>
<string name="addCardTitle">কার্ডের শিরোনাম যোগ করুন</string>
<string name="editCardTitle">কার্ডের শিরোনাম সম্পাদনা করুন</string>
<string name="sendLabel">পাঠান</string>
<string name="sendLabel">লেবেল পাঠান</string>
<string name="share">ভাগ</string>
<string name="copy_to_clipboard">নকল করুন ক্লিপবোর্ড এ</string>
<string name="deleteConfirmation">নিশ্চিতকরণ মুছে দিন</string>
<string name="confirm">নিশ্চিত করুন</string>
<string name="delete">মুছে ফেলুন</string>
<string name="edit">সম্পাদনা</string>
<string name="action_search">খুঁজুন</string>
<string name="card">কার্ড</string>
<string name="currency">মুদ্রা</string>
<string name="cardId">কার্ড আইডি</string>
<string name="noBarcode">বারকোড নেই</string>
<string name="deleteTitle">কার্ড ডিলিট করুন</string>
<string name="ok">ঠিক আছে</string>
<string name="about">সম্পর্কিত</string>
<string name="debug_version_fmt">সংস্করণ:
\n<xliff:g id="version">
\n%s</xliff:g></string>
<string name="importOptionApplicationButton">অন্য অ্যাপ ব্যাবহার করুন</string>
<string name="moveUp">উপরে উঠান</string>
<string name="moveDown">নিচে নামান</string>
<string name="barcode">বারকোড</string>
<string name="expiryDate">মেয়াদোত্তীর্ণ তারিখ</string>
<string name="noBarcodeFound">কোনো বারকোড পাওয়া যায়নি</string>
</resources>

View File

@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="settings_locale">ভাষা</string>
<string name="action_search">খুঁজুন</string>
<string name="settings_pink_theme">গুলাপি</string>
<string name="settings_blue_theme">নীল</string>
<string name="settings_green_theme">সবুজ</string>
<string name="settings_brown_theme">বাদামি</string>
<string name="save">সংরক্ষণ</string>
<string name="cardId">কার্ড আইডি</string>
<string name="barcodeType">বারকোডের ধরন</string>
<string name="about">সম্পর্কিত</string>
<string name="card">কার্ড</string>
<string name="yes">হ্যাঁ</string>
<string name="settings_grey_theme">ধূসর</string>
<string name="ok">ঠিক আছে</string>
<string name="sendLabel">পাঠান…</string>
<string name="sort_by_name">নাম</string>
<string name="previousCard">পূর্ববর্তী</string>
<string name="all">সকল</string>
<string name="barcode">বারকোড</string>
<string name="never">কখনো না</string>
<string name="currency">মুদ্রা</string>
<string name="settings_violet_theme">বেগুনি</string>
<string name="no">না</string>
<string name="nextCard">পরবর্তী</string>
<string name="action_add">যুক্ত করুন</string>
<string name="noGiftCardsGroup">কিছু কার্ড তৈরি করুন এবং তারপর সেগুলিকে এখানে গ্রুপে বরাদ্দ করুন।</string>
<string name="noMatchingGiftCards">কোন ফলাফল নেই. আপনার অনুসন্ধান পরিবর্তন করার চেষ্টা করুন.</string>
<string name="storeName">নাম</string>
<string name="note">বিঃদ্রঃ</string>
<string name="star">ফেভারিটে যোগ করুন</string>
<string name="barcodeNoBarcode">কোন বারকোড নেই</string>
<string name="noBarcode">বারকোড নেই</string>
<string name="unstar">পছন্দের তালিকা থেকে অপসারণ</string>
<string name="cancel">বাতিল করুন</string>
<string name="edit">সম্পাদনা করুন</string>
<string name="delete">মুছে ফেলা</string>
<string name="confirm">নিশ্চিত করুন</string>
<string name="deleteConfirmation">এই কার্ডটি স্থায়ীভাবে মুছবেন\?</string>
<plurals name="deleteCardsConfirmation">
<item quantity="one">এই <xliff:g>%d</xliff:g> কার্ডটি স্থায়ীভাবে মুছবেন\?</item>
<item quantity="other">এই <xliff:g>%d</xliff:g> কার্ডগুলিকে স্থায়ীভাবে মুছবেন\?</item>
</plurals>
<string name="copy_to_clipboard">ক্লিপবোর্ডে আইডি কপি করুন</string>
<string name="share">শেয়ার করুন</string>
<string name="editCardTitle">কার্ড সম্পাদনা করুন</string>
<string name="addCardTitle">কার্ড যোগ করুন</string>
<string name="scanCardBarcode">বারকোড স্ক্যান করুন</string>
<plurals name="deleteCardsTitle">
<item quantity="one"><xliff:g>%d</xliff:g> কার্ড মুছুন</item>
<item quantity="other"><xliff:g>%d</xliff:g> কার্ডগুলো মুছুন</item>
</plurals>
<string name="deleteTitle">কার্ড মুছুন</string>
</resources>

View File

@@ -4,11 +4,11 @@
<string name="cancel">Odustani</string>
<string name="unstar">Ukloni sve omiljene</string>
<string name="star">Omiljene</string>
<string name="barcodeNoBarcode">Ne postoji barkod</string>
<string name="barcodeNoBarcode">Ova kartica nema barkode</string>
<string name="barcodeType">Barcode tip</string>
<string name="note">Bilježnica</string>
<string name="storeName">Ime</string>
<string name="noMatchingGiftCards">Nema rezultata. Pokušaj promijeniti pretragu.</string>
<string name="noMatchingGiftCards">Nisam našao ništa. Pokušaj promijeniti pretragu.</string>
<string name="noGiftCards">Kliknite + Plus dugme da dodate kartu ili uvozite nešto iz menija prvo.</string>
<string name="action_add">Dodaj</string>
<string name="all">Sve</string>
@@ -34,7 +34,6 @@
<string name="barcodeId">Barcode vrijednost</string>
<string name="sameAsCardId">Isto kao i kartica</string>
<string name="setBarcodeId">Postavi vrijednost za bar kod</string>
<string name="unsupportedBarcodeType">Ovaj bar kod još nije prikazan. Ona može biti podržana u kasnijoj verziji app.</string>
<string name="wrongValueForBarcodeType">Izabrana vrijednost nije izvršna</string>
<string name="copy_to_clipboard_multiple_toast">IDs kartica kopiran u clipboard</string>
<string name="intent_import_card_from_url_share_multiple_text">Želim podijeliti karte s tobom</string>
@@ -71,9 +70,9 @@
<string name="sort_by_expiry">Sajam</string>
<string name="reverse">Rikverc</string>
<string name="sort_by">Sortiraj</string>
<string name="noCardExistsError">Nisam mogao pronaći tu karticu</string>
<string name="noCardExistsError">Nisam mogao pronaći karticu</string>
<string name="noStoreError">Nije uneseno ime</string>
<string name="card_ids_copied">Kopiran ID/ovi</string>
<string name="card_ids_copied">Kopiran ID kartice(s)</string>
<string name="noCardsMessage">Dodaj prvo kartu</string>
<string name="addCardTitle">Dodaj Kartu</string>
<string name="editCardTitle">Izmijeni Karticu</string>
@@ -84,33 +83,4 @@
<string name="confirm">Potvrdi</string>
<string name="delete">Obriši</string>
<string name="edit">Izmijeni</string>
<string name="action_search">Traži</string>
<string name="ok">OK</string>
<string name="cardId">ID kartice</string>
<string name="exportFailed">Nisam uspio izvršiti izvoz</string>
<string name="app_copyright_old">Bazirano na Loyalty Card privjesku
\ncopyright © 2016-2020 Branden Archer</string>
<string name="noGiftCardsGroup">Kreirajte kartice, i dodajte ih ovdje u grupu.</string>
<string name="importExportHelp">Backupovanje vaših podataka omogućava njihov prenos na drugi uređaj.</string>
<string name="importSuccessfulTitle">Uvezeno</string>
<string name="exportFailedTitle">Izvoz neuspješan</string>
<string name="scanCardBarcode">Skeniraj barkod</string>
<string name="cardShortcut">Prečica kartice</string>
<string name="noCardIdError">ID nije unesen</string>
<string name="failedParsingImportUriError">Nisam uspio parsirati URI za uvoz</string>
<string name="importExport">Uvoz/Izvoz</string>
<string name="exportName">Izvoz</string>
<string name="importFailedTitle">Uvoz neuspješan</string>
<string name="importFailed">Nisam uspio odraditi uvoz</string>
<string name="exportSuccessfulTitle">Izvezeno</string>
<string name="importing">Uvozim…</string>
<string name="exporting">Izvozim…</string>
<string name="exportOptionExplanation">Ovi podaci će biti zapisani na lokaciju po Vašoj želji.</string>
<string name="importOptionFilesystemTitle">Uvoz iz file sistema</string>
<string name="importOptionFilesystemExplanation">Izaberite specifični file iz file sistema.</string>
<string name="importOptionFilesystemButton">Iz file sistema</string>
<string name="importOptionApplicationTitle">Koristi drugu aplikaciju</string>
<string name="importOptionApplicationExplanation">Koristi bilo koju aplikaciju ili Vašu omiljenu aplikaciju da bi otvorili file.</string>
<string name="importOptionApplicationButton">Koristi drugu aplikaciju</string>
<string name="about">O</string>
</resources>

View File

@@ -1,7 +1,7 @@
<?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">Přidat</string>
<string name="noGiftCards">Klepněte na tlačítko + plus pro přidá karty nebo naimportujete karty z nabídky ⋮.</string>
<string name="noGiftCards">Klepnutím na tlačítko + plus přidáte kartu nebo ji nejprve importujete z nabídky ⋮.</string>
<string name="storeName">Název</string>
<string name="note">Poznámka</string>
<string name="cardId">ID karty</string>
@@ -34,10 +34,10 @@
<string name="importOptionFilesystemExplanation">Vyberte konkrétní soubor v úložišti.</string>
<string name="importOptionFilesystemButton">Ze souborového systému</string>
<string name="importOptionApplicationTitle">Použitím jiné aplikace</string>
<string name="importOptionApplicationExplanation">K otevření souboru použijte libovolnou aplikaci nebo svého oblíbeného správce souborů.</string>
<string name="importOptionApplicationExplanation">K otevření souboru použijte libovolnou aplikaci nebo svého oblíbeného správce souborů.</string>
<string name="importOptionApplicationButton">Použít jinou aplikaci</string>
<string name="about">O aplikaci</string>
<string name="app_license">Copyleftovaný svobodný software s licencí GPLv3+</string>
<string name="app_license">Copyleftovaný svobodný software s licencí GPLv3+</string>
<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">Informace o revizi: <xliff:g id="app_revision_url">%s</xliff:g></string>
@@ -49,20 +49,20 @@
<string name="moveBarcodeToTopOfScreen">Přesunout čárový kód do horní části obrazovky</string>
<string name="chooseExpiryDate">Zvolte datum vypršení platnosti</string>
<string name="never">Nikdy</string>
<string name="expiryDate">Vypršení platnosti</string>
<string name="expiryDate">Platnost</string>
<string name="editBarcode">Upravit čárový kód</string>
<string name="barcode">Kód</string>
<string name="app_resources">Svobodné zdroje třetích stran: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries">Svobodné knihovny třetích stran: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_copyright_old">Založeno na Loyalty Card Keychain
<string name="app_copyright_old">Na základě Loyalty Card Keychain
\ncopyright © 20162020 Branden Archer</string>
<string name="exportOptionExplanation">Data budou zapsána na místo podle vašeho výběru.</string>
<string name="failedParsingImportUriError">Nelze analyzovat importovanou URI</string>
<string name="failedParsingImportUriError">Nelze analyzovat import URI</string>
<string name="noCardExistsError">Takovou kartu nelze najít</string>
<string name="noCardsMessage">Nejprve přidejte kartu</string>
<string name="cardShortcut">Zástupce karty</string>
<string name="share">Sdílet</string>
<string name="unstar">Odebrat z oblíbených</string>
<string name="share">Podíl</string>
<string name="unstar">Odebrat z oblíbených</string>
<string name="star">Přidat do oblíbených</string>
<string name="noBarcode">Žádný čárový kód</string>
<string name="barcodeNoBarcode">Tato karta nemá čárový kód</string>
@@ -72,9 +72,9 @@
<string name="thumbnailDescription">Miniatura</string>
<string name="card_ids_copied">ID zkopírováno</string>
<plurals name="deleteCardsConfirmation">
<item quantity="one">Opravdu chcete trvale odstranit <xliff:g>%d</xliff:g> kartu\?</item>
<item quantity="few">Opravdu chcete trvale odstranit <xliff:g>%d</xliff:g> karty\?</item>
<item quantity="other">Opravdu chcete trvale odstranit <xliff:g>%d</xliff:g> karet\?</item>
<item quantity="one">Opravdu chcete <xliff:g>%d</xliff:g> kartu trvale odstranit\?</item>
<item quantity="few">Opravdu chcete <xliff:g>%d</xliff:g> karty trvale odstranit\?</item>
<item quantity="other">Opravdu chcete <xliff:g>%d</xliff:g> karet trvale odstranit\?</item>
</plurals>
<plurals name="deleteCardsTitle">
<item quantity="one">Odstranit <xliff:g>%d</xliff:g> kartu</item>
@@ -82,7 +82,7 @@
<item quantity="other">Odstranit <xliff:g>%d</xliff:g> karet</item>
</plurals>
<string name="importSuccessful">Data importována</string>
<string name="intent_import_card_from_url_share_text">Chci s Vámi sdílet kartu</string>
<string name="intent_import_card_from_url_share_text">Chci s Vámi sdílet kartu</string>
<string name="settings_disable_lockscreen_while_viewing_card">Bránit uzamykání obrazovky</string>
<string name="settings_keep_screen_on">Udržovat obrazovku zapnutou</string>
<string name="settings_max_font_size_scale">Maximální velikost písma</string>
@@ -113,7 +113,7 @@
<string name="settings_locale">Jazyk</string>
<string name="turn_flashlight_off">Vypnout světlo</string>
<string name="turn_flashlight_on">Zapnout světlo</string>
<string name="failedGeneratingShareURL">Nepodařilo se vygenerovat adresu URL pro sdílení. Nahlaste to prosím.</string>
<string name="failedGeneratingShareURL">Nepodařilo se vygenerovat sdílenou adresu URL. Nahlaste to prosím.</string>
<string name="passwordRequired">Zadejte prosím heslo</string>
<string name="no">Ne</string>
<string name="yes">Ano</string>
@@ -129,27 +129,26 @@
<string name="intent_import_card_from_url_share_multiple_text">Chci s vámi sdílet karty</string>
<string name="copy_to_clipboard_multiple_toast">ID zkopírována do schránky</string>
<string name="wrongValueForBarcodeType">Hodnota není platná pro vybraný typ čárového kódu</string>
<string name="unsupportedBarcodeType">Tento typ čárového kódu zatím nelze zobrazit. Možná bude podporován v pozdější verzi aplikace.</string>
<string name="barcodeId">Hodnota čárového kódu</string>
<string name="setBarcodeId">Nastavení hodnoty čárového kódu</string>
<string name="sameAsCardId">Stejné jako ID</string>
<string name="importVoucherVaultMessage">Vyberte k importu svůj <i>vouchervault.json</i> exportovaný z Voucher Vault.
<string name="importVoucherVaultMessage">Vyberte svůj <i>vouchervault.json</i> exportovaný z Voucher Vault, který chcete importovat.
\nVytvoříte jej tak, že nejprve stisknete tlačítko Exportovat v aplikaci Voucher Vault.</string>
<string name="importVoucherVault">Import z Voucher Vault</string>
<string name="importStocardMessage">Vyberte k importu svůj <i>***-sync.zip</i> exportovaný z aplikace Stocard.
<string name="importVoucherVault">Import z Voucher Vault</string>
<string name="importStocardMessage">Vyberte svůj <i>***-sync.zip</i> exportovaný z aplikace Stocard, který chcete importovat.
\nZískejte ji zasláním e-mailu na adresu support@stocardapp.com s žádostí o export vašich dat.</string>
<string name="importStocard">Import ze Stocard</string>
<string name="importLoyaltyCardKeychainMessage">Vyberte k importu <i>LoyaltyCardKeychain.csv</i> exportovaný z Loyalty Card Keychain.
<string name="importLoyaltyCardKeychainMessage">Vyberte <i>LoyaltyCardKeychain.csv</i> exportovaný z Loyalty Card Keychain, který chcete importovat.
\nVytvoříte jej z nabídky Import/Export v Loyalty Card Keychain tak, že tam nejprve stisknete tlačítko Exportovat.</string>
<string name="importLoyaltyCardKeychain">Import z Loyalty Card Keychain</string>
<string name="importFidmeMessage">Vyberte k importu svůj <i>fidme-export-request-xxxxxx.zip</i> exportovaný z FidMe a poté vyberte typy čárových kódů ručně.
<string name="importLoyaltyCardKeychain">Import z Loyalty Card Keychain</string>
<string name="importFidmeMessage">Vyberte svůj <i>fidme-export-request-xxxxxx.zip</i> exportovaný z FidMe k importu a poté vyberte typy čárových kódů ručně.
\nVytvoříte jej ze svého profilu FidMe tak, že nejprve zvolíte možnost Ochrana dat a poté stisknete tlačítko Extrahovat moje data.</string>
<string name="importFidme">Import z FidMe</string>
<string name="importFidme">Import z FidMe</string>
<string name="importCatimaMessage">Vyberte <i>catima.zip</i> exportovaný z aplikace Catima, který chcete importovat.
\nVytvoříte jej z nabídky Import/Export jiné aplikace Catima tak, že v ní nejprve stisknete tlačítko Exportovat.</string>
<string name="importCatima">Import z Catima</string>
<string name="importCatima">Import z Catima</string>
<string name="accept">Přijmout</string>
<string name="privacy_policy_popup_text">Oznámení o zásadách ochrany osobních údajů (vyžadováno některými obchody s aplikacemi):
<string name="privacy_policy_popup_text">Oznámení o zásadách ochrany osobních údajů (vyžadováno některými obchody s aplikacemi):
\n
\nNejsou shromažďovány žádné údaje, což může potvrdit každý, protože naše aplikace je svobodný software.</string>
<string name="privacy_policy">Zásady soukromí</string>
@@ -162,7 +161,7 @@
<string name="errorReadingImage">Obrázek se nepodařilo přečíst</string>
<string name="noBarcodeFound">Čárový kód nenalezen</string>
<string name="groupsList">Skupiny: <xliff:g>%s</xliff:g></string>
<string name="addFromImage">Výběr obrázku z galerie</string>
<string name="addFromImage">Výběr obrázku z galerie</string>
<string name="addManually">Ruční zadání ID</string>
<string name="leaveWithoutSaveConfirmation">Ukončit bez uložení\?</string>
<string name="leaveWithoutSaveTitle">Ukončit</string>
@@ -194,7 +193,7 @@
<string name="sort_by_expiry">Vypršení</string>
<string name="sort_by_most_recently_used">Naposledy použité</string>
<string name="sort_by_name">Název</string>
<string name="swipeToSwitchImages">Přejetím přepínáte obrázky, dlouhým stisknutím otevřete obrázek v aplikaci pro galerii</string>
<string name="swipeToSwitchImages">Přejetím nebo dlouhým stisknutím přepínáte obrázky</string>
<string name="sort">Seřadit</string>
<string name="barcodeImageDescriptionWithType">Obrázek čárového kódu <xliff:g>%s</xliff:g></string>
<string name="version_history">Historie verzí</string>
@@ -204,7 +203,7 @@
<string name="on_github">na GitHubu</string>
<string name="source_repository">Úložiště zdrojů</string>
<string name="license">Licence</string>
<string name="help_translate_this_app">Pomozte s překladem této aplikace</string>
<string name="help_translate_this_app">Pomozte s překladem této aplikace</string>
<string name="report_error">Nahlásit chybu</string>
<string name="on_google_play">na Google Play</string>
<string name="exportPassword">Nastavení hesla pro ochranu exportu (volitelné)</string>
@@ -216,14 +215,14 @@
<string name="group_name_is_empty">Název skupiny nemůže být prázdný</string>
<string name="group_updated">Skupina aktualizována</string>
<string name="editGroup">Úprava skupiny: <xliff:g>%s</xliff:g></string>
<string name="noGiftCardsGroup">Zatím nemáte žádné věrnostní karty. Jakmile nějaké přidáte, můžete je zde přiřadit do skupiny.</string>
<string name="noGiftCardsGroup">Zatím nemáte žádné věrnostní karty. Jakmile nějaké přidáte, můžete je přiřadit do skupiny zde.</string>
<string name="shortcutSelectCard">Vybrat kartu</string>
<string name="action_show_details">Zobrazit detaily</string>
<string name="action_hide_details">Skrýt detaily</string>
<string name="translate_platform">na Weblate</string>
<string name="showMoreInfo">Zobrazit podrobnosti</string>
<string name="hideMoreInfo">Skrýt podrobnosti</string>
<string name="starred">S hvězdičkou</string>
<string name="starred">S hvězdičkou</string>
<string name="set_scale">Nastavení měřítka</string>
<string name="options">Volby</string>
<plurals name="balancePoints">
@@ -238,7 +237,7 @@
<string name="settings_lock_on_opening_orientation">Zamknout podle orientace použité při otevření karty</string>
<string name="archive">Archivovat</string>
<string name="unarchive">Vrátit z archivu</string>
<string name="archiveList">Archiv</string>
<string name="archiveList">Archivovat</string>
<string name="noUnarchivedCardsMessage">Nejsou žádné karty vrácené z archivu</string>
<string name="unarchived">Karta vrácena z archivu</string>
<string name="settings_card_orientation">Orientace čárového kódu</string>
@@ -260,14 +259,4 @@
<item quantity="few">Zobrazit archiv (<xliff:g>%1$d</xliff:g> karty)</item>
<item quantity="other">Zobrazit archiv (<xliff:g>%1$d</xliff:g> karet)</item>
</plurals>
<string name="barcodeLongPressMessage">V aplikaci pro galerii mohou být otevírány pouze obrázky</string>
<string name="failedToRetrieveImageFile">Nepodařilo se získat soubor obrázku</string>
<string name="cameraPermissionDeniedTitle">Nelze získat přístup k fotoaparátu</string>
<string name="importCards">Importovat karty</string>
<string name="updateBalance">Aktualizovat zůstatek</string>
<string name="currentBalanceSentence">Současný zůstatek: <xliff:g>%s</xliff:g></string>
<string name="noCameraPermissionDirectToSystemSetting">Pro skenování čárových kódů bude Catima potřebovat přístup k fotoaparátu. Klepněte zde pro změnu nastavení oprávnění.</string>
<string name="updateBalanceTitle">Kolik jste utratil\?</string>
<string name="updateBalanceHint">Zadejte výši</string>
<string name="newBalanceSentence">Nový zůstatek: <xliff:g>%s</xliff:g></string>
</resources>

View File

@@ -131,7 +131,6 @@
<string name="noBarcodeFound">Kein Barcode erkannt</string>
<string name="addFromImage">Bild aus der Galerie wählen</string>
<string name="settings_max_font_size_scale">Maximale Schriftgröße</string>
<string name="unsupportedBarcodeType">Dieser Barcodetyp kann noch nicht angezeigt werden. Wir hoffen das Format in einer zukünftigen Version zu unterstützen.</string>
<string name="wrongValueForBarcodeType">Der Wert ist für den gewählten Barcodetyp leider 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>
@@ -185,7 +184,7 @@
<string name="settings_theme_color">Designfarbe</string>
<string name="app_contributors">Ermöglicht durch: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="barcodeImageDescriptionWithType">Bild <xliff:g>%s</xliff:g> Barcode</string>
<string name="swipeToSwitchImages">Wischen zum Wechseln der Bilder, Halten zum Öffnen des Bildes in der Galerie</string>
<string name="swipeToSwitchImages">Wischen oder langes Drücken zum Wechseln der Bilder</string>
<string name="sort_by">Sortieren nach</string>
<string name="sort_by_balance">Kontostand</string>
<string name="sort_by_expiry">Ablaufdatum</string>
@@ -253,14 +252,4 @@
<item quantity="other">Archiv ansehen (<xliff:g>%1$d</xliff:g> Karten)</item>
</plurals>
<string name="welcome">Willkommen bei Catima</string>
<string name="barcodeLongPressMessage">In der Galerie können nur Bilder geöffnet werden</string>
<string name="failedToRetrieveImageFile">Bilddatei konnte nicht abgerufen werden</string>
<string name="updateBalanceTitle">Wie viel haben Sie ausgegeben\?</string>
<string name="cameraPermissionDeniedTitle">Kein Zugriff auf die Kamera möglich</string>
<string name="noCameraPermissionDirectToSystemSetting">Um Strichcodes zu scannen, benötigt Catima Zugriff auf Ihre Kamera. Tippen Sie hier, um Ihre Berechtigungseinstellungen zu ändern.</string>
<string name="updateBalanceHint">Betrag eingeben</string>
<string name="importCards">Karten importieren</string>
<string name="currentBalanceSentence">Aktuelles Guthaben: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Neues Guthaben: <xliff:g>%s</xliff:g></string>
<string name="updateBalance">Guthaben aktualisieren</string>
</resources>

View File

@@ -1,7 +1,7 @@
<?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="noGiftCards">Κάντε κλικ στο + κουμπί για να προσθέσετε μία κάρτα ή προσθέστε από το ⋮ μενού.</string>
<string name="noGiftCards">Κάντε κλικ στο + κουμπί για να προσθέσετε μία κάρτα ή εισάγετε κάρτες από το ⋮ μενού.</string>
<string name="storeName">Όνομα</string>
<string name="note">Σημείωση</string>
<string name="cardId">Κωδικός Κάρτας</string>
@@ -85,7 +85,7 @@
<string name="expiryDate">Ημερομηνία λήξης</string>
<string name="settings_keep_screen_on">Κράτα την οθόνη ανοιχτή</string>
<string name="leaveWithoutSaveTitle">Έξοδος</string>
<string name="swipeToSwitchImages">Σύρετε για να αλλάξετε εικόνες, κρατήστε για να ανοίξετε μια εικόνα στην συλλογή</string>
<string name="swipeToSwitchImages">Σύρετε ή πατήστε παρατεταμένα για να αλλάξετε εικόνες</string>
<string name="sort_by_balance">Υπόλοιπο</string>
<string name="reverse">... σε αντίθετη σειρά</string>
<string name="version_history">Ιστορικό έκδοσης</string>
@@ -148,7 +148,6 @@
<string name="setFrontImage">Επιλογή μπροστινής εικόνας</string>
<string name="importVoucherVaultMessage">Επιλέξτε την <i>vouchervault.json</i> εξαγωγή από το Voucher Vault για εισαγωγή.
\nΔημιουργήστε το επιλέγοντας Εξαγωγή στο Voucher Vault.</string>
<string name="unsupportedBarcodeType">Ο τύπος γραμμοκώδικα δεν γίνεται να εμφανιστεί ακόμα. Μπορεί να υποστηρίζεται σε μια μελλοντική έκδοση της εφαρμογής.</string>
<string name="frontImageDescription">Μπροστινή εικόνα</string>
<string name="photos">Φωτογραφίες</string>
<string name="backImageDescription">Οπίσθια εικόνα</string>
@@ -245,22 +244,4 @@
<string name="unarchive">Αφαίρεση από το αρχείο</string>
<string name="archiveList">Αρχείο</string>
<string name="noUnarchivedCardsMessage">Δεν υπάρχουν αρχειοθετημένες κάρτες</string>
<string name="updateBalanceTitle">Πόσα ξοδέψατε;</string>
<string name="cameraPermissionDeniedTitle">Αδύνατη η πρόσβαση στην κάμερα</string>
<string name="failedToRetrieveImageFile">Αποτυχία ανάκτησης αρχείου εικόνας</string>
<string name="previousCard">Προηγούμενη</string>
<string name="nextCard">Επόμενη</string>
<string name="updateBalance">Ενημέρωση υπολοίπου</string>
<string name="barcodeLongPressMessage">Μόνο εικόνες μπορούν να ανοιχτούν στην εφαρμογή φωτογραφιών</string>
<string name="noCameraPermissionDirectToSystemSetting">Για να σκανάρετε γραμμοκώδικες, θα χρειαστεί πρόσβαση στην κάμερα από το Catima. Πατήστε εδώ για να δώσετε πρόσβαση.</string>
<plurals name="viewArchivedCardsWithCount">
<item quantity="one">Προβολή αρχείου (<xliff:g>%1$d</xliff:g> κάρτας)</item>
<item quantity="other">Προβολή αρχείου (<xliff:g>%1$d</xliff:g> καρτών)</item>
</plurals>
<string name="importCards">Εισαγωγή καρτών</string>
<string name="updateBalanceHint">Εισάγετε ποσό</string>
<string name="currentBalanceSentence">Τωρινό υπόλοιπο <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Νέο υπόλοιπο: <xliff:g>%s</xliff:g></string>
<string name="failedToOpenUrl">Εγκαταστήστε έναν περιηγητή πρώτα</string>
<string name="welcome">Καλώς ήρθατε στο Catima</string>
</resources>

View File

@@ -1,7 +1,7 @@
<?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">Añadir</string>
<string name="noGiftCards">Haz clic en el botón + para añadir una tarjeta, o importa desde el menú ⋮.</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>
@@ -132,7 +132,6 @@
<string name="frontImageDescription">Imagen frontal</string>
<string name="copy_to_clipboard_multiple_toast">Códigos copiados 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 el código</string>
<string name="barcodeId">Valor de código de barra</string>
@@ -146,7 +145,7 @@
\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">Llavero con tarjeta de fidelización</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="chooseImportType">Importar datos de</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> no tendría un saldo válido.</string>
<string name="currency">Moneda</string>
@@ -158,9 +157,8 @@
<string name="settings_disable_lockscreen_while_viewing_card">Evitar el bloqueo de pantalla</string>
<string name="settings_keep_screen_on">Mantener pantalla encendida</string>
<plurals name="selectedCardCount">
<item quantity="one"><xliff:g>%d</xliff:g> seleccionada</item>
<item quantity="many"><xliff:g>%d</xliff:g> seleccionadas</item>
<item quantity="other"><xliff:g>%d</xliff:g> seleccionadas</item>
<item quantity="one"><xliff:g>%d</xliff:g> tarjeta seleccionada</item>
<item quantity="other"><xliff:g>%d</xliff:g> tarjetas seleccionadas</item>
</plurals>
<string name="deleteTitle">Eliminar la tarjeta</string>
<string name="deleteConfirmation">¿Quiere eliminar permanentemente esta tarjeta\?</string>
@@ -226,7 +224,7 @@
<string name="selectColor">Seleccione el color</string>
<string name="setIcon">Establecer icono</string>
<string name="sort">Ordenar</string>
<string name="swipeToSwitchImages">Desliza para cambiar de imagen, mantén presionado para abrir la imagen en la aplicación de la galería</string>
<string name="swipeToSwitchImages">Desliza el dedo o haz una pulsación larga para cambiar de imagen</string>
<string name="sort_by">Ordenar por</string>
<string name="rate_this_app">Califica esta aplicación</string>
<string name="options">Opciones</string>
@@ -259,15 +257,4 @@
<item quantity="many"><xliff:g>%1$d</xliff:g> tarjetas (archivadas)<xliff:g id="archivedCount">%2$d</xliff:g></item>
<item quantity="other"><xliff:g>%1$d</xliff:g> tarjetas (archivadas)<xliff:g id="archivedCount">%2$d</xliff:g></item>
</plurals>
<string name="starred">Estrellado</string>
<string name="failedToRetrieveImageFile">No se pudo recuperar el archivo de imagen</string>
<string name="barcodeLongPressMessage">Solo se pueden abrir imágenes en la aplicación de galería</string>
<string name="updateBalanceTitle">¿Cuánto has gastado\?</string>
<string name="currentBalanceSentence">Saldo actual: <xliff:g>%s</xliff:g></string>
<string name="noCameraPermissionDirectToSystemSetting">Para escanear códigos de barras, Catima necesitará acceso a su cámara. Toque aquí para cambiar la configuración de sus permisos.</string>
<string name="updateBalanceHint">Introduzca el importe</string>
<string name="newBalanceSentence">Nuevo balance: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">No se pudo acceder a la cámara</string>
<string name="updateBalance">Actualizar el balance</string>
<string name="importCards">Importar tarjetas</string>
</resources>

View File

@@ -8,7 +8,6 @@
<string name="intent_import_card_from_url_share_multiple_text">Haluan jakaa joitain kortteja kanssasi</string>
<string name="copy_to_clipboard_multiple_toast">ID-tunnukset kopioitu 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 myöhemmässä versiossa.</string>
<string name="setBarcodeId">Aseta viivakoodin arvo</string>
<string name="sameAsCardId">Sama kuin ID-tunnus</string>
<string name="barcodeId">Viivakoodin arvo</string>

View File

@@ -131,7 +131,6 @@
<string name="sameAsCardId">Identique à lidentifiant</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 lapplication.</string>
<string name="wrongValueForBarcodeType">La valeur nest 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>
@@ -189,7 +188,7 @@
<string name="app_contributors">Rendu possible par : <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="noGroupCards">Ce groupe est vide</string>
<string name="barcodeImageDescriptionWithType">Image <xliff:g>%s</xliff:g> code-barres</string>
<string name="swipeToSwitchImages">Balayez pour changer dimage, maintenez appuyé pour ouvrir limage dans la galerie</string>
<string name="swipeToSwitchImages">Balayez ou appuyez longuement pour changer dimage</string>
<string name="sort">Trier</string>
<string name="sort_by">Trier par</string>
<string name="reverse"> dans lordre inverse</string>
@@ -260,14 +259,4 @@
<item quantity="other">Voir les archives (<xliff:g>%1$d</xliff:g> cartes)</item>
</plurals>
<string name="welcome">Bienvenue dans Catima</string>
<string name="barcodeLongPressMessage">Seules les images peuvent être ouvertes dans lapplication galerie</string>
<string name="failedToRetrieveImageFile">Impossible de récupérer le fichier image</string>
<string name="currentBalanceSentence">Solde actuel : <xliff:g>%s</xliff:g></string>
<string name="updateBalanceHint">Entrez le montant</string>
<string name="cameraPermissionDeniedTitle">Impossible d\'accéder à la caméra</string>
<string name="noCameraPermissionDirectToSystemSetting">Pour scanner les codes-barres, Catima doit avoir accès à votre caméra. Tapez ici pour modifier vos paramètres d\'autorisation.</string>
<string name="updateBalance">Mettre à jour le solde</string>
<string name="updateBalanceTitle">Combien avez-vous dépensé \?</string>
<string name="newBalanceSentence">Nouveau solde : <xliff:g>%s</xliff:g></string>
<string name="importCards">Importer des cartes</string>
</resources>

View File

@@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="storeName">नाम</string>
<string name="note">नोट</string>
<string name="cardId">कार्ड आईडी</string>
<string name="star">पसंदीदा में जोड़ें</string>
<string name="unstar">पसंदीदा से निकाले</string>
<string name="cancel">रद्द करना</string>
<string name="save">बचाना</string>
<string name="delete">मिटाना</string>
<string name="deleteConfirmation">इस कार्ड को स्थायी रूप से हटाएं\?</string>
<plurals name="deleteCardsConfirmation">
<item quantity="one">इस <xliff:g>%d</xliff:g> कार्ड को स्थायी रूप से हटाएं\?</item>
<item quantity="other">ये <xliff:g>%d</xliff:g> कार्ड स्थायी रूप से हटाएं\?</item>
</plurals>
<string name="ok">ठीक</string>
<string name="share">बाँटें</string>
<string name="sendLabel">भेजें…</string>
<string name="editCardTitle">कार्ड संपादित करें</string>
<string name="addCardTitle">कार्ड जोड़ें</string>
<string name="noCardsMessage">पहले एक कार्ड जोड़ें</string>
<string name="card_ids_copied">कॉपी की गई आईडी</string>
<string name="noStoreError">कोई नाम दर्ज नहीं</string>
<string name="noCardIdError">कोई पहचान पत्र (आईडी दर्ज नहीं) की गई</string>
<string name="noCardExistsError">वह कार्ड नहीं मिला</string>
<string name="importExport">आयात / निर्यात</string>
<string name="exportName">निर्यात</string>
<string name="importSuccessfulTitle">आयातित</string>
<string name="importFailed">आयात नहीं कर सका</string>
<string name="action_search">खोज</string>
<string name="noGiftCardsGroup">कुछ कार्ड बनाएँ, और फिर उन्हें यहाँ समूह करें।</string>
<string name="noMatchingGiftCards">कोई परिणाम नहीं। अपनी खोज बदलने का प्रयास करें।</string>
<string name="deleteTitle">कार्ड हटाएं</string>
<plurals name="deleteCardsTitle">
<item quantity="one">कार्ड <xliff:g>%d</xliff:g> हटाएं</item>
<item quantity="other"><xliff:g>%d</xliff:g> इन कार्डों को हटाएं</item>
</plurals>
<string name="importFailedTitle">आयात विफल</string>
<string name="exportOptionExplanation">डाटा आपके मनचाहे स्थान पर लिखा जाएगा.</string>
<string name="importOptionFilesystemExplanation">फाईल सिस्टम से एक फाईल चुनें.</string>
<string name="app_copyright_old">लोयलटी कार्ड कीचैंन पर आधारित
\nकौपीराईट © 20162020 ब्रांडन आर्चर</string>
<string name="action_add">जोड़</string>
<string name="edit">बदलें</string>
<string name="confirm">पक्का करें</string>
<string name="failedParsingImportUriError">दी गई URL का विक्ष्लेषण नही हो सका</string>
<string name="exportSuccessfulTitle">निर्यात सफल</string>
<string name="exportFailedTitle">निर्यात असफल</string>
<string name="exportFailed">निर्यात नही हो सका</string>
<string name="importing">आयात चल रहा है…</string>
<string name="exporting">निर्यात चल रहा है…</string>
<string name="importOptionFilesystemTitle">फाईल सिस्टम से आयात करें</string>
<string name="importOptionFilesystemButton">फाईल सिस्टम से</string>
<string name="importOptionApplicationTitle">दूसरा एप्प इस्तमाल करें</string>
<string name="importOptionApplicationButton">दूसरा एप्प इस्तमाल करें</string>
<string name="about">बारे में</string>
<string name="starImage">पसंदीदा स्टार</string>
<string name="settings_light_theme">उजालित</string>
<string name="settings_dark_theme">अँधेरा</string>
<string name="settings">व्यवस्थाएं (सेटिंगें)</string>
<string name="settings_system_theme">तंत्र</string>
<string name="settings_card_orientation">बारकोड का अनुकूलन(ओरिएंटेशन)</string>
<string name="settings_landscape_orientation">आयत रूप(लैंडस्केप)</string>
<string name="settings_follow_system_orientation">सिस्टम का पालन करें</string>
<string name="settings_portrait_orientation">पोट्रैट</string>
<string name="settings_max_font_size_scale">अक्षर का अधिकतम नाप</string>
<string name="settings_display_barcode_max_brightness">बारकोड का दृश्य उजालित(ब्राइट) करें</string>
<string name="settings_keep_screen_on">स्क्रीन को चालू रखें</string>
<string name="cameraPermissionDeniedTitle">हम कैमरा तक पहुँच नहीं सकते</string>
<string name="noCameraPermissionDirectToSystemSetting">बारकोड स्कैन करने के लिए,को आपके कैमरा का इस्तेमाल करना होगा। इजाज़त कि व्यवस्था (सेटिंग) बदलने के लिए यहाँ दबायें।</string>
<string name="importOptionApplicationExplanation">फाइल खोलने के लिए कोई भी ऐप या अपना पसंदिता फाइल मैनेजर का इस्तेमाल करे।</string>
<string name="settings_category_title_ui">उपयोक्‍ता अंतरापृष्‍ठ (यूजर इंटरफ़ेस)</string>
<string name="settings_theme">विषय</string>
<string name="barcodeType">बारकोड का प्रकार</string>
<string name="barcodeNoBarcode">कोई बारकोड नहीं है</string>
<string name="noBarcode">बारकोड नहीं है</string>
<string name="copy_to_clipboard">पहचान पत्र(आई डी) को क्लिपबोर्ड में कॉपी करें</string>
<string name="scanCardBarcode">बारकोड स्कैन करें</string>
<string name="cardShortcut">कार्ड का सरल उपाय (शॉर्टकट)</string>
<string name="noGiftCards">\"+\" बटन दबाके कार्ड जोड़ें वा मेन्यू से कार्ड आयात करें</string>
<string name="importExportHelp">तथ्य (डाटा) को बैकअप करना हमें उसे दूसरे डिवाइस में भेजने देता है|</string>
<string name="barcodeImageDescriptionWithType"><xliff:g>%s</xliff:g> का बारकोड</string>
<string name="settings_disable_lockscreen_while_viewing_card">स्क्रीन को लॉक होने से रोकें</string>
<string name="enterBarcodeInstructions">अपनी आई डी लिखें तथा या तो बारकोड प्रकार चुनें, या फिर कोई बारकोड नहीं है चुनें|</string>
<string name="settings_lock_on_opening_orientation">कार्ड खोलते समय प्रयोग करि गयी अवस्था को प्रतिबन्ध करें</string>
<string name="intent_import_card_from_url_share_text">मैं तुम्हें एक कार्ड भेजना चाहता हूँ</string>
<string name="selectBarcodeTitle">बारकोड चुनें</string>
<string name="thumbnailDescription">छोटा चित्र</string>
<string name="noGroups">+ दबा कर समूहों को भागीकरण के लिए चुनें|</string>
<string name="sameAsCardId">आई डी से निरंतर</string>
<string name="intent_import_card_from_url_share_multiple_text">में तुम्हें कुछ कार्ड्स भेजना चाहता हूँ</string>
<string name="importSuccessful">जानकारी प्राप्त हुई</string>
<string name="enter_group_name">समूह का नाम लिखें</string>
<string name="group_edit">समूह बदलें</string>
<string name="noGroupCards">यह समूह खाली है</string>
<string name="group_name_already_in_use">समूह का नाम पहले ही प्रयोग में है</string>
<string name="group_name_is_empty">समूह का नाम खाली नहीं हो सकता</string>
<string name="all">सब</string>
<string name="deleteConfirmationGroup">समूह को मिटा दिया जाए\?</string>
<string name="moveUp">ऊपर की और बढ़ें</string>
<string name="moveDown">नीचे की और बढ़ें</string>
<string name="leaveWithoutSaveTitle">निकास करें</string>
<string name="addFromImage">गैलरी से चित्र चुनें</string>
<string name="card">कार्ड</string>
<string name="barcode">बारकोड</string>
<string name="editBarcode">बारकोड में बदलाव करें</string>
<string name="expiryDate">समाप्ति दिन</string>
<string name="never">कभी नहीं</string>
<string name="chooseExpiryDate">समाप्ति दिन चुनें</string>
<string name="moveBarcodeToTopOfScreen">बार कोड को स्क्रीन के ऊपरी भाग पर लाएं</string>
<string name="moveBarcodeToCenterOfScreen">बार कोड को स्क्रीन के बीच में लाएं</string>
<string name="noBarcodeFound">कोई बारकोड नहीं पाया गया</string>
<string name="errorReadingImage">चित्र को पढ़ना संभव नहीं हुआ</string>
<string name="balance">संतुलन</string>
<string name="currency">मुद्रा</string>
<string name="accept">स्वीकार</string>
</resources>

View File

@@ -22,7 +22,7 @@
<string name="action_add">Dodaj</string>
<string name="storeName">Ime</string>
<string name="note">Napomena</string>
<string name="noMatchingGiftCards">Nema rezultata. Pokušajte promijeniti pretraživanje.</string>
<string name="noMatchingGiftCards">Ništa nisam našao. Pokušajte promijeniti pretraživanje.</string>
<string name="cardId">ID kartice</string>
<string name="barcodeType">Vrsta crtičnog koda</string>
<string name="barcodeNoBarcode">Na ovoj kartici nema crtičnog koda</string>
@@ -80,5 +80,4 @@
<string name="leaveWithoutSaveTitle">Izlaz</string>
<string name="card">Karta</string>
<string name="leaveWithoutSaveConfirmation">Otići bez očuvanja\?</string>
<string name="noGiftCardsGroup">Izradite neke kartice, a zatim ih dodijelite grupi ovdje.</string>
</resources>

View File

@@ -151,7 +151,6 @@
<string name="barcodeId">Vonalkód érték</string>
<string name="sameAsCardId">Ugyanaz, mint az azonosító</string>
<string name="setBarcodeId">Vonalkód érték beállítása</string>
<string name="unsupportedBarcodeType">Ez a vonalkód típus még nem megjeleníthető. Feltehetően támogatva lesz egy későbbi verzióban.</string>
<string name="copy_to_clipboard_multiple_toast">Azonosítók a vágólapra másolva</string>
<string name="intent_import_card_from_url_share_multiple_text">Meg akarok veled osztani pár kártyát</string>
<string name="frontImageDescription">Előlapi kép</string>

View File

@@ -7,8 +7,8 @@
<string name="edit">Ubah</string>
<string name="save">Simpan</string>
<string name="deleteTitle">Hapus kartu</string>
<string name="cardId">ID Kartu</string>
<string name="barcodeType">Jenis barcode</string>
<string name="cardId">Kartu ID</string>
<string name="barcodeType">Tipe barcode</string>
<string name="star">Tambahkan ke favorit</string>
<string name="unstar">Hapus dari favorit</string>
<string name="action_add">Tambah</string>
@@ -30,7 +30,7 @@
<string name="scanCardBarcode">Pindai Barcode</string>
<string name="barcodeNoBarcode">Tidak ada barcode</string>
<string name="cancel">Batalkan</string>
<string name="importExport">Impor/Ekspor</string>
<string name="importExport">Import/Ekspor</string>
<string name="settings_category_title_ui">Tampilan Pengguna</string>
<string name="settings_theme">Tema</string>
<string name="all">Semua</string>
@@ -76,17 +76,17 @@
<string name="removeImage">Hapus gambar</string>
<string name="setBackImage">Atur gambar bagian belakang</string>
<string name="intent_import_card_from_url_share_multiple_text">Saya ingin berbagi kartu dengan Anda</string>
<string name="noGiftCards">Tap tanda tombol plus ( + ) untuk menambahkan kartu, atau mengimpor nya melalui menu ( ⋮ ).</string>
<string name="noMatchingGiftCards">Tidak menemukan apapun. Cobalah untuk mengubah pencarian anda.</string>
<string name="noGiftCards">Klik tanda + tombol tambah untuk menambahkan kartu, atau mengimpor beberapa kartu melalui menu.</string>
<string name="noMatchingGiftCards">Tidak menemukan apapun. Coba untuk mengubah pencarian anda.</string>
<string name="noBarcode">Bukan barcode</string>
<string name="confirm">Konfirmasi</string>
<string name="copy_to_clipboard">Salin ID ke papan klip</string>
<string name="sendLabel">Kirim…</string>
<string name="noCardsMessage">Tambah kartu terlebih dahulu</string>
<string name="noStoreError">Nama masih kosong</string>
<string name="noCardIdError">Tidak ada ID yang dimasukkan</string>
<string name="noCardIdError">Kartu ID masih kosong</string>
<string name="noCardExistsError">Tidak dapat menemukan kartu</string>
<string name="failedParsingImportUriError">Tidak dapat memparsing impor URI</string>
<string name="failedParsingImportUriError">Tidak dapat menguraikan alamat impor situs web</string>
<string name="exportName">Ekspor</string>
<string name="importSuccessfulTitle">Sudah diimpor</string>
<string name="importFailedTitle">Impor gagal</string>
@@ -94,13 +94,13 @@
<string name="exportSuccessfulTitle">Sudah diekspor</string>
<string name="exportFailedTitle">Ekspor gagal</string>
<string name="exportFailed">Tidak dapat mengekspor</string>
<string name="importing">Sedang mengimpor…</string>
<string name="exporting">Sedang mengekspor…</string>
<string name="importing">Mengimpor…</string>
<string name="exporting">Mengekspor…</string>
<string name="noExternalStoragePermissionError">Berikan izin penyimpanan eksternal untuk mengimpor atau mengekspor data</string>
<string name="exportOptionExplanation">Data akan ditulis ke lokasi pilihan Anda.</string>
<string name="importOptionFilesystemTitle">Impor dari pengelola file bawaan</string>
<string name="importOptionFilesystemExplanation">Pilih file dari pengelola file bawaan.</string>
<string name="importOptionFilesystemButton">Dari pengelola file bawaan</string>
<string name="importOptionFilesystemTitle">Impor dari sistem</string>
<string name="importOptionFilesystemExplanation">Pilih file dari sistem.</string>
<string name="importOptionFilesystemButton">Dari sistem</string>
<string name="importOptionApplicationTitle">Gunakan aplikasi lain</string>
<string name="importOptionApplicationExplanation">Gunakan aplikasi lain atau pengelola file favorit anda untuk membuka file.</string>
<string name="importOptionApplicationButton">Gunakan aplikasi lain</string>
@@ -123,7 +123,7 @@
<string name="settings_max_font_size_scale">Ukuran maksimal huruf</string>
<string name="settings_display_barcode_max_brightness">Terangkan tampilan barcode</string>
<string name="settings_keep_screen_on">Biarkan layar menyala</string>
<string name="settings_disable_lockscreen_while_viewing_card">Cegah kunci layar</string>
<string name="settings_disable_lockscreen_while_viewing_card">Mencegah layar menyala</string>
<string name="intent_import_card_from_url_share_text">Saya ingin berbagi kartu dengan anda</string>
<string name="importSuccessful">Data terimpor</string>
<string name="exportSuccessful">Data terekspor</string>
@@ -167,7 +167,6 @@
<string name="importVoucherVault">Impor dari Voucher Vault</string>
<string name="importVoucherVaultMessage">Pilih ekspor <i>vouchervault.json</i> Anda dari Vault Voucher untuk diimpor.
\nBuat dengan menekan Ekspor di Vault Voucher terlebih dahulu.</string>
<string name="unsupportedBarcodeType">Jenis barcode ini belum dapat ditampilkan. Ini mungkin didukung di versi aplikasi yang lebih baru.</string>
<string name="wrongValueForBarcodeType">Nilai tidak berlaku untuk jenis barcode yang dipilih</string>
<string name="copy_to_clipboard_multiple_toast">ID disalin ke papan klip</string>
<string name="frontImageDescription">Gambar depan</string>
@@ -178,18 +177,18 @@
<string name="exportPassword">Tetapkan kata sandi untuk melindungi ekspor anda (opsional)</string>
<string name="failedGeneratingShareURL">Tidak dapat membuat alamat berbagi. Mohon laporkan ini.</string>
<string name="app_contributors">Pengembangan dibantu oleh: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="swipeToSwitchImages">Geser untuk beralih gambar, tahan untuk membuka gambar di aplikasi galeri</string>
<string name="reverse">…dalam urutan terbalik</string>
<string name="swipeToSwitchImages">Geser atau tekan yang lama untuk mengganti gambar</string>
<string name="reverse">Ubah urutan</string>
<string name="version_history">Riwayat Versi</string>
<string name="help_translate_this_app">Bantu terjemahkan aplikasi ini</string>
<string name="source_repository">Sumber Repositori</string>
<string name="on_github">di GitHub</string>
<string name="and_data_usage">dan penggunaan data</string>
<string name="on_google_play">di Google Play</string>
<string name="cardShortcut">Pintasan Kartu</string>
<string name="card_ids_copied">ID(s) yang disalin</string>
<string name="cardShortcut">Pintasan kartu</string>
<string name="card_ids_copied">ID kartu yang tersalin</string>
<string name="barcodeImageDescriptionWithType">Gambar <xliff:g>%s</xliff:g> barcode</string>
<string name="importExportHelp">Mencadangkan data anda akan memungkinkan memindahkannya ke perangkat lain.</string>
<string name="importExportHelp">Mencadangkan data anda memungkinkan memindahkannya ke perangkat lain.</string>
<plurals name="selectedCardCount">
<item quantity="other"><xliff:g>%d</xliff:g> kartu dipilih</item>
</plurals>
@@ -242,19 +241,4 @@
<string name="archive">Arsip</string>
<string name="archived">Kartu diarsipkan</string>
<string name="archiveList">Arsip</string>
<string name="failedToRetrieveImageFile">Gagal mengambil file gambar</string>
<string name="barcodeLongPressMessage">Hanya gambar yang dapat dibuka di aplikasi galeri</string>
<string name="unarchive">Ekstrak</string>
<string name="unarchived">Kartu tidak diarsipkan</string>
<string name="noUnarchivedCardsMessage">Tidak ada kartu yang diekstrak</string>
<string name="options">Opsi</string>
<string name="starred">Berbintang</string>
<string name="importCards">Import kartu</string>
<string name="newBalanceSentence">Saldo baru: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">Tidak dapat mengakses kamera</string>
<string name="updateBalance">Perbarui saldo</string>
<string name="updateBalanceHint">Masukkan jumlah</string>
<string name="currentBalanceSentence">Saldo saat ini: <xliff:g>%s</xliff:g></string>
<string name="updateBalanceTitle">Berapa banyak yang telah kamu habiskan \?</string>
<string name="noCameraPermissionDirectToSystemSetting">Untuk memindai barcode, Catima membutuhkan akses ke kamera mu. Tap disini untuk mengganti pengaturan perizinan mu.</string>
</resources>
</resources>

View File

@@ -2,7 +2,7 @@
<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">Premi il pulsante + per aggiungere una carta oppure importala dal menù ⋮.</string>
<string name="noGiftCards">Premi il pulsante + per aggiungere una carta oppure importane alcune dal menù ⋮.</string>
<string name="noMatchingGiftCards">Nessun risultato. Prova a cambiare la tua ricerca.</string>
<string name="storeName">Nome</string>
<string name="note">Note</string>
@@ -131,7 +131,6 @@
<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 massima del carattere</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 libere di terze parti: <xliff:g id="app_resources_list"> %s </xliff:g></string>
<string name="app_libraries">Librerie libere di terze parti: <xliff:g id="app_libraries_list"> %s </xliff:g></string>
@@ -189,7 +188,7 @@
<string name="app_contributors">Reso possibile da: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="noGroupCards">Questo gruppo è vuoto</string>
<string name="barcodeImageDescriptionWithType">Immagine del codice a barre in formato <xliff:g>%s</xliff:g></string>
<string name="swipeToSwitchImages">Scorri per cambiare immagine, tieni premuto per aprire l\'immagine nella galleria</string>
<string name="swipeToSwitchImages">Scorri o premi a lungo per cambiare immagine</string>
<string name="sort_by">Ordina per</string>
<string name="reverse">…in ordine inverso</string>
<string name="sort_by_balance">Saldo</string>
@@ -260,14 +259,4 @@
<item quantity="many">Visualizza archivio (<xliff:g>%1$d</xliff:g> carta)</item>
<item quantity="other">Visualizza archivio (<xliff:g>%1$d</xliff:g> carte)</item>
</plurals>
<string name="failedToRetrieveImageFile">Impossibile ottenere il file dell\'immagine</string>
<string name="barcodeLongPressMessage">Si possono aprire solo immagini dell\'app della galleria</string>
<string name="cameraPermissionDeniedTitle">È impossibile accedere alla fotocamera</string>
<string name="noCameraPermissionDirectToSystemSetting">Per poter scansionare i codici a barre, Catima ha bisogno di accedere alla tua fotocamera. Premi qui per poter cambiare le impostazioni dei permessi.</string>
<string name="updateBalance">Aggiorna bilancio</string>
<string name="updateBalanceTitle">Quanto hai speso\?</string>
<string name="updateBalanceHint">Inserisci l\'importo</string>
<string name="currentBalanceSentence">Bilancio attuale: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Nuovo bilancio: <xliff:g>%s</xliff:g></string>
<string name="importCards">Importa carte</string>
</resources>

View File

@@ -1,7 +1,6 @@
<?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>

View File

@@ -1,29 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="addManually">직접 카드 ID 입력</string>
<string name="groupsList">그룹: <xliff:g>%s</xliff:g></string>
<string name="groupsList">그룹: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="all">모두</string>
<string name="groups">그룹</string>
<string name="enter_group_name">그룹 이름 입력</string>
<string name="settings_dark_theme">어두움</string>
<string name="settings_light_theme">밝음</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="debug_version_fmt">버전: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="version">%s</xliff:g></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="settings_system_theme">시스템</string>
<string name="settings_theme">테마</string>
<string name="settings_category_title_ui">사용자 인터페이스</string>
<string name="settings">설정</string>
<string name="enterBarcodeInstructions">카드 ID를 입력하고 카드에서 사용하는 바코드 이미지를 선택하세요. 바코드를 사용하지 않는 경우 “이 카드는 바코드가 없음”을 선택하세요.</string>
<string name="app_revision_fmt">리비전 정보: <xliff:g id="app_revision_url">%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="selectBarcodeTitle">바코드 선택</string>
<string name="about">정보</string>
<string name="exporting">내보내는 중…</string>
<string name="importing">가져오는 중…</string>
<string name="importExportHelp">데이터를 백업하면 다른 장치로 이동할 수 있습니다.</string>
<string name="importExportHelp">카드를 백업하면 다른 장치로 옮길 수 있습니다.</string>
<string name="exportName">내보내기</string>
<string name="importExport">가져오기/내보내기</string>
<string name="cardShortcut">카드 바로 가기</string>
<string name="scanCardBarcode">바코드 스캔</string>
<string name="scanCardBarcode">카드 바코드 스캔</string>
<string name="addCardTitle">카드 추가</string>
<string name="editCardTitle">카드 편집</string>
<string name="sendLabel">보내기…</string>
@@ -38,7 +38,7 @@
<string name="unstar">즐겨찾기에서 제거</string>
<string name="star">즐겨찾기에 추가</string>
<string name="noBarcode">바코드 없음</string>
<string name="barcodeNoBarcode">바코드가 없습니다</string>
<string name="barcodeNoBarcode">이 카드는 바코드가 없</string>
<string name="barcodeType">바코드 형식</string>
<string name="cardId">카드 ID</string>
<string name="note">노트</string>
@@ -49,22 +49,22 @@
<string name="action_add">추가</string>
<string name="action_search">검색</string>
<string name="copy_to_clipboard_toast">카드 ID를 클립보드에 복사함</string>
<string name="importOptionApplicationTitle">다른 앱 사용</string>
<string name="importOptionApplicationTitle">외부 앱 사용</string>
<string name="importOptionFilesystemExplanation">파일 시스템에서 파일을 선택합니다.</string>
<string name="importOptionFilesystemTitle">파일 시스템에서 가져오기</string>
<string name="exportFailed">내보내기를 수행할 수 없습니다</string>
<string name="exportFailed">카드를 내보낼 수 없</string>
<string name="importOptionApplicationExplanation">다른 파일 관리자 또는 앱을 사용하여 파일을 엽니다.</string>
<string name="exportFailedTitle">내보내기 실패</string>
<string name="exportSuccessfulTitle">내보내기 완료</string>
<string name="importFailed">가져오기를 수행할 수 없습니다</string>
<string name="importFailed">카드를 가져올 수 없</string>
<string name="importFailedTitle">가져오기 실패</string>
<string name="importSuccessfulTitle">가져오기 완료</string>
<string name="noCardIdError">ID를 입력하지 않았습니다</string>
<string name="noCardIdError">카드 ID를 입력하지 않</string>
<string name="storeName">이름</string>
<string name="thumbnailDescription">카드 섬네일</string>
<string name="importOptionApplicationButton">다른 앱 사용</string>
<string name="importOptionApplicationButton">외부 앱 사용</string>
<string name="failedParsingImportUriError">가져온 URI를 분석할 수 없음</string>
<string name="noCardExistsError">해당 카드를 찾을 수 없습니다</string>
<string name="noCardExistsError">카드를 찾을 수 없</string>
<string name="moveUp">목록에서 위로 옮기기</string>
<string name="leaveWithoutSaveTitle">저장하지 않고 종료</string>
<string name="moveDown">목록에서 아래로 옮기기</string>
@@ -73,8 +73,5 @@
<string name="settings_display_barcode_max_brightness">바코드를 표시할 때 화면 밝기 높이기</string>
<string name="barcode">바코드</string>
<string name="deleteConfirmation">정말 이 카드를 삭제하시겠습니까\?</string>
<string name="deleteTitle">카드 </string>
<plurals name="deleteCardsTitle">
<item quantity="other">카드 <xliff:g>%d</xliff:g> 제거</item>
</plurals>
<string name="deleteTitle">카드 제</string>
</resources>

View File

@@ -54,7 +54,6 @@
<string name="updateBarcodeQuestionTitle">Aktualiséiert barcode-Wäert\?</string>
<string name="intent_import_card_from_url_share_text">Ech wëll eng Kaart mat dir deelen</string>
<string name="importSuccessfulTitle">Anere sproochen</string>
<string name="unsupportedBarcodeType">Dee barcode-Typ kann net ugewise ginn. Et kann zu enger spéiderer Versioun vun der App ënnerstëtzt ginn.</string>
<string name="yes">Jo</string>
<string name="importFailedTitle">Import fehlgeschlagen</string>
<string name="importFailed">Kaarten konnten net anere sproochen ginn</string>

View File

@@ -1,7 +1,7 @@
<?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">Norėdami pridėti kortelę, spustelėkite mygtuką + arba importuokite kortelę iš ⋮ meniu.</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>
@@ -14,13 +14,13 @@
<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">Nuskaityti brūkšninį kodą</string>
<string name="scanCardBarcode">Skenuoti kortelės brūkšninį kodą</string>
<string name="noStoreError">Neįvestas pavadinimas</string>
<string name="noCardIdError">Neįvestas ID</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="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>
@@ -30,16 +30,16 @@
<string name="debug_version_fmt">Versija: <xliff:g id="version">%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">ID nukopijuota į iškarpinę</string>
<string name="card_ids_copied">Nukopijuoti ID</string>
<string name="copy_to_clipboard_toast">Kortelės ID nukopijuota į iškarpinę</string>
<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="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">Brūkšninio kodo nėra</string>
<string name="barcodeNoBarcode">Ši kortelė neturi brūkšninio kodo</string>
<string name="barcodeType">Brūkšninio kodo tipas</string>
<string name="noMatchingGiftCards">Rezultatų nėra. Pabandykite pakeisti paiešką.</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.
@@ -60,21 +60,20 @@
<string name="passwordRequired">Įveskite slaptažodį</string>
<string name="no">Ne</string>
<string name="yes">Taip</string>
<string name="updateBarcodeQuestionText">Pakeitėte ID. Ar norite atnaujinti ir brūkšninį kodą, kad būtų naudojama ta pati reikšmė\?</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">Galinis vaizdas</string>
<string name="frontImageDescription">Priekinis vaizdas</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">ID nukopijuotas į iškarpinę</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 ID</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.
\nGaukite susisiekę el. paštu support@stocardapp.com, prašydami eksportuoti jūsų duomenis.</string>
@@ -90,7 +89,7 @@
\n
\nJOKIE DUOMENYS NĖRA RENKAMI, o tai gali patvirtinti bet kas, nes mūsų programėlė yra laisvoji programinė įranga.</string>
<string name="privacy_policy">Privatumo politika</string>
<string name="chooseImportType">Importuoti duomenis iš</string>
<string name="chooseImportType">Importuoti duomenis iš\?</string>
<string name="points">Taškai</string>
<string name="currency">Valiuta</string>
<string name="balance">Balansas</string>
@@ -107,7 +106,7 @@
<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 ID</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>
@@ -120,24 +119,24 @@
<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 mygtuką +, kad pridėtumėte grupes kategorizavimui.</string>
<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">Duomenys eksportuoti</string>
<string name="importSuccessful">Duomenys importuoti</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_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">Sistemos</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">Miniatiūra</string>
<string name="enterBarcodeInstructions">Įveskite ID ir toliau pasirinkite brūkšninio kodo tipą arba \"Nėra brūkšninio kodo\".</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">Laisvosios trečiųjų šalių ištekliai: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries">Laisvosios trečiųjų šalių bibliotekos: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_copyright_old">Paremta Loyalty Card Keychain
@@ -154,8 +153,8 @@
<string name="exportSuccessfulTitle">Eksportuota</string>
<string name="importFailedTitle">Importuoti nepavyko</string>
<string name="importSuccessfulTitle">Importuota</string>
<string name="importExportHelp">Duomenų atsarginių kopijų darymas leidžia perkelti juos į kitą įrenginį.</string>
<string name="noCardExistsError">Nepavyko rasti šios kortelės</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>
@@ -187,11 +186,11 @@
<string name="settings_catima_theme">Catima</string>
<string name="settings_theme_color">Temos spalva</string>
<string name="app_contributors">Tapo įmanoma su pagalba: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="noGroupCards">Grupėje yra tuščia</string>
<string name="barcodeImageDescriptionWithType"><xliff:g>%s</xliff:g> brūkšninio kodo vaizdas</string>
<string name="swipeToSwitchImages">Braukite, kad perjungtumėte vaizdus, palaikykite, kad atvertumėte vaizdą galerijos programėlėje</string>
<string name="noGroupCards">Šioje grupėje ra jokių kortelių</string>
<string name="barcodeImageDescriptionWithType"><xliff:g>%s</xliff:g> tipo kortelės brūkšninio kodo vaizdas</string>
<string name="swipeToSwitchImages">Perbraukite arba ilgai palaikykite paspaudę, kad perjungtumėte vaizdus</string>
<string name="sort_by">Rikiuoti pagal</string>
<string name="reverse">…atvirkštine tvarka</string>
<string name="reverse">Atvirkštinis</string>
<string name="sort_by_balance">Balansas</string>
<string name="sort_by_expiry">Galiojimo pabaiga</string>
<string name="sort_by_most_recently_used">Vėliausiai naudota</string>
@@ -214,60 +213,10 @@
<string name="editGroup">Redaguojama grupė: <xliff:g>%s</xliff:g></string>
<string name="group_updated">Grupė atnaujinta</string>
<string name="group_edit">Redaguoti grupę</string>
<string name="noGiftCardsGroup">Sukurkite keletą kortelių ir priskirkite jas grupei čia.</string>
<string name="noGiftCardsGroup">Dar neturite jokių lojalumo kortelių. Kai kelias pridėsite, galėsite jas priskirti grupei čia.</string>
<string name="setIcon">Nustatyti piktogramą</string>
<string name="selectColor">Pasirinkti spalvą</string>
<string name="action_hide_details">Paslėpti informaciją</string>
<string name="action_show_details">Rodyti išsamią informaciją</string>
<string name="settings_card_orientation">Brūkšninio kodo orientacija</string>
<string name="archiveList">Archyvas</string>
<string name="noUnarchivedCardsMessage">Nėra išarchyvuotų kortelių</string>
<string name="failedLaunchingPhotoPicker">Nepavyko rasti palaikomos galerijos programėlės</string>
<string name="previousCard">Ankstesnė</string>
<string name="nextCard">Kita</string>
<plurals name="viewArchivedCardsWithCount">
<item quantity="one">Peržiūrėti archyvą (<xliff:g>%1$d</xliff:g> kortelė)</item>
<item quantity="few">Peržiūrėti archyvą (<xliff:g>%1$d</xliff:g> kortelės)</item>
<item quantity="other">Peržiūrėti archyvą (<xliff:g>%1$d</xliff:g> kortelių)</item>
</plurals>
<plurals name="groupCardCountWithArchived">
<item quantity="one"><xliff:g>%1$d</xliff:g> kortelė ( archyvuota)<xliff:g id="archivedCount">%2$d</xliff:g></item>
<item quantity="few"><xliff:g>%1$d</xliff:g> kortelės ( archyvuotos)<xliff:g id="archivedCount">%2$d</xliff:g></item>
<item quantity="other"><xliff:g>%1$d</xliff:g> kortelių ( archyvuotų)<xliff:g id="archivedCount">%2$d</xliff:g></item>
</plurals>
<string name="set_scale">Nustatyti mastelį</string>
<string name="hideMoreInfo">Slėpti informaciją</string>
<string name="updateBalance">Atnaujinti balansą</string>
<string name="failedToRetrieveImageFile">Nepavyko gauti vaizdo failo</string>
<string name="barcodeLongPressMessage">Galerijos programėlėje galima atidaryti tik vaizdus</string>
<string name="translate_platform">Weblate svetainėje</string>
<string name="shortcutSelectCard">Pasirinkti kortelę</string>
<string name="options">Parinktys</string>
<string name="starred">Pažymėta žvaigždute</string>
<string name="include_if_asking_support">Jei norite prašyti pagalbos, įtraukite šią informaciją:</string>
<string name="archive">Archyvuoti</string>
<string name="duplicateCard">Dubliuoti</string>
<string name="unarchive">Išarchyvuoti</string>
<string name="archived">Kortelė archyvuota</string>
<string name="unarchived">Kortelė išarchyvuota</string>
<string name="updateBalanceTitle">Kiek išleidote\?</string>
<string name="updateBalanceHint">Įveskite sumą</string>
<string name="currentBalanceSentence">Dabartinis likutis: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Naujas balansas: <xliff:g>%s</xliff:g></string>
<string name="failedToOpenUrl">Pirmiausia įdiekite žiniatinklio naršyklę</string>
<string name="welcome">Sveiki užėję į Catima</string>
<string name="showMoreInfo">Rodyti informaciją</string>
<string name="settings_oled_dark">Visiškai juodas fonas tamsiajai temai</string>
<string name="settings_follow_system_orientation">Sekti sistemą</string>
<string name="settings_portrait_orientation">Portretas</string>
<string name="settings_landscape_orientation">Gulsčias</string>
<string name="settings_lock_on_opening_orientation">Užfiksuoti padėtį, kuri naudojama atidarant kortelę</string>
<string name="cameraPermissionDeniedTitle">Nepavyko pasiekti kameros</string>
<string name="noCameraPermissionDirectToSystemSetting">Skanuoti brūkšniniams kodams Catima reikės gauti leidimo naudotis jūsų kamera. Spustelkite čia norėdami pakeisti leidimų nustatymus.</string>
<plurals name="balancePoints">
<item quantity="one"><xliff:g>%s</xliff:g> taškas</item>
<item quantity="few"><xliff:g>%s</xliff:g> taškai</item>
<item quantity="other"><xliff:g>%s</xliff:g> taškų</item>
</plurals>
<string name="importCards">Importuoti korteles</string>
</resources>

View File

@@ -1,13 +1,13 @@
<?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_search">Meklēt</string>
<resources>
<string name="action_search">Meklēšana</string>
<string name="action_add">Pievienot</string>
<string name="noGiftCards">Noklikšķiniet uz pogas + plus, lai pievienotu karti, vai vispirms importējiet dažus no ⋮ izvēlnes.</string>
<string name="noMatchingGiftCards">Nav rezultātu. Mēģiniet mainīt meklējamo tekstu.</string>
<string name="noMatchingGiftCards">Neko neatradu. Mēģiniet mainīt meklēšanu.</string>
<string name="storeName">Nosaukums</string>
<string name="note">Piezīme</string>
<string name="barcodeType">Svītrkoda tips</string>
<string name="barcodeNoBarcode">Bez svītrkoda</string>
<string name="barcodeType">Svītrkoda Tips</string>
<string name="barcodeNoBarcode">Šai kartei nav svītrkoda</string>
<string name="noBarcode">Nav svītrkoda</string>
<string name="star">Pievienot izlasei</string>
<string name="unstar">Noņemt no izlases</string>
@@ -21,240 +21,73 @@
<string name="balance">Bilance</string>
<string name="noBarcodeFound">Svītrkods netika atrasts</string>
<string name="currency">Valūta</string>
<string name="points">Punkti</string>
<string name="chooseImportType">Importēt datus no</string>
<string name="points">Punkts</string>
<string name="chooseImportType">Importēt datus no\?</string>
<string name="sendLabel">Nosūtīt…</string>
<string name="editCardTitle">Rediģēt karti</string>
<string name="share">Kopīgot</string>
<string name="editCardTitle">Rediģēt Karti</string>
<string name="share">Daļa</string>
<string name="confirm">Apstiprināt</string>
<string name="deleteTitle">Dzēst karti</string>
<string name="deleteConfirmation">Neatgriezeniski dzēst šo karti\?</string>
<string name="ok">Labi</string>
<string name="addCardTitle">Pievienot karti</string>
<string name="scanCardBarcode">Skenēt svītrkodu</string>
<string name="cardShortcut">Kartes saīsne</string>
<string name="deleteConfirmation">Dzēst šo karti pastāvīgi\?</string>
<string name="ok">LABI</string>
<string name="addCardTitle">Pievienot Karti</string>
<string name="scanCardBarcode">Skenēšanas Kartes Svītrkods</string>
<string name="cardShortcut">Kartes Saīsne</string>
<string name="noCardsMessage">Vispirms pievienojiet karti</string>
<string name="noStoreError">Vārds nav ievadīts</string>
<string name="noCardExistsError">Nevarēja atrast karti</string>
<string name="failedParsingImportUriError">Nevarēja parsēt importa URI</string>
<string name="importExport">Imports/Eksports</string>
<string name="exportName">Eksports</string>
<string name="importExportHelp">Dublējot Jūsu datus, tos var pārnest uz citu ierīci.</string>
<string name="importExportHelp">Jūsu Karšu dublēšana ļauj pārvietot tās uz citu ierīci.</string>
<string name="importSuccessfulTitle">Importēts</string>
<string name="importFailedTitle">Imports neizdevās</string>
<string name="importFailed">Karšu importu nevarēja veikt</string>
<string name="exportSuccessfulTitle">Eksportēts</string>
<string name="importFailedTitle">Neizdevās importēt</string>
<string name="importFailed">Nevarēja importēt kartes</string>
<string name="exportSuccessfulTitle">Eksports</string>
<string name="exportFailedTitle">Eksports neizdevās</string>
<string name="exportFailed">Kartes neizdevās eksportēt</string>
<string name="importing">Importē</string>
<string name="exporting">Eksportē</string>
<string name="exportFailed">Nevarēja eksportēt kartes</string>
<string name="importing">Imports</string>
<string name="exporting">Eksports</string>
<string name="noExternalStoragePermissionError">Piešķiriet ārējai atmiņai atļauju vispirms importēt vai eksportēt kartes</string>
<string name="exportOptionExplanation">Dati tiks saglabāti Jūsu izvēlētajā vietā.</string>
<string name="importOptionFilesystemTitle">Imports no failu sistēmas</string>
<string name="exportOptionExplanation">Dati tiks rakstīts uz vietu, pēc jūsu izvēles.</string>
<string name="importOptionFilesystemTitle">Importēt no failu sistēmas</string>
<string name="importOptionFilesystemExplanation">Izvēlieties konkrētu failu no failu sistēmas.</string>
<string name="importOptionFilesystemButton">No failu sistēmas</string>
<string name="importOptionApplicationTitle">Izmantojot citu lietotni</string>
<string name="importOptionApplicationTitle">Izmantojiet citu lietotni</string>
<string name="importOptionApplicationExplanation">Izmantojiet jebkuru lietotni vai savu iecienītāko failu pārvaldnieku, lai atvērtu failu.</string>
<string name="importOptionApplicationButton">Ar citu lietotni</string>
<string name="importOptionApplicationButton">Izmantojiet citu lietotni</string>
<string name="about">Par</string>
<string name="app_license">Copyleft brīva un atvērta programmatūra, licencēta GPLv3+</string>
<string name="selectBarcodeTitle">Izvēlieties svītrkodu</string>
<string name="copy_to_clipboard_toast">Numurs kopēts starpliktuvē</string>
<string name="thumbnailDescription">Sīktēls</string>
<string name="starImage">Izlases zvaigzne</string>
<string name="settings">Iestatījumi</string>
<string name="app_license">Copylefted libre programmatūra, licencēta GPLv3+</string>
<string name="selectBarcodeTitle">Izvēlieties Svītrkodu</string>
<string name="copy_to_clipboard_toast">Kartes ID kopēts starpliktuvē</string>
<string name="thumbnailDescription">Sīktēls kartei</string>
<string name="starImage">Mīļākā zvaigzne</string>
<string name="settings">Iestatījums</string>
<string name="settings_category_title_ui">Interfeiss</string>
<string name="settings_theme">Tēma</string>
<string name="settings_system_theme">Sistēmas</string>
<string name="settings_light_theme">Gaiša</string>
<string name="settings_dark_theme">Tumša</string>
<string name="settings_max_font_size_scale">Maksimālais burtu lielums</string>
<string name="settings_display_barcode_max_brightness">Izgaismot svītrkoda skatu</string>
<string name="settings_keep_screen_on">Turēt ekrānu ieslēgtu</string>
<string name="settings_disable_lockscreen_while_viewing_card">Neļaut ekrānam aizslēgties</string>
<string name="intent_import_card_from_url_share_text">Es vēlos ar Jums kopīgot karti</string>
<string name="importSuccessful">Dati importēti</string>
<string name="exportSuccessful">Dati eksportēti</string>
<string name="noGroups">Spiediet uz \"+\" plus pogas, lai pievienotu grupas karšu kategorizēšanai.</string>
<string name="noGroupCards">Šī grupa ir tukša</string>
<string name="all">Visas</string>
<string name="settings_system_theme">Sistēma</string>
<string name="settings_light_theme">Gaisma</string>
<string name="settings_dark_theme">Tumšs</string>
<string name="settings_max_font_size_scale">Max. fonts</string>
<string name="settings_display_barcode_max_brightness">Izgaismojiet svītrkoda skatu</string>
<string name="settings_keep_screen_on">Saglabāt ekrānu</string>
<string name="settings_disable_lockscreen_while_viewing_card">Novērst bloķēšanas ekrānu</string>
<string name="intent_import_card_from_url_share_text">Es vēlos dalīties ar jums karti</string>
<string name="importSuccessful">Importētie kartes dati</string>
<string name="exportSuccessful">Kartes dati eksportēti</string>
<string name="noGroups">Noklikšķiniet uz pogas + plus, lai vispirms pievienotu grupas kategorizēšanai.</string>
<string name="noGroupCards">Šajā grupā nav nevienas kartes</string>
<string name="all">Visi</string>
<string name="deleteConfirmationGroup">Dzēst grupu\?</string>
<string name="failedOpeningFileManager">Vispirms instalējiet failu pārvaldnieku.</string>
<string name="moveUp">Pārvietot uz augšu</string>
<string name="moveDown">Pārvietot uz leju</string>
<string name="leaveWithoutSaveTitle">Iziet</string>
<string name="leaveWithoutSaveConfirmation">Iziet nesaglabājot\?</string>
<string name="addFromImage">Izvēlēties attēlu no galerijas</string>
<string name="leaveWithoutSaveTitle">Izeja</string>
<string name="leaveWithoutSaveConfirmation">Atstāt bez taupīšanas\?</string>
<string name="addFromImage">Izvēlieties attēlu no galerijas</string>
<string name="card">Karte</string>
<string name="barcode">Svītrkods</string>
<string name="expiryDate">Derīguma termiņš</string>
<string name="never">Nekad</string>
<string name="chooseExpiryDate">Izvēlieties derīguma termiņu</string>
<string name="failedToRetrieveImageFile">Neizdevās ielādēt attēla failu</string>
<string name="barcodeLongPressMessage">Galerijas lietotnē var atvērt tikai attēlus</string>
<string name="sort_by_expiry">Derīguma termiņš</string>
<string name="reverse">...apgrieztā secībā</string>
<string name="credits">Pateicības</string>
<string name="shortcutSelectCard">Izvēlieties karti</string>
<string name="set_scale">Iestatiet mērogu</string>
<string name="duplicateCard">Dublēt</string>
<string name="archive">Arhivēt</string>
<string name="translate_platform">vietnē Weblate</string>
<string name="starred">Izlase</string>
<string name="cardId">Kartes numurs</string>
<string name="enterBarcodeInstructions">Ievadiet kartes numuru un izvēlieties svītrkoda tipu (vai izvēlieties \"bez svītrkoda\").</string>
<plurals name="deleteCardsConfirmation">
<item quantity="zero">Neatgriezeniski dzēst šīs <xliff:g>%d</xliff:g> kartes\?</item>
<item quantity="one">Neatgriezeniski dzēst šo <xliff:g>%d</xliff:g> karti\?</item>
<item quantity="other">Neatgriezeniski dzēst šīs <xliff:g>%d</xliff:g> kartes\?</item>
</plurals>
<string name="noCardIdError">Numurs nav ievadīts</string>
<string name="about_title_fmt">Par <xliff:g id="app_name">%s</xliff:g></string>
<string name="app_revision_fmt">Versijas pārskats: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Derīguma termiņš beidzās: <xliff:g>%s</xliff:g></string>
<string name="action_hide_details">Slēpt detaļas</string>
<string name="action_show_details">Rādīt detalizēti</string>
<string name="selectColor">Izvēlieties krāsu</string>
<string name="settings_catima_theme">Catima</string>
<string name="settings_pink_theme">Rozā</string>
<string name="settings_magenta_theme">Purpura</string>
<string name="settings_sky_blue_theme">Gaiši zila</string>
<string name="settings_green_theme">Zaļa</string>
<string name="sort_by_name">Nosaukums</string>
<string name="on_google_play">pakalpojumā Google Play</string>
<string name="report_error">Ziņojiet par kļūdu</string>
<plurals name="balancePoints">
<item quantity="zero"><xliff:g>%s</xliff:g> punkti</item>
<item quantity="one"><xliff:g>%s</xliff:g> punkts</item>
<item quantity="other"><xliff:g>%s</xliff:g> punkti</item>
</plurals>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> nešķiet derīga bilance.</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="privacy_policy_popup_text">Paziņojums par privātuma politiku (nepieciešams dažiem lietotņu veikaliem):
\n
\nNEKĀDI DATI NETIEK VĀKTI, par ko var pārliecināties ikkatrs, jo mūsu lietotne ir brīva, atvērta koda programmatūra.</string>
<string name="importCatimaMessage">Izvēlieties jūstu <i>catima.zip</i> failu importam.
\nFailu var izveidot eksportējot datus no Catima lietotnes citā ierīce, sadaļā \"Imports/Eksports\".</string>
<string name="importLoyaltyCardKeychainMessage">Importam izvēlieties Jūsu <i>LoyaltyCardKeychain.csv</i> eksporta failu no Loyalty Card Keychain.
\nFailu var izveidot \"Imports/Eksports\" izvēlnē Loyalty Card Keychain lietotnē, spiežot \"Eksportēt\".</string>
<string name="removeImage">Noņemt attēlu</string>
<string name="exportPasswordHint">Ievadiet paroli</string>
<string name="on_github">vietnē GitHub</string>
<string name="settings_locale">Valoda</string>
<string name="failedGeneratingShareURL">Nevarēja izveidot koplietojamu URL. Lūdzu, ziņojiet par šo kļūdu.</string>
<string name="turn_flashlight_off">Izslēgt zibspuldzi</string>
<string name="app_contributors">To padarīja iespējamu: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="sort_by_balance">Bilance</string>
<string name="version_history">Versiju vēsture</string>
<string name="sort_by">Kārtot pēc</string>
<string name="help_translate_this_app">Palīdziet tulkot šo lietotni</string>
<string name="and_data_usage">un datu lietojums</string>
<string name="license">Licence</string>
<string name="source_repository">Pirmkods</string>
<string name="rate_this_app">Novērtējiet šo lietotni</string>
<string name="noGiftCardsGroup">Izveidojiet kartes, un pēc tam šeit pievienojiet tās grupai.</string>
<string name="options">Parametri</string>
<plurals name="groupCardCount">
<item quantity="zero"><xliff:g>%d</xliff:g> kartes</item>
<item quantity="one"><xliff:g>%d</xliff:g> karte</item>
<item quantity="other"><xliff:g>%d</xliff:g> kartes</item>
</plurals>
<plurals name="deleteCardsTitle">
<item quantity="zero">Dzēst <xliff:g>%d</xliff:g> kartes</item>
<item quantity="one">Dzēst <xliff:g>%d</xliff:g> karti</item>
<item quantity="other">Dzēst <xliff:g>%d</xliff:g> kartes</item>
</plurals>
<string name="updateBarcodeQuestionText">Jūs izmainījāt numuru. Vai vēlaties arī atjaunināt svītrkodu ar tādu pašu vērtību\?</string>
<string name="updateBarcodeQuestionTitle">Atjaunināt svītrkoda vērtību\?</string>
<string name="yes"></string>
<string name="no"></string>
<string name="settings_system_locale">Sistēmas</string>
<string name="include_if_asking_support">Ja vēlaties lūgt atbalstu, lūdzu iekļaujiet sekojošo informāciju:</string>
<string name="card_ids_copied">Kopētie numuri</string>
<string name="barcodeImageDescriptionWithType"><xliff:g>%s</xliff:g> svītrkoda attēls</string>
<string name="privacy_policy">Privātuma politika</string>
<string name="accept">Apstiprināt</string>
<string name="editGroup">Grupas rediģēšana: <xliff:g>%s</xliff:g></string>
<string name="settings_brown_theme">Brūna</string>
<string name="copy_to_clipboard">Kopēt kartes numuru starpliktuvē</string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Autortiesības © 2019<xliff:g>%d</xliff:g> Sylvia van Os</string>
<string name="app_copyright_old">Balstīta uz Loyalty Card Keychain
\nautortiesības © 20162020 Branden Archer</string>
<string name="debug_version_fmt">Versija: <xliff:g id="version">%s</xliff:g></string>
<string name="app_libraries">Brīvas trešo pušu programmatūras bibliotēkas: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources">Brīvi trešo pušu resursi: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="settings_card_orientation">Svītrkoda orientācija</string>
<string name="settings_follow_system_orientation">Pēc sistēmas</string>
<string name="settings_portrait_orientation">Portreta</string>
<string name="settings_landscape_orientation">Ainavas</string>
<string name="settings_lock_on_opening_orientation">Ievērot to orientāciju, kādā karte atvērta</string>
<string name="enter_group_name">Ievadiet grupas nosaukumu</string>
<string name="groups">Grupas</string>
<string name="group_edit">Rediģēt grupu</string>
<string name="group_name_already_in_use">Jau ir grupa ar šādu nosaukumu</string>
<string name="group_name_is_empty">Grupas nosaukums nevar būt tukšs</string>
<string name="group_updated">Grupa atjaunināta</string>
<string name="addManually">Ievadīt numuru manuāli</string>
<string name="groupsList">Grupas: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentence">Derīguma termiņš: <xliff:g>%s</xliff:g></string>
<string name="balanceSentence">Bilance: <xliff:g>%s</xliff:g></string>
<string name="editBarcode">Rediģēt svītrkodu</string>
<string name="importCatima">Importēt no Catima</string>
<string name="importFidme">Importēt no FidMe</string>
<string name="importFidmeMessage">Importam izvēlieties Jūsu <i>fidme-export-request-xxxxxx.zip</i> FidMe eksportēto failu, un pēc tam manuāli precizējiet svītrkodu tipus.
\nFailu var izveidot Jūsu FidMe profilā, ejot uz \"Data Protection\" un spiežot \"Extract my data\".</string>
<string name="importLoyaltyCardKeychain">Importēt no Loyalty Card Keychain</string>
<string name="importStocard">Importēt no Stocard</string>
<string name="importStocardMessage">Importam izvēlieties Jūsu <i>***-sync.zip</i> eksporta failu no Stocard.
\nFailu var iegūt sūtot e-pastu uz support@stocardapp.com ar pieprasījumu eksportēt Jūsu datus.</string>
<string name="importVoucherVault">Importēt no Voucher Vault</string>
<string name="importVoucherVaultMessage">Importam izvēlieties Jūsu <i>vouchervault.json</i> failu no Voucher Vault.
\nFailu var izveidot spiežot \"Eksportēt\" Voucher Vault lietotnē.</string>
<string name="barcodeId">Svītrkoda vērtība</string>
<string name="sameAsCardId">Tāpat kā numurs</string>
<string name="setBarcodeId">Norādiet svītrkoda vērtību</string>
<string name="unsupportedBarcodeType">Šo svītrkoda tipu pagaidām nav iespējams attēlot. Iespējams, nākotnē tas tiks atbalstīts vēlākā lietotnes versijā.</string>
<string name="wrongValueForBarcodeType">Šī vērtība nav derīga izvēlētajam svītrkoda tipam</string>
<string name="copy_to_clipboard_multiple_toast">Numuri kopēti starpliktuvē</string>
<string name="intent_import_card_from_url_share_multiple_text">Vēlos koplietot kartes</string>
<string name="frontImageDescription">Priekšas attēls</string>
<string name="backImageDescription">Aizmugures attēls</string>
<string name="photos">Foto</string>
<string name="setFrontImage">Iestatīt priekšas attēlu</string>
<string name="setBackImage">Iestatīt aizmugures attēlu</string>
<string name="takePhoto">Fotografēt</string>
<string name="passwordRequired">Ievadiet paroli</string>
<string name="exportPassword">Iestatiet paroli, lai aizsargātu eksporta failu (nav obligāti)</string>
<string name="turn_flashlight_on">Ieslēgt zibspuldzi</string>
<string name="settings_oled_dark">Tīri melns fons tumšajai tēmai</string>
<string name="setIcon">Iestatīt ikonu</string>
<string name="settings_theme_color">Tēmas krāsa</string>
<string name="settings_violet_theme">Violeta</string>
<string name="settings_blue_theme">Zila</string>
<string name="settings_grey_theme">Pelēka</string>
<string name="sort">Kārtot</string>
<string name="showMoreInfo">Rādīt informāciju</string>
<string name="hideMoreInfo">Slēpt informāciju</string>
<string name="swipeToSwitchImages">Velciet, lai pārslēgtu attēlus; spiediet un turiet lai atvērtu attēlu galerijas lietotnē</string>
<string name="sort_by_most_recently_used">Nesen lietotās</string>
<string name="unarchive">Atarhivēt</string>
<string name="archived">Karte arhivēta</string>
<string name="unarchived">Karte atarhivēta</string>
<string name="archiveList">Arhīvs</string>
<string name="noUnarchivedCardsMessage">Nav atarhivētu karšu</string>
<string name="failedLaunchingPhotoPicker">Nevarēja atrast atbalstītu galerijas lietotni</string>
<string name="previousCard">Iepriekšējā</string>
<string name="nextCard">Nākamā</string>
<plurals name="viewArchivedCardsWithCount">
<item quantity="zero">Skatīt arhivētu (<xliff:g>%1$d</xliff:g> karti)</item>
<item quantity="one">Skatīt arhivētu (<xliff:g>%1$d</xliff:g> karti)</item>
<item quantity="other">Skatīt arhivētas (<xliff:g>%1$d</xliff:g> kartes)</item>
</plurals>
<plurals name="groupCardCountWithArchived">
<item quantity="zero"><xliff:g>%1$d</xliff:g> card (<xliff:g id="archivedCount">%2$d</xliff:g> arhivēta)</item>
<item quantity="one"><xliff:g>%1$d</xliff:g> card (<xliff:g id="archivedCount">%2$d</xliff:g> arhivēta)</item>
<item quantity="other"><xliff:g>%1$d</xliff:g> cards (<xliff:g id="archivedCount">%2$d</xliff:g> arhivētas)</item>
</plurals>
<string name="failedToOpenUrl">Vispirms nepieciešams uzstādīt interneta pārlūku</string>
<string name="welcome">Laipni lūgti Catima</string>
</resources>

View File

@@ -116,7 +116,6 @@
<string name="errorReadingImage">Kunne 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 ID</string>
<string name="barcodeId">Strekkodeverdi</string>
@@ -183,7 +182,7 @@
<string name="settings_theme_color">Draktfarge</string>
<string name="noGroupCards">Denne gruppen er tom</string>
<string name="barcodeImageDescriptionWithType">Bilde av <xliff:g>%s</xliff:g>-strekkode</string>
<string name="swipeToSwitchImages">Dra for å bytte bilder, hold for å åpne et bilde i galleriet.</string>
<string name="swipeToSwitchImages">Dra eller hold lenge for å bygge bilder</string>
<string name="sort_by">Sortering</string>
<string name="reverse">…i omvendt rekkefølge</string>
<string name="sort_by_balance">Saldo</string>
@@ -253,14 +252,4 @@
<item quantity="one">Vis arkiv (<xliff:g>%1$d</xliff:g> kort)</item>
<item quantity="other">Vis arkiv (<xliff:g>%1$d</xliff:g> kort)</item>
</plurals>
<string name="failedToRetrieveImageFile">Kunne ikke hente bildefil</string>
<string name="barcodeLongPressMessage">Kun bilder kan åpnes i galleriet</string>
<string name="cameraPermissionDeniedTitle">Fikk ikke tilgang til kameraet</string>
<string name="noCameraPermissionDirectToSystemSetting">Catima trenger kameratilgang for å skanne strekkoder. Trykk her for å endre tilgangsinnstillingene.</string>
<string name="importCards">Importer kort</string>
<string name="currentBalanceSentence">Nåværende saldo: <xliff:g>%s</xliff:g></string>
<string name="updateBalanceTitle">Hvor mye brukte du\?</string>
<string name="updateBalanceHint">Skriv inn beløp</string>
<string name="newBalanceSentence">Ny saldo: <xliff:g>%s</xliff:g></string>
<string name="updateBalance">Oppdater saldo</string>
</resources>

View File

@@ -130,7 +130,6 @@
<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>
@@ -185,7 +184,7 @@
<string name="app_contributors">Mede mogelijk gemaakt door: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="noGroupCards">Deze groep bevat geen kaarten</string>
<string name="barcodeImageDescriptionWithType">Afbeelding van barcode <xliff:g>%s</xliff:g></string>
<string name="swipeToSwitchImages">Veeg om te bladeren; houd lang ingedrukt om te openen in de galerij-app</string>
<string name="swipeToSwitchImages">Veeg of houd lang ingedrukt om te bladeren</string>
<string name="sort_by">Sorteren op</string>
<string name="reverse">…in omgekeerde volgorde</string>
<string name="sort_by_balance">Op saldo</string>
@@ -253,14 +252,4 @@
<item quantity="one">Archief bekijken (<xliff:g>%1$d</xliff:g> kaart)</item>
<item quantity="other">Archief bekijken (<xliff:g>%1$d</xliff:g> kaarten)</item>
</plurals>
<string name="failedToRetrieveImageFile">De afbeelding kan niet worden opgehaald</string>
<string name="barcodeLongPressMessage">Alleen afbeeldingen kunnen worden geopend in de galerij-app</string>
<string name="cameraPermissionDeniedTitle">Geen cameratoegang</string>
<string name="updateBalanceTitle">Hoeveel heb je uitgegeven\?</string>
<string name="noCameraPermissionDirectToSystemSetting">Catima heeft toegang tot je camera nodig om barcodes te kunnen scannen. Druk hier om toegang te verlenen.</string>
<string name="currentBalanceSentence">Huidig saldo: <xliff:g>%s</xliff:g></string>
<string name="updateBalance">Saldo bijwerken</string>
<string name="updateBalanceHint">Voer een bedrag in</string>
<string name="newBalanceSentence">Nieuw saldo: <xliff:g>%s</xliff:g></string>
<string name="importCards">Kaarten importeren</string>
</resources>

View File

@@ -24,13 +24,13 @@
<string name="noCardsMessage">Najpierw dodaj kartę</string>
<string name="noStoreError">Nie wprowadzono nazwy</string>
<string name="noCardIdError">Nie wprowadzono identyfikatora</string>
<string name="noCardExistsError">Nie można znaleźć tej karty lojalnościowej</string>
<string name="noCardExistsError">Nie można wyszukać karty lojalnościowej</string>
<string name="failedParsingImportUriError">Nie można przeanalizować identyfikatora importu URI</string>
<string name="importExport">Importuj/Eksportuj</string>
<string name="exportName">Eksportuj</string>
<string name="importExportHelp">Kopie zapasowe umożliwiają przeniesienie kart na inne urządzenie.</string>
<string name="importSuccessfulTitle">Zaimportowano</string>
<string name="importFailedTitle">Importowanie nie powioo się</string>
<string name="importFailedTitle">Import nie powiódł się</string>
<string name="importFailed">Nie udało się zaimportować</string>
<string name="exportSuccessfulTitle">Wyeksportowano</string>
<string name="exportFailedTitle">Eksport nie powiódł się</string>
@@ -48,7 +48,7 @@
<string name="app_license">Wolne oprogramowanie typu copyleft, na licencji GPLv3+</string>
<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">Informacje o wydaniu: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="app_revision_fmt">Info o wydaniu: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="selectBarcodeTitle">Wybierz kod kreskowy</string>
<string name="enterBarcodeInstructions">Wprowadź ID, a następnie wybierz typ kodu kreskowego, którego chcesz użyć lub wybierz „Bez kodu kreskowego”.</string>
<string name="copy_to_clipboard_toast">Skopiowano ID do schowka</string>
@@ -63,12 +63,12 @@
<string name="intent_import_card_from_url_share_text">Chcę udostępnić Ci kartę lojalnościową</string>
<string name="deleteConfirmationGroup">Usunąć grupę\?</string>
<string name="all">Wszystko</string>
<string name="noGroups">Kliknij przycisk + plus, aby dodać grupy do kategoryzacji.</string>
<string name="noGroups">Kliknij przycisk + plus, aby dodać grupy w celu kategoryzacji.</string>
<string name="groups">Grupy</string>
<string name="enter_group_name">Wpisz nazwę grupy</string>
<string name="exportSuccessful">Dane zostały wyeksportowane</string>
<string name="importSuccessful">Zaimportowano dane</string>
<string name="starImage">Gwiazdka ulubionych</string>
<string name="starImage">Ulubiona gwiazda</string>
<string name="app_copyright_old">Na podstawie Loyalty Card Keychain
\nWszelkie prawa zastrzeżone © 20162020 Branden Archer</string>
<string name="exportOptionExplanation">Dane zostaną zapisane w wybranym przez Ciebie miejscu.</string>
@@ -109,7 +109,6 @@
<string name="intent_import_card_from_url_share_multiple_text">Chcę Ci udostępnić karty</string>
<string name="copy_to_clipboard_multiple_toast">Skopiowano ID do schowka</string>
<string name="wrongValueForBarcodeType">Wartość nie jest prawidłowa dla wybranego typu kodu kreskowego</string>
<string name="unsupportedBarcodeType">Nie można jeszcze wyświetlić tego typu kodu kreskowego. Być może będzie on obsługiwany w nowszej wersji aplikacji.</string>
<string name="setBarcodeId">Ustaw wartość kodu kreskowego</string>
<string name="sameAsCardId">Taki sam jak ID</string>
<string name="barcodeId">Wartość kodu kreskowego</string>
@@ -206,20 +205,20 @@
<string name="report_error">Zgłoś Błąd</string>
<string name="setIcon">Ustaw ikonę</string>
<string name="on_github">na GitHub\'ie</string>
<string name="swipeToSwitchImages">Przeciągnij aby zmienić obraz, przytrzymaj aby otworzyć obraz w galerii</string>
<string name="swipeToSwitchImages">Przeciągnij lub przytrzymaj aby zmienić obraz</string>
<string name="selectColor">Wybierz kolor</string>
<string name="version_history">Historia Wersji</string>
<string name="and_data_usage">i wykorzystanie danych</string>
<string name="rate_this_app">Oceń tą aplikację</string>
<string name="license">Licencja</string>
<string name="on_google_play">w Google Play</string>
<string name="noGiftCardsGroup">Stwórz karty i przypisz je do grup w tym miejscu.</string>
<string name="noGiftCardsGroup">Stwórz karty i przypisz je do grupy w tym miejscu.</string>
<string name="reverse">...w odwrotnej kolejności</string>
<string name="translate_platform">na Weblate</string>
<string name="sort">Sortuj</string>
<string name="barcodeImageDescriptionWithType">Obraz kodu kreskowego typu <xliff:g>%s</xliff:g></string>
<string name="group_edit">Edytuj Grupę</string>
<string name="group_name_already_in_use">Ta nazwa jest już w użytku</string>
<string name="group_name_already_in_use">Ta nazwa jest już użyta</string>
<string name="group_name_is_empty">Nazwa grupy nie może być pusta</string>
<string name="group_updated">Zaktualizowano grupę</string>
<string name="editGroup">Edytowanie grupy: <xliff:g>%s</xliff:g></string>
@@ -237,7 +236,7 @@
<string name="settings_oled_dark">Całkowicie czarne tło dla ciemnego motywu</string>
<string name="hideMoreInfo">Ukryj informacje</string>
<string name="settings_card_orientation">Orientacja kodu kreskowego</string>
<string name="settings_follow_system_orientation">Śledź orientację systemową</string>
<string name="settings_follow_system_orientation">Śledź system</string>
<string name="set_scale">Ustaw skalę</string>
<string name="duplicateCard">Duplikuj</string>
<string name="starred">Oznaczone gwiazdką</string>
@@ -259,22 +258,4 @@
<item quantity="many"><xliff:g>%1$d</xliff:g> kart (<xliff:g id="archivedCount">%2$d</xliff:g> zarchwizowanych)</item>
<item quantity="other"><xliff:g>%1$d</xliff:g> kart (<xliff:g id="archivedCount">%2$d</xliff:g> zarchwizowanych)</item>
</plurals>
<string name="failedToRetrieveImageFile">Nie udało się pobrać pliku obrazu</string>
<string name="barcodeLongPressMessage">W galerii możesz otworzyć tylko obrazy</string>
<string name="failedToOpenUrl">Najpierw zainstaluj przeglądarkę</string>
<string name="welcome">Witaj w Catima</string>
<plurals name="viewArchivedCardsWithCount">
<item quantity="one">Wyświetl zarchiwizowaną (<xliff:g>%1$d</xliff:g> kartę)</item>
<item quantity="few">Wyświetl zarchiwizowane (<xliff:g>%1$d</xliff:g> karty)</item>
<item quantity="many">Wyświetl zarchiwizowane (<xliff:g>%1$d</xliff:g> karty)</item>
<item quantity="other">Wyświetl zarchiwizowane (<xliff:g>%1$d</xliff:g> karty)</item>
</plurals>
<string name="currentBalanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
<string name="noCameraPermissionDirectToSystemSetting">By zeskanować kody kreskowe, Catima musi mieć dostęp do twojej kamery. Dotknij tutaj by zmienić swoje ustawienia dostępu.</string>
<string name="updateBalanceTitle">Ile wydałeś\?</string>
<string name="updateBalanceHint">Wpisz sumę</string>
<string name="updateBalance">Zaktualizuj balans</string>
<string name="cameraPermissionDeniedTitle">Odmówiono dostępu do kamery</string>
<string name="newBalanceSentence">Nowe saldo: <xliff:g>%s</xliff:g></string>
<string name="importCards">Importuj karty</string>
</resources>

View File

@@ -12,7 +12,7 @@
<string name="cancel">Cancelar</string>
<string name="save">Guardar</string>
<string name="edit">Editar</string>
<string name="noGiftCards">Clique no botão + para adicionar um cartão ou importe-o no menu ⋮.</string>
<string name="noGiftCards">Clique no botão + para adicionar um cartão ou importe um no botão do menu ⋮.</string>
<string name="noBarcode">Sem código de barras</string>
<string name="unstar">Retirar dos favoritos</string>
<string name="importOptionFilesystemButton">Do sistema de ficheiros</string>
@@ -161,7 +161,6 @@
<string name="importVoucherVault">Importar do Voucher Vault</string>
<string name="importVoucherVaultMessage">Selecione a exportação <i>vouchervault.json</i> do Voucher Vault para importar.
\nCrie-a primeiro pressionando a opção \"Exportar\" no Voucher Vault.</string>
<string name="unsupportedBarcodeType">Este tipo de código de barras ainda não pode ser mostrado. Pode vir a ser suportado numa versão posterior da aplicação.</string>
<string name="copy_to_clipboard_multiple_toast">Identificação copiado para a área de transferência</string>
<string name="setFrontImage">Definir imagem frontal</string>
<string name="setBackImage">Definir imagem de trás</string>
@@ -178,7 +177,7 @@
<string name="settings_blue_theme">Azul</string>
<string name="app_contributors">Tornado possível por: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="sort">Ordenar</string>
<string name="swipeToSwitchImages">Deslize para mudar as imagens, toque prolongadamente para abrir na aplicação da galeria</string>
<string name="swipeToSwitchImages">Deslize ou pressione prolongadamente para mudar as imagens</string>
<string name="sort_by_name">Nome</string>
<string name="sort_by_most_recently_used">Mais usados recentemente</string>
<string name="sort_by_expiry">Validade</string>
@@ -260,14 +259,4 @@
<item quantity="other">Ver arquivo (<xliff:g>%1$d</xliff:g> cartões)</item>
</plurals>
<string name="welcome">Bem-vindo ao Catima</string>
<string name="failedToRetrieveImageFile">Falha ao recuperar o ficheiro de imagem</string>
<string name="barcodeLongPressMessage">Apenas imagens podem ser abertas na aplicação de galeria</string>
<string name="noCameraPermissionDirectToSystemSetting">Para digitalizar código de barras, o Catima tem de aceder à câmara. Clique aqui para mudar as configurações de permissão.</string>
<string name="cameraPermissionDeniedTitle">Não foi possível aceder à câmara</string>
<string name="importCards">Importar cartões</string>
<string name="currentBalanceSentence">Saldo atual: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Novo saldo: <xliff:g>%s</xliff:g></string>
<string name="updateBalance">Atualizar saldo</string>
<string name="updateBalanceTitle">Quanto gastou\?</string>
<string name="updateBalanceHint">Introduza o valor</string>
</resources>

View File

@@ -4,7 +4,7 @@
<string name="cardId">Cardului ID</string>
<string name="note">Notă</string>
<string name="storeName">Numele</string>
<string name="noMatchingGiftCards">Nu au fost găsite rezultate. Încercați să schimbați termenii de căutare.</string>
<string name="noMatchingGiftCards">Nu am găsit nimic. Încearcă să schimbi căutarea.</string>
<string name="noGiftCards">Faceți clic pe butonul + plus pentru a adăuga o carte sau importați mai întâi câteva din meniul ⋮.</string>
<string name="action_add">Adăugați</string>
<string name="action_search">Căutare</string>
@@ -21,13 +21,13 @@
<string name="unstar">Eliminați din favorite</string>
<string name="star">Adaugă la favorite</string>
<string name="noBarcode">Fără cod de bare</string>
<string name="barcodeNoBarcode">Nu există cod de bare</string>
<string name="barcodeNoBarcode">Acest card nu are cod de bare</string>
<string name="moveDown">Mutarea în jos</string>
<string name="card">Cardul</string>
<string name="settings_theme">Tema</string>
<string name="all">Toate</string>
<string name="noCardsMessage">Adăugați mai întâi o carte</string>
<string name="noCardExistsError">Acel card nu a putut fi găsit</string>
<string name="noCardExistsError">Nu a putut găsi cardul</string>
<string name="failedParsingImportUriError">Nu s-a putut analiza URI-ul de import</string>
<string name="importExport">Importație/Export</string>
<string name="exportName">Exportați</string>
@@ -88,23 +88,12 @@
<string name="errorReadingImage">Nu s-a putut citi imaginea</string>
<string name="points">Puncte</string>
<string name="cardShortcut">Scurtătură de card</string>
<string name="scanCardBarcode">Scanați codul de bare</string>
<string name="importExportHelp">Copierea de rezervă a datelor vă permite să le mutați pe un alt dispozitiv</string>
<string name="scanCardBarcode">Scanarea codului de bare al cardului</string>
<string name="importExportHelp">Copierea de rezervă a cardurilor vă permite să le mutați pe un alt dispozitiv.</string>
<string name="exportSuccessfulTitle">Exportată</string>
<string name="exportFailedTitle">Export eșuat</string>
<string name="importOptionFilesystemExplanation">Alegeți un anumit fișier din sistemul de fișiere.</string>
<string name="importOptionApplicationButton">Utilizați o altă aplicație</string>
<string name="thumbnailDescription">Miniatură pentru card</string>
<string name="enter_group_name">Introduceți numele grupului</string>
<string name="yes">Da</string>
<string name="no">Nu</string>
<string name="archive">Arhivați</string>
<string name="archiveList">Arhivă</string>
<string name="passwordRequired">Vă rugăm, introduceți parola</string>
<string name="unsupportedBarcodeType">Acest tip de cod de bare nu poate fi afișat. Este posibil ca acesta să se poată afișa într-o versiune mai nouă a aplicației.</string>
<string name="photos">Imagini</string>
<string name="noGiftCardsGroup">Adăugați câteva carduri, iar apoi atribuiți-le grupului aici.</string>
<string name="importCatima">Importați din Catima</string>
<string name="importStocard">Importați din Stocard</string>
<string name="intent_import_card_from_url_share_multiple_text">Aș dori să partajez niște carduri cu tine</string>
</resources>

View File

@@ -132,7 +132,6 @@
<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>
@@ -193,7 +192,7 @@
<string name="app_contributors">Создано при поддержке: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="noGroupCards">Группа пуста</string>
<string name="barcodeImageDescriptionWithType">Изображение штрих-кода <xliff:g>%s</xliff:g></string>
<string name="swipeToSwitchImages">Смахивание переключает изображения, долгое нажатие открывает в приложении галереи</string>
<string name="swipeToSwitchImages">Смахивание или долгое нажатие для переключения изображений</string>
<string name="sort_by_expiry">Срок действия</string>
<string name="sort_by">Сортировать по</string>
<string name="reverse">…в обратном порядке</string>
@@ -267,14 +266,4 @@
<item quantity="many">Просмотр архива (<xliff:g>%1$d</xliff:g> карт)</item>
<item quantity="other">Просмотр архива (<xliff:g>%1$d</xliff:g> карт)</item>
</plurals>
<string name="failedToRetrieveImageFile">Невозможно получить файл изображения</string>
<string name="barcodeLongPressMessage">В приложении галереи можно открывать только изображения</string>
<string name="noCameraPermissionDirectToSystemSetting">Для сканирования штрих-кодов Catima требуется доступ к камере устройства. Нажмите здесь, чтобы изменить настройки разрешений.</string>
<string name="updateBalance">Обновить баланс</string>
<string name="newBalanceSentence">Новый баланс: <xliff:g>%s</xliff:g></string>
<string name="currentBalanceSentence">Текущий баланс: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">Камера недоступна</string>
<string name="updateBalanceHint">Введите сумму</string>
<string name="updateBalanceTitle">Какое изменение\?</string>
<string name="importCards">Импорт карт</string>
</resources>

View File

@@ -190,7 +190,6 @@
<string name="barcodeId">Hodnota čiarového kódu</string>
<string name="sameAsCardId">Rovnaké ako ID</string>
<string name="setBarcodeId">Nastavenie hodnoty čiarového kódu</string>
<string name="unsupportedBarcodeType">Tento typ čiarového kódu zatiaľ nie je možné zobraziť. Možno bude podporovaný v neskoršej verzii aplikácie.</string>
<string name="wrongValueForBarcodeType">Hodnota nie je platná pre vybraný typ čiarového kódu</string>
<string name="frontImageDescription">Obrázok prednej strany</string>
<string name="backImageDescription">Obrázok zadnej strany</string>
@@ -205,5 +204,4 @@
<string name="passwordRequired">Zadajte prosím heslo</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> sa nezdá byť platným zostatkom.</string>
<string name="noGiftCardsGroup">Zatiaľ nemáte žiadne vernostné karty. Keď nejaké pridáte, môžete ich priradiť ku skupine tu.</string>
<string name="noCameraPermissionDirectToSystemSetting"></string>
</resources>

View File

@@ -156,5 +156,4 @@
<string name="updateBarcodeQuestionText">Spremenili ste številko kartice. Želite posodobiti tudi črtno kodo na enako vrednost?</string>
<string name="updateBarcodeQuestionTitle">Posodobi črtno kodo?</string>
<string name="removeImage">Odstrani sliko</string>
<string name="unsupportedBarcodeType">Te vrste črtne kode aplikacija ne more prikazati. Morda bo to možno v prihodnosti.</string>
</resources>

View File

@@ -72,7 +72,6 @@
<string name="intent_import_card_from_url_share_multiple_text">Jag vill dela några kort med dig</string>
<string name="copy_to_clipboard_multiple_toast">ID:n kopierades till Urklipp</string>
<string name="wrongValueForBarcodeType">Värdet är inte giltigt för den valda streckkodstypen</string>
<string name="unsupportedBarcodeType">Denna streckkodstyp kan ännu inte visas. Den kan komma att stödjas i en senare version av appen.</string>
<string name="setBarcodeId">Ange streckkodsvärde</string>
<string name="sameAsCardId">Samma som ID:t</string>
<string name="turn_flashlight_on">Sätt på ficklampa</string>

View File

@@ -1,6 +1,6 @@
<?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="swipeToSwitchImages">Resimler arasında geçiş yapmak için kaydırın, resmi galeri uygulamasında açmak için basılı tutun</string>
<string name="swipeToSwitchImages">Resimler arasında geçiş yapmak için kaydırın veya uzun basın</string>
<string name="app_contributors">Katkıda bulunanlar: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="settings_brown_theme">Kahverengi</string>
<string name="settings_grey_theme">Gri</string>
@@ -32,7 +32,6 @@
<string name="intent_import_card_from_url_share_multiple_text">Seninle birkaç kart paylaşmak istiyorum</string>
<string name="copy_to_clipboard_multiple_toast">Numaralar panoya kopyalandı</string>
<string name="wrongValueForBarcodeType">Değer, seçilen barkod türü için geçerli değil</string>
<string name="unsupportedBarcodeType">Bu barkod türü henüz görüntülenemiyor. Uygulamanın sonraki bir sürümünde desteklenebilir.</string>
<string name="setBarcodeId">Barkod değerini ayarla</string>
<string name="sameAsCardId">Numarayla aynı</string>
<string name="barcodeId">Barkod değeri</string>
@@ -179,7 +178,7 @@
<string name="note">Not</string>
<string name="storeName">Ad</string>
<string name="noMatchingGiftCards">Sonuç yok. Aramanızı değiştirmeyi deneyin.</string>
<string name="noGiftCards">Bir kart eklemek için + artı düğmesine tıklayın veya ⋮ menüsünden içe aktarın.</string>
<string name="noGiftCards">Bir kart eklemek için + artı düğmesine tıklayın veya ⋮ menüsünden birkaçını içe aktarın.</string>
<plurals name="selectedCardCount">
<item quantity="one"><xliff:g>%d</xliff:g> seçildi</item>
<item quantity="other"><xliff:g>%d</xliff:g> seçildi</item>
@@ -253,14 +252,4 @@
<item quantity="other">Arşivi görüntüle (<xliff:g>%1$d</xliff:g> kart)</item>
</plurals>
<string name="welcome">Catima\'ya Hoş Geldiniz</string>
<string name="failedToRetrieveImageFile">Resim dosyası alınamadı</string>
<string name="barcodeLongPressMessage">Galeri uygulamasında yalnızca resimler açılabilir</string>
<string name="noCameraPermissionDirectToSystemSetting">Barkodları taramak için Catima\'nın kameranıza erişmesi gerekecektir. İzin ayarlarınızı değiştirmek için buraya dokunun.</string>
<string name="currentBalanceSentence">Geçerli bakiye: <xliff:g>%s</xliff:g></string>
<string name="updateBalanceHint">Miktarı girin</string>
<string name="updateBalanceTitle">Ne kadar harcadınız\?</string>
<string name="newBalanceSentence">Yeni bakiye: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">Kameraya erişilemedi</string>
<string name="updateBalance">Bakiyeyi güncelle</string>
<string name="importCards">Kartları içe aktar</string>
</resources>

View File

@@ -3,7 +3,7 @@
<string name="privacy_policy_popup_text">Політика конфіденційності (вимагається деякими магазинами):
\n
\nЖОДНОЇ ІНФОРМАЦІЇ НЕ ЗБИРАЄТЬСЯ, що може підтвердити будь-хто, адже наша програма це вільне програмне забезпечення.</string>
<string name="noGiftCards">Натисніть кнопку +, щоб додати картку, або ⋮ для імпорту з меню.</string>
<string name="noGiftCards">Натисніть + щоб додати карту чи імпортуйте з ⋮ меню.</string>
<string name="settings_display_barcode_max_brightness">Яскравіший штрих-код</string>
<string name="enterBarcodeInstructions">Введіть ID та оберіть тип штрих-коду чи \"Не має штрих-коду\".</string>
<string name="selectBarcodeTitle">Оберіть штрих-код</string>
@@ -22,7 +22,6 @@
<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>
@@ -193,7 +192,7 @@
<string name="app_contributors">Стало можливим завдяки: <xliff:g id="app_contributors">%s</xliff:g></string>
<string name="noGroupCards">Пуста група</string>
<string name="barcodeImageDescriptionWithType">Зображення штрих-коду <xliff:g>%s</xliff:g></string>
<string name="swipeToSwitchImages">Свайп для зміни зображень, довге натискання для перегляду в галереї</string>
<string name="swipeToSwitchImages">Свайп чи довге натискання для зміни зображень</string>
<string name="sort_by">Сортувати за</string>
<string name="reverse">у зворотному порядку</string>
<string name="sort_by_balance">Баланс</string>
@@ -262,19 +261,9 @@
<plurals name="viewArchivedCardsWithCount">
<item quantity="one">Переглянути архів (<xliff:g>%1$d</xliff:g> картка)</item>
<item quantity="few">Переглянути архів (<xliff:g>%1$d</xliff:g> картки)</item>
<item quantity="many">Переглянути архів (<xliff:g>%1$d</xliff:g> карток)</item>
<item quantity="other">Переглянути архів (<xliff:g>%1$d</xliff:g> карток)</item>
<item quantity="many">Переглянути архів (<xliff:g>%1$d</xliff:g> картки)</item>
<item quantity="other">Переглянути архів (<xliff:g>%1$d</xliff:g> картки)</item>
</plurals>
<string name="failedToOpenUrl">Спочатку встановіть браузер</string>
<string name="welcome">Ласкаво просимо до Catima</string>
<string name="failedToRetrieveImageFile">Збій доступу до файлу зображення</string>
<string name="barcodeLongPressMessage">Галерея може відкривати лише зображення</string>
<string name="importCards">Імпорт карток</string>
<string name="updateBalanceTitle">Скільки витратили\?</string>
<string name="updateBalanceHint">Введіть суму</string>
<string name="currentBalanceSentence">Поточний баланс: <xliff:g>%s</xliff:g></string>
<string name="newBalanceSentence">Новий баланс: <xliff:g>%s</xliff:g></string>
<string name="cameraPermissionDeniedTitle">Не вдалося отримати доступ до камери</string>
<string name="noCameraPermissionDirectToSystemSetting">Для сканування штрих-кодів програмі Catima потрібен доступ до вашої камери. Натисніть тут, щоб змінити дозволи.</string>
<string name="updateBalance">Оновити баланс</string>
<string name="welcome">Ласкаво просимо до Катіма</string>
</resources>

View File

@@ -19,7 +19,6 @@
<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>
@@ -95,8 +94,6 @@
<string name="importOptionFilesystemTitle">从文件系统导入</string>
<string name="exportOptionExplanation">导出的数据将储存至你选择的位置.</string>
<string name="noExternalStoragePermissionError">在导入导出前需要获得外部储存权限</string>
<string name="cameraPermissionDeniedTitle">无法访问相机</string>
<string name="noCameraPermissionDirectToSystemSetting">Catima需要访问您的相机来扫描条形码. 轻触这里以更改您的权限设置。</string>
<string name="exporting">导出中…</string>
<string name="importing">导入中…</string>
<string name="exportFailed">无法导出卡片</string>
@@ -135,7 +132,7 @@
<string name="note">备注</string>
<string name="storeName">名称</string>
<string name="noMatchingGiftCards">没有结果。尝试改变你的搜索。</string>
<string name="noGiftCards">点击 \"+\"加号按钮来添加卡片,或者从⋮ 菜单导入。</string>
<string name="noGiftCards">点击 \"+\"加号按钮来添加卡片,或者从⋮ 菜单导入一些</string>
<string name="action_add">添加</string>
<string name="action_search">搜索</string>
<string name="deleteConfirmation">删除此卡?</string>
@@ -201,7 +198,7 @@
<string name="sort_by_name">名称</string>
<string name="help_translate_this_app">帮助翻译此应用</string>
<string name="sort_by_balance">余额</string>
<string name="swipeToSwitchImages">滑动切换图片,按住打开图库应用中的图片</string>
<string name="swipeToSwitchImages">滑动或长按来切换图片</string>
<string name="reverse">倒序</string>
<string name="sort_by">排序方式</string>
<string name="selectColor">选择颜色</string>
@@ -245,15 +242,4 @@
<string name="noUnarchivedCardsMessage">没有未归档卡</string>
<string name="failedToOpenUrl">先安装一个浏览器</string>
<string name="welcome">欢迎使用Catima</string>
<string name="updateBalanceHint">输入金额</string>
<string name="importCards">导入卡</string>
<plurals name="viewArchivedCardsWithCount">
<item quantity="other">查看存档(<xliff:g>%1$d</xliff:g> 张卡片)</item>
</plurals>
<string name="updateBalance">更新余额</string>
<string name="updateBalanceTitle">你花了多少钱?</string>
<string name="currentBalanceSentence">当前余额:<xliff:g>%s</xliff:g></string>
<string name="failedToRetrieveImageFile">无法检索图像文件</string>
<string name="newBalanceSentence">新余额:<xliff:g>%s</xliff:g></string>
<string name="barcodeLongPressMessage">只能在图库应用程序中打开图像</string>
</resources>

View File

@@ -194,7 +194,6 @@
<string name="moveBarcodeToTopOfScreen">將條碼移至螢幕上方</string>
<string name="moveBarcodeToCenterOfScreen">將條碼移至螢幕中央</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="unsupportedBarcodeType">尚支援此條碼種類,但未來版本的應用程式可能會支援此條碼種類。</string>
<string name="wrongValueForBarcodeType">條碼內容不適用於此條碼種類</string>
<string name="backImageDescription">背面圖片</string>
<string name="updateBarcodeQuestionText">您已更新了 ID是否要更新條碼內容以匹配此 ID</string>
@@ -224,28 +223,4 @@
<string name="set_scale">設定大小</string>
<string name="include_if_asking_support">如果您想請求協助,請附上以下訊息:</string>
<string name="settings_card_orientation">條碼方向</string>
<string name="failedToRetrieveImageFile">無法擷取圖片檔案</string>
<string name="barcodeLongPressMessage">圖庫應用程式僅可開啟圖片</string>
<string name="duplicateCard">重複</string>
<string name="archive">封存</string>
<string name="unarchive">解除封存</string>
<string name="archived">卡片已封存</string>
<string name="unarchived">卡片已解除封存</string>
<plurals name="groupCardCountWithArchived">
<item quantity="other"><xliff:g>%1$d</xliff:g> 張卡片 (<xliff:g id="archivedCount">%2$d</xliff:g> 張已封存)</item>
</plurals>
<string name="settings_portrait_orientation">直向</string>
<string name="settings_follow_system_orientation">跟隨系統</string>
<string name="settings_landscape_orientation">橫向</string>
<string name="failedToOpenUrl">先安裝網頁瀏覽器</string>
<string name="archiveList">封存</string>
<string name="failedLaunchingPhotoPicker">無法找到支援的圖庫應用程式</string>
<string name="previousCard">上一張</string>
<string name="noUnarchivedCardsMessage">沒有已封存的卡片</string>
<string name="nextCard">下一張</string>
<string name="welcome">歡迎使用 Catima</string>
<plurals name="viewArchivedCardsWithCount">
<item quantity="other">檢視封存 (<xliff:g>%1$d</xliff:g> 張卡片)</item>
</plurals>
<string name="settings_lock_on_opening_orientation">開啟卡片時鎖定的方向</string>
</resources>

Some files were not shown because too many files have changed in this diff Show More