Compare commits

...

74 Commits

Author SHA1 Message Date
Sylvia van Os
de8aa6b6fd Release v1.14.1 2021-06-14 21:27:44 +02:00
Sylvia van Os
a5a7be02f6 Translators are awesome <3 2021-06-14 21:18:21 +02:00
Sylvia van Os
14b7f8af81 Merge pull request #237 from weblate/weblate-catima-catima
Translations update from Weblate
2021-06-14 06:57:44 +02:00
huuhaa
62d01abf92 Translated using Weblate (Finnish)
Currently translated at 100.0% (155 of 155 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fi/
2021-06-14 04:32:36 +02:00
solokot
a328fa8f4a Translated using Weblate (Russian)
Currently translated at 100.0% (155 of 155 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2021-06-14 04:32:34 +02:00
Sylvia van Os
9e55271db1 Merge pull request #236 from weblate/weblate-catima-catima
Translations update from Weblate
2021-06-13 01:17:04 +02:00
huuhaa
e09ba941b8 Added translation using Weblate (Finnish) 2021-06-13 01:11:13 +02:00
Sylvia van Os
7562b662b7 Update target SDK 2021-06-10 16:50:38 +02:00
Sylvia van Os
ce65163377 Don't show update barcode dialog if value is the same as card ID 2021-06-10 16:49:52 +02:00
Sylvia van Os
da445255ec Merge branch 'master' of github.com:TheLastProject/loyalty-card-locker 2021-06-10 13:18:00 +02:00
Sylvia van Os
fb36aecf42 Add missing barcode ID field to export 2021-06-10 13:17:48 +02:00
Sylvia van Os
3d624eae97 Merge pull request #233 from weblate/weblate-catima-catima
Translations update from Weblate
2021-06-08 05:21:38 +02:00
solokot
0a05676a87 Translated using Weblate (Russian)
Currently translated at 100.0% (155 of 155 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2021-06-08 02:46:40 +02:00
Heimen Stoffels
bce6ae0da6 Translated using Weblate (Dutch)
Currently translated at 100.0% (155 of 155 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nl/
2021-06-08 02:46:40 +02:00
J. Lavoie
2268465d2e Translated using Weblate (Italian)
Currently translated at 100.0% (155 of 155 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/it/
2021-06-08 02:46:40 +02:00
J. Lavoie
7a9953cfee Translated using Weblate (French)
Currently translated at 100.0% (155 of 155 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fr/
2021-06-08 02:46:40 +02:00
J. Lavoie
ecc11c120b Translated using Weblate (German)
Currently translated at 100.0% (155 of 155 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/de/
2021-06-08 02:46:39 +02:00
Sylvia van Os
f4d4e3d6fb Release v1.14 2021-06-07 20:21:48 +02:00
Sylvia van Os
929633e4dd Ask to update barcode value if card ID changes 2021-06-06 21:13:44 +02:00
Sylvia van Os
eec7359603 Merge pull request #230 from weblate/weblate-catima-catima
Translations update from Weblate
2021-05-25 12:07:42 +02:00
solokot
4168ec3b43 Translated using Weblate (Russian)
Currently translated at 100.0% (3 of 3 strings)

Translation: Catima/Fastlane
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ru/
2021-05-25 08:33:41 +02:00
Sylvia van Os
6568ebb01c Merge pull request #224 from weblate/weblate-catima-catima
Translations update from Weblate
2021-05-09 11:56:14 +02:00
Heimen Stoffels
99e2a75d46 Translated using Weblate (Dutch)
Currently translated at 100.0% (3 of 3 strings)

Translation: Catima/Fastlane
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/nl/
2021-05-09 11:33:39 +02:00
Allan Nordhøy
43ae42c7c5 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (3 of 3 strings)

Translation: Catima/Fastlane
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/nb_NO/
2021-05-09 11:33:39 +02:00
Allan Nordhøy
a7aa3e9e0e Shorter title and description (#220) 2021-05-08 00:51:49 +02:00
Weblate (bot)
5a9f0a44fd Translations update from Weblate (#222)
* Translated using Weblate (Japanese)

Currently translated at 100.0% (151 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ja/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 99.3% (150 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/zh_Hans/

Co-authored-by: Nyatsuki <Odamaki@yandex.ru>
Co-authored-by: Kevin Sicong Jiang <kev4313@yahoo.com>
2021-05-02 13:02:04 +02:00
Kevin Sicong Jiang
4a1858e47b Fix active tab lost on rotation (#221) 2021-05-01 23:41:19 +02:00
Sylvia van Os
d8d8a59707 Merge pull request #219 from weblate/weblate-catima-catima
Translations update from Weblate
2021-05-01 10:57:58 +02:00
Kevin Sicong Jiang
b027beea35 Added translation using Weblate (Chinese (Simplified)) 2021-05-01 10:35:08 +02:00
Sylvia van Os
b4d0651e99 Merge pull request #216 from weblate/weblate-catima-catima
Translations update from Weblate
2021-04-29 13:42:59 +02:00
Allan Nordhøy
b40380dff6 Translated using Weblate (Slovenian)
Currently translated at 41.7% (63 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/sl/
2021-04-29 13:32:10 +02:00
Allan Nordhøy
b1a0a98004 Translated using Weblate (Norwegian Bokmål)
Currently translated at 84.1% (127 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nb_NO/
2021-04-29 13:32:10 +02:00
J. Lavoie
044d363f47 Translated using Weblate (Italian)
Currently translated at 100.0% (151 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/it/
2021-04-29 13:32:09 +02:00
J. Lavoie
35d659be31 Translated using Weblate (French)
Currently translated at 100.0% (151 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fr/
2021-04-29 13:32:09 +02:00
Adolfo Jayme Barrientos
8bc1e2d321 Translated using Weblate (Spanish)
Currently translated at 77.4% (117 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/es/
2021-04-29 13:32:09 +02:00
J. Lavoie
b8811ba053 Translated using Weblate (German)
Currently translated at 100.0% (151 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/de/
2021-04-29 13:32:08 +02:00
Sylvia van Os
cbaf172e9d Merge branch 'master' of github.com:TheLastProject/loyalty-card-locker 2021-04-28 12:45:39 +02:00
Sylvia van Os
78c831cb68 Add Voucher Vault PDF 417 export support
a2911e0738
2021-04-28 12:45:02 +02:00
Sylvia van Os
279e775fb6 Merge pull request #212 from weblate/weblate-catima-catima
Translations update from Weblate
2021-04-27 09:12:53 +02:00
solokot
e5b30c9528 Translated using Weblate (Russian)
Currently translated at 100.0% (151 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2021-04-27 04:01:04 +02:00
Heimen Stoffels
eb9732658f Translated using Weblate (Dutch)
Currently translated at 100.0% (151 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nl/
2021-04-27 04:01:03 +02:00
Sylvia van Os
5feb59612d Merge branch 'master' of github.com:TheLastProject/loyalty-card-locker 2021-04-26 20:58:20 +02:00
Sylvia van Os
09bd9b3882 Update CHANGELOG 2021-04-26 20:54:53 +02:00
Sylvia van Os
beb619000c Merge pull request #211 from weblate/weblate-catima-catima
Translations update from Weblate
2021-04-26 20:53:33 +02:00
Heimen Stoffels
72425dd39e Translated using Weblate (Dutch)
Currently translated at 100.0% (151 of 151 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nl/
2021-04-26 20:52:01 +02:00
Sylvia van Os
a93d240d9a Fix translation oops 2021-04-26 20:51:48 +02:00
Sylvia van Os
d380e284b1 Merge pull request #205 from TheLastProject/feature/multiselect
Support multi-selection
2021-04-26 20:18:06 +02:00
Sylvia van Os
cbbb434aae spotBugs 2021-04-26 20:12:05 +02:00
Sylvia van Os
6dc8490b5e Fix lint 2021-04-26 19:42:57 +02:00
Sylvia van Os
b2c57258b3 Fix unit tests 2021-04-26 19:23:22 +02:00
Sylvia van Os
fe0ae4049b Merge pull request #209 from weblate/weblate-catima-catima
Translations update from Weblate
2021-04-25 11:14:23 +02:00
Nyatsuki
0517a7514e Translated using Weblate (Japanese)
Currently translated at 100.0% (3 of 3 strings)

Translation: Catima/Fastlane
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ja/
2021-04-25 09:32:11 +02:00
Sylvia van Os
39544ac853 Really fix typo 2021-04-18 22:43:38 +02:00
Sylvia van Os
f46e1d09ba Fix typo 2021-04-18 22:42:41 +02:00
Sylvia van Os
6421f09eab Implement multi-copy and multi-share 2021-04-18 13:47:51 +02:00
Arshbeer Singh
45663065f9 WIP Issue #14 (and #65)
Implement Functionality to Copy Multiple Cards
2021-04-18 00:43:03 +02:00
Arshbeer Singh
67328724fa WIP Issue #14 (and #65)
Add Ability to Select Multiple Cards
Highlight Card on Long Press/Click
Replace ListView with RecyclerView for Extra Features and Functionality
Add Card Long Press Animations
Replace CursorAdapter with a combination of RecyclerViewAdapter and Cursor Adapter
2021-04-17 23:16:54 +02:00
Arshbeer Singh
55373e82a5 Fix Issue #65 2021-04-17 15:48:48 +02:00
Sylvia van Os
acdb5d6fe7 Merge pull request #203 from weblate/weblate-catima-catima
Translations update from Weblate
2021-04-17 13:30:03 +02:00
Nyatsuki
d9461c476a Translated using Weblate (Japanese)
Currently translated at 100.0% (147 of 147 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ja/
2021-04-17 13:27:05 +02:00
solokot
deee5f6aa2 Translated using Weblate (Russian)
Currently translated at 100.0% (147 of 147 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/ru/
2021-04-17 13:27:03 +02:00
Heimen Stoffels
efd2b1ffe1 Translated using Weblate (Dutch)
Currently translated at 100.0% (147 of 147 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/nl/
2021-04-17 13:27:02 +02:00
J. Lavoie
a87d8bbfe4 Translated using Weblate (Italian)
Currently translated at 100.0% (147 of 147 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/it/
2021-04-17 13:27:02 +02:00
J. Lavoie
a1d5275063 Translated using Weblate (French)
Currently translated at 100.0% (147 of 147 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fr/
2021-04-17 13:27:01 +02:00
J. Lavoie
e327306955 Translated using Weblate (German)
Currently translated at 100.0% (147 of 147 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/de/
2021-04-17 13:27:01 +02:00
Sylvia van Os
9469ae37e1 Merge pull request #202 from weblate/weblate-catima-catima
Translations update from Weblate
2021-04-16 12:02:17 +02:00
Nyatsuki
9e2d65b2cd Added translation using Weblate (Japanese) 2021-04-16 11:26:53 +02:00
Allan Nordhøy
d509c06815 App strings reworked 3 (#188) 2021-04-15 21:51:41 +02:00
Sylvia van Os
70faa7636a Merge pull request #201 from weblate/weblate-catima-catima
Translations update from Weblate
2021-04-15 21:30:42 +02:00
psa-jforestier
4072bc7607 Translated using Weblate (French)
Currently translated at 100.0% (147 of 147 strings)

Translation: Catima/Catima
Translate-URL: https://hosted.weblate.org/projects/catima/catima/fr/
2021-04-15 21:26:59 +02:00
Sylvia van Os
eced502985 Merge pull request #200 from weblate/weblate-catima-catima
Translations update from Weblate
2021-04-14 16:06:52 +02:00
solokot
47441dbb9a Translated using Weblate (Russian)
Currently translated at 100.0% (3 of 3 strings)

Translation: Catima/Fastlane
Translate-URL: https://hosted.weblate.org/projects/catima/fastlane/ru/
2021-04-14 15:27:05 +02:00
Allan Nordhøy
e7729d9763 README reworked (#191) 2021-04-12 22:11:21 +02:00
Sylvia van Os
df40b72f77 Fastlane fixes 2021-04-11 00:26:22 +02:00
91 changed files with 2179 additions and 964 deletions

View File

@@ -1,5 +1,22 @@
# Changelog
## v1.14.1 (2021-06-14)
Changes:
- Add missing barcode ID to export
- Don't show update barcode dialog if value is the same as card ID
- Add Finnish translation
## v1.14 (2021-06-07)
Changes:
- Support new PDF417 export from Voucher Vault
- Support copying multiple barcodes at once
- Support sharing multiple loyalty cards at once
- Ask to update barcode value if card ID changes
## v1.13 (2021-04-10)
Changes:

View File

@@ -11,15 +11,15 @@ spotbugs {
}
android {
compileSdkVersion 29
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "me.hackerchick.catima"
minSdkVersion 19
targetSdkVersion 29
versionCode 67
versionName "1.13"
targetSdkVersion 30
versionCode 69
versionName "1.14.1"
vectorDrawables.useSupportLibrary true
}

View File

@@ -87,9 +87,9 @@ public class AboutActivity extends AppCompatActivity
"<br/><br/>" +
getString(R.string.app_license) +
"<br/><br/>" +
String.format(getString(R.string.app_libraries), appName, libs.toString()) +
String.format(getString(R.string.app_libraries), libs.toString()) +
"<br/><br/>" +
String.format(getString(R.string.app_resources), appName, resources.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT));
String.format(getString(R.string.app_resources), resources.toString()), HtmlCompat.FROM_HTML_MODE_COMPACT));
aboutTextView.setMovementMethod(LinkMovementMethod.getInstance());
}

View File

@@ -4,9 +4,6 @@ import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
@@ -28,6 +25,10 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.Map;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
/**
* This activity is callable and will allow a user to enter
* barcode data and generate all barcodes possible for

View File

@@ -0,0 +1,87 @@
package protect.card_locker;
import android.database.Cursor;
import androidx.recyclerview.widget.RecyclerView;
public abstract class BaseCursorAdapter<V extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<V>
{
private Cursor mCursor;
private boolean mDataValid;
private int mRowIDColumn;
public BaseCursorAdapter(Cursor inputCursor)
{
setHasStableIds(true);
swapCursor(inputCursor);
}
public abstract void onBindViewHolder(V inputHolder, Cursor inputCursor);
@Override
public void onBindViewHolder(V inputHolder, int inputPosition)
{
if (!mDataValid)
{
throw new IllegalStateException("Cannot bind view holder when cursor is in invalid state.");
}
if (!mCursor.moveToPosition(inputPosition))
{
throw new IllegalStateException("Could not move cursor to position " + inputPosition + " when trying to bind view holder");
}
onBindViewHolder(inputHolder, mCursor);
}
@Override
public int getItemCount()
{
if (mDataValid)
{
return mCursor.getCount();
}
else
{
return 0;
}
}
@Override
public long getItemId(int inputPosition)
{
if (!mDataValid)
{
throw new IllegalStateException("Cannot lookup item id when cursor is in invalid state.");
}
if (!mCursor.moveToPosition(inputPosition))
{
throw new IllegalStateException("Could not move cursor to position " + inputPosition + " when trying to get an item id");
}
return mCursor.getLong(mRowIDColumn);
}
public void swapCursor(Cursor inputCursor)
{
if (inputCursor == mCursor)
{
return;
}
if (inputCursor != null)
{
mCursor = inputCursor;
mDataValid = true;
notifyDataSetChanged();
}
else
{
notifyItemRangeRemoved(0, getItemCount());
mCursor = null;
mRowIDColumn = -1;
mDataValid = false;
}
}
}

View File

@@ -2,32 +2,28 @@ package protect.card_locker;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.pm.ShortcutInfoCompat;
import androidx.core.content.pm.ShortcutManagerCompat;
import androidx.core.graphics.drawable.IconCompat;
import android.os.Parcelable;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.RecyclerView;
/**
* The configuration screen for creating a shortcut.
*/
public class CardShortcutConfigure extends AppCompatActivity
public class CardShortcutConfigure extends AppCompatActivity implements LoyaltyCardCursorAdapter.CardAdapterListener
{
static final String TAG = "Catima";
final DBHelper mDb = new DBHelper(this);
@Override
public void onCreate(Bundle bundle)
{
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
// Set the result to CANCELED. This will cause nothing to happen if the
@@ -45,53 +41,59 @@ public class CardShortcutConfigure extends AppCompatActivity
final DBHelper db = new DBHelper(this);
// If there are no cards, bail
if(db.getLoyaltyCardCount() == 0)
{
if (db.getLoyaltyCardCount() == 0) {
Toast.makeText(this, R.string.noCardsMessage, Toast.LENGTH_LONG).show();
finish();
}
final ListView cardList = findViewById(R.id.list);
final RecyclerView cardList = findViewById(R.id.list);
cardList.setVisibility(View.VISIBLE);
Cursor cardCursor = db.getLoyaltyCardCursor();
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor);
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor, this);
cardList.setAdapter(adapter);
}
cardList.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Cursor selected = (Cursor) parent.getItemAtPosition(position);
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
private void onClickAction(int position) {
Cursor selected = mDb.getLoyaltyCardCursor();
selected.moveToPosition(position);
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
Log.d(TAG, "Creating shortcut for card " + loyaltyCard.store + "," + loyaltyCard.id);
Log.d(TAG, "Creating shortcut for card " + loyaltyCard.store + "," + loyaltyCard.id);
Intent shortcutIntent = new Intent(CardShortcutConfigure.this, LoyaltyCardViewActivity.class);
shortcutIntent.setAction(Intent.ACTION_MAIN);
// Prevent instances of the view activity from piling up; if one exists let this
// one replace it.
shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Bundle bundle = new Bundle();
bundle.putInt("id", loyaltyCard.id);
bundle.putBoolean("view", true);
shortcutIntent.putExtras(bundle);
Intent shortcutIntent = new Intent(CardShortcutConfigure.this, LoyaltyCardViewActivity.class);
shortcutIntent.setAction(Intent.ACTION_MAIN);
// Prevent instances of the view activity from piling up; if one exists let this
// one replace it.
shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Bundle bundle = new Bundle();
bundle.putInt("id", loyaltyCard.id);
bundle.putBoolean("view", true);
shortcutIntent.putExtras(bundle);
Bitmap icon = Utils.generateIcon(CardShortcutConfigure.this, loyaltyCard.store, loyaltyCard.headerColor, true).getLetterTile();
Parcelable icon = Intent.ShortcutIconResource.fromContext(CardShortcutConfigure.this, R.mipmap.ic_launcher);
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, loyaltyCard.store);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
setResult(RESULT_OK, intent);
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(CardShortcutConfigure.this, String.valueOf(loyaltyCard.id))
.setIntent(shortcutIntent)
.setIcon(IconCompat.createWithAdaptiveBitmap(icon))
.setShortLabel(loyaltyCard.store)
.build();
finish();
}
Intent intent = ShortcutManagerCompat.createShortcutResultIntent(CardShortcutConfigure.this, shortcutInfo);
setResult(RESULT_OK, intent);
@Override
public void onIconClicked(int inputPosition) {
onClickAction(inputPosition);
}
finish();
}
});
@Override
public void onRowClicked(int inputPosition) {
onClickAction(inputPosition);
}
@Override
public void onRowLongClicked(int inputPosition) {
// do nothing
}
}

View File

@@ -6,14 +6,13 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.graphics.Color;
import com.google.zxing.BarcodeFormat;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Currency;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;
public class DBHelper extends SQLiteOpenHelper

View File

@@ -8,15 +8,6 @@ import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
@@ -29,7 +20,13 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class ImportExportActivity extends AppCompatActivity
{

View File

@@ -8,7 +8,6 @@ import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;

View File

@@ -10,6 +10,7 @@ import java.io.InvalidObjectException;
import java.math.BigDecimal;
import java.util.Currency;
import java.util.Date;
import java.util.List;
public class ImportURIHelper {
private static final String STORE = DBHelper.LoyaltyCardDbIds.STORE;
@@ -29,6 +30,7 @@ public class ImportURIHelper {
private final String oldHost;
private final String oldPath;
private final String shareText;
private final String shareMultipleText;
public ImportURIHelper(Context context) {
this.context = context;
@@ -37,6 +39,7 @@ public class ImportURIHelper {
oldHost = "brarcher.github.io";
oldPath = "/loyalty-card-locker/share";
shareText = context.getResources().getString(R.string.intent_import_card_from_url_share_text);
shareMultipleText = context.getResources().getString(R.string.intent_import_card_from_url_share_multiple_text);
}
private boolean isImportUri(Uri uri) {
@@ -126,17 +129,33 @@ public class ImportURIHelper {
return uriBuilder.build();
}
private void startShareIntent(Uri uri) {
public void startShareIntent(List<LoyaltyCard> loyaltyCards) {
int loyaltyCardCount = loyaltyCards.size();
StringBuilder text = new StringBuilder();
if (loyaltyCardCount == 1) {
text.append(shareText);
} else {
text.append(shareMultipleText);
}
text.append("\n\n");
for (int i = 0; i < loyaltyCardCount; i++) {
LoyaltyCard loyaltyCard = loyaltyCards.get(i);
text.append(loyaltyCard.store + ": " + toUri(loyaltyCard));
if (i < (loyaltyCardCount - 1)) {
text.append("\n\n");
}
}
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, shareText + "\n" + uri.toString());
sendIntent.putExtra(Intent.EXTRA_TEXT, text.toString());
sendIntent.setType("text/plain");
Intent shareIntent = Intent.createChooser(sendIntent, null);
context.startActivity(shareIntent);
}
public void startShareIntent(LoyaltyCard loyaltyCard) {
startShareIntent(toUri(loyaltyCard));
}
}

View File

@@ -0,0 +1,37 @@
package protect.card_locker;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.content.Context;
import android.view.View;
public class LoyaltyCardAnimator {
private static AnimatorSet selectedViewIn, defaultViewOut, selectedViewOut, defaultViewIn;
public static void flipView(Context inputContext, final View inputSelectedView, final View inputDefaultView, boolean inputItemSelected) {
selectedViewIn = (AnimatorSet) AnimatorInflater.loadAnimator(inputContext, R.animator.flip_left_in);
defaultViewOut = (AnimatorSet) AnimatorInflater.loadAnimator(inputContext, R.animator.flip_right_out);
selectedViewOut = (AnimatorSet) AnimatorInflater.loadAnimator(inputContext, R.animator.flip_left_out);
defaultViewIn = (AnimatorSet) AnimatorInflater.loadAnimator(inputContext, R.animator.flip_right_in);
final AnimatorSet showFrontAnim = new AnimatorSet();
final AnimatorSet showBackAnim = new AnimatorSet();
selectedViewIn.setTarget(inputSelectedView);
defaultViewOut.setTarget(inputDefaultView);
showFrontAnim.playTogether(selectedViewIn, defaultViewOut);
selectedViewOut.setTarget(inputSelectedView);
defaultViewIn.setTarget(inputDefaultView);
showBackAnim.playTogether(defaultViewIn, selectedViewOut);
if (inputItemSelected) {
showFrontAnim.start();
} else {
showBackAnim.start();
}
}
}

View File

@@ -2,98 +2,296 @@ package protect.card_locker;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.util.SparseBooleanArray;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.Date;
import java.util.ArrayList;
import androidx.cardview.widget.CardView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import protect.card_locker.preferences.Settings;
class LoyaltyCardCursorAdapter extends CursorAdapter
public class LoyaltyCardCursorAdapter extends BaseCursorAdapter<LoyaltyCardCursorAdapter.LoyaltyCardListItemViewHolder>
{
Settings settings;
private static int mCurrentSelectedIndex = -1;
private Cursor mCursor;
Settings mSettings;
boolean mDarkModeEnabled;
private Context mContext;
private CardAdapterListener mListener;
private SparseBooleanArray mSelectedItems;
private SparseBooleanArray mAnimationItemsIndex;
private boolean mReverseAllAnimations = false;
public LoyaltyCardCursorAdapter(Context context, Cursor cursor)
public LoyaltyCardCursorAdapter(Context inputContext, Cursor inputCursor, CardAdapterListener inputListener)
{
super(context, cursor, 0);
settings = new Settings(context);
super(inputCursor);
mSettings = new Settings(inputContext);
mCursor = inputCursor;
mContext = inputContext;
mListener = inputListener;
mSelectedItems = new SparseBooleanArray();
mAnimationItemsIndex = new SparseBooleanArray();
mDarkModeEnabled = MainActivity.isDarkModeEnabled(inputContext);
}
// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
public LoyaltyCardListItemViewHolder onCreateViewHolder(ViewGroup inputParent, int inputViewType)
{
return LayoutInflater.from(context).inflate(R.layout.loyalty_card_layout, parent, false);
View itemView = LayoutInflater.from(inputParent.getContext()).inflate(R.layout.loyalty_card_layout, inputParent, false);
return new LoyaltyCardListItemViewHolder(itemView);
}
// The bindView method is used to bind all data to a given view
// such as setting the text on a TextView.
@Override
public void bindView(View view, Context context, Cursor cursor)
public Cursor getCursor()
{
// Find fields to populate in inflated template
ImageView thumbnail = view.findViewById(R.id.thumbnail);
TextView storeField = view.findViewById(R.id.store);
TextView noteField = view.findViewById(R.id.note);
TextView balanceField = view.findViewById(R.id.balance);
TextView expiryField = view.findViewById(R.id.expiry);
ImageView star = view.findViewById(R.id.star);
return mCursor;
}
// Extract properties from cursor
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
// Populate fields with extracted properties
storeField.setText(loyaltyCard.store);
storeField.setTextSize(settings.getFontSizeMax(settings.getMediumFont()));
if(!loyaltyCard.note.isEmpty())
{
noteField.setVisibility(View.VISIBLE);
noteField.setText(loyaltyCard.note);
noteField.setTextSize(settings.getFontSizeMax(settings.getSmallFont()));
}
else
{
noteField.setVisibility(View.GONE);
public void onBindViewHolder(LoyaltyCardListItemViewHolder inputHolder, Cursor inputCursor) {
if (mDarkModeEnabled) {
inputHolder.mStarIcon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
}
if(!loyaltyCard.balance.equals(new BigDecimal("0"))) {
balanceField.setVisibility(View.VISIBLE);
balanceField.setText(context.getString(R.string.balanceSentence, Utils.formatBalance(context, loyaltyCard.balance, loyaltyCard.balanceType)));
balanceField.setTextSize(settings.getFontSizeMax(settings.getSmallFont()));
}
else
{
balanceField.setVisibility(View.GONE);
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(inputCursor);
inputHolder.mStoreField.setText(loyaltyCard.store);
inputHolder.mStoreField.setTextSize(mSettings.getFontSizeMax(mSettings.getMediumFont()));
if (!loyaltyCard.note.isEmpty()) {
inputHolder.mNoteField.setVisibility(View.VISIBLE);
inputHolder.mNoteField.setText(loyaltyCard.note);
inputHolder.mNoteField.setTextSize(mSettings.getFontSizeMax(mSettings.getSmallFont()));
} else {
inputHolder.mNoteField.setVisibility(View.GONE);
}
if(loyaltyCard.expiry != null)
if (!loyaltyCard.balance.equals(new BigDecimal("0"))) {
inputHolder.mBalanceField.setVisibility(View.VISIBLE);
inputHolder.mBalanceField.setText(mContext.getString(R.string.balanceSentence, Utils.formatBalance(mContext, loyaltyCard.balance, loyaltyCard.balanceType)));
inputHolder.mBalanceField.setTextSize(mSettings.getFontSizeMax(mSettings.getSmallFont()));
} else {
inputHolder.mBalanceField.setVisibility(View.GONE);
}
if (loyaltyCard.expiry != null)
{
expiryField.setVisibility(View.VISIBLE);
inputHolder.mExpiryField.setVisibility(View.VISIBLE);
int expiryString = R.string.expiryStateSentence;
if(Utils.hasExpired(loyaltyCard.expiry)) {
expiryString = R.string.expiryStateSentenceExpired;
expiryField.setTextColor(context.getResources().getColor(R.color.alert));
inputHolder.mExpiryField.setTextColor(mContext.getResources().getColor(R.color.alert));
}
inputHolder.mExpiryField.setText(mContext.getString(expiryString, DateFormat.getDateInstance(DateFormat.LONG).format(loyaltyCard.expiry)));
inputHolder.mExpiryField.setTextSize(mSettings.getFontSizeMax(mSettings.getSmallFont()));
} else {
inputHolder.mExpiryField.setVisibility(View.GONE);
}
inputHolder.mStarIcon.setVisibility((loyaltyCard.starStatus != 0) ? View.VISIBLE : View.GONE);
inputHolder.mCardIcon.setImageBitmap(Utils.generateIcon(mContext, loyaltyCard.store, loyaltyCard.headerColor).getLetterTile());
inputHolder.itemView.setActivated(mSelectedItems.get(inputCursor.getPosition(), false));
applyIconAnimation(inputHolder, inputCursor.getPosition());
applyClickEvents(inputHolder, inputCursor.getPosition());
}
private void applyClickEvents(LoyaltyCardListItemViewHolder inputHolder, final int inputPosition)
{
inputHolder.mThumbnailContainer.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View inputView)
{
mListener.onIconClicked(inputPosition);
}
});
inputHolder.mRow.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View inputView)
{
mListener.onRowClicked(inputPosition);
}
});
inputHolder.mInformationContainer.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View inputView)
{
mListener.onRowClicked(inputPosition);
}
});
inputHolder.mRow.setOnLongClickListener(new View.OnLongClickListener()
{
@Override
public boolean onLongClick(View inputView)
{
mListener.onRowLongClicked(inputPosition);
inputView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
return true;
}
});
inputHolder.mInformationContainer.setOnLongClickListener(new View.OnLongClickListener()
{
@Override
public boolean onLongClick(View inputView)
{
mListener.onRowLongClicked(inputPosition);
inputView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
return true;
}
});
}
private void applyIconAnimation(LoyaltyCardListItemViewHolder inputHolder, int inputPosition)
{
if (mSelectedItems.get(inputPosition, false))
{
inputHolder.mThumbnailFrontContainer.setVisibility(View.GONE);
resetIconYAxis(inputHolder.mThumbnailBackContainer);
inputHolder.mThumbnailBackContainer.setVisibility(View.VISIBLE);
inputHolder.mThumbnailBackContainer.setAlpha(1);
if (mCurrentSelectedIndex == inputPosition)
{
LoyaltyCardAnimator.flipView(mContext, inputHolder.mThumbnailBackContainer, inputHolder.mThumbnailFrontContainer, true);
resetCurrentIndex();
}
expiryField.setText(context.getString(expiryString, DateFormat.getDateInstance(DateFormat.LONG).format(loyaltyCard.expiry)));
expiryField.setTextSize(settings.getFontSizeMax(settings.getSmallFont()));
}
else
{
expiryField.setVisibility(View.GONE);
inputHolder.mThumbnailBackContainer.setVisibility(View.GONE);
resetIconYAxis(inputHolder.mThumbnailFrontContainer);
inputHolder.mThumbnailFrontContainer.setVisibility(View.VISIBLE);
inputHolder.mThumbnailFrontContainer.setAlpha(1);
if ((mReverseAllAnimations && mAnimationItemsIndex.get(inputPosition, false)) || mCurrentSelectedIndex == inputPosition)
{
LoyaltyCardAnimator.flipView(mContext, inputHolder.mThumbnailBackContainer, inputHolder.mThumbnailFrontContainer, false);
resetCurrentIndex();
}
}
}
private void resetIconYAxis(View inputView)
{
if (inputView.getRotationY() != 0)
{
inputView.setRotationY(0);
}
}
public void resetAnimationIndex()
{
mReverseAllAnimations = false;
mAnimationItemsIndex.clear();
}
@SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
public void toggleSelection(int inputPosition)
{
mCurrentSelectedIndex = inputPosition;
if (mSelectedItems.get(inputPosition, false))
{
mSelectedItems.delete(inputPosition);
mAnimationItemsIndex.delete(inputPosition);
}
else
{
mSelectedItems.put(inputPosition, true);
mAnimationItemsIndex.put(inputPosition, true);
}
notifyItemChanged(inputPosition);
}
public void clearSelections()
{
mReverseAllAnimations = true;
mSelectedItems.clear();
notifyDataSetChanged();
}
public int getSelectedItemCount()
{
return mSelectedItems.size();
}
public ArrayList<LoyaltyCard> getSelectedItems()
{
ArrayList<LoyaltyCard> result = new ArrayList<>();
int i;
for(i = 0; i < mSelectedItems.size(); i++)
{
mCursor.moveToPosition(mSelectedItems.keyAt(i));
result.add(LoyaltyCard.toLoyaltyCard(mCursor));
}
if (loyaltyCard.starStatus!=0) star.setVisibility(View.VISIBLE);
else star.setVisibility(View.GONE);
thumbnail.setImageBitmap(Utils.generateIcon(context, loyaltyCard.store, loyaltyCard.headerColor).getLetterTile());
return result;
}
}
private void resetCurrentIndex()
{
mCurrentSelectedIndex = -1;
}
public interface CardAdapterListener
{
void onIconClicked(int inputPosition);
void onRowClicked(int inputPosition);
void onRowLongClicked(int inputPosition);
}
public class LoyaltyCardListItemViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener
{
public TextView mStoreField, mNoteField, mBalanceField, mExpiryField;
public LinearLayout mInformationContainer;
public ImageView mCardIcon, mStarIcon;
public CardView mThumbnailContainer;
public ConstraintLayout mRow;
public RelativeLayout mThumbnailFrontContainer, mThumbnailBackContainer;
public LoyaltyCardListItemViewHolder(View inputView)
{
super(inputView);
mThumbnailContainer = inputView.findViewById(R.id.thumbnail_container);
mRow = inputView.findViewById(R.id.row);
mThumbnailFrontContainer = inputView.findViewById(R.id.thumbnail_front);
mThumbnailBackContainer = inputView.findViewById(R.id.thumbnail_back);
mInformationContainer = inputView.findViewById(R.id.information_container);
mStoreField = inputView.findViewById(R.id.store);
mNoteField = inputView.findViewById(R.id.note);
mBalanceField = inputView.findViewById(R.id.balance);
mExpiryField = inputView.findViewById(R.id.expiry);
mCardIcon = inputView.findViewById(R.id.thumbnail);
mStarIcon = inputView.findViewById(R.id.star);
inputView.setOnLongClickListener(this);
}
@Override
public boolean onLongClick(View inputView)
{
mListener.onRowLongClicked(getAdapterPosition());
inputView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
return true;
}
}
}

View File

@@ -6,22 +6,10 @@ import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import com.google.android.material.chip.Chip;
import com.google.android.material.chip.ChipGroup;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.DialogFragment;
import android.os.LocaleList;
import android.text.Editable;
import android.text.InputType;
@@ -29,7 +17,6 @@ import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
@@ -42,6 +29,10 @@ import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.chip.Chip;
import com.google.android.material.chip.ChipGroup;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;
import com.google.zxing.BarcodeFormat;
import com.jaredrummler.android.colorpicker.ColorPickerDialog;
@@ -50,7 +41,6 @@ import com.jaredrummler.android.colorpicker.ColorPickerDialogListener;
import java.io.InvalidObjectException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
@@ -60,10 +50,18 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.DialogFragment;
public class LoyaltyCardEditActivity extends AppCompatActivity
{
private static final String TAG = "Catima";
private final String STATE_TAB_INDEX = "savedTab";
TabLayout tabs;
ImageView thumbnail;
@@ -95,6 +93,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
ImportURIHelper importUriHelper;
boolean hasChanged = false;
String tempStoredOldBarcodeValue = null;
boolean initDone = false;
AlertDialog confirmExitDialog = null;
@@ -119,6 +118,20 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
+ ", updateLoyaltyCard=" + updateLoyaltyCard);
}
@Override
public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
tabs = findViewById(R.id.tabs);
savedInstanceState.putInt(STATE_TAB_INDEX, tabs.getSelectedTabPosition());
}
@Override
public void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
tabs = findViewById(R.id.tabs);
tabs.selectTab(tabs.getTabAt(savedInstanceState.getInt(STATE_TAB_INDEX)));
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
@@ -159,12 +172,9 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
enterButton = findViewById(R.id.enterButton);
warnOnInvalidBarcodeType = new Runnable() {
@Override
public void run() {
if (!(boolean) barcodeImage.getTag()) {
Toast.makeText(LoyaltyCardEditActivity.this, getString(R.string.wrongValueForBarcodeType), Toast.LENGTH_LONG).show();
}
warnOnInvalidBarcodeType = () -> {
if (!(boolean) barcodeImage.getTag()) {
Toast.makeText(LoyaltyCardEditActivity.this, getString(R.string.wrongValueForBarcodeType), Toast.LENGTH_LONG).show();
}
};
@@ -310,15 +320,30 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
cardIdFieldView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (initDone) {
if (tempStoredOldBarcodeValue == null) {
// We changed the card ID, save the current barcode ID in a temp
// variable and make sure to ask the user later if they also want to
// update the barcode ID
if (barcodeIdField.getTag() == null) {
// If it is set to "same as Card ID", temp-save the value before the
// Card ID change
tempStoredOldBarcodeValue = s.toString();
} else {
// Otherwise, set the temp value to the current field value
tempStoredOldBarcodeValue = barcodeIdField.getText().toString();
}
barcodeIdField.setText(tempStoredOldBarcodeValue);
barcodeIdField.setTag(tempStoredOldBarcodeValue);
}
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
hasChanged = true;
if (!s.toString().isEmpty()) {
generateOrHideBarcode();
}
}
@Override
@@ -338,6 +363,10 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
hasChanged = true;
if (s.toString().equals(getString(R.string.sameAsCardId))) {
// If the user manually changes the barcode again make sure we disable the
// request to update it to match the card id (if changed)
tempStoredOldBarcodeValue = null;
barcodeIdField.setTag(null);
} else if (s.toString().equals(getString(R.string.setBarcodeId))) {
if (!lastValue.toString().equals(getString(R.string.setBarcodeId))) {
@@ -353,19 +382,15 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
}
builder.setView(input);
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
barcodeIdField.setTag(input.getText().toString());
barcodeIdField.setText(input.getText());
}
});
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
builder.setPositiveButton(getString(R.string.ok), (dialog, which) -> {
// If the user manually changes the barcode again make sure we disable the
// request to update it to match the card id (if changed)
tempStoredOldBarcodeValue = null;
barcodeIdField.setTag(input.getText().toString());
barcodeIdField.setText(input.getText());
});
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);
@@ -623,11 +648,6 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
thumbnail.setOnClickListener(new ColorSelectListener(headingColorValue));
if (!initDone) {
hasChanged = false;
initDone = true;
}
// Update from intent
if (barcodeType != null) {
try {
@@ -649,6 +669,11 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
}
}
if (!initDone) {
hasChanged = false;
initDone = true;
}
generateOrHideBarcode();
enterButton.setOnClickListener(new EditCardIdAndBarcode());
@@ -681,8 +706,56 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
askBeforeQuitIfChanged();
}
private void askBarcodeChange(Runnable callback) {
if (tempStoredOldBarcodeValue.equals(cardIdFieldView.getText().toString())) {
// They are the same, don't ask
barcodeIdField.setText(R.string.sameAsCardId);
tempStoredOldBarcodeValue = null;
if (callback != null) {
callback.run();
}
return;
}
new AlertDialog.Builder(this)
.setTitle(R.string.updateBarcodeQuestionTitle)
.setMessage(R.string.updateBarcodeQuestionText)
.setPositiveButton(R.string.yes, (dialog, which) -> {
barcodeIdField.setText(R.string.sameAsCardId);
tempStoredOldBarcodeValue = null;
if (callback != null) {
callback.run();
}
})
.setNegativeButton(R.string.no, (dialog, which) -> {
barcodeIdField.setText(tempStoredOldBarcodeValue);
tempStoredOldBarcodeValue = null;
if (callback != null) {
callback.run();
}
})
.setOnDismissListener(dialogInterface -> {
barcodeIdField.setText(tempStoredOldBarcodeValue);
tempStoredOldBarcodeValue = null;
if (callback != null) {
callback.run();
}
})
.show();
}
private void askBeforeQuitIfChanged() {
if (!hasChanged) {
if (tempStoredOldBarcodeValue != null) {
askBarcodeChange(this::askBeforeQuitIfChanged);
return;
}
finish();
return;
}
@@ -807,6 +880,11 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
private void doSave()
{
if (tempStoredOldBarcodeValue != null) {
askBarcodeChange(this::doSave);
return;
}
String store = storeFieldEdit.getText().toString();
String note = noteFieldEdit.getText().toString();
Date expiry = (Date) expiryField.getTag();
@@ -996,6 +1074,11 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
}
private void showPart(String part) {
if (tempStoredOldBarcodeValue != null) {
askBarcodeChange(() -> showPart(part));
return;
}
View cardPart = findViewById(R.id.cardPart);
View barcodePart = findViewById(R.id.barcodePart);

View File

@@ -1,8 +1,8 @@
package protect.card_locker;
import android.app.Application;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.app.AppCompatDelegate;
import protect.card_locker.preferences.Settings;
public class LoyaltyCardLockerApplication extends Application {

View File

@@ -7,24 +7,12 @@ import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.Guideline;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.widget.TextViewCompat;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.Toolbar;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
@@ -41,8 +29,17 @@ import com.google.zxing.BarcodeFormat;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.Toolbar;
import androidx.constraintlayout.widget.Guideline;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.widget.TextViewCompat;
import protect.card_locker.preferences.Settings;
public class LoyaltyCardViewActivity extends AppCompatActivity
@@ -491,7 +488,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity
break;
case R.id.action_share:
importURIHelper.startShareIntent(loyaltyCard);
importURIHelper.startShareIntent(Arrays.asList(loyaltyCard));
return true;
case R.id.action_lock_unlock:

View File

@@ -1,63 +1,157 @@
package protect.card_locker;
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import android.util.Log;
import android.view.ContextMenu;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.tabs.TabLayout;
import java.util.List;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ActionMode;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import protect.card_locker.preferences.SettingsActivity;
public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener
public class MainActivity extends AppCompatActivity implements LoyaltyCardCursorAdapter.CardAdapterListener, GestureDetector.OnGestureListener
{
private static final String TAG = "Catima";
private Menu menu;
private GestureDetector gestureDetector;
protected String filter = "";
private final DBHelper mDB = new DBHelper(this);
private LoyaltyCardCursorAdapter mAdapter;
private ActionMode mCurrentActionMode;
private Menu mMenu;
private GestureDetector mGestureDetector;
protected String mFilter = "";
protected int selectedTab = 0;
private RecyclerView mCardList;
private ActionMode.Callback mCurrentActionModeCallback = new ActionMode.Callback()
{
@Override
public boolean onCreateActionMode(ActionMode inputMode, Menu inputMenu)
{
inputMode.getMenuInflater().inflate(R.menu.card_longclick_menu, inputMenu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode inputMode, Menu inputMenu)
{
return false;
}
@Override
public boolean onActionItemClicked(ActionMode inputMode, MenuItem inputItem)
{
if (inputItem.getItemId() == R.id.action_copy_to_clipboard)
{
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
String clipboardData;
int cardCount = mAdapter.getSelectedItemCount();
if (cardCount == 1) {
clipboardData = mAdapter.getSelectedItems().get(0).cardId;
} else {
StringBuilder cardIds = new StringBuilder();
for (int i = 0; i < cardCount; i++) {
LoyaltyCard loyaltyCard = mAdapter.getSelectedItems().get(i);
cardIds.append(loyaltyCard.store + ": " + loyaltyCard.cardId);
if (i < (cardCount - 1)) {
cardIds.append("\n");
}
}
clipboardData = cardIds.toString();
}
ClipData clip = ClipData.newPlainText(getString(R.string.card_ids_copied), clipboardData);
clipboard.setPrimaryClip(clip);
Toast.makeText(MainActivity.this, cardCount > 1 ? R.string.copy_to_clipboard_multiple_toast : R.string.copy_to_clipboard_toast, Toast.LENGTH_LONG).show();
inputMode.finish();
return true;
}
else if (inputItem.getItemId() == R.id.action_share)
{
final ImportURIHelper importURIHelper = new ImportURIHelper(MainActivity.this);
importURIHelper.startShareIntent(mAdapter.getSelectedItems());
inputMode.finish();
return true;
}
else if(inputItem.getItemId() == R.id.action_edit)
{
if (mAdapter.getSelectedItemCount() != 1) {
throw new IllegalArgumentException("Cannot edit more than 1 card at a time");
}
Intent intent = new Intent(getApplicationContext(), LoyaltyCardEditActivity.class);
Bundle bundle = new Bundle();
bundle.putInt("id", mAdapter.getSelectedItems().get(0).id);
bundle.putBoolean("update", true);
intent.putExtras(bundle);
startActivity(intent);
inputMode.finish();
return true;
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode inputMode)
{
mAdapter.clearSelections();
mCurrentActionMode = null;
mCardList.post(new Runnable()
{
@Override
public void run()
{
mAdapter.resetAnimationIndex();
}
});
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
protected void onCreate(Bundle inputSavedInstanceState)
{
super.onCreate(savedInstanceState);
super.onCreate(inputSavedInstanceState);
setContentView(R.layout.main_activity);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
updateLoyaltyCardList(filter, null);
updateLoyaltyCardList(mFilter, null);
TabLayout groupsTabLayout = findViewById(R.id.groups);
groupsTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
selectedTab = tab.getPosition();
updateLoyaltyCardList(filter, tab.getTag());
updateLoyaltyCardList(mFilter, tab.getTag());
// Store active tab in Shared Preference to restore next app launch
SharedPreferences activeTabPref = getApplicationContext().getSharedPreferences(
@@ -79,12 +173,12 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
}
});
gestureDetector = new GestureDetector(this, this);
mGestureDetector = new GestureDetector(this, this);
View.OnTouchListener gestureTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(final View v, final MotionEvent event){
return gestureDetector.onTouchEvent(event);
return mGestureDetector.onTouchEvent(event);
}
};
@@ -129,15 +223,23 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
}
@Override
protected void onResume() {
protected void onResume()
{
super.onResume();
if (menu != null)
if(mCurrentActionMode != null)
{
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
mAdapter.clearSelections();
mCurrentActionMode.finish();
}
if (!searchView.isIconified()) {
filter = searchView.getQuery().toString();
if (mMenu != null)
{
SearchView searchView = (SearchView) mMenu.findItem(R.id.action_search).getActionView();
if (!searchView.isIconified())
{
mFilter = searchView.getQuery().toString();
}
}
@@ -163,11 +265,12 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
assert tab != null;
group = tab.getTag();
}
updateLoyaltyCardList(filter, group);
updateLoyaltyCardList(mFilter, group);
// End of active tab logic
FloatingActionButton addButton = findViewById(R.id.fabAdd);
addButton.setOnClickListener(new View.OnClickListener() {
addButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), ScanActivity.class);
@@ -183,14 +286,12 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
if (requestCode == Utils.MAIN_REQUEST) {
// We're coming back from another view so clear the search
// We only do this now to prevent a flash of all entries right after picking one
filter = "";
if (menu != null)
mFilter = "";
if (mMenu != null)
{
MenuItem searchItem = menu.findItem(R.id.action_search);
MenuItem searchItem = mMenu.findItem(R.id.action_search);
searchItem.collapseActionView();
}
// In case the theme changed
recreate();
return;
@@ -209,16 +310,18 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
}
@Override
public void onBackPressed() {
if (menu == null)
public void onBackPressed()
{
if (mMenu == null)
{
super.onBackPressed();
return;
}
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
SearchView searchView = (SearchView) mMenu.findItem(R.id.action_search).getActionView();
if (!searchView.isIconified()) {
if (!searchView.isIconified())
{
searchView.setIconified(true);
} else {
TabLayout groupsTabLayout = findViewById(R.id.groups);
@@ -239,21 +342,29 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
group = (Group) tag;
}
final ListView cardList = findViewById(R.id.list);
mCardList = findViewById(R.id.list);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
mCardList.setLayoutManager(mLayoutManager);
mCardList.setItemAnimator(new DefaultItemAnimator());
final TextView helpText = findViewById(R.id.helpText);
final TextView noMatchingCardsText = findViewById(R.id.noMatchingCardsText);
final DBHelper db = new DBHelper(this);
Cursor cardCursor = db.getLoyaltyCardCursor(filterText, group);
Cursor cardCursor = mDB.getLoyaltyCardCursor(filterText, group);
if(db.getLoyaltyCardCount() > 0)
mAdapter = new LoyaltyCardCursorAdapter(this, cardCursor, this);
mCardList.setAdapter(mAdapter);
registerForContextMenu(mCardList);
if(mDB.getLoyaltyCardCount() > 0)
{
// We want the cardList to be visible regardless of the filtered match count
// to ensure that the noMatchingCardsText doesn't end up being shown below
// the keyboard
cardList.setVisibility(View.VISIBLE);
mCardList.setVisibility(View.VISIBLE);
helpText.setVisibility(View.GONE);
if(cardCursor.getCount() > 0)
if(mAdapter.getItemCount() > 0)
{
noMatchingCardsText.setVisibility(View.GONE);
}
@@ -264,35 +375,14 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
}
else
{
cardList.setVisibility(View.GONE);
mCardList.setVisibility(View.GONE);
helpText.setVisibility(View.VISIBLE);
noMatchingCardsText.setVisibility(View.GONE);
}
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor);
cardList.setAdapter(adapter);
registerForContextMenu(cardList);
cardList.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Cursor selected = (Cursor) parent.getItemAtPosition(position);
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
Intent i = new Intent(view.getContext(), LoyaltyCardViewActivity.class);
i.setAction("");
final Bundle b = new Bundle();
b.putInt("id", loyaltyCard.id);
i.putExtras(b);
ShortcutHelper.updateShortcuts(MainActivity.this, loyaltyCard, i);
startActivityForResult(i, Utils.MAIN_REQUEST);
}
});
if (mCurrentActionMode != null) {
mCurrentActionMode.finish();
}
}
public void updateTabGroups(TabLayout groupsTabLayout)
@@ -333,80 +423,47 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
public boolean onCreateOptionsMenu(Menu inputMenu)
{
super.onCreateContextMenu(menu, v, menuInfo);
if (v.getId()==R.id.list)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.card_longclick_menu, menu);
}
}
this.mMenu = inputMenu;
@Override
public boolean onContextItemSelected(MenuItem item)
{
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
ListView listView = findViewById(R.id.list);
Cursor cardCursor = (Cursor)listView.getItemAtPosition(info.position);
LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cardCursor);
if(item.getItemId() == R.id.action_clipboard)
{
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(card.store, card.cardId);
clipboard.setPrimaryClip(clip);
Toast.makeText(this, R.string.copy_to_clipboard_toast, Toast.LENGTH_LONG).show();
return true;
}
else if(item.getItemId() == R.id.action_share)
{
final ImportURIHelper importURIHelper = new ImportURIHelper(this);
importURIHelper.startShareIntent(card);
return true;
}
return super.onContextItemSelected(item);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
this.menu = menu;
getMenuInflater().inflate(R.menu.main_menu, menu);
getMenuInflater().inflate(R.menu.main_menu, inputMenu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
if (searchManager != null) {
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
if (searchManager != null)
{
SearchView searchView = (SearchView) inputMenu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setSubmitButtonEnabled(false);
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
searchView.setOnCloseListener(new SearchView.OnCloseListener()
{
@Override
public boolean onClose() {
public boolean onClose()
{
invalidateOptionsMenu();
return false;
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
{
@Override
public boolean onQueryTextSubmit(String query) {
public boolean onQueryTextSubmit(String query)
{
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
filter = newText;
public boolean onQueryTextChange(String newText)
{
mFilter = newText;
TabLayout groupsTabLayout = findViewById(R.id.groups);
TabLayout.Tab currentTab = groupsTabLayout.getTabAt(groupsTabLayout.getSelectedTabPosition());
updateLoyaltyCardList(
newText,
mFilter,
currentTab != null ? currentTab.getTag() : null
);
@@ -414,14 +471,13 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
}
});
}
return super.onCreateOptionsMenu(menu);
return super.onCreateOptionsMenu(inputMenu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
public boolean onOptionsItemSelected(MenuItem inputItem)
{
int id = item.getItemId();
int id = inputItem.getItemId();
if (id == R.id.action_manage_groups)
{
@@ -430,14 +486,14 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
return true;
}
if(id == R.id.action_import_export)
if (id == R.id.action_import_export)
{
Intent i = new Intent(getApplicationContext(), ImportExportActivity.class);
startActivityForResult(i, Utils.MAIN_REQUEST);
return true;
}
if(id == R.id.action_settings)
if (id == R.id.action_settings)
{
Intent i = new Intent(getApplicationContext(), SettingsActivity.class);
startActivityForResult(i, Utils.MAIN_REQUEST);
@@ -450,14 +506,14 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
return true;
}
if(id == R.id.action_about)
if (id == R.id.action_about)
{
Intent i = new Intent(getApplicationContext(), AboutActivity.class);
startActivityForResult(i, Utils.MAIN_REQUEST);
return true;
}
return super.onOptionsItemSelected(item);
return super.onOptionsItemSelected(inputItem);
}
protected static boolean isDarkModeEnabled(Context inputContext)
@@ -536,4 +592,79 @@ public class MainActivity extends AppCompatActivity implements GestureDetector.O
return false;
}
@Override
public void onRowLongClicked(int inputPosition)
{
enableActionMode(inputPosition);
}
private void enableActionMode(int inputPosition)
{
if (mCurrentActionMode == null)
{
mCurrentActionMode = startSupportActionMode(mCurrentActionModeCallback);
}
toggleSelection(inputPosition);
}
private void toggleSelection(int inputPosition)
{
mAdapter.toggleSelection(inputPosition);
int count = mAdapter.getSelectedItemCount();
if (count == 0) {
mCurrentActionMode.finish();
} else {
mCurrentActionMode.setTitle("Selected: " + count + " Cards");
MenuItem editItem = mCurrentActionMode.getMenu().findItem(R.id.action_edit);
if (count == 1) {
editItem.setVisible(true);
editItem.setEnabled(true);
} else {
editItem.setVisible(false);
editItem.setEnabled(false);
}
mCurrentActionMode.invalidate();
}
}
@Override
public void onIconClicked(int inputPosition)
{
if (mCurrentActionMode == null)
{
mCurrentActionMode = startSupportActionMode(mCurrentActionModeCallback);
}
toggleSelection(inputPosition);
}
@Override
public void onRowClicked(int inputPosition)
{
if (mAdapter.getSelectedItemCount() > 0)
{
enableActionMode(inputPosition);
}
else
{
Cursor selected = mAdapter.getCursor();
selected.moveToPosition(inputPosition);
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected);
Intent i = new Intent(this, LoyaltyCardViewActivity.class);
i.setAction("");
final Bundle b = new Bundle();
b.putInt("id", loyaltyCard.id);
i.putExtras(b);
ShortcutHelper.updateShortcuts(MainActivity.this, loyaltyCard, i);
startActivityForResult(i, Utils.MAIN_REQUEST);
}
}
}

View File

@@ -9,6 +9,14 @@ import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.NumberFormat;
@@ -19,15 +27,6 @@ import java.util.GregorianCalendar;
import androidx.core.graphics.ColorUtils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
public class Utils {
private static final String TAG = "Catima";

View File

@@ -58,6 +58,7 @@ public class CsvDatabaseExporter implements DatabaseExporter
DBHelper.LoyaltyCardDbIds.BALANCE_TYPE,
DBHelper.LoyaltyCardDbIds.CARD_ID,
DBHelper.LoyaltyCardDbIds.HEADER_COLOR,
DBHelper.LoyaltyCardDbIds.BARCODE_ID,
DBHelper.LoyaltyCardDbIds.BARCODE_TYPE,
DBHelper.LoyaltyCardDbIds.STAR_STATUS);
@@ -75,6 +76,7 @@ public class CsvDatabaseExporter implements DatabaseExporter
card.balanceType,
card.cardId,
card.headerColor,
card.barcodeId,
card.barcodeType,
card.starStatus);

View File

@@ -7,23 +7,17 @@ import com.google.zxing.BarcodeFormat;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.json.JSONException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.Currency;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipFile;
import protect.card_locker.DBHelper;
import protect.card_locker.FormatException;

View File

@@ -2,10 +2,8 @@ package protect.card_locker.importexport;
import org.json.JSONException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import protect.card_locker.DBHelper;

View File

@@ -1,33 +1,21 @@
package protect.card_locker.importexport;
import android.annotation.SuppressLint;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import com.google.zxing.BarcodeFormat;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Currency;
import java.util.Date;
import java.util.TimeZone;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import protect.card_locker.DBHelper;

View File

@@ -7,8 +7,6 @@ import java.io.OutputStreamWriter;
import protect.card_locker.DBHelper;
import protect.card_locker.DataFormat;
import protect.card_locker.importexport.CsvDatabaseExporter;
import protect.card_locker.importexport.DatabaseExporter;
public class MultiFormatExporter
{

View File

@@ -6,14 +6,11 @@ import org.json.JSONException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import protect.card_locker.DBHelper;
import protect.card_locker.DataFormat;
import protect.card_locker.FormatException;
import protect.card_locker.importexport.CsvDatabaseImporter;
import protect.card_locker.importexport.DatabaseImporter;
public class MultiFormatImporter
{

View File

@@ -84,6 +84,9 @@ public class VoucherVaultImporter implements DatabaseImporter
case "EAN13":
barcodeType = BarcodeFormat.EAN_13;
break;
case "PDF417":
barcodeType = BarcodeFormat.PDF_417;
break;
case "QR":
barcodeType = BarcodeFormat.QR_CODE;
break;

View File

@@ -2,11 +2,11 @@ package protect.card_locker.preferences;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;
import androidx.annotation.IntegerRes;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.preference.PreferenceManager;
import protect.card_locker.R;
public class Settings

View File

@@ -1,15 +1,15 @@
package protect.card_locker.preferences;
import android.os.Bundle;
import android.view.MenuItem;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import android.view.MenuItem;
import nl.invissvenska.numberpickerpreference.NumberDialogPreference;
import nl.invissvenska.numberpickerpreference.NumberPickerPreferenceDialogFragment;
import protect.card_locker.R;

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:valueFrom="1.0"
android:valueTo="0.0" />
<objectAnimator
android:duration="@integer/full_rotation_duration"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:propertyName="rotationY"
android:valueFrom="-180"
android:valueTo="0" />
<objectAnimator
android:duration="1"
android:propertyName="alpha"
android:startOffset="@integer/half_rotation_duration"
android:valueFrom="0.0"
android:valueTo="1.0" />
</set>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="@integer/full_rotation_duration"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:propertyName="rotationY"
android:valueFrom="0"
android:valueTo="180" />
<objectAnimator
android:duration="1"
android:propertyName="alpha"
android:startOffset="@integer/half_rotation_duration"
android:valueFrom="1.0"
android:valueTo="0.0" />
</set>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:valueFrom="1.0"
android:valueTo="0.0" />
<objectAnimator
android:duration="@integer/full_rotation_duration"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:propertyName="rotationY"
android:valueFrom="180"
android:valueTo="0" />
<objectAnimator
android:duration="1"
android:propertyName="alpha"
android:startOffset="@integer/half_rotation_duration"
android:valueFrom="0.0"
android:valueTo="1.0" />
</set>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="@integer/full_rotation_duration"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:propertyName="rotationY"
android:valueFrom="0"
android:valueTo="-180" />
<objectAnimator
android:duration="1"
android:propertyName="alpha"
android:startOffset="@integer/half_rotation_duration"
android:valueFrom="1.0"
android:valueTo="0.0" />
</set>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@color/colorPrimary"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
</vector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/darker_gray"/>
<size android:height="1dp"/>
</shape>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/listItemHighlight" android:state_activated="true" />
</selector>

View File

@@ -27,9 +27,11 @@
android:text="@string/noMatchingGiftCards"
android:visibility="gone"/>
<ListView
android:layout_width="wrap_content"
android:layout_height="match_parent"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:visibility="gone"/>
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:visibility="gone" />
</RelativeLayout>

View File

@@ -1,80 +1,118 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/row"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:baselineAligned="false"
android:layout_height="wrap_content"
android:layout_marginBottom="0.5dp"
android:background="@drawable/list_row"
android:clickable="true"
android:focusable="true"
android:padding="@dimen/activity_margin">
<androidx.cardview.widget.CardView
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:layout_marginEnd="@dimen/activity_margin"
app:cardCornerRadius="4dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/thumbnail"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:contentDescription="@string/thumbnailDescription"
android:src="@mipmap/ic_launcher"/>
</androidx.cardview.widget.CardView>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:id="@+id/information_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginLeft="@dimen/activity_margin"
android:layout_toEndOf="@+id/thumbnail_container"
android:layout_toRightOf="@+id/thumbnail_container"
android:layout_weight="1"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="@+id/thumbnail_container"
app:layout_constraintEnd_toStartOf="@+id/star"
app:layout_constraintStart_toEndOf="@+id/thumbnail_container"
app:layout_constraintTop_toTopOf="@+id/thumbnail_container">
<LinearLayout
android:id="@+id/valueLayout"
<TextView
android:id="@+id/store"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible" >
<TextView
android:id="@+id/store"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/storeNameTextSize"
android:textStyle="bold"/>
</LinearLayout>
android:textSize="@dimen/storeNameTextSize"
android:textStyle="bold" />
<TextView
android:id="@+id/note"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textSize="@dimen/noteTextSize"/>
android:lines="1"
android:textSize="@dimen/noteTextSize" />
<TextView
android:id="@+id/balance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textSize="@dimen/noteTextSize"/>
android:lines="1"
android:textSize="@dimen/noteTextSize" />
<TextView
android:id="@+id/expiry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textSize="@dimen/noteTextSize"/>
android:lines="1"
android:textSize="@dimen/noteTextSize" />
</LinearLayout>
<androidx.cardview.widget.CardView
android:id="@+id/thumbnail_container"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
app:cardCornerRadius="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:id="@+id/thumbnail_front"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize">
<ImageView
android:id="@+id/thumbnail"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:contentDescription="@string/thumbnailDescription"
android:src="@mipmap/ic_launcher" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/thumbnail_back"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize">
<ImageView
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:layout_centerHorizontal="true"
android:contentDescription="@string/thumbnailDescription"
app:srcCompat="@drawable/ic_done" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
<ImageView
android:id="@+id/star"
android:layout_width="@dimen/cardThumbnailSize"
android:layout_height="@dimen/cardThumbnailSize"
android:layout_marginStart="@dimen/activity_margin"
android:layout_marginLeft="@dimen/activity_margin"
app:srcCompat="@drawable/ic_starred_white"
app:tint="@color/iconColor"
android:contentDescription="@string/starImage"/>
</LinearLayout>
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginStart="@dimen/activity_margin"
android:contentDescription="@string/starImage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@android:color/black" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<menu>
</menu>

View File

@@ -3,11 +3,24 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_clipboard"
android:id="@+id/action_copy_to_clipboard"
android:title="@string/copy_to_clipboard"
android:icon="@drawable/ic_copy"
android:titleCondensed="@string/copy_to_clipboard"
app:showAsAction="always"/>
<item
android:id="@+id/action_share"
android:title="@string/share"
android:icon="@drawable/ic_share"
android:titleCondensed="@string/share"
app:showAsAction="always"/>
<item
android:id="@+id/action_edit"
android:icon="@drawable/ic_edit"
android:title="@string/editCardTitle"
android:titleCondensed="@string/editCardTitle"
app:showAsAction="always"/>
</menu>

View File

@@ -48,7 +48,6 @@
<string name="about_title_fmt">O aplikaci <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Verze: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Revizní informace: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> používá tyto knihovny třetích stran: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="selectBarcodeTitle">Vyberte čárový kód</string>
<string name="copy_to_clipboard_toast">ID karty zkopírováno do schránky</string>

View File

@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
<string name="action_search">Suchen</string>
<string name="action_add">Hinzufügen</string>
<string name="noGiftCards">Klicken Sie auf die Schaltfläche + (plus), um zuerst eine Karte hinzuzufügen.
\n
\nCatima trägt Ihre Karten auf dem Gerät, so dass sie immer in Reichweite sind.</string>
<string name="noGiftCards">Klicken Sie auf das Pluszeichen +, um eine Karte hinzuzufügen, oder importieren Sie zunächst einige aus dem ⋮ Menü.</string>
<string name="noMatchingGiftCards">Nichts gefunden. Versuchen Sie, Ihre Suche zu ändern.</string>
<string name="storeName">Geschäft</string>
<string name="storeName">Name</string>
<string name="note">Notiz</string>
<string name="cardId">Kartennummer</string>
<string name="cancel">Abbrechen</string>
@@ -19,7 +17,7 @@
<string name="star">Zu den Favoriten hinzufügen</string>
<string name="unstar">Aus der Favoritenliste entfernen</string>
<string name="deleteTitle">Karte entfernen</string>
<string name="deleteConfirmation">Bitte bestätigen Sie, dass diese Karte gelöscht werden soll.</string>
<string name="deleteConfirmation">Diese Karte löschen\?</string>
<string name="ok">OK</string>
<string name="copy_to_clipboard">Nummer in die Zwischenablage kopieren</string>
<string name="sendLabel">Senden </string>
@@ -29,7 +27,7 @@
<string name="cardShortcut">Shortcut zu einer Karte</string>
<string name="noCardsMessage">Fügen Sie zuerst eine Karte hinzu</string>
<string name="barcodeImageDescription">Bild des Strichcodes</string>
<string name="noStoreError">Kein Geschäft angegeben</string>
<string name="noStoreError">Kein Name eingegeben</string>
<string name="noCardIdError">Keine Kartennummer angegeben</string>
<string name="noCardExistsError">Karte konnte nicht gefunden werden</string>
<string name="importExport">Import/Export</string>
@@ -47,16 +45,14 @@
<string name="importOptionFilesystemTitle">Importiere aus Dateisystem</string>
<string name="importOptionFilesystemExplanation">Wähle eine Datei aus dem Speicher aus.</string>
<string name="importOptionFilesystemButton">Aus Dateisystem</string>
<string name="importOptionApplicationTitle">Externe Anwendung verwenden</string>
<string name="importOptionApplicationTitle">Andere Anwendung verwenden</string>
<string name="importOptionApplicationExplanation">Verwenden Sie eine beliebige Anwendung oder Ihren bevorzugten Dateiverwaltungsprogramm, um eine Datei zu öffnen.</string>
<string name="importOptionApplicationButton">Externe Anwendung nutzen</string>
<string name="importOptionApplicationButton">Andere Anwendung verwenden</string>
<string name="about">Über</string>
<string name="app_license">Freie Software, lizensiert unter der GPLv3+.</string>
<string name="about_title_fmt">Über <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Version: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Informationen zu dieser Version: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> benutzt die folgenden Fremdbibliotheken: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> verwendet folgenden Dritt-Ressourcen: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="selectBarcodeTitle">Strichcode auswählen</string>
<string name="copy_to_clipboard_toast">Nummer in die Zwischenablage kopiert</string>
<string name="thumbnailDescription">Vorschaubild für die Karte</string>
@@ -71,19 +67,18 @@
<string name="settings_light_theme">Hell</string>
<string name="settings_system_theme">System</string>
<string name="settings_theme">Design</string>
<string name="enterBarcodeInstructions">Geben Sie die Karten-ID ein und wählen Sie das Bild aus, das den Strichcode darstellt, den Sie verwenden möchten, oder wählen Sie „Diese Karte hat keinen Strichcode“, um keinen Strichcode zu verwenden.</string>
<string name="app_copyright_old">Basiert auf Loyalty Card Keychain, Copyright 20162020 Branden Archer.</string>
<string name="enterBarcodeInstructions">Geben Sie die Karten-ID ein und wählen Sie unten entweder den Strichcodetyp oder „Diese Karte hat keinen Strichcode“.</string>
<string name="app_copyright_old">Basierend auf Loyalty Card Keychain
\nCopyright © 2016-2020 Branden Archer.</string>
<string name="exportOptionExplanation">Die Daten werden an einen Ort Ihrer Wahl geschrieben.</string>
<string name="failedParsingImportUriError">Der Import-URI konnte nicht analysiert werden</string>
<string name="share">Teilen</string>
<string name="barcodeNoBarcode">Diese Karte hat keinen Strichcode</string>
<string name="barcodeType">Strichcode-Typ</string>
<string name="starImage">Favoritenstern</string>
<string name="deleteConfirmationGroup">Bitte bestätigen Sie, dass Sie diese Gruppe löschen möchten</string>
<string name="deleteConfirmationGroup">Gruppe löschen\?</string>
<string name="all">Alle</string>
<string name="noGroups">Klicken Sie auf die Schaltfläche + (plus), um zuerst Gruppen hinzuzufügen.
\n
\nGruppen machen es einfacher, Dinge zu finden.</string>
<string name="noGroups">Klicken Sie auf das Pluszeichen +, um zunächst Gruppen zur Kategorisierung hinzuzufügen.</string>
<string name="groups">Gruppen</string>
<string name="enter_group_name">Geben Sie den Gruppennamen ein</string>
<string name="leaveWithoutSaveConfirmation">Beenden ohne zu speichern\?</string>
@@ -91,16 +86,16 @@
<string name="failedOpeningFileManager">Installieren Sie zunächst ein Dateiverwaltungsprogramm.</string>
<string name="noBarcode">Kein Strichcode</string>
<string name="addManually">Die Karten-ID manuell eingeben</string>
<string name="moveDown">In der Liste nach unten verschieben</string>
<string name="moveUp">In der Liste nach oben verschieben</string>
<string name="moveDown">Nach unten verschieben</string>
<string name="moveUp">Nach oben verschieben</string>
<plurals name="groupCardCount">
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> Karte</item>
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> Karten</item>
<item quantity="one"><xliff:g>%d</xliff:g> Karte</item>
<item quantity="other"><xliff:g>%d</xliff:g> Karten</item>
</plurals>
<string name="groupsList">Gruppen: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="groupsList">Gruppen: <xliff:g>%s</xliff:g></string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="chooseImportType">Daten importieren aus\?</string>
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> scheint kein gültiges Guthaben zu sein.</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> scheint kein gültiges Guthaben zu sein.</string>
<string name="points">Punkte</string>
<string name="currency">Währung</string>
<string name="balance">Guthaben</string>
@@ -112,34 +107,28 @@
<string name="editBarcode">Strichcode bearbeiten</string>
<string name="barcode">Strichcode</string>
<string name="card">Karte</string>
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> Punkte</string>
<string name="balanceSentence">Guthaben: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Abgelaufen: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentence">Läuft ab: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="settings_disable_lockscreen_while_viewing_card">Sperrbildschirm deaktivieren während eine Karte angesehen wird</string>
<string name="settings_keep_screen_on">Bildschirm anlassen während eine Karte angesehen wird</string>
<string name="balancePoints"><xliff:g>%s</xliff:g> Punkte</string>
<string name="balanceSentence">Guthaben: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Abgelaufen: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentence">Läuft ab: <xliff:g>%s</xliff:g></string>
<string name="settings_disable_lockscreen_while_viewing_card">Sperrbildschirm verhindern</string>
<string name="settings_keep_screen_on">Bildschirm eingeschaltet halten</string>
<string name="privacy_policy_popup_text">Hinweis zum Datenschutz (oft gefordert):
\n
\nWir sammeln KEINE DATEN, was jeder bestätigen kann, da unsere Anwendung eine freie Software ist.</string>
\nKEINE DATEN WERDEN GESAMMELT, was jeder bestätigen kann, da unsere Anwendung eine freie Software ist.</string>
<string name="accept">Annehmen</string>
<string name="privacy_policy">Datenschutzrichtlinie</string>
<string name="importVoucherVaultMessage">Bitte wählen Sie Ihre Voucher Vault-Exportdatei aus. Es heißt höchstwahrscheinlich vouchervault.json.
\n
\nEine Voucher Vault-Exportdatei kann durch Drücken von Exportieren erstellt werden.</string>
<string name="importVoucherVaultMessage">Suchen Sie eine Datei, die wahrscheinlich <i>vouchervault.json</i> heißt, um sie zu importieren.
\nOder erstellen Sie sie, indem Sie zuerst in Voucher Vault auf Export drücken.</string>
<string name="importVoucherVault">Aus Voucher Vault importieren</string>
<string name="importLoyaltyCardKeychainMessage">Bitte wählen Sie Ihre Loyalty Card Keychain-Exportdatei aus. Es heißt höchstwahrscheinlich LoyaltyCardKeychain.csv.
\n
\nEine Loyalty Card Keychain-Exportdatei kann erstellt werden, indem Sie im Menü Import/Export auf Exportieren klicken.</string>
<string name="importLoyaltyCardKeychainMessage">Suchen Sie eine Datei, die höchstwahrscheinlich <i>LoyaltyCardKeychain.csv</i> heißt, um sie zu importieren.
\nOder erstellen Sie sie über das Menü Import/Export in Loyalty Card Keychain, indem Sie zuerst auf Export drücken.</string>
<string name="importLoyaltyCardKeychain">Aus Loyalty Card Keychain importieren</string>
<string name="importFidmeMessage">Bitte wählen Sie Ihre FidMe-Exportdatei aus. Es wird höchstwahrscheinlich so etwas wie fidme-export-request-xxxxxx.zip genannt.
\n
\nEine FidMe-Exportdatei kann in der FidMe-Anwendung erstellt werden, indem Sie zu Ihrem Profil gehen, Datenschutz auswählen und dann auf Meine Daten extrahieren klicken.
\n
\nBitte beachten Sie, dass FidMe den Strichcode-Typ nicht in den Exportdaten speichert, sodass Sie die importierten Karten manuell bearbeiten müssen.</string>
<string name="importFidmeMessage">Suchen Sie eine Datei, die wahrscheinlich <i>fidme-export-request-xxxxxx.zip</i> heißt, um sie zu importieren, und wählen Sie anschließend die Strichcodetypen manuell aus.
\nOder erstellen Sie sie aus Ihrem FidMe-Profil, indem Sie Datenschutz wählen und dann zuerst auf Extrahiere meine Daten drücken.</string>
<string name="importFidme">Aus FidMe importieren</string>
<string name="importCatimaMessage">Bitte wählen Sie Ihre Catima-Exportdatei aus. Es heißt höchstwahrscheinlich Catima.csv.
\n
\nEine Catima-Exportdatei kann erstellt werden, indem Sie im Menü Import/Export auf Exportieren klicken.</string>
<string name="importCatimaMessage">Suchen Sie eine Datei, die wahrscheinlich <i>Catima.csv</i> heißt, um sie zu importieren.
\nOder erstellen Sie sie aus dem Import/Export-Menü einer anderen Catima-Anwendung, indem Sie dort zuerst Export drücken.</string>
<string name="importCatima">Aus Catima importieren</string>
<string name="setBarcodeId">Strichcodewert setzen</string>
<string name="sameAsCardId">Gleich wie Karten-ID</string>
@@ -147,7 +136,18 @@
<string name="errorReadingImage">Das Bild konnte nicht gelesen werden</string>
<string name="noBarcodeFound">Kein Strichcode gefunden</string>
<string name="addFromImage">Bild aus der Galerie auswählen</string>
<string name="settings_max_font_size_scale">Maximale Schriftgröße</string>
<string name="settings_max_font_size_scale">Max. Schriftgröße</string>
<string name="unsupportedBarcodeType">Dieser Strichcodetyp kann noch nicht angezeigt werden. Er wird möglicherweise in einer neueren Version der Anwendung unterstützt.</string>
<string name="wrongValueForBarcodeType">Der Wert ist für den gewählten Strichcodetyp nicht gültig</string>
<string name="app_resources">Freie Ressourcen von Drittanbietern: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries">Freie Bibliotheken von Drittanbietern: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
<string name="intent_import_card_from_url_share_multiple_text">Ich möchte Karten mit dir teilen</string>
<string name="copy_to_clipboard_multiple_toast">Kartennummern in die Zwischenablage kopiert</string>
<string name="card_ids_copied">Kartennummer(n) kopiert</string>
<string name="card_selected">"Ausgewählt: "</string>
<string name="no">Nein</string>
<string name="yes">Ja</string>
<string name="updateBarcodeQuestionText">Sie haben die Karten-ID geändert. Möchten Sie auch den Strichcode aktualisieren, um denselben Wert zu verwenden\?</string>
<string name="updateBarcodeQuestionTitle">Strichcodewert aktualisieren\?</string>
</resources>

View File

@@ -49,8 +49,6 @@
<string name="about_title_fmt">Σχετικά με <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Έκδοση: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Πληροφορίες Αναθεώρησης: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries">Το <xliff:g id="app_name">%s</xliff:g> χρησιμοποιεί τις ακόλουθες βιβλιοθήκες τρίτων: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources">Το <xliff:g id="app_name">%s</xliff:g> χρησιμοποιεί τους παρακάτω πόρους τρίτων: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="selectBarcodeTitle">Επιλέξτε Barcode</string>
<string name="copy_to_clipboard_toast">Ο κωδικός της κάρτας αντιγράφτηκε στο πρόχειρο</string>
<string name="thumbnailDescription">Μικρογραφία κάρτας</string>

View File

@@ -1,10 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
<string name="action_add">Añadir</string>
<string name="noGiftCards">Pulse el botón «+» para añadir una nueva tarjeta.
\n
\nCatima guarda sus tarjetas en el dispositivo, para que estén siempre a su alcance.</string>
<string name="storeName">Tienda</string>
<string name="noGiftCards">Pulse el botón «+» para añadir una tarjeta, o importe algunas del menú ⋮.</string>
<string name="storeName">Nombre</string>
<string name="note">Nota</string>
<string name="cardId">Id. de tarjeta</string>
<string name="cancel">Cancelar</string>
@@ -12,10 +10,10 @@
<string name="edit">Editar</string>
<string name="delete">Eliminar</string>
<string name="confirm">Confirmar</string>
<string name="lockScreen">Bloquear rotación</string>
<string name="unlockScreen">Desbloquear rotación</string>
<string name="lockScreen">Bloquear giro</string>
<string name="unlockScreen">Desbloquear giro</string>
<string name="deleteTitle">Eliminar tarjeta</string>
<string name="deleteConfirmation">Por favor, confirme que quiere eliminar esta tarjeta.</string>
<string name="deleteConfirmation">¿Quiere eliminar esta tarjeta\?</string>
<string name="ok">Aceptar</string>
<string name="copy_to_clipboard">Copiar id. en portapapeles</string>
<string name="sendLabel">Enviar…</string>
@@ -25,7 +23,7 @@
<string name="cardShortcut">Atajo de tarjeta</string>
<string name="noCardsMessage">Añada una tarjeta primero</string>
<string name="barcodeImageDescription">Imagen del código de barras de la tarjeta</string>
<string name="noStoreError">Establecimiento no especificado</string>
<string name="noStoreError">No se proporcionó ningún nombre</string>
<string name="noCardIdError">Id. de tarjeta no especificado</string>
<string name="noCardExistsError">No se ha podido encontrar la tarjeta</string>
<string name="importExport">Importar/exportar</string>
@@ -43,11 +41,11 @@
<string name="importOptionFilesystemTitle">Importar desde el sistema de archivos</string>
<string name="importOptionFilesystemExplanation">Elegir un archivo concreto del sistema de archivos.</string>
<string name="importOptionFilesystemButton">Desde el sistema de archivos</string>
<string name="importOptionApplicationTitle">Utilizar aplicación externa</string>
<string name="importOptionApplicationTitle">Utilizar otra aplicación</string>
<string name="importOptionApplicationExplanation">Use una aplicación o su gestor de archivos favoritos para abrir un archivo.</string>
<string name="importOptionApplicationButton">Utilizar aplicación externa</string>
<string name="importOptionApplicationButton">Utilizar otra aplicación</string>
<string name="about">Acerca de</string>
<string name="app_license">Software libre con copyleft, disponible bajo la licencia GPLv3+.</string>
<string name="app_license">Programa libre con «copyleft», disponible en virtud de la licencia GPLv3+.</string>
<string name="about_title_fmt">Acerca de <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Versión: <xliff:g id="version">%s</xliff:g></string>
<string name="settings">Configuración</string>
@@ -62,7 +60,8 @@
<string name="settings_system_theme">Sistema</string>
<string name="settings_theme">Tema</string>
<string name="enterBarcodeInstructions">Introduzca el identificador de tarjeta y seleccione la imagen que represente el código de barras que se utilizará, o bien, elija «Esta tarjeta no tiene código de barras» para no utilizar ninguno.</string>
<string name="app_copyright_old">Basado en Loyalty Card Keychain, derechos de autor 20162020 de Branden Archer.</string>
<string name="app_copyright_old">Basado en Loyalty Card Keychain
\nderechos de autor © 2016-2020 de Branden Archer.</string>
<string name="exportOptionExplanation">Los datos se guardarán en la ubicación que elija.</string>
<string name="failedParsingImportUriError">No se pudo procesar el URI de importación</string>
<string name="share">Compartir</string>
@@ -70,33 +69,29 @@
<string name="barcodeType">Tipo de código de barras</string>
<string name="noMatchingGiftCards">No se ha encontrado nada. Pruebe a modificar su búsqueda.</string>
<string name="action_search">Buscar</string>
<string name="app_libraries"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> usa las siguientes librerías de terceros: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_libraries_list">%s</xliff:g></string>
<string name="app_revision_fmt">Información de la revisión: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
<string name="noGroups">Pulse el botón «+» para añadir grupos.
\n
\nLos grupos permiten encontrar cosas fácilmente.</string>
<string name="app_revision_fmt">Información de la revisión: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="noGroups">Primero pulse en el botón «+» para añadir grupos de categorización.</string>
<string name="starImage">Favorito</string>
<string name="thumbnailDescription">Miniatura de la tarjeta</string>
<string name="copy_to_clipboard_toast">Id. de la tarjeta copiado al portapapeles</string>
<string name="copy_to_clipboard_toast">Se copió el identificador de tarjeta en el portapapeles</string>
<string name="selectBarcodeTitle">Seleccionar el código de barras</string>
<string name="app_resources"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> usa los siguientes recursos de terceros: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_resources_list">%s</xliff:g></string>
<string name="unstar">Eliminar de favoritos</string>
<string name="noBarcode">Sin código de barras</string>
<string name="enter_group_name">Introducir nombre del grupo</string>
<string name="groups">Grupos</string>
<string name="groupsList">Grupos: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="groupsList">Grupos: <xliff:g>%s</xliff:g></string>
<string name="addManually">Introducir el id. de la tarjeta manualmente</string>
<string name="leaveWithoutSaveConfirmation">¿Está seguro de querer abandonar esta página\? Los cambios no se guardarán.</string>
<string name="leaveWithoutSaveTitle">Salir sin guardar</string>
<string name="moveDown">Bajar en la lista</string>
<string name="moveUp">Subir en la lista</string>
<string name="failedOpeningFileManager">Fallo al abrir el gestor de archivos. Por favor, asegúrese de que haya uno instalado.</string>
<string name="deleteConfirmationGroup">Por favor, confirme que desea eliminar este grupo</string>
<string name="leaveWithoutSaveConfirmation">¿Quiere abandonar sin guardar\?</string>
<string name="leaveWithoutSaveTitle">Salir</string>
<string name="moveDown">Bajar</string>
<string name="moveUp">Subir</string>
<string name="failedOpeningFileManager">Instale un gestor de archivos primero.</string>
<string name="deleteConfirmationGroup">¿Quiere eliminar el grupo\?</string>
<string name="all">Todo</string>
<string name="star">Añadir a favoritos</string>
<plurals name="groupCardCount">
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> tarjeta</item>
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> tarjetas</item>
<item quantity="one"><xliff:g>%d</xliff:g> tarjeta</item>
<item quantity="other"><xliff:g>%d</xliff:g> tarjetas</item>
</plurals>
<string name="points">Puntos</string>
<string name="moveBarcodeToCenterOfScreen">Centrar el código de barras en la pantalla</string>
@@ -107,7 +102,10 @@
<string name="editBarcode">Editar el código de barras</string>
<string name="barcode">Código de barras</string>
<string name="card">Tarjeta</string>
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> puntos</string>
<string name="expiryStateSentenceExpired">Expirado: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentence">Expira: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
</resources>
<string name="balancePoints"><xliff:g>%s</xliff:g> puntos</string>
<string name="expiryStateSentenceExpired">Expirado: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentence">Expira: <xliff:g>%s</xliff:g></string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Derechos de autor © 2019-<xliff:g>%d</xliff:g> de Sylvia van Os.</string>
<string name="app_resources">Recursos de terceros libres: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries">Bibliotecas de terceros libres: <xliff:g id="app_libraries_list">%s</xliff:g></string>
</resources>

View File

@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
<string name="noExternalStoragePermissionError">Salli käyttöoikeus ulkoisen tallennustilan käyttöön voidaksesi tuoda tai viedä kortteja</string>
<string name="no">Ei</string>
<string name="yes">Kyllä</string>
<string name="updateBarcodeQuestionText">Vaihdoit kortin ID-tunnuksen. Haluatko päivittää myös viivakoodin käyttämään samaa arvoa\?</string>
<string name="updateBarcodeQuestionTitle">Päivitä viivakoodin arvo\?</string>
<string name="intent_import_card_from_url_share_multiple_text">Haluan jakaa joitain kortteja kanssasi</string>
<string name="copy_to_clipboard_multiple_toast">Kopioitiin korttitunnukset leikepöydälle</string>
<string name="wrongValueForBarcodeType">Arvo ei ole kelvollinen valitulle viivakoodityypille</string>
<string name="unsupportedBarcodeType">Tätä viivakoodityyppiä ei voi vielä näyttää. Sitä saatetaan tukea sovelluksen uudemmassa versiossa.</string>
<string name="setBarcodeId">Aseta viivakoodin arvo</string>
<string name="sameAsCardId">Sama kuin kortin ID-tunnus</string>
<string name="barcodeId">Viivakoodin arvo</string>
<string name="importVoucherVaultMessage">Etsi tiedostoa joka on todennäköisesti nimetty nimellä <i>vouchervault.json</i> tuotavaksi.
\nTai luo se Vie toiminnolla Voucher Vault sovelluksessa.</string>
<string name="importVoucherVault">Tuo Voucher Vault varmuuskopiotiedostosta</string>
<string name="importLoyaltyCardKeychainMessage">Etsi tiedostoa joka on todennäköisesti nimetty nimellä <i>LoyaltyCardKeychain.csv</i> tuotavaksi.
\nTai luo se Tuo/Vie toiminnolla Loyalty Card Keychain sovelluksessa, valitsemalla valikosta Vie.</string>
<string name="importLoyaltyCardKeychain">Tuo Loyalty Card Keychain varmuuskopiotiedostosta</string>
<string name="importFidmeMessage">Etsi tiedostoa joka on todennäköisesti nimetty nimellä <i>fidme-export-request-xxxxxx.zip</i> tuotavaksi ja valitse viivakoodityypit manuaalisesti jälkeenpäin.
\nTai luo se Tuo/Vie toiminnolla FidMe profiilistasi, valitsemalla Tietotosuoja ja sitten valitsemalla Vie tietoni.</string>
<string name="importFidme">Tuo FidMe varmuuskopiotiedostosta</string>
<string name="importCatimaMessage">Etsi tiedostoa joka on todennäköisesti nimetty nimellä <i>Catima.csv</i> tuotavaksi.
\nTai luo se Tuo/Vie toiminnolla toisen puhelimen Catima sovelluksessa, valitsemalla valikosta Vie.</string>
<string name="importCatima">Tuo Catima varmuuskopiotiedostosta</string>
<string name="accept">Hyväksy</string>
<string name="privacy_policy_popup_text">Tietosuojaseloste (joidenkin sovelluskauppojen vaatimus):
\n
\nMITÄÄN TIETOJA EI KERÄTÄ LAINKAAN, minkä kuka tahansa voi vahvistaa, koska sovelluksemma on vapaa ohjelmisto.</string>
<string name="privacy_policy">Tietosuojakäytäntö</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain varmuuskopiotiedostosta</string>
<string name="chooseImportType">Tuo tietoja kohteesta\?</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> ei vaikuta olevan kelvollinen saldo.</string>
<string name="points">Pisteet</string>
<string name="currency">Valuutta</string>
<string name="balance">Saldo</string>
<string name="errorReadingImage">Kuvaa ei voitu lukea</string>
<string name="noBarcodeFound">Viivakoodia ei löytynyt</string>
<string name="moveBarcodeToCenterOfScreen">Keskitä viivakoodi näytölle</string>
<string name="moveBarcodeToTopOfScreen">Siirrä viivakoodi näytön yläosaan</string>
<string name="chooseExpiryDate">Valitse viimeinen voimassaolopäivä</string>
<string name="never">Ei koskaan</string>
<string name="expiryDate">Viimeinen voimassaolopäivä</string>
<string name="editBarcode">Muokkaa viivakoodia</string>
<string name="barcode">Viivakoodi</string>
<string name="card">Kortti</string>
<string name="balancePoints"><xliff:g>%s</xliff:g> pistettä</string>
<string name="balanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Vanhentunut: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentence">Vanhenee: <xliff:g>%s</xliff:g></string>
<string name="groupsList">Ryhmät: <xliff:g>%s</xliff:g></string>
<string name="addFromImage">Valitse kuva galleriasta</string>
<string name="addManually">Anna kortin ID-tunnus manuaalisesti</string>
<string name="leaveWithoutSaveConfirmation">Poistu tallentamatta\?</string>
<string name="leaveWithoutSaveTitle">Poistu</string>
<string name="moveDown">Siirrä alaspäin</string>
<string name="moveUp">Siirrä ylöspäin</string>
<string name="failedOpeningFileManager">Asenna ensin tiedostonhallintaohjelma.</string>
<string name="deleteConfirmationGroup">Poista ryhmä\?</string>
<string name="all">Kaikki</string>
<plurals name="groupCardCount">
<item quantity="one"><xliff:g>%d</xliff:g> kortti</item>
<item quantity="other"><xliff:g>%d</xliff:g> kortit</item>
</plurals>
<string name="noGroups">Napsauta + plus-painiketta lisätäksesi ensin ryhmät luokittelua varten.</string>
<string name="groups">Ryhmät</string>
<string name="enter_group_name">Anna ryhmän nimi</string>
<string name="exportSuccessful">Korttitietojen vienti valmis</string>
<string name="importSuccessful">Korttitietojen tuonti valmis</string>
<string name="intent_import_card_from_url_share_text">Haluan jakaa kortin kanssasi</string>
<string name="settings_disable_lockscreen_while_viewing_card">Estä lukitusnäyttö</string>
<string name="settings_keep_screen_on">Pidä näyttö päällä</string>
<string name="settings_lock_barcode_orientation">Lukitse viivakoodin suunta</string>
<string name="settings_display_barcode_max_brightness">Kirkasta viivakoodinäkymää</string>
<string name="settings_max_font_size_scale">Fontin enimmäiskoko</string>
<string name="settings_dark_theme">Tumma</string>
<string name="settings_light_theme">Vaalea</string>
<string name="settings_system_theme">Järjestelmän oletus</string>
<string name="settings_theme">Teema</string>
<string name="settings_category_title_ui">Käyttöliittymä</string>
<string name="settings">Asetukset</string>
<string name="starImage">Suosikki tähti</string>
<string name="thumbnailDescription">Kortin pikkukuva</string>
<string name="copy_to_clipboard_toast">Kortin ID-tunnus kopioitu leikepöydälle</string>
<string name="enterBarcodeInstructions">Syötä kortin ID-tunnus ja valitse sen viivakoodityyppi, tai valitse \"Tällä kortilla ei ole viivakoodia\".</string>
<string name="selectBarcodeTitle">Valitse viivakoodi</string>
<string name="app_resources">Kolmannen osapuolen vapaat resurssit: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries">Kolmannen osapuolen vapaat kirjastot: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_revision_fmt">Muutostiedot: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="debug_version_fmt">Versio: <xliff:g id="version">%s</xliff:g></string>
<string name="about_title_fmt">Tietoja <xliff:g id="app_name">%s</xliff:g></string>
<string name="app_license">Copyleft (käyttäjänoikeus) - vapaa ohjelmisto, lisenssi GPLv3+.</string>
<string name="app_copyright_old">Perustuu Loyalty Card Keychain sovellukseen
\ntekijänoikeus © 20162020 Branden Archer.</string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Tekijänoikeus © 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
<string name="about">Tietoja</string>
<string name="importOptionApplicationButton">Käytä toista sovellusta</string>
<string name="importOptionApplicationExplanation">Käytä mitä tahansa sovellusta tai suosikkitiedostonhallintaasi tiedoston avaamiseen.</string>
<string name="importOptionApplicationTitle">Käytä toista sovellusta</string>
<string name="importOptionFilesystemButton">Tiedostojärjestelmästä</string>
<string name="importOptionFilesystemExplanation">Valitse tietty tiedosto tiedostojärjestelmästä.</string>
<string name="importOptionFilesystemTitle">Tuo tiedostojärjestelmästä</string>
<string name="exportOptionExplanation">Tiedot kirjoitetaan valitsemaasi sijaintiin.</string>
<string name="exporting">Viedään…</string>
<string name="importing">Tuodaan…</string>
<string name="exportFailed">Kortteja ei voitu viedä</string>
<string name="exportFailedTitle">Vienti epäonnistui</string>
<string name="exportSuccessfulTitle">Vienti valmis</string>
<string name="importFailed">Kortteja ei voitu tuoda</string>
<string name="importFailedTitle">Tuonti epäonnistui</string>
<string name="importSuccessfulTitle">Tuonti valmis</string>
<string name="importExportHelp">Varmuuskopioimalla korttisi, voit siirtää ne toiseen laitteeseen.</string>
<string name="exportName">Vie</string>
<string name="importExport">Tuo/Vie</string>
<string name="failedParsingImportUriError">Tuonnin URI: n jäsentäminen epäonnistui</string>
<string name="noCardExistsError">Korttia ei löytynyt</string>
<string name="noCardIdError">Kortin ID-tunnusta ei annettu</string>
<string name="noStoreError">Nimeä ei annettu</string>
<string name="barcodeImageDescription">Kuva kortin viivakoodista</string>
<string name="card_ids_copied">Kopioidut korttitunnukset</string>
<string name="noCardsMessage">Lisää ensin kortti</string>
<string name="cardShortcut">Kortin pikakuvake</string>
<string name="scanCardBarcode">Skannaa kortin viivakoodi</string>
<string name="addCardTitle">Lisää kortti</string>
<string name="editCardTitle">Muokkaa korttia</string>
<string name="sendLabel">Lähetä…</string>
<string name="share">Jaa</string>
<string name="copy_to_clipboard">Kopioi ID-tunnus leikepöydälle</string>
<string name="ok">OK</string>
<string name="deleteConfirmation">Poista tämä kortti\?</string>
<string name="deleteTitle">Poista kortti</string>
<string name="unlockScreen">Poista kierron esto</string>
<string name="lockScreen">Estä kierto</string>
<string name="confirm">Vahvista</string>
<string name="delete">Poista</string>
<string name="edit">Muokkaa</string>
<string name="save">Tallenna</string>
<string name="cancel">Peruuta</string>
<string name="unstar">Poista suosikeista</string>
<string name="star">Lisää suosikkeihin</string>
<string name="noBarcode">Ei viivakoodia</string>
<string name="barcodeNoBarcode">Tällä kortilla ei ole viivakoodia</string>
<string name="barcodeType">Viivakoodin tyyppi</string>
<string name="cardId">Kortin ID-tunnus</string>
<string name="note">Lisätieto</string>
<string name="storeName">Nimi</string>
<string name="noMatchingGiftCards">Ei hakutuloksia, kokeile toisella hakutermillä.</string>
<string name="noGiftCards">Lisää ensin kortti napsauttamalla + plus-painiketta, tai mene ⋮ valikkoon tuodaksesi varmuuskopiosta.</string>
<string name="card_selected">"Valittu: "</string>
<string name="action_add">Lisää</string>
<string name="action_search">Hae</string>
</resources>

View File

@@ -1,10 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
<string name="action_add">Ajouter</string>
<string name="noGiftCards">Appuyez d\'abord sur le bouton + (plus) pour ajouter une carte.
\n
\nCatima enregistre vos cartes sur votre appareil, pour toujours les avoir à portée de main.</string>
<string name="storeName">Magasin</string>
<string name="noGiftCards">Cliquez sur le bouton + plus pour ajouter une carte, ou importez-en dabord depuis le menu ⋮</string>
<string name="storeName">Nom</string>
<string name="note">Notes</string>
<string name="cardId">Numéro</string>
<string name="cancel">Annuler</string>
@@ -15,7 +13,7 @@
<string name="lockScreen">Désactiver la rotation</string>
<string name="unlockScreen">Activer la rotation</string>
<string name="deleteTitle">Supprimer la carte de fidélité</string>
<string name="deleteConfirmation">Confirmez la suppression de cette carte.</string>
<string name="deleteConfirmation">Supprimer cette carte \?</string>
<string name="ok">OK</string>
<string name="copy_to_clipboard">Copier le numéro dans le presse-papier</string>
<string name="sendLabel">Envoyer…</string>
@@ -25,7 +23,7 @@
<string name="cardShortcut">Raccourci de carte</string>
<string name="noCardsMessage">Ajoutez d\'abord une carte</string>
<string name="barcodeImageDescription">Image du code-barres</string>
<string name="noStoreError">Aucun nom de magasin saisi</string>
<string name="noStoreError">Aucun nom saisi</string>
<string name="noCardIdError">Aucun numéro de carte saisi</string>
<string name="noCardExistsError">Aucune carte trouvée</string>
<string name="importExport">Importer/Exporter</string>
@@ -43,16 +41,14 @@
<string name="importOptionFilesystemTitle">Importer depuis le système de fichiers</string>
<string name="importOptionFilesystemExplanation">Choisissez le fichier à importer.</string>
<string name="importOptionFilesystemButton">Système de fichiers</string>
<string name="importOptionApplicationTitle">Utiliser une application externe</string>
<string name="importOptionApplicationTitle">Utiliser une autre application</string>
<string name="importOptionApplicationExplanation">Utilisez le gestionnaire de fichiers de votre choix pour importer un fichier.</string>
<string name="importOptionApplicationButton">Utiliser une application externe</string>
<string name="importOptionApplicationButton">Utiliser une autre application</string>
<string name="about">À propos</string>
<string name="app_license">Logiciel libre à copyleft, sous licence GPLv3+.</string>
<string name="about_title_fmt">À propos de <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Version : <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Notes de version : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> utilise les bibliothèques-tierces suivantes : <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> utilise les ressources tierces suivantes : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_resources_list">%s</xliff:g></string>
<string name="app_revision_fmt">Notes de version : <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="selectBarcodeTitle">Choisissez le code-barres</string>
<string name="copy_to_clipboard_toast">Numéro de carte copié dans le presse-papier</string>
<string name="thumbnailDescription">Miniature de la carte</string>
@@ -67,9 +63,10 @@
<string name="settings_light_theme">Clair</string>
<string name="settings_system_theme">Système</string>
<string name="settings_theme">Thème</string>
<string name="enterBarcodeInstructions">Entrez l\'identifiant de la carte puis sélectionnez l\'image qui représente le code-barres que vous souhaitez utiliser, ou sélectionnez « Cette carte n\'a pas de code-barres » pour ne pas utiliser de code-barres.</string>
<string name="app_copyright_old">Basé sur Loyalty Card Keychain, copyright 20162020 Branden Archer.</string>
<string name="exportOptionExplanation">Les données seront eportées vers l\'emplacement de votre choix.</string>
<string name="enterBarcodeInstructions">Entrez lidentifiant de la carte et choisissez le type de code-barres ci-dessous, ou « Cette carte na pas de code-barres ».</string>
<string name="app_copyright_old">Basé sur Loyalty Card Keychain
\ncopyright © 2016-2020 Branden Archer.</string>
<string name="exportOptionExplanation">Les données seront exportées vers l\'emplacement de votre choix.</string>
<string name="failedParsingImportUriError">Impossible d\'analyser l\'URI d\'importation</string>
<string name="share">Partager</string>
<string name="barcodeNoBarcode">Cette carte n\'a pas de code-barres</string>
@@ -79,11 +76,9 @@
<string name="unstar">Retirer des favoris</string>
<string name="star">Ajouter aux favoris</string>
<string name="starImage">Étoile favorite</string>
<string name="deleteConfirmationGroup">Confirmez que vous voulez supprimer ce groupe</string>
<string name="deleteConfirmationGroup">Supprimer le groupe \?</string>
<string name="all">Tous</string>
<string name="noGroups">Cliquez d\'abord sur le bouton + (plus) pour ajouter un groupe.
\n
\nLes groupes permettent de facilement retrouver vos cartes.</string>
<string name="noGroups">Cliquez sur le bouton + pour ajouter des groupes à catégoriser.</string>
<string name="groups">Groupes</string>
<string name="enter_group_name">Entrez le nom du groupe</string>
<string name="noBarcode">Aucun code-barres</string>
@@ -91,17 +86,17 @@
<string name="leaveWithoutSaveTitle">Quitter</string>
<string name="failedOpeningFileManager">Installez dabord un gestionnaire de fichiers.</string>
<string name="addManually">Entrer manuellement l\'identifiant de la carte</string>
<string name="moveDown">Descendre dans la liste</string>
<string name="moveUp">Monter dans la liste</string>
<string name="moveDown">Descendre</string>
<string name="moveUp">Monter</string>
<plurals name="groupCardCount">
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> carte</item>
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> cartes</item>
<item quantity="one"><xliff:g>%d</xliff:g> carte</item>
<item quantity="other"><xliff:g>%d</xliff:g> cartes</item>
</plurals>
<string name="groupsList">Groupes : <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="groupsList">Groupes : <xliff:g>%s</xliff:g></string>
<string name="accept">Accepter</string>
<string name="privacy_policy_popup_text">Avis sur la politique de confidentialité (exigé par certains magasins d\'applications) :
\n
\nNous ne collectons AUCUNE DONNÉE, ce que tout le monde peut confirmer puisque notre application est un logiciel libre.</string>
\nAUCUNE DONNÉE NEST COLLECTÉE, ce que tout le monde peut confirmer puisque notre application est un logiciel libre.</string>
<string name="privacy_policy">Politique de confidentialité</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="chooseImportType">Importer les données depuis \?</string>
@@ -121,25 +116,19 @@
<string name="balanceSentence">Solde : &lt;xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\"&gt;%s&lt;/xliff:g&gt;</string>
<string name="expiryStateSentenceExpired">Expiré : &lt;xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\"&gt;%s&lt;/xliff:g&gt;</string>
<string name="expiryStateSentence">Expire : &lt;xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\"&gt;%s&lt;/xliff:g&gt;</string>
<string name="settings_disable_lockscreen_while_viewing_card">Désactiver l\'écran de verrouillage pendant l\'affichage d\'une carte</string>
<string name="settings_keep_screen_on">Garder l\'écran allumé pendant l\'affichage d\'une carte</string>
<string name="importVoucherVaultMessage">Veuillez sélectionner votre fichier d\'exportation Voucher Vault. Il est probablement nommé vouchervault.json.
\n
\nUn fichier d\'exportation Voucher Vault peut être créé en appuyant sur Exporter.</string>
<string name="settings_disable_lockscreen_while_viewing_card">Empêcher le verrouillage de lécran</string>
<string name="settings_keep_screen_on">Garder lécran allumé</string>
<string name="importVoucherVaultMessage">Trouvez un fichier probablement nommé <i>vouchervault.json</i> à importer.
\nOu créez-le en appuyant dabord sur Exporter dans Voucher Vault.</string>
<string name="importVoucherVault">Importer depuis Voucher Vault</string>
<string name="importLoyaltyCardKeychainMessage">Veuillez sélectionner votre fichier d\'exportation Loyalty Card Keychain . Il s\'appelle très probablement LoyaltyCardKeychain.csv.
\n
\nUn fichier d\'exportation Loyalty Card Keychain peut être créé en allant dans le menu Importer/Exporter et en appuyant sur Exporter.</string>
<string name="importLoyaltyCardKeychainMessage">Trouvez un fichier probablement nommé <i>LoyaltyCardKeychain.csv</i> à importer.
\nOu créez-le à partir du menu Importer/Exporter du Loyalty Card Keychain en appuyant dabord sur Exporter.</string>
<string name="importLoyaltyCardKeychain">Importer depuis Loyalty Card Keychain</string>
<string name="importFidmeMessage">Veuillez sélectionner votre fichier d\'exportation FidMe. Il est très probablement nommé quelque chose comme fidme-export-request-xxxxxx.zip.
\n
\nUn fichier d\'exportation FidMe peut être créé dans l\'application FidMe en accédant à votre profil, en choisissant Protection des données, puis en appuyant sur Extraire mes données.
\n
\nVeuillez noter que FidMe ne stocke pas le type de code-barres dans les données d\'exportation, vous devrez donc éditer les cartes importées manuellement.</string>
<string name="importFidmeMessage">Trouvez un fichier probablement nommé <i>fidme-export-request-xxxxxx.zip</i> pour limporter, et sélectionnez ensuite manuellement les types de codes-barres.
\nVous pouvez aussi le créer à partir de votre profil FidMe en choisissant Protection des données, puis en cliquant sur Extraire mes données.</string>
<string name="importFidme">Importer depuis FidMe</string>
<string name="importCatimaMessage">Veuillez sélectionner votre fichier d\'exportation Catima. Il est probablement nommé Catima.csv.
\n
\nUn fichier d\'exportation Catima peut être créé en allant dans le menu Importer/Exporter et en appuyant sur Exporter.</string>
<string name="importCatimaMessage">Trouvez un fichier probablement nommé <i>Catima.csv</i> à importer.
\nOu créez-le à partir du menu Importer/Exporter dune autre application Catima en appuyant dabord sur Exporter.</string>
<string name="importCatima">Importer depuis Catima</string>
<string name="addFromImage">Sélectionner dans la galerie</string>
<string name="errorReadingImage">Impossible de lire l\'image</string>
@@ -147,7 +136,18 @@
<string name="setBarcodeId">Définir la valeur du code-barres</string>
<string name="sameAsCardId">Identique à lidentifiant de la carte</string>
<string name="barcodeId">Valeur du code-barres</string>
<string name="settings_max_font_size_scale">Échelle maximale de taille de police</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 plus récente de l\'application.</string>
<string name="wrongValueForBarcodeType">La valeur n\'est pas valide pour le type de code-barres sélectionné</string>
<string name="app_resources">Ressources libres tierces : <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries">Bibliothèques libres tierces : <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
<string name="intent_import_card_from_url_share_multiple_text">Je veux partager des cartes avec vous</string>
<string name="copy_to_clipboard_multiple_toast">Nméros des cartes copiés dans le presse-papier</string>
<string name="card_ids_copied">Num. de la carte copié(s)</string>
<string name="card_selected">"Sélectionnée : "</string>
<string name="updateBarcodeQuestionText">Vous avez changé l\'identifiant de la carte. Voulez-vous également mettre à jour le code-barres pour utiliser la même valeur \?</string>
<string name="no">Non</string>
<string name="yes">Oui</string>
<string name="updateBarcodeQuestionTitle">Mettre à jour la valeur du code-barres \?</string>
</resources>

View File

@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
<string name="action_search">Cerca</string>
<string name="action_add">Aggiungi</string>
<string name="noGiftCards">Fai clic sul pulsante + (più) per aggiungere prima una carta.
\n
\nCatima trasporta le tue carte sul dispositivo, quindi sono sempre a portata di mano.</string>
<string name="noGiftCards">Clicca il pulsante + più per aggiungere una carta, o importane alcune dal menù ⋮ prima.</string>
<string name="noMatchingGiftCards">Non ho trovato niente. Prova a cambiare la tua ricerca.</string>
<string name="storeName">Negozio</string>
<string name="storeName">Nome</string>
<string name="note">Note</string>
<string name="cardId">Codice</string>
<string name="barcodeNoBarcode">Questa carta non ha un codice a barre</string>
@@ -18,7 +16,7 @@
<string name="lockScreen">Blocca rotazione</string>
<string name="unlockScreen">Sblocca rotazione</string>
<string name="deleteTitle">Rimuovi carta fedeltà</string>
<string name="deleteConfirmation">Conferma di voler eliminare questa carta.</string>
<string name="deleteConfirmation">Eliminare questa carta\?</string>
<string name="ok">OK</string>
<string name="copy_to_clipboard">Copia ID negli appunti</string>
<string name="share">Condividi</string>
@@ -29,7 +27,7 @@
<string name="cardShortcut">Scorciatoia per la carta</string>
<string name="noCardsMessage">Aggiungi prima una carta</string>
<string name="barcodeImageDescription">Immagine del codice della carta</string>
<string name="noStoreError">Nessun negozio inserito</string>
<string name="noStoreError">Nessun nome inserito</string>
<string name="noCardIdError">Nessun codice carta inserito</string>
<string name="noCardExistsError">Impossibile trovare la carta</string>
<string name="failedParsingImportUriError">Impossibile analizzare l\'URI</string>
@@ -48,19 +46,17 @@
<string name="importOptionFilesystemTitle">Importa dal file system</string>
<string name="importOptionFilesystemExplanation">Scegli un file dal file system.</string>
<string name="importOptionFilesystemButton">Dal file system</string>
<string name="importOptionApplicationTitle">Usa un\'applicazione esterna</string>
<string name="importOptionApplicationTitle">Usa unaltra app</string>
<string name="importOptionApplicationExplanation">Usa qualsiasi app o il tuo gestore di file preferito per aprire un file.</string>
<string name="importOptionApplicationButton">Usa un\'applicazione esterna</string>
<string name="importOptionApplicationButton">Usa unaltra app</string>
<string name="about">Informazioni</string>
<string name="app_license">Software libero con copyleft, licenza GPLv3+.</string>
<string name="about_title_fmt">Informazioni su <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Versione: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Informazioni sulla revisione: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url"> %s </xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> usa le seguenti librerie di terze parti: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> usa le seguenti risorse di terze parti: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_revision_fmt">Informazioni sulla revisione: <xliff:g id="app_revision_url"> %s </xliff:g></string>
<string name="selectBarcodeTitle">Seleziona codice a barre</string>
<string name="enterBarcodeInstructions">Immettere l\'ID della carta, quindi selezionare l\'immagine che rappresenta il codice a barre desiderato oppure selezionare «Questa carta non ha un codice a barre» per non valorizzare il dato.</string>
<string name="copy_to_clipboard_toast">ID della carta copiato negli appunti</string>
<string name="enterBarcodeInstructions">Inserisci lID della carta, e scegli il suo tipo di codice a barre qui sotto, oppure «Questa carta non ha codice a barre».</string>
<string name="copy_to_clipboard_toast">Numero della carta copiato negli appunti</string>
<string name="thumbnailDescription">Miniatura carta</string>
<string name="settings">Impostazioni</string>
<string name="settings_category_title_ui">Interfaccia utente</string>
@@ -73,30 +69,29 @@
<string name="intent_import_card_from_url_share_text">Voglio condividere una carta fedeltà con te</string>
<string name="exportSuccessful">Dati della carta importati</string>
<string name="importSuccessful">Dati della carta importati</string>
<string name="app_copyright_old">Basato su Loyalty Card Keychain, copyright 20162020 Branden Archer.</string>
<string name="app_copyright_old">Basato su Loyalty Card Keychain
\ncopyright © 20162020 Branden Archer.</string>
<string name="exportOptionExplanation">I dati verranno scritti in una posizione a tua scelta.</string>
<string name="barcodeType">Tipo di codice a barre</string>
<string name="unstar">Rimuovi dai preferiti</string>
<string name="star">Aggiungi ai preferiti</string>
<string name="starImage">Stella preferita</string>
<string name="deleteConfirmationGroup">Conferma di voler eliminare questo gruppo</string>
<string name="deleteConfirmationGroup">Eliminare il gruppo\?</string>
<string name="all">Tutti</string>
<string name="noGroups">Fai clic sul pulsante + (più) per aggiungere prima i gruppi.
\n
\nI gruppi rendono le cose più facili da trovare.</string>
<string name="noGroups">Clicca sul pulsante + più per aggiungere prima i gruppi per la categorizzazione.</string>
<string name="groups">Gruppi</string>
<string name="enter_group_name">Inserisci il nome del gruppo</string>
<string name="groupsList">Gruppi: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="groupsList">Gruppi: <xliff:g>%s</xliff:g></string>
<string name="addManually">Inserisci manualmente l\'ID della carta</string>
<string name="leaveWithoutSaveConfirmation">Uscire senza salvare\?</string>
<string name="leaveWithoutSaveTitle">Esci</string>
<string name="moveDown">Sposta in basso nell\'elenco</string>
<string name="moveUp">Sposta in alto nell\'elenco</string>
<string name="moveDown">Sposta in basso</string>
<string name="moveUp">Sposta in alto</string>
<string name="failedOpeningFileManager">Installa prima un gestore di file.</string>
<string name="noBarcode">Nessun codice a barre</string>
<plurals name="groupCardCount">
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> carta</item>
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> carte</item>
<item quantity="one"><xliff:g>%d</xliff:g> carta</item>
<item quantity="other"><xliff:g>%d</xliff:g> carte</item>
</plurals>
<string name="parsingBalanceFailed">&lt;xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\"&gt;%s&lt;/xliff:g&gt; non sembra un saldo corretto.</string>
<string name="points">Punti</string>
@@ -110,36 +105,30 @@
<string name="editBarcode">Modifica il codice a barre</string>
<string name="barcode">Codice a barre</string>
<string name="card">Carta</string>
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> punti</string>
<string name="balanceSentence">Saldo: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Scaduta: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentence">Scade: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="settings_keep_screen_on">Mantieni schermo acceso durante la visualizzazione di una carta</string>
<string name="balancePoints"><xliff:g>%s</xliff:g> punti</string>
<string name="balanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Scaduta: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentence">Scade: <xliff:g>%s</xliff:g></string>
<string name="settings_keep_screen_on">Tieni schermo attivo</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="chooseImportType">Importare i dati da\?</string>
<string name="settings_disable_lockscreen_while_viewing_card">Mantieni schermo attivo mentre visualizzi una carta</string>
<string name="settings_disable_lockscreen_while_viewing_card">Impedisci blocco schermo</string>
<string name="accept">Accetta</string>
<string name="privacy_policy_popup_text">Informativa sulla riservatezza (spesso richiesta):
\n
\nNon raccogliamo NESSUN dato, cosa che chiunque può confermare dato che la nostra applicazione è un software libero.</string>
\nNESSUN DATO VIENE RACCOLTO, cosa che chiunque può confermare dato che la nostra applicazione è un software libero.</string>
<string name="privacy_policy">Informativa sulla riservatezza</string>
<string name="importVoucherVaultMessage">Seleziona il tuo file di esportazione Voucher Vault. Molto probabilmente si chiama vouchervault.json.
\n
\nÈ possibile creare un file di esportazione Voucher Vault premendo Esporta.</string>
<string name="importVoucherVaultMessage">Trova un file probabilmente chiamato <i>vouchervault.json</i> da importare.
\nOppure crealo premendo prima Esporta in Voucher Vault.</string>
<string name="importVoucherVault">Importa da Voucher Vault</string>
<string name="importLoyaltyCardKeychainMessage">Seleziona il file di esportazione Loyalty Card Keychain . Molto probabilmente si chiama LoyaltyCardKeychain.csv.
\n
\nÈ possibile creare un file di esportazione Loyalty Card Keychain accedendo al menu Importa / Esporta e premendo Esporta.</string>
<string name="importLoyaltyCardKeychainMessage">Trova un file probabilmente chiamato <i>LoyaltyCardKeychain.csv</i> da importare.
\nOppure crealo dal menù Importa/Esporta nel Loyalty Card Keychain premendo prima Esporta.</string>
<string name="importLoyaltyCardKeychain">Importa da Loyalty Card Keychain</string>
<string name="importFidmeMessage">Seleziona il tuo file di esportazione FidMe. Molto probabilmente si chiama qualcosa come fidme-export-request-xxxxxx.zip.
\n
\nUn file di esportazione FidMe può essere creato nell\'app FidMe andando sul tuo profilo, scegliendo Protezione dati e quindi premendo Estrai i miei dati.
\n
\nTieni presente che FidMe non memorizza il tipo di codice a barre nei dati di esportazione, quindi dovrai modificare manualmente le carte importate.</string>
<string name="importFidmeMessage">Trova un file probabilmente chiamato <i>fidme-export-request-xxxxxx.zip</i> da importare, e poi seleziona i tipi di codice a barre manualmente in seguito.
\nOppure crearlo dal tuo profilo FidMe scegliendo Protezione dati e poi premendo Estrai i miei dati prima.</string>
<string name="importFidme">Importa da FidMe</string>
<string name="importCatimaMessage">Seleziona il tuo file di esportazione Catima. Molto probabilmente si chiama Catima.csv.
\n
\nÈ possibile creare un file di esportazione Catima andando nel menu Importa / Esporta e premendo Esporta.</string>
<string name="importCatimaMessage">Trova un file probabilmente chiamato <i>Catima.csv</i> da importare.
\nOppure crealo dal menù Importa/Esporta di unaltra applicazione Catima premendo prima Esporta.</string>
<string name="importCatima">Importa da Catima</string>
<string name="setBarcodeId">Imposta il valore del codice a barre</string>
<string name="sameAsCardId">Uguale all\'ID della carta</string>
@@ -147,7 +136,18 @@
<string name="errorReadingImage">Impossibile leggere l\'immagine</string>
<string name="noBarcodeFound">Nessun codice a barre trovato</string>
<string name="addFromImage">Seleziona immagine dalla galleria</string>
<string name="settings_max_font_size_scale">Scala massima delle dimensioni dei caratteri</string>
<string name="settings_max_font_size_scale">Dimensione mass. caratteri</string>
<string name="unsupportedBarcodeType">Questo tipo di codice a barre non può ancora essere visualizzato. Potrebbe essere supportato in una versione più recente dell\'applicazione.</string>
<string name="wrongValueForBarcodeType">Il valore non è valido per il tipo di codice a barre selezionato</string>
<string name="app_resources">Risorse libre di terze parti: <xliff:g id="app_resources_list"> %s </xliff:g></string>
<string name="app_libraries">Librerie libre di terze parti: <xliff:g id="app_libraries_list"> %s </xliff:g></string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
<string name="intent_import_card_from_url_share_multiple_text">Voglio condividere alcune carte con te</string>
<string name="copy_to_clipboard_multiple_toast">Numeri delle carte copiati negli appunti</string>
<string name="card_ids_copied">Numero/i della carta copiato/i</string>
<string name="card_selected">"Selezionata: "</string>
<string name="no">No</string>
<string name="yes"></string>
<string name="updateBarcodeQuestionText">Hai cambiato l\'ID della carta. Vuoi anche aggiornare il codice a barre per usare lo stesso valore\?</string>
<string name="updateBarcodeQuestionTitle">Aggiornare il valore del codice a barre\?</string>
</resources>

View File

@@ -0,0 +1,148 @@
<?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">インポートするには <i>LoyaltyCardKeychain.csv</i> のような名前のファイルを選択してください。
\nまたは、あらかじめ Loyalty Card Keychainアプリからファイルをエクスポートしてください。</string>
<string name="importLoyaltyCardKeychain">Loyalty Card Keychain からインポート</string>
<string name="importFidmeMessage">インポートするには <i>fidme-export-request-xxxxxx.zip</i> のような名前のファイルを選択してください。そのあと手動でバーコード形式を選択してください。
\nまたは 、あらかじめFidMeからファイルを作成してください。</string>
<string name="importFidme">FidMe からインポート</string>
<string name="importCatimaMessage">インポートするには <i>Catima.csv</i> のような名前のファイルを選択してください。
\nまたは、あらかじめ他のCatima アプリからファイルをエクスポートしてください。</string>
<string name="importCatima">Catima からインポート</string>
<string name="accept">承認</string>
<string name="privacy_policy_popup_text">プライバシーポリシーの案内:
\n
\nこのアプリはユーザーのデータを一切収集しません。</string>
<string name="privacy_policy">プライバシーポリシー</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="chooseImportType">インポート元を選択</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> は有効な残高ではないようです。</string>
<string name="points">ポイント</string>
<string name="currency">通貨</string>
<string name="balance">残高</string>
<string name="errorReadingImage">画像が読み込めませんでした</string>
<string name="noBarcodeFound">バーコードが見つかりませんでした</string>
<string name="moveBarcodeToCenterOfScreen">バーコードを画面の中央に配置</string>
<string name="moveBarcodeToTopOfScreen">バーコードを画面の上部に移動</string>
<string name="chooseExpiryDate">有効期限を選択</string>
<string name="never">なし</string>
<string name="expiryDate">有効期限</string>
<string name="editBarcode">バーコードの編集</string>
<string name="barcode">バーコード</string>
<string name="card">カード</string>
<string name="balancePoints"><xliff:g>%s</xliff:g> ポイント</string>
<string name="balanceSentence">残高: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentenceExpired">期限: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentence">期限: <xliff:g>%s</xliff:g></string>
<string name="groupsList">グループ: <xliff:g>%s</xliff:g></string>
<string name="addFromImage">ギャラリーから画像を選択</string>
<string name="addManually">カード番号を手動で入力</string>
<string name="leaveWithoutSaveConfirmation">保存せずに終了しますか?</string>
<string name="leaveWithoutSaveTitle">終了する</string>
<plurals name="groupCardCount">
<item quantity="other"><xliff:g>%d</xliff:g></item>
</plurals>
<string name="moveDown">下に移動</string>
<string name="moveUp">上に移動</string>
<string name="failedOpeningFileManager">ファイルマネージャーをインストールしてください。</string>
<string name="deleteConfirmationGroup">グループを削除しますか?</string>
<string name="all">すべて</string>
<string name="noGroups">+ボタンを押してグループを追加してください。</string>
<string name="groups">グループ</string>
<string name="enter_group_name">グループ名を入力</string>
<string name="exportSuccessful">カードのデータがエクスポートされました</string>
<string name="importSuccessful">カードのデータがインポートされました</string>
<string name="intent_import_card_from_url_share_text">あなたとカードを共有したいです</string>
<string name="settings_disable_lockscreen_while_viewing_card">バーコード表示中は画面をロックしない</string>
<string name="settings_keep_screen_on">バーコード表示中は画面を消灯しない</string>
<string name="settings_lock_barcode_orientation">バーコード表示画面を自動回転しない</string>
<string name="settings_display_barcode_max_brightness">バーコード表示画面を明るくする</string>
<string name="settings_max_font_size_scale">最大のフォントサイズ</string>
<string name="settings_dark_theme">ダーク</string>
<string name="settings_light_theme">ライト</string>
<string name="settings_system_theme">システムに従う</string>
<string name="settings_theme">テーマ</string>
<string name="settings_category_title_ui">ユーザーインターフェイス</string>
<string name="settings">設定</string>
<string name="starImage">お気に入りのスター</string>
<string name="thumbnailDescription">カードのサムネイル</string>
<string name="copy_to_clipboard_toast">カード番号をクリップボードにコピーしました</string>
<string name="enterBarcodeInstructions">カード番号を入力し、バーコード形式を選択してください。</string>
<string name="selectBarcodeTitle">バーコード選択</string>
<string name="app_libraries">Third-party libre libraries: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_revision_fmt">Revision Info: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="debug_version_fmt">Version: <xliff:g id="version">%s</xliff:g></string>
<string name="about_title_fmt">About <xliff:g id="app_name">%s</xliff:g></string>
<string name="app_license">Copylefted libre software, licensed GPLv3+.</string>
<string name="app_copyright_old">Based on Loyalty Card Keychain
\ncopyright © 20162020 Branden Archer.</string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
<string name="app_resources">Third-party libre resources: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="about">Catimaについて</string>
<string name="importOptionApplicationButton">外部のアプリを使う</string>
<string name="importOptionApplicationExplanation">任意のアプリやお気に入りのファイルマネージャーからファイルを開く。</string>
<string name="importOptionApplicationTitle">外部アプリを使う</string>
<string name="importOptionFilesystemButton">ファイルを選択</string>
<string name="importOptionFilesystemExplanation">ストレージからファイルを選択してください。</string>
<string name="importOptionFilesystemTitle">ストレージからインポート</string>
<string name="exportOptionExplanation">選択した場所にデータを出力します。</string>
<string name="noExternalStoragePermissionError">カードをインポート/エクスポートするために外部ストレージへのアクセスを許可してください</string>
<string name="exporting">エクスポート中…</string>
<string name="importing">インポート中…</string>
<string name="exportFailed">カードをエクスポートできませんでした</string>
<string name="exportFailedTitle">エクスポート失敗</string>
<string name="exportSuccessfulTitle">エクスポートしました</string>
<string name="sameAsCardId">カードの表記と同一</string>
<string name="barcodeId">バーコード番号</string>
<string name="importVoucherVaultMessage">インポートするには <i>vouchervault.json</i> のような名前のファイルを選択してください。
\nまたは、あらかじめVoucher Vault でファイルを作成してください。</string>
<string name="importVoucherVault">Voucher Vault からインポート</string>
<string name="importFailed">カードをインポートできません</string>
<string name="importFailedTitle">インポート失敗</string>
<string name="importSuccessfulTitle">インポートしました</string>
<string name="importExportHelp">カードをバックアップすると、カードを他のデバイスに移すことができます。</string>
<string name="exportName">エクスポート</string>
<string name="importExport">インポート/エクスポート</string>
<string name="failedParsingImportUriError">インポートURIを解析できません</string>
<string name="noCardExistsError">カードが見つかりません</string>
<string name="noCardIdError">カード番号が入力されていません</string>
<string name="noStoreError">名前が入力されていません</string>
<string name="barcodeImageDescription">バーコードの画像</string>
<string name="noCardsMessage">カードを追加</string>
<string name="cardShortcut">カードのショートカット</string>
<string name="scanCardBarcode">カードのバーコードをスキャン</string>
<string name="addCardTitle">カードの追加</string>
<string name="editCardTitle">カードの編集</string>
<string name="sendLabel">送信先を選択…</string>
<string name="share">共有</string>
<string name="copy_to_clipboard">カード番号をクリップボードにコピー</string>
<string name="ok">はい</string>
<string name="deleteConfirmation">選択したカードを削除しますか?</string>
<string name="deleteTitle">カードを削除</string>
<string name="unlockScreen">自動回転を無効にしない</string>
<string name="lockScreen">自動回転を無効にする</string>
<string name="confirm">確認</string>
<string name="delete">削除</string>
<string name="edit">編集</string>
<string name="save">保存</string>
<string name="cancel">取り消し</string>
<string name="unstar">お気に入りから削除</string>
<string name="star">お気に入りに追加</string>
<string name="noBarcode">バーコードなし</string>
<string name="barcodeNoBarcode">バーコード指定なし</string>
<string name="barcodeType">形式</string>
<string name="cardId">カード番号</string>
<string name="note">メモ</string>
<string name="storeName">名前</string>
<string name="noMatchingGiftCards">該当なし</string>
<string name="noGiftCards">まず初めに+ボタンを押してカードを追加するか、メニューから以前のカードをインポートしてください。</string>
<string name="action_add">追加</string>
<string name="action_search">検索</string>
<string name="intent_import_card_from_url_share_multiple_text">あなたとカードを共有したいです</string>
<string name="copy_to_clipboard_multiple_toast">カード番号をクリップボードにコピーしました</string>
<string name="card_ids_copied">コピーしたカード</string>
<string name="card_selected">"選択: "</string>
</resources>

View File

@@ -15,8 +15,6 @@
<string name="settings_category_title_ui">사용자 인터페이스</string>
<string name="settings">설정</string>
<string name="enterBarcodeInstructions">카드 ID를 입력하고 카드에서 사용하는 바코드 이미지를 선택하세요. 바코드를 사용하지 않는 경우 “이 카드는 바코드가 없음”을 선택하세요.</string>
<string name="app_resources"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> 앱은 다음 서드 파티 리소스를 사용합니다: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g> 앱은 다음 서드 파티 라이브러리를 사용합니다: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_libraries_list">%s</xliff:g></string>
<string name="app_revision_fmt">리비전 정보: &lt;xliff:g xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\" id=\"app_revision_url\"&gt;%s&lt;/xliff:g&gt;</string>
<string name="selectBarcodeTitle">바코드 선택</string>
<string name="about">정보</string>

View File

@@ -35,7 +35,6 @@
<string name="about_title_fmt">Apie <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Versija: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Revizijos informacija: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> naudoja šias trečiosios šalies bibliotekas: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="selectBarcodeTitle">Pasirinkite brūkšninį kodą</string>
<string name="copy_to_clipboard_toast">Kortelės ID nukopijuota į iškarpinę</string>

View File

@@ -1,9 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
<string name="action_add">Legg til</string>
<string name="noGiftCards">Klikk på \"+\" (pluss)-knappen for å legge til et kort først.
\n
\nDa har du dem alltid hendig.</string>
<string name="noGiftCards">Klikk på «+» (pluss)-knappen for å legge til eller importere kort fra ⋮-menyen først-.</string>
<string name="storeName">Butikk</string>
<string name="note">Merknad</string>
<string name="cardId">Kort-ID</string>
@@ -16,7 +14,7 @@
<string name="lockScreen">Ingen rotering</string>
<string name="unlockScreen">Skru på rotering</string>
<string name="deleteTitle">Fjern kundekort</string>
<string name="deleteConfirmation">Bekreft at du ønsker å slette dette kortet.</string>
<string name="deleteConfirmation">Slett dette kortet\?</string>
<string name="ok">OK</string>
<string name="copy_to_clipboard">Kopier ID til utklippstavle</string>
<string name="sendLabel">Send…</string>
@@ -50,11 +48,9 @@
<string name="importOptionApplicationButton">Bruk eksternt program</string>
<string name="about">Om</string>
<string name="app_license">Gemenhetslig fri programvare, lisensiert GPLv3+.</string>
<string name="about_title_fmt">Om <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Versjon: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="version">%s</xliff:g></string>
<string name="about_title_fmt">Om <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Versjon: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Utgivelsesinfo: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> bruker følgende tredjepartsbibliotek: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> bruker følgende tredjepartsressurser: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="selectBarcodeTitle">Velg strekkode</string>
<string name="enterBarcodeInstructions">Skriv inn strekkodeverdien og velg så bildet som representerer strekkoden du ønsker å bruke.</string>
<string name="copy_to_clipboard_toast">Kort-ID kopiert til utklippstavle</string>
@@ -70,7 +66,8 @@
<string name="settings_light_theme">Lys</string>
<string name="settings_system_theme">System</string>
<string name="settings_theme">Drakt</string>
<string name="app_copyright_old">Basert på Kundekortknippe, opphavsrett 20162020 Branden Archer.</string>
<string name="app_copyright_old">Basert på Kundekortknippe
\nopphavsrett 20162020 Branden Archer.</string>
<string name="failedParsingImportUriError">Kunne ikke tolke importerings-URI</string>
<string name="share">Del</string>
<string name="barcodeNoBarcode">Dette kortet har ingen strekkode</string>
@@ -79,10 +76,8 @@
<string name="starImage">Favorittstjerne</string>
<string name="unstar">Fjern fra favoritter</string>
<string name="star">Legg til i favoritter</string>
<string name="noGroups">Klikk på «+»-tegnet for å legge til grupper først.
\n
\nGrupper gjør ting enklere å finne.</string>
<string name="deleteConfirmationGroup">Bekreft at du ønsker å slette denne gruppen</string>
<string name="noGroups">Klikk på «+»- (pluss)-tegnet for å legge til grupper for kategorisering først.</string>
<string name="deleteConfirmationGroup">Slett gruppe\?</string>
<string name="all">Alle</string>
<string name="groups">Grupper</string>
<string name="enter_group_name">Skriv inn gruppenavn</string>
@@ -94,26 +89,26 @@
<string name="moveDown">Flytt nedover i listen</string>
<string name="moveUp">Flytt oppover i listen</string>
<plurals name="groupCardCount">
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> kort</item>
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> kort</item>
<item quantity="one"><xliff:g>%d</xliff:g> kort</item>
<item quantity="other"><xliff:g>%d</xliff:g> kort</item>
</plurals>
<string name="groupsList">Grupper: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="groupsList">Grupper: <xliff:g>%s</xliff:g></string>
<string name="editBarcode">Rediger strekkode</string>
<string name="barcode">Strekkode</string>
<string name="card">Kort</string>
<string name="expiryStateSentence">Utløper: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentence">Utløper: <xliff:g>%s</xliff:g></string>
<string name="chooseExpiryDate">Velg utløpsdato</string>
<string name="never">Aldri</string>
<string name="expiryDate">Utløpsdato</string>
<string name="expiryStateSentenceExpired">Utløpt: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Utløpt: <xliff:g>%s</xliff:g></string>
<string name="moveBarcodeToCenterOfScreen">Sentrer strekkoden på skjermen</string>
<string name="moveBarcodeToTopOfScreen">Flytt strekkoden til toppen av skjermen</string>
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> ser ikke ut til å være en gyldig saldo.</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> ser ikke ut til å være en gyldig saldo.</string>
<string name="points">Poeng</string>
<string name="currency">Valuta</string>
<string name="balance">Saldo</string>
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> poeng</string>
<string name="balanceSentence">Saldo: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="balancePoints"><xliff:g>%s</xliff:g> poeng</string>
<string name="balanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
<string name="chooseImportType">Importer data fra\?</string>
<string name="app_loyalty_card_keychain">Kundekortsknippe</string>
<string name="settings_disable_lockscreen_while_viewing_card">Skru av låseskjerm under kortvisning</string>
@@ -132,22 +127,23 @@
<string name="setBarcodeId">Sett strekkodeverdi</string>
<string name="sameAsCardId">Samme som kort-ID</string>
<string name="barcodeId">Strekkodeverdi</string>
<string name="importVoucherVaultMessage">Velg din Voucher Vault-eksportfil. Antagelig vouchervault.json.
\n
\nEn Voucher Vault-eksportfil kan opprettes ved å trykke «Eksporter».</string>
<string name="importVoucherVaultMessage">Finn en fil som antagelig heter <i>voucher.vault.json</i> å importere.
\nEller opprett den ved å trykke «Eksport» i Voucher Vault først.</string>
<string name="importVoucherVault">Importer fra Voucher Vault</string>
<string name="importLoyaltyCardKeychainMessage">Velg din Kundekortknippe-eksportfil. Antagelig LoyaltyCardKeychain.csv.
\n
\nDen kan opprettes ved å gå til import/eksport-menyen der og trykke «Eksporter».</string>
<string name="importLoyaltyCardKeychainMessage">Finn en fil som antagelig heter <i>LoyaltyCardKeychain.csv</i> å importere.
\nEller opprett den i Import/eksport-menyen i Kundekortknippe ved å trykke «Eksporter» der først.</string>
<string name="importLoyaltyCardKeychain">Importer fra Kundekortknippe</string>
<string name="importFidmeMessage">Velg din FidMe-eksportfil. Antagelig fidme-export-request-xxxxxx.zip.
\n
\nDen kan opprettes i FidMe-programmet ved å gå til profilen din der, velge \"Databeskyttelse\", og så trykke «Pakk ut dataen min».
\n
\nMerk deg at FidMe ikke lagrer strekkodetypen i eksportdata, så du må redigere importerte kort manuelt.</string>
<string name="importCatimaMessage">Velg din Catima-eksportfil. Antagelig Catima.csv.
\n
\nDen kan eksporteres ved å gå til import/eksport-menyen og trykke «Eksporter».</string>
<string name="importFidmeMessage">Finn en fil som antagelig heter <i>fidme.export-request-xxxxx.zip</i> å importere, for så å så velge strekkodetypene manuelt etterpå-
\nEller opprett den i din FidMe-profil ved å velge «Databeskyttelse», for så å trykke «Pakk ut dataen min» først.</string>
<string name="importCatimaMessage">Finn en fil som antagelig heter <i>Catima.csv</i> å importere.
\nEller opprett den i Import/eksport-menyen i et annet Catima-program ved å trykke «Eksporter» der først.</string>
<string name="settings_max_font_size_scale">Maksimal skriftstørrelse</string>
<string name="wrongValueForBarcodeType">Verdien er ikke gyldig for valgt strekkodetype</string>
<string name="intent_import_card_from_url_share_multiple_text">Jeg ønsker å dele noen kort med deg</string>
<string name="copy_to_clipboard_multiple_toast">Kopierte kort-ID til utklippstavle</string>
<string name="app_resources">Frie tredjepartsressurser: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries">Frie tredjepartsbibliotek: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="card_selected">"Valgt: "</string>
<string name="card_ids_copied">Kopierte kort-ID(er)</string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Opphavsrett © 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
</resources>

View File

@@ -11,6 +11,8 @@
<color name="colorPrimaryText">#000000</color>
<color name="colorSecondaryText">#ffffff</color>
<color name="listItemHighlight">#88000000</color>
<color name="inputContrastBackground">#070707</color>
<color name="inputBackground">#000000</color>
<color name="inputBorder">#222222</color>

View File

@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
<string name="action_search">Zoeken</string>
<string name="action_add">Toevoegen</string>
<string name="noGiftCards">Druk op de knop \'+\' (plus) om een kaart toe te voegen.
\n
\nMet Catima heb je je klantenkaarten altijd binnen handbereik, gewoon op je apparaat.</string>
<string name="noMatchingGiftCards">Geen zoekresultaten. Probeer een andere zoekopdracht.</string>
<string name="storeName">Winkel</string>
<string name="noGiftCards">Druk op de plusknop (+) om een kaart toe te voegen of importeer kaarten via het ⋮-menu.</string>
<string name="noMatchingGiftCards">Geen zoekresultaten - probeer een andere zoekopdracht.</string>
<string name="storeName">Naam</string>
<string name="note">Aantekening</string>
<string name="cardId">Kaartnummer</string>
<string name="barcodeType">Soort barcode</string>
@@ -19,7 +17,7 @@
<string name="lockScreen">Draaien niet toestaan</string>
<string name="unlockScreen">Draaien toestaan</string>
<string name="deleteTitle">Kaart verwijderen</string>
<string name="deleteConfirmation">Bevestig dat je deze kaart wilt verwijderen.</string>
<string name="deleteConfirmation">Kaart verwijderen\?</string>
<string name="ok">Oké</string>
<string name="copy_to_clipboard">Kaartnummer kopiëren naar klembord</string>
<string name="share">Delen</string>
@@ -30,7 +28,7 @@
<string name="cardShortcut">Kaartsnelkoppeling</string>
<string name="noCardsMessage">Voeg eerst een kaart toe</string>
<string name="barcodeImageDescription">Afbeelding van barcode</string>
<string name="noStoreError">Geen winkelnaam ingevoerd</string>
<string name="noStoreError">Geen naam ingevoerd</string>
<string name="noCardIdError">Geen kaartnummer ingevoerd</string>
<string name="noCardExistsError">De kaart is niet aangetroffen</string>
<string name="failedParsingImportUriError">Kan de import-uri niet verwerken</string>
@@ -45,24 +43,22 @@
<string name="exportFailed">Het exporteren is mislukt</string>
<string name="importing">Bezig met importeren…</string>
<string name="exporting">Bezig met exporteren…</string>
<string name="noExternalStoragePermissionError">Verleen het recht \'externe opslag\' om kaarten te kunnen im- of exporteren</string>
<string name="noExternalStoragePermissionError">Verleen het recht externe opslag om kaarten te kunnen im- of exporteren</string>
<string name="exportOptionExplanation">De gegevens worden weggeschreven op een locatie naar keuze.</string>
<string name="importOptionFilesystemTitle">Importeren uit bestandssysteem</string>
<string name="importOptionFilesystemExplanation">Kies een specifiek bestand vanop het bestandssysteem.</string>
<string name="importOptionFilesystemButton">Van bestandssysteem</string>
<string name="importOptionApplicationTitle">Externe app gebruiken</string>
<string name="importOptionApplicationTitle">Andere app gebruiken</string>
<string name="importOptionApplicationExplanation">Open een bestand middels een app of je favoriete bestandsbeheerder.</string>
<string name="importOptionApplicationButton">Externe app gebruiken</string>
<string name="importOptionApplicationButton">Andere app gebruiken</string>
<string name="about">Over</string>
<string name="app_license">Vrije software, uitgebracht onder de GPLv3-licentie.</string>
<string name="about_title_fmt">Over <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Versie: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Versie-informatie: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> gebruikt de volgende bibliotheken van externe partijen: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> gebruikt de volgende bronnen van externe partijen: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="selectBarcodeTitle">Barcode toevoegen</string>
<string name="enterBarcodeInstructions">Voer de barcode in en kies daarna de afbeelding van de barcode die je wilt gebruiken of druk op “Deze kaart heeft geen barcode” om geen barcode te gebruiken.</string>
<string name="copy_to_clipboard_toast">Kaartnummer is gekopieerd naar het klembord</string>
<string name="enterBarcodeInstructions">Voer de kaart-id in en kies daarna het soort barcode druk op “Deze kaart heeft geen barcode”.</string>
<string name="copy_to_clipboard_toast">De kaart-id is gekopieerd naar het klembord</string>
<string name="thumbnailDescription">Miniatuurvoorbeeld van kaart</string>
<string name="settings">Instellingen</string>
<string name="settings_category_title_ui">Vormgeving</string>
@@ -75,15 +71,14 @@
<string name="intent_import_card_from_url_share_text">Ik wil een klantenkaart met je delen</string>
<string name="all">Alles</string>
<string name="importSuccessful">De kaartgegevens zijn geïmporteerd</string>
<string name="deleteConfirmationGroup">Bevestig dat je deze groep wilt verwijderen</string>
<string name="noGroups">Druk op de knop \'+\' (plus) om een groep toe te voegen.
\n
\nDoor kaarten te groeperen vind je ze makkelijker terug.</string>
<string name="deleteConfirmationGroup">Groep verwijderen\?</string>
<string name="noGroups">Druk op de plusknop (+) om een groep toe te voegen.</string>
<string name="exportSuccessful">De kaartgegevens zijn geëxporteerd</string>
<string name="groups">Groepen</string>
<string name="enter_group_name">Voer een groepsnaam in</string>
<string name="starImage">Favoriete ster</string>
<string name="app_copyright_old">Gebaseerd op Loyalty Card Keychain, copyright 20162020 Branden Archer.</string>
<string name="app_copyright_old">Gebaseerd op Loyalty Card Keychain,
\ncopyright ©20162020 Branden Archer.</string>
<string name="unstar">Verwijderen uit favorieten</string>
<string name="star">Toevoegen aan favorieten</string>
<string name="addManually">Kaartnummer handmatig invoeren</string>
@@ -94,51 +89,45 @@
<string name="failedOpeningFileManager">Installeer een bestandsbeheerder.</string>
<string name="noBarcode">Geen barcode</string>
<plurals name="groupCardCount">
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> kaart</item>
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> kaarten</item>
<item quantity="one"><xliff:g>%d</xliff:g> kaart</item>
<item quantity="other"><xliff:g>%d</xliff:g> kaarten</item>
</plurals>
<string name="groupsList">Groepen: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="groupsList">Groepen: <xliff:g>%s</xliff:g></string>
<string name="editBarcode">Barcode aanpassen</string>
<string name="barcode">Barcode</string>
<string name="card">Kaart</string>
<string name="chooseExpiryDate">Kies een vervaldatum</string>
<string name="never">Nooit</string>
<string name="expiryDate">Vervaldatum</string>
<string name="expiryStateSentence">Vervalt op <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Verlopen: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentence">Vervalt op <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Verlopen: <xliff:g>%s</xliff:g></string>
<string name="moveBarcodeToCenterOfScreen">Barcode verplaatsen naar midden van scherm</string>
<string name="moveBarcodeToTopOfScreen">Barcode verplaatsen naar bovenkant van scherm</string>
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> lijkt geen geldig saldo te zijn.</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> lijkt geen geldig saldo te zijn.</string>
<string name="points">Aantal punten</string>
<string name="currency">Valuta</string>
<string name="balance">Saldo</string>
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> punten</string>
<string name="balanceSentence">Saldo: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="balancePoints"><xliff:g>%s</xliff:g> punten</string>
<string name="balanceSentence">Saldo: <xliff:g>%s</xliff:g></string>
<string name="chooseImportType">Gegevens importeren uit…\?</string>
<string name="app_loyalty_card_keychain">Klantenkaartkluis</string>
<string name="settings_disable_lockscreen_while_viewing_card">Vergrendelscherm uitschakelen tijdens tonen van kaart</string>
<string name="settings_keep_screen_on">Scherm niet uitschakelen tijdens tonen van kaart</string>
<string name="settings_disable_lockscreen_while_viewing_card">Vergrendelscherm uitschakelen</string>
<string name="settings_keep_screen_on">Scherm niet uitschakelen</string>
<string name="privacy_policy_popup_text">Privacybeleid (vereist door sommige appwinkels):
\n
\nWe verzamelen HELEMAAL NIKS. Bovendien is onze app open source, zodat een ieder met eigen ogen kan zien wat de app wel of niet doet.</string>
\nER WORDEN GEEN GEGEVENS VERZAMELD. Bovendien is onze app open source, zodat een ieder met eigen ogen kan zien wat de app wel of niet doet.</string>
<string name="privacy_policy">Privacybeleid</string>
<string name="accept">Accepteren</string>
<string name="importVoucherVaultMessage">Kies het gewenste Voucher Vault-exportbestand - normaliter heet dit bestand \'vouchervault.json\'.
\n
\nGa naar het Exportmenu om een Voucher Vault-exportbestand samen te stellen.</string>
<string name="importVoucherVaultMessage">Kies het te importeren Voucher Vault-exportbestand genaamd <i>vouchervault.json</i>.
\nOf ga naar het exportmenu van Voucher Vault om exportbestand samen te stellen.</string>
<string name="importVoucherVault">Importeren uit Voucher Vault</string>
<string name="importLoyaltyCardKeychainMessage">Kies het gewenste Klantenkaartkluis-exportbestand - normaliter heet dit bestand \'LoyaltyCardKeychain.csv\'.
\n
\nGa naar het Import-/Exportmenu om een Klantenkaartkluis-exportbestand samen te stellen.</string>
<string name="importLoyaltyCardKeychainMessage">Kies het te importeren Klantenkaartkluis-exportbestand - genaamd <i>LoyaltyCardKeychain.csv</i>.
\nOf ga naar het import-/exportmenu van Klantenkaartkluis om een exportbestand samen te stellen.</string>
<string name="importLoyaltyCardKeychain">Importeren uit Klantenkaartkluis</string>
<string name="importFidmeMessage">Kies het gewenste FidMe-exportbestand - normaliter heet dit bestand \'fidme-export-request-xxxxxx.zip\'.
\n
\nOpen de FidMe-app, ga naar je profiel en druk op \'Gegevensbescherming\' om een exportbestand samen te stellen.
\n
\nLet op: FidMe slaat de soorten barcodes niet op in het exportbestand, dus dat moet je achteraf nog instellen.</string>
<string name="importCatimaMessage">Kies het gewenste Catima-exportbestand - normaliter heet dit bestand \'Catima.csv\'.
\n
\nGa naar het Import-/Exportmenu om een Catima-exportbestand samen te stellen.</string>
<string name="importFidmeMessage">Kies het te importeren FidMe-exportbestand genaamd <i>fidme-export-request-xxxxxx.zip</i>.
\nOf ga naar je FidMe-profiel en druk op Gegevensbescherming om een exportbestand samen te stellen.</string>
<string name="importCatimaMessage">Kies het te importeren exportbestand genaamd <i>Catima.csv</i>.
\nOf ga naar het import-/exportmenu van Catima op een ander apparaat om een exportbestand samen te stellen.</string>
<string name="importFidme">Importeren uit FidMe</string>
<string name="importCatima">Importeren uit Catima</string>
<string name="errorReadingImage">De afbeelding kan niet worden uitgelezen</string>
@@ -147,7 +136,18 @@
<string name="setBarcodeId">Barcodewaarde instellen</string>
<string name="sameAsCardId">Gelijk aan kaart-id</string>
<string name="barcodeId">Barcodewaarde</string>
<string name="settings_max_font_size_scale">Maximale tekstgrootte</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">Externe vrije bronnen: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries">Externe vrije bibliotheken: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Auteursrecht © 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
<string name="intent_import_card_from_url_share_multiple_text">Ik wil kaarten met je delen</string>
<string name="copy_to_clipboard_multiple_toast">De kaart-id\'s zijn gekopieerd naar het klembord</string>
<string name="card_ids_copied">De kaart-ids zijn gekopieerd</string>
<string name="card_selected">"Geselecteerd: "</string>
<string name="no">Nee</string>
<string name="yes">Ja</string>
<string name="updateBarcodeQuestionText">Je hebt de kaart-id aangepast. Wil je dezelfde waarde toekennen aan de barcode\?</string>
<string name="updateBarcodeQuestionTitle">Barcodewaarde bijwerken\?</string>
</resources>

View File

@@ -54,8 +54,6 @@
<string name="about_title_fmt">O <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Wersja: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Info o wydaniu: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> wykorzystuje następujące biblioteki osób trzecich: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> wykorzystuje następujące zasoby osób trzecich: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="selectBarcodeTitle">Wybierz kod kreskowy</string>
<string name="enterBarcodeInstructions">Wprowadź identyfikator karty, a następnie wybierz obraz reprezentujący kod kreskowy, którego chcesz użyć, lub wybierz „Ta karta nie ma kodu kreskowego”, aby nie używać kodu kreskowego.</string>
<string name="copy_to_clipboard_toast">Skopiowano identyfikator karty do schowka</string>

View File

@@ -1,12 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
<string name="action_search">Поиск</string>
<string name="action_add">Добавить</string>
<string name="noGiftCards">Нажмите кнопку + (плюс), чтобы добавить карту.
\n
\nCatima хранит ваши карты на устройстве, поэтому они всегда под рукой.</string>
<string name="noGiftCards">Нажмите кнопку \"+\" для добавления карты или используйте меню \"⋮\" для импортирования.</string>
<string name="noMatchingGiftCards">Ничего не найдено. Попробуйте изменить поисковый запрос.</string>
<string name="storeName">Магазин</string>
<string name="storeName">Название</string>
<string name="note">Примечание</string>
<string name="cardId">Номер карты</string>
<string name="barcodeType">Тип штрих-кода</string>
@@ -19,7 +17,7 @@
<string name="lockScreen">Блокировать поворот экрана</string>
<string name="unlockScreen">Автоповорот экрана</string>
<string name="deleteTitle">Удаление карты</string>
<string name="deleteConfirmation">Подтвердите удаление карты.</string>
<string name="deleteConfirmation">Удалить карту\?</string>
<string name="ok">ОК</string>
<string name="copy_to_clipboard">Копировать номер карты</string>
<string name="share">Переслать</string>
@@ -30,7 +28,7 @@
<string name="cardShortcut">Ярлык карты</string>
<string name="noCardsMessage">Сначала добавьте карту</string>
<string name="barcodeImageDescription">Изображение штрих-кода карты</string>
<string name="noStoreError">Название магазина не указано</string>
<string name="noStoreError">Название не указано</string>
<string name="noCardIdError">Номер карты не указан</string>
<string name="noCardExistsError">Карта не найдена</string>
<string name="failedParsingImportUriError">Невозможно разобрать импортируемый URI</string>
@@ -55,13 +53,11 @@
<string name="importOptionApplicationButton">Использовать другое приложение</string>
<string name="about">О приложении</string>
<string name="app_license">Авторское лево свободного программного обеспечения, лицензия GPLv3+.</string>
<string name="about_title_fmt">О приложении <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_name">%s</xliff:g></string>
<string name="about_title_fmt">О приложении <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Версия: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Информация о версиях: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> использует следующие сторонние библиотеки: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> использует следующие сторонние ресурсы: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_revision_fmt">Информация о версиях: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="selectBarcodeTitle">Выбор штрих-кода</string>
<string name="enterBarcodeInstructions">Введите номер карты и выберите тип штрих-кода. Или выберите \"Эта карта без штрих-кода\", чтобы не использовать его.</string>
<string name="enterBarcodeInstructions">Введите номер карты и выберите тип штрих-кода. Или выберите \"Эта карта без штрих-кода\".</string>
<string name="copy_to_clipboard_toast">Номер карты скопирован в буфер обмена</string>
<string name="thumbnailDescription">Логотип карты</string>
<string name="settings">Настройки</string>
@@ -72,34 +68,33 @@
<string name="settings_dark_theme">Тёмная</string>
<string name="settings_display_barcode_max_brightness">Максимальная яркость при показе карты</string>
<string name="settings_lock_barcode_orientation">Портретная ориентация экрана при показе карты</string>
<string name="intent_import_card_from_url_share_text">Я хочу поделиться картой с вами</string>
<string name="intent_import_card_from_url_share_text">Я хочу поделиться с вами картой</string>
<string name="exportSuccessful">Данные карт успешно экспортированы</string>
<string name="all">Все</string>
<string name="noGroups">Нажмите кнопку + (плюс), чтобы добавить группы.
\n
\nГруппы упрощают поиск.</string>
<string name="noGroups">Нажмите кнопку \"+\", чтобы добавить группы для упорядочивания записей.</string>
<string name="groups">Группы</string>
<string name="enter_group_name">Введите название группы</string>
<string name="importSuccessful">Данные карт успешно импортированы</string>
<string name="starImage">Звезда избранного</string>
<string name="app_copyright_old">На основе Loyalty Card Keychain, авторские права 20162020 Branden Archer.</string>
<string name="app_copyright_old">На основе Loyalty Card Keychain
\nавторские права © 20162020 Branden Archer.</string>
<string name="unstar">Удалить из избранного</string>
<string name="star">Добавить в избранное</string>
<string name="noBarcode">Нет штрих-кода</string>
<string name="deleteConfirmationGroup">Подтвердите, что хотите удалить эту группу</string>
<string name="deleteConfirmationGroup">Удалить группу\?</string>
<string name="leaveWithoutSaveConfirmation">Выйти без сохранения\?</string>
<string name="leaveWithoutSaveTitle">Выход</string>
<string name="failedOpeningFileManager">Требуется файловый менеджер.</string>
<string name="balancePoints"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> баллов</string>
<string name="balanceSentence">Баланс: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Истёк срок действия: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="expiryStateSentence">Истекает срок действия: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="balancePoints"><xliff:g>%s</xliff:g> баллов</string>
<string name="balanceSentence">Баланс: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentenceExpired">Срок действия истёк: <xliff:g>%s</xliff:g></string>
<string name="expiryStateSentence">Срок действия истекает: <xliff:g>%s</xliff:g></string>
<string name="points">Баллы</string>
<string name="parsingBalanceFailed"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g> не похож на правильный баланс.</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g> не похож на правильный баланс.</string>
<string name="addManually">Ручной ввод номера карты</string>
<string name="privacy_policy_popup_text">Уведомление о политике конфиденциальности (требуется некоторыми магазинами приложений):
\n
\nМы ВООБЩЕ НЕ собираем НИКАКИХ ДАННЫХ, что может подтвердить любой, так как наше приложение является свободным программным обеспечением.</string>
\nНИКАКИЕ ДАННЫЕ НЕ СОБИРАЮТСЯ ВООБЩЕ, что может подтвердить любой, так как наше приложение является свободным программным обеспечением.</string>
<string name="privacy_policy">Политика конфиденциальности</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="chooseImportType">Откуда импортировать данные\?</string>
@@ -113,34 +108,28 @@
<string name="editBarcode">Изменить штрих-код</string>
<string name="barcode">Штрих-код</string>
<string name="card">Карта</string>
<string name="groupsList">Группы: <xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%s</xliff:g></string>
<string name="moveDown">Переместить ниже в вписке</string>
<string name="moveUp">Переместить выше в вписке</string>
<string name="settings_disable_lockscreen_while_viewing_card">Не блокировать экран при показе карты</string>
<string name="settings_keep_screen_on">Не отключать экран при показе карты</string>
<string name="groupsList">Группы: <xliff:g>%s</xliff:g></string>
<string name="moveDown">Переместить ниже</string>
<string name="moveUp">Переместить выше</string>
<string name="settings_disable_lockscreen_while_viewing_card">Не давать блокировать экран</string>
<string name="settings_keep_screen_on">Не отключать экран</string>
<plurals name="groupCardCount">
<item quantity="one"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> карта</item>
<item quantity="few"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> карты</item>
<item quantity="many"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> карт</item>
<item quantity="other"><xliff:g xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">%d</xliff:g> карт</item>
<item quantity="one"><xliff:g>%d</xliff:g> карта</item>
<item quantity="few"><xliff:g>%d</xliff:g> карты</item>
<item quantity="many"><xliff:g>%d</xliff:g> карт</item>
<item quantity="other"><xliff:g>%d</xliff:g> карт</item>
</plurals>
<string name="accept">Принять</string>
<string name="importVoucherVaultMessage">Выберите файл экспорта Voucher Vault. Обычно он называется \"vouchervault.json\".
\n
\nФайл экспорта Voucher Vault можно создать, нажав кнопку \"Экспорт\".</string>
<string name="importVoucherVaultMessage">Выберите файл для импортирования, обычно именуемый <i>vouchervault.json</i>.
\nФайл экспорта можно создать в приложении Voucher Vault, нажав кнопку \"Экспорт\".</string>
<string name="importVoucherVault">Импорт из Voucher Vault</string>
<string name="importFidmeMessage">Выберите файл экспорта FidMe. Обычно он называется как-то вроде \"fidme-export-request-xxxxxx.zip\".
\n
\nФайл экспорта FidMe можно создать в приложении FidMe, перейдя в свой профиль, выбрав функцию \"Защита данных\", и затем нажав кнопку \"Извлечь мои данные\".
\n
\nОбратите внимание, что FidMe не сохраняет тип штрих-кода в экспортированных данных, поэтому вам придётся редактировать импортированные данные карт вручную.</string>
<string name="importLoyaltyCardKeychainMessage">Выберите файл экспорта Loyalty Card Keychain. Обычно он называется \"LoyaltyCardKeychain.csv\".
\n
\nФайл экспорта Loyalty Card Keychain можно создать, перейдя в меню \"Импорт/Экспорт\" и нажав кнопку \"Экспорт\".</string>
<string name="importFidmeMessage">Выберите файл для импортирования, обычно именуемый <i>fidme-export-request-xxxxxx.zip</i>, а затем вручную выберите типы штрих-кодов.
\nФайл экспорта можно создать в приложении FidMe, перейдя в свой профиль, выбрав функцию \"Защита данных\", и затем нажав кнопку \"Извлечь мои данные\".</string>
<string name="importLoyaltyCardKeychainMessage">Выберите файл экспорта, обычно именуемый <i>LoyaltyCardKeychain.csv</i>.
\nФайл экспорта можно создать в приложении Loyalty Card Keychain, перейдя в меню \"Импорт/Экспорт\" и нажав кнопку \"Экспорт\".</string>
<string name="importLoyaltyCardKeychain">Импорт из Loyalty Card Keychain</string>
<string name="importCatimaMessage">Выберите файл экспорта Catima. Обычно он называется \"Catima.csv\".
\n
\nФайл экспорта Catima можно создать, перейдя в меню \"Импорт/Экспорт\" и нажав кнопку \"Экспорт\".</string>
<string name="importCatimaMessage">Выберите файл для импортирования, обычно именуемый <i>Catima.csv</i>.
\nФайл экспорта можно создать в другой копии Catima, перейдя в меню \"Импорт/Экспорт\" и нажав кнопку \"Экспорт\".</string>
<string name="importFidme">Импорт из FidMe</string>
<string name="importCatima">Импорт из Catima</string>
<string name="errorReadingImage">Невозможно считать изображение</string>
@@ -152,4 +141,15 @@
<string name="settings_max_font_size_scale">Максимальный размер шрифта</string>
<string name="unsupportedBarcodeType">В настоящее время данный тип штрих-кодов не отображается. Его поддержка может быть добавлена в следующих версиях приложения.</string>
<string name="wrongValueForBarcodeType">Недопустимое значение для выбранного типа штрих-кода</string>
<string name="app_resources">Сторонние свободные ресурсы: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries">Сторонние свободные библиотеки: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Авторские права © 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
<string name="intent_import_card_from_url_share_multiple_text">Поделиться картами</string>
<string name="card_ids_copied">Скопированные номера карт</string>
<string name="copy_to_clipboard_multiple_toast">Номера карт скопированы в буфер обмена</string>
<string name="card_selected">"Выбрано: "</string>
<string name="updateBarcodeQuestionText">Вы изменили номер карты. Обновить также значение штрих-кода, чтобы использовалось одинаковое значение\?</string>
<string name="no">Нет</string>
<string name="yes">Да</string>
<string name="updateBarcodeQuestionTitle">Обновить значение штрих-кода\?</string>
</resources>

View File

@@ -54,8 +54,6 @@
<string name="about_title_fmt">O <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Verzia: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Informácia pri revízii: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> používa nasledujúce knižnice tretej strany: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> používa tieto knižnice tretích strán: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="selectBarcodeTitle">Vyberte čiarový kód</string>
<string name="copy_to_clipboard_toast">ID karty skopírované do schránky</string>

View File

@@ -1,8 +1,6 @@
<resources
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="action_add">Dodaj</string>
<string name="noGiftCards">Trenutno nimate shranjene nobene kartice zvestobe. Kliknite \"+\" (plus) na vrhu, da jih dodate.\n\n Aplikacija Kartice zvestobe Vam omogoča, da imate kartice zvestobe shranjene na Vašem telefonu in vedno v dosegu roke.</string>
<string name="storeName">Shrani</string>
<string name="note">Zabeležka</string>
@@ -18,15 +16,13 @@
<string name="deleteConfirmation">Prosim potrdite, če želite izbrisati to kartico.</string>
<string name="ok">Vredu</string>
<string name="copy_to_clipboard">Kopirajte številko kartice</string>
<string name="sendLabel">Pošlji#8230;</string>
<string name="sendLabel">Pošlji</string>
<string name="editCardTitle">Uredi kartico zvestobe</string>
<string name="addCardTitle">Dodaj kartico zvestobe</string>
<string name="scanCardBarcode">Skeniraj črtno kodo</string>
<string name="cardShortcut">Bližnjica do kartice</string>
<string name="noCardsMessage">Trenutno ni na voljo nobene kartice. Najprej jih je potrebno dodati.</string>
<string name="barcodeImageDescription">Slika črtne kode na kartici</string>
<string name="noStoreError">Ime trgovine ni bilo vnešeno</string>
<string name="noCardIdError">Številka kartice ni bila vnešena</string>
<string name="noCardExistsError">Te kartice zvestobe ni bilo moč najti</string>
@@ -39,8 +35,8 @@
<string name="exportSuccessfulTitle">Izvoz je uspel</string>
<string name="exportFailedTitle">Izvoz ni uspel</string>
<string name="exportFailed">Napaka pri izvozu</string>
<string name="importing">Uvažanje&#8230;</string>
<string name="exporting">Izvažanje&#8230;</string>
<string name="importing">Uvažanje</string>
<string name="exporting">Izvažanje</string>
<string name="noExternalStoragePermissionError">Izvažanje in uvažanje je nemogoče brez omogočenega dostopa do zunanje shrambe</string>
<string name="importOptionFilesystemTitle">Uvozi iz datotečnega sistema</string>
<string name="importOptionFilesystemExplanation">Izberite specifično datoteko iz datotečnega sistema</string>
@@ -48,22 +44,16 @@
<string name="importOptionApplicationTitle">Uporabi zunanjo aplikacijo</string>
<string name="importOptionApplicationExplanation">Uporabi zunanjo aplikacijo, kot npr. Dropbox, Google Drive ali ostale upravljalnike datotek, za odpiranje datoteko.</string>
<string name="importOptionApplicationButton">Uporabi zunanjo aplikacijo</string>
<string name="about">Več o aplikaciji</string>
<string name="app_license">Licencirano s skladu z GPLv3.</string>
<string name="about_title_fmt">Več o <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Verzija: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Informacije o popravkih: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> uporablja sledeče zunanje knjižnice: <xliff:g id="app_libraries_list">%s</xliff:g> </string>
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g>uporablja sledeče zunanje vire: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="selectBarcodeTitle">Izberite črtno kodo</string>
<string name="copy_to_clipboard_toast">Številka kartice je bila kopirana v odložišče</string>
<string name="thumbnailDescription">Ikona kartice</string>
<string name="settings">Nastavitve</string>
<string name="settings_category_title_ui">Uporabniški vmesnik</string>
<string name="settings_display_barcode_max_brightness">Povečaj osvetljenost prikaza črtne kode</string>
<string name="settings_lock_barcode_orientation">Zakleni orientacijo črtne kode</string>
</resources>
</resources>

View File

@@ -1,8 +1,9 @@
<resources>>
<resources>
<style name="AppTheme.NoActionBar" parent="AppTheme">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
</style>
</resources>

View File

@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" xmlns:tools="http://schemas.android.com/tools">
<string name="app_revision_fmt">更新日志: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="groupsList">组:<xliff:g>%s</xliff:g></string>
<plurals name="groupCardCount">
<item quantity="other"><xliff:g>%d</xliff:g> 卡片</item>
</plurals>
<string name="app_libraries">第三方自由程序库: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="debug_version_fmt">版本: <xliff:g id="version">%s</xliff:g></string>
<string name="about_title_fmt">关于 <xliff:g id="app_name">%s</xliff:g></string>
<string name="barcode">条形码</string>
<string name="card">卡片</string>
<string name="addManually">手动输入卡号</string>
<string name="settings_system_theme">系统设置</string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
<string name="importOptionApplicationButton">使用其他应用</string>
<string name="importOptionFilesystemButton">从文件系统</string>
<string name="barcodeImageDescription">卡片二维码图像</string>
<string name="unstar">从收藏中删除</string>
<string name="intent_import_card_from_url_share_multiple_text">我想和你分享一些卡片</string>
<string name="copy_to_clipboard_multiple_toast">已将卡号复制到剪贴板</string>
<string name="wrongValueForBarcodeType">该值对所选条形码类型无效</string>
<string name="unsupportedBarcodeType">此条形码类型尚无法显示。较新版本的应用程序可能提供支持。</string>
<string name="setBarcodeId">设置条形码值</string>
<string name="sameAsCardId">与卡号相同</string>
<string name="barcodeId">条形码值</string>
<string name="importVoucherVaultMessage">找到一个可能名为<i>vouchervault.json</i>的文件进行导入。
\n或者先在Voucher Vault中按下导出键来创建导出。</string>
<string name="importVoucherVault">从 Voucher Vault 导入</string>
<string name="importLoyaltyCardKeychainMessage">找到一个很可能名为<i>LoyaltyCardKeychain.csv</i>的文件来导入。
\n或者先从Loyalty Card Keychain的Import/Export菜单中选择Export来导出。</string>
<string name="importLoyaltyCardKeychain">从 Loyalty Card Keychain 导入</string>
<string name="importFidmeMessage">找到一个可能名为<i>fidme-export-request-xxxxxx.zip</i>的文件进行导入,之后再手动选择条码类型。
\n或者从你的FidMe配置文件中选择数据保护然后按提取我的数据来创建导出。</string>
<string name="importFidme">从 FidMe 导入</string>
<string name="importCatimaMessage">找到一个可能名为<i>Catima.csv</i>的文件来导入。
\n或者先从另一个Catima应用程序的导入/导出菜单中,来创建导出。</string>
<string name="importCatima">从 Catima 导入</string>
<string name="accept">接受</string>
<string name="privacy_policy_popup_text">隐私政策通知(一些应用程序商店要求)。
\n
\n本应用没有收集任何数据任何人都可以查阅源码来确认因为本软件是自由软件。</string>
<string name="privacy_policy">隐私政策</string>
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="chooseImportType">导入数据?</string>
<string name="parsingBalanceFailed"><xliff:g>%s</xliff:g>似乎不是有效的余额。</string>
<string name="points">积分</string>
<string name="currency">货币</string>
<string name="balance">余额</string>
<string name="errorReadingImage">无法读取图像</string>
<string name="noBarcodeFound">未找到条形码</string>
<string name="moveBarcodeToCenterOfScreen">将条形码居中显示</string>
<string name="moveBarcodeToTopOfScreen">将条形码移到屏幕的顶部</string>
<string name="chooseExpiryDate">选择到期日</string>
<string name="never">从不</string>
<string name="expiryDate">过期时间</string>
<string name="editBarcode">编辑条形码</string>
<string name="balancePoints"><xliff:g>%s</xliff:g></string>
<string name="balanceSentence">余额:<xliff:g>%s</xliff:g></string>
<string name="expiryStateSentenceExpired">过期:<xliff:g>%s</xliff:g></string>
<string name="expiryStateSentence">过期: <xliff:g>%s</xliff:g></string>
<string name="addFromImage">从相册中选择图片</string>
<string name="leaveWithoutSaveConfirmation">不保存就离开吗?</string>
<string name="leaveWithoutSaveTitle">退出</string>
<string name="moveDown">向下移</string>
<string name="moveUp">向上移</string>
<string name="failedOpeningFileManager">请先安装文件管理器。</string>
<string name="deleteConfirmationGroup">删除群组?</string>
<string name="all">全部</string>
<string name="noGroups">点击 \"+\" 按钮,先添加组进行分类。</string>
<string name="enter_group_name">输入组名</string>
<string name="groups"></string>
<string name="exportSuccessful">已导出卡片数据</string>
<string name="importSuccessful">已导入卡片数据</string>
<string name="intent_import_card_from_url_share_text">我想和你分享一张卡</string>
<string name="settings_disable_lockscreen_while_viewing_card">禁用锁屏</string>
<string name="settings_keep_screen_on">保持屏幕常亮</string>
<string name="settings_lock_barcode_orientation">锁定条码方向</string>
<string name="settings_display_barcode_max_brightness">提高条码界面亮度</string>
<string name="settings_max_font_size_scale">最大字体大小</string>
<string name="settings_dark_theme">暗色</string>
<string name="settings_light_theme">浅色</string>
<string name="settings_theme">主题</string>
<string name="settings_category_title_ui">用户界面</string>
<string name="settings">设置</string>
<string name="thumbnailDescription">卡片缩略图</string>
<string name="copy_to_clipboard_toast">已复制卡号到剪贴板</string>
<string name="enterBarcodeInstructions">输入卡号,并从下面选择其条码类型,或选择\"此卡片没有条码\"。</string>
<string name="selectBarcodeTitle">选择条码</string>
<string name="app_resources">第三方自由资源:<xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_license">本软件为自由软件,使用 GPLv3+ 许可.</string>
<string name="app_copyright_old">基于 Loyalty Card Keychain
\ncopyright © 20162020 Branden Archer.</string>
<string name="about">关于</string>
<string name="importOptionApplicationExplanation">使用任何应用程序或您喜欢的文件管理器打开文件。</string>
<string name="importOptionApplicationTitle">使用其他应用</string>
<string name="importOptionFilesystemExplanation">请从文件系统选择文件.</string>
<string name="importOptionFilesystemTitle">从文件系统导入</string>
<string name="exportOptionExplanation">导出的数据将储存至你选择的位置.</string>
<string name="noExternalStoragePermissionError">在导入导出前需要获得外部储存权限</string>
<string name="exporting">导出中…</string>
<string name="importing">导入中…</string>
<string name="exportFailed">无法导出卡片</string>
<string name="exportFailedTitle">导出失败</string>
<string name="exportSuccessfulTitle">导出成功</string>
<string name="importFailed">无法导入卡片</string>
<string name="importFailedTitle">导入失败</string>
<string name="importSuccessfulTitle">导入成功</string>
<string name="importExportHelp">备份卡片后你可以让你将它们转移到其他设备。</string>
<string name="exportName">导出</string>
<string name="importExport">导入/导出</string>
<string name="failedParsingImportUriError">无法解析导入的URI</string>
<string name="noCardExistsError">无法到卡片</string>
<string name="noCardIdError">未输入卡号</string>
<string name="noStoreError">未输入卡片名称</string>
<string name="card_ids_copied">复制卡号</string>
<string name="noCardsMessage">请先添加一张卡片</string>
<string name="cardShortcut">卡片快捷键</string>
<string name="editCardTitle">编辑卡片</string>
<string name="addCardTitle">添加卡片</string>
<string name="scanCardBarcode">扫描卡片条码</string>
<string name="sendLabel">发送…</string>
<string name="share">分享</string>
<string name="copy_to_clipboard">复制卡号到剪贴板</string>
<string name="ok">确定</string>
<string name="deleteConfirmation">删除此卡?</string>
<string name="deleteTitle">移除卡片</string>
<string name="unlockScreen">解除旋转锁定</string>
<string name="lockScreen">锁定旋转</string>
<string name="confirm">确认</string>
<string name="delete">删除</string>
<string name="edit">编辑</string>
<string name="save">保存</string>
<string name="cancel">取消</string>
<string name="star">添加到收藏</string>
<string name="noBarcode">无条形码</string>
<string name="barcodeNoBarcode">此卡无条形码</string>
<string name="barcodeType">条形码类型</string>
<string name="cardId">卡号</string>
<string name="note">备注</string>
<string name="storeName">名称</string>
<string name="noMatchingGiftCards">没有找到任何东西。尝试改变你的搜索。</string>
<string name="noGiftCards">点击 \"+\"加号按钮来添加卡片,或者先从⋮菜单中导入一些。</string>
<string name="card_selected">"选中: "</string>
<string name="action_add">添加</string>
<string name="action_search">搜索</string>
</resources>

View File

@@ -10,6 +10,8 @@
<color name="colorPrimaryText">#ffffff</color>
<color name="colorSecondaryText">#000000</color>
<color name="listItemHighlight">#44000000</color>
<color name="inputContrastBackground">#F8F8F8</color>
<color name="inputBackground">#FFFFFF</color>
<color name="inputBorder">#DDDDDD</color>

View File

@@ -2,4 +2,6 @@
<resources>
<string name="app_revision_url" translatable="false">https://github.com/TheLastProject/Catima/releases</string>
<string name="app_webpage_url" translatable="false">https://github.com/TheLastProject/Catima</string>
<integer name="full_rotation_duration">100</integer>
<integer name="half_rotation_duration">50</integer>
</resources>

View File

@@ -4,11 +4,12 @@
<string name="action_search">Search</string>
<string name="action_add">Add</string>
<string name="card_selected">Selected:\u0020</string>
<string name="noGiftCards">Click the "+" (plus) button to add a card first.\n\nCatima carries your cards on the device, so they are always within reach.</string>
<string name="noGiftCards">Click the + plus button to add a card, or import some from the ⋮ menu first.</string>
<string name="noMatchingGiftCards">Didn\'t find anything. Try changing your search.</string>
<string name="storeName">Store</string>
<string name="storeName">Name</string>
<string name="note">Note</string>
<string name="cardId">Card ID</string>
<string name="barcodeType">Barcode type</string>
@@ -26,7 +27,7 @@
<string name="lockScreen">Block Rotation</string>
<string name="unlockScreen">Unblock Rotation</string>
<string name="deleteTitle">Remove Card</string>
<string name="deleteConfirmation">Please confirm you want to delete this card.</string>
<string name="deleteConfirmation">Delete this card?</string>
<string name="ok">OK</string>
<string name="copy_to_clipboard">Copy ID to clipboard</string>
<string name="share">Share</string>
@@ -36,10 +37,11 @@
<string name="scanCardBarcode">Scan Card Barcode</string>
<string name="cardShortcut">Card Shortcut</string>
<string name="noCardsMessage">Add a card first</string>
<string name="card_ids_copied">Copied Card ID(s)</string>
<string name="barcodeImageDescription">Image of card barcode</string>
<string name="noStoreError">No store entered</string>
<string name="noStoreError">No name entered</string>
<string name="noCardIdError">No card ID entered</string>
<string name="noCardExistsError">Could not find card</string>
<string name="failedParsingImportUriError">Could not parse the import URI</string>
@@ -59,22 +61,22 @@
<string name="importOptionFilesystemTitle">Import from filesystem</string>
<string name="importOptionFilesystemExplanation">Choose a specific file from the filesystem.</string>
<string name="importOptionFilesystemButton">From filesystem</string>
<string name="importOptionApplicationTitle">Use external app</string>
<string name="importOptionApplicationTitle">Use another app</string>
<string name="importOptionApplicationExplanation">Use any app or your favorite file manager to open a file.</string>
<string name="importOptionApplicationButton">Use external app</string>
<string name="importOptionApplicationButton">Use another app</string>
<string name="about">About</string>
<string name="app_copyright_fmt" translatable="false" tools:ignore="PluralsCandidate">Copyright 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
<string name="app_copyright_old">Based on Loyalty Card Keychain, copyright 20162020 Branden Archer.</string>
<string name="app_copyright_fmt" tools:ignore="PluralsCandidate">Copyright © 2019<xliff:g>%d</xliff:g> Sylvia van Os.</string>
<string name="app_copyright_old">Based on Loyalty Card Keychain\ncopyright © 20162020 Branden Archer.</string>
<string name="app_license">Copylefted libre software, licensed GPLv3+.</string>
<string name="about_title_fmt">About <xliff:g id="app_name">%s</xliff:g></string>
<string name="debug_version_fmt">Version: <xliff:g id="version">%s</xliff:g></string>
<string name="app_revision_fmt">Revision Info: <xliff:g id="app_revision_url">%s</xliff:g></string>
<string name="app_libraries"><xliff:g id="app_name">%s</xliff:g> uses the following third-party libraries: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources"><xliff:g id="app_name">%s</xliff:g> uses the following third-party resources: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="app_libraries">Third-party libre libraries: <xliff:g id="app_libraries_list">%s</xliff:g></string>
<string name="app_resources">Third-party libre resources: <xliff:g id="app_resources_list">%s</xliff:g></string>
<string name="selectBarcodeTitle">Select Barcode</string>
<string name="enterBarcodeInstructions">Enter the card ID then select the image which represents the barcode you want to use, or select &#8220;This card has no barcode&#8221; to not use a barcode.</string>
<string name="enterBarcodeInstructions">Enter the card ID, and either pick its barcode type below, or &#8220;This card has no barcode&#8221;.</string>
<string name="copy_to_clipboard_toast">Card ID copied to clipboard</string>
@@ -92,15 +94,15 @@
<string name="settings_dark_theme">Dark</string>
<string name="settings_key_dark_theme" translatable="false">dark</string>
<string name="settings_key_max_font_size_scale" translatable="false">pref_max_font_size_scale</string>
<string name="settings_max_font_size_scale">Maximum font size scale</string>
<string name="settings_max_font_size_scale">Max. font size</string>
<string name="settings_display_barcode_max_brightness">Brighten barcode view</string>
<string name="settings_key_display_barcode_max_brightness" translatable="false">pref_display_card_max_brightness</string>
<string name="settings_lock_barcode_orientation">Lock barcode orientation</string>
<string name="settings_key_lock_barcode_orientation" translatable="false">pref_lock_barcode_orientation</string>
<string name="settings_keep_screen_on">Keep screen on while viewing a card</string>
<string name="settings_keep_screen_on">Keep screen on</string>
<string name="settings_key_keep_screen_on" translatable="false">pref_keep_screen_on</string>
<string name="settings_disable_lockscreen_while_viewing_card">Disable lock screen while viewing a card</string>
<string name="settings_disable_lockscreen_while_viewing_card">Prevent lock screen</string>
<string name="settings_key_disable_lockscreen_while_viewing_card" translatable="false">pref_disable_lockscreen_while_viewing_card</string>
<string name="sharedpreference_active_tab" translatable="false">sharedpreference_active_tab</string>
@@ -116,17 +118,17 @@
<string name="enter_group_name">Enter group name</string>
<string name="groups">Groups</string>
<string name="noGroups">Click the "+" (plus) button to add groups first.\n\nGroups make things easier to find.</string>
<string name="noGroups">Click the + plus button to add groups for categorization first.</string>
<plurals name="groupCardCount">
<item quantity="one"><xliff:g>%d</xliff:g> card</item>
<item quantity="other"><xliff:g>%d</xliff:g> cards</item>
</plurals>
<string name="all">All</string>
<string name="deleteConfirmationGroup">Please confirm you want to delete this group</string>
<string name="deleteConfirmationGroup">Delete group?</string>
<string name="failedOpeningFileManager">Install a file manager first.</string>
<string name="moveUp">Move up in list</string>
<string name="moveDown">Move down in list</string>
<string name="moveUp">Move upwards</string>
<string name="moveDown">Move downwards</string>
<string name="leaveWithoutSaveTitle">Exit</string>
<string name="leaveWithoutSaveConfirmation">Leave without saving?</string>
<string name="addManually">Manually enter card ID</string>
@@ -158,19 +160,25 @@
<string name="app_loyalty_card_keychain">Loyalty Card Keychain</string>
<string name="privacy_policy">Privacy Policy</string>
<string name="privacy_policy_popup_text">Privacy policy notice (required by some app stores):\n\nWe collect NO DATA AT ALL, which anyone can confirm since our app is libre software.</string>
<string name="privacy_policy_popup_text">Privacy policy notice (required by some app stores):\n\nNO DATA IS COLLECTED AT ALL, which anyone can confirm since our app is libre software.</string>
<string name="accept">Accept</string>
<string name="importCatima">Import from Catima</string>
<string name="importCatimaMessage">Please select your Catima export file. It is most likely named Catima.csv.\n\nA Catima export file can be created by going to the Import/Export menu and pressing "Export".</string>
<string name="importCatimaMessage">Find a file likely named <i>Catima.csv</i> to import.\nOr create it from the Import/Export menu of another Catima app by pressing "Export" there first.</string>
<string name="importFidme">Import from FidMe</string>
<string name="importFidmeMessage">Please select your FidMe export file. It is most likely named something like fidme-export-request-xxxxxx.zip.\n\nA FidMe export file can be created in the FidMe app by going to your profile, choosing "Data Protection" and then pressing "Extract my data".\n\nPlease note that FidMe does not store the barcode type in the export data so you will have to edit the imported cards manually.</string>
<string name="importFidmeMessage">Find a file likely named <i>fidme-export-request-xxxxxx.zip</i> to import, and then select the barcode types manually afterwards.\nOr create it from your FidMe profile by choosing "Data Protection" and then pressing "Extract my data" first.</string>
<string name="importLoyaltyCardKeychain">Import from Loyalty Card Keychain</string>
<string name="importLoyaltyCardKeychainMessage">Please select your Loyalty Card Keychain export file. It is most likely named LoyaltyCardKeychain.csv.\n\nA Loyalty Card Keychain export file can be created by going to the Import/Export menu and pressing "Export".</string>
<string name="importLoyaltyCardKeychainMessage">Find a file most likely named <i>LoyaltyCardKeychain.csv</i> to import.\nOr create it from the Import/Export menu in Loyalty Card Keychain by pressing "Export" first.</string>
<string name="importVoucherVault">Import from Voucher Vault</string>
<string name="importVoucherVaultMessage">Please select your Voucher Vault export file. It is most likely named vouchervault.json.\n\nA Voucher Vault export file can be created by pressing "Export".</string>
<string name="importVoucherVaultMessage">Find a file likely named <i>vouchervault.json</i> to import.\nOr create it by pressing "Export" in Voucher Vault first.</string>
<string name="barcodeId">Barcode value</string>
<string name="sameAsCardId">Same as card ID</string>
<string name="setBarcodeId">Set barcode value</string>
<string name="unsupportedBarcodeType">This barcode type can\'t yet be displayed. It may be supported in a newer version of the app.</string>
<string name="wrongValueForBarcodeType">The value is not valid for the selected barcode type</string>
<string name="copy_to_clipboard_multiple_toast">Copied card IDs to clipboard</string>
<string name="intent_import_card_from_url_share_multiple_text">I want to share some cards with you</string>
<string name="updateBarcodeQuestionTitle">Update barcode value?</string>
<string name="updateBarcodeQuestionText">You changed the card ID. Do you want to also update the barcode to use the same value?</string>
<string name="yes">Yes</string>
<string name="no">No</string>
</resources>

View File

@@ -7,6 +7,9 @@
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorSecondary">@color/colorSecondary</item>
<item name="colorAccent">@color/colorSecondary</item>
<item name="actionModeBackground">@color/colorPrimary</item>
<item name="windowActionModeOverlay">true</item>
<item name="actionModeCloseDrawable">@drawable/ic_close</item>
</style>
<style name="AppTheme.NoActionBar" parent="AppTheme">

View File

@@ -38,7 +38,7 @@ public class DatabaseTest
public void setUp()
{
Activity activity = Robolectric.setupActivity(MainActivity.class);
db = new DBHelper(activity);
db = TestHelpers.getEmptyDb(activity);
}
@Test

View File

@@ -1,8 +1,5 @@
package protect.card_locker;
import static org.junit.Assert.assertEquals;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -10,6 +7,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.view.View;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
@@ -17,6 +15,9 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import static org.junit.Assert.assertEquals;
import static org.robolectric.Shadows.shadowOf;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 23)
public class ImportExportActivityTest

View File

@@ -17,7 +17,6 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.LooperMode;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -25,13 +24,12 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Currency;
import java.util.Date;
@@ -62,7 +60,7 @@ public class ImportExportTest
public void setUp()
{
activity = Robolectric.setupActivity(MainActivity.class);
db = new DBHelper(activity);
db = TestHelpers.getEmptyDb(activity);
nowMs = System.currentTimeMillis();
Calendar lastYear = Calendar.getInstance();
@@ -314,20 +312,6 @@ public class ImportExportTest
cursor.close();
}
/**
* Delete the contents of the database
*/
private void clearDatabase()
{
SQLiteDatabase database = db.getWritableDatabase();
database.execSQL("delete from " + DBHelper.LoyaltyCardDbIds.TABLE);
database.execSQL("delete from " + DBHelper.LoyaltyCardDbGroups.TABLE);
database.execSQL("delete from " + DBHelper.LoyaltyCardDbIdsGroups.TABLE);
database.close();
assertEquals(0, db.getLoyaltyCardCount());
}
@Test
public void multipleCardsExportImport() throws IOException
{
@@ -343,7 +327,7 @@ public class ImportExportTest
assertTrue(result);
outStream.close();
clearDatabase();
TestHelpers.getEmptyDb(activity);
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
@@ -356,7 +340,7 @@ public class ImportExportTest
checkLoyaltyCards();
// Clear the database for the next format under test
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -374,7 +358,7 @@ public class ImportExportTest
assertTrue(result);
outStream.close();
clearDatabase();
TestHelpers.getEmptyDb(activity);
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
@@ -387,7 +371,7 @@ public class ImportExportTest
checkLoyaltyCardsFiveStarred();
// Clear the database for the next format under test
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
private List<String> groupsToGroupNames(List<Group> groups)
@@ -447,7 +431,7 @@ public class ImportExportTest
assertTrue(result);
outStream.close();
clearDatabase();
TestHelpers.getEmptyDb(activity);
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
@@ -473,7 +457,7 @@ public class ImportExportTest
assertEquals(emptyGroup, db.getLoyaltyCardGroups(10));
// Clear the database for the next format under test
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -502,7 +486,7 @@ public class ImportExportTest
checkLoyaltyCards();
// Clear the database for the next format under test
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -521,7 +505,7 @@ public class ImportExportTest
boolean result = MultiFormatExporter.exportData(db, outStream, DataFormat.Catima);
assertTrue(result);
clearDatabase();
TestHelpers.getEmptyDb(activity);
// commons-csv would throw a RuntimeException if an entry was quotes but had
// content after. For example:
@@ -537,7 +521,7 @@ public class ImportExportTest
assertEquals(0, db.getLoyaltyCardCount());
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
}
@@ -576,7 +560,7 @@ public class ImportExportTest
assertNotNull(listener.success);
assertEquals(true, listener.success);
clearDatabase();
TestHelpers.getEmptyDb(activity);
// Import everything back from the default location
@@ -599,7 +583,7 @@ public class ImportExportTest
checkLoyaltyCards();
// Clear the database for the next format under test
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -635,7 +619,7 @@ public class ImportExportTest
assertNull(card.headerColor);
assertEquals(0, card.starStatus);
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -673,7 +657,7 @@ public class ImportExportTest
assertNull(card.headerColor);
assertEquals(0, card.starStatus);
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -698,7 +682,7 @@ public class ImportExportTest
assertEquals(false, result);
assertEquals(0, db.getLoyaltyCardCount());
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -736,7 +720,7 @@ public class ImportExportTest
assertEquals(1, (long) card.headerColor);
assertEquals(0, card.starStatus);
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -774,7 +758,7 @@ public class ImportExportTest
assertEquals(1, (long) card.headerColor);
assertEquals(1, card.starStatus);
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -812,7 +796,7 @@ public class ImportExportTest
assertEquals(1, (long) card.headerColor);
assertEquals(0, card.starStatus);
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -869,7 +853,7 @@ public class ImportExportTest
assertEquals(1, (long) card.headerColor);
assertEquals(0, card.starStatus);
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -889,8 +873,8 @@ public class ImportExportTest
"_id\r\n" +
"Example\r\n" +
"\r\n" +
"_id,store,note,expiry,balance,balancetype,cardid,headercolor,barcodetype,starstatus\r\n" +
"1,Card 1,Note 1,1618053234,100,USD,1234,1,QR_CODE,0\r\n" +
"_id,store,note,expiry,balance,balancetype,cardid,headercolor,barcodeid,barcodetype,starstatus\r\n" +
"1,Card 1,Note 1,1618053234,100,USD,1234,1,5432,QR_CODE,0\r\n" +
"\r\n" +
"cardId,groupId\r\n" +
"1,Example\r\n";
@@ -1026,7 +1010,7 @@ public class ImportExportTest
assertEquals(null, card6.headerColor);
assertEquals(0, card6.starStatus);
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
@Test
@@ -1087,6 +1071,6 @@ public class ImportExportTest
assertEquals(Color.rgb(128, 0, 128), (long) card.headerColor);
assertEquals(0, card.starStatus);
clearDatabase();
TestHelpers.getEmptyDb(activity);
}
}

View File

@@ -3,13 +3,16 @@ package protect.card_locker;
import android.app.Activity;
import android.graphics.Color;
import android.net.Uri;
import com.google.zxing.BarcodeFormat;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.io.InvalidObjectException;
import java.math.BigDecimal;
import java.util.Currency;
@@ -18,7 +21,6 @@ import java.util.Date;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static protect.card_locker.DBHelper.LoyaltyCardDbIds;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 23)
@@ -31,7 +33,7 @@ public class ImportURITest {
{
Activity activity = Robolectric.setupActivity(MainActivity.class);
importURIHelper = new ImportURIHelper(activity);
db = new DBHelper(activity);
db = TestHelpers.getEmptyDb(activity);
}
@Test

View File

@@ -4,11 +4,8 @@ import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import androidx.preference.PreferenceManager;
import androidx.test.core.app.ApplicationProvider;
import protect.card_locker.preferences.Settings;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -21,13 +18,22 @@ import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLog;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.Currency;
import java.util.Date;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.RecyclerView;
import protect.card_locker.preferences.Settings;
import static android.os.Looper.getMainLooper;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 23)
@@ -40,8 +46,10 @@ public class LoyaltyCardCursorAdapterTest
@Before
public void setUp()
{
ShadowLog.stream = System.out;
activity = Robolectric.setupActivity(MainActivity.class);
db = new DBHelper(activity);
db = TestHelpers.getEmptyDb(activity);
settings = PreferenceManager.getDefaultSharedPreferences(activity);
}
@@ -54,12 +62,12 @@ public class LoyaltyCardCursorAdapterTest
private View createView(Cursor cursor)
{
LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(activity.getApplicationContext(), cursor);
LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(activity.getApplicationContext(), cursor, (MainActivity) activity);
View view = adapter.newView(activity.getApplicationContext(), cursor, null);
adapter.bindView(view, activity.getApplicationContext(), cursor);
RecyclerView.ViewHolder viewHolder = adapter.createViewHolder(activity.findViewById(R.id.list), 0);
adapter.bindViewHolder((LoyaltyCardCursorAdapter.LoyaltyCardListItemViewHolder) viewHolder, cursor.getPosition());
return view;
return viewHolder.itemView;
}
private void checkView(final View view, final String store, final String note, final String expiry, final String balance, boolean checkFontSizes)
@@ -148,7 +156,7 @@ public class LoyaltyCardCursorAdapterTest
@Test
public void TestCursorAdapterFontSizes()
{
final Context context = ApplicationProvider.getApplicationContext();
final Context context = activity.getApplicationContext();
Date expiryDate = new Date();
String dateString = context.getString(R.string.expiryStateSentence, DateFormat.getDateInstance(DateFormat.LONG).format(expiryDate));
@@ -173,22 +181,39 @@ public class LoyaltyCardCursorAdapterTest
@Test
public void TestCursorAdapterStarring()
{
db.insertLoyaltyCard("storeA", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 0);
db.insertLoyaltyCard("storeB", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 1);
db.insertLoyaltyCard("storeC", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 1);
assertNotEquals(-1, db.insertLoyaltyCard("storeA", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 0));
assertNotEquals(-1, db.insertLoyaltyCard("storeB", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 1));
assertNotEquals(-1, db.insertLoyaltyCard("storeC", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 1));
assertEquals(3, db.getLoyaltyCardCount());
Cursor cursor = db.getLoyaltyCardCursor();
assertEquals(3, cursor.getCount());
cursor.moveToFirst();
System.out.println(LoyaltyCard.toLoyaltyCard(cursor).store);
cursor.moveToNext();
System.out.println(LoyaltyCard.toLoyaltyCard(cursor).store);
cursor.moveToNext();
System.out.println(LoyaltyCard.toLoyaltyCard(cursor).store);
assertTrue(cursor.moveToFirst());
LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
assertEquals("storeB", loyaltyCard.store);
View view = createView(cursor);
ImageView star = view.findViewById(R.id.star);
assertEquals(View.VISIBLE, star.getVisibility());
cursor.moveToNext();
assertTrue(cursor.moveToNext());
loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
assertEquals("storeC", loyaltyCard.store);
view = createView(cursor);
star = view.findViewById(R.id.star);
assertEquals(View.VISIBLE, star.getVisibility());
cursor.moveToNext();
assertTrue(cursor.moveToNext());
loyaltyCard = LoyaltyCard.toLoyaltyCard(cursor);
assertEquals("storeA", loyaltyCard.store);
view = createView(cursor);
star = view.findViewById(R.id.star);
assertEquals(View.GONE, star.getVisibility());

View File

@@ -1,26 +1,18 @@
package protect.card_locker;
import static android.os.Looper.getMainLooper;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import androidx.preference.PreferenceManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -30,20 +22,13 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.core.widget.TextViewCompat;
import androidx.test.core.app.ApplicationProvider;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
import com.google.android.material.textfield.TextInputLayout;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.client.android.Intents;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Currency;
import java.util.Date;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -53,10 +38,26 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowActivity;
import org.robolectric.shadows.ShadowAlertDialog;
import org.robolectric.shadows.ShadowDialog;
import org.robolectric.shadows.ShadowLog;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Currency;
import java.util.Date;
import androidx.core.widget.TextViewCompat;
import androidx.preference.PreferenceManager;
import static android.os.Looper.getMainLooper;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 23)
public class LoyaltyCardViewActivityTest
@@ -328,7 +329,7 @@ public class LoyaltyCardViewActivityTest
activityController.resume();
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
final Context context = activity.getApplicationContext();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.never) , "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId),"");
}
@@ -343,7 +344,7 @@ public class LoyaltyCardViewActivityTest
Activity activity = (Activity)activityController.get();
DBHelper db = new DBHelper(activity);
DBHelper db = TestHelpers.getEmptyDb(activity);
assertEquals(0, db.getLoyaltyCardCount());
final EditText storeField = activity.findViewById(R.id.storeNameEdit);
@@ -388,7 +389,7 @@ public class LoyaltyCardViewActivityTest
activityController.resume();
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
final Context context = activity.getApplicationContext();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId),"");
@@ -412,7 +413,7 @@ public class LoyaltyCardViewActivityTest
activityController.resume();
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
final Context context = activity.getApplicationContext();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId), "");
@@ -431,7 +432,7 @@ public class LoyaltyCardViewActivityTest
activityController.resume();
LoyaltyCardEditActivity activity = (LoyaltyCardEditActivity) activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
final Context context = activity.getApplicationContext();
checkAllFields(activity, ViewMode.ADD_CARD, "", "", context.getString(R.string.never), "0", context.getString(R.string.points), "", context.getString(R.string.sameAsCardId),"");
@@ -485,8 +486,8 @@ public class LoyaltyCardViewActivityTest
{
ActivityController activityController = createActivityWithLoyaltyCard(true);
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
DBHelper db = new DBHelper(activity);
final Context context = activity.getApplicationContext();
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0);
@@ -504,8 +505,8 @@ public class LoyaltyCardViewActivityTest
{
ActivityController activityController = createActivityWithLoyaltyCard(false);
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
DBHelper db = new DBHelper(activity);
final Context context = activity.getApplicationContext();
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0);
@@ -523,8 +524,8 @@ public class LoyaltyCardViewActivityTest
{
ActivityController activityController = createActivityWithLoyaltyCard(true);
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
DBHelper db = new DBHelper(activity);
final Context context = activity.getApplicationContext();
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0);
@@ -547,8 +548,8 @@ public class LoyaltyCardViewActivityTest
{
ActivityController activityController = createActivityWithLoyaltyCard(true);
LoyaltyCardEditActivity activity = (LoyaltyCardEditActivity) activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
DBHelper db = new DBHelper(activity);
final Context context = activity.getApplicationContext();
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0);
@@ -585,8 +586,8 @@ public class LoyaltyCardViewActivityTest
{
ActivityController activityController = createActivityWithLoyaltyCard(true);
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
DBHelper db = new DBHelper(activity);
final Context context = activity.getApplicationContext();
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0);
@@ -618,8 +619,8 @@ public class LoyaltyCardViewActivityTest
{
ActivityController activityController = createActivityWithLoyaltyCard(true);
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
DBHelper db = new DBHelper(activity);
final Context context = activity.getApplicationContext();
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", new Date(), new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0);
@@ -643,8 +644,8 @@ public class LoyaltyCardViewActivityTest
{
ActivityController activityController = createActivityWithLoyaltyCard(true);
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
DBHelper db = new DBHelper(activity);
final Context context = activity.getApplicationContext();
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0);
@@ -694,8 +695,8 @@ public class LoyaltyCardViewActivityTest
{
ActivityController activityController = createActivityWithLoyaltyCard(true);
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
DBHelper db = new DBHelper(activity);
final Context context = activity.getApplicationContext();
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("10.00"), Currency.getInstance("USD"), EAN_BARCODE_DATA, null, EAN_BARCODE_TYPE, Color.BLACK, 0);
@@ -735,7 +736,7 @@ public class LoyaltyCardViewActivityTest
{
ActivityController activityController = createActivityWithLoyaltyCard(false);
Activity activity = (Activity)activityController.get();
DBHelper db = new DBHelper(activity);
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0);
@@ -784,7 +785,7 @@ public class LoyaltyCardViewActivityTest
ActivityController activityController = createActivityWithLoyaltyCard(false);
Activity activity = (Activity)activityController.get();
DBHelper db = new DBHelper(activity);
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0);
activityController.start();
@@ -804,7 +805,7 @@ public class LoyaltyCardViewActivityTest
ActivityController activityController = createActivityWithLoyaltyCard(false);
Activity activity = (Activity)activityController.get();
DBHelper db = new DBHelper(activity);
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, 0);
activityController.start();
@@ -823,7 +824,7 @@ public class LoyaltyCardViewActivityTest
ActivityController activityController = createActivityWithLoyaltyCard(true);
Activity activity = (Activity)activityController.get();
DBHelper db = new DBHelper(activity);
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, null, 0);
activityController.start();
@@ -841,7 +842,7 @@ public class LoyaltyCardViewActivityTest
ActivityController activityController = createActivityWithLoyaltyCard(true);
Activity activity = (Activity)activityController.get();
DBHelper db = new DBHelper(activity);
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, null, Color.BLACK, 0);
activityController.start();
@@ -858,8 +859,8 @@ public class LoyaltyCardViewActivityTest
public void removeBarcodeFromLoyaltyCard() throws IOException, ParseException {
ActivityController activityController = createActivityWithLoyaltyCard(true);
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
DBHelper db = new DBHelper(activity);
final Context context = activity.getApplicationContext();
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0);
@@ -889,7 +890,7 @@ public class LoyaltyCardViewActivityTest
ActivityController activityController = createActivityWithLoyaltyCard(false);
Activity activity = (Activity)activityController.get();
DBHelper db = new DBHelper(activity);
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0);
final int LARGE_FONT_SIZE = 40;
@@ -964,7 +965,7 @@ public class LoyaltyCardViewActivityTest
ActivityController activityController = createActivityWithLoyaltyCard(false);
Activity activity = (Activity) activityController.get();
DBHelper db = new DBHelper(activity);
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK,0);
activityController.start();
activityController.visible();
@@ -999,7 +1000,7 @@ public class LoyaltyCardViewActivityTest
ActivityController activityController = createActivityWithLoyaltyCard(false);
Activity activity = (Activity)activityController.get();
DBHelper db = new DBHelper(activity);
DBHelper db = TestHelpers.getEmptyDb(activity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, BARCODE_DATA, null, BARCODE_TYPE, Color.BLACK, 0);
activityController.start();
@@ -1110,7 +1111,7 @@ public class LoyaltyCardViewActivityTest
activityController.resume();
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
final Context context = activity.getApplicationContext();
shadowOf(getMainLooper()).idle();
@@ -1133,7 +1134,7 @@ public class LoyaltyCardViewActivityTest
activityController.resume();
Activity activity = (Activity)activityController.get();
final Context context = ApplicationProvider.getApplicationContext();
final Context context = activity.getApplicationContext();
checkAllFields(activity, ViewMode.ADD_CARD, "Example Store", "", context.getString(R.string.never), "0", context.getString(R.string.points), "123456", null, "AZTEC");
assertEquals(-416706, ((ColorDrawable) activity.findViewById(R.id.thumbnail).getBackground()).getColor());

View File

@@ -17,17 +17,20 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowActivity;
import org.w3c.dom.Text;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import androidx.recyclerview.widget.RecyclerView;
import static android.os.Looper.getMainLooper;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.robolectric.Shadows.shadowOf;
@RunWith(RobolectricTestRunner.class)
@@ -37,10 +40,9 @@ public class MainActivityTest
private SharedPreferences prefs;
@Test
public void initiallyNoLoyaltyCards() throws Exception
{
public void initiallyNoLoyaltyCards() {
Activity activity = Robolectric.setupActivity(MainActivity.class);
assertTrue(activity != null);
assertNotNull(activity);
TextView helpText = activity.findViewById(R.id.helpText);
assertEquals(View.VISIBLE, helpText.getVisibility());
@@ -48,17 +50,16 @@ public class MainActivityTest
TextView noMatchingCardsText = activity.findViewById(R.id.noMatchingCardsText);
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
ListView list = activity.findViewById(R.id.list);
RecyclerView list = activity.findViewById(R.id.list);
assertEquals(View.GONE, list.getVisibility());
}
@Test
public void onCreateShouldInflateLayout() throws Exception
{
public void onCreateShouldInflateLayout() {
final MainActivity activity = Robolectric.setupActivity(MainActivity.class);
final Menu menu = shadowOf(activity).getOptionsMenu();
assertTrue(menu != null);
assertNotNull(menu);
// The settings, import/export, groups, search and add button should be present
assertEquals(menu.size(), 6);
@@ -92,11 +93,11 @@ public class MainActivityTest
TextView helpText = mainActivity.findViewById(R.id.helpText);
TextView noMatchingCardsText = mainActivity.findViewById(R.id.noMatchingCardsText);
ListView list = mainActivity.findViewById(R.id.list);
RecyclerView list = mainActivity.findViewById(R.id.list);
assertEquals(0, list.getCount());
assertEquals(0, list.getAdapter().getItemCount());
DBHelper db = new DBHelper(mainActivity);
DBHelper db = TestHelpers.getEmptyDb(mainActivity);
db.insertLoyaltyCard("store", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 0);
assertEquals(View.VISIBLE, helpText.getVisibility());
@@ -110,9 +111,7 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getAdapter().getCount());
Cursor cursor = (Cursor)list.getAdapter().getItem(0);
assertNotNull(cursor);
assertEquals(1, list.getAdapter().getItemCount());
db.close();
}
@@ -125,14 +124,15 @@ public class MainActivityTest
Activity mainActivity = (Activity)activityController.get();
activityController.start();
activityController.resume();
activityController.visible();
TextView helpText = mainActivity.findViewById(R.id.helpText);
TextView noMatchingCardsText = mainActivity.findViewById(R.id.noMatchingCardsText);
ListView list = mainActivity.findViewById(R.id.list);
RecyclerView list = mainActivity.findViewById(R.id.list);
assertEquals(0, list.getCount());
assertEquals(0, list.getAdapter().getItemCount());
DBHelper db = new DBHelper(mainActivity);
DBHelper db = TestHelpers.getEmptyDb(mainActivity);
db.insertLoyaltyCard("storeB", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 0);
db.insertLoyaltyCard("storeA", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 0);
db.insertLoyaltyCard("storeD", "note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 1);
@@ -144,27 +144,17 @@ public class MainActivityTest
activityController.pause();
activityController.resume();
activityController.visible();
assertEquals(View.GONE, helpText.getVisibility());
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(4, list.getAdapter().getCount());
Cursor cursor = (Cursor)list.getAdapter().getItem(0);
assertNotNull(cursor);
assertEquals("storeC",cursor.getString(cursor.getColumnIndex("store")));
cursor = (Cursor)list.getAdapter().getItem(1);
assertNotNull(cursor);
assertEquals("storeD",cursor.getString(cursor.getColumnIndex("store")));
cursor = (Cursor)list.getAdapter().getItem(2);
assertNotNull(cursor);
assertEquals("storeA",cursor.getString(cursor.getColumnIndex("store")));
cursor = (Cursor)list.getAdapter().getItem(3);
assertNotNull(cursor);
assertEquals("storeB",cursor.getString(cursor.getColumnIndex("store")));
assertEquals(4, list.getAdapter().getItemCount());
assertEquals("storeC", ((TextView) list.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.store)).getText());
assertEquals("storeD", ((TextView) list.findViewHolderForAdapterPosition(1).itemView.findViewById(R.id.store)).getText());
assertEquals("storeA", ((TextView) list.findViewHolderForAdapterPosition(2).itemView.findViewById(R.id.store)).getText());
assertEquals("storeB", ((TextView) list.findViewHolderForAdapterPosition(3).itemView.findViewById(R.id.store)).getText());
db.close();
}
@@ -178,7 +168,7 @@ public class MainActivityTest
activityController.start();
activityController.resume();
DBHelper db = new DBHelper(mainActivity);
DBHelper db = TestHelpers.getEmptyDb(mainActivity);
TabLayout groupTabs = mainActivity.findViewById(R.id.groups);
@@ -230,10 +220,10 @@ public class MainActivityTest
TextView helpText = mainActivity.findViewById(R.id.helpText);
TextView noMatchingCardsText = mainActivity.findViewById(R.id.noMatchingCardsText);
ListView list = mainActivity.findViewById(R.id.list);
RecyclerView list = mainActivity.findViewById(R.id.list);
TabLayout groupTabs = mainActivity.findViewById(R.id.groups);
DBHelper db = new DBHelper(mainActivity);
DBHelper db = TestHelpers.getEmptyDb(mainActivity);
db.insertLoyaltyCard("The First Store", "Initial note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 0);
db.insertLoyaltyCard("The Second Store", "Secondary note", null, new BigDecimal("0"), null, "cardId", null, BarcodeFormat.UPC_A, Color.BLACK, 0);
@@ -249,9 +239,9 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(2, list.getCount());
assertEquals(2, list.getAdapter().getItemCount());
mainActivity.filter = "store";
mainActivity.mFilter = "store";
activityController.pause();
activityController.resume();
@@ -260,7 +250,7 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(2, list.getCount());
assertEquals(2, list.getAdapter().getItemCount());
// Switch to Group one
groupTabs.selectTab(groupTabs.getTabAt(1));
@@ -272,7 +262,7 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getCount());
assertEquals(1, list.getAdapter().getItemCount());
// Switch back to all groups
groupTabs.selectTab(groupTabs.getTabAt(0));
@@ -281,9 +271,9 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(2, list.getCount());
assertEquals(2, list.getAdapter().getItemCount());
mainActivity.filter = "first";
mainActivity.mFilter = "first";
activityController.pause();
activityController.resume();
@@ -292,7 +282,7 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getCount());
assertEquals(1, list.getAdapter().getItemCount());
// Switch to Group one
groupTabs.selectTab(groupTabs.getTabAt(1));
@@ -304,7 +294,7 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getCount());
assertEquals(1, list.getAdapter().getItemCount());
// Switch back to all groups
groupTabs.selectTab(groupTabs.getTabAt(0));
@@ -313,9 +303,9 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getCount());
assertEquals(1, list.getAdapter().getItemCount());
mainActivity.filter = "initial";
mainActivity.mFilter = "initial";
activityController.pause();
activityController.resume();
@@ -324,7 +314,7 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getCount());
assertEquals(1, list.getAdapter().getItemCount());
// Switch to Group one
groupTabs.selectTab(groupTabs.getTabAt(1));
@@ -336,7 +326,7 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getCount());
assertEquals(1, list.getAdapter().getItemCount());
// Switch back to all groups
groupTabs.selectTab(groupTabs.getTabAt(0));
@@ -345,9 +335,9 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getCount());
assertEquals(1, list.getAdapter().getItemCount());
mainActivity.filter = "second";
mainActivity.mFilter = "second";
activityController.pause();
activityController.resume();
@@ -356,7 +346,7 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getCount());
assertEquals(1, list.getAdapter().getItemCount());
// Switch to Group one
groupTabs.selectTab(groupTabs.getTabAt(1));
@@ -364,11 +354,13 @@ public class MainActivityTest
activityController.pause();
activityController.resume();
shadowOf(getMainLooper()).idle();
assertEquals(View.GONE, helpText.getVisibility());
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(0, list.getCount());
assertEquals(0, list.getAdapter().getItemCount());
// Switch back to all groups
groupTabs.selectTab(groupTabs.getTabAt(0));
@@ -377,18 +369,20 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getCount());
assertEquals(1, list.getAdapter().getItemCount());
mainActivity.filter = "company";
mainActivity.mFilter = "company";
activityController.pause();
activityController.resume();
shadowOf(getMainLooper()).idle();
assertEquals(View.GONE, helpText.getVisibility());
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(0, list.getCount());
assertEquals(0, list.getAdapter().getItemCount());
// Switch to Group one
groupTabs.selectTab(groupTabs.getTabAt(1));
@@ -396,11 +390,13 @@ public class MainActivityTest
activityController.pause();
activityController.resume();
shadowOf(getMainLooper()).idle();
assertEquals(View.GONE, helpText.getVisibility());
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(0, list.getCount());
assertEquals(0, list.getAdapter().getItemCount());
// Switch back to all groups
groupTabs.selectTab(groupTabs.getTabAt(0));
@@ -409,18 +405,20 @@ public class MainActivityTest
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(0, list.getCount());
assertEquals(0, list.getAdapter().getItemCount());
mainActivity.filter = "";
mainActivity.mFilter = "";
activityController.pause();
activityController.resume();
shadowOf(getMainLooper()).idle();
assertEquals(View.GONE, helpText.getVisibility());
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(2, list.getCount());
assertEquals(2, list.getAdapter().getItemCount());
// Switch to Group one
groupTabs.selectTab(groupTabs.getTabAt(1));
@@ -428,11 +426,13 @@ public class MainActivityTest
activityController.pause();
activityController.resume();
shadowOf(getMainLooper()).idle();
assertEquals(View.GONE, helpText.getVisibility());
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(1, list.getCount());
assertEquals(1, list.getAdapter().getItemCount());
// Switch back to all groups
groupTabs.selectTab(groupTabs.getTabAt(0));
@@ -441,7 +441,7 @@ public class MainActivityTest
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
assertEquals(View.VISIBLE, list.getVisibility());
assertEquals(2, list.getCount());
assertEquals(2, list.getAdapter().getItemCount());
db.close();
}

