diff options
Diffstat (limited to 'main/src/cgeo/geocaching/filter')
24 files changed, 589 insertions, 339 deletions
diff --git a/main/src/cgeo/geocaching/filter/AbstractFilter.java b/main/src/cgeo/geocaching/filter/AbstractFilter.java index e602b0f..4d521c5 100644 --- a/main/src/cgeo/geocaching/filter/AbstractFilter.java +++ b/main/src/cgeo/geocaching/filter/AbstractFilter.java @@ -1,21 +1,30 @@ package cgeo.geocaching.filter; +import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.Geocache; +import org.eclipse.jdt.annotation.NonNull; + import java.util.ArrayList; import java.util.List; abstract class AbstractFilter implements IFilter { + @NonNull private final String name; - protected AbstractFilter(final String name) { + protected AbstractFilter(final int nameResourceId) { + this(CgeoApplication.getInstance().getString(nameResourceId)); + } + + protected AbstractFilter(@NonNull final String name) { this.name = name; } + @Override - public void filter(final List<Geocache> list) { + public void filter(@NonNull final List<Geocache> list) { final List<Geocache> itemsToRemove = new ArrayList<>(); - for (Geocache item : list) { + for (final Geocache item : list) { if (!accepts(item)) { itemsToRemove.add(item); } @@ -24,6 +33,7 @@ abstract class AbstractFilter implements IFilter { } @Override + @NonNull public String getName() { return name; } @@ -37,4 +47,9 @@ abstract class AbstractFilter implements IFilter { public String toString() { return getName(); } + + @Override + public int getImageId() { + return 0; + } } diff --git a/main/src/cgeo/geocaching/filter/AttributeFilter.java b/main/src/cgeo/geocaching/filter/AttributeFilter.java index b59ab29..6ed4a8f 100644 --- a/main/src/cgeo/geocaching/filter/AttributeFilter.java +++ b/main/src/cgeo/geocaching/filter/AttributeFilter.java @@ -4,6 +4,8 @@ import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.Geocache; import cgeo.geocaching.R; +import org.eclipse.jdt.annotation.NonNull; + import android.content.res.Resources; import java.util.LinkedList; @@ -13,7 +15,7 @@ class AttributeFilter extends AbstractFilter { private final String attribute; - public AttributeFilter(final String name, final String attribute) { + public AttributeFilter(@NonNull final String name, final String attribute) { super(name); this.attribute = attribute; } @@ -25,13 +27,14 @@ class AttributeFilter extends AbstractFilter { } @Override - public boolean accepts(final Geocache cache) { + public boolean accepts(@NonNull final Geocache cache) { return cache.getAttributes().contains(attribute); } public static class Factory implements IFilterFactory { @Override + @NonNull public List<IFilter> getFilters() { final String packageName = CgeoApplication.getInstance().getBaseContext().getPackageName(); final Resources res = CgeoApplication.getInstance().getResources(); diff --git a/main/src/cgeo/geocaching/filter/DifficultyFilter.java b/main/src/cgeo/geocaching/filter/DifficultyFilter.java index 175ad75..7989560 100644 --- a/main/src/cgeo/geocaching/filter/DifficultyFilter.java +++ b/main/src/cgeo/geocaching/filter/DifficultyFilter.java @@ -3,6 +3,8 @@ package cgeo.geocaching.filter; import cgeo.geocaching.Geocache; import cgeo.geocaching.R; +import org.eclipse.jdt.annotation.NonNull; + import java.util.ArrayList; import java.util.List; @@ -13,7 +15,7 @@ class DifficultyFilter extends AbstractRangeFilter { } @Override - public boolean accepts(final Geocache cache) { + public boolean accepts(@NonNull final Geocache cache) { final float difficulty = cache.getDifficulty(); return rangeMin <= difficulty && difficulty < rangeMax; } @@ -24,6 +26,7 @@ class DifficultyFilter extends AbstractRangeFilter { private static final int DIFFICULTY_MAX = 5; @Override + @NonNull public List<IFilter> getFilters() { final ArrayList<IFilter> filters = new ArrayList<>(DIFFICULTY_MAX); for (int difficulty = DIFFICULTY_MIN; difficulty <= DIFFICULTY_MAX; difficulty++) { diff --git a/main/src/cgeo/geocaching/filter/DistanceFilter.java b/main/src/cgeo/geocaching/filter/DistanceFilter.java index 3328c72..b352f5d 100644 --- a/main/src/cgeo/geocaching/filter/DistanceFilter.java +++ b/main/src/cgeo/geocaching/filter/DistanceFilter.java @@ -2,28 +2,31 @@ package cgeo.geocaching.filter; import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.Geocache; -import cgeo.geocaching.sensors.IGeoData; import cgeo.geocaching.R; -import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.location.Geopoint; +import cgeo.geocaching.sensors.GeoData; +import cgeo.geocaching.sensors.Sensors; + +import org.eclipse.jdt.annotation.NonNull; import java.util.ArrayList; import java.util.List; class DistanceFilter extends AbstractFilter { - private final IGeoData geo; + private final GeoData geo; private final int minDistance; private final int maxDistance; - public DistanceFilter(String name, final int minDistance, final int maxDistance) { + public DistanceFilter(@NonNull final String name, final int minDistance, final int maxDistance) { super(name); this.minDistance = minDistance; this.maxDistance = maxDistance; - geo = CgeoApplication.getInstance().currentGeo(); + geo = Sensors.getInstance().currentGeo(); } @Override - public boolean accepts(final Geocache cache) { - final Geopoint currentPos = new Geopoint(geo.getLocation()); + public boolean accepts(@NonNull final Geocache cache) { + final Geopoint currentPos = new Geopoint(geo); final Geopoint coords = cache.getCoords(); if (coords == null) { // If a cache has no coordinates, consider it to be out of range. It will @@ -39,6 +42,7 @@ class DistanceFilter extends AbstractFilter { private static final int[] KILOMETERS = { 0, 2, 5, 10, 20, 50 }; @Override + @NonNull public List<IFilter> getFilters() { final List<IFilter> filters = new ArrayList<>(KILOMETERS.length); for (int i = 0; i < KILOMETERS.length; i++) { diff --git a/main/src/cgeo/geocaching/filter/FilterActivity.java b/main/src/cgeo/geocaching/filter/FilterActivity.java new file mode 100644 index 0000000..13a2263 --- /dev/null +++ b/main/src/cgeo/geocaching/filter/FilterActivity.java @@ -0,0 +1,154 @@ +package cgeo.geocaching.filter; + +import butterknife.ButterKnife; +import butterknife.InjectView; + +import cgeo.geocaching.R; +import cgeo.geocaching.activity.AbstractActionBarActivity; +import cgeo.geocaching.filter.FilterRegistry.FactoryEntry; +import cgeo.geocaching.utils.Log; + +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.OptionsItem; +import org.androidannotations.annotations.OptionsMenu; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.ExpandableListView; +import android.widget.ExpandableListView.OnChildClickListener; +import android.widget.LinearLayout; +import android.widget.SimpleExpandableListAdapter; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Show a filter selection using an {@code ExpandableListView}. + */ +@OptionsMenu(R.menu.filter_options) +@EActivity +public class FilterActivity extends AbstractActionBarActivity { + + public static final String EXTRA_FILTER_RESULT = null; + public static final int REQUEST_SELECT_FILTER = 1234; + + private static final String KEY_FILTER_NAME = "filterName"; + private static final String KEY_FILTER_GROUP_NAME = "filterGroupName"; + + @InjectView(R.id.filterList) protected ExpandableListView filterList; + @InjectView(R.id.filters) protected LinearLayout filtersContainer; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState, R.layout.filter_activity); + ButterKnife.inject(this); + + createListAdapter(); + } + + private void createListAdapter() { + final SimpleExpandableListAdapter adapter = + new SimpleExpandableListAdapter( + this, + // top level entries in the next 4 lines + createFilterTopLevelGroups(), + android.R.layout.simple_expandable_list_item_1, + new String[] { KEY_FILTER_GROUP_NAME }, + new int[] { android.R.id.text1 }, + + // child level entries in the next 4 lines + createFilterChildren(), + android.R.layout.simple_expandable_list_item_2, + new String[] { KEY_FILTER_NAME, "CHILD_NAME" }, + new int[] { android.R.id.text1 } + ); + filterList.setAdapter(adapter); + filterList.setOnChildClickListener(new OnChildClickListener() { + + @Override + public boolean onChildClick(final ExpandableListView parent, final View v, final int groupPosition, final int childPosition, final long id) { + setFilterResult(groupPosition, childPosition); + return true; + } + + }); + } + + public static @Nullable IFilter getFilterFromPosition(final int groupPosition, final int childPosition) { + if (groupPosition < 0 || childPosition < 0) { + return null; + } + final FactoryEntry factoryEntry = FilterRegistry.getInstance().getFactories().get(groupPosition); + return createFilterFactory(factoryEntry.getFactory()).getFilters().get(childPosition); + } + + /** + * Creates the group list with the mapped properties. + */ + private static List<Map<String, String>> createFilterTopLevelGroups() { + final ArrayList<Map<String, String>> groups = new ArrayList<>(); + for (final FactoryEntry factoryEntry : FilterRegistry.getInstance().getFactories()) { + final Map<String, String> map = new HashMap<>(); + map.put(KEY_FILTER_GROUP_NAME, factoryEntry.getName()); + groups.add(map); + } + return groups; + } + + private static List<List<Map<String, String>>> createFilterChildren() { + final List<List<Map<String, String>>> listOfChildGroups = new ArrayList<>(); + + for (final FactoryEntry factoryEntry : FilterRegistry.getInstance().getFactories()) { + final IFilterFactory factory = createFilterFactory(factoryEntry.getFactory()); + final List<? extends IFilter> filters = factory.getFilters(); + + final List<Map<String, String>> childGroups = new ArrayList<>(filters.size()); + + for (final IFilter filter : filters) { + final HashMap<String, String> hashMap = new HashMap<>(1); + hashMap.put(KEY_FILTER_NAME, filter.getName()); + hashMap.put("CHILD_NAME", filter.getName()); + childGroups.add(hashMap); + } + listOfChildGroups.add(childGroups); + } + return listOfChildGroups; + } + + private static IFilterFactory createFilterFactory(final Class<? extends IFilterFactory> class1) { + try { + return class1.newInstance(); + } catch (final InstantiationException e) { + Log.e("createFilterFactory", e); + } catch (final IllegalAccessException e) { + Log.e("createFilterFactory", e); + } + return null; + } + + /** + * After calling this method, the calling activity must implement onActivityResult, and check the + * {@link #EXTRA_FILTER_RESULT}. + */ + public static void selectFilter(@NonNull final Activity context) { + context.startActivityForResult(new Intent(context, FilterActivity_.class), REQUEST_SELECT_FILTER); + } + + @OptionsItem(R.id.menu_reset_filter) + void resetFilter() { + setFilterResult(-1, -1); + } + + private void setFilterResult(final int groupPosition, final int childPosition) { + final Intent resultIntent = new Intent(); + resultIntent.putExtra(EXTRA_FILTER_RESULT, new int[] { groupPosition, childPosition }); + setResult(Activity.RESULT_OK, resultIntent); + finish(); + } +} diff --git a/main/src/cgeo/geocaching/filter/FilterRegistry.java b/main/src/cgeo/geocaching/filter/FilterRegistry.java new file mode 100644 index 0000000..d6d9db9 --- /dev/null +++ b/main/src/cgeo/geocaching/filter/FilterRegistry.java @@ -0,0 +1,86 @@ +package cgeo.geocaching.filter; + +import cgeo.geocaching.CgeoApplication; +import cgeo.geocaching.R; +import cgeo.geocaching.filter.SizeFilter.Factory; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; + +import android.content.res.Resources; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * singleton registry of all available filter components + * + */ +public class FilterRegistry { + private final List<FactoryEntry> registry = new ArrayList<>(); + private static Resources res; + + static class FactoryEntry { + private final String name; + private final @NonNull Class<? extends IFilterFactory> filterFactory; + + public FactoryEntry(final String name, final @NonNull Class<? extends IFilterFactory> filterFactory) { + this.name = name; + this.filterFactory = filterFactory; + } + + @Override + public String toString() { + return name; + } + + public String getName() { + return name; + } + + public Class<? extends IFilterFactory> getFactory() { + return filterFactory; + } + } + + private static class SingletonHolder { + private static final FilterRegistry INSTANCE = new FilterRegistry(); + } + + public static FilterRegistry getInstance() { + return SingletonHolder.INSTANCE; + } + + private FilterRegistry() { + res = CgeoApplication.getInstance().getResources(); + register(R.string.caches_filter_type, TypeFilter.Factory.class); + register(R.string.caches_filter_size, SizeFilter.Factory.class); + register(R.string.cache_terrain, TerrainFilter.Factory.class); + register(R.string.cache_difficulty, DifficultyFilter.Factory.class); + register(R.string.cache_attributes, AttributeFilter.Factory.class); + register(R.string.cache_status, StateFilterFactory.class); + register(R.string.caches_filter_origin, OriginFilter.Factory.class); + register(R.string.caches_filter_distance, DistanceFilter.Factory.class); + register(R.string.caches_filter_popularity, PopularityFilter.Factory.class); + register(R.string.caches_filter_popularity_ratio, PopularityRatioFilter.Factory.class); + register(R.string.caches_filter_personal_data, PersonalDataFilterFactory.class); + } + + private void register(final int resourceId, final @NonNull Class<? extends IFilterFactory> factoryClass) { + registry.add(new FactoryEntry(res.getString(resourceId), factoryClass)); + } + + public String getFactoryName(final Class<Factory> factoryClass) { + for (final FactoryEntry entry : registry) { + if (entry.filterFactory == factoryClass) { + return entry.name; + } + } + return StringUtils.EMPTY; + } + + public List<FactoryEntry> getFactories() { + return Collections.unmodifiableList(registry); + } +} diff --git a/main/src/cgeo/geocaching/filter/FilterUserInterface.java b/main/src/cgeo/geocaching/filter/FilterUserInterface.java deleted file mode 100644 index 9f1d563..0000000 --- a/main/src/cgeo/geocaching/filter/FilterUserInterface.java +++ /dev/null @@ -1,130 +0,0 @@ -package cgeo.geocaching.filter; - -import cgeo.geocaching.CgeoApplication; -import cgeo.geocaching.R; -import cgeo.geocaching.enumerations.CacheType; -import cgeo.geocaching.settings.Settings; -import cgeo.geocaching.utils.Log; - -import rx.functions.Action1; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.res.Resources; -import android.widget.ArrayAdapter; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -public final class FilterUserInterface { - - private static class FactoryEntry { - private final String name; - private final Class<? extends IFilterFactory> filterFactory; - - public FactoryEntry(final String name, final Class<? extends IFilterFactory> filterFactory) { - this.name = name; - this.filterFactory = filterFactory; - } - - @Override - public String toString() { - return name; - } - } - - private final Activity activity; - private final ArrayList<FactoryEntry> registry; - private final Resources res; - - public FilterUserInterface(final Activity activity) { - this.activity = activity; - this.res = CgeoApplication.getInstance().getResources(); - - registry = new ArrayList<>(); - if (Settings.getCacheType() == CacheType.ALL) { - register(R.string.caches_filter_type, TypeFilter.Factory.class); - } - register(R.string.caches_filter_size, SizeFilter.Factory.class); - register(R.string.cache_terrain, TerrainFilter.Factory.class); - register(R.string.cache_difficulty, DifficultyFilter.Factory.class); - register(R.string.cache_attributes, AttributeFilter.Factory.class); - register(R.string.cache_status, StateFilter.Factory.class); - register(R.string.caches_filter_track, TrackablesFilter.class); - register(R.string.caches_filter_modified, ModifiedFilter.class); - register(R.string.caches_filter_origin, OriginFilter.Factory.class); - register(R.string.caches_filter_distance, DistanceFilter.Factory.class); - register(R.string.caches_filter_personal_note, PersonalNoteFilter.class); - register(R.string.caches_filter_popularity, PopularityFilter.Factory.class); - register(R.string.caches_filter_popularity_ratio, PopularityRatioFilter.Factory.class); - - // sort by localized names - Collections.sort(registry, new Comparator<FactoryEntry>() { - - @Override - public int compare(final FactoryEntry lhs, final FactoryEntry rhs) { - return lhs.name.compareToIgnoreCase(rhs.name); - } - }); - - // reset shall be last - register(R.string.caches_filter_clear, null); - } - - private void register(final int resourceId, final Class<? extends IFilterFactory> factoryClass) { - registry.add(new FactoryEntry(res.getString(resourceId), factoryClass)); - } - - public void selectFilter(final Action1<IFilter> runAfterwards) { - final AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle(R.string.caches_filter_title); - - final ArrayAdapter<FactoryEntry> adapter = new ArrayAdapter<>(activity, android.R.layout.select_dialog_item, registry); - - builder.setAdapter(adapter, new DialogInterface.OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int itemIndex) { - FactoryEntry entry = adapter.getItem(itemIndex); - // reset? - if (entry.filterFactory == null) { - runAfterwards.call(null); - } - else { - try { - IFilterFactory factoryInstance = entry.filterFactory.newInstance(); - selectFromFactory(factoryInstance, entry.name, runAfterwards); - } catch (Exception e) { - Log.e("selectFilter", e); - } - } - } - }); - - builder.create().show(); - } - - private void selectFromFactory(final IFilterFactory factory, final String menuTitle, final Action1<IFilter> runAfterwards) { - final List<IFilter> filters = Collections.unmodifiableList(factory.getFilters()); - if (filters.size() == 1) { - runAfterwards.call(filters.get(0)); - return; - } - - final AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle(menuTitle); - - final ArrayAdapter<IFilter> adapter = new ArrayAdapter<>(activity, android.R.layout.select_dialog_item, filters); - builder.setAdapter(adapter, new DialogInterface.OnClickListener() { - @Override - public void onClick(final DialogInterface dialog, final int item) { - runAfterwards.call(filters.get(item)); - } - }); - - builder.create().show(); - } - -} diff --git a/main/src/cgeo/geocaching/filter/IFilter.java b/main/src/cgeo/geocaching/filter/IFilter.java index 4fafe6f..f590f79 100644 --- a/main/src/cgeo/geocaching/filter/IFilter.java +++ b/main/src/cgeo/geocaching/filter/IFilter.java @@ -2,17 +2,21 @@ package cgeo.geocaching.filter; import cgeo.geocaching.Geocache; +import org.eclipse.jdt.annotation.NonNull; + import java.util.List; public interface IFilter { + @NonNull String getName(); /** - * @param cache - * @return true if the filter accepts the cache, false otherwise + * @return {@code true} if the filter accepts the cache, false otherwise */ - boolean accepts(final Geocache cache); + boolean accepts(@NonNull final Geocache cache); + + void filter(@NonNull final List<Geocache> list); - void filter(final List<Geocache> list); + int getImageId(); }
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/filter/IFilterFactory.java b/main/src/cgeo/geocaching/filter/IFilterFactory.java index afc99af..82e69da 100644 --- a/main/src/cgeo/geocaching/filter/IFilterFactory.java +++ b/main/src/cgeo/geocaching/filter/IFilterFactory.java @@ -1,7 +1,10 @@ package cgeo.geocaching.filter; +import org.eclipse.jdt.annotation.NonNull; + import java.util.List; interface IFilterFactory { + @NonNull List<? extends IFilter> getFilters(); } diff --git a/main/src/cgeo/geocaching/filter/ModifiedFilter.java b/main/src/cgeo/geocaching/filter/ModifiedFilter.java index 2ac088a..9b5c856 100644 --- a/main/src/cgeo/geocaching/filter/ModifiedFilter.java +++ b/main/src/cgeo/geocaching/filter/ModifiedFilter.java @@ -1,25 +1,27 @@ package cgeo.geocaching.filter; -import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.Geocache; import cgeo.geocaching.R; +import org.eclipse.jdt.annotation.NonNull; + import java.util.Collections; import java.util.List; class ModifiedFilter extends AbstractFilter implements IFilterFactory { public ModifiedFilter() { - super(CgeoApplication.getInstance().getString(R.string.caches_filter_modified)); + super(R.string.caches_filter_modified); } @Override - public boolean accepts(final Geocache cache) { + public boolean accepts(@NonNull final Geocache cache) { // modified on GC return cache.hasUserModifiedCoords() || cache.hasFinalDefined(); } @Override + @NonNull public List<ModifiedFilter> getFilters() { return Collections.singletonList(this); } diff --git a/main/src/cgeo/geocaching/filter/OfflineLogFilter.java b/main/src/cgeo/geocaching/filter/OfflineLogFilter.java new file mode 100644 index 0000000..0ed9618 --- /dev/null +++ b/main/src/cgeo/geocaching/filter/OfflineLogFilter.java @@ -0,0 +1,19 @@ +package cgeo.geocaching.filter; + +import cgeo.geocaching.Geocache; +import cgeo.geocaching.R; + +import org.eclipse.jdt.annotation.NonNull; + +public class OfflineLogFilter extends AbstractFilter { + + protected OfflineLogFilter() { + super(R.string.caches_filter_offline_log); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return cache.isLogOffline(); + } + +} diff --git a/main/src/cgeo/geocaching/filter/OriginFilter.java b/main/src/cgeo/geocaching/filter/OriginFilter.java index 99d1c05..d51b02c 100644 --- a/main/src/cgeo/geocaching/filter/OriginFilter.java +++ b/main/src/cgeo/geocaching/filter/OriginFilter.java @@ -4,6 +4,8 @@ import cgeo.geocaching.Geocache; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; +import org.eclipse.jdt.annotation.NonNull; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -13,22 +15,23 @@ public class OriginFilter extends AbstractFilter { private final IConnector connector; - public OriginFilter(final IConnector connector) { + public OriginFilter(@NonNull final IConnector connector) { super(connector.getName()); this.connector = connector; } @Override - public final boolean accepts(final Geocache cache) { + public final boolean accepts(@NonNull final Geocache cache) { return ConnectorFactory.getConnector(cache) == connector; } public static final class Factory implements IFilterFactory { @Override + @NonNull public List<OriginFilter> getFilters() { final ArrayList<OriginFilter> filters = new ArrayList<>(); - for (IConnector connector : ConnectorFactory.getConnectors()) { + for (final IConnector connector : ConnectorFactory.getConnectors()) { filters.add(new OriginFilter(connector)); } diff --git a/main/src/cgeo/geocaching/filter/OwnRatingFilter.java b/main/src/cgeo/geocaching/filter/OwnRatingFilter.java new file mode 100644 index 0000000..1b86bab --- /dev/null +++ b/main/src/cgeo/geocaching/filter/OwnRatingFilter.java @@ -0,0 +1,34 @@ +package cgeo.geocaching.filter; + +import cgeo.geocaching.Geocache; +import cgeo.geocaching.R; +import cgeo.geocaching.gcvote.GCVote; + +import org.eclipse.jdt.annotation.NonNull; + +import java.util.Collections; +import java.util.List; + +/** + * Filter {@link Geocache}s if they have a locally stored <b>own</b> {@link GCVote} rating. This filter will not do any + * network request to find potentially missing local votes. + * + */ +public class OwnRatingFilter extends AbstractFilter implements IFilterFactory { + + protected OwnRatingFilter() { + super(R.string.caches_filter_own_rating); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return cache.getMyVote() > 0; + } + + @Override + @NonNull + public List<OwnRatingFilter> getFilters() { + return Collections.singletonList(this); + } + +} diff --git a/main/src/cgeo/geocaching/filter/PersonalDataFilterFactory.java b/main/src/cgeo/geocaching/filter/PersonalDataFilterFactory.java new file mode 100644 index 0000000..e9780da --- /dev/null +++ b/main/src/cgeo/geocaching/filter/PersonalDataFilterFactory.java @@ -0,0 +1,16 @@ +package cgeo.geocaching.filter; + +import org.eclipse.jdt.annotation.NonNull; + +import java.util.Arrays; +import java.util.List; + +public class PersonalDataFilterFactory implements IFilterFactory { + + @Override + @NonNull + public List<? extends IFilter> getFilters() { + return Arrays.asList(new OwnRatingFilter(), new PersonalNoteFilter(), new ModifiedFilter(), new OfflineLogFilter()); + } + +} diff --git a/main/src/cgeo/geocaching/filter/PersonalNoteFilter.java b/main/src/cgeo/geocaching/filter/PersonalNoteFilter.java index 15d262f..11c623e 100644 --- a/main/src/cgeo/geocaching/filter/PersonalNoteFilter.java +++ b/main/src/cgeo/geocaching/filter/PersonalNoteFilter.java @@ -1,26 +1,30 @@ package cgeo.geocaching.filter; -import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.Geocache; import cgeo.geocaching.R; import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.annotation.NonNull; import java.util.Collections; import java.util.List; +/** + * Filter that accepts {@link Geocache}s with a non empty personal note stored locally. + */ public class PersonalNoteFilter extends AbstractFilter implements IFilterFactory { protected PersonalNoteFilter() { - super(CgeoApplication.getInstance().getString(R.string.caches_filter_personal_note)); + super(R.string.caches_filter_personal_note); } @Override - public boolean accepts(Geocache cache) { + public boolean accepts(@NonNull final Geocache cache) { return StringUtils.isNotBlank(cache.getPersonalNote()); } @Override + @NonNull public List<PersonalNoteFilter> getFilters() { return Collections.singletonList(this); } diff --git a/main/src/cgeo/geocaching/filter/PopularityFilter.java b/main/src/cgeo/geocaching/filter/PopularityFilter.java index a0244b9..eabc533 100644 --- a/main/src/cgeo/geocaching/filter/PopularityFilter.java +++ b/main/src/cgeo/geocaching/filter/PopularityFilter.java @@ -4,6 +4,8 @@ import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.Geocache; import cgeo.geocaching.R; +import org.eclipse.jdt.annotation.NonNull; + import java.util.ArrayList; import java.util.List; @@ -11,14 +13,14 @@ class PopularityFilter extends AbstractFilter { private final int minFavorites; private final int maxFavorites; - public PopularityFilter(String name, final int minFavorites, final int maxFavorites) { + public PopularityFilter(@NonNull final String name, final int minFavorites, final int maxFavorites) { super(name); this.minFavorites = minFavorites; this.maxFavorites = maxFavorites; } @Override - public boolean accepts(final Geocache cache) { + public boolean accepts(@NonNull final Geocache cache) { return (cache.getFavoritePoints() > minFavorites) && (cache.getFavoritePoints() <= maxFavorites); } @@ -27,10 +29,10 @@ class PopularityFilter extends AbstractFilter { private static final int[] FAVORITES = { 10, 20, 50, 100, 200, 500 }; @Override + @NonNull public List<IFilter> getFilters() { final List<IFilter> filters = new ArrayList<>(FAVORITES.length); - for (int i = 0; i < FAVORITES.length; i++) { - final int minRange = FAVORITES[i]; + for (final int minRange : FAVORITES) { final int maxRange = Integer.MAX_VALUE; final String range = "> " + minRange; final String name = CgeoApplication.getInstance().getResources().getQuantityString(R.plurals.favorite_points, minRange, range); diff --git a/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java b/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java index a04f219..0548345 100644 --- a/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java +++ b/main/src/cgeo/geocaching/filter/PopularityRatioFilter.java @@ -6,6 +6,8 @@ import cgeo.geocaching.Geocache; import cgeo.geocaching.R; import cgeo.geocaching.enumerations.LogType; +import org.eclipse.jdt.annotation.NonNull; + import java.util.ArrayList; import java.util.List; @@ -16,14 +18,14 @@ class PopularityRatioFilter extends AbstractFilter { private final int minRatio; private final int maxRatio; - public PopularityRatioFilter(String name, final int minRatio, final int maxRatio) { + public PopularityRatioFilter(@NonNull final String name, final int minRatio, final int maxRatio) { super(name); this.minRatio = minRatio; this.maxRatio = maxRatio; } @Override - public boolean accepts(final Geocache cache) { + public boolean accepts(@NonNull final Geocache cache) { final int finds = getFindsCount(cache); if (finds == 0) { // Prevent division by zero @@ -35,11 +37,11 @@ class PopularityRatioFilter extends AbstractFilter { return ratio > minRatio && ratio <= maxRatio; } - private static int getFindsCount(Geocache cache) { + private static int getFindsCount(final Geocache cache) { if (cache.getLogCounts().isEmpty()) { cache.setLogCounts(DataStore.loadLogCounts(cache.getGeocode())); } - Integer logged = cache.getLogCounts().get(LogType.FOUND_IT); + final Integer logged = cache.getLogCounts().get(LogType.FOUND_IT); if (logged != null) { return logged; } @@ -51,12 +53,12 @@ class PopularityRatioFilter extends AbstractFilter { private static final int[] RATIOS = { 10, 20, 30, 40, 50, 75 }; @Override + @NonNull public List<IFilter> getFilters() { final List<IFilter> filters = new ArrayList<>(RATIOS.length); - for (int i = 0; i < RATIOS.length; i++) { - final int minRange = RATIOS[i]; + for (final int minRange : RATIOS) { final int maxRange = Integer.MAX_VALUE; - final String name = "> " + minRange + " " + CgeoApplication.getInstance().getResources().getString(R.string.percent_favorite_points); + final String name = CgeoApplication.getInstance().getResources().getString(R.string.more_than_percent_favorite_points, minRange); filters.add(new PopularityRatioFilter(name, minRange, maxRange)); } return filters; diff --git a/main/src/cgeo/geocaching/filter/RatingFilter.java b/main/src/cgeo/geocaching/filter/RatingFilter.java new file mode 100644 index 0000000..16ce16c --- /dev/null +++ b/main/src/cgeo/geocaching/filter/RatingFilter.java @@ -0,0 +1,25 @@ +package cgeo.geocaching.filter; + +import cgeo.geocaching.Geocache; +import cgeo.geocaching.R; +import cgeo.geocaching.gcvote.GCVote; + +import org.eclipse.jdt.annotation.NonNull; + +/** + * Filter {@link Geocache}s if they have a locally stored {@link GCVote} rating. This filter will not do any network + * request to find potentially missing local votes. + * + */ +public class RatingFilter extends AbstractFilter { + + protected RatingFilter() { + super(R.string.caches_filter_rating); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return cache.getRating() > 0; + } + +} diff --git a/main/src/cgeo/geocaching/filter/SizeFilter.java b/main/src/cgeo/geocaching/filter/SizeFilter.java index f02874c..a19d95b 100644 --- a/main/src/cgeo/geocaching/filter/SizeFilter.java +++ b/main/src/cgeo/geocaching/filter/SizeFilter.java @@ -3,23 +3,26 @@ package cgeo.geocaching.filter; import cgeo.geocaching.Geocache; import cgeo.geocaching.enumerations.CacheSize; +import org.eclipse.jdt.annotation.NonNull; + import java.util.LinkedList; import java.util.List; class SizeFilter extends AbstractFilter { private final CacheSize cacheSize; - public SizeFilter(final CacheSize cacheSize) { + public SizeFilter(@NonNull final CacheSize cacheSize) { super(cacheSize.id); this.cacheSize = cacheSize; } @Override - public boolean accepts(final Geocache cache) { + public boolean accepts(@NonNull final Geocache cache) { return cacheSize == cache.getSize(); } @Override + @NonNull public String getName() { return cacheSize.getL10n(); } @@ -27,16 +30,17 @@ class SizeFilter extends AbstractFilter { public static class Factory implements IFilterFactory { @Override + @NonNull public List<IFilter> getFilters() { final CacheSize[] cacheSizes = CacheSize.values(); final List<IFilter> filters = new LinkedList<>(); - for (CacheSize cacheSize : cacheSizes) { + for (final CacheSize cacheSize : cacheSizes) { if (cacheSize != CacheSize.UNKNOWN) { filters.add(new SizeFilter(cacheSize)); } } return filters; } - } + } diff --git a/main/src/cgeo/geocaching/filter/StateFilter.java b/main/src/cgeo/geocaching/filter/StateFilter.java deleted file mode 100644 index ebe133c..0000000 --- a/main/src/cgeo/geocaching/filter/StateFilter.java +++ /dev/null @@ -1,153 +0,0 @@ -package cgeo.geocaching.filter; - -import cgeo.geocaching.CgeoApplication; -import cgeo.geocaching.Geocache; -import cgeo.geocaching.R; - -import android.content.res.Resources; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -abstract class StateFilter extends AbstractFilter { - - static final Resources res = CgeoApplication.getInstance().getResources(); - - protected StateFilter(final String name) { - super(name); - } - - static class StateFoundFilter extends StateFilter { - - public StateFoundFilter() { - super(res.getString(R.string.cache_status_found)); - } - - @Override - public boolean accepts(final Geocache cache) { - return cache.isFound(); - } - - } - - static class StateNotFoundFilter extends StateFilter { - - public StateNotFoundFilter() { - super(res.getString(R.string.cache_not_status_found)); - } - - @Override - public boolean accepts(final Geocache cache) { - return !cache.isFound(); - } - - } - - static class StateArchivedFilter extends StateFilter { - public StateArchivedFilter() { - super(res.getString(R.string.cache_status_archived)); - } - - @Override - public boolean accepts(final Geocache cache) { - return cache.isArchived(); - } - } - - static class StateDisabledFilter extends StateFilter { - public StateDisabledFilter() { - super(res.getString(R.string.cache_status_disabled)); - } - - @Override - public boolean accepts(final Geocache cache) { - return cache.isDisabled(); - } - } - - static class StatePremiumFilter extends StateFilter { - public StatePremiumFilter() { - super(res.getString(R.string.cache_status_premium)); - } - - @Override - public boolean accepts(final Geocache cache) { - return cache.isPremiumMembersOnly(); - } - } - - static class StateNonPremiumFilter extends StateFilter { - public StateNonPremiumFilter() { - super(res.getString(R.string.cache_status_not_premium)); - } - - @Override - public boolean accepts(final Geocache cache) { - return !cache.isPremiumMembersOnly(); - } - } - - private static class StateOfflineLogFilter extends StateFilter { - public StateOfflineLogFilter() { - super(res.getString(R.string.cache_status_offline_log)); - } - - @Override - public boolean accepts(final Geocache cache) { - return cache.isLogOffline(); - } - } - - static class StateStoredFilter extends StateFilter { - public StateStoredFilter() { - super(res.getString(R.string.cache_status_stored)); - } - - @Override - public boolean accepts(final Geocache cache) { - return cache.isOffline(); - } - } - - static class StateNotStoredFilter extends StateFilter { - public StateNotStoredFilter() { - super(res.getString(R.string.cache_status_not_stored)); - } - - @Override - public boolean accepts(final Geocache cache) { - return !cache.isOffline(); - } - } - - public static class Factory implements IFilterFactory { - - @Override - public List<StateFilter> getFilters() { - final List<StateFilter> filters = new ArrayList<>(6); - filters.add(new StateFoundFilter()); - filters.add(new StateNotFoundFilter()); - filters.add(new StateArchivedFilter()); - filters.add(new StateDisabledFilter()); - filters.add(new StatePremiumFilter()); - filters.add(new StateNonPremiumFilter()); - filters.add(new StateOfflineLogFilter()); - filters.add(new StateStoredFilter()); - filters.add(new StateNotStoredFilter()); - - Collections.sort(filters, new Comparator<StateFilter>() { - - @Override - public int compare(final StateFilter filter1, final StateFilter filter2) { - return String.CASE_INSENSITIVE_ORDER.compare(filter1.getName(), filter2.getName()); - } - }); - - return filters; - } - - } - -} diff --git a/main/src/cgeo/geocaching/filter/StateFilterFactory.java b/main/src/cgeo/geocaching/filter/StateFilterFactory.java new file mode 100644 index 0000000..42de764 --- /dev/null +++ b/main/src/cgeo/geocaching/filter/StateFilterFactory.java @@ -0,0 +1,145 @@ +package cgeo.geocaching.filter; + +import cgeo.geocaching.Geocache; +import cgeo.geocaching.R; + +import org.eclipse.jdt.annotation.NonNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +class StateFilterFactory implements IFilterFactory { + + @Override + @NonNull + public List<? extends IFilter> getFilters() { + final List<AbstractFilter> filters = new ArrayList<>(6); + filters.add(new StateFoundFilter()); + filters.add(new StateNotFoundFilter()); + filters.add(new StateArchivedFilter()); + filters.add(new StateDisabledFilter()); + filters.add(new StatePremiumFilter()); + filters.add(new StateNonPremiumFilter()); + filters.add(new StateOfflineLogFilter()); + filters.add(new StateStoredFilter()); + filters.add(new StateNotStoredFilter()); + filters.add(new RatingFilter()); + filters.add(new TrackablesFilter()); + + Collections.sort(filters, new Comparator<AbstractFilter>() { + + @Override + public int compare(final AbstractFilter filter1, final AbstractFilter filter2) { + return String.CASE_INSENSITIVE_ORDER.compare(filter1.getName(), filter2.getName()); + } + }); + + return filters; + } + + static class StateFoundFilter extends AbstractFilter { + + public StateFoundFilter() { + super(R.string.cache_status_found); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return cache.isFound(); + } + + } + + static class StateNotFoundFilter extends AbstractFilter { + + public StateNotFoundFilter() { + super(R.string.cache_not_status_found); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return !cache.isFound(); + } + + } + + static class StateArchivedFilter extends AbstractFilter { + public StateArchivedFilter() { + super(R.string.cache_status_archived); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return cache.isArchived(); + } + } + + static class StateDisabledFilter extends AbstractFilter { + public StateDisabledFilter() { + super(R.string.cache_status_disabled); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return cache.isDisabled(); + } + } + + static class StatePremiumFilter extends AbstractFilter { + public StatePremiumFilter() { + super(R.string.cache_status_premium); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return cache.isPremiumMembersOnly(); + } + } + + static class StateNonPremiumFilter extends AbstractFilter { + public StateNonPremiumFilter() { + super(R.string.cache_status_not_premium); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return !cache.isPremiumMembersOnly(); + } + } + + private static class StateOfflineLogFilter extends AbstractFilter { + public StateOfflineLogFilter() { + super(R.string.cache_status_offline_log); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return cache.isLogOffline(); + } + } + + static class StateStoredFilter extends AbstractFilter { + public StateStoredFilter() { + super(R.string.cache_status_stored); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return cache.isOffline(); + } + } + + static class StateNotStoredFilter extends AbstractFilter { + public StateNotStoredFilter() { + super(R.string.cache_status_not_stored); + } + + @Override + public boolean accepts(@NonNull final Geocache cache) { + return !cache.isOffline(); + } + } + +} diff --git a/main/src/cgeo/geocaching/filter/TerrainFilter.java b/main/src/cgeo/geocaching/filter/TerrainFilter.java index 7da6a19..977e4a5 100644 --- a/main/src/cgeo/geocaching/filter/TerrainFilter.java +++ b/main/src/cgeo/geocaching/filter/TerrainFilter.java @@ -3,6 +3,8 @@ package cgeo.geocaching.filter; import cgeo.geocaching.Geocache; import cgeo.geocaching.R; +import org.eclipse.jdt.annotation.NonNull; + import java.util.ArrayList; import java.util.List; @@ -13,7 +15,7 @@ class TerrainFilter extends AbstractRangeFilter { } @Override - public boolean accepts(final Geocache cache) { + public boolean accepts(@NonNull final Geocache cache) { final float terrain = cache.getTerrain(); return rangeMin <= terrain && terrain < rangeMax; } @@ -23,6 +25,7 @@ class TerrainFilter extends AbstractRangeFilter { private static final int TERRAIN_MAX = 7; @Override + @NonNull public List<IFilter> getFilters() { final ArrayList<IFilter> filters = new ArrayList<>(TERRAIN_MAX); for (int terrain = TERRAIN_MIN; terrain <= TERRAIN_MAX; terrain++) { diff --git a/main/src/cgeo/geocaching/filter/TrackablesFilter.java b/main/src/cgeo/geocaching/filter/TrackablesFilter.java index d836a0f..debe11f 100644 --- a/main/src/cgeo/geocaching/filter/TrackablesFilter.java +++ b/main/src/cgeo/geocaching/filter/TrackablesFilter.java @@ -1,25 +1,18 @@ package cgeo.geocaching.filter; -import cgeo.geocaching.CgeoApplication; import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import java.util.Collections; -import java.util.List; +import org.eclipse.jdt.annotation.NonNull; -class TrackablesFilter extends AbstractFilter implements IFilterFactory { +class TrackablesFilter extends AbstractFilter { public TrackablesFilter() { - super(CgeoApplication.getInstance().getString(R.string.caches_filter_track)); + super(R.string.caches_filter_track); } @Override - public boolean accepts(final Geocache cache) { + public boolean accepts(@NonNull final Geocache cache) { return cache.hasTrackables(); } - @Override - public List<TrackablesFilter> getFilters() { - return Collections.singletonList(this); - } - } diff --git a/main/src/cgeo/geocaching/filter/TypeFilter.java b/main/src/cgeo/geocaching/filter/TypeFilter.java index d363d39..b8c879f 100644 --- a/main/src/cgeo/geocaching/filter/TypeFilter.java +++ b/main/src/cgeo/geocaching/filter/TypeFilter.java @@ -3,23 +3,26 @@ package cgeo.geocaching.filter; import cgeo.geocaching.Geocache; import cgeo.geocaching.enumerations.CacheType; +import org.eclipse.jdt.annotation.NonNull; + import java.util.LinkedList; import java.util.List; class TypeFilter extends AbstractFilter { private final CacheType cacheType; - public TypeFilter(final CacheType cacheType) { + public TypeFilter(@NonNull final CacheType cacheType) { super(cacheType.id); this.cacheType = cacheType; } @Override - public boolean accepts(final Geocache cache) { + public boolean accepts(@NonNull final Geocache cache) { return cacheType == cache.getType(); } @Override + @NonNull public String getName() { return cacheType.getL10n(); } @@ -27,10 +30,11 @@ class TypeFilter extends AbstractFilter { public static class Factory implements IFilterFactory { @Override + @NonNull public List<IFilter> getFilters() { final CacheType[] types = CacheType.values(); final List<IFilter> filters = new LinkedList<>(); - for (CacheType cacheType : types) { + for (final CacheType cacheType : types) { if (cacheType != CacheType.ALL) { filters.add(new TypeFilter(cacheType)); } @@ -39,4 +43,9 @@ class TypeFilter extends AbstractFilter { } } + + @Override + public int getImageId() { + return cacheType.markerId; + } } |