mirror of
https://github.com/CatimaLoyalty/Android.git
synced 2026-04-16 13:27:28 -04:00
Feature/groups (#71)
* Basic group management * Assign cards to groups * Fix lint * Fix findbugs 'dodgy code' * Group name as unique key * More group tests * Import/export groups * Implement group renaming and deleting * Fix findBugs * Fix chip marking in edit activity * Group import/export tests * Fix some state bugs * Some last fixes * Remove redundant if statement * Fix findBugs * Deduplicate code * Cleanup * Fix groups not showing up with new card * Fix capture and enter button touching * Fix dialog button look
This commit is contained in:
@@ -45,7 +45,7 @@ android {
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'androidx.appcompat:appcompat:1.2.0'
|
||||
compile 'com.google.android.material:material:1.2.0-alpha03'
|
||||
compile 'com.google.android.material:material:1.2.1'
|
||||
compile 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
compile 'com.journeyapps:zxing-android-embedded:3.5.0@aar'
|
||||
compile 'com.google.zxing:core:3.3.0'
|
||||
@@ -58,9 +58,6 @@ dependencies {
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile "org.robolectric:robolectric:4.0.2"
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
task findbugs(type: FindBugs, dependsOn: 'assembleDebug') {
|
||||
|
||||
@@ -33,6 +33,11 @@
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ManageGroupsActivity"
|
||||
android:label="@string/groups"
|
||||
android:theme="@style/AppTheme.NoActionBar">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".LoyaltyCardViewActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
|
||||
@@ -18,7 +18,34 @@ public class CsvDatabaseExporter implements DatabaseExporter
|
||||
{
|
||||
CSVPrinter printer = new CSVPrinter(output, CSVFormat.RFC4180);
|
||||
|
||||
// Print the header
|
||||
// Print the version
|
||||
printer.printRecord("2");
|
||||
|
||||
printer.println();
|
||||
|
||||
// Print the header for groups
|
||||
printer.printRecord(DBHelper.LoyaltyCardDbGroups.ID);
|
||||
|
||||
Cursor groupCursor = db.getGroupCursor();
|
||||
|
||||
while(groupCursor.moveToNext())
|
||||
{
|
||||
Group group = Group.toGroup(groupCursor);
|
||||
|
||||
printer.printRecord(group._id);
|
||||
|
||||
if(Thread.currentThread().isInterrupted())
|
||||
{
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
groupCursor.close();
|
||||
|
||||
// Print an empty line
|
||||
printer.println();
|
||||
|
||||
// Print the header for cards
|
||||
printer.printRecord(DBHelper.LoyaltyCardDbIds.ID,
|
||||
DBHelper.LoyaltyCardDbIds.STORE,
|
||||
DBHelper.LoyaltyCardDbIds.NOTE,
|
||||
@@ -28,11 +55,11 @@ public class CsvDatabaseExporter implements DatabaseExporter
|
||||
DBHelper.LoyaltyCardDbIds.BARCODE_TYPE,
|
||||
DBHelper.LoyaltyCardDbIds.STAR_STATUS);
|
||||
|
||||
Cursor cursor = db.getLoyaltyCardCursor();
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor();
|
||||
|
||||
while(cursor.moveToNext())
|
||||
while(cardCursor.moveToNext())
|
||||
{
|
||||
LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cursor);
|
||||
LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cardCursor);
|
||||
|
||||
printer.printRecord(card.id,
|
||||
card.store,
|
||||
@@ -49,7 +76,32 @@ public class CsvDatabaseExporter implements DatabaseExporter
|
||||
}
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
cardCursor.close();
|
||||
|
||||
// Print an empty line
|
||||
printer.println();
|
||||
|
||||
// Print the header for card group mappings
|
||||
printer.printRecord(DBHelper.LoyaltyCardDbIdsGroups.cardID,
|
||||
DBHelper.LoyaltyCardDbIdsGroups.groupID);
|
||||
|
||||
Cursor cardCursor2 = db.getLoyaltyCardCursor();
|
||||
|
||||
while(cardCursor2.moveToNext())
|
||||
{
|
||||
LoyaltyCard card = LoyaltyCard.toLoyaltyCard(cardCursor2);
|
||||
|
||||
for (Group group : db.getLoyaltyCardGroups(card.id)) {
|
||||
printer.printRecord(card.id, group._id);
|
||||
}
|
||||
|
||||
if(Thread.currentThread().isInterrupted())
|
||||
{
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
cardCursor2.close();
|
||||
|
||||
printer.close();
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class for importing a database from CSV (Comma Separate Values)
|
||||
@@ -19,6 +22,34 @@ import java.io.InputStreamReader;
|
||||
public class CsvDatabaseImporter implements DatabaseImporter
|
||||
{
|
||||
public void importData(DBHelper db, InputStreamReader input) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
BufferedReader bufferedReader = new BufferedReader(input);
|
||||
|
||||
bufferedReader.mark(100);
|
||||
|
||||
Integer version = 1;
|
||||
|
||||
try {
|
||||
version = Integer.parseInt(bufferedReader.readLine());
|
||||
} catch (NumberFormatException _e) {
|
||||
// Assume version 1
|
||||
}
|
||||
|
||||
bufferedReader.reset();
|
||||
|
||||
switch (version) {
|
||||
case 1:
|
||||
parseV1(db, bufferedReader);
|
||||
break;
|
||||
case 2:
|
||||
parseV2(db, bufferedReader);
|
||||
break;
|
||||
default:
|
||||
throw new FormatException(String.format("No code to parse version %s", version));
|
||||
}
|
||||
}
|
||||
|
||||
public void parseV1(DBHelper db, BufferedReader input) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
final CSVParser parser = new CSVParser(input, CSVFormat.RFC4180.withHeader());
|
||||
|
||||
@@ -51,6 +82,116 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
}
|
||||
}
|
||||
|
||||
public void parseV2(DBHelper db, BufferedReader input) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
SQLiteDatabase database = db.getWritableDatabase();
|
||||
database.beginTransaction();
|
||||
|
||||
Integer part = 0;
|
||||
String stringPart = "";
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
String tmp = input.readLine();
|
||||
|
||||
if (tmp == null || tmp.isEmpty()) {
|
||||
switch (part) {
|
||||
case 0:
|
||||
// This is the version info, ignore
|
||||
break;
|
||||
case 1:
|
||||
parseV2Groups(db, database, stringPart);
|
||||
break;
|
||||
case 2:
|
||||
parseV2Cards(db, database, stringPart);
|
||||
break;
|
||||
case 3:
|
||||
parseV2CardGroups(db, database, stringPart);
|
||||
break;
|
||||
default:
|
||||
throw new FormatException("Issue parsing CSV data, too many parts for v2 parsing");
|
||||
}
|
||||
|
||||
if (tmp == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
part += 1;
|
||||
stringPart = "";
|
||||
} else {
|
||||
stringPart += tmp + "\n";
|
||||
}
|
||||
}
|
||||
database.setTransactionSuccessful();
|
||||
} catch (FormatException e) {
|
||||
throw new FormatException("Issue parsing CSV data", e);
|
||||
} finally {
|
||||
database.endTransaction();
|
||||
database.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void parseV2Groups(DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
// Parse groups
|
||||
final CSVParser groupParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.withHeader());
|
||||
|
||||
try {
|
||||
for (CSVRecord record : groupParser) {
|
||||
importGroup(database, db, record);
|
||||
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
groupParser.close();
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new FormatException("Issue parsing CSV data", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseV2Cards(DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
// Parse cards
|
||||
final CSVParser cardParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.withHeader());
|
||||
|
||||
try {
|
||||
for (CSVRecord record : cardParser) {
|
||||
importLoyaltyCard(database, db, record);
|
||||
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
cardParser.close();
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new FormatException("Issue parsing CSV data", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseV2CardGroups(DBHelper db, SQLiteDatabase database, String data) throws IOException, FormatException, InterruptedException
|
||||
{
|
||||
// Parse card group mappings
|
||||
final CSVParser cardGroupParser = new CSVParser(new StringReader(data), CSVFormat.RFC4180.withHeader());
|
||||
|
||||
try {
|
||||
for (CSVRecord record : cardGroupParser) {
|
||||
importCardGroupMapping(database, db, record);
|
||||
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
|
||||
cardGroupParser.close();
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new FormatException("Issue parsing CSV data", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a string from the items array. The index into the array
|
||||
* is determined by looking up the index in the fields map using the
|
||||
@@ -145,11 +286,38 @@ public class CsvDatabaseImporter implements DatabaseImporter
|
||||
int starStatus = 0;
|
||||
try {
|
||||
starStatus = extractInt(DBHelper.LoyaltyCardDbIds.STAR_STATUS, record, false);
|
||||
} catch (FormatException _ ) {
|
||||
} catch (FormatException _e ) {
|
||||
// This field did not exist in versions 0.28 and before
|
||||
// We catch this exception so we can still import old backups
|
||||
}
|
||||
if (starStatus != 1) starStatus = 0;
|
||||
helper.insertLoyaltyCard(database, id, store, note, cardId, barcodeType, headerColor, headerTextColor, starStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a single group into the database using the given
|
||||
* session.
|
||||
*/
|
||||
private void importGroup(SQLiteDatabase database, DBHelper helper, CSVRecord record)
|
||||
throws IOException, FormatException
|
||||
{
|
||||
String id = extractString(DBHelper.LoyaltyCardDbGroups.ID, record, null);
|
||||
|
||||
helper.insertGroup(database, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a single card to group mapping into the database using the given
|
||||
* session.
|
||||
*/
|
||||
private void importCardGroupMapping(SQLiteDatabase database, DBHelper helper, CSVRecord record)
|
||||
throws IOException, FormatException
|
||||
{
|
||||
Integer cardId = extractInt(DBHelper.LoyaltyCardDbIdsGroups.cardID, record, false);
|
||||
String groupId = extractString(DBHelper.LoyaltyCardDbIdsGroups.groupID, record, null);
|
||||
|
||||
List<Group> cardGroups = helper.getLoyaltyCardGroups(cardId);
|
||||
cardGroups.add(helper.getGroup(groupId));
|
||||
helper.setLoyaltyCardGroups(database, cardId, cardGroups);
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,26 @@
|
||||
package protect.card_locker;
|
||||
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DBHelper extends SQLiteOpenHelper
|
||||
{
|
||||
public static final String DATABASE_NAME = "Catima.db";
|
||||
public static final int ORIGINAL_DATABASE_VERSION = 1;
|
||||
public static final int DATABASE_VERSION = 4;
|
||||
|
||||
static class LoyaltyCardDbGroups
|
||||
{
|
||||
public static final String TABLE = "groups";
|
||||
public static final String ID = "_id";
|
||||
}
|
||||
|
||||
static class LoyaltyCardDbIds
|
||||
{
|
||||
public static final String TABLE = "cards";
|
||||
@@ -26,6 +34,13 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
public static final String STAR_STATUS = "starstatus";
|
||||
}
|
||||
|
||||
static class LoyaltyCardDbIdsGroups
|
||||
{
|
||||
public static final String TABLE = "cardsGroups";
|
||||
public static final String cardID = "cardId";
|
||||
public static final String groupID = "groupId";
|
||||
}
|
||||
|
||||
public DBHelper(Context context)
|
||||
{
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
@@ -34,7 +49,11 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db)
|
||||
{
|
||||
// create table for gift cards
|
||||
// create table for card groups
|
||||
db.execSQL("create table " + LoyaltyCardDbGroups.TABLE + "(" +
|
||||
LoyaltyCardDbGroups.ID + " TEXT primary key not null)");
|
||||
|
||||
// create table for cards
|
||||
db.execSQL("create table " + LoyaltyCardDbIds.TABLE + "(" +
|
||||
LoyaltyCardDbIds.ID + " INTEGER primary key autoincrement," +
|
||||
LoyaltyCardDbIds.STORE + " TEXT not null," +
|
||||
@@ -44,6 +63,12 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
LoyaltyCardDbIds.CARD_ID + " TEXT not null," +
|
||||
LoyaltyCardDbIds.BARCODE_TYPE + " TEXT not null," +
|
||||
LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0' )");
|
||||
|
||||
// create associative table for cards in groups
|
||||
db.execSQL("create table " + LoyaltyCardDbIdsGroups.TABLE + "(" +
|
||||
LoyaltyCardDbIdsGroups.cardID + " INTEGER," +
|
||||
LoyaltyCardDbIdsGroups.groupID + " TEXT," +
|
||||
"primary key (" + LoyaltyCardDbIdsGroups.cardID + "," + LoyaltyCardDbIdsGroups.groupID +"))");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,12 +89,24 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbIds.HEADER_TEXT_COLOR + " INTEGER");
|
||||
}
|
||||
|
||||
// Upgrade from version 3 to version 4
|
||||
if(oldVersion < 4 && newVersion >= 4)
|
||||
{
|
||||
db.execSQL("ALTER TABLE " + LoyaltyCardDbIds.TABLE
|
||||
+ " ADD COLUMN " + LoyaltyCardDbIds.STAR_STATUS + " INTEGER DEFAULT '0'");
|
||||
}
|
||||
|
||||
// Upgrade from version 4 to version 5
|
||||
if(oldVersion < 5 && newVersion >= 5)
|
||||
{
|
||||
db.execSQL("create table " + LoyaltyCardDbGroups.TABLE + "(" +
|
||||
LoyaltyCardDbGroups.ID + " TEXT primary key not null)");
|
||||
|
||||
db.execSQL("create table " + LoyaltyCardDbIdsGroups.TABLE + "(" +
|
||||
LoyaltyCardDbIdsGroups.cardID + " INTEGER," +
|
||||
LoyaltyCardDbIdsGroups.groupID + " TEXT," +
|
||||
"primary key (" + LoyaltyCardDbIdsGroups.cardID + "," + LoyaltyCardDbIdsGroups.groupID +"))");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +127,8 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
return newId;
|
||||
}
|
||||
|
||||
public boolean insertLoyaltyCard(final SQLiteDatabase db, final int id,
|
||||
final String store, final String note, final String cardId,
|
||||
public boolean insertLoyaltyCard(final SQLiteDatabase db, final int id, final String store,
|
||||
final String note, final String cardId,
|
||||
final String barcodeType, final Integer headerColor,
|
||||
final Integer headerTextColor, final int starStatus)
|
||||
{
|
||||
@@ -108,7 +145,6 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
return (newId != -1);
|
||||
}
|
||||
|
||||
|
||||
public boolean updateLoyaltyCard(final int id, final String store, final String note,
|
||||
final String cardId, final String barcodeType,
|
||||
final Integer headerColor, final Integer headerTextColor)
|
||||
@@ -149,6 +185,7 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
if(data.getCount() == 1)
|
||||
{
|
||||
data.moveToFirst();
|
||||
|
||||
card = LoyaltyCard.toLoyaltyCard(data);
|
||||
}
|
||||
|
||||
@@ -157,12 +194,76 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
return card;
|
||||
}
|
||||
|
||||
public List<Group> getLoyaltyCardGroups(final int id)
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor data = db.rawQuery("select * from " + LoyaltyCardDbGroups.TABLE + " g " +
|
||||
" LEFT JOIN " + LoyaltyCardDbIdsGroups.TABLE + " ig ON ig." + LoyaltyCardDbIdsGroups.groupID + " = g." + LoyaltyCardDbGroups.ID +
|
||||
" where " + LoyaltyCardDbIdsGroups.cardID + "=?" +
|
||||
" ORDER BY " + LoyaltyCardDbIdsGroups.groupID, new String[]{String.format("%d", id)});
|
||||
|
||||
List<Group> groups = new ArrayList<>();
|
||||
|
||||
if (!data.moveToFirst()) {
|
||||
return groups;
|
||||
}
|
||||
|
||||
groups.add(Group.toGroup(data));
|
||||
|
||||
while (data.moveToNext()) {
|
||||
groups.add(Group.toGroup(data));
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
public void setLoyaltyCardGroups(final int id, List<Group> groups)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
|
||||
// First delete lookup table entries associated with this card
|
||||
db.delete(LoyaltyCardDbIdsGroups.TABLE,
|
||||
LoyaltyCardDbIdsGroups.cardID + " = ? ",
|
||||
new String[]{String.format("%d", id)});
|
||||
|
||||
// Then create entries for selected values
|
||||
for (Group group : groups) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbIdsGroups.cardID, id);
|
||||
contentValues.put(LoyaltyCardDbIdsGroups.groupID, group._id);
|
||||
db.insert(LoyaltyCardDbIdsGroups.TABLE, null, contentValues);
|
||||
}
|
||||
}
|
||||
|
||||
public void setLoyaltyCardGroups(final SQLiteDatabase db, final int id, List<Group> groups)
|
||||
{
|
||||
// First delete lookup table entries associated with this card
|
||||
db.delete(LoyaltyCardDbIdsGroups.TABLE,
|
||||
LoyaltyCardDbIdsGroups.cardID + " = ? ",
|
||||
new String[]{String.format("%d", id)});
|
||||
|
||||
// Then create entries for selected values
|
||||
for (Group group : groups) {
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbIdsGroups.cardID, id);
|
||||
contentValues.put(LoyaltyCardDbIdsGroups.groupID, group._id);
|
||||
db.insert(LoyaltyCardDbIdsGroups.TABLE, null, contentValues);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean deleteLoyaltyCard (final int id)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
int rowsDeleted = db.delete(LoyaltyCardDbIds.TABLE,
|
||||
// Delete card
|
||||
int rowsDeleted = db.delete(LoyaltyCardDbIds.TABLE,
|
||||
LoyaltyCardDbIds.ID + " = ? ",
|
||||
new String[]{String.format("%d", id)});
|
||||
|
||||
// And delete lookup table entries associated with this card
|
||||
db.delete(LoyaltyCardDbIdsGroups.TABLE,
|
||||
LoyaltyCardDbIdsGroups.cardID + " = ? ",
|
||||
new String[]{String.format("%d", id)});
|
||||
|
||||
return (rowsDeleted == 1);
|
||||
}
|
||||
|
||||
@@ -179,16 +280,52 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
* @return Cursor
|
||||
*/
|
||||
public Cursor getLoyaltyCardCursor(final String filter)
|
||||
{
|
||||
return getLoyaltyCardCursor(filter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor to all loyalty cards with the filter text in either the store or note in a certain group.
|
||||
*
|
||||
* @param filter
|
||||
* @param group
|
||||
* @return Cursor
|
||||
*/
|
||||
public Cursor getLoyaltyCardCursor(final String filter, Group group)
|
||||
{
|
||||
String actualFilter = String.format("%%%s%%", filter);
|
||||
String[] selectionArgs = { actualFilter, actualFilter };
|
||||
StringBuilder groupFilter = new StringBuilder();
|
||||
String limitString = "";
|
||||
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
|
||||
if (group != null) {
|
||||
List<Integer> allowedIds = getGroupCardIds(group._id);
|
||||
|
||||
// Empty group
|
||||
if (allowedIds.size() > 0) {
|
||||
groupFilter.append("AND (");
|
||||
|
||||
for (int i = 0; i < allowedIds.size(); i++) {
|
||||
groupFilter.append(LoyaltyCardDbIds.ID + " = " + allowedIds.get(i));
|
||||
if (i != allowedIds.size() - 1) {
|
||||
groupFilter.append(" OR ");
|
||||
}
|
||||
}
|
||||
groupFilter.append(") ");
|
||||
} else {
|
||||
limitString = "LIMIT 0";
|
||||
}
|
||||
}
|
||||
|
||||
Cursor res = db.rawQuery("select * from " + LoyaltyCardDbIds.TABLE +
|
||||
" WHERE " + LoyaltyCardDbIds.STORE + " LIKE ? " +
|
||||
" OR " + LoyaltyCardDbIds.NOTE + " LIKE ? " +
|
||||
" ORDER BY " + LoyaltyCardDbIds.STAR_STATUS + " DESC," + LoyaltyCardDbIds.STORE + " COLLATE NOCASE ASC", selectionArgs, null);
|
||||
" WHERE (" + LoyaltyCardDbIds.STORE + " LIKE ? " +
|
||||
" OR " + LoyaltyCardDbIds.NOTE + " LIKE ? )" +
|
||||
groupFilter.toString() +
|
||||
" ORDER BY " + LoyaltyCardDbIds.STAR_STATUS + " DESC," + LoyaltyCardDbIds.STORE + " COLLATE NOCASE ASC " +
|
||||
limitString, selectionArgs, null);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -227,5 +364,172 @@ public class DBHelper extends SQLiteOpenHelper
|
||||
|
||||
return numItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor to all groups.
|
||||
*
|
||||
* @return Cursor
|
||||
*/
|
||||
public Cursor getGroupCursor()
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
|
||||
Cursor res = db.rawQuery("select * from " + LoyaltyCardDbGroups.TABLE +
|
||||
" ORDER BY " + LoyaltyCardDbGroups.ID + " COLLATE NOCASE ASC", null, null);
|
||||
return res;
|
||||
}
|
||||
|
||||
public List<Group> getGroups() {
|
||||
Cursor data = getGroupCursor();
|
||||
|
||||
List<Group> groups = new ArrayList<>();
|
||||
|
||||
if (!data.moveToFirst()) {
|
||||
return groups;
|
||||
}
|
||||
|
||||
groups.add(Group.toGroup(data));
|
||||
|
||||
while (data.moveToNext()) {
|
||||
groups.add(Group.toGroup(data));
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
public Group getGroup(final String groupName)
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor data = db.rawQuery("select * from " + LoyaltyCardDbGroups.TABLE +
|
||||
" where " + LoyaltyCardDbGroups.ID + "=?", new String[]{groupName});
|
||||
|
||||
Group group = null;
|
||||
|
||||
if(data.getCount() == 1)
|
||||
{
|
||||
data.moveToFirst();
|
||||
|
||||
group = Group.toGroup(data);
|
||||
}
|
||||
|
||||
data.close();
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
public int getGroupCount()
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor data = db.rawQuery("SELECT Count(*) FROM " + LoyaltyCardDbGroups.TABLE, null);
|
||||
|
||||
int numItems = 0;
|
||||
|
||||
if(data.getCount() == 1)
|
||||
{
|
||||
data.moveToFirst();
|
||||
numItems = data.getInt(0);
|
||||
}
|
||||
|
||||
data.close();
|
||||
|
||||
return numItems;
|
||||
}
|
||||
|
||||
public List<Integer> getGroupCardIds(final String groupName)
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
Cursor data = db.rawQuery("SELECT " + LoyaltyCardDbIdsGroups.cardID +
|
||||
" FROM " + LoyaltyCardDbIdsGroups.TABLE +
|
||||
" WHERE " + LoyaltyCardDbIdsGroups.groupID + " =? ", new String[]{groupName});
|
||||
|
||||
List<Integer> cardIds = new ArrayList<>();
|
||||
|
||||
if (!data.moveToFirst()) {
|
||||
return cardIds;
|
||||
}
|
||||
|
||||
cardIds.add(data.getInt(0));
|
||||
|
||||
while (data.moveToNext()) {
|
||||
cardIds.add(data.getInt(0));
|
||||
}
|
||||
|
||||
data.close();
|
||||
|
||||
return cardIds;
|
||||
}
|
||||
|
||||
public long insertGroup(final String name)
|
||||
{
|
||||
if (name.isEmpty()) return -1;
|
||||
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbGroups.ID, name);
|
||||
final long newId = db.insert(LoyaltyCardDbGroups.TABLE, null, contentValues);
|
||||
return newId;
|
||||
}
|
||||
|
||||
public boolean insertGroup(final SQLiteDatabase db, final String name)
|
||||
{
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbGroups.ID, name);
|
||||
final long newId = db.insert(LoyaltyCardDbGroups.TABLE, null, contentValues);
|
||||
return (newId != -1);
|
||||
}
|
||||
|
||||
public boolean updateGroup(final String groupName, final String newName)
|
||||
{
|
||||
if (newName.isEmpty()) return false;
|
||||
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(LoyaltyCardDbGroups.ID, newName);
|
||||
try {
|
||||
int rowsUpdated = db.update(LoyaltyCardDbGroups.TABLE, contentValues,
|
||||
LoyaltyCardDbGroups.ID + "=?",
|
||||
new String[]{groupName});
|
||||
return (rowsUpdated == 1);
|
||||
} catch (android.database.sqlite.SQLiteConstraintException _e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean deleteGroup(final String groupName)
|
||||
{
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
// Delete group
|
||||
int rowsDeleted = db.delete(LoyaltyCardDbGroups.TABLE,
|
||||
LoyaltyCardDbGroups.ID + " = ? ",
|
||||
new String[]{groupName});
|
||||
|
||||
// And delete lookup table entries associated with this group
|
||||
db.delete(LoyaltyCardDbIdsGroups.TABLE,
|
||||
LoyaltyCardDbIdsGroups.groupID + " = ? ",
|
||||
new String[]{groupName});
|
||||
|
||||
return (rowsDeleted == 1);
|
||||
}
|
||||
|
||||
public int getGroupCardCount(final String groupName)
|
||||
{
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
|
||||
Cursor data = db.rawQuery("SELECT Count(*) FROM " + LoyaltyCardDbIdsGroups.TABLE +
|
||||
" where " + LoyaltyCardDbIdsGroups.groupID + "=?",
|
||||
new String[]{groupName});
|
||||
|
||||
int numItems = 0;
|
||||
|
||||
if(data.getCount() == 1)
|
||||
{
|
||||
data.moveToFirst();
|
||||
numItems = data.getInt(0);
|
||||
}
|
||||
|
||||
data.close();
|
||||
|
||||
return numItems;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
app/src/main/java/protect/card_locker/Group.java
Normal file
20
app/src/main/java/protect/card_locker/Group.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
public class Group
|
||||
{
|
||||
public final String _id;
|
||||
|
||||
public Group(final String _id)
|
||||
{
|
||||
this._id = _id;
|
||||
}
|
||||
|
||||
public static Group toGroup(Cursor cursor)
|
||||
{
|
||||
String _id = cursor.getString(cursor.getColumnIndexOrThrow(DBHelper.LoyaltyCardDbGroups.ID));
|
||||
|
||||
return new Group(_id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CursorAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import protect.card_locker.preferences.Settings;
|
||||
|
||||
class GroupCursorAdapter extends CursorAdapter
|
||||
{
|
||||
Settings settings;
|
||||
DBHelper db;
|
||||
|
||||
public GroupCursorAdapter(Context context, Cursor cursor)
|
||||
{
|
||||
super(context, cursor, 0);
|
||||
settings = new Settings(context);
|
||||
|
||||
db = new DBHelper(context);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
return LayoutInflater.from(context).inflate(R.layout.group_layout, parent, false);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
// Find fields to populate in inflated template
|
||||
TextView nameField = (TextView) view.findViewById(R.id.name);
|
||||
TextView countField = (TextView) view.findViewById(R.id.cardCount);
|
||||
|
||||
// Extract properties from cursor
|
||||
Group group = Group.toGroup(cursor);
|
||||
|
||||
// Populate fields with extracted properties
|
||||
nameField.setText(group._id);
|
||||
countField.setText(String.format(context.getString(R.string.groupCardCount), db.getGroupCardCount(group._id)));
|
||||
|
||||
nameField.setTextSize(settings.getCardTitleListFontSize());
|
||||
countField.setTextSize(settings.getCardNoteListFontSize());
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class LoyaltyCard
|
||||
@@ -20,7 +21,8 @@ public class LoyaltyCard
|
||||
public final int starStatus;
|
||||
|
||||
public LoyaltyCard(final int id, final String store, final String note, final String cardId,
|
||||
final String barcodeType, final Integer headerColor, final Integer headerTextColor,final int starStatus)
|
||||
final String barcodeType, final Integer headerColor, final Integer headerTextColor,
|
||||
final int starStatus)
|
||||
{
|
||||
this.id = id;
|
||||
this.store = store;
|
||||
|
||||
@@ -9,6 +9,8 @@ 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;
|
||||
@@ -33,6 +35,8 @@ import com.jaredrummler.android.colorpicker.ColorPickerDialog;
|
||||
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
{
|
||||
@@ -43,6 +47,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
|
||||
EditText storeFieldEdit;
|
||||
EditText noteFieldEdit;
|
||||
ChipGroup groupsChips;
|
||||
ImageView headingColorSample;
|
||||
Button headingColorSelectButton;
|
||||
ImageView headingStoreTextColorSample;
|
||||
@@ -99,6 +104,7 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
|
||||
storeFieldEdit = findViewById(R.id.storeNameEdit);
|
||||
noteFieldEdit = findViewById(R.id.noteEdit);
|
||||
groupsChips = findViewById(R.id.groupChips);
|
||||
headingColorSample = findViewById(R.id.headingColorSample);
|
||||
headingColorSelectButton = findViewById(R.id.headingColorSelectButton);
|
||||
headingStoreTextColorSample = findViewById(R.id.headingStoreTextColorSample);
|
||||
@@ -213,6 +219,40 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
hideBarcode();
|
||||
}
|
||||
|
||||
if(groupsChips.getChildCount() == 0)
|
||||
{
|
||||
List<Group> existingGroups = db.getGroups();
|
||||
|
||||
List<Group> loyaltyCardGroups = db.getLoyaltyCardGroups(loyaltyCardId);
|
||||
|
||||
View groupsView = findViewById(R.id.groupsView);
|
||||
View groupsTableRow = findViewById(R.id.groupsTableRow);
|
||||
|
||||
if (existingGroups.isEmpty()) {
|
||||
groupsView.setVisibility(View.GONE);
|
||||
groupsTableRow.setVisibility(View.GONE);
|
||||
} else {
|
||||
groupsView.setVisibility(View.VISIBLE);
|
||||
groupsTableRow.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
for (Group group : db.getGroups()) {
|
||||
Chip chip = (Chip) getLayoutInflater().inflate(R.layout.layout_chip_choice, groupsChips, false);
|
||||
chip.setText(group._id);
|
||||
chip.setTag(group);
|
||||
|
||||
chip.setChecked(false);
|
||||
for (Group loyaltyCardGroup : loyaltyCardGroups) {
|
||||
if (loyaltyCardGroup._id.equals(group._id)) {
|
||||
chip.setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
groupsChips.addView(chip);
|
||||
}
|
||||
}
|
||||
|
||||
if(headingColorValue == null)
|
||||
{
|
||||
// Select a random color to start out with.
|
||||
@@ -404,6 +444,13 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
return;
|
||||
}
|
||||
|
||||
List<Group> selectedGroups = new ArrayList<>();
|
||||
|
||||
for (Integer chipId : groupsChips.getCheckedChipIds()) {
|
||||
Chip chip = groupsChips.findViewById(chipId);
|
||||
selectedGroups.add((Group) chip.getTag());
|
||||
}
|
||||
|
||||
if(updateLoyaltyCard)
|
||||
{ //update of "starStatus" not necessary, since it cannot be changed in this activity (only in ViewActivity)
|
||||
db.updateLoyaltyCard(loyaltyCardId, store, note, cardId, barcodeType, headingColorValue, headingStoreTextColorValue);
|
||||
@@ -414,6 +461,8 @@ public class LoyaltyCardEditActivity extends AppCompatActivity
|
||||
loyaltyCardId = (int)db.insertLoyaltyCard(store, note, cardId, barcodeType, headingColorValue, headingStoreTextColorValue, 0);
|
||||
}
|
||||
|
||||
db.setLoyaltyCardGroups(loyaltyCardId, selectedGroups);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package protect.card_locker;
|
||||
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.graphics.Color;
|
||||
@@ -34,7 +33,6 @@ import com.google.zxing.BarcodeFormat;
|
||||
|
||||
import protect.card_locker.preferences.Settings;
|
||||
|
||||
|
||||
public class LoyaltyCardViewActivity extends AppCompatActivity
|
||||
{
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
@@ -11,6 +11,10 @@ import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
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.Menu;
|
||||
@@ -22,13 +26,12 @@ import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import protect.card_locker.preferences.SettingsActivity;
|
||||
|
||||
@@ -39,6 +42,7 @@ public class MainActivity extends AppCompatActivity
|
||||
|
||||
private Menu menu;
|
||||
protected String filter = "";
|
||||
protected int selectedTab = 0;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
@@ -48,7 +52,26 @@ public class MainActivity extends AppCompatActivity
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
updateLoyaltyCardList("");
|
||||
updateLoyaltyCardList(filter, 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());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,7 +87,22 @@ public class MainActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
updateLoyaltyCardList(filter);
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
boolean hasReset = updateTabGroups(groupsTabLayout);
|
||||
|
||||
Object group = null;
|
||||
|
||||
if (groupsTabLayout.getTabCount() != 0) {
|
||||
TabLayout.Tab tab = groupsTabLayout.getTabAt(0);
|
||||
|
||||
if (!hasReset) {
|
||||
tab = groupsTabLayout.getTabAt(selectedTab);
|
||||
}
|
||||
|
||||
groupsTabLayout.selectTab(tab);
|
||||
group = tab.getTag();
|
||||
}
|
||||
updateLoyaltyCardList(filter, group);
|
||||
|
||||
FloatingActionButton addButton = findViewById(R.id.fabAdd);
|
||||
addButton.setOnClickListener(new View.OnClickListener() {
|
||||
@@ -109,17 +147,31 @@ public class MainActivity extends AppCompatActivity
|
||||
if (!searchView.isIconified()) {
|
||||
searchView.setIconified(true);
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
|
||||
if (groupsTabLayout.getVisibility() == View.VISIBLE && selectedTab != 0) {
|
||||
selectedTab = 0;
|
||||
groupsTabLayout.selectTab(groupsTabLayout.getTabAt(0));
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLoyaltyCardList(String filterText)
|
||||
private void updateLoyaltyCardList(String filterText, Object tag)
|
||||
{
|
||||
Group group = null;
|
||||
if (tag != null) {
|
||||
group = (Group) tag;
|
||||
}
|
||||
|
||||
final ListView cardList = findViewById(R.id.list);
|
||||
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);
|
||||
|
||||
if(db.getLoyaltyCardCount() > 0)
|
||||
{
|
||||
// We want the cardList to be visible regardless of the filtered match count
|
||||
@@ -127,7 +179,7 @@ public class MainActivity extends AppCompatActivity
|
||||
// the keyboard
|
||||
cardList.setVisibility(View.VISIBLE);
|
||||
helpText.setVisibility(View.GONE);
|
||||
if(db.getLoyaltyCardCount(filterText) > 0)
|
||||
if(cardCursor.getCount() > 0)
|
||||
{
|
||||
noMatchingCardsText.setVisibility(View.GONE);
|
||||
}
|
||||
@@ -143,8 +195,6 @@ public class MainActivity extends AppCompatActivity
|
||||
noMatchingCardsText.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
Cursor cardCursor = db.getLoyaltyCardCursor(filterText);
|
||||
|
||||
final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor);
|
||||
cardList.setAdapter(adapter);
|
||||
|
||||
@@ -171,6 +221,53 @@ public class MainActivity extends AppCompatActivity
|
||||
});
|
||||
}
|
||||
|
||||
public boolean updateTabGroups(TabLayout groupsTabLayout)
|
||||
{
|
||||
final DBHelper db = new DBHelper(this);
|
||||
|
||||
List<Group> newGroups = db.getGroups();
|
||||
|
||||
if (newGroups.size() == 0) {
|
||||
groupsTabLayout.removeAllTabs();
|
||||
groupsTabLayout.setVisibility(View.GONE);
|
||||
return true;
|
||||
}
|
||||
|
||||
// -1 because there is an "All" tab
|
||||
boolean isChanged = groupsTabLayout.getTabCount() - 1 != newGroups.size();
|
||||
|
||||
if (!isChanged) {
|
||||
for (int i = 0; i < newGroups.size(); i++) {
|
||||
if (!((Group) groupsTabLayout.getTabAt(i + 1).getTag())._id.equals(newGroups.get(i)._id)) {
|
||||
isChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isChanged) {
|
||||
groupsTabLayout.removeAllTabs();
|
||||
|
||||
TabLayout.Tab allTab = groupsTabLayout.newTab();
|
||||
allTab.setText(R.string.all);
|
||||
allTab.setTag(null);
|
||||
groupsTabLayout.addTab(allTab);
|
||||
|
||||
for (Group group : newGroups) {
|
||||
TabLayout.Tab tab = groupsTabLayout.newTab();
|
||||
tab.setText(group._id);
|
||||
tab.setTag(group);
|
||||
groupsTabLayout.addTab(tab);
|
||||
}
|
||||
|
||||
groupsTabLayout.setVisibility(View.VISIBLE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
|
||||
{
|
||||
@@ -240,7 +337,10 @@ public class MainActivity extends AppCompatActivity
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
filter = newText;
|
||||
updateLoyaltyCardList(newText);
|
||||
|
||||
TabLayout groupsTabLayout = findViewById(R.id.groups);
|
||||
|
||||
updateLoyaltyCardList(newText, groupsTabLayout.getTabAt(groupsTabLayout.getSelectedTabPosition()).getTag());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -254,6 +354,13 @@ public class MainActivity extends AppCompatActivity
|
||||
{
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == R.id.action_manage_groups)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), ManageGroupsActivity.class);
|
||||
startActivityForResult(i, MAIN_REQUEST_CODE);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(id == R.id.action_import_export)
|
||||
{
|
||||
Intent i = new Intent(getApplicationContext(), ImportExportActivity.class);
|
||||
|
||||
186
app/src/main/java/protect/card_locker/ManageGroupsActivity.java
Normal file
186
app/src/main/java/protect/card_locker/ManageGroupsActivity.java
Normal file
@@ -0,0 +1,186 @@
|
||||
package protect.card_locker;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
public class ManageGroupsActivity extends AppCompatActivity
|
||||
{
|
||||
private static final String TAG = "Catima";
|
||||
|
||||
private AlertDialog newGroupDialog;
|
||||
private final DBHelper db = new DBHelper(this);
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.manage_groups_activity);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar != null)
|
||||
{
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
newGroupDialog = createNewGroupDialog();
|
||||
|
||||
updateGroupList();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
updateGroupList();
|
||||
|
||||
FloatingActionButton addButton = findViewById(R.id.fabAdd);
|
||||
addButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
newGroupDialog.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
private void updateGroupList()
|
||||
{
|
||||
final ListView groupList = findViewById(R.id.list);
|
||||
final TextView helpText = findViewById(R.id.helpText);
|
||||
final DBHelper db = new DBHelper(this);
|
||||
|
||||
if(db.getGroupCount() > 0)
|
||||
{
|
||||
groupList.setVisibility(View.VISIBLE);
|
||||
helpText.setVisibility(View.GONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
groupList.setVisibility(View.GONE);
|
||||
helpText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
Cursor groupCursor = db.getGroupCursor();
|
||||
|
||||
final GroupCursorAdapter adapter = new GroupCursorAdapter(this, groupCursor);
|
||||
groupList.setAdapter(adapter);
|
||||
|
||||
registerForContextMenu(groupList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == android.R.id.home) {
|
||||
finish();
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public void editGroup(View view) {
|
||||
LinearLayout parentRow = (LinearLayout) view.getParent();
|
||||
|
||||
TextView groupNameTextView = (TextView) parentRow.findViewById(R.id.name);
|
||||
|
||||
final String groupName = (String) groupNameTextView.getText();
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.enter_group_name);
|
||||
final EditText input = new EditText(this);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
input.setText(groupName);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
db.updateGroup(groupName, input.getText().toString());
|
||||
updateGroupList();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public void deleteGroup(View view) {
|
||||
LinearLayout parentRow = (LinearLayout) view.getParent();
|
||||
|
||||
TextView groupNameTextView = (TextView) parentRow.findViewById(R.id.name);
|
||||
|
||||
final String groupName = (String) groupNameTextView.getText();
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.deleteConfirmationGroup);
|
||||
builder.setMessage(groupName);
|
||||
|
||||
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
db.deleteGroup(groupName);
|
||||
updateGroupList();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private AlertDialog createNewGroupDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.enter_group_name);
|
||||
final EditText input = new EditText(this);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
db.insertGroup(input.getText().toString());
|
||||
updateGroupList();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.cancel();
|
||||
}
|
||||
});
|
||||
AlertDialog dialog = builder.create();
|
||||
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
BIN
app/src/main/res/drawable-hdpi/ic_folder_white.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_folder_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 B |
BIN
app/src/main/res/drawable-mdpi/ic_folder_white.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_folder_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 135 B |
BIN
app/src/main/res/drawable-xhdpi/ic_folder_white.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_folder_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 207 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_folder_white.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_folder_white.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 252 B |
68
app/src/main/res/layout/group_layout.xml
Normal file
68
app/src/main/res/layout/group_layout.xml
Normal file
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:baselineAligned="false"
|
||||
android:padding="@dimen/activity_margin">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/valueLayout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="visible">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/storeNameTextSize"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cardCount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:textSize="@dimen/noteTextSize"/>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/edit"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
android:src="@drawable/ic_mode_edit_white_24dp"
|
||||
android:contentDescription="@string/edit"
|
||||
app:tint="#000000"
|
||||
android:onClick="editGroup" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/delete"
|
||||
android:layout_width="@dimen/cardThumbnailSize"
|
||||
android:layout_height="@dimen/cardThumbnailSize"
|
||||
android:layout_marginLeft="@dimen/activity_margin"
|
||||
android:src="@drawable/ic_delete_white_24dp"
|
||||
android:contentDescription="@string/delete"
|
||||
app:tint="#000000"
|
||||
android:onClick="deleteGroup"/>
|
||||
|
||||
</LinearLayout>
|
||||
25
app/src/main/res/layout/group_main.xml
Normal file
25
app/src/main/res/layout/group_main.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
tools:context="protect.card_locker.MainActivity"
|
||||
tools:showIn="@layout/main_activity">
|
||||
|
||||
<TextView
|
||||
style="@style/AppTheme.TextView.NoData"
|
||||
android:id="@+id/helpText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/noGroups"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ListView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/list"
|
||||
android:visibility="gone"/>
|
||||
</RelativeLayout>
|
||||
9
app/src/main/res/layout/layout_chip_choice.xml
Normal file
9
app/src/main/res/layout/layout_chip_choice.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
style="@style/Widget.MaterialComponents.Chip.Choice"
|
||||
app:checkedIconVisible="true"
|
||||
android:textAppearance="?android:attr/textAppearance" />
|
||||
@@ -145,6 +145,62 @@
|
||||
android:background="@color/inputBorder" />
|
||||
</TableRow>
|
||||
|
||||
<!-- Groups -->
|
||||
<View
|
||||
android:id="@+id/groupsView"
|
||||
android:layout_height="@dimen/inputBorderThickness"
|
||||
android:layout_width="match_parent"
|
||||
android:background="@color/inputBorder"
|
||||
android:visibility="gone"/>
|
||||
<TableRow
|
||||
android:id="@+id/groupsTableRow"
|
||||
android:background="@color/inputBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone">
|
||||
<View
|
||||
android:gravity="start"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_weight="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="@dimen/inputPadding"
|
||||
android:paddingEnd="@dimen/inputPadding">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/groupsField"
|
||||
android:text="@string/groups"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
/>
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/groupChips"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:padding="@dimen/inputPadding"
|
||||
android:textSize="@dimen/inputSize"
|
||||
android:layout_toEndOf="@id/groupsField"
|
||||
android:layout_toRightOf="@id/groupsField"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
|
||||
<View
|
||||
android:gravity="end"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="@dimen/inputBorderThickness"
|
||||
android:background="@color/inputBorder" />
|
||||
</TableRow>
|
||||
|
||||
|
||||
<!-- Store Header Background Color -->
|
||||
<View
|
||||
android:layout_height="@dimen/inputBorderThickness"
|
||||
@@ -432,11 +488,13 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/barcodeCaptureLayout">
|
||||
<Button android:id="@+id/captureButton"
|
||||
android:layout_margin="@dimen/inputMargin"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/capture"
|
||||
android:layout_weight="1.0"/>
|
||||
<Button android:id="@+id/enterButton"
|
||||
android:layout_margin="@dimen/inputMargin"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/enterCard"
|
||||
|
||||
@@ -29,6 +29,13 @@
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/groups"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabMode="scrollable"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<include layout="@layout/content_main"/>
|
||||
|
||||
36
app/src/main/res/layout/manage_groups_activity.xml
Normal file
36
app/src/main/res/layout/manage_groups_activity.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context="protect.card_locker.MainActivity">
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fabAdd"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:src="@drawable/ic_add_white_24dp"
|
||||
android:contentDescription="@string/action_add"
|
||||
android:layout_margin="16dp" />
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<include layout="@layout/group_main"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -8,6 +8,11 @@
|
||||
android:icon="@drawable/ic_search_white"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:showAsAction="always|collapseActionView"/>
|
||||
<item
|
||||
android:id="@+id/action_manage_groups"
|
||||
android:icon="@drawable/ic_folder_white"
|
||||
android:title="@string/groups"
|
||||
app:showAsAction="always"/>
|
||||
<item
|
||||
android:id="@+id/action_import_export"
|
||||
android:icon="@drawable/ic_import_export_white_24dp"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<resources>>
|
||||
|
||||
<style name="AppTheme.NoActionBar">
|
||||
<style name="AppTheme.NoActionBar" parent="AppTheme">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
<dimen name="inputBorderThickness">2dip</dimen>
|
||||
<dimen name="inputBorderDividerThickness">4dip</dimen>
|
||||
<dimen name="inputMargin">2dip</dimen>
|
||||
<dimen name="inputPadding">20dip</dimen>
|
||||
<dimen name="colorSamplePadding">10dip</dimen>
|
||||
<dimen name="inputSize">18sp</dimen>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<string name="action_add">Add</string>
|
||||
|
||||
<string name="noGiftCards">You don\'t have any cards at the moment. Click the "+" (plus) button to get started.\n\nCatima lets you carry your cards on your phone, so they are always within reach.</string>
|
||||
<string name="noMatchingGiftCards">No cards match the search filter. Please try some different terms.</string>
|
||||
<string name="noMatchingGiftCards">No cards match the filter. Please try some different terms.</string>
|
||||
|
||||
<string name="storeName">Store</string>
|
||||
<string name="note">Note</string>
|
||||
@@ -123,4 +123,11 @@
|
||||
<string name="intent_import_card_from_url_path_prefix_old" translatable="false">/loyalty-card-locker/share</string>
|
||||
<string name="importSuccessful">Successfully imported loyalty card data</string>
|
||||
<string name="exportSuccessful">Successfully exported loyalty card data</string>
|
||||
|
||||
<string name="enter_group_name">Enter group name</string>
|
||||
<string name="groups">Groups</string>
|
||||
<string name="noGroups">You don\'t have any groups at the moment. Click the "+" (plus) button to get started.\n\nCards can be assigned to groups to make them easier to find.</string>
|
||||
<string name="groupCardCount"><xliff:g>%d</xliff:g> cards</string>
|
||||
<string name="all">All</string>
|
||||
<string name="deleteConfirmationGroup">Please confirm you want to delete this group</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorSecondary">@color/colorSecondary</item>
|
||||
<item name="colorAccent">@color/colorSecondary</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar">
|
||||
<style name="AppTheme.NoActionBar" parent="AppTheme">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
|
||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.MaterialComponents.Dark.ActionBar"/>
|
||||
|
||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
|
||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.MaterialComponents.Light"/>
|
||||
|
||||
<style name="CardView.ActionBarTheme" parent="@style/ThemeOverlay.AppCompat.ActionBar">
|
||||
<style name="CardView.ActionBarTheme" parent="@style/ThemeOverlay.MaterialComponents.ActionBar">
|
||||
<!-- THIS is where you can color the arrow! -->
|
||||
<item name="colorControlNormal">@android:color/white</item>
|
||||
</style>
|
||||
|
||||
@@ -15,7 +15,11 @@ import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -101,8 +105,6 @@ public class DatabaseTest
|
||||
assertEquals(BarcodeFormat.UPC_A.toString(), loyaltyCard.barcodeType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void updateMissingGiftCard()
|
||||
{
|
||||
@@ -256,6 +258,161 @@ public class DatabaseTest
|
||||
return (int)newId;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addRemoveOneGroup()
|
||||
{
|
||||
assertEquals(0, db.getGroupCount());
|
||||
long id = db.insertGroup("group one");
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
|
||||
Group group = db.getGroup("group one");
|
||||
assertNotNull(group);
|
||||
assertEquals("group one", group._id);
|
||||
|
||||
result = db.deleteGroup("group one");
|
||||
assertTrue(result);
|
||||
assertEquals(0, db.getGroupCount());
|
||||
assertNull(db.getGroup("group one"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateGroup()
|
||||
{
|
||||
long id = db.insertGroup("group one");
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
|
||||
result = db.updateGroup("group one", "group one renamed");
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
|
||||
// Group one no longer exists
|
||||
Group group = db.getGroup("group one");
|
||||
assertNull(group);
|
||||
|
||||
// But group one renamed does
|
||||
Group group2 = db.getGroup("group one renamed");
|
||||
assertNotNull(group2);
|
||||
assertEquals("group one renamed", group2._id);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateMissingGroup()
|
||||
{
|
||||
assertEquals(0, db.getGroupCount());
|
||||
|
||||
boolean result = db.updateGroup("group one", "new name");
|
||||
assertEquals(false, result);
|
||||
assertEquals(0, db.getGroupCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyGroupValues()
|
||||
{
|
||||
long id = db.insertGroup("");
|
||||
boolean result = (id != -1);
|
||||
assertFalse(result);
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void duplicateGroupName()
|
||||
{
|
||||
assertEquals(0, db.getGroupCount());
|
||||
long id = db.insertGroup("group one");
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
|
||||
Group group = db.getGroup("group one");
|
||||
assertNotNull(group);
|
||||
assertEquals("group one", group._id);
|
||||
|
||||
// Should fail on duplicate
|
||||
long id2 = db.insertGroup("group one");
|
||||
boolean result2 = (id2 != -1);
|
||||
assertFalse(result2);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateGroupDuplicate()
|
||||
{
|
||||
long id = db.insertGroup("group one");
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getGroupCount());
|
||||
|
||||
long id2 = db.insertGroup("group two");
|
||||
boolean result2 = (id2 != -1);
|
||||
assertTrue(result2);
|
||||
assertEquals(2, db.getGroupCount());
|
||||
|
||||
// Should fail when trying to rename group two to one
|
||||
boolean result3 = db.updateGroup("group two", "group one");
|
||||
assertFalse(result3);
|
||||
assertEquals(2, db.getGroupCount());
|
||||
|
||||
// Rename failed so both should still be the same
|
||||
Group group = db.getGroup("group one");
|
||||
assertNotNull(group);
|
||||
assertEquals("group one", group._id);
|
||||
|
||||
Group group2 = db.getGroup("group two");
|
||||
assertNotNull(group2);
|
||||
assertEquals("group two", group2._id);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cardAddAndRemoveGroups()
|
||||
{
|
||||
// Create card
|
||||
assertEquals(0, db.getLoyaltyCardCount());
|
||||
long id = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString(), DEFAULT_HEADER_COLOR, DEFAULT_HEADER_TEXT_COLOR, 0);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
assertEquals(1, db.getLoyaltyCardCount());
|
||||
|
||||
// Create two groups to only one card
|
||||
assertEquals(0, db.getGroupCount());
|
||||
long gid = db.insertGroup("one");
|
||||
boolean gresult = (gid != -1);
|
||||
assertTrue(gresult);
|
||||
|
||||
long gid2 = db.insertGroup("two");
|
||||
boolean gresult2 = (gid2 != -1);
|
||||
assertTrue(gresult2);
|
||||
|
||||
assertEquals(2, db.getGroupCount());
|
||||
|
||||
Group group1 = db.getGroup("one");
|
||||
|
||||
// Card has no groups by default
|
||||
List<Group> cardGroups = db.getLoyaltyCardGroups(1);
|
||||
assertEquals(0, cardGroups.size());
|
||||
|
||||
// Add one groups to card
|
||||
List<Group> groupList1 = new ArrayList<>();
|
||||
groupList1.add(group1);
|
||||
db.setLoyaltyCardGroups(1, groupList1);
|
||||
|
||||
List<Group> cardGroups1 = db.getLoyaltyCardGroups(1);
|
||||
assertEquals(1, cardGroups1.size());
|
||||
assertEquals(cardGroups1.get(0)._id, group1._id);
|
||||
assertEquals(1, db.getGroupCardCount("one"));
|
||||
assertEquals(0, db.getGroupCardCount("two"));
|
||||
|
||||
// Remove groups
|
||||
db.setLoyaltyCardGroups(1, new ArrayList<Group>());
|
||||
List<Group> cardGroups2 = db.getLoyaltyCardGroups(1);
|
||||
assertEquals(0, cardGroups2.size());
|
||||
assertEquals(0, db.getGroupCardCount("one"));
|
||||
assertEquals(0, db.getGroupCardCount("two"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void databaseUpgradeFromVersion1()
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.view.View;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -17,7 +16,6 @@ import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(sdk = 23)
|
||||
|
||||
@@ -24,7 +24,9 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -100,6 +102,20 @@ public class ImportExportTest
|
||||
assertEquals(cardsToAdd, db.getLoyaltyCardCount());
|
||||
}
|
||||
|
||||
private void addGroups(int groupsToAdd)
|
||||
{
|
||||
// Add in reverse order to test sorting
|
||||
for(int index = groupsToAdd; index > 0; index--)
|
||||
{
|
||||
String groupName = String.format("group, \"%4d", index);
|
||||
long id = db.insertGroup(groupName);
|
||||
boolean result = (id != -1);
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
assertEquals(groupsToAdd, db.getGroupCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that all of the cards follow the pattern
|
||||
* specified in addLoyaltyCards(), and are in sequential order
|
||||
@@ -181,6 +197,29 @@ public class ImportExportTest
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that all of the groups follow the pattern
|
||||
* specified in addGroups(), and are in sequential order
|
||||
* where the smallest group's index is 1
|
||||
*/
|
||||
private void checkGroups()
|
||||
{
|
||||
Cursor cursor = db.getGroupCursor();
|
||||
int index = 1;
|
||||
|
||||
while(cursor.moveToNext())
|
||||
{
|
||||
Group group = Group.toGroup(cursor);
|
||||
|
||||
String expectedGroupName = String.format("group, \"%4d", index);
|
||||
|
||||
assertEquals(expectedGroupName, group._id);
|
||||
|
||||
index++;
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the contents of the database
|
||||
*/
|
||||
@@ -263,6 +302,96 @@ public class ImportExportTest
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> groupsToGroupNames(List<Group> groups)
|
||||
{
|
||||
List<String> groupNames = new ArrayList<>();
|
||||
|
||||
for (Group group : groups) {
|
||||
groupNames.add(group._id);
|
||||
}
|
||||
|
||||
return groupNames;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleCardsExportImportWithGroups() throws IOException
|
||||
{
|
||||
final int NUM_CARDS = 10;
|
||||
final int NUM_GROUPS = 3;
|
||||
|
||||
for(DataFormat format : DataFormat.values())
|
||||
{
|
||||
addLoyaltyCards(NUM_CARDS);
|
||||
addGroups(NUM_GROUPS);
|
||||
|
||||
List<Group> emptyGroup = new ArrayList<>();
|
||||
|
||||
List<Group> groupsForOne = new ArrayList<>();
|
||||
groupsForOne.add(db.getGroup("group, \" 1"));
|
||||
|
||||
List<Group> groupsForTwo = new ArrayList<>();
|
||||
groupsForTwo.add(db.getGroup("group, \" 1"));
|
||||
groupsForTwo.add(db.getGroup("group, \" 2"));
|
||||
|
||||
List<Group> groupsForThree = new ArrayList<>();
|
||||
groupsForThree.add(db.getGroup("group, \" 1"));
|
||||
groupsForThree.add(db.getGroup("group, \" 2"));
|
||||
groupsForThree.add(db.getGroup("group, \" 3"));
|
||||
|
||||
List<Group> groupsForFour = new ArrayList<>();
|
||||
groupsForFour.add(db.getGroup("group, \" 1"));
|
||||
groupsForFour.add(db.getGroup("group, \" 2"));
|
||||
groupsForFour.add(db.getGroup("group, \" 3"));
|
||||
|
||||
List<Group> groupsForFive = new ArrayList<>();
|
||||
groupsForFive.add(db.getGroup("group, \" 1"));
|
||||
groupsForFive.add(db.getGroup("group, \" 3"));
|
||||
|
||||
db.setLoyaltyCardGroups(1, groupsForOne);
|
||||
db.setLoyaltyCardGroups(2, groupsForTwo);
|
||||
db.setLoyaltyCardGroups(3, groupsForThree);
|
||||
db.setLoyaltyCardGroups(4, groupsForFour);
|
||||
db.setLoyaltyCardGroups(5, groupsForFive);
|
||||
|
||||
ByteArrayOutputStream outData = new ByteArrayOutputStream();
|
||||
OutputStreamWriter outStream = new OutputStreamWriter(outData);
|
||||
|
||||
// Export data to CSV format
|
||||
boolean result = MultiFormatExporter.exportData(db, outStream, format);
|
||||
assertTrue(result);
|
||||
outStream.close();
|
||||
|
||||
clearDatabase();
|
||||
|
||||
ByteArrayInputStream inData = new ByteArrayInputStream(outData.toByteArray());
|
||||
InputStreamReader inStream = new InputStreamReader(inData);
|
||||
|
||||
// Import the CSV data
|
||||
result = MultiFormatImporter.importData(db, inStream, DataFormat.CSV);
|
||||
assertTrue(result);
|
||||
|
||||
assertEquals(NUM_CARDS, db.getLoyaltyCardCount());
|
||||
assertEquals(NUM_GROUPS, db.getGroupCount());
|
||||
|
||||
checkLoyaltyCards();
|
||||
checkGroups();
|
||||
|
||||
assertEquals(groupsToGroupNames(groupsForOne), groupsToGroupNames(db.getLoyaltyCardGroups(1)));
|
||||
assertEquals(groupsToGroupNames(groupsForTwo), groupsToGroupNames(db.getLoyaltyCardGroups(2)));
|
||||
assertEquals(groupsToGroupNames(groupsForThree), groupsToGroupNames(db.getLoyaltyCardGroups(3)));
|
||||
assertEquals(groupsToGroupNames(groupsForFour), groupsToGroupNames(db.getLoyaltyCardGroups(4)));
|
||||
assertEquals(groupsToGroupNames(groupsForFive), groupsToGroupNames(db.getLoyaltyCardGroups(5)));
|
||||
assertEquals(emptyGroup, db.getLoyaltyCardGroups(6));
|
||||
assertEquals(emptyGroup, db.getLoyaltyCardGroups(7));
|
||||
assertEquals(emptyGroup, db.getLoyaltyCardGroups(8));
|
||||
assertEquals(emptyGroup, db.getLoyaltyCardGroups(9));
|
||||
assertEquals(emptyGroup, db.getLoyaltyCardGroups(10));
|
||||
|
||||
// Clear the database for the next format under test
|
||||
clearDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importExistingCardsNotReplace() throws IOException
|
||||
{
|
||||
@@ -395,7 +524,7 @@ public class ImportExportTest
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithoutColors() throws IOException
|
||||
public void importWithoutColorsV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -427,7 +556,7 @@ public class ImportExportTest
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithoutNullColors() throws IOException
|
||||
public void importWithoutNullColorsV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -461,7 +590,7 @@ public class ImportExportTest
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithoutInvalidColors() throws IOException
|
||||
public void importWithoutInvalidColorsV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -485,7 +614,7 @@ public class ImportExportTest
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithNoBarcodeType() throws IOException
|
||||
public void importWithNoBarcodeTypeV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -519,7 +648,7 @@ public class ImportExportTest
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithStarredField() throws IOException
|
||||
public void importWithStarredFieldV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -555,7 +684,7 @@ public class ImportExportTest
|
||||
|
||||
|
||||
@Test
|
||||
public void importWithNoStarredField() throws IOException
|
||||
public void importWithNoStarredFieldV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
@@ -589,7 +718,7 @@ public class ImportExportTest
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importWithInvalidStarField() throws IOException
|
||||
public void importWithInvalidStarFieldV1() throws IOException
|
||||
{
|
||||
String csvText = "";
|
||||
csvText += DBHelper.LoyaltyCardDbIds.ID + "," +
|
||||
|
||||
@@ -2,28 +2,28 @@ package protect.card_locker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
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.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.android.controller.ActivityController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
@@ -60,9 +60,10 @@ public class MainActivityTest
|
||||
final Menu menu = shadowOf(activity).getOptionsMenu();
|
||||
assertTrue(menu != null);
|
||||
|
||||
// The settings, search and add button should be present
|
||||
assertEquals(menu.size(), 4);
|
||||
// The settings, import/export, groups, search and add button should be present
|
||||
assertEquals(menu.size(), 5);
|
||||
assertEquals("Search", menu.findItem(R.id.action_search).getTitle().toString());
|
||||
assertEquals("Groups", menu.findItem(R.id.action_manage_groups).getTitle().toString());
|
||||
assertEquals("Import/Export", menu.findItem(R.id.action_import_export).getTitle().toString());
|
||||
assertEquals("About", menu.findItem(R.id.action_about).getTitle().toString());
|
||||
assertEquals("Settings", menu.findItem(R.id.action_settings).getTitle().toString());
|
||||
@@ -165,6 +166,54 @@ public class MainActivityTest
|
||||
assertEquals("storeB",cursor.getString(cursor.getColumnIndex("store")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGroups()
|
||||
{
|
||||
ActivityController activityController = Robolectric.buildActivity(MainActivity.class).create();
|
||||
|
||||
Activity mainActivity = (Activity)activityController.get();
|
||||
activityController.start();
|
||||
activityController.resume();
|
||||
|
||||
DBHelper db = new DBHelper(mainActivity);
|
||||
|
||||
TabLayout groupTabs = mainActivity.findViewById(R.id.groups);
|
||||
|
||||
// No group tabs by default
|
||||
assertEquals(0, groupTabs.getTabCount());
|
||||
|
||||
// Having at least one group should create two tabs: One all and one for each group
|
||||
db.insertGroup("One");
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
assertEquals(2, groupTabs.getTabCount());
|
||||
assertEquals("All", groupTabs.getTabAt(0).getText().toString());
|
||||
assertEquals("One", groupTabs.getTabAt(1).getText().toString());
|
||||
|
||||
// Adding another group should have them sorted alphabetically
|
||||
db.insertGroup("Alphabetical two");
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
assertEquals(3, groupTabs.getTabCount());
|
||||
assertEquals("All", groupTabs.getTabAt(0).getText().toString());
|
||||
assertEquals("Alphabetical two", groupTabs.getTabAt(1).getText().toString());
|
||||
assertEquals("One", groupTabs.getTabAt(2).getText().toString());
|
||||
|
||||
// Removing a group should also change the list
|
||||
db.deleteGroup("Alphabetical two");
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
assertEquals(2, groupTabs.getTabCount());
|
||||
assertEquals("All", groupTabs.getTabAt(0).getText().toString());
|
||||
assertEquals("One", groupTabs.getTabAt(1).getText().toString());
|
||||
|
||||
// Removing the last group should make the tabs disappear
|
||||
db.deleteGroup("One");
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
assertEquals(0, groupTabs.getTabCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFiltering()
|
||||
{
|
||||
@@ -177,11 +226,17 @@ public class MainActivityTest
|
||||
TextView helpText = mainActivity.findViewById(R.id.helpText);
|
||||
TextView noMatchingCardsText = mainActivity.findViewById(R.id.noMatchingCardsText);
|
||||
ListView list = mainActivity.findViewById(R.id.list);
|
||||
TabLayout groupTabs = mainActivity.findViewById(R.id.groups);
|
||||
|
||||
DBHelper db = new DBHelper(mainActivity);
|
||||
db.insertLoyaltyCard("The First Store", "Initial note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
db.insertLoyaltyCard("The Second Store", "Secondary note", "cardId", BarcodeFormat.UPC_A.toString(), Color.BLACK, Color.WHITE, 0);
|
||||
|
||||
db.insertGroup("Group one");
|
||||
List<Group> groups = new ArrayList<>();
|
||||
groups.add(db.getGroup("Group one"));
|
||||
db.setLoyaltyCardGroups(1, groups);
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
@@ -202,6 +257,27 @@ public class MainActivityTest
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
|
||||
mainActivity.filter = "first";
|
||||
|
||||
activityController.pause();
|
||||
@@ -213,6 +289,27 @@ public class MainActivityTest
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
mainActivity.filter = "initial";
|
||||
|
||||
activityController.pause();
|
||||
@@ -224,6 +321,27 @@ public class MainActivityTest
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
mainActivity.filter = "second";
|
||||
|
||||
activityController.pause();
|
||||
@@ -235,6 +353,27 @@ public class MainActivityTest
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
mainActivity.filter = "company";
|
||||
|
||||
activityController.pause();
|
||||
@@ -246,6 +385,27 @@ public class MainActivityTest
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.VISIBLE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(0, list.getCount());
|
||||
|
||||
mainActivity.filter = "";
|
||||
|
||||
activityController.pause();
|
||||
@@ -256,5 +416,26 @@ public class MainActivityTest
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
|
||||
// Switch to Group one
|
||||
groupTabs.selectTab(groupTabs.getTabAt(1));
|
||||
|
||||
activityController.pause();
|
||||
activityController.resume();
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(1, list.getCount());
|
||||
|
||||
// Switch back to all groups
|
||||
groupTabs.selectTab(groupTabs.getTabAt(0));
|
||||
|
||||
assertEquals(View.GONE, helpText.getVisibility());
|
||||
assertEquals(View.GONE, noMatchingCardsText.getVisibility());
|
||||
assertEquals(View.VISIBLE, list.getVisibility());
|
||||
|
||||
assertEquals(2, list.getCount());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user