diff options
| author | Bananeweizen <bananeweizen@gmx.de> | 2013-09-14 07:51:24 +0200 |
|---|---|---|
| committer | Bananeweizen <bananeweizen@gmx.de> | 2013-09-14 07:51:24 +0200 |
| commit | 8987674ab4882f7684c773fc181f5a3fac5f8f12 (patch) | |
| tree | d54dbf08cbee8791c5cc7853bab55779a179c7d0 /main/src/cgeo/geocaching/list/StoredList.java | |
| parent | 7f42e219f58d14f7f4a8bf27886bb615c918a6b2 (diff) | |
| download | cgeo-8987674ab4882f7684c773fc181f5a3fac5f8f12.zip cgeo-8987674ab4882f7684c773fc181f5a3fac5f8f12.tar.gz cgeo-8987674ab4882f7684c773fc181f5a3fac5f8f12.tar.bz2 | |
refactoring: introduce PseudoList to handle non concrete lists
* should make adding a history list entry easier
* includes some non null annotations
* moved list code into separate package
Diffstat (limited to 'main/src/cgeo/geocaching/list/StoredList.java')
| -rw-r--r-- | main/src/cgeo/geocaching/list/StoredList.java | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/list/StoredList.java b/main/src/cgeo/geocaching/list/StoredList.java new file mode 100644 index 0000000..f1632c4 --- /dev/null +++ b/main/src/cgeo/geocaching/list/StoredList.java @@ -0,0 +1,217 @@ +package cgeo.geocaching.list; + +import cgeo.geocaching.CgeoApplication; +import cgeo.geocaching.DataStore; +import cgeo.geocaching.R; +import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.utils.RunnableWithArgument; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.res.Resources; +import android.view.View; +import android.widget.EditText; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public final class StoredList extends AbstractList { + public static final int TEMPORARY_LIST_ID = 0; + public static final int STANDARD_LIST_ID = 1; + private final int count; // this value is only valid as long as the list is not changed by other database operations + + public StoredList(int id, String title, int count) { + super(id, title); + this.count = count; + } + + @Override + public String getTitleAndCount() { + return title + " [" + count + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + id; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof StoredList)) { + return false; + } + return id == ((StoredList) obj).id; + } + + public static class UserInterface { + private final Activity activity; + private final CgeoApplication app; + private final Resources res; + + public UserInterface(final Activity activity) { + this.activity = activity; + app = CgeoApplication.getInstance(); + res = app.getResources(); + } + + public void promptForListSelection(final int titleId, @NonNull final RunnableWithArgument<Integer> runAfterwards) { + promptForListSelection(titleId, runAfterwards, false, -1); + } + + public void promptForListSelection(final int titleId, @NonNull final RunnableWithArgument<Integer> runAfterwards, final boolean onlyConcreteLists, final int exceptListId) { + promptForListSelection(titleId, runAfterwards, onlyConcreteLists, exceptListId, StringUtils.EMPTY); + } + + public void promptForListSelection(final int titleId, @NonNull final RunnableWithArgument<Integer> runAfterwards, final boolean onlyConcreteLists, final int exceptListId, final String newListName) { + final List<AbstractList> lists = new ArrayList<AbstractList>(); + lists.addAll(getSortedLists()); + + if (exceptListId > StoredList.TEMPORARY_LIST_ID) { + StoredList exceptList = DataStore.getList(exceptListId); + if (exceptList != null) { + lists.remove(exceptList); + } + } + + if (!onlyConcreteLists) { + lists.add(PseudoList.ALL_LIST); + } + + final List<CharSequence> listsTitle = new ArrayList<CharSequence>(); + for (AbstractList list : lists) { + listsTitle.add(list.getTitleAndCount()); + } + listsTitle.add("<" + res.getString(R.string.list_menu_create) + ">"); + + final CharSequence[] items = new CharSequence[listsTitle.size()]; + + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setTitle(res.getString(titleId)); + builder.setItems(listsTitle.toArray(items), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int itemId) { + if (itemId >= lists.size()) { + // create new list on the fly + promptForListCreation(runAfterwards, newListName); + } + else { + runAfterwards.run(lists.get(itemId).id); + } + } + }); + builder.create().show(); + } + + @NonNull + private static List<StoredList> getSortedLists() { + final Collator collator = Collator.getInstance(); + final List<StoredList> lists = DataStore.getLists(); + Collections.sort(lists, new Comparator<StoredList>() { + + @Override + public int compare(StoredList lhs, StoredList rhs) { + // have the standard list at the top + if (lhs.id == STANDARD_LIST_ID) { + return -1; + } + if (rhs.id == STANDARD_LIST_ID) { + return 1; + } + // otherwise sort alphabetical + return collator.compare(lhs.getTitle(), rhs.getTitle()); + } + }); + return lists; + } + + public void promptForListCreation(@NonNull final RunnableWithArgument<Integer> runAfterwards, String newListName) { + handleListNameInput(newListName, R.string.list_dialog_create_title, R.string.list_dialog_create, new RunnableWithArgument<String>() { + + @Override + public void run(final String listName) { + final int newId = DataStore.createList(listName); + + if (newId >= DataStore.customListIdOffset) { + ActivityMixin.showToast(activity, res.getString(R.string.list_dialog_create_ok)); + runAfterwards.run(newId); + } else { + ActivityMixin.showToast(activity, res.getString(R.string.list_dialog_create_err)); + } + } + }); + } + + private void handleListNameInput(final String defaultValue, int dialogTitle, int buttonTitle, final RunnableWithArgument<String> runnable) { + final AlertDialog.Builder alert = new AlertDialog.Builder(activity); + final View view = activity.getLayoutInflater().inflate(R.layout.list_create_dialog, null); + final EditText input = (EditText) view.findViewById(R.id.text); + input.setText(defaultValue); + + alert.setTitle(dialogTitle); + alert.setView(view); + alert.setPositiveButton(buttonTitle, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int whichButton) { + // remove whitespaces added by autocompletion of Android keyboard + String listName = StringUtils.trim(input.getText().toString()); + if (StringUtils.isNotBlank(listName)) { + runnable.run(listName); + } + } + }); + alert.setNegativeButton(res.getString(R.string.list_dialog_cancel), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int whichButton) { + dialog.dismiss(); + } + }); + + alert.show(); + } + + public void promptForListRename(final int listId, @NonNull final Runnable runAfterRename) { + final StoredList list = DataStore.getList(listId); + handleListNameInput(list.title, R.string.list_dialog_rename_title, R.string.list_dialog_rename, new RunnableWithArgument<String>() { + + @Override + public void run(final String listName) { + DataStore.renameList(listId, listName); + runAfterRename.run(); + } + }); + } + } + + /** + * Get the list title. This method is not public by intention to make clients use the {@link UserInterface} class. + * + * @return + */ + protected String getTitle() { + return title; + } + + /** + * Return the given list, if it is a concrete list. Return the default list otherwise. + */ + public static int getConcreteList(int listId) { + if (listId == PseudoList.ALL_LIST_ID || listId == TEMPORARY_LIST_ID) { + return STANDARD_LIST_ID; + } + return listId; + } + +} |
