diff options
Diffstat (limited to 'main/src/cgeo/geocaching/Geocache.java')
| -rw-r--r-- | main/src/cgeo/geocaching/Geocache.java | 217 |
1 files changed, 133 insertions, 84 deletions
diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java index 836cccb..3c69197 100644 --- a/main/src/cgeo/geocaching/Geocache.java +++ b/main/src/cgeo/geocaching/Geocache.java @@ -5,13 +5,13 @@ import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.activity.IAbstractActivity; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; +import cgeo.geocaching.connector.ILoggingManager; import cgeo.geocaching.connector.capability.ISearchByCenter; import cgeo.geocaching.connector.capability.ISearchByGeocode; import cgeo.geocaching.connector.gc.GCConnector; import cgeo.geocaching.connector.gc.GCConstants; import cgeo.geocaching.connector.gc.Tile; import cgeo.geocaching.enumerations.CacheAttribute; -import cgeo.geocaching.enumerations.CacheRealm; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LoadFlags; @@ -23,6 +23,7 @@ import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.files.GPXParser; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.network.HtmlImage; +import cgeo.geocaching.settings.Settings; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.LazyInitializedList; import cgeo.geocaching.utils.Log; @@ -47,8 +48,8 @@ import java.util.Collections; import java.util.Date; import java.util.EnumSet; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.regex.Pattern; @@ -85,7 +86,6 @@ public class Geocache implements ICache, IWaypoint { private String location = null; private Geopoint coords = null; private boolean reliableLatLon = false; - private Double elevation = null; private String personalNote = null; /** * lazy initialized @@ -106,20 +106,20 @@ public class Geocache implements ICache, IWaypoint { private float myVote = 0; // valid ratings are larger than zero private int inventoryItems = 0; private boolean onWatchlist = false; - private List<String> attributes = new LazyInitializedList<String>() { + private final List<String> attributes = new LazyInitializedList<String>() { @Override public List<String> call() { return cgData.loadAttributes(geocode); } }; - private List<Waypoint> waypoints = new LazyInitializedList<Waypoint>() { + private final List<Waypoint> waypoints = new LazyInitializedList<Waypoint>() { @Override public List<Waypoint> call() { return cgData.loadWaypoints(geocode); } }; private List<Image> spoilers = null; - private List<LogEntry> logs = new LazyInitializedList<LogEntry>() { + private final List<LogEntry> logs = new LazyInitializedList<LogEntry>() { @Override public List<LogEntry> call() { return cgData.loadLogs(geocode); @@ -135,6 +135,7 @@ public class Geocache implements ICache, IWaypoint { private String nameForSorting; private final EnumSet<StorageLocation> storageLocation = EnumSet.of(StorageLocation.HEAP); private boolean finalDefined = false; + private boolean logPasswordRequired = false; private int zoomlevel = Tile.ZOOMLEVEL_MAX + 1; private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+"); @@ -175,7 +176,9 @@ public class Geocache implements ICache, IWaypoint { } /** - * Gather missing information from another cache object. + * Gather missing information for new Geocache object from the stored Geocache object. + * This is called in the new Geocache parsed from website to set information not yet + * parsed. * * @param other * the other version, or null if non-existent @@ -187,6 +190,8 @@ public class Geocache implements ICache, IWaypoint { } updated = System.currentTimeMillis(); + // if parsed cache is not yet detailed and stored is, the information of + // the parsed cache will be overwritten if (!detailed && (other.detailed || zoomlevel < other.zoomlevel)) { detailed = other.detailed; detailedUpdate = other.detailedUpdate; @@ -194,15 +199,19 @@ public class Geocache implements ICache, IWaypoint { cacheType = other.cacheType; zoomlevel = other.zoomlevel; // boolean values must be enumerated here. Other types are assigned outside this if-statement + // TODO: check whether a search or a live map systematically returns those, in which case + // we want to keep the most recent one instead of getting information from the previously + // stored data. This is the case for "archived" for example which has been taken out of this + // list. premiumMembersOnly = other.premiumMembersOnly; reliableLatLon = other.reliableLatLon; - archived = other.archived; found = other.found; disabled = other.disabled; favorite = other.favorite; onWatchlist = other.onWatchlist; logOffline = other.logOffline; finalDefined = other.finalDefined; + archived = other.archived; } /* @@ -269,11 +278,14 @@ public class Geocache implements ICache, IWaypoint { if (coords == null) { coords = other.coords; } - if (elevation == null) { - elevation = other.elevation; - } - if (personalNote == null) { // don't use StringUtils.isBlank here. Otherwise we cannot recognize a note which was deleted on GC + // don't use StringUtils.isBlank here. Otherwise we cannot recognize a note which was deleted on GC + if (personalNote == null) { personalNote = other.personalNote; + } else if (other.personalNote != null && !personalNote.equals(other.personalNote)) { + final PersonalNote myNote = new PersonalNote(this); + final PersonalNote otherNote = new PersonalNote(other); + final PersonalNote mergedNote = myNote.mergeWith(otherNote); + personalNote = mergedNote.toString(); } if (StringUtils.isBlank(getShortDescription())) { shortdesc = other.getShortDescription(); @@ -305,7 +317,7 @@ public class Geocache implements ICache, IWaypoint { this.setWaypoints(other.waypoints, false); } else { - ArrayList<Waypoint> newPoints = new ArrayList<Waypoint>(waypoints); + final ArrayList<Waypoint> newPoints = new ArrayList<Waypoint>(waypoints); Waypoint.mergeWayPoints(newPoints, other.waypoints, false); this.setWaypoints(newPoints, false); } @@ -332,12 +344,10 @@ public class Geocache implements ICache, IWaypoint { // if cache has ORIGINAL type waypoint ... it is considered that it has modified coordinates, otherwise not userModifiedCoords = false; - if (waypoints != null) { - for (Waypoint wpt : waypoints) { - if (wpt.getWaypointType() == WaypointType.ORIGINAL) { - userModifiedCoords = true; - break; - } + for (final Waypoint wpt : waypoints) { + if (wpt.getWaypointType() == WaypointType.ORIGINAL) { + userModifiedCoords = true; + break; } } @@ -388,7 +398,6 @@ public class Geocache implements ICache, IWaypoint { StringUtils.equalsIgnoreCase(cacheId, other.cacheId) && (direction != null ? direction.equals(other.direction) : null == other.direction) && (distance != null ? distance.equals(other.distance) : null == other.distance) && - (elevation != null ? elevation.equals(other.elevation) : null == other.elevation) && rating == other.rating && votes == other.votes && myVote == other.myVote && @@ -447,13 +456,13 @@ public class Geocache implements ICache, IWaypoint { } public void logVisit(final IAbstractActivity fromActivity) { - if (StringUtils.isBlank(cacheId)) { + if (!getConnector().canLog(this)) { fromActivity.showToast(((Activity) fromActivity).getResources().getString(R.string.err_cannot_log_visit)); return; } - Intent logVisitIntent = new Intent((Activity) fromActivity, VisitCacheActivity.class); - logVisitIntent.putExtra(VisitCacheActivity.EXTRAS_ID, cacheId); - logVisitIntent.putExtra(VisitCacheActivity.EXTRAS_GEOCODE, geocode); + final Intent logVisitIntent = new Intent((Activity) fromActivity, LogCacheActivity.class); + logVisitIntent.putExtra(LogCacheActivity.EXTRAS_ID, cacheId); + logVisitIntent.putExtra(LogCacheActivity.EXTRAS_GEOCODE, geocode); ((Activity) fromActivity).startActivity(logVisitIntent); } @@ -470,7 +479,7 @@ public class Geocache implements ICache, IWaypoint { } final boolean status = cgData.saveLogOffline(geocode, date.getTime(), logType, log); - Resources res = fromActivity.getResources(); + final Resources res = fromActivity.getResources(); if (status) { ActivityMixin.showToast(fromActivity, res.getString(R.string.info_log_saved)); cgData.saveVisitDate(geocode); @@ -482,35 +491,43 @@ public class Geocache implements ICache, IWaypoint { } } + public void clearOfflineLog() { + cgData.clearLogOffline(geocode); + notifyChange(); + } + public List<LogType> getPossibleLogTypes() { - final List<LogType> logTypes = new LinkedList<LogType>(); + final List<LogType> logTypes = new ArrayList<LogType>(); if (isEventCache()) { logTypes.add(LogType.WILL_ATTEND); - logTypes.add(LogType.NOTE); logTypes.add(LogType.ATTENDED); - logTypes.add(LogType.NEEDS_ARCHIVE); if (isOwner()) { logTypes.add(LogType.ANNOUNCEMENT); } } else if (CacheType.WEBCAM == cacheType) { logTypes.add(LogType.WEBCAM_PHOTO_TAKEN); - logTypes.add(LogType.DIDNT_FIND_IT); - logTypes.add(LogType.NOTE); - logTypes.add(LogType.NEEDS_ARCHIVE); - logTypes.add(LogType.NEEDS_MAINTENANCE); } else { logTypes.add(LogType.FOUND_IT); + } + if (!isEventCache()) { logTypes.add(LogType.DIDNT_FIND_IT); - logTypes.add(LogType.NOTE); - logTypes.add(LogType.NEEDS_ARCHIVE); + } + logTypes.add(LogType.NOTE); + if (!isEventCache()) { logTypes.add(LogType.NEEDS_MAINTENANCE); } if (isOwner()) { logTypes.add(LogType.OWNER_MAINTENANCE); - logTypes.add(LogType.TEMP_DISABLE_LISTING); - logTypes.add(LogType.ENABLE_LISTING); + if (isDisabled()) { + logTypes.add(LogType.ENABLE_LISTING); + } + else { + logTypes.add(LogType.TEMP_DISABLE_LISTING); + } logTypes.add(LogType.ARCHIVE); - logTypes.remove(LogType.UPDATE_COORDINATES); + } + if (!isArchived() && !isOwner()) { + logTypes.add(LogType.NEEDS_ARCHIVE); } return logTypes; } @@ -551,12 +568,16 @@ public class Geocache implements ICache, IWaypoint { return getConnector().supportsLogging(); } + public boolean supportsLogImages() { + return getConnector().supportsLogImages(); + } + public boolean supportsOwnCoordinates() { return getConnector().supportsOwnCoordinates(); } - public CacheRealm getCacheRealm() { - return getConnector().getCacheRealm(); + public ILoggingManager getLoggingManager(Activity activity) { + return getConnector().getLoggingManager(activity, this); } @Override @@ -651,7 +672,7 @@ public class Geocache implements ICache, IWaypoint { */ private void initializeCacheTexts() { if (description == null || shortdesc == null || hint == null || location == null) { - Geocache partial = cgData.loadCacheTexts(this.getGeocode()); + final Geocache partial = cgData.loadCacheTexts(this.getGeocode()); if (description == null) { setDescription(partial.getDescription()); } @@ -710,10 +731,7 @@ public class Geocache implements ICache, IWaypoint { public String getPersonalNote() { // non premium members have no personal notes, premium members have an empty string by default. // map both to null, so other code doesn't need to differentiate - if (StringUtils.isBlank(personalNote)) { - return null; - } - return personalNote; + return StringUtils.defaultIfBlank(personalNote, null); } public boolean supportsUserActions() { @@ -729,7 +747,7 @@ public class Geocache implements ICache, IWaypoint { return; } - StringBuilder subject = new StringBuilder("Geocache "); + final StringBuilder subject = new StringBuilder("Geocache "); subject.append(geocode); if (StringUtils.isNotBlank(name)) { subject.append(" - ").append(name); @@ -765,13 +783,8 @@ public class Geocache implements ICache, IWaypoint { return favorite; } - public void setFavorite(boolean favourite) { - this.favorite = favourite; - } - - @Override - public boolean isWatchlist() { - return onWatchlist; + public void setFavorite(boolean favorite) { + this.favorite = favorite; } @Override @@ -829,8 +842,7 @@ public class Geocache implements ICache, IWaypoint { } public boolean isVirtual() { - return CacheType.VIRTUAL == cacheType || CacheType.WEBCAM == cacheType - || CacheType.EARTH == cacheType; + return cacheType.isVirtual(); } public boolean showSize() { @@ -922,14 +934,6 @@ public class Geocache implements ICache, IWaypoint { this.reliableLatLon = reliableLatLon; } - public Double getElevation() { - return elevation; - } - - public void setElevation(Double elevation) { - this.elevation = elevation; - } - public void setShortDescription(String shortdesc) { this.shortdesc = shortdesc; } @@ -970,6 +974,7 @@ public class Geocache implements ICache, IWaypoint { this.inventoryItems = inventoryItems; } + @Override public boolean isOnWatchlist() { return onWatchlist; } @@ -1002,7 +1007,7 @@ public class Geocache implements ICache, IWaypoint { } finalDefined = false; if (waypoints != null) { - for (Waypoint waypoint : waypoints) { + for (final Waypoint waypoint : waypoints) { waypoint.setGeocode(geocode); if (waypoint.isFinalWithCoords()) { finalDefined = true; @@ -1023,8 +1028,8 @@ public class Geocache implements ICache, IWaypoint { * @return only the logs of friends, never <code>null</code> */ public List<LogEntry> getFriendsLogs() { - ArrayList<LogEntry> friendLogs = new ArrayList<LogEntry>(); - for (LogEntry log : logs) { + final ArrayList<LogEntry> friendLogs = new ArrayList<LogEntry>(); + for (final LogEntry log : logs) { if (log.friend) { friendLogs.add(log); } @@ -1117,7 +1122,7 @@ public class Geocache implements ICache, IWaypoint { } public void setPersonalNote(String personalNote) { - this.personalNote = personalNote; + this.personalNote = StringUtils.trimToNull(personalNote); } public void setDisabled(boolean disabled) { @@ -1239,7 +1244,7 @@ public class Geocache implements ICache, IWaypoint { */ private void resetFinalDefined() { finalDefined = false; - for (Waypoint wp : waypoints) { + for (final Waypoint wp : waypoints) { if (wp.isFinalWithCoords()) { finalDefined = true; break; @@ -1360,6 +1365,9 @@ public class Geocache implements ICache, IWaypoint { return null; } + /** + * Detect coordinates in the personal note and convert them to user defined waypoints. Works by rule of thumb. + */ public void parseWaypointsFromNote() { try { if (StringUtils.isBlank(getPersonalNote())) { @@ -1378,26 +1386,48 @@ public class Geocache implements ICache, IWaypoint { ((point.getLatitudeE6() % 1000) != 0 || (point.getLongitudeE6() % 1000) != 0) && !hasIdenticalWaypoint(point)) { final String name = cgeoapplication.getInstance().getString(R.string.cache_personal_note) + " " + count; - final Waypoint waypoint = new Waypoint(name, WaypointType.WAYPOINT, false); + final String potentialWaypointType = note.substring(Math.max(0, matcher.start() - 15)); + final Waypoint waypoint = new Waypoint(name, parseWaypointType(potentialWaypointType), false); waypoint.setCoords(point); addOrChangeWaypoint(waypoint, false); count++; } - } catch (Geopoint.ParseException e) { + } catch (final Geopoint.ParseException e) { // ignore } note = note.substring(matcher.start() + 1); matcher = new MatcherWrapper(coordPattern, note); } - } catch (Exception e) { + } catch (final Exception e) { Log.e("Geocache.parseWaypointsFromNote", e); } } + /** + * Detect waypoint types in the personal note text. It works by rule of thumb only. + */ + private static WaypointType parseWaypointType(final String input) { + final String lowerInput = StringUtils.substring(input, 0, 20).toLowerCase(Locale.getDefault()); + for (final WaypointType wpType : WaypointType.values()) { + if (lowerInput.contains(wpType.getL10n().toLowerCase(Locale.getDefault()))) { + return wpType; + } + if (lowerInput.contains(wpType.id)) { + return wpType; + } + if (lowerInput.contains(wpType.name().toLowerCase(Locale.US))) { + return wpType; + } + } + return WaypointType.WAYPOINT; + } + private boolean hasIdenticalWaypoint(final Geopoint point) { for (final Waypoint waypoint: waypoints) { - if (waypoint.getCoords().equals(point)) { + // waypoint can have no coords such as a Final set by cache owner + final Geopoint coords = waypoint.getCoords(); + if (coords != null && coords.equals(point)) { return true; } } @@ -1437,12 +1467,16 @@ public class Geocache implements ICache, IWaypoint { } public void store(final int listId, CancellableHandler handler) { - int newListId = listId < StoredList.STANDARD_LIST_ID + final int newListId = listId < StoredList.STANDARD_LIST_ID ? Math.max(getListId(), StoredList.STANDARD_LIST_ID) : listId; storeCache(this, null, newListId, false, handler); } + public int getZoomLevel() { + return this.zoomlevel; + } + public void setZoomlevel(int zoomlevel) { this.zoomlevel = zoomlevel; } @@ -1468,7 +1502,7 @@ public class Geocache implements ICache, IWaypoint { cgData.removeCache(getGeocode(), EnumSet.of(RemoveFlag.REMOVE_CACHE)); handler.sendMessage(Message.obtain()); - } catch (Exception e) { + } catch (final Exception e) { Log.e("cache.drop: ", e); } } @@ -1525,9 +1559,12 @@ public class Geocache implements ICache, IWaypoint { Geocache cache; // get cache details, they may not yet be complete if (origCache != null) { + SearchResult search = null; // only reload the cache if it was already stored or doesn't have full details (by checking the description) if (origCache.isOffline() || StringUtils.isBlank(origCache.getDescription())) { - final SearchResult search = searchByGeocode(origCache.getGeocode(), null, listId, false, handler); + search = searchByGeocode(origCache.getGeocode(), null, listId, false, handler); + } + if (search != null) { cache = search.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); } else { cache = origCache; @@ -1564,7 +1601,7 @@ public class Geocache implements ICache, IWaypoint { // store spoilers if (CollectionUtils.isNotEmpty(cache.getSpoilers())) { - for (Image oneSpoiler : cache.getSpoilers()) { + for (final Image oneSpoiler : cache.getSpoilers()) { imgGetter.getDrawable(oneSpoiler.getUrl()); } } @@ -1575,9 +1612,9 @@ public class Geocache implements ICache, IWaypoint { // store images from logs if (Settings.isStoreLogImages()) { - for (LogEntry log : cache.getLogs()) { + for (final LogEntry log : cache.getLogs()) { if (log.hasLogImages()) { - for (Image oneLogImg : log.getLogImages()) { + for (final Image oneLogImg : log.getLogImages()) { imgGetter.getDrawable(oneLogImg.getUrl()); } } @@ -1600,8 +1637,8 @@ public class Geocache implements ICache, IWaypoint { if (handler != null) { handler.sendMessage(Message.obtain()); } - } catch (Exception e) { - Log.e("cgBase.storeCache"); + } catch (final Exception e) { + Log.e("Geocache.storeCache", e); } } @@ -1653,7 +1690,7 @@ public class Geocache implements ICache, IWaypoint { if (hours >= 0 && hours < 24 && minutes >= 0 && minutes < 60) { return String.valueOf(hours * 60 + minutes); } - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { // cannot happen, but static code analysis doesn't know } } @@ -1668,7 +1705,7 @@ public class Geocache implements ICache, IWaypoint { if (hours >= 0 && hours < 24) { return String.valueOf(hours * 60); } - } catch (NumberFormatException e) { + } catch (final NumberFormatException e) { // cannot happen, but static code analysis doesn't know } } @@ -1697,9 +1734,9 @@ public class Geocache implements ICache, IWaypoint { } public List<Image> getImages() { - List<Image> result = new ArrayList<Image>(); + final List<Image> result = new ArrayList<Image>(); result.addAll(getSpoilers()); - for (LogEntry log : getLogs()) { + for (final LogEntry log : getLogs()) { result.addAll(log.getLogImages()); } return result; @@ -1717,11 +1754,23 @@ public class Geocache implements ICache, IWaypoint { * the cache, so the result might be wrong. */ public boolean hasOwnLog(LogType logType) { - for (LogEntry logEntry : getLogs()) { + for (final LogEntry logEntry : getLogs()) { if (logEntry.type == logType && logEntry.isOwn()) { return true; } } return false; } + + public int getMapMarkerId() { + return getConnector().getCacheMapMarkerId(isDisabled() || isArchived()); + } + + public boolean isLogPasswordRequired() { + return logPasswordRequired; + } + + public void setLogPasswordRequired(boolean required) { + logPasswordRequired = required; + } } |
