aboutsummaryrefslogtreecommitdiffstats
path: root/main/src
diff options
context:
space:
mode:
Diffstat (limited to 'main/src')
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java231
-rw-r--r--main/src/cgeo/geocaching/Geocache.java138
-rw-r--r--main/src/cgeo/geocaching/MainActivity.java9
-rw-r--r--main/src/cgeo/geocaching/SearchResult.java3
-rw-r--r--main/src/cgeo/geocaching/cgeoapplication.java2
-rw-r--r--main/src/cgeo/geocaching/cgeocaches.java2
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCConnector.java2
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCMap.java15
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCParser.java19
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Login.java18
-rw-r--r--main/src/cgeo/geocaching/connector/gc/SearchHandler.java21
-rw-r--r--main/src/cgeo/geocaching/export/FieldnoteExport.java2
-rw-r--r--main/src/cgeo/geocaching/export/GpxExport.java12
-rw-r--r--main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java30
-rw-r--r--main/src/cgeo/geocaching/loaders/RecaptchaReceiver.java6
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java14
-rw-r--r--main/src/cgeo/geocaching/settings/EditPasswordPreference.java1
-rw-r--r--main/src/cgeo/geocaching/settings/SettingsActivity.java23
-rw-r--r--main/src/cgeo/geocaching/ui/CacheListAdapter.java6
-rw-r--r--main/src/cgeo/geocaching/ui/EditNoteDialog.java7
-rw-r--r--main/src/cgeo/geocaching/utils/FileUtils.java28
-rw-r--r--main/src/cgeo/geocaching/utils/MatcherWrapper.java4
-rw-r--r--main/src/cgeo/geocaching/utils/SimpleCancellableHandler.java16
-rw-r--r--main/src/cgeo/geocaching/utils/SimpleHandler.java11
24 files changed, 393 insertions, 227 deletions
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index ac9b156..45a1dd2 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -121,8 +121,7 @@ import java.util.regex.Pattern;
*
* e.g. details, description, logs, waypoints, inventory...
*/
-public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailActivity.Page>
- implements EditNoteDialogListener {
+public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailActivity.Page> {
private static final int MENU_FIELD_COPY = 1;
private static final int MENU_FIELD_TRANSLATE = 2;
@@ -142,6 +141,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
private static final int CONTEXT_MENU_WAYPOINT_DEFAULT_NAVIGATION = 1240;
private static final int CONTEXT_MENU_WAYPOINT_RESET_ORIGINAL_CACHE_COORDINATES = 1241;
+ private static final int MESSAGE_FAILED = -1;
+ private static final int MESSAGE_SUCCEEDED = 1;
+
private static final Pattern[] DARK_COLOR_PATTERNS = {
Pattern.compile("((?<!bg)color)=\"#" + "(0[0-9]){3}" + "\"", Pattern.CASE_INSENSITIVE),
Pattern.compile("((?<!bg)color)=\"" + "black" + "\"", Pattern.CASE_INSENSITIVE),
@@ -156,8 +158,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
private SearchResult search;
- private EditNoteDialogListener editNoteDialogListener;
-
private final GeoDirHandler locationUpdater = new GeoDirHandler() {
@Override
public void updateGeoData(final IGeoData geo) {
@@ -1061,7 +1061,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
private LinearLayout detailsList;
// TODO Do we need this thread-references?
- private StoreCacheThread storeThread;
private RefreshCacheThread refreshThread;
private Thread watchlistThread;
@@ -1208,26 +1207,14 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
new RunnableWithArgument<Integer>() {
@Override
public void run(final Integer selectedListId) {
- storeCache(selectedListId);
+ storeCache(selectedListId, new StoreCacheHandler(CacheDetailActivity.this, progress));
}
}, true, StoredList.TEMPORARY_LIST_ID);
} else {
- storeCache(StoredList.TEMPORARY_LIST_ID);
+ storeCache(StoredList.TEMPORARY_LIST_ID, new StoreCacheHandler(CacheDetailActivity.this, progress));
}
}
- protected void storeCache(int listId) {
- final StoreCacheHandler storeCacheHandler = new StoreCacheHandler(CacheDetailActivity.this, progress);
-
- progress.show(CacheDetailActivity.this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true, storeCacheHandler.cancelMessage());
-
- if (storeThread != null) {
- storeThread.interrupt();
- }
-
- storeThread = new StoreCacheThread(listId, storeCacheHandler);
- storeThread.start();
- }
}
private class RefreshCacheClickListener implements View.OnClickListener {
@@ -1256,22 +1243,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
}
- private class StoreCacheThread extends Thread {
- final private int listId;
- final private CancellableHandler handler;
-
- public StoreCacheThread(final int listId, final CancellableHandler handler) {
- this.listId = listId;
- this.handler = handler;
- }
-
- @Override
- public void run() {
- cache.store(listId, handler);
- storeThread = null;
- }
- }
-
private class RefreshCacheThread extends Thread {
final private CancellableHandler handler;
@@ -1342,7 +1313,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
public void onClick(View arg0) {
doExecute(R.string.cache_dialog_watchlist_add_title,
R.string.cache_dialog_watchlist_add_message,
- new WatchlistAddThread(new WatchlistHandler(CacheDetailActivity.this, progress)));
+ new WatchlistAddThread(new SimpleUpdateHandler(CacheDetailActivity.this, progress)));
}
}
@@ -1354,7 +1325,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
public void onClick(View arg0) {
doExecute(R.string.cache_dialog_watchlist_remove_title,
R.string.cache_dialog_watchlist_remove_message,
- new WatchlistRemoveThread(new WatchlistHandler(CacheDetailActivity.this, progress)));
+ new WatchlistRemoveThread(new SimpleUpdateHandler(CacheDetailActivity.this, progress)));
}
}
@@ -1369,7 +1340,16 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
@Override
public void run() {
watchlistThread = null;
- handler.sendEmptyMessage(ConnectorFactory.getConnector(cache).addToWatchlist(cache) ? 1 : -1);
+ Message msg;
+ if (ConnectorFactory.getConnector(cache).addToWatchlist(cache)) {
+ msg = Message.obtain(handler, MESSAGE_SUCCEEDED);
+ } else {
+ msg = Message.obtain(handler, MESSAGE_FAILED);
+ Bundle bundle = new Bundle();
+ bundle.putString(SimpleCancellableHandler.MESSAGE_TEXT, res.getString(R.string.err_watchlist_failed));
+ msg.setData(bundle);
+ }
+ handler.sendMessage(msg);
}
}
@@ -1384,7 +1364,16 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
@Override
public void run() {
watchlistThread = null;
- handler.sendEmptyMessage(ConnectorFactory.getConnector(cache).removeFromWatchlist(cache) ? 1 : -1);
+ Message msg;
+ if (ConnectorFactory.getConnector(cache).removeFromWatchlist(cache)) {
+ msg = Message.obtain(handler, MESSAGE_SUCCEEDED);
+ } else {
+ msg = Message.obtain(handler, MESSAGE_FAILED);
+ Bundle bundle = new Bundle();
+ bundle.putString(SimpleCancellableHandler.MESSAGE_TEXT, res.getString(R.string.err_watchlist_failed));
+ msg.setData(bundle);
+ }
+ handler.sendMessage(msg);
}
}
@@ -1399,7 +1388,16 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
@Override
public void run() {
watchlistThread = null;
- handler.sendEmptyMessage(GCConnector.addToFavorites(cache) ? 1 : -1);
+ Message msg;
+ if (GCConnector.addToFavorites(cache)) {
+ msg = Message.obtain(handler, MESSAGE_SUCCEEDED);
+ } else {
+ msg = Message.obtain(handler, MESSAGE_FAILED);
+ Bundle bundle = new Bundle();
+ bundle.putString(SimpleCancellableHandler.MESSAGE_TEXT, res.getString(R.string.err_favorite_failed));
+ msg.setData(bundle);
+ }
+ handler.sendMessage(msg);
}
}
@@ -1414,7 +1412,16 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
@Override
public void run() {
watchlistThread = null;
- handler.sendEmptyMessage(GCConnector.removeFromFavorites(cache) ? 1 : -1);
+ Message msg;
+ if (GCConnector.removeFromFavorites(cache)) {
+ msg = Message.obtain(handler, MESSAGE_SUCCEEDED);
+ } else {
+ msg = Message.obtain(handler, MESSAGE_FAILED);
+ Bundle bundle = new Bundle();
+ bundle.putString(SimpleCancellableHandler.MESSAGE_TEXT, res.getString(R.string.err_favorite_failed));
+ msg.setData(bundle);
+ }
+ handler.sendMessage(msg);
}
}
@@ -1426,7 +1433,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
public void onClick(View arg0) {
doExecute(R.string.cache_dialog_favorite_add_title,
R.string.cache_dialog_favorite_add_message,
- new FavoriteAddThread(new FavoriteUpdateHandler(CacheDetailActivity.this, progress)));
+ new FavoriteAddThread(new SimpleUpdateHandler(CacheDetailActivity.this, progress)));
}
}
@@ -1438,7 +1445,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
public void onClick(View arg0) {
doExecute(R.string.cache_dialog_favorite_remove_title,
R.string.cache_dialog_favorite_remove_message,
- new FavoriteRemoveThread(new FavoriteUpdateHandler(CacheDetailActivity.this, progress)));
+ new FavoriteRemoveThread(new SimpleUpdateHandler(CacheDetailActivity.this, progress)));
}
}
@@ -1649,7 +1656,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
// cache personal note
- setPersonalNote();
+ setPersonalNote(personalNoteView, cache.getPersonalNote());
personalNoteView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance());
registerForContextMenu(personalNoteView);
final Button personalNoteEdit = (Button) view.findViewById(R.id.edit_personalnote);
@@ -1657,7 +1664,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
@Override
public void onClick(View v) {
if (cache.isOffline()) {
- editPersonalNote();
+ editPersonalNote(cache, CacheDetailActivity.this);
} else {
warnPersonalNoteNeedsStoring();
}
@@ -1727,24 +1734,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
return view;
}
- private void editPersonalNote() {
- if (cache.isOffline()) {
- editNoteDialogListener = new EditNoteDialogListener() {
- @Override
- public void onFinishEditNoteDialog(final String note) {
- cache.setPersonalNote(note);
- cache.parseWaypointsFromNote();
- setPersonalNote();
- cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
- CacheDetailActivity.this.notifyDataSetChanged();
- }
- };
- final FragmentManager fm = getSupportFragmentManager();
- final EditNoteDialog dialog = EditNoteDialog.newInstance(cache.getPersonalNote());
- dialog.show(fm, "fragment_edit_note");
- }
- }
-
Thread currentThread;
private void uploadPersonalNote() {
@@ -1760,16 +1749,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
currentThread.start();
}
- private void setPersonalNote() {
- final String personalNote = cache.getPersonalNote();
- personalNoteView.setText(personalNote, TextView.BufferType.SPANNABLE);
- if (StringUtils.isNotBlank(personalNote)) {
- personalNoteView.setVisibility(View.VISIBLE);
- } else {
- personalNoteView.setVisibility(View.GONE);
- }
- }
-
private void loadLongDescription() {
final Button showDesc = (Button) view.findViewById(R.id.show_description);
showDesc.setVisibility(View.GONE);
@@ -1796,8 +1775,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
- cache.store(null);
- editPersonalNote();
+ storeCache(StoredList.STANDARD_LIST_ID, new StoreCachePersonalNoteHandler(CacheDetailActivity.this, progress));
}
});
@@ -1808,11 +1786,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
- @Override
- public void onFinishEditNoteDialog(final String note) {
- editNoteDialogListener.onFinishEditNoteDialog(note);
- }
-
/**
* Loads the description in background. <br />
* <br />
@@ -2271,7 +2244,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
Message msg = Message.obtain();
Bundle bundle = new Bundle();
- bundle.putString(SimpleCancellableHandler.SUCCESS_TEXT, res.getString(R.string.cache_personal_note_upload_done));
+ bundle.putString(SimpleCancellableHandler.MESSAGE_TEXT, res.getString(R.string.cache_personal_note_upload_done));
msg.setData(bundle);
handler.sendMessage(msg);
}
@@ -2389,7 +2362,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
return search;
}
- private static final class StoreCacheHandler extends SimpleCancellableHandler {
+ private static class StoreCacheHandler extends SimpleCancellableHandler {
public StoreCacheHandler(CacheDetailActivity activity, Progress progress) {
super(activity, progress);
@@ -2433,47 +2406,103 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
}
- private static final class FavoriteUpdateHandler extends SimpleHandler {
+ private static final class SimpleUpdateHandler extends SimpleHandler {
- public FavoriteUpdateHandler(CacheDetailActivity activity, Progress progress) {
+ public SimpleUpdateHandler(CacheDetailActivity activity, Progress progress) {
super(activity, progress);
}
@Override
public void handleMessage(Message msg) {
- if (msg.what == -1) {
- dismissProgress();
- showToast(R.string.err_favorite_failed);
+ if (msg.what == MESSAGE_FAILED) {
+ super.handleMessage(msg);
} else {
notifyDatasetChanged(activityRef);
}
}
}
- /**
- * Handler, called when watchlist add or remove is done
- */
- private static final class WatchlistHandler extends SimpleHandler {
+ private static void notifyDatasetChanged(WeakReference<AbstractActivity> activityRef) {
+ CacheDetailActivity activity = ((CacheDetailActivity) activityRef.get());
+ if (activity != null) {
+ activity.notifyDataSetChanged();
+ }
+ }
+
+ private StoreCacheThread storeThread;
+
+ private class StoreCacheThread extends Thread {
+ final private int listId;
+ final private CancellableHandler handler;
- public WatchlistHandler(CacheDetailActivity activity, Progress progress) {
+ public StoreCacheThread(final int listId, final CancellableHandler handler) {
+ this.listId = listId;
+ this.handler = handler;
+ }
+
+ @Override
+ public void run() {
+ cache.store(listId, handler);
+ storeThread = null;
+ }
+ }
+
+ protected void storeCache(final int listId, final StoreCacheHandler storeCacheHandler) {
+ progress.show(CacheDetailActivity.this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true, storeCacheHandler.cancelMessage());
+
+ if (storeThread != null) {
+ storeThread.interrupt();
+ }
+
+ storeThread = new StoreCacheThread(listId, storeCacheHandler);
+ storeThread.start();
+ }
+
+ private static final class StoreCachePersonalNoteHandler extends StoreCacheHandler {
+
+ public StoreCachePersonalNoteHandler(CacheDetailActivity activity, Progress progress) {
super(activity, progress);
}
@Override
- public void handleMessage(Message msg) {
- if (msg.what == -1) {
- dismissProgress();
- showToast(R.string.err_watchlist_failed);
+ public void handleRegularMessage(Message msg) {
+ if (UPDATE_LOAD_PROGRESS_DETAIL == msg.what && msg.obj instanceof String) {
+ updateStatusMsg(R.string.cache_dialog_offline_save_message, (String) msg.obj);
} else {
- notifyDatasetChanged(activityRef);
+ dismissProgress();
+ CacheDetailActivity activity = (CacheDetailActivity) activityRef.get();
+ if (activity != null) {
+ editPersonalNote(activity.getCache(), activity);
+ }
}
}
}
- private static void notifyDatasetChanged(WeakReference<AbstractActivity> activityRef) {
- CacheDetailActivity activity = ((CacheDetailActivity) activityRef.get());
- if (activity != null) {
- activity.notifyDataSetChanged();
+ public static void editPersonalNote(final Geocache cache, final CacheDetailActivity activity) {
+ if (cache.isOffline()) {
+ EditNoteDialogListener editNoteDialogListener = new EditNoteDialogListener() {
+ @Override
+ public void onFinishEditNoteDialog(final String note) {
+ cache.setPersonalNote(note);
+ cache.parseWaypointsFromNote();
+ TextView personalNoteView = (TextView) activity.findViewById(R.id.personalnote);
+ setPersonalNote(personalNoteView, note);
+ cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB));
+ activity.notifyDataSetChanged();
+ }
+ };
+ final FragmentManager fm = activity.getSupportFragmentManager();
+ final EditNoteDialog dialog = EditNoteDialog.newInstance(cache.getPersonalNote(), editNoteDialogListener);
+ dialog.show(fm, "fragment_edit_note");
+ }
+ }
+
+ private static void setPersonalNote(final TextView personalNoteView, final String personalNote) {
+ personalNoteView.setText(personalNote, TextView.BufferType.SPANNABLE);
+ if (StringUtils.isNotBlank(personalNote)) {
+ personalNoteView.setVisibility(View.VISIBLE);
+ } else {
+ personalNoteView.setVisibility(View.GONE);
}
}
}
diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java
index 3c69197..f229af8 100644
--- a/main/src/cgeo/geocaching/Geocache.java
+++ b/main/src/cgeo/geocaching/Geocache.java
@@ -32,6 +32,7 @@ import cgeo.geocaching.utils.LogTemplateProvider.LogContext;
import cgeo.geocaching.utils.MatcherWrapper;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import android.app.Activity;
@@ -95,17 +96,18 @@ public class Geocache implements ICache, IWaypoint {
* lazy initialized
*/
private String description = null;
- private boolean disabled = false;
- private boolean archived = false;
- private boolean premiumMembersOnly = false;
- private boolean found = false;
- private boolean favorite = false;
+ private Boolean disabled = null;
+ private Boolean archived = null;
+ private Boolean premiumMembersOnly = null;
+ private Boolean found = null;
+ private Boolean favorite = null;
+ private Boolean onWatchlist = null;
+ private Boolean logOffline = null;
private int favoritePoints = 0;
private float rating = 0; // valid ratings are larger than zero
private int votes = 0;
private float myVote = 0; // valid ratings are larger than zero
private int inventoryItems = 0;
- private boolean onWatchlist = false;
private final List<String> attributes = new LazyInitializedList<String>() {
@Override
public List<String> call() {
@@ -127,7 +129,6 @@ public class Geocache implements ICache, IWaypoint {
};
private List<Trackable> inventory = null;
private Map<LogType, Integer> logCounts = new HashMap<LogType, Integer>();
- private boolean logOffline = false;
private boolean userModifiedCoords = false;
// temporary values
private boolean statusChecked = false;
@@ -136,7 +137,7 @@ public class Geocache implements ICache, IWaypoint {
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 int zoomlevel = Tile.ZOOMLEVEL_MIN - 1;
private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+");
@@ -196,34 +197,37 @@ public class Geocache implements ICache, IWaypoint {
detailed = other.detailed;
detailedUpdate = other.detailedUpdate;
coords = other.coords;
- cacheType = other.cacheType;
+ // merge cache type only if really available from other
+ if (null != other.cacheType && CacheType.UNKNOWN != other.cacheType) {
+ 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;
+ finalDefined = other.finalDefined;
+ }
+
+ if (premiumMembersOnly == null) {
+ premiumMembersOnly = other.premiumMembersOnly;
+ }
+ if (found == null) {
found = other.found;
+ }
+ if (disabled == null) {
disabled = other.disabled;
+ }
+ if (favorite == null) {
favorite = other.favorite;
+ }
+ if (archived == null) {
+ archived = other.archived;
+ }
+ if (onWatchlist == null) {
onWatchlist = other.onWatchlist;
+ }
+ if (logOffline == null) {
logOffline = other.logOffline;
- finalDefined = other.finalDefined;
- archived = other.archived;
}
-
- /*
- * No gathering for boolean members if other cache is not-detailed
- * and does not have information with higher reliability (denoted by zoomlevel)
- * - found
- * - own
- * - disabled
- * - favorite
- * - onWatchlist
- * - logOffline
- */
if (visitedDate == 0) {
visitedDate = other.visitedDate;
}
@@ -374,14 +378,14 @@ public class Geocache implements ICache, IWaypoint {
StringUtils.equalsIgnoreCase(name, other.name) &&
cacheType == other.cacheType &&
size == other.size &&
- found == other.found &&
- premiumMembersOnly == other.premiumMembersOnly &&
+ ObjectUtils.equals(found, other.found) &&
+ ObjectUtils.equals(premiumMembersOnly, other.premiumMembersOnly) &&
difficulty == other.difficulty &&
terrain == other.terrain &&
(coords != null ? coords.equals(other.coords) : null == other.coords) &&
reliableLatLon == other.reliableLatLon &&
- disabled == other.disabled &&
- archived == other.archived &&
+ ObjectUtils.equals(disabled, other.disabled) &&
+ ObjectUtils.equals(archived, other.archived) &&
listId == other.listId &&
StringUtils.equalsIgnoreCase(ownerDisplayName, other.ownerDisplayName) &&
StringUtils.equalsIgnoreCase(ownerUserId, other.ownerUserId) &&
@@ -389,9 +393,9 @@ public class Geocache implements ICache, IWaypoint {
StringUtils.equalsIgnoreCase(personalNote, other.personalNote) &&
StringUtils.equalsIgnoreCase(getShortDescription(), other.getShortDescription()) &&
StringUtils.equalsIgnoreCase(getLocation(), other.getLocation()) &&
- favorite == other.favorite &&
+ ObjectUtils.equals(favorite, other.favorite) &&
favoritePoints == other.favoritePoints &&
- onWatchlist == other.onWatchlist &&
+ ObjectUtils.equals(onWatchlist, other.onWatchlist) &&
(hidden != null ? hidden.equals(other.hidden) : null == other.hidden) &&
StringUtils.equalsIgnoreCase(guid, other.guid) &&
StringUtils.equalsIgnoreCase(getHint(), other.getHint()) &&
@@ -408,7 +412,7 @@ public class Geocache implements ICache, IWaypoint {
logs == other.logs &&
inventory == other.inventory &&
logCounts == other.logCounts &&
- logOffline == other.logOffline &&
+ ObjectUtils.equals(logOffline, other.logOffline) &&
finalDefined == other.finalDefined;
}
@@ -483,7 +487,7 @@ public class Geocache implements ICache, IWaypoint {
if (status) {
ActivityMixin.showToast(fromActivity, res.getString(R.string.info_log_saved));
cgData.saveVisitDate(geocode);
- logOffline = true;
+ logOffline = Boolean.TRUE;
notifyChange();
} else {
@@ -610,21 +614,21 @@ public class Geocache implements ICache, IWaypoint {
@Override
public boolean isArchived() {
- return archived;
+ return (archived != null && archived.booleanValue());
}
@Override
public boolean isDisabled() {
- return disabled;
+ return (disabled != null && disabled.booleanValue());
}
@Override
public boolean isPremiumMembersOnly() {
- return premiumMembersOnly;
+ return (premiumMembersOnly != null && premiumMembersOnly.booleanValue());
}
public void setPremiumMembersOnly(boolean members) {
- this.premiumMembersOnly = members;
+ this.premiumMembersOnly = Boolean.valueOf(members);
}
@Override
@@ -775,16 +779,16 @@ public class Geocache implements ICache, IWaypoint {
@Override
public boolean isFound() {
- return found;
+ return (found != null && found.booleanValue());
}
@Override
public boolean isFavorite() {
- return favorite;
+ return (favorite != null && favorite.booleanValue());
}
public void setFavorite(boolean favorite) {
- this.favorite = favorite;
+ this.favorite = Boolean.valueOf(favorite);
}
@Override
@@ -830,12 +834,15 @@ public class Geocache implements ICache, IWaypoint {
@Override
public String getNameForSorting() {
if (null == nameForSorting) {
- final MatcherWrapper matcher = new MatcherWrapper(NUMBER_PATTERN, name);
- if (matcher.find()) {
- nameForSorting = name.replace(matcher.group(), StringUtils.leftPad(matcher.group(), 6, '0'));
- }
- else {
- nameForSorting = name;
+ nameForSorting = name;
+ // pad each number part to a fixed size of 6 digits, so that numerical sorting becomes equivalent to string sorting
+ MatcherWrapper matcher = new MatcherWrapper(NUMBER_PATTERN, nameForSorting);
+ int start = 0;
+ while (matcher.find(start)) {
+ final String number = matcher.group();
+ nameForSorting = StringUtils.substring(nameForSorting, 0, matcher.start()) + StringUtils.leftPad(number, 6, '0') + StringUtils.substring(nameForSorting, matcher.start() + number.length());
+ start = matcher.start() + Math.max(6, number.length());
+ matcher = new MatcherWrapper(NUMBER_PATTERN, nameForSorting);
}
}
return nameForSorting;
@@ -919,8 +926,25 @@ public class Geocache implements ICache, IWaypoint {
return coords;
}
+ /**
+ * Set reliable coordinates
+ *
+ * @param coords
+ */
public void setCoords(Geopoint coords) {
this.coords = coords;
+ this.zoomlevel = Tile.ZOOMLEVEL_MAX + 1;
+ }
+
+ /**
+ * Set unreliable coordinates from a certain map zoom level
+ *
+ * @param coords
+ * @param zoomlevel
+ */
+ public void setCoords(Geopoint coords, int zoomlevel) {
+ this.coords = coords;
+ this.zoomlevel = zoomlevel;
}
/**
@@ -976,11 +1000,11 @@ public class Geocache implements ICache, IWaypoint {
@Override
public boolean isOnWatchlist() {
- return onWatchlist;
+ return (onWatchlist != null && onWatchlist.booleanValue());
}
public void setOnWatchlist(boolean onWatchlist) {
- this.onWatchlist = onWatchlist;
+ this.onWatchlist = Boolean.valueOf(onWatchlist);
}
/**
@@ -1049,11 +1073,11 @@ public class Geocache implements ICache, IWaypoint {
}
public boolean isLogOffline() {
- return logOffline;
+ return (logOffline != null && logOffline.booleanValue());
}
public void setLogOffline(boolean logOffline) {
- this.logOffline = logOffline;
+ this.logOffline = Boolean.valueOf(logOffline);
}
public boolean isStatusChecked() {
@@ -1126,15 +1150,15 @@ public class Geocache implements ICache, IWaypoint {
}
public void setDisabled(boolean disabled) {
- this.disabled = disabled;
+ this.disabled = Boolean.valueOf(disabled);
}
public void setArchived(boolean archived) {
- this.archived = archived;
+ this.archived = Boolean.valueOf(archived);
}
public void setFound(boolean found) {
- this.found = found;
+ this.found = Boolean.valueOf(found);
}
public void setAttributes(List<String> attributes) {
@@ -1477,10 +1501,6 @@ public class Geocache implements ICache, IWaypoint {
return this.zoomlevel;
}
- public void setZoomlevel(int zoomlevel) {
- this.zoomlevel = zoomlevel;
- }
-
@Override
public int getId() {
return 0;
diff --git a/main/src/cgeo/geocaching/MainActivity.java b/main/src/cgeo/geocaching/MainActivity.java
index b565431..2d488d6 100644
--- a/main/src/cgeo/geocaching/MainActivity.java
+++ b/main/src/cgeo/geocaching/MainActivity.java
@@ -328,6 +328,11 @@ public class MainActivity extends AbstractActivity {
}
private void init() {
+
+ if (app.checkLogin) {
+ (new FirstLoginThread()).start();
+ }
+
if (initialized) {
return;
}
@@ -336,10 +341,6 @@ public class MainActivity extends AbstractActivity {
Settings.setLanguage(Settings.isUseEnglish());
- if (app.firstRun) {
- (new FirstLoginThread()).start();
- }
-
findOnMap.setClickable(true);
findOnMap.setOnClickListener(new OnClickListener() {
@Override
diff --git a/main/src/cgeo/geocaching/SearchResult.java b/main/src/cgeo/geocaching/SearchResult.java
index 5053a85..e637d1f 100644
--- a/main/src/cgeo/geocaching/SearchResult.java
+++ b/main/src/cgeo/geocaching/SearchResult.java
@@ -271,6 +271,9 @@ public class SearchResult implements Parcelable {
if (other != null) {
addGeocodes(other.geocodes);
addFilteredGeocodes(other.filteredGeocodes);
+ if (StringUtils.isBlank(url)) {
+ url = other.url;
+ }
}
}
diff --git a/main/src/cgeo/geocaching/cgeoapplication.java b/main/src/cgeo/geocaching/cgeoapplication.java
index b227939..fd5f714 100644
--- a/main/src/cgeo/geocaching/cgeoapplication.java
+++ b/main/src/cgeo/geocaching/cgeoapplication.java
@@ -18,7 +18,7 @@ public class cgeoapplication extends Application {
private volatile GeoDataProvider geo;
private volatile DirectionProvider dir;
- public boolean firstRun = true; // c:geo is just launched
+ public boolean checkLogin = true; // c:geo is just launched
public boolean showLoginToast = true; //login toast shown just once.
private boolean liveMapHintShown = false; // livemap hint has been shown
final private StatusUpdater statusUpdater = new StatusUpdater();
diff --git a/main/src/cgeo/geocaching/cgeocaches.java b/main/src/cgeo/geocaching/cgeocaches.java
index 5d7841d..b364573 100644
--- a/main/src/cgeo/geocaching/cgeocaches.java
+++ b/main/src/cgeo/geocaching/cgeocaches.java
@@ -1481,9 +1481,9 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity
currentLoader.reset();
((OfflineGeocacheListLoader) currentLoader).setListId(listId);
((OfflineGeocacheListLoader) currentLoader).setSearchCenter(coords);
+ adapter.setComparator(null); // delete current sorting
currentLoader.startLoading();
-
invalidateOptionsMenuCompatible();
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
index e6fff79..835359a 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java
@@ -299,7 +299,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode,
final StatusCode status = Login.login();
if (status == StatusCode.NO_ERROR) {
- cgeoapplication.getInstance().firstRun = false;
+ cgeoapplication.getInstance().checkLogin = false;
Login.detectGcCustomDate();
}
diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java
index 4bc55fe..6a602a7 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCMap.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java
@@ -2,7 +2,6 @@ package cgeo.geocaching.connector.gc;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.cgData;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.CacheSize;
@@ -11,9 +10,11 @@ import cgeo.geocaching.enumerations.LiveMapStrategy.Strategy;
import cgeo.geocaching.enumerations.LiveMapStrategy.StrategyFlag;
import cgeo.geocaching.enumerations.StatusCode;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.GeopointFormatter.Format;
import cgeo.geocaching.geopoint.Units;
import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.Parameters;
+import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.ui.Formatter;
import cgeo.geocaching.utils.LeastRecentlyUsedMap;
import cgeo.geocaching.utils.Log;
@@ -208,8 +209,7 @@ public class GCMap {
cache.setReliableLatLon(false);
cache.setGeocode(id);
cache.setName(nameCache.get(id));
- cache.setZoomlevel(tile.getZoomlevel());
- cache.setCoords(tile.getCoord(xy));
+ cache.setCoords(tile.getCoord(xy), tile.getZoomlevel());
if (strategy.flags.contains(StrategyFlag.PARSE_TILES) && bitmap != null) {
for (UTFGridPosition singlePos : singlePositions.get(id)) {
if (IconDecoder.parseMapPNG(cache, bitmap, singlePos, tile.getZoomlevel())) {
@@ -286,11 +286,18 @@ public class GCMap {
Log.d("GCMap.searchByViewport" + viewport.toString());
final SearchResult searchResult = new SearchResult();
- searchResult.setUrl(GCConstants.URL_LIVE_MAP + "?ll=" + viewport.getCenter().getLatitude() + "," + viewport.getCenter().getLongitude());
+
+ if (Settings.isDebug()) {
+ searchResult.setUrl(viewport.getCenter().format(Format.LAT_LON_DECMINUTE));
+ }
if (strategy.flags.contains(StrategyFlag.LOAD_TILES)) {
final Set<Tile> tiles = Tile.getTilesForViewport(viewport);
+ if (Settings.isDebug()) {
+ searchResult.setUrl(new StringBuilder().append(tiles.iterator().next().getZoomlevel()).append(Formatter.SEPARATOR).append(searchResult.getUrl()).toString());
+ }
+
for (Tile tile : tiles) {
if (!Tile.Cache.contains(tile)) {
diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java
index e32f72d..7dc048a 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCParser.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java
@@ -78,20 +78,15 @@ public abstract class GCParser {
searchResult.viewstates = Login.getViewstates(page);
// recaptcha
- String recaptchaChallenge = null;
if (showCaptcha) {
final String recaptchaJsParam = TextUtils.getMatch(page, GCConstants.PATTERN_SEARCH_RECAPTCHA, false, null);
if (recaptchaJsParam != null) {
- final Parameters params = new Parameters("k", recaptchaJsParam.trim());
- final String recaptchaJs = Network.getResponseData(Network.getRequest("http://www.google.com/recaptcha/api/challenge", params));
+ thread.setKey(recaptchaJsParam.trim());
- if (StringUtils.isNotBlank(recaptchaJs)) {
- recaptchaChallenge = TextUtils.getMatch(recaptchaJs, GCConstants.PATTERN_SEARCH_RECAPTCHACHALLENGE, true, 1, null, true);
- }
+ thread.fetchChallenge();
}
- if (thread != null && StringUtils.isNotBlank(recaptchaChallenge)) {
- thread.setChallenge(recaptchaChallenge);
+ if (thread != null && StringUtils.isNotBlank(thread.getChallenge())) {
thread.notifyNeed();
}
}
@@ -276,7 +271,7 @@ public abstract class GCParser {
}
String recaptchaText = null;
- if (thread != null && recaptchaChallenge != null) {
+ if (thread != null && StringUtils.isNotBlank(thread.getChallenge())) {
if (thread.getText() == null) {
thread.waitForUser();
}
@@ -284,7 +279,7 @@ public abstract class GCParser {
recaptchaText = thread.getText();
}
- if (!cids.isEmpty() && (Settings.isPremiumMember() || showCaptcha) && (recaptchaChallenge == null || StringUtils.isNotBlank(recaptchaText))) {
+ if (!cids.isEmpty() && (Settings.isPremiumMember() || showCaptcha) && ((thread == null || StringUtils.isBlank(thread.getChallenge())) || StringUtils.isNotBlank(recaptchaText))) {
Log.i("Trying to get .loc for " + cids.size() + " caches");
try {
@@ -305,8 +300,8 @@ public abstract class GCParser {
params.put("CID", cid);
}
- if (recaptchaChallenge != null && StringUtils.isNotBlank(recaptchaText)) {
- params.put("recaptcha_challenge_field", recaptchaChallenge);
+ if (thread != null && StringUtils.isNotBlank(thread.getChallenge()) && StringUtils.isNotBlank(recaptchaText)) {
+ params.put("recaptcha_challenge_field", thread.getChallenge());
params.put("recaptcha_response_field", recaptchaText);
}
params.put("ctl00$ContentBody$uxDownloadLoc", "Download Waypoints");
diff --git a/main/src/cgeo/geocaching/connector/gc/Login.java b/main/src/cgeo/geocaching/connector/gc/Login.java
index 2b32ba9..2629339 100644
--- a/main/src/cgeo/geocaching/connector/gc/Login.java
+++ b/main/src/cgeo/geocaching/connector/gc/Login.java
@@ -69,7 +69,7 @@ public abstract class Login {
final ImmutablePair<String, String> login = Settings.getGcLogin();
if (StringUtils.isEmpty(login.left) || StringUtils.isEmpty(login.right)) {
- Login.setActualStatus(cgeoapplication.getInstance().getString(R.string.err_login));
+ clearLoginInfo();
Log.e("Login.login: No login information stored");
return StatusCode.NO_LOGIN_INFO_STORED;
}
@@ -153,9 +153,23 @@ public abstract class Login {
return StatusCode.MAINTENANCE;
}
+ resetLoginStatus();
+
+ return StatusCode.NO_ERROR;
+ }
+
+ private static void resetLoginStatus() {
Cookies.clearCookies();
Settings.setCookieStore(null);
- return StatusCode.NO_ERROR;
+
+ setActualLoginStatus(false);
+ }
+
+ private static void clearLoginInfo() {
+ resetLoginStatus();
+
+ setActualCachesFound(-1);
+ setActualStatus(cgeoapplication.getInstance().getString(R.string.err_login));
}
static void setActualCachesFound(final int found) {
diff --git a/main/src/cgeo/geocaching/connector/gc/SearchHandler.java b/main/src/cgeo/geocaching/connector/gc/SearchHandler.java
index 45832e4..4358399 100644
--- a/main/src/cgeo/geocaching/connector/gc/SearchHandler.java
+++ b/main/src/cgeo/geocaching/connector/gc/SearchHandler.java
@@ -15,11 +15,13 @@ import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
+import android.widget.ImageButton;
import android.widget.ImageView;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
import java.net.URL;
public class SearchHandler extends Handler {
@@ -37,7 +39,7 @@ public class SearchHandler extends Handler {
imageView.setImageBitmap(img);
}
} catch (Exception e) {
- // nothing
+ Log.e("Error setting reCAPTCHA image", e);
}
}
};
@@ -58,6 +60,20 @@ public class SearchHandler extends Handler {
imageView = (ImageView) view.findViewById(R.id.image);
+ ImageButton reloadButton = (ImageButton) view.findViewById(R.id.button_recaptcha_refresh);
+ reloadButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ recaptchaThread.fetchChallenge();
+ try {
+ (new GetCaptchaThread(new URL("http://www.google.com/recaptcha/api/image?c=" + recaptchaThread.getChallenge()))).start();
+ } catch (MalformedURLException e) {
+ Log.e("Bad reCAPTCHA image url", e);
+ }
+ }
+ });
+
(new GetCaptchaThread(new URL("http://www.google.com/recaptcha/api/image?c=" + recaptchaThread.getChallenge()))).start();
dlg.setTitle(res.getString(R.string.caches_recaptcha_title));
@@ -76,7 +92,7 @@ public class SearchHandler extends Handler {
dlg.create().show();
}
} catch (Exception e) {
- // nothing
+ Log.e("Error in reCAPTCHA handler", e);
}
}
@@ -90,6 +106,7 @@ public class SearchHandler extends Handler {
@Override
public void run() {
try {
+ Log.d("Getting reCAPTCHA image from: " + uri.toString());
HttpURLConnection connection = (HttpURLConnection) uri.openConnection();
connection.setDoInput(true);
connection.connect();
diff --git a/main/src/cgeo/geocaching/export/FieldnoteExport.java b/main/src/cgeo/geocaching/export/FieldnoteExport.java
index 9d0310c..38cd43e 100644
--- a/main/src/cgeo/geocaching/export/FieldnoteExport.java
+++ b/main/src/cgeo/geocaching/export/FieldnoteExport.java
@@ -137,8 +137,8 @@ class FieldnoteExport extends AbstractExport {
if (!onlyNew || onlyNew && log.date > Settings.getFieldnoteExportDate()) {
appendFieldNote(fieldNoteBuffer, cache, log);
}
- publishProgress(++i);
}
+ publishProgress(++i);
}
} catch (final Exception e) {
Log.e("FieldnoteExport.ExportTask generation", e);
diff --git a/main/src/cgeo/geocaching/export/GpxExport.java b/main/src/cgeo/geocaching/export/GpxExport.java
index 61be3c5..c31b1ae 100644
--- a/main/src/cgeo/geocaching/export/GpxExport.java
+++ b/main/src/cgeo/geocaching/export/GpxExport.java
@@ -1,11 +1,12 @@
package cgeo.geocaching.export;
import cgeo.geocaching.Geocache;
-import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.R;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.activity.ActivityMixin;
+import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.utils.AsyncTaskWithProgress;
+import cgeo.geocaching.utils.FileUtils;
import cgeo.geocaching.utils.Log;
import android.app.Activity;
@@ -106,6 +107,12 @@ class GpxExport extends AbstractExport {
this.activity = activity;
}
+ private File getExportFile() {
+ final SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
+ final Date now = new Date();
+ return FileUtils.getUniqueNamedFile(Settings.getGpxExportDir() + File.separatorChar + "export_" + fileNameDateFormat.format(now) + ".gpx");
+ }
+
@Override
protected File doInBackgroundInternal(String[] geocodes) {
// quick check for being able to write the GPX file
@@ -117,8 +124,7 @@ class GpxExport extends AbstractExport {
setMessage(cgeoapplication.getInstance().getResources().getQuantityString(R.plurals.cache_counts, allGeocodes.size(), allGeocodes.size()));
- final SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
- final File exportFile = new File(Settings.getGpxExportDir() + File.separatorChar + "export_" + fileNameDateFormat.format(new Date()) + ".gpx");
+ final File exportFile = getExportFile();
BufferedWriter writer = null;
try {
final File exportLocation = new File(Settings.getGpxExportDir());
diff --git a/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java b/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java
index ece5c2f..ebf29d1 100644
--- a/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java
+++ b/main/src/cgeo/geocaching/loaders/AbstractSearchLoader.java
@@ -1,7 +1,13 @@
package cgeo.geocaching.loaders;
import cgeo.geocaching.SearchResult;
+import cgeo.geocaching.connector.gc.GCConstants;
+import cgeo.geocaching.network.Network;
+import cgeo.geocaching.network.Parameters;
import cgeo.geocaching.utils.Log;
+import cgeo.geocaching.utils.TextUtils;
+
+import org.apache.commons.lang3.StringUtils;
import android.content.Context;
import android.os.Handler;
@@ -25,6 +31,7 @@ public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult>
private Handler recaptchaHandler = null;
private String recaptchaChallenge = null;
+ private String recaptchaKey = null;
private String recaptchaText = null;
private SearchResult search;
private boolean loading;
@@ -90,8 +97,27 @@ public abstract class AbstractSearchLoader extends AsyncTaskLoader<SearchResult>
}
@Override
- public void setChallenge(String challenge) {
- recaptchaChallenge = challenge;
+ public void setKey(String key) {
+ recaptchaKey = key;
+ }
+
+ @Override
+ public String getKey() {
+ return recaptchaKey;
+ }
+
+ @Override
+ public void fetchChallenge() {
+ recaptchaChallenge = null;
+
+ if (StringUtils.isNotEmpty(recaptchaKey)) {
+ final Parameters params = new Parameters("k", getKey());
+ final String recaptchaJs = Network.getResponseData(Network.getRequest("http://www.google.com/recaptcha/api/challenge", params));
+
+ if (StringUtils.isNotBlank(recaptchaJs)) {
+ recaptchaChallenge = TextUtils.getMatch(recaptchaJs, GCConstants.PATTERN_SEARCH_RECAPTCHACHALLENGE, true, 1, null, true);
+ }
+ }
}
@Override
diff --git a/main/src/cgeo/geocaching/loaders/RecaptchaReceiver.java b/main/src/cgeo/geocaching/loaders/RecaptchaReceiver.java
index f64bf89..fd5189c 100644
--- a/main/src/cgeo/geocaching/loaders/RecaptchaReceiver.java
+++ b/main/src/cgeo/geocaching/loaders/RecaptchaReceiver.java
@@ -8,7 +8,11 @@ public interface RecaptchaReceiver {
public String getChallenge();
- public void setChallenge(String challenge);
+ public void fetchChallenge();
+
+ public String getKey();
+
+ public void setKey(String key);
public void notifyNeed();
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index f892622..d4754aa 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -156,12 +156,12 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
private ScaleOverlay overlayScale = null;
private PositionOverlay overlayPosition = null;
// data for overlays
- private static final int[][] INSET_RELIABLE = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; // center, 33x40 / 45x51
- private static final int[][] INSET_TYPE = { { 5, 8, 6, 10 }, { 4, 4, 5, 11 } }; // center, 22x22 / 36x36
- private static final int[][] INSET_OWN = { { 21, 0, 0, 26 }, { 25, 0, 0, 35 } }; // top right, 12x12 / 16x16
- private static final int[][] INSET_FOUND = { { 0, 0, 21, 28 }, { 0, 0, 25, 35 } }; // top left, 12x12 / 16x16
- private static final int[][] INSET_USERMODIFIEDCOORDS = { { 21, 28, 0, 0 }, { 19, 25, 0, 0 } }; // bottom right, 12x12 / 26x26
- private static final int[][] INSET_PERSONALNOTE = { { 0, 28, 21, 0 }, { 0, 25, 19, 0 } }; // bottom left, 12x12 / 26x26
+ private static final int[][] INSET_RELIABLE = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; // center, 33x40 / 45x51 / 60x68
+ private static final int[][] INSET_TYPE = { { 5, 8, 6, 10 }, { 4, 4, 5, 11 }, { 4, 4, 5, 11 } }; // center, 22x22 / 36x36
+ private static final int[][] INSET_OWN = { { 21, 0, 0, 26 }, { 25, 0, 0, 35 }, { 40, 0, 0, 48 } }; // top right, 12x12 / 16x16 / 20x20
+ private static final int[][] INSET_FOUND = { { 0, 0, 21, 28 }, { 0, 0, 25, 35 }, { 0, 0, 40, 48 } }; // top left, 12x12 / 16x16 / 20x20
+ private static final int[][] INSET_USERMODIFIEDCOORDS = { { 21, 28, 0, 0 }, { 19, 25, 0, 0 }, { 25, 33, 0, 0 } }; // bottom right, 12x12 / 26x26 / 35x35
+ private static final int[][] INSET_PERSONALNOTE = { { 0, 28, 21, 0 }, { 0, 25, 19, 0 }, { 0, 33, 25, 0 } }; // bottom left, 12x12 / 26x26 / 35x35
private SparseArray<LayerDrawable> overlaysCache = new SparseArray<LayerDrawable>();
/** Count of caches currently visible */
@@ -1677,7 +1677,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
// background: disabled or not
final Drawable marker = getResources().getDrawable(cache.getMapMarkerId());
layers.add(marker);
- final int resolution = marker.getIntrinsicWidth() > 40 ? 1 : 0;
+ final int resolution = marker.getIntrinsicWidth() > 40 ? (marker.getIntrinsicWidth() > 50 ? 2 : 1) : 0;
// reliable or not
if (!cache.isReliableLatLon()) {
insets.add(INSET_RELIABLE[resolution]);
diff --git a/main/src/cgeo/geocaching/settings/EditPasswordPreference.java b/main/src/cgeo/geocaching/settings/EditPasswordPreference.java
index d89f128..20d0250 100644
--- a/main/src/cgeo/geocaching/settings/EditPasswordPreference.java
+++ b/main/src/cgeo/geocaching/settings/EditPasswordPreference.java
@@ -10,7 +10,6 @@ import android.util.AttributeSet;
* Use it exactly as an EditTextPreference
*
* @see SettingsActivity - search for EditPasswordPreference
- * @author koem
*/
public class EditPasswordPreference extends EditTextPreference {
diff --git a/main/src/cgeo/geocaching/settings/SettingsActivity.java b/main/src/cgeo/geocaching/settings/SettingsActivity.java
index 4b1c92b..aa0848a 100644
--- a/main/src/cgeo/geocaching/settings/SettingsActivity.java
+++ b/main/src/cgeo/geocaching/settings/SettingsActivity.java
@@ -9,6 +9,7 @@ import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory;
import cgeo.geocaching.apps.cache.navi.NavigationAppFactory.NavigationAppsEnum;
import cgeo.geocaching.compatibility.Compatibility;
+import cgeo.geocaching.connector.gc.Login;
import cgeo.geocaching.files.SimpleDirChooser;
import cgeo.geocaching.maps.MapProviderFactory;
import cgeo.geocaching.maps.interfaces.MapSource;
@@ -56,7 +57,6 @@ import java.util.List;
* guidelines and the <a href="http://developer.android.com/guide/topics/ui/settings.html">Settings API Guide</a> for
* more information on developing a Settings UI.
*
- * @author koem (initial author)
*/
public class SettingsActivity extends PreferenceActivity {
@@ -124,6 +124,7 @@ public class SettingsActivity extends PreferenceActivity {
initDebugPreference();
initBasicMemberPreferences();
initSend2CgeoPreferences();
+ initServicePreferences();
for (int k : new int[] { R.string.pref_username, R.string.pref_password,
R.string.pref_pass_vote, R.string.pref_signature,
@@ -136,6 +137,11 @@ public class SettingsActivity extends PreferenceActivity {
}
}
+ private void initServicePreferences() {
+ getPreference(R.string.pref_connectorOCActive).setOnPreferenceChangeListener(VALUE_CHANGE_LISTENER);
+ getPreference(R.string.pref_connectorGCActive).setOnPreferenceChangeListener(VALUE_CHANGE_LISTENER);
+ }
+
private static String getKey(final int prefKeyId) {
return cgeoapplication.getInstance().getString(prefKeyId);
}
@@ -493,6 +499,17 @@ public class SettingsActivity extends PreferenceActivity {
// simple string representation.
preference.setSummary(stringValue);
}
+ // reset log-in if gc user or password is changed
+ if (isPreference(preference, R.string.pref_username) || isPreference(preference, R.string.pref_password)) {
+ if (Login.isActualLoginStatus()) {
+ Login.logout();
+ }
+ cgeoapplication.getInstance().checkLogin = true;
+ }
+ // reset log-in status if connector activation was changed
+ if (isPreference(preference, R.string.pref_connectorOCActive) || isPreference(preference, R.string.pref_connectorGCActive)) {
+ cgeoapplication.getInstance().checkLogin = true;
+ }
return true;
}
};
@@ -546,4 +563,8 @@ public class SettingsActivity extends PreferenceActivity {
public static void addPreferencesFromResource(final PreferenceActivity preferenceActivity, final int preferencesResId) {
preferenceActivity.addPreferencesFromResource(preferencesResId);
}
+
+ private static boolean isPreference(final Preference preference, int preferenceKeyId) {
+ return getKey(preferenceKeyId).equals(preference.getKey());
+ }
}
diff --git a/main/src/cgeo/geocaching/ui/CacheListAdapter.java b/main/src/cgeo/geocaching/ui/CacheListAdapter.java
index 3179857..c6aeaa6 100644
--- a/main/src/cgeo/geocaching/ui/CacheListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/CacheListAdapter.java
@@ -6,12 +6,12 @@ import cgeo.geocaching.CacheDetailActivity;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
-import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.CacheListType;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.filter.IFilter;
import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.sorting.CacheComparator;
import cgeo.geocaching.sorting.DistanceComparator;
import cgeo.geocaching.sorting.EventDateComparator;
@@ -645,6 +645,10 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> {
}
public void setInitialComparator() {
+ // will be called repeatedly when coming back to the list, therefore check first for an already existing sorting
+ if (cacheComparator != null) {
+ return;
+ }
CacheComparator comparator = null; // a null comparator will automatically sort by distance
if (cacheListType == CacheListType.HISTORY) {
comparator = new VisitComparator();
diff --git a/main/src/cgeo/geocaching/ui/EditNoteDialog.java b/main/src/cgeo/geocaching/ui/EditNoteDialog.java
index 9a122e2..50cf57a 100644
--- a/main/src/cgeo/geocaching/ui/EditNoteDialog.java
+++ b/main/src/cgeo/geocaching/ui/EditNoteDialog.java
@@ -20,13 +20,15 @@ public class EditNoteDialog extends DialogFragment {
public static final String ARGUMENT_INITIAL_NOTE = "initialNote";
private EditText mEditText;
+ private EditNoteDialogListener listener;
- public static EditNoteDialog newInstance(final String initialNote) {
+ public static EditNoteDialog newInstance(final String initialNote, EditNoteDialogListener listener) {
EditNoteDialog dialog = new EditNoteDialog();
Bundle arguments = new Bundle();
arguments.putString(EditNoteDialog.ARGUMENT_INITIAL_NOTE, initialNote);
dialog.setArguments(arguments);
+ dialog.listener = listener;
return dialog;
}
@@ -49,8 +51,7 @@ public class EditNoteDialog extends DialogFragment {
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
- final EditNoteDialogListener activity = (EditNoteDialogListener) getActivity();
- activity.onFinishEditNoteDialog(mEditText.getText().toString());
+ listener.onFinishEditNoteDialog(mEditText.getText().toString());
dialog.dismiss();
}
});
diff --git a/main/src/cgeo/geocaching/utils/FileUtils.java b/main/src/cgeo/geocaching/utils/FileUtils.java
index 5ab8fcc..0b358d2 100644
--- a/main/src/cgeo/geocaching/utils/FileUtils.java
+++ b/main/src/cgeo/geocaching/utils/FileUtils.java
@@ -1,6 +1,7 @@
package cgeo.geocaching.utils;
import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
import android.os.Handler;
import android.os.Message;
@@ -11,8 +12,6 @@ import java.util.List;
/**
* Utility class for files
*
- * @author rsudev
- *
*/
public final class FileUtils {
@@ -65,4 +64,29 @@ public final class FileUtils {
public abstract boolean shouldEnd();
}
+
+ /**
+ * Create a unique non existing file named like the given file name. If a file with the given name already exists,
+ * add a number as suffix to the file name.<br>
+ * Example: For the file name "file.ext" this will return the first file of the list
+ * <ul>
+ * <li>file.ext</li>
+ * <li>file_2.ext</li>
+ * <li>file_3.ext</li>
+ * </ul>
+ * which does not yet exist.
+ */
+ public static File getUniqueNamedFile(final String baseNameAndPath) {
+ String extension = StringUtils.substringAfterLast(baseNameAndPath, ".");
+ String pathName = StringUtils.substringBeforeLast(baseNameAndPath, ".");
+ int number = 1;
+ while (new File(getNumberedFileName(pathName, extension, number)).exists()) {
+ number++;
+ }
+ return new File(getNumberedFileName(pathName, extension, number));
+ }
+
+ private static String getNumberedFileName(String pathName, String extension, int number) {
+ return pathName + (number > 1 ? "_" + Integer.toString(number) : "") + "." + extension;
+ }
}
diff --git a/main/src/cgeo/geocaching/utils/MatcherWrapper.java b/main/src/cgeo/geocaching/utils/MatcherWrapper.java
index c3c1663..78b1170 100644
--- a/main/src/cgeo/geocaching/utils/MatcherWrapper.java
+++ b/main/src/cgeo/geocaching/utils/MatcherWrapper.java
@@ -22,6 +22,10 @@ public class MatcherWrapper {
return matcher.find();
}
+ public boolean find(int start) {
+ return matcher.find(start);
+ }
+
/**
* see {@link Matcher#group(int)}
*/
diff --git a/main/src/cgeo/geocaching/utils/SimpleCancellableHandler.java b/main/src/cgeo/geocaching/utils/SimpleCancellableHandler.java
index 94246e0..75c10ab 100644
--- a/main/src/cgeo/geocaching/utils/SimpleCancellableHandler.java
+++ b/main/src/cgeo/geocaching/utils/SimpleCancellableHandler.java
@@ -10,7 +10,7 @@ import android.os.Message;
import java.lang.ref.WeakReference;
public class SimpleCancellableHandler extends CancellableHandler {
- public static final String SUCCESS_TEXT = "success_message";
+ public static final String MESSAGE_TEXT = "message_text";
protected final WeakReference<AbstractActivity> activityRef;
protected final WeakReference<Progress> progressDialogRef;
@@ -22,13 +22,10 @@ public class SimpleCancellableHandler extends CancellableHandler {
@Override
public void handleRegularMessage(final Message msg) {
AbstractActivity activity = activityRef.get();
- if (activity != null && msg.getData() != null && msg.getData().getString(SUCCESS_TEXT) != null) {
- activity.showToast(msg.getData().getString(SUCCESS_TEXT));
- }
- Progress progressDialog = progressDialogRef.get();
- if (progressDialog != null) {
- progressDialog.dismiss();
+ if (activity != null && msg.getData() != null && msg.getData().getString(MESSAGE_TEXT) != null) {
+ activity.showToast(msg.getData().getString(MESSAGE_TEXT));
}
+ dismissProgress();
return;
}
@@ -38,10 +35,7 @@ public class SimpleCancellableHandler extends CancellableHandler {
if (activity != null) {
activity.showToast((String) extra);
}
- Progress progressDialog = progressDialogRef.get();
- if (progressDialog != null) {
- progressDialog.dismiss();
- }
+ dismissProgress();
}
public final void showToast(int resId) {
diff --git a/main/src/cgeo/geocaching/utils/SimpleHandler.java b/main/src/cgeo/geocaching/utils/SimpleHandler.java
index 554ded6..b01d0e1 100644
--- a/main/src/cgeo/geocaching/utils/SimpleHandler.java
+++ b/main/src/cgeo/geocaching/utils/SimpleHandler.java
@@ -10,7 +10,7 @@ import android.os.Message;
import java.lang.ref.WeakReference;
public abstract class SimpleHandler extends Handler {
- public static final String SUCCESS_TEXT = "success_message";
+ public static final String MESSAGE_TEXT = "message_text";
protected final WeakReference<AbstractActivity> activityRef;
protected final WeakReference<Progress> progressDialogRef;
@@ -22,13 +22,10 @@ public abstract class SimpleHandler extends Handler {
@Override
public void handleMessage(final Message msg) {
AbstractActivity activity = activityRef.get();
- if (activity != null && msg.getData() != null && msg.getData().getString(SUCCESS_TEXT) != null) {
- activity.showToast(msg.getData().getString(SUCCESS_TEXT));
- }
- Progress progressDialog = progressDialogRef.get();
- if (progressDialog != null) {
- progressDialog.dismiss();
+ if (activity != null && msg.getData() != null && msg.getData().getString(MESSAGE_TEXT) != null) {
+ activity.showToast(msg.getData().getString(MESSAGE_TEXT));
}
+ dismissProgress();
return;
}