View File

@@ -0,0 +1,18 @@
package protect.card_locker;
import android.app.Activity;
import android.database.sqlite.SQLiteDatabase;
public class TestHelpers {
static public DBHelper getEmptyDb(Activity activity) {
DBHelper db = new DBHelper(activity);
// Make sure DB is empty
SQLiteDatabase database = db.getWritableDatabase();
database.execSQL("delete from " + DBHelper.LoyaltyCardDbIds.TABLE);
database.execSQL("delete from " + DBHelper.LoyaltyCardDbGroups.TABLE);
database.execSQL("delete from " + DBHelper.LoyaltyCardDbIdsGroups.TABLE);
database.close();
return db;
}
}

View File

@@ -1,17 +1,14 @@
package protect.card_locker;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.util.Util;
import java.math.BigDecimal;
import java.util.Currency;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 23)

View File

@@ -1,20 +1,25 @@
# Catima
Copylefted libre software (GPLv3+) card management app.
![Android CI](https://github.com/TheLastProject/Catima/workflows/Android%20CI/badge.svg)
[![Translation status](https://hosted.weblate.org/widgets/catima/-/svg-badge.svg)](https://hosted.weblate.org/engage/catima/)
<a href="https://play.google.com/store/apps/details?id=me.hackerchick.catima" target="_blank">
<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" alt="Get it on Google Play" height="90"/></a>
<a href="https://f-droid.org/repository/browse/?fdid=me.hackerchick.catima" target="_blank">
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="90"/></a>
<a href="https://apt.izzysoft.de/fdroid/index/apk/me.hackerchick.catima" target="_blank">
<img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png" alt="Get it on IzzyOnDroid" height="90"/></a>
<a href="https://play.google.com/store/apps/details?id=me.hackerchick.catima" target="_blank">
<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" alt="Get it on Google Play" height="90"/></a>
![Logo](https://github.com/TheLastProject/Catima/raw/master/app/src/main/ic_launcher-playstore.png)
*Logo by [Rose (TangentFoxy)](http://github.com/TangentFoxy)*
Stores all of your store loyalty cards on your phone, removing the need to carry them around. Currently the following barcode types are supported:
Stores your store loyalty and membership cards on your device, instead of having to carry them around.
Supported barcodes:
- AZTEC
- CODABAR
@@ -39,16 +44,17 @@ Stores all of your store loyalty cards on your phone, removing the need to carry
[<img src="https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-07.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-07.png)
[<img src="https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-08.png" width=250>](https://github.com/TheLastProject/Catima/raw/master/fastlane/metadata/android/en-US/images/phoneScreenshots/screenshot-08.png)
# Migrating from other apps
# Moving data from other apps
[See our migration guides](migrate).
Within the app you can import cards and codes from files, Catima, Loyalty Card Keychain, Voucher Vault, and FidMe.
For FidMe you need to select the barcode type for each entry afterwards.
# Building
To build, use the gradle wrapper scripts provided in the top level directory of the project. The following will
compile the application and run all unit tests:
Use the Gradle wrapper scripts provided in the top level directory of the project.
To compile the app and run all unit tests:
GNU/Linux, OSX, UNIX:
Linux|GNU, Unix-like, macOS:
```
./gradlew build
```
@@ -62,8 +68,8 @@ Windows:
[![Translation status](https://hosted.weblate.org/widgets/catima/-/open-graph.png)](https://hosted.weblate.org/engage/catima/)
Please contribute through [our Weblate page](https://hosted.weblate.org/projects/catima/).
Help translate the app to your language from [our Hosted Weblate page](https://hosted.weblate.org/projects/catima/).
# Note from Developer
# Developer Note
This application is based on the great [Loyalty Card Keychain](https://github.com/brarcher/loyalty-card-locker) by [Branden Archer](https://github.com/brarcher). This fork was created due to the original developer having stopped development of this app.
This app is based on the great (but no longer developed) [Loyalty Card Keychain](https://github.com/brarcher/loyalty-card-locker) by [Branden Archer](https://github.com/brarcher).

View File

@@ -5,6 +5,6 @@ Someone wants to share a card with you. To import this card, you will first need
<a href="https://play.google.com/store/apps/details?id=me.hackerchick.catima" target="_blank">
<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" alt="Get it on Google Play" height="90"/></a>
<a href="https://f-droid.org/repository/browse/?fdid=me.hackerchick.catima" target="_blank">
<img src="https://f-droidgitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="90"/></a>
<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="90"/></a>
After installing the app, just click the link you were given again and choose "Import into Catima".

View File

@@ -1 +1 @@
No plastic pollution. 💳 Store discounts, membership cards and barcodes in this EDC wallet.
For your barcodes, memberships, loyalty programs, coupons and tickets.

View File

@@ -1 +1 @@
Catima — Card Wallet for Loyalty Cards, Tickets, and Coupons 🎴
Catima — The Libre Card Wallet

View File

@@ -0,0 +1,17 @@
<b>楽天ポイントカードやdポイントカード、Pontaカードなどのバーコードを読み取ってスマホ一つで一括管理</b>
お店のレジでお財布からポイントカードを出す手間が省けます。
手持ちのポイントカードを登録してお財布の中のポイントカードを減らしませんか?
- ネット接続不要なので広告は一切なしで、データ流出の心配もありません。
- カードに名前や色を自由に指定してわかりやすく管理
- バーコードが読み取れなくても手動で番号を入力可能
- Catima, Loyalty Card Keychain, Voucher Vault, FidMe 等のほかのポイントカード管理アプリからデータをインポートできます。
- すべてのカードをバックアップして新しいスマホに手軽に移行可能
- 任意のアプリを使ってポイントカードを共有できます。
- ダークテーマと視覚障がい者のためのオプション
- 自由ソフトウェアコミュニティによって全ての人のために作られています。
- 20以上の言語に対応
- 有志の貢献によって支えられている無料のアプリ
Not only Free Software / Open Source. <i>Copylefted</i> libre software (GPLv3+) card management.

View File

@@ -0,0 +1 @@
Catima はバーコード付きのポイントカードや会員カードをまとめられるアプリです。

View File

@@ -0,0 +1 @@
Catima — 複数のポイントカードを一括管理

View File

@@ -1 +1 @@
Ingen plastforurensning. 💳 Lagre butikkrabatter, medlemskort og strekkoder.
For dine butikkrabatter, billetter, medlemskort og strekkoder.

View File

@@ -1 +1 @@
Catima — for kundekort, billetter og kuponger 🎴
Catima — Den frie kortlommen

View File

@@ -1 +1 @@
Geen plasticvervuiling meer. 💳 Sla codes en klantenkaarten op op je telefoon.
Sla barcodes, coupons, tickets en cadeau- en klantenkaarten op op je telefoon.

View File

@@ -1 +1 @@
Catima - Kaart-, ticket- en couponbeheerder 🎴
Catima - Dé vrije kaartbeheerder

View File

@@ -1,4 +1,4 @@
Нужно искать пластиковые бонусные карты на кассе в магазине или интернет-магазине.
Не нужно искать пластиковые бонусные карты на кассе в магазине или интернет-магазине.
<b>Соканируйте штрих-коды на своё устройство с помощью камеры и забудьте о пластиковых картах.</b>
😺
Забудьте о бумажнике или держите его налегке для ценных вещей.

View File

@@ -1 +1 @@
Нет пластику. 💳 Храните карты и штрих-коды в электронном кошельке.
Для штрих-кодов, карт членства и лояльности, купонов и билетов.

View File

@@ -1 +1 @@
Catima — менеджер карт скидок, билетов и купонов 🎴
Catima — свободный кошелёк для карт

View File

@@ -1,19 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="192"
height="192"
viewBox="0 0 50.799999 50.799999"
version="1.1"
id="svg8"
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
sodipodi:docname="Catima v1.svg">
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="192" height="192" viewBox="0 0 50.799999 50.799999"
version="1.1" id="svg8" inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)" sodipodi:docname="Catima v1.svg">
<defs
id="defs2" />
<sodipodi:namedview

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB