From 69e4014ae05de2926ed8f2a33655038b6594c7dc Mon Sep 17 00:00:00 2001 From: Vivek Date: Mon, 19 Mar 2018 01:12:08 +0800 Subject: [PATCH 1/8] Add tags to database --- .../geeksfactory/opacclient/objects/Tag.java | 32 ++++++++++++++ .../storage/StarContentProvider.java | 2 +- .../opacclient/storage/StarDataSource.java | 43 +++++++++++++++++++ .../opacclient/storage/StarDatabase.java | 26 ++++++++++- 4 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java new file mode 100644 index 000000000..af6067aa2 --- /dev/null +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java @@ -0,0 +1,32 @@ +package de.geeksfactory.opacclient.objects; + +/** + * Object representing a tag in a starred item. + */ + +public class Tag { + + private int id; + private String tagName; + + @Override + public String toString() { + return "Tag [id=" + id + ", tag=" + tagName + "]"; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getTagName() { + return tagName; + } + + public void setTagName(String tagName) { + this.tagName = tagName; + } +} diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarContentProvider.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarContentProvider.java index cf47ba6c4..9f055a359 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarContentProvider.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarContentProvider.java @@ -73,7 +73,7 @@ private static Mime getTypeMime(Uri uri) { @Override public boolean onCreate() { - database = new StarDatabase(getContext()); + database = StarDatabase.getInstance(getContext()); return true; } diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java index 8b831279b..0987f9e4e 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java @@ -24,6 +24,7 @@ import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; import java.util.ArrayList; import java.util.List; @@ -33,14 +34,18 @@ import de.geeksfactory.opacclient.OpacClient; import de.geeksfactory.opacclient.objects.SearchResult; import de.geeksfactory.opacclient.objects.Starred; +import de.geeksfactory.opacclient.objects.Tag; import de.geeksfactory.opacclient.searchfields.SearchField; public class StarDataSource { + private SQLiteDatabase database; private Activity context; public StarDataSource(Activity context) { this.context = context; + StarDatabase dbHelper = StarDatabase.getInstance(context); + database = dbHelper.getWritableDatabase(); } public static Starred cursorToItem(Cursor cursor) { @@ -202,4 +207,42 @@ public void renameLibraries(Map map) { new String[]{entry.getKey()}); } } + + public static Tag cursorToTag(Cursor cursor) { + Tag tag = new Tag(); + tag.setId(cursor.getInt(0)); + tag.setTagName(cursor.getString(1)); + return tag; + } + + public long addTag(Starred item, Tag tag) { + ContentValues values = new ContentValues(); + values.put("tag", tag.getTagName()); + database.insert(StarDatabase.TAGS_TABLE, null, values); + values = new ContentValues(); + values.put("tag", tag.getId()); + values.put("item", item.getId()); + return database.insert(StarDatabase.STAR_TAGS_TABLE, null, values); + } + + public boolean hasTag(Tag tag) { + if (tag == null) { + return false; + } + String[] selA = {tag.getTagName()}; + Cursor cursor = database.query(StarDatabase.STAR_TAGS_TABLE, null, null, + selA, null, null, null); + int c = cursor.getCount(); + cursor.close(); + return (c > 0); + } + + public void removeTag(Tag tag) { + String[] selA = {"" + tag.getId()}; + database.delete(StarDatabase.STAR_TAGS_TABLE, "id=?", selA); + if (!hasTag(tag)) { + selA = new String[]{"" + tag.getTagName()}; + database.delete(StarDatabase.TAGS_TABLE, "tag=?", selA); + } + } } diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java index f19439a13..3891e1572 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java @@ -28,10 +28,19 @@ public class StarDatabase extends SQLiteOpenHelper { + private static StarDatabase instance; public static final String STAR_TABLE = "starred"; + public static final String TAGS_TABLE = "tags"; + public static final String STAR_TAGS_TABLE = "starred_tags"; private static final String DATABASE_CREATE = "create table " + STAR_TABLE + " ( id integer primary key autoincrement," + " medianr text," + " bib text," + " title text," + " mediatype text" + ");"; + public static final String TAGS_DATABASE_CREATE = "create table " + TAGS_TABLE + + " ( id integer primary key autoincrement," +" tag text);"; + public static final String STAR_TAGS_DATABASE_CREATE = "create table " + STAR_TAGS_TABLE + + " ( tag integer references tags (id)," + " item integer references starred (id)," + + " primary key (tag, item)" + + "foreign key (item) references starred (id) on delete cascade" + ");"; // CHANGE THIS public static final String STAR_WHERE_ID = "id = ?"; public static final String STAR_WHERE_LIB = "bib = ?"; @@ -39,16 +48,25 @@ public class StarDatabase extends SQLiteOpenHelper { public static final String STAR_WHERE_NR_LIB = "bib = ? AND medianr = ?"; public static final String[] COLUMNS = {"id AS _id", "medianr", "bib", "title", "mediatype"}; + public static final String[] TAGS_COLUMNS = {"id", "tags"}; + public static final String[] STAR_TAGS_COLUMNS = {"tag", "item"}; private static final String DATABASE_NAME = "starred.db"; - private static final int DATABASE_VERSION = 6; // REPLACE ONUPGRADE IF YOU + private static final int DATABASE_VERSION = 7; // REPLACE ONUPGRADE IF YOU - public StarDatabase(Context context) { + private StarDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } + public static synchronized StarDatabase getInstance(Context context) { + if (instance == null) instance = new StarDatabase(context); + return instance; + } + @Override public void onCreate(SQLiteDatabase db) { db.execSQL(DATABASE_CREATE); + db.execSQL(TAGS_DATABASE_CREATE); + db.execSQL(STAR_TAGS_DATABASE_CREATE); } @Override @@ -59,6 +77,10 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Add column for media type db.execSQL("alter table " + STAR_TABLE + " add column mediatype text"); } + if (oldVersion < 7) { + db.execSQL(TAGS_DATABASE_CREATE); + db.execSQL(STAR_TAGS_DATABASE_CREATE); + } } else { Log.w(StarDatabase.class.getName(), "Upgrading database from version " + oldVersion + " to " + newVersion From 2e519965c3fb86e68641a94ccb5d36c686458fbd Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 22 Mar 2018 18:18:19 +0800 Subject: [PATCH 2/8] Implement add tags functionality Implement add tags functionality --- .../opacclient/objects/Starred.java | 15 ++++++ .../opacclient/frontend/StarredFragment.java | 54 +++++++++++++++++++ .../opacclient/storage/StarDataSource.java | 22 ++++++-- .../opacclient/storage/StarDatabase.java | 2 +- .../src/main/res/layout/listitem_starred.xml | 20 +++++++ .../opacapp/src/main/res/values/strings.xml | 1 + 6 files changed, 110 insertions(+), 4 deletions(-) diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java index d2e861d3e..26f639988 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java @@ -32,6 +32,7 @@ public class Starred { private String mnr; private String title; private SearchResult.MediaType mediaType; + private Tag tag; @Override public String toString() { @@ -94,4 +95,18 @@ public SearchResult.MediaType getMediaType() { public void setMediaType(SearchResult.MediaType mediaType) { this.mediaType = mediaType; } + + /** + * Get this item's tag + */ + public Tag getTag() { + return tag; + } + + /** + * Set this item's tag + */ + public void setTag(Tag tag) { + this.tag = tag; + } } diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java index a381c2a34..4b3b07279 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java @@ -22,8 +22,10 @@ package de.geeksfactory.opacclient.frontend; import android.app.Activity; +import android.app.AlertDialog; import android.content.ActivityNotFoundException; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; @@ -37,6 +39,7 @@ import android.support.v4.content.Loader; import android.support.v4.widget.SimpleCursorAdapter; import android.text.Html; +import android.text.InputType; import android.util.Log; import android.view.LayoutInflater; import android.view.MenuInflater; @@ -46,6 +49,7 @@ import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; +import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; @@ -99,6 +103,7 @@ public class StarredFragment extends Fragment implements private int activatedPosition = ListView.INVALID_POSITION; private TextView tvWelcome; private Starred sItem; + private String tagName = ""; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -473,6 +478,13 @@ private void setActivatedPosition(int position) { activatedPosition = position; } + private void addTag(Starred item, String tagName, Cursor cursor) { + StarDataSource data = new StarDataSource(getActivity()); + sItem = item; + data.addTag(item, tagName); + item.setTag(data.getTagByTagName(tagName)); + } + @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -499,6 +511,7 @@ public ItemListAdapter() { public void bindView(View view, Context context, Cursor cursor) { Starred item = StarDataSource.cursorToItem(cursor); + TextView tv = (TextView) view.findViewById(R.id.tvTitle); if (item.getTitle() != null) { tv.setText(Html.fromHtml(item.getTitle())); @@ -513,6 +526,47 @@ public void bindView(View view, Context context, Cursor cursor) { ivType.setImageBitmap(null); } + TextView tagView = (TextView) view.findViewById(R.id.tvTag); + +// EditText et = (EditText) view.findViewById(R.id.etvAddTagText); + ImageView ivAddTag = (ImageView) view.findViewById(R.id.ivAddTag); + ivAddTag.setFocusableInTouchMode(false); + ivAddTag.setFocusable(false); + ivAddTag.setTag(item); + + ivAddTag.setOnClickListener((View arg0) -> { + // Create alert dialog box for entering of tag + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle("Add tag to " + item.getTitle()); + + // Set up the input + final EditText input = new EditText(context); + + // Specify the type of input expected + input.setInputType(InputType.TYPE_CLASS_TEXT); + builder.setView(input); + + // Set up the buttons + builder.setPositiveButton("OK", + (dialog, which) -> { + tagName = input.getText().toString(); + System.out.println(tagName); + Starred item1 = (Starred) arg0.getTag(); + addTag(item1, tagName, cursor); + if (item1.getTag() != null) { + System.out.println(item1.getTag().getTagName()); + tagView.setText(Html.fromHtml(item1.getTag().getTagName())); + } else { + tagView.setText(""); + } + }); + + builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel()); + + builder.show(); + + }); + ImageView ivDelete = (ImageView) view.findViewById(R.id.ivDelete); ivDelete.setFocusableInTouchMode(false); ivDelete.setFocusable(false); diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java index 0987f9e4e..31da954f1 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java @@ -215,12 +215,13 @@ public static Tag cursorToTag(Cursor cursor) { return tag; } - public long addTag(Starred item, Tag tag) { + public long addTag(Starred item, String tagName) { ContentValues values = new ContentValues(); - values.put("tag", tag.getTagName()); + values.put("tag", tagName); database.insert(StarDatabase.TAGS_TABLE, null, values); + values = new ContentValues(); - values.put("tag", tag.getId()); + values.put("tag", getTagByTagName(tagName).getId()); values.put("item", item.getId()); return database.insert(StarDatabase.STAR_TAGS_TABLE, null, values); } @@ -245,4 +246,19 @@ public void removeTag(Tag tag) { database.delete(StarDatabase.TAGS_TABLE, "tag=?", selA); } } + + public Tag getTagByTagName(String tagName) { + String[] selA = {tagName}; + Cursor cursor = database.query(StarDatabase.TAGS_TABLE, StarDatabase.TAGS_COLUMNS, "tag = ?", + selA, null, null, null); + Tag item = null; + cursor.moveToFirst(); + if (!cursor.isAfterLast()) { + item = cursorToTag(cursor); + cursor.moveToNext(); + } + // Make sure to close the cursor + cursor.close(); + return item; + } } diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java index 3891e1572..3ea971583 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java @@ -48,7 +48,7 @@ public class StarDatabase extends SQLiteOpenHelper { public static final String STAR_WHERE_NR_LIB = "bib = ? AND medianr = ?"; public static final String[] COLUMNS = {"id AS _id", "medianr", "bib", "title", "mediatype"}; - public static final String[] TAGS_COLUMNS = {"id", "tags"}; + public static final String[] TAGS_COLUMNS = {"id", "tag"}; public static final String[] STAR_TAGS_COLUMNS = {"tag", "item"}; private static final String DATABASE_NAME = "starred.db"; private static final int DATABASE_VERSION = 7; // REPLACE ONUPGRADE IF YOU diff --git a/opacclient/opacapp/src/main/res/layout/listitem_starred.xml b/opacclient/opacapp/src/main/res/layout/listitem_starred.xml index 6e7376771..099aebd4d 100644 --- a/opacclient/opacapp/src/main/res/layout/listitem_starred.xml +++ b/opacclient/opacapp/src/main/res/layout/listitem_starred.xml @@ -36,4 +36,24 @@ android:padding="5dp" android:textAppearance="?android:attr/textAppearanceMedium"/> + + + \ No newline at end of file diff --git a/opacclient/opacapp/src/main/res/values/strings.xml b/opacclient/opacapp/src/main/res/values/strings.xml index d8515fe4c..aa6a2f9f0 100644 --- a/opacclient/opacapp/src/main/res/values/strings.xml +++ b/opacclient/opacapp/src/main/res/values/strings.xml @@ -126,6 +126,7 @@ Library Really delete account? Select Account + Add tag Privacy Library Search From 97ef386a778eeb83c3f803c1a3316bb171252432 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 25 Mar 2018 18:03:22 +0800 Subject: [PATCH 3/8] Implement remove tag functionality The following were done as well: - Improve add tag functionality to use a list of tags of instead of single tags - Add comments to code --- .../opacclient/objects/Starred.java | 24 ++-- .../geeksfactory/opacclient/objects/Tag.java | 12 ++ .../opacclient/frontend/StarredFragment.java | 115 ++++++++++++++++-- .../opacclient/storage/StarDataSource.java | 72 ++++++++--- .../src/main/res/layout/listitem_starred.xml | 13 ++ .../opacapp/src/main/res/values/strings.xml | 1 + 6 files changed, 203 insertions(+), 34 deletions(-) diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java index 26f639988..4fbdfc784 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java @@ -21,6 +21,9 @@ */ package de.geeksfactory.opacclient.objects; +import java.util.ArrayList; +import java.util.List; + /** * Object representing a bookmarked item. Not part of the API you are interested * in if you want to implement a library system. @@ -32,7 +35,7 @@ public class Starred { private String mnr; private String title; private SearchResult.MediaType mediaType; - private Tag tag; + private List tags = new ArrayList<>(); @Override public String toString() { @@ -97,16 +100,23 @@ public void setMediaType(SearchResult.MediaType mediaType) { } /** - * Get this item's tag + * Get this item's tag list + */ + public List getTags() { + return tags; + } + + /** + * Add a tag to this item's tag list */ - public Tag getTag() { - return tag; + public void addTag(Tag tag) { + this.tags.add(tag); } /** - * Set this item's tag + * Remove a tag from this item's tag list */ - public void setTag(Tag tag) { - this.tag = tag; + public void removeTag(Tag tag) { + this.tags.remove(tag); } } diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java index af6067aa2..643125c5b 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java @@ -14,18 +14,30 @@ public String toString() { return "Tag [id=" + id + ", tag=" + tagName + "]"; } + /** + * Get this tag's ID + */ public int getId() { return id; } + /** + * Set this tag's ID + */ public void setId(int id) { this.id = id; } + /** + * Get this tag's name + */ public String getTagName() { return tagName; } + /** + * Set this tag's name + */ public void setTagName(String tagName) { this.tagName = tagName; } diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java index 4b3b07279..32394b594 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java @@ -68,6 +68,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import de.geeksfactory.opacclient.OpacClient; import de.geeksfactory.opacclient.R; @@ -75,6 +76,7 @@ import de.geeksfactory.opacclient.objects.Account; import de.geeksfactory.opacclient.objects.SearchResult; import de.geeksfactory.opacclient.objects.Starred; +import de.geeksfactory.opacclient.objects.Tag; import de.geeksfactory.opacclient.searchfields.SearchField; import de.geeksfactory.opacclient.searchfields.SearchField.Meaning; import de.geeksfactory.opacclient.searchfields.SearchQuery; @@ -478,11 +480,42 @@ private void setActivatedPosition(int position) { activatedPosition = position; } - private void addTag(Starred item, String tagName, Cursor cursor) { + /** + * Adds tag to the database and the starred item. + * @param item + * @param tagName + * @return updated tag list + */ + private List addTag(Starred item, String tagName) { StarDataSource data = new StarDataSource(getActivity()); sItem = item; data.addTag(item, tagName); - item.setTag(data.getTagByTagName(tagName)); + item.addTag(data.getTagByTagName(tagName)); + return data.getAllTags(item); + } + + /** + * Removes tag from the database and the starred item. + * @param item + * @param tagName + * @return updated tag list + */ + private List removeTag(Starred item, String tagName) { + StarDataSource data = new StarDataSource(getActivity()); + sItem = item; + data.removeTag(data.getTagByTagName(tagName)); + item.removeTag(data.getTagByTagName(tagName)); + return data.getAllTags(item); + } + + /** + * Returns latest the tag list from the database. + * @param item + * @return the updated tag list + */ + private List getTags(Starred item) { + StarDataSource data = new StarDataSource(getActivity()); + return data.getAllTags(item); } @Override @@ -527,14 +560,74 @@ public void bindView(View view, Context context, Cursor cursor) { } TextView tagView = (TextView) view.findViewById(R.id.tvTag); + List currentTags = getTags(item); + + ImageView ivRemoveTag = (ImageView) view.findViewById(R.id.ivRemoveTag); + ivRemoveTag.setFocusableInTouchMode(false); + ivRemoveTag.setFocusable(false); + ivRemoveTag.setTag(item); + + ivRemoveTag.setOnClickListener(arg0 -> { + // Create alert dialog box for removing of tags + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle("Choose tags to remove from " + item.getTitle()); + + // add a checkbox list from the current tags list + String[] tagsList = new String[currentTags.size()]; + for (int i = 0; i < currentTags.size(); i++) { + tagsList[i] = currentTags.get(i).getTagName(); + } + boolean[] checkedItems = new boolean[tagsList.length]; + + builder.setMultiChoiceItems(tagsList, null, (dialog, which, isChecked) -> { + // user checked or unchecked a box + checkedItems[which] = true; + }); + + // Set up the buttons + builder.setPositiveButton("OK", (dialog, which) -> { + // Iterate through each tag name in the tag list and remove those that have + // been checked + for (int i = 0; i < tagsList.length; i++) { + if (checkedItems[i]) { + List tags = removeTag(item, tagsList[i]); + // Update the tags text view + if (tags.size() > 0) { + StringBuilder tagsBuilder = new StringBuilder(); + for (Tag t : tags) { + tagsBuilder.append(t.getTagName()).append(" | "); + } + System.out.println(tagsBuilder.toString()); + tagView.setText(Html.fromHtml(tagsBuilder.toString())); + } else { + tagView.setText(""); + } + } + } + }); + + builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel()); + + AlertDialog dialog = builder.create(); + dialog.show(); + }); -// EditText et = (EditText) view.findViewById(R.id.etvAddTagText); ImageView ivAddTag = (ImageView) view.findViewById(R.id.ivAddTag); ivAddTag.setFocusableInTouchMode(false); ivAddTag.setFocusable(false); ivAddTag.setTag(item); - ivAddTag.setOnClickListener((View arg0) -> { + if (currentTags.size() > 0) { + StringBuilder tagsBuilder = new StringBuilder(); + for (Tag t : currentTags) { + tagsBuilder.append(t.getTagName()).append(" | "); + } + tagView.setText(Html.fromHtml(tagsBuilder.toString())); + } else { + tagView.setText(""); + } + + ivAddTag.setOnClickListener(arg0 -> { // Create alert dialog box for entering of tag AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("Add tag to " + item.getTitle()); @@ -550,12 +643,14 @@ public void bindView(View view, Context context, Cursor cursor) { builder.setPositiveButton("OK", (dialog, which) -> { tagName = input.getText().toString(); - System.out.println(tagName); - Starred item1 = (Starred) arg0.getTag(); - addTag(item1, tagName, cursor); - if (item1.getTag() != null) { - System.out.println(item1.getTag().getTagName()); - tagView.setText(Html.fromHtml(item1.getTag().getTagName())); + List tags = addTag(item, tagName); + // Create a string from updated tag list and update the view + if (tags.size() > 0) { + StringBuilder tagsBuilder = new StringBuilder(); + for (Tag t : tags) { + tagsBuilder.append(t.getTagName()).append(" | "); + } + tagView.setText(Html.fromHtml(tagsBuilder.toString())); } else { tagView.setText(""); } diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java index 31da954f1..f0683457b 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java @@ -24,6 +24,7 @@ import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; +import android.database.sqlite.SQLiteConstraintException; import android.database.sqlite.SQLiteDatabase; import java.util.ArrayList; @@ -215,6 +216,9 @@ public static Tag cursorToTag(Cursor cursor) { return tag; } + /** + * Add given tag to the tags database and the starred-tag database + */ public long addTag(Starred item, String tagName) { ContentValues values = new ContentValues(); values.put("tag", tagName); @@ -223,28 +227,24 @@ public long addTag(Starred item, String tagName) { values = new ContentValues(); values.put("tag", getTagByTagName(tagName).getId()); values.put("item", item.getId()); - return database.insert(StarDatabase.STAR_TAGS_TABLE, null, values); - } - - public boolean hasTag(Tag tag) { - if (tag == null) { - return false; + try { + return database.insert(StarDatabase.STAR_TAGS_TABLE, null, values); + } catch (SQLiteConstraintException e) { + return -1; } - String[] selA = {tag.getTagName()}; - Cursor cursor = database.query(StarDatabase.STAR_TAGS_TABLE, null, null, - selA, null, null, null); - int c = cursor.getCount(); - cursor.close(); - return (c > 0); + } + /** + * Remove given tag from the starred-tag database and the tags database + */ public void removeTag(Tag tag) { String[] selA = {"" + tag.getId()}; - database.delete(StarDatabase.STAR_TAGS_TABLE, "id=?", selA); - if (!hasTag(tag)) { - selA = new String[]{"" + tag.getTagName()}; - database.delete(StarDatabase.TAGS_TABLE, "tag=?", selA); - } + database.delete(StarDatabase.STAR_TAGS_TABLE, "tag=?", selA); + + selA = new String[]{"" + tag.getTagName()}; + database.delete(StarDatabase.TAGS_TABLE, "tag=?", selA); + } public Tag getTagByTagName(String tagName) { @@ -261,4 +261,42 @@ public Tag getTagByTagName(String tagName) { cursor.close(); return item; } + + public Tag getTagById(long id) { + String[] selA = {String.valueOf(id)}; + Cursor cursor = database.query(StarDatabase.TAGS_TABLE, StarDatabase.TAGS_COLUMNS, "id = ?", + selA, null, null, null); + Tag item = null; + cursor.moveToFirst(); + if (!cursor.isAfterLast()) { + item = cursorToTag(cursor); + cursor.moveToNext(); + } + // Make sure to close the cursor + cursor.close(); + return item; + } + + public static int cursorToStarAndTagId(Cursor cursor) { + return(cursor.getInt(0)); + } + + /** + * Get all tags that belong to this Starred item + */ + public List getAllTags(Starred item) { + List tags = new ArrayList<>(); + String[] selA = {Integer.toString(item.getId())}; + Cursor cursor = database.query(StarDatabase.STAR_TAGS_TABLE, StarDatabase.STAR_TAGS_COLUMNS, "item = ?", selA, null, null, null); + + cursor.moveToFirst(); + while (!cursor.isAfterLast()) { + int tagId = cursorToStarAndTagId(cursor); + tags.add(getTagById(tagId)); + cursor.moveToNext(); + } + // Make sure to close the cursor + cursor.close(); + return tags; + } } diff --git a/opacclient/opacapp/src/main/res/layout/listitem_starred.xml b/opacclient/opacapp/src/main/res/layout/listitem_starred.xml index 099aebd4d..a1a4dfba3 100644 --- a/opacclient/opacapp/src/main/res/layout/listitem_starred.xml +++ b/opacclient/opacapp/src/main/res/layout/listitem_starred.xml @@ -56,4 +56,17 @@ android:layout_toStartOf="@+id/ivDelete" android:contentDescription="@string/tag_add" app:srcCompat="@drawable/ic_add_24dp"/> + + \ No newline at end of file diff --git a/opacclient/opacapp/src/main/res/values/strings.xml b/opacclient/opacapp/src/main/res/values/strings.xml index aa6a2f9f0..5e99e8746 100644 --- a/opacclient/opacapp/src/main/res/values/strings.xml +++ b/opacclient/opacapp/src/main/res/values/strings.xml @@ -127,6 +127,7 @@ Really delete account? Select Account Add tag + Remove tag Privacy Library Search From f53da815bc91b5da3cc5d9fd23696a21316a79bd Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 31 Mar 2018 01:34:05 +0800 Subject: [PATCH 4/8] Better implementation of add and remove tag function and improve UI --- .../opacclient/objects/Starred.java | 5 +- .../geeksfactory/opacclient/objects/Tag.java | 15 ++ .../opacclient/frontend/StarredFragment.java | 217 +++++++++--------- .../opacclient/storage/StarDataSource.java | 74 +++++- .../opacclient/storage/StarDatabase.java | 2 +- .../drawable/ic_local_offer_black_24dp.xml | 9 + .../src/main/res/layout/listitem_starred.xml | 27 +-- .../src/main/res/layout/listitem_tag.xml | 29 +++ .../opacapp/src/main/res/layout/tag_menu.xml | 34 +++ .../opacapp/src/main/res/values/strings.xml | 4 +- 10 files changed, 278 insertions(+), 138 deletions(-) create mode 100644 opacclient/opacapp/src/main/res/drawable/ic_local_offer_black_24dp.xml create mode 100644 opacclient/opacapp/src/main/res/layout/listitem_tag.xml create mode 100644 opacclient/opacapp/src/main/res/layout/tag_menu.xml diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java index 4fbdfc784..45cb763b7 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Starred.java @@ -117,6 +117,9 @@ public void addTag(Tag tag) { * Remove a tag from this item's tag list */ public void removeTag(Tag tag) { - this.tags.remove(tag); + if (tags.contains(tag)) { + this.tags.remove(tag); + } + } } diff --git a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java index 643125c5b..75f79a0b0 100644 --- a/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java +++ b/opacclient/libopac/src/main/java/de/geeksfactory/opacclient/objects/Tag.java @@ -8,6 +8,7 @@ public class Tag { private int id; private String tagName; + private int starredItemRefId; @Override public String toString() { @@ -41,4 +42,18 @@ public String getTagName() { public void setTagName(String tagName) { this.tagName = tagName; } + + /** + * Get this tag's reference ID to the starred item it is attached to + */ + public int getStarredItemRefId() { + return starredItemRefId; + } + + /** + * Set this tag's reference ID to the starred item it is attached to + */ + public void setStarredItemRefId(int starredItemRefId) { + this.starredItemRefId = starredItemRefId; + } } diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java index 32394b594..ab0d38031 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/frontend/StarredFragment.java @@ -25,13 +25,14 @@ import android.app.AlertDialog; import android.content.ActivityNotFoundException; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager.LoaderCallbacks; @@ -39,16 +40,20 @@ import android.support.v4.content.Loader; import android.support.v4.widget.SimpleCursorAdapter; import android.text.Html; -import android.text.InputType; import android.util.Log; import android.view.LayoutInflater; import android.view.MenuInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; @@ -68,7 +73,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import de.geeksfactory.opacclient.OpacClient; import de.geeksfactory.opacclient.R; @@ -105,7 +109,6 @@ public class StarredFragment extends Fragment implements private int activatedPosition = ListView.INVALID_POSITION; private TextView tvWelcome; private Starred sItem; - private String tagName = ""; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -486,26 +489,22 @@ private void setActivatedPosition(int position) { * @param tagName * @return updated tag list */ - private List addTag(Starred item, String tagName) { + private Tag addTag(Starred item, String tagName) { StarDataSource data = new StarDataSource(getActivity()); sItem = item; data.addTag(item, tagName); - item.addTag(data.getTagByTagName(tagName)); - return data.getAllTags(item); + Tag tagFromDatabase = data.getTagByTagName(tagName); + item.addTag(tagFromDatabase); + return tagFromDatabase; } /** * Removes tag from the database and the starred item. - * @param item - * @param tagName - * @return updated tag list + * @param tag */ - private List removeTag(Starred item, String tagName) { + private void removeTag(Tag tag) { StarDataSource data = new StarDataSource(getActivity()); - sItem = item; - data.removeTag(data.getTagByTagName(tagName)); - item.removeTag(data.getTagByTagName(tagName)); - return data.getAllTags(item); + data.removeTag(data.getTagByTagName(tag.getTagName())); } /** @@ -518,6 +517,16 @@ private List getTags(Starred item) { return data.getAllTags(item); } + private List getTagNames(Starred item) { + StarDataSource data = new StarDataSource(getActivity()); + return data.getAllTagNames(item); + } + +// private List getAllTagNamesExceptThisItem(Starred item) { +// StarDataSource data = new StarDataSource(getActivity()); +// return data.getAllTagNamesExceptThisItem(item); +// } + @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -559,108 +568,58 @@ public void bindView(View view, Context context, Cursor cursor) { ivType.setImageBitmap(null); } - TextView tagView = (TextView) view.findViewById(R.id.tvTag); - List currentTags = getTags(item); + ImageView ivTagMenu = (ImageView) view.findViewById(R.id.ivTagMenu); + ivTagMenu.setFocusableInTouchMode(false); + ivTagMenu.setFocusable(false); + ivTagMenu.setTag(item); + List currentTagList = getTags(item); + List currentTagListNames = getTagNames(item); - ImageView ivRemoveTag = (ImageView) view.findViewById(R.id.ivRemoveTag); - ivRemoveTag.setFocusableInTouchMode(false); - ivRemoveTag.setFocusable(false); - ivRemoveTag.setTag(item); - ivRemoveTag.setOnClickListener(arg0 -> { + ivTagMenu.setOnClickListener(arg0 -> { // Create alert dialog box for removing of tags AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle("Choose tags to remove from " + item.getTitle()); - - // add a checkbox list from the current tags list - String[] tagsList = new String[currentTags.size()]; - for (int i = 0; i < currentTags.size(); i++) { - tagsList[i] = currentTags.get(i).getTagName(); - } - boolean[] checkedItems = new boolean[tagsList.length]; - - builder.setMultiChoiceItems(tagsList, null, (dialog, which, isChecked) -> { - // user checked or unchecked a box - checkedItems[which] = true; - }); - - // Set up the buttons - builder.setPositiveButton("OK", (dialog, which) -> { - // Iterate through each tag name in the tag list and remove those that have - // been checked - for (int i = 0; i < tagsList.length; i++) { - if (checkedItems[i]) { - List tags = removeTag(item, tagsList[i]); - // Update the tags text view - if (tags.size() > 0) { - StringBuilder tagsBuilder = new StringBuilder(); - for (Tag t : tags) { - tagsBuilder.append(t.getTagName()).append(" | "); - } - System.out.println(tagsBuilder.toString()); - tagView.setText(Html.fromHtml(tagsBuilder.toString())); - } else { - tagView.setText(""); - } - } + builder.setTitle(item.getTitle() + " tags list"); + + // set the custom layout + final View customLayout = getLayoutInflater().inflate(R.layout.tag_menu, null); + builder.setView(customLayout); + + // create list view + ListView tagsListView = (ListView) customLayout.findViewById(R.id.lvTags); + ArrayAdapter tagAdapter = new TagListAdapter(context, currentTagList); + tagsListView.setAdapter(tagAdapter); + + EditText editText = (EditText) customLayout.findViewById(R.id.autoCompleteTextView); +// ArrayAdapter allTagNamesAdapter = new ArrayAdapter<>(context, android.R.layout.select_dialog_item, getAllTagNamesExceptThisItem(item)); +// autocomplete.setThreshold(2); +// autocomplete.setAdapter(allTagNamesAdapter); + + Button addTagButton = (Button) customLayout.findViewById(R.id.addTag); + addTagButton.setOnClickListener(view1 -> { + String tagName = editText.getText().toString(); + // prevent an empty tag or an exisiting tag from being added + if (!tagName.equals("") && !currentTagListNames.contains(tagName)) { + Tag tagToAdd = addTag(item, tagName); + currentTagList.add(tagToAdd); + tagAdapter.notifyDataSetChanged(); + currentTagListNames.add(tagName); + editText.setText(""); + Toast.makeText(context, "Added tag \"" + tagName + "\" to " + item.getTitle(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(context, "Please enter a nonempty tag name that already isn't on the list", Toast.LENGTH_LONG).show(); } + // hide keyboard once done so as to see toast messages + editText.onEditorAction(EditorInfo.IME_ACTION_DONE); + }); - builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel()); + builder.setNegativeButton("Back", (dialog, which) -> dialog.cancel()); AlertDialog dialog = builder.create(); dialog.show(); }); - ImageView ivAddTag = (ImageView) view.findViewById(R.id.ivAddTag); - ivAddTag.setFocusableInTouchMode(false); - ivAddTag.setFocusable(false); - ivAddTag.setTag(item); - - if (currentTags.size() > 0) { - StringBuilder tagsBuilder = new StringBuilder(); - for (Tag t : currentTags) { - tagsBuilder.append(t.getTagName()).append(" | "); - } - tagView.setText(Html.fromHtml(tagsBuilder.toString())); - } else { - tagView.setText(""); - } - - ivAddTag.setOnClickListener(arg0 -> { - // Create alert dialog box for entering of tag - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle("Add tag to " + item.getTitle()); - - // Set up the input - final EditText input = new EditText(context); - - // Specify the type of input expected - input.setInputType(InputType.TYPE_CLASS_TEXT); - builder.setView(input); - - // Set up the buttons - builder.setPositiveButton("OK", - (dialog, which) -> { - tagName = input.getText().toString(); - List tags = addTag(item, tagName); - // Create a string from updated tag list and update the view - if (tags.size() > 0) { - StringBuilder tagsBuilder = new StringBuilder(); - for (Tag t : tags) { - tagsBuilder.append(t.getTagName()).append(" | "); - } - tagView.setText(Html.fromHtml(tagsBuilder.toString())); - } else { - tagView.setText(""); - } - }); - - builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel()); - - builder.show(); - - }); ImageView ivDelete = (ImageView) view.findViewById(R.id.ivDelete); ivDelete.setFocusableInTouchMode(false); @@ -676,4 +635,52 @@ public void onClick(View arg0) { }); } } + + private class TagListAdapter extends ArrayAdapter { + + public TagListAdapter(Context context, List tagList) { + super(getActivity(), R.layout.listitem_tag, tagList); + } + + @NonNull + @Override + public View getView(int position, View convertView, @NonNull ViewGroup parent) { + View itemView = convertView; + if (itemView == null) { + itemView = getLayoutInflater().inflate(R.layout.listitem_tag, parent, false); + } + + Tag currentTag = getItem(position); + + TextView tv = (TextView) itemView.findViewById(R.id.tvTitle); + tv.setText(currentTag.getTagName()); + + ImageView ivDelete = (ImageView) itemView.findViewById(R.id.ivDelete); + ivDelete.setFocusableInTouchMode(false); + ivDelete.setFocusable(false); + ivDelete.setTag(currentTag); + ivDelete.setOnClickListener(arg0 -> { + Tag item = (Tag) arg0.getTag(); + removeTag(item); + Toast.makeText(getContext(), "Removed tag \"" + item.getTagName() + "\"", Toast.LENGTH_SHORT).show(); + }); + + return itemView; + } + + @Override + public void notifyDataSetChanged() { + super.notifyDataSetChanged(); + } + + @Override + public void add(Tag object) { + super.add(object); + } + + public void removeTag(Tag object) { + super.remove(object); + StarredFragment.this.removeTag(object); + } + } } diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java index f0683457b..167af4e59 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDataSource.java @@ -36,7 +36,6 @@ import de.geeksfactory.opacclient.objects.SearchResult; import de.geeksfactory.opacclient.objects.Starred; import de.geeksfactory.opacclient.objects.Tag; -import de.geeksfactory.opacclient.searchfields.SearchField; public class StarDataSource { @@ -216,13 +215,36 @@ public static Tag cursorToTag(Cursor cursor) { return tag; } + public boolean hasTagNameInTagTable(String tagName) { + if (tagName == null) { + return false; + } + String[] selA = {tagName}; + Cursor cursor = database.query(StarDatabase.TAGS_TABLE, null, "tag = ?", + selA, null, null, null); + int c = cursor.getCount(); + cursor.close(); + return (c > 0); + } + + public boolean hasTagIdInStarTagTable(long tagId) { + String[] selA = {"" + tagId}; + Cursor cursor = database.query(StarDatabase.STAR_TAGS_TABLE, null, "tag = ?", + selA, null, null, null); + int c = cursor.getCount(); + cursor.close(); + return (c > 0); + } + /** * Add given tag to the tags database and the starred-tag database */ public long addTag(Starred item, String tagName) { ContentValues values = new ContentValues(); values.put("tag", tagName); - database.insert(StarDatabase.TAGS_TABLE, null, values); + if (!hasTagNameInTagTable(tagName)) { + database.insert(StarDatabase.TAGS_TABLE, null, values); + } values = new ContentValues(); values.put("tag", getTagByTagName(tagName).getId()); @@ -241,10 +263,10 @@ public long addTag(Starred item, String tagName) { public void removeTag(Tag tag) { String[] selA = {"" + tag.getId()}; database.delete(StarDatabase.STAR_TAGS_TABLE, "tag=?", selA); - - selA = new String[]{"" + tag.getTagName()}; - database.delete(StarDatabase.TAGS_TABLE, "tag=?", selA); - + if (!hasTagIdInStarTagTable(tag.getId())) { + selA = new String[]{"" + tag.getTagName()}; + database.delete(StarDatabase.TAGS_TABLE, "tag=?", selA); + } } public Tag getTagByTagName(String tagName) { @@ -299,4 +321,44 @@ public List getAllTags(Starred item) { cursor.close(); return tags; } + + /** + * Get all tag names that belong to this Starred item + */ + public List getAllTagNames(Starred item) { + List tags = new ArrayList<>(); + String[] selA = {Integer.toString(item.getId())}; + Cursor cursor = database.query(StarDatabase.STAR_TAGS_TABLE, StarDatabase.STAR_TAGS_COLUMNS, "item = ?", selA, null, null, null); + + cursor.moveToFirst(); + while (!cursor.isAfterLast()) { + int tagId = cursorToStarAndTagId(cursor); + tags.add(getTagById(tagId).getTagName()); + cursor.moveToNext(); + } + // Make sure to close the cursor + cursor.close(); + return tags; + } + +// /** +// * Get all tags that do not belong to this Starred item +// */ +// public List getAllTagNamesExceptThisItem(Starred item) { +// List listOfTagNames = new ArrayList<>(); +// Cursor cursor = database.rawQuery("select * from " + StarDatabase.STAR_TAGS_TABLE, null); +// +// cursor.moveToFirst(); +// while (!cursor.isAfterLast()) { +// if (cursor.getInt(1) != item.getId()) { +// int tagId = cursorToStarAndTagId(cursor); +// listOfTagNames.add(getTagById(tagId).getTagName()); +// cursor.moveToNext(); +// } +// +// } +// // Make sure to close the cursor +// cursor.close(); +// return listOfTagNames; +// } } diff --git a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java index 3ea971583..22fc2d2bb 100644 --- a/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java +++ b/opacclient/opacapp/src/main/java/de/geeksfactory/opacclient/storage/StarDatabase.java @@ -36,7 +36,7 @@ public class StarDatabase extends SQLiteOpenHelper { + " ( id integer primary key autoincrement," + " medianr text," + " bib text," + " title text," + " mediatype text" + ");"; public static final String TAGS_DATABASE_CREATE = "create table " + TAGS_TABLE - + " ( id integer primary key autoincrement," +" tag text);"; + + " ( id integer primary key autoincrement," +" tag text unique);"; public static final String STAR_TAGS_DATABASE_CREATE = "create table " + STAR_TAGS_TABLE + " ( tag integer references tags (id)," + " item integer references starred (id)," + " primary key (tag, item)" diff --git a/opacclient/opacapp/src/main/res/drawable/ic_local_offer_black_24dp.xml b/opacclient/opacapp/src/main/res/drawable/ic_local_offer_black_24dp.xml new file mode 100644 index 000000000..8b19fe422 --- /dev/null +++ b/opacclient/opacapp/src/main/res/drawable/ic_local_offer_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/opacclient/opacapp/src/main/res/layout/listitem_starred.xml b/opacclient/opacapp/src/main/res/layout/listitem_starred.xml index a1a4dfba3..a4854ac35 100644 --- a/opacclient/opacapp/src/main/res/layout/listitem_starred.xml +++ b/opacclient/opacapp/src/main/res/layout/listitem_starred.xml @@ -36,16 +36,8 @@ android:padding="5dp" android:textAppearance="?android:attr/textAppearanceMedium"/> - - + android:contentDescription="@string/tag_menu" + app:srcCompat="@drawable/ic_local_offer_black_24dp" + tools:src="@drawable/ic_local_offer_black_24dp"/> - \ No newline at end of file diff --git a/opacclient/opacapp/src/main/res/layout/listitem_tag.xml b/opacclient/opacapp/src/main/res/layout/listitem_tag.xml new file mode 100644 index 000000000..ca32e27d8 --- /dev/null +++ b/opacclient/opacapp/src/main/res/layout/listitem_tag.xml @@ -0,0 +1,29 @@ + + + + + + + + \ No newline at end of file diff --git a/opacclient/opacapp/src/main/res/layout/tag_menu.xml b/opacclient/opacapp/src/main/res/layout/tag_menu.xml new file mode 100644 index 000000000..7b383208c --- /dev/null +++ b/opacclient/opacapp/src/main/res/layout/tag_menu.xml @@ -0,0 +1,34 @@ + + + + + + + + +