Allow managing and adding tags
This commit is contained in:
parent
37d75491f4
commit
11b9d0164a
9 changed files with 295 additions and 42 deletions
|
@ -79,6 +79,8 @@ So make sure you have a **current backup** before switching!
|
||||||
|
|
||||||
* [Carlos Melero](https://github.com/carmebar) ([view contributions](https://github.com/flocke/andOTP/commits/master?author=carmebar))
|
* [Carlos Melero](https://github.com/carmebar) ([view contributions](https://github.com/flocke/andOTP/commits/master?author=carmebar))
|
||||||
* [SuperVirus](https://github.com/SuperVirus) ([view contributions](https://github.com/flocke/andOTP/commits/master?author=SuperVirus))
|
* [SuperVirus](https://github.com/SuperVirus) ([view contributions](https://github.com/flocke/andOTP/commits/master?author=SuperVirus))
|
||||||
|
* [RichyHBM](https://github.com/RichyHBM) ([view contributions](https://github.com/flocke/andOTP/commits/master?author=RichyHBM))
|
||||||
|
|
||||||
|
|
||||||
#### Translators:
|
#### Translators:
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ import android.view.WindowManager;
|
||||||
import android.view.animation.LinearInterpolator;
|
import android.view.animation.LinearInterpolator;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
import android.widget.CheckedTextView;
|
import android.widget.CheckedTextView;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
@ -59,7 +60,9 @@ import android.widget.Toast;
|
||||||
import com.google.zxing.integration.android.IntentIntegrator;
|
import com.google.zxing.integration.android.IntentIntegrator;
|
||||||
import com.google.zxing.integration.android.IntentResult;
|
import com.google.zxing.integration.android.IntentResult;
|
||||||
|
|
||||||
|
import org.shadowice.flocke.andotp.Utilities.DatabaseHelper;
|
||||||
import org.shadowice.flocke.andotp.Utilities.Settings;
|
import org.shadowice.flocke.andotp.Utilities.Settings;
|
||||||
|
import org.shadowice.flocke.andotp.Utilities.TagDialogHelper;
|
||||||
import org.shadowice.flocke.andotp.View.EntriesCardAdapter;
|
import org.shadowice.flocke.andotp.View.EntriesCardAdapter;
|
||||||
import org.shadowice.flocke.andotp.Database.Entry;
|
import org.shadowice.flocke.andotp.Database.Entry;
|
||||||
import org.shadowice.flocke.andotp.View.FloatingActionMenu;
|
import org.shadowice.flocke.andotp.View.FloatingActionMenu;
|
||||||
|
@ -69,9 +72,12 @@ import org.shadowice.flocke.andotp.Utilities.TokenCalculator;
|
||||||
import org.shadowice.flocke.andotp.View.TagsAdapter;
|
import org.shadowice.flocke.andotp.View.TagsAdapter;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
import static org.shadowice.flocke.andotp.Utilities.Settings.SortMode;
|
import static org.shadowice.flocke.andotp.Utilities.Settings.SortMode;
|
||||||
|
|
||||||
|
@ -115,6 +121,7 @@ public class MainActivity extends BaseActivity
|
||||||
final EditText periodInput = inputView.findViewById(R.id.manual_period);
|
final EditText periodInput = inputView.findViewById(R.id.manual_period);
|
||||||
final EditText digitsInput = inputView.findViewById(R.id.manual_digits);
|
final EditText digitsInput = inputView.findViewById(R.id.manual_digits);
|
||||||
final Spinner algorithmInput = inputView.findViewById(R.id.manual_algorithm);
|
final Spinner algorithmInput = inputView.findViewById(R.id.manual_algorithm);
|
||||||
|
final Button tagsInput = inputView.findViewById(R.id.manual_tags);
|
||||||
|
|
||||||
final ArrayAdapter<TokenCalculator.HashAlgorithm> algorithmAdapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, TokenCalculator.HashAlgorithm.values());
|
final ArrayAdapter<TokenCalculator.HashAlgorithm> algorithmAdapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, TokenCalculator.HashAlgorithm.values());
|
||||||
final ArrayAdapter<Entry.OTPType> typeAdapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, Entry.PublicTypes.toArray(new Entry.OTPType[Entry.PublicTypes.size()]));
|
final ArrayAdapter<Entry.OTPType> typeAdapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, Entry.PublicTypes.toArray(new Entry.OTPType[Entry.PublicTypes.size()]));
|
||||||
|
@ -157,6 +164,36 @@ public class MainActivity extends BaseActivity
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
List<String> allTags = adapter.getTags();
|
||||||
|
HashMap<String, Boolean> tagsHashMap = new HashMap<>();
|
||||||
|
for(String tag: allTags) {
|
||||||
|
tagsHashMap.put(tag, false);
|
||||||
|
}
|
||||||
|
final TagsAdapter tagsAdapter = new TagsAdapter(this, tagsHashMap);
|
||||||
|
|
||||||
|
final Callable tagsCallable = new Callable() {
|
||||||
|
@Override
|
||||||
|
public Object call() throws Exception {
|
||||||
|
List<String> selectedTags = tagsAdapter.getActiveTags();
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for(int j = 0; j < selectedTags.size(); j++) {
|
||||||
|
stringBuilder.append(selectedTags.get(j));
|
||||||
|
if(j < selectedTags.size() - 1) {
|
||||||
|
stringBuilder.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tagsInput.setText(stringBuilder.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
tagsInput.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
TagDialogHelper.createTagsDialog(MainActivity.this, tagsAdapter, tagsCallable, tagsCallable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setTitle(R.string.dialog_title_manual_entry)
|
builder.setTitle(R.string.dialog_title_manual_entry)
|
||||||
.setView(inputView)
|
.setView(inputView)
|
||||||
|
@ -172,7 +209,7 @@ public class MainActivity extends BaseActivity
|
||||||
int period = Integer.parseInt(periodInput.getText().toString());
|
int period = Integer.parseInt(periodInput.getText().toString());
|
||||||
int digits = Integer.parseInt(digitsInput.getText().toString());
|
int digits = Integer.parseInt(digitsInput.getText().toString());
|
||||||
|
|
||||||
Entry e = new Entry(type, secret, period, digits, label, algorithm, new ArrayList<String>());
|
Entry e = new Entry(type, secret, period, digits, label, algorithm, tagsAdapter.getActiveTags());
|
||||||
e.updateOTP();
|
e.updateOTP();
|
||||||
adapter.addEntry(e);
|
adapter.addEntry(e);
|
||||||
adapter.saveEntries();
|
adapter.saveEntries();
|
||||||
|
@ -288,7 +325,14 @@ public class MainActivity extends BaseActivity
|
||||||
llm.setOrientation(LinearLayoutManager.VERTICAL);
|
llm.setOrientation(LinearLayoutManager.VERTICAL);
|
||||||
recList.setLayoutManager(llm);
|
recList.setLayoutManager(llm);
|
||||||
|
|
||||||
adapter = new EntriesCardAdapter(this);
|
HashMap<String, Boolean> tagsHashMap = new HashMap<>();
|
||||||
|
for(Entry entry : DatabaseHelper.loadDatabase(this)) {
|
||||||
|
for(String tag : entry.getTags())
|
||||||
|
tagsHashMap.put(tag, settings.getTagToggle(tag));
|
||||||
|
}
|
||||||
|
tagsDrawerAdapter = new TagsAdapter(this, tagsHashMap);
|
||||||
|
|
||||||
|
adapter = new EntriesCardAdapter(this, tagsDrawerAdapter);
|
||||||
recList.setAdapter(adapter);
|
recList.setAdapter(adapter);
|
||||||
|
|
||||||
recList.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
recList.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
|
@ -582,9 +626,6 @@ public class MainActivity extends BaseActivity
|
||||||
});
|
});
|
||||||
allTagsButton.setChecked(settings.getAllTagsToggle());
|
allTagsButton.setChecked(settings.getAllTagsToggle());
|
||||||
|
|
||||||
List<String> sortedTags = adapter.getTags();
|
|
||||||
Collections.sort(sortedTags);
|
|
||||||
tagsDrawerAdapter = new TagsAdapter(this, sortedTags);
|
|
||||||
tagsDrawerListView.setAdapter(tagsDrawerAdapter);
|
tagsDrawerListView.setAdapter(tagsDrawerAdapter);
|
||||||
|
|
||||||
tagsDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
tagsDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
|
@ -594,33 +635,27 @@ public class MainActivity extends BaseActivity
|
||||||
checkedTextView.setChecked(!checkedTextView.isChecked());
|
checkedTextView.setChecked(!checkedTextView.isChecked());
|
||||||
|
|
||||||
settings.setTagToggle(checkedTextView.getText().toString(), checkedTextView.isChecked());
|
settings.setTagToggle(checkedTextView.getText().toString(), checkedTextView.isChecked());
|
||||||
|
tagsDrawerAdapter.setTagState(checkedTextView.getText().toString(), checkedTextView.isChecked());
|
||||||
List<String> checkedTags = new ArrayList<>();
|
adapter.filterByTags(tagsDrawerAdapter.getActiveTags());
|
||||||
for(int i = 0; i < tagsDrawerListView.getChildCount(); i++) {
|
|
||||||
CheckedTextView childCheckBox = (CheckedTextView)tagsDrawerListView.getChildAt(i);
|
|
||||||
if(childCheckBox.isChecked()) {
|
|
||||||
checkedTags.add(childCheckBox.getText().toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
adapter.filterByTags(checkedTags);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
adapter.filterByTags(getCheckedTags());
|
adapter.filterByTags(tagsDrawerAdapter.getActiveTags());
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshTags() {
|
void refreshTags() {
|
||||||
tagsDrawerAdapter.setTags(adapter.getTags());
|
HashMap<String, Boolean> tagsHashMap = new HashMap<>();
|
||||||
adapter.filterByTags(getCheckedTags());
|
for(String tag: tagsDrawerAdapter.getTags()) {
|
||||||
}
|
tagsHashMap.put(tag, false);
|
||||||
|
|
||||||
List<String> getCheckedTags() {
|
|
||||||
List<String> checkedTags = new ArrayList<>();
|
|
||||||
for(String tag : adapter.getTags()) {
|
|
||||||
if(settings.getTagToggle(tag)) {
|
|
||||||
checkedTags.add(tag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return checkedTags;
|
for(String tag: tagsDrawerAdapter.getActiveTags()) {
|
||||||
|
tagsHashMap.put(tag, true);
|
||||||
|
}
|
||||||
|
for(String tag: adapter.getTags()) {
|
||||||
|
if(!tagsHashMap.containsKey(tag))
|
||||||
|
tagsHashMap.put(tag, true);
|
||||||
|
}
|
||||||
|
tagsDrawerAdapter.setTags(tagsHashMap);
|
||||||
|
adapter.filterByTags(tagsDrawerAdapter.getActiveTags());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -65,7 +65,7 @@ public class Entry {
|
||||||
|
|
||||||
public Entry(){}
|
public Entry(){}
|
||||||
|
|
||||||
public Entry(OTPType type, String secret, int period, int digits, String label, TokenCalculator.HashAlgorithm algorithm, ArrayList<String> tags) {
|
public Entry(OTPType type, String secret, int period, int digits, String label, TokenCalculator.HashAlgorithm algorithm, List<String> tags) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.secret = new Base32().decode(secret.toUpperCase());
|
this.secret = new Base32().decode(secret.toUpperCase());
|
||||||
this.period = period;
|
this.period = period;
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
package org.shadowice.flocke.andotp.Utilities;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AbsListView;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CheckedTextView;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import org.shadowice.flocke.andotp.Database.Entry;
|
||||||
|
import org.shadowice.flocke.andotp.R;
|
||||||
|
import org.shadowice.flocke.andotp.View.EntriesCardAdapter;
|
||||||
|
import org.shadowice.flocke.andotp.View.TagsAdapter;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class TagDialogHelper {
|
||||||
|
public static void createTagsDialog(Context context, final TagsAdapter tagsAdapter, final Callable newTagCallable, final Callable selectedTagsCallable) {
|
||||||
|
final EditText input = new EditText(context);
|
||||||
|
|
||||||
|
final AlertDialog.Builder newTagBuilder = new AlertDialog.Builder(context);
|
||||||
|
newTagBuilder.setTitle(R.string.button_new_tag)
|
||||||
|
.setView(input)
|
||||||
|
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
String newTag = input.getText().toString();
|
||||||
|
HashMap<String, Boolean> allTags = tagsAdapter.getTagsWithState();
|
||||||
|
allTags.put(newTag, true);
|
||||||
|
tagsAdapter.setTags(allTags);
|
||||||
|
if(newTagCallable != null) {
|
||||||
|
try {
|
||||||
|
newTagCallable.call();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
final ListView tagsSelectionView = new ListView(context);
|
||||||
|
tagsSelectionView.setAdapter(tagsAdapter);
|
||||||
|
tagsSelectionView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
CheckedTextView checkedTextView = ((CheckedTextView)view);
|
||||||
|
checkedTextView.setChecked(!checkedTextView.isChecked());
|
||||||
|
|
||||||
|
tagsAdapter.setTagState(checkedTextView.getText().toString(), checkedTextView.isChecked());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final AlertDialog.Builder tagsSelectorBuilder = new AlertDialog.Builder(context);
|
||||||
|
tagsSelectorBuilder.setTitle(R.string.label_tags)
|
||||||
|
.setView(tagsSelectionView)
|
||||||
|
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
dialogInterface.dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
if(selectedTagsCallable != null) {
|
||||||
|
try {
|
||||||
|
selectedTagsCallable.call();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNeutralButton(R.string.button_new_tag, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
newTagBuilder.create().show();
|
||||||
|
}
|
||||||
|
}).create().show();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import org.shadowice.flocke.andotp.Database.Entry;
|
import org.shadowice.flocke.andotp.Database.Entry;
|
||||||
import org.shadowice.flocke.andotp.Utilities.DatabaseHelper;
|
import org.shadowice.flocke.andotp.Utilities.DatabaseHelper;
|
||||||
|
import org.shadowice.flocke.andotp.Utilities.TagDialogHelper;
|
||||||
import org.shadowice.flocke.andotp.View.ItemTouchHelper.ItemTouchHelperAdapter;
|
import org.shadowice.flocke.andotp.View.ItemTouchHelper.ItemTouchHelperAdapter;
|
||||||
import org.shadowice.flocke.andotp.R;
|
import org.shadowice.flocke.andotp.R;
|
||||||
|
|
||||||
|
@ -52,8 +53,10 @@ import static org.shadowice.flocke.andotp.Utilities.Settings.SortMode;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
||||||
implements ItemTouchHelperAdapter, Filterable {
|
implements ItemTouchHelperAdapter, Filterable {
|
||||||
|
@ -66,11 +69,12 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
||||||
private List<String> tagsFilter = new ArrayList<>();
|
private List<String> tagsFilter = new ArrayList<>();
|
||||||
|
|
||||||
private SortMode sortMode = SortMode.UNSORTED;
|
private SortMode sortMode = SortMode.UNSORTED;
|
||||||
|
private TagsAdapter tagsFilterAdapter;
|
||||||
|
|
||||||
public EntriesCardAdapter(Context context) {
|
public EntriesCardAdapter(Context context, TagsAdapter tagsFilterAdapter) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
this.sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
this.tagsFilterAdapter = tagsFilterAdapter;
|
||||||
loadEntries();
|
loadEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,6 +256,50 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void editEntryTags(final int pos) {
|
||||||
|
final Entry entry = displayedEntries.get(pos);
|
||||||
|
|
||||||
|
HashMap<String, Boolean> tagsHashMap = new HashMap<>();
|
||||||
|
for(String tag: entry.getTags()) {
|
||||||
|
tagsHashMap.put(tag, true);
|
||||||
|
}
|
||||||
|
for(String tag: getTags()) {
|
||||||
|
if(!tagsHashMap.containsKey(tag))
|
||||||
|
tagsHashMap.put(tag, false);
|
||||||
|
}
|
||||||
|
final TagsAdapter tagsAdapter = new TagsAdapter(context, tagsHashMap);
|
||||||
|
|
||||||
|
final Callable tagsCallable = new Callable() {
|
||||||
|
@Override
|
||||||
|
public Object call() throws Exception {
|
||||||
|
entry.setTags(tagsAdapter.getActiveTags());
|
||||||
|
|
||||||
|
List<String> inUseTags = getTags();
|
||||||
|
|
||||||
|
HashMap<String, Boolean> tagsHashMap = new HashMap<>();
|
||||||
|
for(String tag: tagsFilterAdapter.getTags()) {
|
||||||
|
if(inUseTags.contains(tag))
|
||||||
|
tagsHashMap.put(tag, false);
|
||||||
|
}
|
||||||
|
for(String tag: tagsFilterAdapter.getActiveTags()) {
|
||||||
|
if(inUseTags.contains(tag))
|
||||||
|
tagsHashMap.put(tag, true);
|
||||||
|
}
|
||||||
|
for(String tag: getTags()) {
|
||||||
|
if(inUseTags.contains(tag))
|
||||||
|
if(!tagsHashMap.containsKey(tag))
|
||||||
|
tagsHashMap.put(tag, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
tagsFilterAdapter.setTags(tagsHashMap);
|
||||||
|
filterByTags(tagsFilterAdapter.getActiveTags());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TagDialogHelper.createTagsDialog(context, tagsAdapter, tagsCallable, tagsCallable);
|
||||||
|
}
|
||||||
|
|
||||||
public void removeItem(final int pos) {
|
public void removeItem(final int pos) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
|
||||||
|
@ -290,6 +338,9 @@ public class EntriesCardAdapter extends RecyclerView.Adapter<EntryViewHolder>
|
||||||
if (id == R.id.menu_popup_editLabel) {
|
if (id == R.id.menu_popup_editLabel) {
|
||||||
editEntryLabel(pos);
|
editEntryLabel(pos);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (id == R.id.menu_popup_editTags) {
|
||||||
|
editEntryTags(pos);
|
||||||
|
return true;
|
||||||
} else if (id == R.id.menu_popup_remove) {
|
} else if (id == R.id.menu_popup_remove) {
|
||||||
removeItem(pos);
|
removeItem(pos);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package org.shadowice.flocke.andotp.View;
|
package org.shadowice.flocke.andotp.View;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.util.Pair;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -9,40 +11,81 @@ import android.widget.CheckedTextView;
|
||||||
|
|
||||||
import org.shadowice.flocke.andotp.Utilities.Settings;
|
import org.shadowice.flocke.andotp.Utilities.Settings;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.ListIterator;
|
||||||
|
|
||||||
public class TagsAdapter extends ArrayAdapter<String> {
|
public class TagsAdapter extends ArrayAdapter<String> {
|
||||||
private Context context;
|
private Context context;
|
||||||
private Settings settings;
|
private List<String> tagsOrder;
|
||||||
private List<String> tags;
|
private HashMap<String, Boolean> tagsState;
|
||||||
private static final int layoutResourceId = android.R.layout.simple_list_item_multiple_choice;
|
private static final int layoutResourceId = android.R.layout.simple_list_item_multiple_choice;
|
||||||
|
|
||||||
public TagsAdapter(Context context, List<String> tags) {
|
public TagsAdapter(Context context, HashMap<String, Boolean> tags) {
|
||||||
super(context, layoutResourceId, tags);
|
super(context, layoutResourceId, new ArrayList<>(tags.keySet()));
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.settings = new Settings(context);
|
|
||||||
this.tags = tags;
|
this.tagsState = tags;
|
||||||
|
this.tagsOrder = new ArrayList<>(tagsState.keySet());
|
||||||
|
Collections.sort(this.tagsOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public View getView(int i, View view, ViewGroup viewGroup) {
|
public View getView(int i, View view, @NonNull ViewGroup viewGroup) {
|
||||||
CheckedTextView checkedTextView;
|
CheckedTextView checkedTextView;
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
checkedTextView = (CheckedTextView)LayoutInflater.from(context).inflate(layoutResourceId, viewGroup, false);
|
checkedTextView = (CheckedTextView)LayoutInflater.from(context).inflate(layoutResourceId, viewGroup, false);
|
||||||
} else{
|
} else{
|
||||||
checkedTextView = (CheckedTextView) view;
|
checkedTextView = (CheckedTextView) view;
|
||||||
}
|
}
|
||||||
checkedTextView.setText(tags.get(i));
|
checkedTextView.setText(tagsOrder.get(i));
|
||||||
checkedTextView.setChecked(settings.getTagToggle(tags.get(i)));
|
checkedTextView.setChecked(tagsState.get(tagsOrder.get(i)));
|
||||||
|
|
||||||
return checkedTextView;
|
return checkedTextView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTags(List<String> tags) {
|
public List<String> getTags() {
|
||||||
this.tags = tags;
|
return tagsOrder;
|
||||||
Collections.sort(this.tags);
|
}
|
||||||
|
|
||||||
|
public Boolean getTagState(String tag) {
|
||||||
|
if(tagsState.containsKey(tag))
|
||||||
|
return tagsState.get(tag);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagState(String tag, Boolean state) {
|
||||||
|
if(tagsState.containsKey(tag))
|
||||||
|
tagsState.put(tag, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getActiveTags() {
|
||||||
|
List<String> tagsList = new ArrayList<>();
|
||||||
|
for(String tag : tagsOrder)
|
||||||
|
{
|
||||||
|
if(tagsState.get(tag)) {
|
||||||
|
tagsList.add(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tagsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String, Boolean> getTagsWithState() {
|
||||||
|
return new HashMap<String, Boolean>(tagsState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTags(HashMap<String, Boolean> tags) {
|
||||||
|
this.tagsState = tags;
|
||||||
|
this.tagsOrder = new ArrayList<>(tagsState.keySet());
|
||||||
|
Collections.sort(this.tagsOrder);
|
||||||
|
|
||||||
this.clear();
|
this.clear();
|
||||||
this.addAll(this.tags);
|
this.addAll(getTags());
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,4 +127,25 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_weight="2"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/label_tags"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/manual_tags"
|
||||||
|
style="?android:attr/spinnerStyle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="7"
|
||||||
|
android:textAlignment="textEnd" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -5,6 +5,10 @@
|
||||||
android:id="@+id/menu_popup_editLabel"
|
android:id="@+id/menu_popup_editLabel"
|
||||||
android:title="@string/menu_popup_edit_label" />
|
android:title="@string/menu_popup_edit_label" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_popup_editTags"
|
||||||
|
android:title="@string/menu_popup_edit_tags" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_popup_remove"
|
android:id="@+id/menu_popup_remove"
|
||||||
android:title="@string/menu_popup_remove" />
|
android:title="@string/menu_popup_remove" />
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
<string name="button_enter_details">Enter details</string>
|
<string name="button_enter_details">Enter details</string>
|
||||||
<string name="button_scan_qr">Scan QR-Code</string>
|
<string name="button_scan_qr">Scan QR-Code</string>
|
||||||
<string name="button_save">Save</string>
|
<string name="button_save">Save</string>
|
||||||
|
<string name="button_new_tag">New tag</string>
|
||||||
<string name="button_warned">You have been warned!</string>
|
<string name="button_warned">You have been warned!</string>
|
||||||
<string name="button_all_tags">All tags</string>
|
<string name="button_all_tags">All tags</string>
|
||||||
|
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
<string name="menu_sort_label">Label</string>
|
<string name="menu_sort_label">Label</string>
|
||||||
|
|
||||||
<string name="menu_popup_edit_label">Edit label</string>
|
<string name="menu_popup_edit_label">Edit label</string>
|
||||||
|
<string name="menu_popup_edit_tags">Edit tags</string>
|
||||||
<string name="menu_popup_remove">Remove</string>
|
<string name="menu_popup_remove">Remove</string>
|
||||||
|
|
||||||
<!-- Toast messages -->
|
<!-- Toast messages -->
|
||||||
|
|
Loading…
Reference in a new issue