diff options
Diffstat (limited to 'main/src')
146 files changed, 2506 insertions, 1902 deletions
diff --git a/main/src/android/support/v4/app/FragmentListActivity.java b/main/src/android/support/v4/app/FragmentListActivity.java index d392ac6..e3ed42c 100644 --- a/main/src/android/support/v4/app/FragmentListActivity.java +++ b/main/src/android/support/v4/app/FragmentListActivity.java @@ -188,6 +188,7 @@ public class FragmentListActivity extends FragmentActivity { private boolean mFinishedStart = false; private Runnable mRequestFocus = new Runnable() { + @Override public void run() { mList.focusableViewAvailable(mList); } @@ -305,6 +306,7 @@ public class FragmentListActivity extends FragmentActivity { } private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() { + @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { onListItemClick((ListView)parent, v, position, id); diff --git a/main/src/cgeo/geocaching/AboutActivity.java b/main/src/cgeo/geocaching/AboutActivity.java index b7a14ff..c154ffb 100644 --- a/main/src/cgeo/geocaching/AboutActivity.java +++ b/main/src/cgeo/geocaching/AboutActivity.java @@ -17,7 +17,7 @@ public class AboutActivity extends AbstractActivity { super.onCreate(savedInstanceState); setTheme(); - setContentView(R.layout.about); + setContentView(R.layout.about_activity); setTitle(res.getString(R.string.about)); ((TextView) findViewById(R.id.about_version_string)).setText(Version.getVersionName(this)); diff --git a/main/src/cgeo/geocaching/AbstractLoggingActivity.java b/main/src/cgeo/geocaching/AbstractLoggingActivity.java index eaeffb0..37c3643 100644 --- a/main/src/cgeo/geocaching/AbstractLoggingActivity.java +++ b/main/src/cgeo/geocaching/AbstractLoggingActivity.java @@ -51,7 +51,7 @@ public abstract class AbstractLoggingActivity extends AbstractActivity { menu.findItem(MENU_SIGNATURE).setVisible(signatureAvailable); boolean smileyVisible = false; - final cgCache cache = getLogContext().getCache(); + final Geocache cache = getLogContext().getCache(); if (cache != null && ConnectorFactory.getConnector(cache).equals(GCConnector.getInstance())) { smileyVisible = true; } diff --git a/main/src/cgeo/geocaching/AbstractPopupActivity.java b/main/src/cgeo/geocaching/AbstractPopupActivity.java index db9a04c..f903d00 100644 --- a/main/src/cgeo/geocaching/AbstractPopupActivity.java +++ b/main/src/cgeo/geocaching/AbstractPopupActivity.java @@ -1,6 +1,7 @@ package cgeo.geocaching; import cgeo.geocaching.activity.AbstractActivity; +import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.apps.cache.navi.NavigationAppFactory; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.LoadFlags; @@ -37,9 +38,8 @@ public abstract class AbstractPopupActivity extends AbstractActivity { private static final int MENU_NAVIGATION = 3; private static final int MENU_DEFAULT_NAVIGATION = 2; private static final int MENU_SHOW_IN_BROWSER = 7; - protected static final String EXTRA_GEOCODE = "geocode"; - protected cgCache cache = null; + protected Geocache cache = null; protected String geocode = null; protected CacheDetailsCreator details; @@ -130,6 +130,8 @@ public abstract class AbstractPopupActivity extends AbstractActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + // set theme + this.setTheme(ActivityMixin.getDialogTheme()); // set layout setContentView(layout); setTitle(res.getString(R.string.detail)); @@ -137,7 +139,7 @@ public abstract class AbstractPopupActivity extends AbstractActivity { // get parameters final Bundle extras = getIntent().getExtras(); if (extras != null) { - geocode = extras.getString(EXTRA_GEOCODE); + geocode = extras.getString(Intents.EXTRA_GEOCODE); } if (StringUtils.isBlank(geocode)) { diff --git a/main/src/cgeo/geocaching/AdressListActivity.java b/main/src/cgeo/geocaching/AddressListActivity.java index 8ce16dd..b1de065 100644 --- a/main/src/cgeo/geocaching/AdressListActivity.java +++ b/main/src/cgeo/geocaching/AddressListActivity.java @@ -16,7 +16,7 @@ import android.os.Bundle; import java.util.List; import java.util.Locale; -public class AdressListActivity extends AbstractListActivity { +public class AddressListActivity extends AbstractListActivity { @Override public void onCreate(Bundle savedInstanceState) { @@ -27,7 +27,7 @@ public class AdressListActivity extends AbstractListActivity { setTitle(res.getString(R.string.search_address_result)); // get parameters - final String keyword = getIntent().getStringExtra("keyword"); + final String keyword = getIntent().getStringExtra(Intents.EXTRA_KEYWORD); if (keyword == null) { showToast(res.getString(R.string.err_search_address_forgot)); @@ -46,7 +46,7 @@ public class AdressListActivity extends AbstractListActivity { @Override protected List<Address> doInBackground(Void... params) { - final Geocoder geocoder = new Geocoder(AdressListActivity.this, Locale.getDefault()); + final Geocoder geocoder = new Geocoder(AddressListActivity.this, Locale.getDefault()); try { return geocoder.getFromLocationName(keyword, 20); } catch (Exception e) { @@ -55,7 +55,7 @@ public class AdressListActivity extends AbstractListActivity { Log.i("No geocoder available"); } else { - Log.e("AdressListActivity.doInBackground", e); + Log.e("AddressListActivity.doInBackground", e); } return null; } @@ -70,7 +70,7 @@ public class AdressListActivity extends AbstractListActivity { } } else { finish(); - cgeocaches.startActivityAddress(AdressListActivity.this, null, keyword); + cgeocaches.startActivityAddress(AddressListActivity.this, null, keyword); } } diff --git a/main/src/cgeo/geocaching/CacheCache.java b/main/src/cgeo/geocaching/CacheCache.java index e027a8a..e70b7a0 100644 --- a/main/src/cgeo/geocaching/CacheCache.java +++ b/main/src/cgeo/geocaching/CacheCache.java @@ -20,10 +20,10 @@ import java.util.Set; public class CacheCache { private static final int MAX_CACHED_CACHES = 1000; - final private LeastRecentlyUsedMap<String, cgCache> cachesCache; + final private LeastRecentlyUsedMap<String, Geocache> cachesCache; public CacheCache() { - cachesCache = new LeastRecentlyUsedMap.LruCache<String, cgCache>(MAX_CACHED_CACHES); + cachesCache = new LeastRecentlyUsedMap.LruCache<String, Geocache>(MAX_CACHED_CACHES); cachesCache.setRemoveHandler(new CacheRemoveHandler()); } @@ -51,7 +51,7 @@ public class CacheCache { * Cache * */ - public void putCacheInCache(final cgCache cache) { + public void putCacheInCache(final Geocache cache) { if (cache == null) { throw new IllegalArgumentException("cache must not be null"); } @@ -69,7 +69,7 @@ public class CacheCache { * Geocode of the cache to retrieve from the cache * @return cache if found, null else */ - public cgCache getCacheFromCache(final String geocode) { + public Geocache getCacheFromCache(final String geocode) { if (StringUtils.isBlank(geocode)) { throw new IllegalArgumentException("geocode must not be empty"); } @@ -80,14 +80,14 @@ public class CacheCache { public synchronized Set<String> getInViewport(final Viewport viewport, final CacheType cacheType) { final Set<String> geocodes = new HashSet<String>(); - for (final cgCache cache : cachesCache.values()) { + for (final Geocache cache : cachesCache.values()) { if (cache.getCoords() == null) { // FIXME: this kludge must be removed, it is only present to help us debug the cases where // caches contain null coordinates. Log.e("CacheCache.getInViewport: got cache with null coordinates: " + cache.getGeocode()); continue; } - if ((CacheType.ALL == cacheType || cache.getType() == cacheType) && viewport.contains(cache)) { + if (cacheType.contains(cache) && viewport.contains(cache)) { geocodes.add(cache.getGeocode()); } } @@ -99,10 +99,10 @@ public class CacheCache { return StringUtils.join(cachesCache.keySet(), ' '); } - private static class CacheRemoveHandler implements RemoveHandler<cgCache> { + private static class CacheRemoveHandler implements RemoveHandler<Geocache> { @Override - public void onRemove(final cgCache removed) { + public void onRemove(final Geocache removed) { // FIXME: as above, we sometimes get caches with null coordinates, that may then provoke // a NullPointerException down the invocation chain. if (removed.getCoords() != null) { diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java index 634eea6..f35d599 100644 --- a/main/src/cgeo/geocaching/CacheDetailActivity.java +++ b/main/src/cgeo/geocaching/CacheDetailActivity.java @@ -19,13 +19,15 @@ import cgeo.geocaching.network.HtmlImage; import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.ui.AbstractCachingPageViewCreator; +import cgeo.geocaching.ui.AnchorAwareLinkMovementMethod; import cgeo.geocaching.ui.CacheDetailsCreator; import cgeo.geocaching.ui.DecryptTextClickListener; -import cgeo.geocaching.ui.EditorDialog; import cgeo.geocaching.ui.Formatter; import cgeo.geocaching.ui.ImagesList; import cgeo.geocaching.ui.ImagesList.ImageType; import cgeo.geocaching.ui.LoggingUI; +import cgeo.geocaching.ui.WeakReferenceHandler; +import cgeo.geocaching.ui.dialog.EditorDialog; import cgeo.geocaching.utils.BaseUtils; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.ClipboardUtils; @@ -35,6 +37,7 @@ import cgeo.geocaching.utils.HtmlUtils; import cgeo.geocaching.utils.ImageHelper; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.MatcherWrapper; +import cgeo.geocaching.utils.RunnableWithArgument; import cgeo.geocaching.utils.TranslationUtils; import cgeo.geocaching.utils.UnknownTagsHandler; @@ -45,7 +48,6 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import android.R.color; -import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; @@ -53,6 +55,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; @@ -76,6 +79,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.view.View; +import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; @@ -88,7 +92,6 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; -import android.widget.RadioButton; import android.widget.ScrollView; import android.widget.TextView; import android.widget.TextView.BufferType; @@ -129,8 +132,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private static final int CONTEXT_MENU_WAYPOINT_RESET_ORIGINAL_CACHE_COORDINATES = 1241; private static final Pattern DARK_COLOR_PATTERN = Pattern.compile(Pattern.quote("color=\"#") + "(0[0-9]){3}" + "\""); + public static final String STATE_PAGE_INDEX = "cgeo.geocaching.pageIndex"; - private cgCache cache; + private Geocache cache; private final Progress progress = new Progress(); private SearchResult search; @@ -214,9 +218,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc String name = null; String guid = null; if (geocode == null && extras != null) { - geocode = extras.getString("geocode"); - name = extras.getString("name"); - guid = extras.getString("guid"); + geocode = extras.getString(Intents.EXTRA_GEOCODE); + name = extras.getString(Intents.EXTRA_NAME); + guid = extras.getString(Intents.EXTRA_GUID); } // try to get data from URI @@ -287,7 +291,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } }); - final int pageToOpen = Settings.isOpenLastDetailsPage() ? Settings.getLastDetailsPage() : 1; + final int pageToOpen = savedInstanceState != null ? + savedInstanceState.getInt(STATE_PAGE_INDEX, 0) : + Settings.isOpenLastDetailsPage() ? Settings.getLastDetailsPage() : 1; createViewPager(pageToOpen, new OnPageSelectedListener() { @Override @@ -307,6 +313,12 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } @Override + public void onSaveInstanceState(final Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt(STATE_PAGE_INDEX, getCurrentItem()); + } + + @Override public void onResume() { super.onResume(); @@ -337,9 +349,10 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc final int viewId = view.getId(); contextMenuWPIndex = -1; switch (viewId) { - case R.id.value: // coordinates + case R.id.value: // coordinates, gc-code, name clickedItemText = ((TextView) view).getText(); - buildOptionsContextmenu(menu, viewId, res.getString(R.string.cache_coordinates), true); + String itemTitle = (String) ((TextView) ((View) view.getParent()).findViewById(R.id.name)).getText(); + buildOptionsContextmenu(menu, viewId, itemTitle, true); break; case R.id.shortdesc: clickedItemText = ((TextView) view).getText(); @@ -498,7 +511,15 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc break; case CONTEXT_MENU_WAYPOINT_RESET_ORIGINAL_CACHE_COORDINATES: - new ResetCacheCoordinatesDialog(cache, cache.getWaypoint(index), this).show(); + final Waypoint waypointReset = cache.getWaypoint(index); + if (ConnectorFactory.getConnector(cache).supportsOwnCoordinates()) { + createResetCacheCoordinatesDialog(cache, waypointReset).show(); + } + else { + final ProgressDialog progressDialog = ProgressDialog.show(this, getString(R.string.cache), getString(R.string.waypoint_reset), true); + final HandlerResetCoordinates handler = new HandlerResetCoordinates(this, progressDialog, false); + new ResetCoordsThread(cache, handler, waypointReset, true, false, progressDialog).start(); + } break; default: @@ -677,7 +698,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc @Override public void run() { - search = cgCache.searchByGeocode(geocode, StringUtils.isBlank(geocode) ? guid : null, 0, false, handler); + search = Geocache.searchByGeocode(geocode, StringUtils.isBlank(geocode) ? guid : null, 0, false, handler); handler.sendMessage(Message.obtain()); } } @@ -757,14 +778,14 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } /** - * Tries to navigate to the {@link cgCache} of this activity. + * Tries to navigate to the {@link Geocache} of this activity. */ private void startDefaultNavigation() { NavigationAppFactory.startDefaultNavigationApplication(1, this, cache); } /** - * Tries to navigate to the {@link cgCache} of this activity. + * Tries to navigate to the {@link Geocache} of this activity. */ private void startDefaultNavigation2() { NavigationAppFactory.startDefaultNavigationApplication(2, this, cache); @@ -833,7 +854,8 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc private void showUserActionsDialog(final CharSequence name) { final CharSequence[] items = { res.getString(R.string.user_menu_view_hidden), res.getString(R.string.user_menu_view_found), - res.getString(R.string.user_menu_open_browser) + res.getString(R.string.user_menu_open_browser), + res.getString(R.string.user_menu_send_message) }; AlertDialog.Builder builder = new AlertDialog.Builder(this); @@ -851,6 +873,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc case 2: startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + Network.encode(name.toString())))); return; + case 3: + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/email/?u=" + Network.encode(name.toString())))); + return; default: break; } @@ -878,7 +903,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc public static void startActivity(final Context context, final String geocode) { final Intent detailIntent = new Intent(context, CacheDetailActivity.class); - detailIntent.putExtra("geocode", geocode); + detailIntent.putExtra(Intents.EXTRA_GEOCODE, geocode); context.startActivity(detailIntent); } @@ -1023,8 +1048,8 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } final boolean strikethru = !CacheAttribute.isEnabled(attributeName); - final CacheAttribute attrib = CacheAttribute.getByGcRawName(CacheAttribute.trimAttributeName(attributeName)); - if (attrib != CacheAttribute.UNKNOWN) { + final CacheAttribute attrib = CacheAttribute.getByRawName(CacheAttribute.trimAttributeName(attributeName)); + if (attrib != null) { noAttributeIconsFound = false; Drawable d = res.getDrawable(attrib.drawableId); iv.setImageDrawable(d); @@ -1038,7 +1063,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc fl.addView(strikethruImage); } } else { - Drawable d = res.getDrawable(R.drawable.attribute_icon_not_found); + Drawable d = res.getDrawable(R.drawable.attribute_unknown); iv.setImageDrawable(d); } @@ -1065,10 +1090,11 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc for (String attributeName : cache.getAttributes()) { final boolean enabled = CacheAttribute.isEnabled(attributeName); // search for a translation of the attribute - CacheAttribute attrib = CacheAttribute.getByGcRawName(CacheAttribute.trimAttributeName(attributeName)); - if (attrib != CacheAttribute.UNKNOWN) { - attributeName = attrib.getL10n(enabled); + CacheAttribute attrib = CacheAttribute.getByRawName(CacheAttribute.trimAttributeName(attributeName)); + if (attrib == null) { + attrib = CacheAttribute.UNKNOWN; } + attributeName = attrib.getL10n(enabled); if (buffer.length() > 0) { buffer.append('\n'); } @@ -1121,10 +1147,10 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc span.setSpan(new ForegroundColorSpan(res.getColor(R.color.archived_cache_color)), 0, span.toString().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } - details.add(R.string.cache_name, span); + registerForContextMenu(details.add(R.string.cache_name, span)); details.add(R.string.cache_type, cache.getType().getL10n()); details.addSize(cache); - details.add(R.string.cache_geocode, cache.getGeocode()); + registerForContextMenu(details.add(R.string.cache_geocode, cache.getGeocode())); details.addCacheState(cache); details.addDistance(cache, cacheDistanceView); @@ -1196,12 +1222,12 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } // cache attributes - if (cache.getAttributes().isNotEmpty()) { + if (!cache.getAttributes().isEmpty()) { new AttributeViewBuilder().fillView((LinearLayout) view.findViewById(R.id.attributes_innerbox)); view.findViewById(R.id.attributes_box).setVisibility(View.VISIBLE); } - updateOfflineBox(); + updateOfflineBox(view, cache, res, new RefreshCacheClickListener(), new DropCacheClickListener(), new StoreCacheClickListener()); // watchlist Button buttonWatchlistAdd = (Button) view.findViewById(R.id.add_to_watchlist); @@ -1217,6 +1243,11 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc buttonFavPointRemove.setOnClickListener(new FavoriteRemoveClickListener()); updateFavPointBox(); + // list + Button buttonChangeList = (Button) view.findViewById(R.id.change_list); + buttonChangeList.setOnClickListener(new ChangeListClickListener()); + updateListBox(); + // data license IConnector connector = ConnectorFactory.getConnector(cache); if (connector != null) { @@ -1286,6 +1317,21 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc return; } + if (Settings.getChooseList()) { + // let user select list to store cache in + new StoredList.UserInterface(CacheDetailActivity.this).promptForListSelection(R.string.list_title, + new RunnableWithArgument<Integer>() { + @Override + public void run(final Integer selectedListId) { + storeCache(selectedListId); + } + }, true, StoredList.TEMPORARY_LIST_ID); + } else { + storeCache(StoredList.TEMPORARY_LIST_ID); + } + } + + protected void storeCache(int listId) { final StoreCacheHandler storeCacheHandler = new 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()); @@ -1294,7 +1340,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc storeThread.interrupt(); } - storeThread = new StoreCacheThread(storeCacheHandler); + storeThread = new StoreCacheThread(listId, storeCacheHandler); storeThread.start(); } } @@ -1321,15 +1367,17 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } private class StoreCacheThread extends Thread { + final private int listId; final private CancellableHandler handler; - public StoreCacheThread(final CancellableHandler handler) { + public StoreCacheThread(final int listId, final CancellableHandler handler) { + this.listId = listId; this.handler = handler; } @Override public void run() { - cache.store(handler); + cache.store(listId, handler); } } @@ -1514,6 +1562,38 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } /** + * Listener for "change list" button + */ + private class ChangeListClickListener implements View.OnClickListener { + @Override + public void onClick(View view) { + new StoredList.UserInterface(CacheDetailActivity.this).promptForListSelection(R.string.list_title, + new RunnableWithArgument<Integer>() { + @Override + public void run(final Integer selectedListId) { + switchListById(selectedListId); + } + }, true, cache.getListId()); + } + } + + /** + * move cache to another list + * + * @param listId + * the ID of the list + */ + public void switchListById(int listId) { + if (listId < 0) { + return; + } + + Settings.saveLastList(listId); + cgData.moveToList(cache, listId); + updateListBox(); + } + + /** * shows/hides buttons, sets text in watchlist box */ private void updateWatchlistBox() { @@ -1527,7 +1607,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc Button buttonRemove = (Button) view.findViewById(R.id.remove_from_watchlist); TextView text = (TextView) view.findViewById(R.id.watchlist_text); - if (cache.isOnWatchlist() || cache.isOwn()) { + if (cache.isOnWatchlist() || cache.isOwner()) { buttonAdd.setVisibility(View.GONE); buttonRemove.setVisibility(View.VISIBLE); text.setText(R.string.cache_watchlist_on); @@ -1538,7 +1618,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } // the owner of a cache has it always on his watchlist. Adding causes an error - if (cache.isOwn()) { + if (cache.isOwner()) { buttonAdd.setEnabled(false); buttonAdd.setVisibility(View.GONE); buttonRemove.setEnabled(false); @@ -1554,7 +1634,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc LinearLayout layout = (LinearLayout) view.findViewById(R.id.favpoint_box); boolean supportsFavoritePoints = cache.supportsFavoritePoints(); layout.setVisibility(supportsFavoritePoints ? View.VISIBLE : View.GONE); - if (!supportsFavoritePoints || cache.isOwn() || !Settings.isPremiumMember()) { + if (!supportsFavoritePoints || cache.isOwner() || !Settings.isPremiumMember()) { return; } Button buttonAdd = (Button) view.findViewById(R.id.add_to_favpoint); @@ -1581,6 +1661,31 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } /** + * shows/hides/updates list box + */ + private void updateListBox() { + View box = view.findViewById(R.id.list_box); + + if (cache.isOffline()) { + // show box + box.setVisibility(View.VISIBLE); + + // update text + TextView text = (TextView) view.findViewById(R.id.list_text); + StoredList list = cgData.getList(cache.getListId()); + if (list != null) { + text.setText(res.getString(R.string.cache_list_text) + " " + list.title); + } else { + // this should not happen + text.setText(R.string.cache_list_unknown); + } + } else { + // hide box + box.setVisibility(View.GONE); + } + } + + /** * Handler, called when watchlist add or remove is done */ private class WatchlistHandler extends Handler { @@ -1596,46 +1701,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } } - private void updateOfflineBox() { - // offline use - final TextView offlineText = (TextView) view.findViewById(R.id.offline_text); - final Button offlineRefresh = (Button) view.findViewById(R.id.offline_refresh); - final Button offlineStore = (Button) view.findViewById(R.id.offline_store); - - if (cache.isOffline()) { - long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.getDetailedUpdate() / (60 * 1000)); // minutes - - String ago; - if (diff < 15) { - ago = res.getString(R.string.cache_offline_time_mins_few); - } else if (diff < 50) { - ago = res.getString(R.string.cache_offline_time_about) + " " + diff + " " + res.getString(R.string.cache_offline_time_mins); - } else if (diff < 90) { - ago = res.getString(R.string.cache_offline_time_about) + " " + res.getString(R.string.cache_offline_time_hour); - } else if (diff < (48 * 60)) { - ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / 60) + " " + res.getString(R.string.cache_offline_time_hours); - } else { - ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / (24 * 60)) + " " + res.getString(R.string.cache_offline_time_days); - } - - offlineText.setText(res.getString(R.string.cache_offline_stored) + "\n" + ago); - offlineRefresh.setOnClickListener(new RefreshCacheClickListener()); - - offlineStore.setText(res.getString(R.string.cache_offline_drop)); - offlineStore.setClickable(true); - offlineStore.setOnClickListener(new DropCacheClickListener()); - } else { - offlineText.setText(res.getString(R.string.cache_offline_not_ready)); - offlineRefresh.setOnClickListener(new RefreshCacheClickListener()); - - offlineStore.setText(res.getString(R.string.cache_offline_store)); - offlineStore.setClickable(true); - offlineStore.setOnClickListener(new StoreCacheClickListener()); - } - offlineRefresh.setVisibility(cache.supportsRefresh() ? View.VISIBLE : View.GONE); - offlineRefresh.setClickable(true); - } - private class PreviewMapTask extends AsyncTask<Void, Void, BitmapDrawable> { @Override protected BitmapDrawable doInBackground(Void... parameters) { @@ -1658,7 +1723,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } } - private Bitmap decode(final cgCache cache) { + private Bitmap decode(final Geocache cache) { return StaticMapsProvider.getPreviewMap(cache.getGeocode()); } @@ -1872,7 +1937,9 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc // sometimes technically incorrect. if (unknownTagsHandler.isProblematicDetected() && descriptionView != null) { final int startPos = description.length(); - ((Editable) description).append("\n\n").append(res.getString(R.string.cache_description_table_note)); + final IConnector connector = ConnectorFactory.getConnector(cache); + final Spanned tableNote = Html.fromHtml(res.getString(R.string.cache_description_table_note, "<a href=\"" + cache.getUrl() + "\">" + connector.getName() + "</a>")); + ((Editable) description).append("\n\n").append(tableNote); ((Editable) description).setSpan(new StyleSpan(Typeface.ITALIC), startPos, description.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); publishProgress(); } @@ -1892,7 +1959,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc if (description != null) { if (StringUtils.isNotBlank(descriptionString)) { descriptionView.setText(description, TextView.BufferType.SPANNABLE); - descriptionView.setMovementMethod(LinkMovementMethod.getInstance()); + descriptionView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance()); fixBlackTextColor(descriptionView, descriptionString); } @@ -1978,7 +2045,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } } - final List<LogEntry> logs = allLogs ? cache.getLogs().asList() : cache.getFriendsLogs(); + final List<LogEntry> logs = allLogs ? cache.getLogs() : cache.getFriendsLogs(); view.setAdapter(new ArrayAdapter<LogEntry>(CacheDetailActivity.this, R.layout.cacheview_logs_item, logs) { final UserActionsClickListener userActionsClickListener = new UserActionsClickListener(); final DecryptTextClickListener decryptTextClickListener = new DecryptTextClickListener(); @@ -2231,72 +2298,74 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc public static void startActivity(final Context context, final String geocode, final String cacheName) { final Intent cachesIntent = new Intent(context, CacheDetailActivity.class); - cachesIntent.putExtra("geocode", geocode); - cachesIntent.putExtra("name", cacheName); + cachesIntent.putExtra(Intents.EXTRA_GEOCODE, geocode); + cachesIntent.putExtra(Intents.EXTRA_NAME, cacheName); context.startActivity(cachesIntent); } public static void startActivityGuid(final Context context, final String guid, final String cacheName) { final Intent cacheIntent = new Intent(context, CacheDetailActivity.class); - cacheIntent.putExtra("guid", guid); - cacheIntent.putExtra("name", cacheName); + cacheIntent.putExtra(Intents.EXTRA_GUID, guid); + cacheIntent.putExtra(Intents.EXTRA_NAME, cacheName); context.startActivity(cacheIntent); } /** * A dialog to allow the user to select reseting coordinates local/remote/both. */ - private class ResetCacheCoordinatesDialog extends AlertDialog { + private AlertDialog createResetCacheCoordinatesDialog(final Geocache cache, final Waypoint wpt) { - final RadioButton resetBoth; - final RadioButton resetLocal; - - public ResetCacheCoordinatesDialog(final cgCache cache, final Waypoint wpt, final Activity activity) { - super(activity); - - View layout = activity.getLayoutInflater().inflate(R.layout.reset_cache_coords_dialog, null); - setView(layout); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.waypoint_reset_cache_coords); - resetLocal = (RadioButton) layout.findViewById(R.id.reset_cache_coordinates_local); - resetBoth = (RadioButton) layout.findViewById(R.id.reset_cache_coordinates_local_and_remote); + String[] items = new String[] {res.getString(R.string.waypoint_localy_reset_cache_coords), res.getString(R.string.waypoint_reset_local_and_remote_cache_coords)}; + builder.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() { - if (ConnectorFactory.getConnector(cache).supportsOwnCoordinates()) { - resetBoth.setVisibility(View.VISIBLE); + @Override + public void onClick(DialogInterface dialog, final int which) { + dialog.dismiss(); + final ProgressDialog progressDialog = ProgressDialog.show(CacheDetailActivity.this, getString(R.string.cache), getString(R.string.waypoint_reset), true); + final HandlerResetCoordinates handler = new HandlerResetCoordinates(CacheDetailActivity.this, progressDialog, which == 1); + new ResetCoordsThread(cache, handler, wpt, which == 0 || which == 1, which == 1, progressDialog).start(); } + }); + return builder.create(); + } - layout.findViewById(R.id.reset).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - final ProgressDialog p = ProgressDialog.show(CacheDetailActivity.this, res.getString(R.string.cache), res.getString(R.string.waypoint_reset), true); - final Handler h = new Handler() { - private boolean remoteFinished = false; - private boolean localFinished = false; + private static class HandlerResetCoordinates extends WeakReferenceHandler<CacheDetailActivity> { + private boolean remoteFinished = false; + private boolean localFinished = false; + private final ProgressDialog progressDialog; + private final boolean resetRemote; - @Override - public void handleMessage(Message msg) { - if (msg.what == ResetCoordsThread.LOCAL) { - localFinished = true; - } else { - remoteFinished = true; - } + protected HandlerResetCoordinates(CacheDetailActivity activity, ProgressDialog progressDialog, boolean resetRemote) { + super(activity); + this.progressDialog = progressDialog; + this.resetRemote = resetRemote; + } - if ((localFinished) && (remoteFinished || !resetBoth.isChecked())) { - p.dismiss(); - notifyDataSetChanged(); - } - } + @Override + public void handleMessage(Message msg) { + if (msg.what == ResetCoordsThread.LOCAL) { + localFinished = true; + } else { + remoteFinished = true; + } - }; - new ResetCoordsThread(cache, h, wpt, resetLocal.isChecked() || resetBoth.isChecked(), resetBoth.isChecked(), p).start(); + if (localFinished && (remoteFinished || !resetRemote)) { + progressDialog.dismiss(); + final CacheDetailActivity activity = getActivity(); + if (activity != null) { + activity.notifyDataSetChanged(); } - }); + } } + } private class ResetCoordsThread extends Thread { - private final cgCache cache; + private final Geocache cache; private final Handler handler; private final boolean local; private final boolean remote; @@ -2305,7 +2374,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc public static final int LOCAL = 0; public static final int ON_WEBSITE = 1; - public ResetCoordsThread(cgCache cache, Handler handler, final Waypoint wpt, boolean local, boolean remote, final ProgressDialog progress) { + public ResetCoordsThread(Geocache cache, Handler handler, final Waypoint wpt, boolean local, boolean remote, final ProgressDialog progress) { this.cache = cache; this.handler = handler; this.local = local; @@ -2378,7 +2447,7 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc pages.add(Page.DETAILS); final int detailsIndex = pages.size() - 1; pages.add(Page.DESCRIPTION); - if (cache.getLogs().isNotEmpty()) { + if (!cache.getLogs().isEmpty()) { pages.add(Page.LOGS); } if (CollectionUtils.isNotEmpty(cache.getFriendsLogs())) { @@ -2422,4 +2491,47 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc } } + static void updateOfflineBox(final View view, final Geocache cache, final Resources res, + final OnClickListener refreshCacheClickListener, + final OnClickListener dropCacheClickListener, + final OnClickListener storeCacheClickListener) { + // offline use + final TextView offlineText = (TextView) view.findViewById(R.id.offline_text); + final Button offlineRefresh = (Button) view.findViewById(R.id.offline_refresh); + final Button offlineStore = (Button) view.findViewById(R.id.offline_store); + + if (cache.isOffline()) { + long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.getDetailedUpdate() / (60 * 1000)); // minutes + + String ago; + if (diff < 15) { + ago = res.getString(R.string.cache_offline_time_mins_few); + } else if (diff < 50) { + ago = res.getString(R.string.cache_offline_time_about) + " " + diff + " " + res.getString(R.string.cache_offline_time_mins); + } else if (diff < 90) { + ago = res.getString(R.string.cache_offline_time_about) + " " + res.getString(R.string.cache_offline_time_hour); + } else if (diff < (48 * 60)) { + ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / 60) + " " + res.getString(R.string.cache_offline_time_hours); + } else { + ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / (24 * 60)) + " " + res.getString(R.string.cache_offline_time_days); + } + + offlineText.setText(res.getString(R.string.cache_offline_stored) + "\n" + ago); + offlineRefresh.setOnClickListener(refreshCacheClickListener); + + offlineStore.setText(res.getString(R.string.cache_offline_drop)); + offlineStore.setClickable(true); + offlineStore.setOnClickListener(dropCacheClickListener); + } else { + offlineText.setText(res.getString(R.string.cache_offline_not_ready)); + offlineRefresh.setOnClickListener(refreshCacheClickListener); + + offlineStore.setText(res.getString(R.string.cache_offline_store)); + offlineStore.setClickable(true); + offlineStore.setOnClickListener(storeCacheClickListener); + } + offlineRefresh.setVisibility(cache.supportsRefresh() ? View.VISIBLE : View.GONE); + offlineRefresh.setClickable(true); + } + } diff --git a/main/src/cgeo/geocaching/CachePopup.java b/main/src/cgeo/geocaching/CachePopup.java index 4bda294..e6d0148 100644 --- a/main/src/cgeo/geocaching/CachePopup.java +++ b/main/src/cgeo/geocaching/CachePopup.java @@ -6,6 +6,7 @@ import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.ui.CacheDetailsCreator; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.RunnableWithArgument; import org.apache.commons.lang3.StringUtils; @@ -15,7 +16,6 @@ import android.content.res.Configuration; import android.os.Handler; import android.os.Message; import android.view.View; -import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; @@ -90,47 +90,8 @@ public class CachePopup extends AbstractPopupActivity { addCacheDetails(); // offline use - final TextView offlineText = (TextView) findViewById(R.id.offline_text); - final Button offlineRefresh = (Button) findViewById(R.id.offline_refresh); - final Button offlineStore = (Button) findViewById(R.id.offline_store); - - if (cache.getListId() > 0) { - final long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.getDetailedUpdate() / (60 * 1000)); // minutes - - String ago; - if (diff < 15) { - ago = res.getString(R.string.cache_offline_time_mins_few); - } else if (diff < 50) { - ago = res.getString(R.string.cache_offline_time_about) + " " + diff + " " + res.getString(R.string.cache_offline_time_mins); - } else if (diff < 90) { - ago = res.getString(R.string.cache_offline_time_about) + " " + res.getString(R.string.cache_offline_time_hour); - } else if (diff < (48 * 60)) { - ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / 60) + " " + res.getString(R.string.cache_offline_time_hours); - } else { - ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / (24 * 60)) + " " + res.getString(R.string.cache_offline_time_days); - } - - offlineText.setText(res.getString(R.string.cache_offline_stored) + "\n" + ago); - - offlineRefresh.setVisibility(View.VISIBLE); - offlineRefresh.setEnabled(true); - offlineRefresh.setOnClickListener(new RefreshCacheClickListener()); - - offlineStore.setText(res.getString(R.string.cache_offline_drop)); - offlineStore.setEnabled(true); - offlineStore.setOnClickListener(new DropCacheClickListener()); - } else { - offlineText.setText(res.getString(R.string.cache_offline_not_ready)); - - offlineRefresh.setVisibility(View.GONE); - offlineRefresh.setEnabled(false); - offlineRefresh.setOnTouchListener(null); - offlineRefresh.setOnClickListener(null); + CacheDetailActivity.updateOfflineBox(findViewById(android.R.id.content), cache, res, new RefreshCacheClickListener(), new DropCacheClickListener(), new StoreCacheClickListener()); - offlineStore.setText(res.getString(R.string.cache_offline_store)); - offlineStore.setEnabled(true); - offlineStore.setOnClickListener(new StoreCacheClickListener()); - } } catch (Exception e) { Log.e("cgeopopup.init", e); } @@ -154,22 +115,39 @@ public class CachePopup extends AbstractPopupActivity { return; } + if (Settings.getChooseList()) { + // let user select list to store cache in + new StoredList.UserInterface(CachePopup.this).promptForListSelection(R.string.list_title, + new RunnableWithArgument<Integer>() { + @Override + public void run(final Integer selectedListId) { + storeCache(selectedListId); + } + }, true, StoredList.TEMPORARY_LIST_ID); + } else { + storeCache(StoredList.TEMPORARY_LIST_ID); + } + } + + protected void storeCache(final int listId) { final StoreCacheHandler storeCacheHandler = new StoreCacheHandler(); progress.show(CachePopup.this, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true, storeCacheHandler.cancelMessage()); - new StoreCacheThread(storeCacheHandler).start(); + new StoreCacheThread(listId, storeCacheHandler).start(); } } private class StoreCacheThread extends Thread { + final private int listId; final private CancellableHandler handler; - public StoreCacheThread(final CancellableHandler handler) { + public StoreCacheThread(final int listId, final CancellableHandler handler) { + this.listId = listId; this.handler = handler; } @Override public void run() { - cache.store(handler); + cache.store(listId, handler); invalidateOptionsMenuCompatible(); } } @@ -235,7 +213,7 @@ public class CachePopup extends AbstractPopupActivity { } /** - * Tries to navigate to the {@link cgCache} of this activity. + * Tries to navigate to the {@link Geocache} of this activity. */ @Override protected void startDefaultNavigation2() { @@ -249,7 +227,7 @@ public class CachePopup extends AbstractPopupActivity { public static void startActivity(final Context context, final String geocode) { final Intent popupIntent = new Intent(context, CachePopup.class); - popupIntent.putExtra(EXTRA_GEOCODE, geocode); + popupIntent.putExtra(Intents.EXTRA_GEOCODE, geocode); context.startActivity(popupIntent); } diff --git a/main/src/cgeo/geocaching/EditWaypointActivity.java b/main/src/cgeo/geocaching/EditWaypointActivity.java index 3958d5f..3c8789f 100644 --- a/main/src/cgeo/geocaching/EditWaypointActivity.java +++ b/main/src/cgeo/geocaching/EditWaypointActivity.java @@ -11,6 +11,7 @@ import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; +import cgeo.geocaching.ui.dialog.CoordinatesInputDialog; import cgeo.geocaching.utils.BaseUtils; import cgeo.geocaching.utils.GeoDirHandler; import cgeo.geocaching.utils.Log; @@ -20,6 +21,7 @@ import org.apache.commons.lang3.StringUtils; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; +import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -81,7 +83,7 @@ public class EditWaypointActivity extends AbstractActivity { else { ((EditText) findViewById(R.id.note)).setText(StringUtils.trimToEmpty(waypoint.getNote())); } - cgCache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_ONLY); + Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_ONLY); setCoordsModificationVisibility(ConnectorFactory.getConnector(geocode), cache); } @@ -112,9 +114,9 @@ public class EditWaypointActivity extends AbstractActivity { // get parameters Bundle extras = getIntent().getExtras(); if (extras != null) { - geocode = extras.getString("geocode"); - wpCount = extras.getInt("count", 0); - id = extras.getInt("waypoint"); + geocode = extras.getString(Intents.EXTRA_GEOCODE); + wpCount = extras.getInt(Intents.EXTRA_COUNT, 0); + id = extras.getInt(Intents.EXTRA_WAYPOINT_ID); } if (StringUtils.isBlank(geocode) && id <= 0) { @@ -159,7 +161,7 @@ public class EditWaypointActivity extends AbstractActivity { } if (geocode != null) { - cgCache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); IConnector con = ConnectorFactory.getConnector(geocode); setCoordsModificationVisibility(con, cache); } @@ -169,7 +171,7 @@ public class EditWaypointActivity extends AbstractActivity { disableSuggestions((EditText) findViewById(R.id.distance)); } - private void setCoordsModificationVisibility(IConnector con, cgCache cache) { + private void setCoordsModificationVisibility(IConnector con, Geocache cache) { if (cache != null && (cache.getType() == CacheType.MYSTERY || cache.getType() == CacheType.MULTI)) { findViewById(R.id.modify_cache_coordinates_group).setVisibility(View.VISIBLE); findViewById(R.id.modify_cache_coordinates_local_and_remote).setVisibility(con.supportsOwnCoordinates() ? View.VISIBLE : View.GONE); @@ -290,10 +292,10 @@ public class EditWaypointActivity extends AbstractActivity { } else if (gpTemp != null) { gp = gpTemp; } - cgCache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); - cgeocoords coordsDialog = new cgeocoords(EditWaypointActivity.this, cache, gp, app.currentGeo()); + Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); + CoordinatesInputDialog coordsDialog = new CoordinatesInputDialog(EditWaypointActivity.this, cache, gp, app.currentGeo()); coordsDialog.setCancelable(true); - coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() { + coordsDialog.setOnCoordinateUpdate(new CoordinatesInputDialog.CoordinateUpdate() { @Override public void update(final Geopoint gp) { ((Button) findViewById(R.id.buttonLatitude)).setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); @@ -352,11 +354,17 @@ public class EditWaypointActivity extends AbstractActivity { } } + public static final int SUCCESS = 0; + public static final int UPLOAD_START = 1; + public static final int UPLOAD_ERROR = 2; + public static final int UPLOAD_NOT_POSSIBLE = 3; + public static final int UPLOAD_SUCCESS = 4; + public static final int SAVE_ERROR = 5; + private class coordsListener implements View.OnClickListener { @Override public void onClick(View arg0) { - // TODO Show progress across whole function, it is performing very long time on slower devices final String bearingText = ((EditText) findViewById(R.id.bearing)).getText().toString(); // combine distance from EditText and distanceUnit saved from Spinner final String distanceText = ((EditText) findViewById(R.id.distance)).getText().toString() + distanceUnit; @@ -408,121 +416,118 @@ public class EditWaypointActivity extends AbstractActivity { coords = coords.project(bearing, distance); } - String name = ((EditText) findViewById(R.id.name)).getText().toString().trim(); // if no name is given, just give the waypoint its number as name - if (StringUtils.isEmpty(name)) { - name = res.getString(R.string.waypoint) + " " + (wpCount + 1); - } + final String givenName = ((EditText) findViewById(R.id.name)).getText().toString().trim(); + final String name = StringUtils.isNotEmpty(givenName) ? givenName : res.getString(R.string.waypoint) + " " + (wpCount + 1); final String note = ((EditText) findViewById(R.id.note)).getText().toString().trim(); + final Geopoint coordsToSave = coords; + final ProgressDialog progress = ProgressDialog.show(EditWaypointActivity.this, getString(R.string.cache), getString(R.string.waypoint_being_saved), true); + final Handler finishHandler = new Handler() { - final Waypoint waypoint = new Waypoint(name, type, own); - waypoint.setGeocode(geocode); - waypoint.setPrefix(prefix); - waypoint.setLookup(lookup); - waypoint.setCoords(coords); - waypoint.setNote(note); - waypoint.setId(id); - - cgCache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); - if (null != cache && cache.addOrChangeWaypoint(waypoint, true)) { - cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); - StaticMapsProvider.removeWpStaticMaps(id, geocode); - if (Settings.isStoreOfflineWpMaps()) { - StaticMapsProvider.storeWaypointStaticMap(cache, waypoint, false); - } - final RadioButton modifyLocal = (RadioButton) findViewById(R.id.modify_cache_coordinates_local); - final RadioButton modifyBoth = (RadioButton) findViewById(R.id.modify_cache_coordinates_local_and_remote); - if (modifyLocal.isChecked() || modifyBoth.isChecked()) { - if (!cache.hasUserModifiedCoords()) { - final Waypoint origWaypoint = new Waypoint(cgeoapplication.getInstance().getString(R.string.cache_coordinates_original), WaypointType.ORIGINAL, false); - origWaypoint.setCoords(cache.getCoords()); - cache.addOrChangeWaypoint(origWaypoint, false); - cache.setUserModifiedCoords(true); + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case UPLOAD_SUCCESS: + showToast(getString(R.string.waypoint_coordinates_has_been_modified_on_website, coordsToSave)); + //$FALL-THROUGH$ + case SUCCESS: + progress.dismiss(); + finish(); + break; + case UPLOAD_START: + progress.setMessage(getString(R.string.waypoint_coordinates_uploading_to_website, coordsToSave)); + break; + case UPLOAD_ERROR: + progress.dismiss(); + finish(); + showToast(getString(R.string.waypoint_coordinates_upload_error)); + break; + case UPLOAD_NOT_POSSIBLE: + progress.dismiss(); + finish(); + showToast(getString(R.string.waypoint_coordinates_couldnt_be_modified_on_website)); + break; + case SAVE_ERROR: + progress.dismiss(); + finish(); //TODO: should we close activity here ? + showToast(res.getString(R.string.err_waypoint_add_failed)); + break; } - cache.setCoords(waypoint.getCoords()); - cgData.saveChangedCache(cache); } - if (modifyBoth.isChecked() && waypoint.getCoords() != null) { - if (cache.supportsOwnCoordinates()) { - final ProgressDialog progress = ProgressDialog.show(EditWaypointActivity.this, getString(R.string.cache), getString(R.string.waypoint_coordinates_uploading_to_website, waypoint.getCoords()), true); - Handler finishHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - progress.dismiss(); - finish(); + }; + + class SaveWptTask extends AsyncTask<Void, Void, Void> { + + @Override + protected Void doInBackground(Void... params) { + final Waypoint waypoint = new Waypoint(name, type, own); + waypoint.setGeocode(geocode); + waypoint.setPrefix(prefix); + waypoint.setLookup(lookup); + waypoint.setCoords(coordsToSave); + waypoint.setNote(note); + waypoint.setId(id); + + Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); + if (null != cache && cache.addOrChangeWaypoint(waypoint, true)) { + cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + StaticMapsProvider.removeWpStaticMaps(id, geocode); + if (Settings.isStoreOfflineWpMaps()) { + StaticMapsProvider.storeWaypointStaticMap(cache, waypoint, false); + } + final RadioButton modifyLocal = (RadioButton) findViewById(R.id.modify_cache_coordinates_local); + final RadioButton modifyBoth = (RadioButton) findViewById(R.id.modify_cache_coordinates_local_and_remote); + if (modifyLocal.isChecked() || modifyBoth.isChecked()) { + if (!cache.hasUserModifiedCoords()) { + final Waypoint origWaypoint = new Waypoint(cgeoapplication.getInstance().getString(R.string.cache_coordinates_original), WaypointType.ORIGINAL, false); + origWaypoint.setCoords(cache.getCoords()); + cache.addOrChangeWaypoint(origWaypoint, false); + cache.setUserModifiedCoords(true); } - }; - new UploadModifiedCoordsThread(cache, waypoint.getCoords(), progress, finishHandler).start(); + cache.setCoords(waypoint.getCoords()); + cgData.saveChangedCache(cache); + } + if (modifyBoth.isChecked() && waypoint.getCoords() != null) { + finishHandler.sendEmptyMessage(UPLOAD_START); + + if (cache.supportsOwnCoordinates()) { + boolean result = uploadModifiedCoords(cache, waypoint.getCoords()); + finishHandler.sendEmptyMessage(result ? SUCCESS : UPLOAD_ERROR); + } else { + showToast(getString(R.string.waypoint_coordinates_couldnt_be_modified_on_website)); + finishHandler.sendEmptyMessage(UPLOAD_NOT_POSSIBLE); + } + } else { + finishHandler.sendEmptyMessage(SUCCESS); + } } else { - showToast(getString(R.string.waypoint_coordinates_couldnt_be_modified_on_website)); + finishHandler.sendEmptyMessage(SAVE_ERROR); } - } else { - finish(); + return null; } - } else { - showToast(res.getString(R.string.err_waypoint_add_failed)); } + new SaveWptTask().execute(); } } - private class UploadModifiedCoordsThread extends Thread { - - private final Geopoint waypoint_uploaded; - private final ProgressDialog progress; - private final cgCache cache; - private final Handler handler; - - public UploadModifiedCoordsThread(cgCache cache, Geopoint wpt, ProgressDialog progress, Handler finishHandler) { - this.cache = cache; - this.waypoint_uploaded = wpt; - this.progress = progress; - this.handler = finishHandler; - } - - @Override - public void run() { - boolean result = false; - IConnector con = ConnectorFactory.getConnector(cache); - if (con.supportsOwnCoordinates()) { - result = con.uploadModifiedCoordinates(cache, waypoint_uploaded); - } - final boolean res = result; - runOnUiThread(new Runnable() { - - @Override - public void run() { - if (res) { - showToast(getString(R.string.waypoint_coordinates_has_been_modified_on_website, waypoint_uploaded.getCoords().toString())); - } else { - showToast(getString(R.string.waypoint_coordinates_upload_error)); - } - if (progress != null) { - progress.dismiss(); - } - handler.sendMessage(Message.obtain()); - } - }); - } + private static boolean uploadModifiedCoords(final Geocache cache, final Geopoint waypointUploaded) { + final IConnector con = ConnectorFactory.getConnector(cache); + return con.supportsOwnCoordinates() && con.uploadModifiedCoordinates(cache, waypointUploaded); } @Override - public void goManual(View view) { - if (id >= 0) { - ActivityMixin.goManual(this, "c:geo-waypoint-edit"); - } else { - ActivityMixin.goManual(this, "c:geo-waypoint-new"); - } + public void goManual(final View view) { + ActivityMixin.goManual(this, id >= 0 ? "c:geo-waypoint-edit" : "c:geo-waypoint-new"); } public static void startActivityEditWaypoint(final Context context, final int waypointId) { - final Intent editIntent = new Intent(context, EditWaypointActivity.class); - editIntent.putExtra("waypoint", waypointId); - context.startActivity(editIntent); + context.startActivity(new Intent(context, EditWaypointActivity.class) + .putExtra(Intents.EXTRA_WAYPOINT_ID, waypointId)); } - public static void startActivityAddWaypoint(final Context context, final cgCache cache) { - final Intent addWptIntent = new Intent(context, EditWaypointActivity.class); - addWptIntent.putExtra("geocode", cache.getGeocode()).putExtra("count", cache.getWaypoints().size()); - context.startActivity(addWptIntent); + public static void startActivityAddWaypoint(final Context context, final Geocache cache) { + context.startActivity(new Intent(context, EditWaypointActivity.class) + .putExtra(Intents.EXTRA_GEOCODE, cache.getGeocode()) + .putExtra(Intents.EXTRA_COUNT, cache.getWaypoints().size())); } } diff --git a/main/src/cgeo/geocaching/cgCache.java b/main/src/cgeo/geocaching/Geocache.java index 24bd66b..18a315c 100644 --- a/main/src/cgeo/geocaching/cgCache.java +++ b/main/src/cgeo/geocaching/Geocache.java @@ -47,6 +47,7 @@ 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.Map; import java.util.regex.Pattern; @@ -54,7 +55,7 @@ import java.util.regex.Pattern; /** * Internal c:geo representation of a "cache" */ -public class cgCache implements ICache, IWaypoint { +public class Geocache implements ICache, IWaypoint { private long updated = 0; private long detailedUpdate = 0; @@ -69,48 +70,58 @@ public class cgCache implements ICache, IWaypoint { private String ownerDisplayName = ""; private String ownerUserId = ""; private Date hidden = null; - private String hint = ""; + /** + * lazy initialized + */ + private String hint = null; private CacheSize size = CacheSize.UNKNOWN; private float difficulty = 0; private float terrain = 0; private Float direction = null; private Float distance = null; - private String latlon = ""; - private String location = ""; + /** + * lazy initialized + */ + private String location = null; private Geopoint coords = null; private boolean reliableLatLon = false; private Double elevation = null; private String personalNote = null; - private String shortdesc = ""; + /** + * lazy initialized + */ + private String shortdesc = null; + /** + * 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 own = false; 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 LazyInitializedList<String> attributes = new LazyInitializedList<String>() { + private List<String> attributes = new LazyInitializedList<String>() { @Override - protected List<String> loadFromDatabase() { + public List<String> call() { return cgData.loadAttributes(geocode); } }; - private LazyInitializedList<Waypoint> waypoints = new LazyInitializedList<Waypoint>() { + private List<Waypoint> waypoints = new LazyInitializedList<Waypoint>() { @Override - protected List<Waypoint> loadFromDatabase() { + public List<Waypoint> call() { return cgData.loadWaypoints(geocode); } }; private List<Image> spoilers = null; - private LazyInitializedList<LogEntry> logs = new LazyInitializedList<LogEntry>() { + private List<LogEntry> logs = new LazyInitializedList<LogEntry>() { @Override - protected List<LogEntry> loadFromDatabase() { + public List<LogEntry> call() { return cgData.loadLogs(geocode); } }; @@ -133,7 +144,7 @@ public class cgCache implements ICache, IWaypoint { /** * Create a new cache. To be used everywhere except for the GPX parser */ - public cgCache() { + public Geocache() { // empty } @@ -143,7 +154,7 @@ public class cgCache implements ICache, IWaypoint { * * @param gpxParser */ - public cgCache(GPXParser gpxParser) { + public Geocache(GPXParser gpxParser) { setReliableLatLon(true); setAttributes(Collections.<String> emptyList()); setWaypoints(Collections.<Waypoint> emptyList(), false); @@ -170,7 +181,7 @@ public class cgCache implements ICache, IWaypoint { * the other version, or null if non-existent * @return true if this cache is "equal" to the other version */ - public boolean gatherMissingFrom(final cgCache other) { + public boolean gatherMissingFrom(final Geocache other) { if (other == null) { return false; } @@ -187,7 +198,6 @@ public class cgCache implements ICache, IWaypoint { reliableLatLon = other.reliableLatLon; archived = other.archived; found = other.found; - own = other.own; disabled = other.disabled; favorite = other.favorite; onWatchlist = other.onWatchlist; @@ -235,8 +245,8 @@ public class cgCache implements ICache, IWaypoint { if (hidden == null) { hidden = other.hidden; } - if (StringUtils.isBlank(hint)) { - hint = other.hint; + if (StringUtils.isBlank(getHint())) { + hint = other.getHint(); } if (size == null || CacheSize.UNKNOWN == size) { size = other.size; @@ -253,11 +263,8 @@ public class cgCache implements ICache, IWaypoint { if (distance == null) { distance = other.distance; } - if (StringUtils.isBlank(latlon)) { - latlon = other.latlon; - } - if (StringUtils.isBlank(location)) { - location = other.location; + if (StringUtils.isBlank(getLocation())) { + location = other.getLocation(); } if (coords == null) { coords = other.coords; @@ -268,11 +275,11 @@ public class cgCache implements ICache, IWaypoint { if (personalNote == null) { // don't use StringUtils.isBlank here. Otherwise we cannot recognize a note which was deleted on GC personalNote = other.personalNote; } - if (StringUtils.isBlank(shortdesc)) { - shortdesc = other.shortdesc; + if (StringUtils.isBlank(getShortDescription())) { + shortdesc = other.getShortDescription(); } - if (StringUtils.isBlank(description)) { - description = other.description; + if (StringUtils.isBlank(getDescription())) { + description = other.getDescription(); } // FIXME: this makes no sense to favor this over the other. 0 should not be a special case here as it is // in the range of acceptable values. This is probably the case at other places (rating, votes, etc.) too. @@ -289,14 +296,17 @@ public class cgCache implements ICache, IWaypoint { myVote = other.myVote; } if (attributes.isEmpty()) { - attributes.set(other.attributes); + attributes.clear(); + if (other.attributes != null) { + attributes.addAll(other.attributes); + } } if (waypoints.isEmpty()) { - this.setWaypoints(other.waypoints.asList(), false); + this.setWaypoints(other.waypoints, false); } else { - ArrayList<Waypoint> newPoints = new ArrayList<Waypoint>(waypoints.asList()); - Waypoint.mergeWayPoints(newPoints, other.waypoints.asList(), false); + ArrayList<Waypoint> newPoints = new ArrayList<Waypoint>(waypoints); + Waypoint.mergeWayPoints(newPoints, other.waypoints, false); this.setWaypoints(newPoints, false); } if (spoilers == null) { @@ -311,7 +321,10 @@ public class cgCache implements ICache, IWaypoint { inventoryItems = other.inventoryItems; } if (logs.isEmpty()) { // keep last known logs if none - logs.set(other.logs); + logs.clear(); + if (other.logs != null) { + logs.addAll(other.logs); + } } if (logCounts.isEmpty()) { logCounts = other.logCounts; @@ -345,14 +358,13 @@ public class cgCache implements ICache, IWaypoint { * the other cache to compare this one to * @return true if both caches have the same content */ - private boolean isEqualTo(final cgCache other) { + private boolean isEqualTo(final Geocache other) { return detailed == other.detailed && StringUtils.equalsIgnoreCase(geocode, other.geocode) && StringUtils.equalsIgnoreCase(name, other.name) && cacheType == other.cacheType && size == other.size && found == other.found && - own == other.own && premiumMembersOnly == other.premiumMembersOnly && difficulty == other.difficulty && terrain == other.terrain && @@ -363,17 +375,16 @@ public class cgCache implements ICache, IWaypoint { listId == other.listId && StringUtils.equalsIgnoreCase(ownerDisplayName, other.ownerDisplayName) && StringUtils.equalsIgnoreCase(ownerUserId, other.ownerUserId) && - StringUtils.equalsIgnoreCase(description, other.description) && + StringUtils.equalsIgnoreCase(getDescription(), other.getDescription()) && StringUtils.equalsIgnoreCase(personalNote, other.personalNote) && - StringUtils.equalsIgnoreCase(shortdesc, other.shortdesc) && - StringUtils.equalsIgnoreCase(latlon, other.latlon) && - StringUtils.equalsIgnoreCase(location, other.location) && + StringUtils.equalsIgnoreCase(getShortDescription(), other.getShortDescription()) && + StringUtils.equalsIgnoreCase(getLocation(), other.getLocation()) && favorite == other.favorite && favoritePoints == other.favoritePoints && onWatchlist == other.onWatchlist && (hidden != null ? hidden.equals(other.hidden) : null == other.hidden) && StringUtils.equalsIgnoreCase(guid, other.guid) && - StringUtils.equalsIgnoreCase(hint, other.hint) && + StringUtils.equalsIgnoreCase(getHint(), other.getHint()) && StringUtils.equalsIgnoreCase(cacheId, other.cacheId) && (direction != null ? direction.equals(other.direction) : null == other.direction) && (distance != null ? distance.equals(other.distance) : null == other.distance) && @@ -427,7 +438,7 @@ public class cgCache implements ICache, IWaypoint { return false; } final Boolean found = Pattern.compile(guid, Pattern.CASE_INSENSITIVE).matcher(page).find(); - Log.i("cgCache.isGuidContainedInPage: guid '" + guid + "' " + (found ? "" : "not ") + "found"); + Log.i("Geocache.isGuidContainedInPage: guid '" + guid + "' " + (found ? "" : "not ") + "found"); return found; } @@ -472,14 +483,13 @@ public class cgCache implements ICache, IWaypoint { } public List<LogType> getPossibleLogTypes() { - boolean isOwner = getOwnerUserId() != null && getOwnerUserId().equalsIgnoreCase(Settings.getUsername()); - List<LogType> logTypes = new ArrayList<LogType>(); + final List<LogType> logTypes = new LinkedList<LogType>(); if (isEventCache()) { logTypes.add(LogType.WILL_ATTEND); logTypes.add(LogType.NOTE); logTypes.add(LogType.ATTENDED); logTypes.add(LogType.NEEDS_ARCHIVE); - if (isOwner) { + if (isOwner()) { logTypes.add(LogType.ANNOUNCEMENT); } } else if (CacheType.WEBCAM == cacheType) { @@ -495,7 +505,7 @@ public class cgCache implements ICache, IWaypoint { logTypes.add(LogType.NEEDS_ARCHIVE); logTypes.add(LogType.NEEDS_MAINTENANCE); } - if (isOwner) { + if (isOwner()) { logTypes.add(LogType.OWNER_MAINTENANCE); logTypes.add(LogType.TEMP_DISABLE_LISTING); logTypes.add(LogType.ENABLE_LISTING); @@ -593,8 +603,8 @@ public class cgCache implements ICache, IWaypoint { } @Override - public boolean isOwn() { - return own; + public boolean isOwner() { + return getConnector().isOwner(this); } @Override @@ -602,21 +612,39 @@ public class cgCache implements ICache, IWaypoint { return ownerUserId; } + /** + * Attention, calling this method may trigger a database access for the cache! + */ @Override public String getHint() { + initializeCacheTexts(); return hint; } + /** + * Attention, calling this method may trigger a database access for the cache! + */ @Override public String getDescription() { - if (description == null) { - description = StringUtils.defaultString(cgData.getCacheDescription(geocode)); - } + initializeCacheTexts(); return description; } + /** + * loads long text parts of a cache on demand (but all fields together) + */ + private void initializeCacheTexts() { + if (description == null || shortdesc == null || hint == null || location == null) { + cgData.loadCacheTexts(this); + } + } + + /** + * Attention, calling this method may trigger a database access for the cache! + */ @Override public String getShortDescription() { + initializeCacheTexts(); return shortdesc; } @@ -639,8 +667,12 @@ public class cgCache implements ICache, IWaypoint { return guid; } + /** + * Attention, calling this method may trigger a database access for the cache! + */ @Override public String getLocation() { + initializeCacheTexts(); return location; } @@ -718,7 +750,7 @@ public class cgCache implements ICache, IWaypoint { } @Override - public LazyInitializedList<String> getAttributes() { + public List<String> getAttributes() { return attributes; } @@ -840,14 +872,6 @@ public class cgCache implements ICache, IWaypoint { this.distance = distance; } - public String getLatlon() { - return latlon; - } - - public void setLatlon(String latlon) { - this.latlon = latlon; - } - @Override public Geopoint getCoords() { return coords; @@ -876,11 +900,7 @@ public class cgCache implements ICache, IWaypoint { this.elevation = elevation; } - public String getShortdesc() { - return shortdesc; - } - - public void setShortdesc(String shortdesc) { + public void setShortDescription(String shortdesc) { this.shortdesc = shortdesc; } @@ -934,7 +954,7 @@ public class cgCache implements ICache, IWaypoint { * @return always non <code>null</code> */ public List<Waypoint> getWaypoints() { - return waypoints.asList(); + return waypoints; } /** @@ -946,7 +966,10 @@ public class cgCache implements ICache, IWaypoint { * @return <code>true</code> if waypoints successfully added to waypoint database */ public boolean setWaypoints(List<Waypoint> waypoints, boolean saveToDatabase) { - this.waypoints.set(waypoints); + this.waypoints.clear(); + if (waypoints != null) { + this.waypoints.addAll(waypoints); + } finalDefined = false; if (waypoints != null) { for (Waypoint waypoint : waypoints) { @@ -962,7 +985,7 @@ public class cgCache implements ICache, IWaypoint { /** * @return never <code>null</code> */ - public LazyInitializedList<LogEntry> getLogs() { + public List<LogEntry> getLogs() { return logs; } @@ -984,7 +1007,10 @@ public class cgCache implements ICache, IWaypoint { * the log entries */ public void setLogs(List<LogEntry> logs) { - this.logs.set(logs); + this.logs.clear(); + if (logs != null) { + this.logs.addAll(logs); + } } public boolean isLogOffline() { @@ -1076,12 +1102,11 @@ public class cgCache implements ICache, IWaypoint { this.found = found; } - public void setOwn(boolean own) { - this.own = own; - } - public void setAttributes(List<String> attributes) { - this.attributes.set(attributes); + this.attributes.clear(); + if (attributes != null) { + this.attributes.addAll(attributes); + } } public void setSpoilers(List<Image> spoilers) { @@ -1149,7 +1174,7 @@ public class cgCache implements ICache, IWaypoint { public boolean addOrChangeWaypoint(final Waypoint waypoint, boolean saveToDatabase) { waypoint.setGeocode(geocode); - if (waypoint.getId() <= 0) { // this is a new waypoint + if (waypoint.getId() < 0) { // this is a new waypoint waypoints.add(waypoint); if (waypoint.isFinalWithCoords()) { finalDefined = true; @@ -1230,7 +1255,7 @@ public class cgCache implements ICache, IWaypoint { if (waypoint == null) { return false; } - if (waypoint.getId() <= 0) { + if (waypoint.getId() < 0) { return false; } if (waypoint.isUserDefined()) { @@ -1333,7 +1358,7 @@ public class cgCache implements ICache, IWaypoint { matcher = new MatcherWrapper(coordPattern, note); } } catch (Exception e) { - Log.e("cgCache.parseWaypointsFromNote", e); + Log.e("Geocache.parseWaypointsFromNote", e); } } @@ -1358,16 +1383,22 @@ public class cgCache implements ICache, IWaypoint { if (this == obj) { return true; } - if (!(obj instanceof cgCache)) { + if (!(obj instanceof Geocache)) { return false; } // just compare the geocode even if that is not what "equals" normally does - return StringUtils.isNotBlank(geocode) && geocode.equals(((cgCache) obj).geocode); + return StringUtils.isNotBlank(geocode) && geocode.equals(((Geocache) obj).geocode); } public void store(CancellableHandler handler) { - final int listId = Math.max(getListId(), StoredList.STANDARD_LIST_ID); - storeCache(this, null, listId, false, handler); + store(StoredList.TEMPORARY_LIST_ID, handler); + } + + public void store(final int listId, CancellableHandler handler) { + int newListId = listId < StoredList.STANDARD_LIST_ID + ? Math.max(getListId(), StoredList.STANDARD_LIST_ID) + : listId; + storeCache(this, null, newListId, false, handler); } public void setZoomlevel(int zoomlevel) { @@ -1447,9 +1478,9 @@ public class cgCache implements ICache, IWaypoint { storeCache(null, geocode, newListId, true, handler); } - public static void storeCache(cgCache origCache, String geocode, int listId, boolean forceRedownload, CancellableHandler handler) { + public static void storeCache(Geocache origCache, String geocode, int listId, boolean forceRedownload, CancellableHandler handler) { try { - cgCache cache; + Geocache cache; // get cache details, they may not yet be complete if (origCache != null) { // only reload the cache if it was already stored or doesn't have full details (by checking the description) @@ -1534,7 +1565,7 @@ public class cgCache implements ICache, IWaypoint { public static SearchResult searchByGeocode(final String geocode, final String guid, final int listId, final boolean forceReload, final CancellableHandler handler) { if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) { - Log.e("cgCache.searchByGeocode: No geocode nor guid given"); + Log.e("Geocache.searchByGeocode: No geocode nor guid given"); return null; } @@ -1612,7 +1643,7 @@ public class cgCache implements ICache, IWaypoint { * @return */ public boolean hasAttribute(CacheAttribute attribute, boolean yes) { - cgCache fullCache = cgData.loadCache(getGeocode(), EnumSet.of(LoadFlag.LOAD_ATTRIBUTES)); + Geocache fullCache = cgData.loadCache(getGeocode(), EnumSet.of(LoadFlag.LOAD_ATTRIBUTES)); if (fullCache == null) { fullCache = this; } diff --git a/main/src/cgeo/geocaching/ICache.java b/main/src/cgeo/geocaching/ICache.java index 030c53f..6d0d89a 100644 --- a/main/src/cgeo/geocaching/ICache.java +++ b/main/src/cgeo/geocaching/ICache.java @@ -4,7 +4,6 @@ package cgeo.geocaching; import cgeo.geocaching.enumerations.LogType; -import cgeo.geocaching.utils.LazyInitializedList; import java.util.Date; import java.util.List; @@ -28,7 +27,7 @@ public interface ICache extends IBasicCache { /** * @return true if the user is the owner of the cache, false else */ - public boolean isOwn(); + public boolean isOwner(); /** * @return true is the cache is archived, false else @@ -107,7 +106,7 @@ public interface ICache extends IBasicCache { * * @return the list of attributes for this cache */ - public LazyInitializedList<String> getAttributes(); + public List<String> getAttributes(); /** * @return the list of trackables in this cache diff --git a/main/src/cgeo/geocaching/IWaypoint.java b/main/src/cgeo/geocaching/IWaypoint.java index 78e3b43..2b992e1 100644 --- a/main/src/cgeo/geocaching/IWaypoint.java +++ b/main/src/cgeo/geocaching/IWaypoint.java @@ -1,12 +1,14 @@ -/** - * - */ package cgeo.geocaching; import cgeo.geocaching.enumerations.WaypointType; public interface IWaypoint extends ILogable, ICoordinates { + /** + * Return an unique waypoint id. + * + * @return a non-negative id if set, -1 if unset + */ public abstract int getId(); public abstract WaypointType getWaypointType(); diff --git a/main/src/cgeo/geocaching/Intents.java b/main/src/cgeo/geocaching/Intents.java new file mode 100644 index 0000000..07e1c13 --- /dev/null +++ b/main/src/cgeo/geocaching/Intents.java @@ -0,0 +1,28 @@ +package cgeo.geocaching; + +public class Intents { + + private Intents() { + // Do not instantiate + } + + private static final String PREFIX = "cgeo.geocaching.intent.extra."; + + public static final String EXTRA_ADDRESS = PREFIX + "address"; + public static final String EXTRAS_COORDS = PREFIX + "coords"; + public static final String EXTRA_COUNT = PREFIX + "count"; + public static final String EXTRA_GEOCODE = PREFIX + "geocode"; + public static final String EXTRA_GUID = PREFIX + "guid"; + public static final String EXTRA_ID = PREFIX + "id"; + public static final String EXTRA_KEYWORD = PREFIX + "keyword"; + public static final String EXTRA_KEYWORD_SEARCH = PREFIX + "keyword_search"; + public static final String EXTRA_LIST_ID = PREFIX + "list_id"; + public static final String EXTRA_LIST_TYPE = PREFIX + "list_type"; + public static final String EXTRA_MAP_FILE = PREFIX + "map_file"; + public static final String EXTRA_NAME = PREFIX + "name"; + public static final String EXTRA_SEARCH = PREFIX + "search"; + public static final String EXTRA_START_DIR = PREFIX + "start_dir"; + public static final String EXTRA_TRACKING_CODE = PREFIX + "tracking_code"; + public static final String EXTRA_USERNAME = PREFIX + "username"; + public static final String EXTRA_WAYPOINT_ID = PREFIX + "waypoint_id"; +} diff --git a/main/src/cgeo/geocaching/LiveMapInfo.java b/main/src/cgeo/geocaching/LiveMapInfo.java deleted file mode 100644 index 2fee940..0000000 --- a/main/src/cgeo/geocaching/LiveMapInfo.java +++ /dev/null @@ -1,52 +0,0 @@ -package cgeo.geocaching; - -import cgeo.geocaching.activity.AbstractActivity; - -import android.os.Bundle; -import android.view.View; -import android.widget.Button; -import android.widget.CheckBox; - -public class LiveMapInfo extends AbstractActivity { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.livemapinfo); - - final int showCount = Settings.getLiveMapHintShowCount(); - - if (showCount > 2) { - final CheckBox cb = (CheckBox) findViewById(R.id.live_map_hint_hide); - cb.setVisibility(View.VISIBLE); - } - - final Button closeButton = (Button) findViewById(R.id.live_map_hint_ok); - closeButton.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View v) { - final CheckBox cb = (CheckBox) findViewById(R.id.live_map_hint_hide); - if (cb.isChecked()) { - Settings.setHideLiveHint(true); - } - finish(); - } - }); - - Settings.setLiveMapHintShowCount(showCount + 1); - } - - @Override - protected void onStop() { - - final CheckBox cb = (CheckBox) findViewById(R.id.live_map_hint_hide); - if (cb.isChecked()) { - Settings.setHideLiveHint(true); - } - - super.onStop(); - } - -} diff --git a/main/src/cgeo/geocaching/LogTrackableActivity.java b/main/src/cgeo/geocaching/LogTrackableActivity.java index 0217c08..b8983ba 100644 --- a/main/src/cgeo/geocaching/LogTrackableActivity.java +++ b/main/src/cgeo/geocaching/LogTrackableActivity.java @@ -7,8 +7,8 @@ import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.twitter.Twitter; -import cgeo.geocaching.ui.DateDialog; import cgeo.geocaching.ui.Formatter; +import cgeo.geocaching.ui.dialog.DateDialog; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.LogTemplateProvider.LogContext; @@ -119,11 +119,11 @@ public class LogTrackableActivity extends AbstractLoggingActivity implements Dat // get parameters final Bundle extras = getIntent().getExtras(); if (extras != null) { - geocode = extras.getString("geocode"); - guid = extras.getString("guid"); + geocode = extras.getString(Intents.EXTRA_GEOCODE); + guid = extras.getString(Intents.EXTRA_GUID); - if (StringUtils.isNotBlank(extras.getString("trackingcode"))) { - ((EditText) findViewById(R.id.tracking)).setText(extras.getString("trackingcode")); + if (StringUtils.isNotBlank(extras.getString(Intents.EXTRA_TRACKING_CODE))) { + ((EditText) findViewById(R.id.tracking)).setText(extras.getString(Intents.EXTRA_TRACKING_CODE)); } } @@ -357,9 +357,9 @@ public class LogTrackableActivity extends AbstractLoggingActivity implements Dat public static void startActivity(final Context context, final Trackable trackable) { final Intent logTouchIntent = new Intent(context, LogTrackableActivity.class); - logTouchIntent.putExtra("geocode", trackable.getGeocode()); - logTouchIntent.putExtra("guid", trackable.getGuid()); - logTouchIntent.putExtra("trackingcode", trackable.getTrackingcode()); + logTouchIntent.putExtra(Intents.EXTRA_GEOCODE, trackable.getGeocode()); + logTouchIntent.putExtra(Intents.EXTRA_GUID, trackable.getGuid()); + logTouchIntent.putExtra(Intents.EXTRA_TRACKING_CODE, trackable.getTrackingcode()); context.startActivity(logTouchIntent); } diff --git a/main/src/cgeo/geocaching/SearchActivity.java b/main/src/cgeo/geocaching/SearchActivity.java index 4c9a230..ddb9483 100644 --- a/main/src/cgeo/geocaching/SearchActivity.java +++ b/main/src/cgeo/geocaching/SearchActivity.java @@ -7,6 +7,7 @@ import cgeo.geocaching.connector.capability.ISearchByGeocode; import cgeo.geocaching.connector.gc.GCConstants; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; +import cgeo.geocaching.ui.dialog.CoordinatesInputDialog; import cgeo.geocaching.utils.BaseUtils; import cgeo.geocaching.utils.EditUtils; import cgeo.geocaching.utils.GeoDirHandler; @@ -32,8 +33,6 @@ import java.util.Locale; public class SearchActivity extends AbstractActivity { - private static final String EXTRAS_KEYWORDSEARCH = "keywordsearch"; - private static final int MENU_SEARCH_OWN_CACHES = 1; private EditText latEdit = null; private EditText lonEdit = null; @@ -50,7 +49,7 @@ public class SearchActivity extends AbstractActivity { Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) { final String query = intent.getStringExtra(SearchManager.QUERY); - final boolean keywordSearch = intent.getBooleanExtra(EXTRAS_KEYWORDSEARCH, true); + final boolean keywordSearch = intent.getBooleanExtra(Intents.EXTRA_KEYWORD_SEARCH, true); if (instantSearch(query, keywordSearch)) { setResult(RESULT_OK); @@ -111,7 +110,7 @@ public class SearchActivity extends AbstractActivity { final IConnector connector = ConnectorFactory.getConnector(geocode); if (connector instanceof ISearchByGeocode) { final Intent cachesIntent = new Intent(this, CacheDetailActivity.class); - cachesIntent.putExtra("geocode", geocode.toUpperCase(Locale.US)); + cachesIntent.putExtra(Intents.EXTRA_GEOCODE, geocode.toUpperCase(Locale.US)); startActivity(cachesIntent); return true; } @@ -120,7 +119,7 @@ public class SearchActivity extends AbstractActivity { final String trackable = BaseUtils.getMatch(query, GCConstants.PATTERN_TB_CODE, true, 0, "", false); if (StringUtils.isNotBlank(trackable)) { final Intent trackablesIntent = new Intent(this, TrackableActivity.class); - trackablesIntent.putExtra("geocode", trackable.toUpperCase(Locale.US)); + trackablesIntent.putExtra(Intents.EXTRA_GEOCODE, trackable.toUpperCase(Locale.US)); startActivity(trackablesIntent); return true; } @@ -257,9 +256,9 @@ public class SearchActivity extends AbstractActivity { @Override public void onClick(View arg0) { - cgeocoords coordsDialog = new cgeocoords(SearchActivity.this, null, null, app.currentGeo()); + CoordinatesInputDialog coordsDialog = new CoordinatesInputDialog(SearchActivity.this, null, null, app.currentGeo()); coordsDialog.setCancelable(true); - coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() { + coordsDialog.setOnCoordinateUpdate(new CoordinatesInputDialog.CoordinateUpdate() { @Override public void update(Geopoint gp) { ((Button) findViewById(R.id.buttonLatitude)).setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); @@ -334,8 +333,8 @@ public class SearchActivity extends AbstractActivity { return; } - final Intent addressesIntent = new Intent(this, AdressListActivity.class); - addressesIntent.putExtra("keyword", addText); + final Intent addressesIntent = new Intent(this, AddressListActivity.class); + addressesIntent.putExtra(Intents.EXTRA_KEYWORD, addText); startActivity(addressesIntent); } @@ -409,7 +408,7 @@ public class SearchActivity extends AbstractActivity { } final Intent trackablesIntent = new Intent(this, TrackableActivity.class); - trackablesIntent.putExtra("geocode", trackableText.toUpperCase(Locale.US)); + trackablesIntent.putExtra(Intents.EXTRA_GEOCODE, trackableText.toUpperCase(Locale.US)); startActivity(trackablesIntent); } @@ -432,7 +431,7 @@ public class SearchActivity extends AbstractActivity { final Intent searchIntent = new Intent(fromActivity, SearchActivity.class); searchIntent.setAction(Intent.ACTION_SEARCH). putExtra(SearchManager.QUERY, scan). - putExtra(SearchActivity.EXTRAS_KEYWORDSEARCH, false); + putExtra(Intents.EXTRA_KEYWORD_SEARCH, false); fromActivity.startActivityForResult(searchIntent, cgeo.SEARCH_REQUEST_CODE); } } diff --git a/main/src/cgeo/geocaching/SearchResult.java b/main/src/cgeo/geocaching/SearchResult.java index d1b1df6..b0540f2 100644 --- a/main/src/cgeo/geocaching/SearchResult.java +++ b/main/src/cgeo/geocaching/SearchResult.java @@ -8,6 +8,7 @@ import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.gcvote.GCVote; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import android.os.Parcel; @@ -101,7 +102,7 @@ public class SearchResult implements Parcelable { * @param cache the cache to include */ - public SearchResult(final cgCache cache) { + public SearchResult(final Geocache cache) { this(Collections.singletonList(cache)); } @@ -110,9 +111,9 @@ public class SearchResult implements Parcelable { * * @param caches the non-null collection of caches to include */ - public SearchResult(final Collection<cgCache> caches) { + public SearchResult(final Collection<Geocache> caches) { this(); - for (final cgCache cache : caches) { + for (final Geocache cache : caches) { addCache(cache); } } @@ -190,13 +191,13 @@ public class SearchResult implements Parcelable { SearchResult result = new SearchResult(this); result.geocodes.clear(); - final ArrayList<cgCache> cachesForVote = new ArrayList<cgCache>(); - final Set<cgCache> caches = cgData.loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB); - for (cgCache cache : caches) { + final ArrayList<Geocache> cachesForVote = new ArrayList<Geocache>(); + final Set<Geocache> caches = cgData.loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB); + for (Geocache cache : caches) { // Is there any reason to exclude the cache from the list? final boolean excludeCache = (excludeDisabled && cache.isDisabled()) || - (excludeMine && (cache.isOwn() || cache.isFound())) || - (cacheType != CacheType.ALL && cacheType != cache.getType()); + (excludeMine && (cache.isOwner() || cache.isFound())) || + (!cacheType.contains(cache)); if (!excludeCache) { result.addCache(cache); cachesForVote.add(cache); @@ -206,14 +207,11 @@ public class SearchResult implements Parcelable { return result; } - public cgCache getFirstCacheFromResult(final EnumSet<LoadFlag> loadFlags) { - if (geocodes != null && geocodes.size() >= 1) { - return cgData.loadCache((String) geocodes.toArray()[0], loadFlags); - } - return null; + public Geocache getFirstCacheFromResult(final EnumSet<LoadFlag> loadFlags) { + return CollectionUtils.isNotEmpty(geocodes) ? cgData.loadCache(geocodes.iterator().next(), loadFlags) : null; } - public Set<cgCache> getCachesFromSearchResult(final EnumSet<LoadFlag> loadFlags) { + public Set<Geocache> getCachesFromSearchResult(final EnumSet<LoadFlag> loadFlags) { return cgData.loadCaches(geocodes, loadFlags); } @@ -231,7 +229,7 @@ public class SearchResult implements Parcelable { } /** Add the cache geocode to the search and store the cache in the CacheCache */ - public boolean addCache(final cgCache cache) { + public boolean addCache(final Geocache cache) { addGeocode(cache.getGeocode()); return cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE)); } diff --git a/main/src/cgeo/geocaching/Settings.java b/main/src/cgeo/geocaching/Settings.java index 96aab88..0c157e1 100644 --- a/main/src/cgeo/geocaching/Settings.java +++ b/main/src/cgeo/geocaching/Settings.java @@ -86,6 +86,7 @@ public final class Settings { private static final String KEY_MEMBER_STATUS = "memberstatus"; private static final String KEY_COORD_INPUT_FORMAT = "coordinputformat"; private static final String KEY_LOG_OFFLINE = "log_offline"; + private static final String KEY_CHOOSE_LIST = "choose_list"; private static final String KEY_LOAD_DIRECTION_IMG = "loaddirectionimg"; private static final String KEY_GC_CUSTOM_DATE = "gccustomdate"; private static final String KEY_SHOW_WAYPOINTS_THRESHOLD = "gcshowwaypointsthreshold"; @@ -128,7 +129,7 @@ public final class Settings { Min, Sec; - static coordInputFormatEnum fromInt(int id) { + public static coordInputFormatEnum fromInt(int id) { final coordInputFormatEnum[] values = coordInputFormatEnum.values(); if (id < 0 || id >= values.length) { return Min; @@ -204,6 +205,7 @@ public final class Settings { e.putString(KEY_MEMBER_STATUS, old.getString(KEY_MEMBER_STATUS, "")); e.putInt(KEY_COORD_INPUT_FORMAT, old.getInt(KEY_COORD_INPUT_FORMAT, 0)); e.putBoolean(KEY_LOG_OFFLINE, old.getBoolean(KEY_LOG_OFFLINE, false)); + e.putBoolean(KEY_CHOOSE_LIST, old.getBoolean(KEY_CHOOSE_LIST, false)); e.putBoolean(KEY_LOAD_DIRECTION_IMG, old.getBoolean(KEY_LOAD_DIRECTION_IMG, true)); e.putString(KEY_GC_CUSTOM_DATE, old.getString(KEY_GC_CUSTOM_DATE, null)); e.putInt(KEY_SHOW_WAYPOINTS_THRESHOLD, old.getInt(KEY_SHOW_WAYPOINTS_THRESHOLD, 0)); @@ -552,6 +554,20 @@ public final class Settings { return sharedPrefs.getBoolean(KEY_LOG_OFFLINE, false); } + static void setChooseList(final boolean choose) { + editSharedSettings(new PrefRunnable() { + + @Override + public void edit(Editor edit) { + edit.putBoolean(KEY_CHOOSE_LIST, choose); + } + }); + } + + public static boolean getChooseList() { + return sharedPrefs.getBoolean(KEY_CHOOSE_LIST, false); + } + static void setLoadDirImg(final boolean value) { editSharedSettings(new PrefRunnable() { @@ -1381,12 +1397,6 @@ public final class Settings { } } - public static String getPreferencesName() { - // There is currently no Android API to get the file name of the shared preferences. Let's hardcode - // it without needing a cgeoapplication instance. - return "cgeo.geocaching_preferences"; - } - public static boolean getPlainLogs() { return sharedPrefs.getBoolean(KEY_PLAIN_LOGS, false); } diff --git a/main/src/cgeo/geocaching/SettingsActivity.java b/main/src/cgeo/geocaching/SettingsActivity.java index 64a086d..3463204 100644 --- a/main/src/cgeo/geocaching/SettingsActivity.java +++ b/main/src/cgeo/geocaching/SettingsActivity.java @@ -521,6 +521,17 @@ public class SettingsActivity extends AbstractActivity { } }); + final CheckBox chooseList = (CheckBox) findViewById(R.id.choose_list); + chooseList.setChecked(Settings.getChooseList()); + chooseList.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + Settings.setChooseList(!Settings.getChooseList()); + chooseList.setChecked(Settings.getChooseList()); + } + }); + final CheckBox plainLogs = (CheckBox) findViewById(R.id.plain_logs); plainLogs.setChecked(Settings.getPlainLogs()); plainLogs.setOnClickListener(new View.OnClickListener() { @@ -973,8 +984,8 @@ public class SettingsActivity extends AbstractActivity { switch (requestCode) { case SELECT_MAPFILE_REQUEST: - if (data.hasExtra("mapfile")) { - final String mapFile = data.getStringExtra("mapfile"); + if (data.hasExtra(Intents.EXTRA_MAP_FILE)) { + final String mapFile = data.getStringExtra(Intents.EXTRA_MAP_FILE); Settings.setMapFile(mapFile); if (!Settings.isValidMapFile(Settings.getMapFile())) { showToast(res.getString(R.string.warn_invalid_mapfile)); @@ -1019,10 +1030,7 @@ public class SettingsActivity extends AbstractActivity { if (resultCode != RESULT_OK) { return; } - // we may come back from either our selfmade chooser or from the Open Intent manager - final String directory = data.hasExtra(SimpleDirChooser.EXTRA_CHOSEN_DIR) ? - data.getStringExtra(SimpleDirChooser.EXTRA_CHOSEN_DIR) : - new File(data.getData().getPath()).getAbsolutePath(); + final String directory = new File(data.getData().getPath()).getAbsolutePath(); if (StringUtils.isNotBlank(directory)) { runnableSetDir.run(directory); EditText directoryText = (EditText) findViewById(textField); @@ -1032,19 +1040,18 @@ public class SettingsActivity extends AbstractActivity { } private void selectDirectory(String startDirectory, int directoryKind) { - Intent dirChooser; try { - dirChooser = new Intent(FileManagerIntents.ACTION_PICK_DIRECTORY); + final Intent dirChooser = new Intent(FileManagerIntents.ACTION_PICK_DIRECTORY); if (StringUtils.isNotBlank(startDirectory)) { - dirChooser.setData(Uri.parse("file://" + new File(startDirectory).getAbsolutePath())); + dirChooser.setData(Uri.fromFile(new File(startDirectory))); } dirChooser.putExtra(FileManagerIntents.EXTRA_TITLE, res.getString(R.string.simple_dir_chooser_title)); dirChooser.putExtra(FileManagerIntents.EXTRA_BUTTON_TEXT, res.getString(android.R.string.ok)); startActivityForResult(dirChooser, directoryKind); } catch (android.content.ActivityNotFoundException ex) { // OI file manager not available - dirChooser = new Intent(this, SimpleDirChooser.class); - dirChooser.putExtra(SimpleDirChooser.START_DIR, startDirectory); + final Intent dirChooser = new Intent(this, SimpleDirChooser.class); + dirChooser.putExtra(Intents.EXTRA_START_DIR, startDirectory); startActivityForResult(dirChooser, directoryKind); } } diff --git a/main/src/cgeo/geocaching/StaticMapsActivity.java b/main/src/cgeo/geocaching/StaticMapsActivity.java index 263b6b8..d7cef65 100644 --- a/main/src/cgeo/geocaching/StaticMapsActivity.java +++ b/main/src/cgeo/geocaching/StaticMapsActivity.java @@ -177,7 +177,7 @@ public class StaticMapsActivity extends AbstractActivity { } private boolean downloadStaticMaps() { - final cgCache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); if (waypoint_id == null) { showToast(res.getString(R.string.info_storing_static_maps)); StaticMapsProvider.storeCacheStaticMap(cache, true); diff --git a/main/src/cgeo/geocaching/StaticMapsProvider.java b/main/src/cgeo/geocaching/StaticMapsProvider.java index b418400..6feacc2 100644 --- a/main/src/cgeo/geocaching/StaticMapsProvider.java +++ b/main/src/cgeo/geocaching/StaticMapsProvider.java @@ -80,7 +80,7 @@ public class StaticMapsProvider { } } - public static void downloadMaps(cgCache cache) { + public static void downloadMaps(Geocache cache) { if (cache == null) { Log.e("downloadMaps - missing input parameter cache"); return; @@ -105,7 +105,7 @@ public class StaticMapsProvider { } } - public static void storeWaypointStaticMap(cgCache cache, Waypoint waypoint, boolean waitForResult) { + public static void storeWaypointStaticMap(Geocache cache, Waypoint waypoint, boolean waitForResult) { int edge = StaticMapsProvider.guessMaxDisplaySide(); storeWaypointStaticMap(cache.getGeocode(), edge, waypoint, waitForResult); } @@ -128,12 +128,12 @@ public class StaticMapsProvider { downloadMaps(geocode, wpMarkerUrl, WAYPOINT_PREFIX + waypoint.getId() + '_', wpLatlonMap, edge, null, waitForResult); } - public static void storeCacheStaticMap(cgCache cache, final boolean waitForResult) { + public static void storeCacheStaticMap(Geocache cache, final boolean waitForResult) { int edge = guessMaxDisplaySide(); storeCacheStaticMap(cache, edge, waitForResult); } - private static void storeCacheStaticMap(final cgCache cache, final int edge, final boolean waitForResult) { + private static void storeCacheStaticMap(final Geocache cache, final int edge, final boolean waitForResult) { final String latlonMap = cache.getCoords().format(Format.LAT_LON_DECDEGREE_COMMA); final Parameters waypoints = new Parameters(); for (final Waypoint waypoint : cache.getWaypoints()) { @@ -148,7 +148,7 @@ public class StaticMapsProvider { downloadMaps(cache.getGeocode(), cacheMarkerUrl, "", latlonMap, edge, waypoints, waitForResult); } - public static void storeCachePreviewMap(final cgCache cache) { + public static void storeCachePreviewMap(final Geocache cache) { if (cache == null) { Log.e("storeCachePreviewMap - missing input parameter cache"); return; @@ -193,7 +193,7 @@ public class StaticMapsProvider { } } - private static String getCacheMarkerUrl(final cgCache cache) { + private static String getCacheMarkerUrl(final Geocache cache) { StringBuilder url = new StringBuilder(MARKERS_URL); url.append("marker_cache_").append(cache.getType().id); if (cache.isFound()) { @@ -229,7 +229,7 @@ public class StaticMapsProvider { * @param cache * @return <code>true</code> if at least one mapfile exists; <code>false</code> otherwise */ - public static boolean hasStaticMap(final cgCache cache) { + public static boolean hasStaticMap(final Geocache cache) { if (cache == null) { return false; } diff --git a/main/src/cgeo/geocaching/StoredList.java b/main/src/cgeo/geocaching/StoredList.java index d6f0993..5a6f132 100644 --- a/main/src/cgeo/geocaching/StoredList.java +++ b/main/src/cgeo/geocaching/StoredList.java @@ -1,6 +1,6 @@ package cgeo.geocaching; -import cgeo.geocaching.activity.IAbstractActivity; +import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.utils.RunnableWithArgument; import org.apache.commons.lang3.StringUtils; @@ -50,19 +50,15 @@ public class StoredList { if (!(obj instanceof StoredList)) { return false; } - StoredList other = (StoredList) obj; - if (id != other.id) { - return false; - } - return true; + return id == ((StoredList) obj).id; } public static class UserInterface { - private final IAbstractActivity activity; + private final Activity activity; private final cgeoapplication app; private final Resources res; - public UserInterface(final IAbstractActivity activity) { + public UserInterface(final Activity activity) { this.activity = activity; app = cgeoapplication.getInstance(); res = app.getResources(); @@ -97,7 +93,7 @@ public class StoredList { final CharSequence[] items = new CharSequence[listsTitle.size()]; - AlertDialog.Builder builder = new AlertDialog.Builder((Activity) activity); + AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(res.getString(titleId)); builder.setItems(listsTitle.toArray(items), new DialogInterface.OnClickListener() { @Override @@ -127,20 +123,20 @@ public class StoredList { final int newId = cgData.createList(listName); if (newId >= cgData.customListIdOffset) { - activity.showToast(res.getString(R.string.list_dialog_create_ok)); + ActivityMixin.showToast(activity, res.getString(R.string.list_dialog_create_ok)); if (runAfterwards != null) { runAfterwards.run(newId); } } else { - activity.showToast(res.getString(R.string.list_dialog_create_err)); + ActivityMixin.showToast(activity, res.getString(R.string.list_dialog_create_err)); } } }); } private void handleListNameInput(final String defaultValue, int dialogTitle, int buttonTitle, final RunnableWithArgument<String> runnable) { - final AlertDialog.Builder alert = new AlertDialog.Builder((Activity) activity); - final View view = ((Activity) activity).getLayoutInflater().inflate(R.layout.list_create_dialog, null); + final AlertDialog.Builder alert = new AlertDialog.Builder(activity); + final View view = activity.getLayoutInflater().inflate(R.layout.list_create_dialog, null); final EditText input = (EditText) view.findViewById(R.id.text); input.setText(defaultValue); diff --git a/main/src/cgeo/geocaching/TrackableActivity.java b/main/src/cgeo/geocaching/TrackableActivity.java index df3c6e4..fea4521 100644 --- a/main/src/cgeo/geocaching/TrackableActivity.java +++ b/main/src/cgeo/geocaching/TrackableActivity.java @@ -52,7 +52,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi private final int resId; - private Page(final int resId) { + Page(final int resId) { this.resId = resId; } } @@ -126,10 +126,10 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi // try to get data from extras if (extras != null) { - geocode = extras.getString("geocode"); - name = extras.getString("name"); - guid = extras.getString("guid"); - id = extras.getString("id"); + geocode = extras.getString(Intents.EXTRA_GEOCODE); + name = extras.getString(Intents.EXTRA_NAME); + guid = extras.getString(Intents.EXTRA_GUID); + id = extras.getString(Intents.EXTRA_ID); } // try to get data from URI @@ -216,6 +216,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi menu.add(viewId, 1, 0, res.getString(R.string.user_menu_view_hidden)); menu.add(viewId, 2, 0, res.getString(R.string.user_menu_view_found)); menu.add(viewId, 3, 0, res.getString(R.string.user_menu_open_browser)); + menu.add(viewId, 4, 0, res.getString(R.string.user_menu_send_message)); } @Override @@ -230,6 +231,9 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi case 3: startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + Network.encode(contextMenuUser)))); return true; + case 4: + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/email/?u=" + Network.encode(contextMenuUser)))); + return true; default: return false; } @@ -353,9 +357,9 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi public static void startActivity(final AbstractActivity fromContext, final String guid, final String geocode, final String name) { final Intent trackableIntent = new Intent(fromContext, TrackableActivity.class); - trackableIntent.putExtra("guid", guid); - trackableIntent.putExtra("geocode", geocode); - trackableIntent.putExtra("name", name); + trackableIntent.putExtra(Intents.EXTRA_GUID, guid); + trackableIntent.putExtra(Intents.EXTRA_GEOCODE, geocode); + trackableIntent.putExtra(Intents.EXTRA_NAME, name); fromContext.startActivity(trackableIntent); } diff --git a/main/src/cgeo/geocaching/VisitCacheActivity.java b/main/src/cgeo/geocaching/VisitCacheActivity.java index 760d992..b2c6625 100644 --- a/main/src/cgeo/geocaching/VisitCacheActivity.java +++ b/main/src/cgeo/geocaching/VisitCacheActivity.java @@ -10,8 +10,8 @@ import cgeo.geocaching.gcvote.GCVote; import cgeo.geocaching.loaders.UrlLoader; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.twitter.Twitter; -import cgeo.geocaching.ui.DateDialog; import cgeo.geocaching.ui.Formatter; +import cgeo.geocaching.ui.dialog.DateDialog; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.LogTemplateProvider; import cgeo.geocaching.utils.LogTemplateProvider.LogContext; @@ -66,7 +66,7 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD private static final int SELECT_IMAGE = 101; private LayoutInflater inflater = null; - private cgCache cache = null; + private Geocache cache = null; private ProgressDialog waitDialog = null; private String cacheid = null; private String geocode = null; @@ -568,7 +568,7 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD if (logResult.left == StatusCode.NO_ERROR) { final LogEntry logNow = new LogEntry(date, typeSelected, log); - cache.getLogs().prepend(logNow); + cache.getLogs().add(0, logNow); if (typeSelected == LogType.FOUND_IT) { cache.setFound(true); @@ -625,7 +625,7 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD } private void selectAllTrackablesAction() { - Builder alert = new AlertDialog.Builder(VisitCacheActivity.this); + Builder alert = new AlertDialog.Builder(this); alert.setTitle(res.getString(R.string.log_tb_changeall)); String[] tbLogTypes = getTBLogTypes(); alert.setItems(tbLogTypes, new OnClickListener() { @@ -654,7 +654,7 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD } private void selectLogType() { - Builder alert = new AlertDialog.Builder(VisitCacheActivity.this); + Builder alert = new AlertDialog.Builder(this); String[] choices = new String[possibleLogTypes.size()]; for (int i = 0; i < choices.length; i++) { choices[i] = possibleLogTypes.get(i).getL10n(); @@ -672,7 +672,7 @@ public class VisitCacheActivity extends AbstractLoggingActivity implements DateD private void selectTrackableAction(View view) { final int realViewId = view.getId(); - Builder alert = new AlertDialog.Builder(VisitCacheActivity.this); + Builder alert = new AlertDialog.Builder(this); final TrackableLog trackableLog = actionButtons.get(realViewId); alert.setTitle(trackableLog.name); String[] tbLogTypes = getTBLogTypes(); diff --git a/main/src/cgeo/geocaching/Waypoint.java b/main/src/cgeo/geocaching/Waypoint.java index 7a8b787..1d88c40 100644 --- a/main/src/cgeo/geocaching/Waypoint.java +++ b/main/src/cgeo/geocaching/Waypoint.java @@ -8,13 +8,15 @@ import org.apache.commons.lang3.StringUtils; import android.content.res.Resources; import android.widget.TextView; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class Waypoint implements IWaypoint, Comparable<Waypoint> { public static final String PREFIX_OWN = "OWN"; private static final int ORDER_UNDEFINED = -2; - private int id = 0; + private int id = -1; private String geocode = "geocode"; private WaypointType waypointType = WaypointType.WAYPOINT; private String prefix = ""; @@ -46,7 +48,7 @@ public class Waypoint implements IWaypoint, Comparable<Waypoint> { public Waypoint(final Waypoint other) { merge(other); this.waypointType = other.waypointType; - id = 0; + id = -1; } public void setIcon(final Resources res, final TextView nameView) { @@ -77,31 +79,25 @@ public class Waypoint implements IWaypoint, Comparable<Waypoint> { note = old.note; } } + if (id < 0) { + id = old.id; + } } - public static void mergeWayPoints(List<Waypoint> newPoints, - List<Waypoint> oldPoints, boolean forceMerge) { - // copy user modified details of the waypoints - if (newPoints != null && oldPoints != null) { - for (Waypoint old : oldPoints) { - if (old != null) { - boolean merged = false; - if (StringUtils.isNotEmpty(old.name)) { - for (Waypoint waypoint : newPoints) { - if (waypoint != null && waypoint.name != null) { - if (old.name.equalsIgnoreCase(waypoint.name)) { - waypoint.merge(old); - merged = true; - break; - } - } - } - } - // user added waypoints should also be in the new list - if (!merged && (old.isUserDefined() || forceMerge)) { - newPoints.add(old); - } - } + public static void mergeWayPoints(final List<Waypoint> newPoints, final List<Waypoint> oldPoints, final boolean forceMerge) { + // Build a map of new waypoints for faster subsequent lookups + final Map<String, Waypoint> newPrefixes = new HashMap<String, Waypoint>(newPoints.size()); + for (final Waypoint waypoint : newPoints) { + newPrefixes.put(waypoint.getPrefix(), waypoint); + } + + // Copy user modified details of the old waypoints over the new ones + for (final Waypoint oldWaypoint : oldPoints) { + final String prefix = oldWaypoint.getPrefix(); + if (newPrefixes.containsKey(prefix)) { + newPrefixes.get(prefix).merge(oldWaypoint); + } else if (oldWaypoint.isUserDefined() || forceMerge) { + newPoints.add(oldWaypoint); } } } diff --git a/main/src/cgeo/geocaching/WaypointPopup.java b/main/src/cgeo/geocaching/WaypointPopup.java index a69b729..766d43d 100644 --- a/main/src/cgeo/geocaching/WaypointPopup.java +++ b/main/src/cgeo/geocaching/WaypointPopup.java @@ -17,7 +17,6 @@ import android.widget.LinearLayout; import android.widget.TextView; public class WaypointPopup extends AbstractPopupActivity { - private static final String EXTRA_WAYPOINT_ID = "waypoint_id"; private int waypointId = 0; private Waypoint waypoint = null; @@ -31,7 +30,7 @@ public class WaypointPopup extends AbstractPopupActivity { // get parameters final Bundle extras = getIntent().getExtras(); if (extras != null) { - waypointId = extras.getInt(EXTRA_WAYPOINT_ID); + waypointId = extras.getInt(Intents.EXTRA_WAYPOINT_ID); } } @@ -83,7 +82,7 @@ public class WaypointPopup extends AbstractPopupActivity { } /** - * Tries to navigate to the {@link cgCache} of this activity. + * Tries to navigate to the {@link Geocache} of this activity. */ @Override protected void startDefaultNavigation2() { @@ -97,8 +96,8 @@ public class WaypointPopup extends AbstractPopupActivity { public static void startActivity(final Context context, final int waypointId, final String geocode) { final Intent popupIntent = new Intent(context, WaypointPopup.class); - popupIntent.putExtra(EXTRA_WAYPOINT_ID, waypointId); - popupIntent.putExtra(EXTRA_GEOCODE, geocode); + popupIntent.putExtra(Intents.EXTRA_WAYPOINT_ID, waypointId); + popupIntent.putExtra(Intents.EXTRA_GEOCODE, geocode); context.startActivity(popupIntent); } diff --git a/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java b/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java index 56431d4..366a59d 100644 --- a/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java +++ b/main/src/cgeo/geocaching/activity/AbstractViewPagerActivity.java @@ -237,8 +237,8 @@ public abstract class AbstractViewPagerActivity<Page extends Enum<Page>> extends pageOrder.addAll(pagesAndIndex.getLeft()); // switch to details page, if we're out of bounds - final int defaultPage = pagesAndIndex.getRight().intValue(); - if (viewPager.getCurrentItem() < 0 || viewPager.getCurrentItem() >= viewPagerAdapter.getCount()) { + final int defaultPage = pagesAndIndex.getRight(); + if (getCurrentItem() < 0 || getCurrentItem() >= viewPagerAdapter.getCount()) { viewPager.setCurrentItem(defaultPage, false); } @@ -267,6 +267,10 @@ public abstract class AbstractViewPagerActivity<Page extends Enum<Page>> extends } protected final boolean isCurrentPage(Page page) { - return viewPager.getCurrentItem() == getPageIndex(page); + return getCurrentItem() == getPageIndex(page); + } + + protected int getCurrentItem() { + return viewPager.getCurrentItem(); } } diff --git a/main/src/cgeo/geocaching/activity/ActivityMixin.java b/main/src/cgeo/geocaching/activity/ActivityMixin.java index 8900593..de2dade 100644 --- a/main/src/cgeo/geocaching/activity/ActivityMixin.java +++ b/main/src/cgeo/geocaching/activity/ActivityMixin.java @@ -79,6 +79,22 @@ public final class ActivityMixin { } } + public static int getTheme() { + if (Settings.isLightSkin()) { + return R.style.light; + } + + return R.style.dark; + } + + public static int getDialogTheme() { + if (Settings.isLightSkin()) { + return R.style.popup_light; + } + + return R.style.popup_dark; + } + public static void showToast(final Activity activity, final String text) { if (StringUtils.isNotBlank(text)) { Toast toast = Toast.makeText(activity, text, Toast.LENGTH_LONG); diff --git a/main/src/cgeo/geocaching/activity/Progress.java b/main/src/cgeo/geocaching/activity/Progress.java index 1aa1942..34e7623 100644 --- a/main/src/cgeo/geocaching/activity/Progress.java +++ b/main/src/cgeo/geocaching/activity/Progress.java @@ -1,6 +1,6 @@ package cgeo.geocaching.activity; -import cgeo.geocaching.ui.CustomProgressDialog; +import cgeo.geocaching.ui.dialog.CustomProgressDialog; import android.app.ProgressDialog; import android.content.Context; diff --git a/main/src/cgeo/geocaching/apps/AbstractApp.java b/main/src/cgeo/geocaching/apps/AbstractApp.java index 678b98c..c95e8b4 100644 --- a/main/src/cgeo/geocaching/apps/AbstractApp.java +++ b/main/src/cgeo/geocaching/apps/AbstractApp.java @@ -1,6 +1,6 @@ package cgeo.geocaching.apps; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.cgeo; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.utils.ProcessUtils; @@ -56,7 +56,7 @@ public abstract class AbstractApp implements App { } @Override - public boolean isEnabled(cgCache cache) { + public boolean isEnabled(Geocache cache) { return cache != null; } } diff --git a/main/src/cgeo/geocaching/apps/AbstractLocusApp.java b/main/src/cgeo/geocaching/apps/AbstractLocusApp.java index ad421f6..53620e4 100644 --- a/main/src/cgeo/geocaching/apps/AbstractLocusApp.java +++ b/main/src/cgeo/geocaching/apps/AbstractLocusApp.java @@ -1,7 +1,7 @@ package cgeo.geocaching.apps; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; import cgeo.geocaching.Waypoint; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheSize; @@ -66,8 +66,8 @@ public abstract class AbstractLocusApp extends AbstractApp { for (Object o : objectsToShow) { Point p = null; // get icon and Point - if (o instanceof cgCache) { - p = getCachePoint((cgCache) o, withCacheWaypoints, withCacheDetails); + if (o instanceof Geocache) { + p = getCachePoint((Geocache) o, withCacheWaypoints, withCacheDetails); } else if (o instanceof Waypoint) { p = getWaypointPoint((Waypoint) o); } @@ -104,7 +104,7 @@ public abstract class AbstractLocusApp extends AbstractApp { * should be false for all if more then 200 Caches are transferred * @return null, when the <code>Point</code> could not be constructed */ - private static Point getCachePoint(cgCache cache, boolean withWaypoints, boolean withCacheDetails) { + private static Point getCachePoint(Geocache cache, boolean withWaypoints, boolean withCacheDetails) { if (cache == null || cache.getCoords() == null) { return null; } diff --git a/main/src/cgeo/geocaching/apps/App.java b/main/src/cgeo/geocaching/apps/App.java index 9d6d371..bc99526 100644 --- a/main/src/cgeo/geocaching/apps/App.java +++ b/main/src/cgeo/geocaching/apps/App.java @@ -1,6 +1,6 @@ package cgeo.geocaching.apps; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; public interface App { public boolean isInstalled(); @@ -17,5 +17,5 @@ public interface App { * @param cache * @return */ - boolean isEnabled(final cgCache cache); + boolean isEnabled(final Geocache cache); } diff --git a/main/src/cgeo/geocaching/apps/LocusDataStorageProvider.java b/main/src/cgeo/geocaching/apps/LocusDataStorageProvider.java index 6897f95..03954f5 100644 --- a/main/src/cgeo/geocaching/apps/LocusDataStorageProvider.java +++ b/main/src/cgeo/geocaching/apps/LocusDataStorageProvider.java @@ -4,16 +4,12 @@ import menion.android.locus.addon.publiclib.geoData.PointsData; import menion.android.locus.addon.publiclib.utils.DataCursor; import menion.android.locus.addon.publiclib.utils.DataStorage; -import org.apache.commons.collections.CollectionUtils; - import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Parcel; -import java.util.ArrayList; - /** * code provided by menion - developer of Locus */ @@ -23,20 +19,14 @@ public class LocusDataStorageProvider extends ContentProvider { public Cursor query(Uri aUri, String[] aProjection, String aSelection, String[] aSelectionArgs, String aSortOrder) { - DataCursor cursor = new DataCursor(new String[] { "data" }); - - ArrayList<PointsData> data = DataStorage.getData(); - if (CollectionUtils.isEmpty(data)) { - return cursor; - } + final DataCursor cursor = new DataCursor(new String[] { "data" }); - for (int i = 0; i < data.size(); i++) { - // get byte array - Parcel par = Parcel.obtain(); - data.get(i).writeToParcel(par, 0); - byte[] byteData = par.marshall(); - // add to row - cursor.addRow(new Object[] { byteData }); + for (final PointsData item : DataStorage.getData()) { + final Parcel par = Parcel.obtain(); + item.writeToParcel(par, 0); + // add byte array to row + cursor.addRow(new Object[] { par.marshall() }); + par.recycle(); } // data filled to cursor, clear reference to prevent some memory issue DataStorage.clearData(); diff --git a/main/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java b/main/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java index 8087d6d..fd7d4b5 100644 --- a/main/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java +++ b/main/src/cgeo/geocaching/apps/cache/AbstractGeneralApp.java @@ -1,6 +1,6 @@ package cgeo.geocaching.apps.cache; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.apps.AbstractApp; import cgeo.geocaching.apps.cache.navi.CacheNavigationApp; @@ -14,7 +14,7 @@ abstract class AbstractGeneralApp extends AbstractApp implements CacheNavigation } @Override - public void navigate(Activity activity, cgCache cache) { + public void navigate(Activity activity, Geocache cache) { final Intent intent = getLaunchIntent(); if (intent != null) { intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); diff --git a/main/src/cgeo/geocaching/apps/cache/CacheBeaconApp.java b/main/src/cgeo/geocaching/apps/cache/CacheBeaconApp.java index 4ba336f..9cfafb4 100644 --- a/main/src/cgeo/geocaching/apps/cache/CacheBeaconApp.java +++ b/main/src/cgeo/geocaching/apps/cache/CacheBeaconApp.java @@ -1,7 +1,7 @@ package cgeo.geocaching.apps.cache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; import cgeo.geocaching.enumerations.CacheAttribute; public class CacheBeaconApp extends AbstractGeneralApp { @@ -11,8 +11,8 @@ public class CacheBeaconApp extends AbstractGeneralApp { } @Override - public boolean isEnabled(cgCache cache) { - return cache.hasAttribute(CacheAttribute.WIRELESS_BEACON, true); + public boolean isEnabled(Geocache cache) { + return cache.hasAttribute(CacheAttribute.WIRELESSBEACON, true); } } diff --git a/main/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java b/main/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java index 8c06d7a..39e1963 100644 --- a/main/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java +++ b/main/src/cgeo/geocaching/apps/cache/WhereYouGoApp.java @@ -1,7 +1,7 @@ package cgeo.geocaching.apps.cache; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.enumerations.CacheType; public class WhereYouGoApp extends AbstractGeneralApp { @@ -10,7 +10,7 @@ public class WhereYouGoApp extends AbstractGeneralApp { } @Override - public boolean isEnabled(cgCache cache) { + public boolean isEnabled(Geocache cache) { return cache.getType() == CacheType.WHERIGO; } } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java b/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java index 67aa849..a3ea57e 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/AbstractPointNavigationApp.java @@ -1,6 +1,6 @@ package cgeo.geocaching.apps.cache.navi; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.Waypoint; import cgeo.geocaching.apps.AbstractApp; @@ -20,7 +20,7 @@ abstract class AbstractPointNavigationApp extends AbstractApp implements CacheNa } @Override - public void navigate(Activity activity, cgCache cache) { + public void navigate(Activity activity, Geocache cache) { navigate(activity, cache.getCoords()); } @@ -30,7 +30,7 @@ abstract class AbstractPointNavigationApp extends AbstractApp implements CacheNa } @Override - public boolean isEnabled(cgCache cache) { + public boolean isEnabled(Geocache cache) { return cache.getCoords() != null; } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/AbstractStaticMapsApp.java b/main/src/cgeo/geocaching/apps/cache/navi/AbstractStaticMapsApp.java index e6bf9f4..d089e82 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/AbstractStaticMapsApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/AbstractStaticMapsApp.java @@ -5,7 +5,7 @@ import cgeo.geocaching.R; import cgeo.geocaching.StaticMapsActivity; import cgeo.geocaching.StaticMapsProvider; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.cgData; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.apps.AbstractApp; @@ -41,7 +41,7 @@ abstract class AbstractStaticMapsApp extends AbstractApp implements CacheNavigat return false; } - protected static boolean invokeStaticMaps(final Activity activity, final cgCache cache, final Waypoint waypoint, final boolean download) { + protected static boolean invokeStaticMaps(final Activity activity, final Geocache cache, final Waypoint waypoint, final boolean download) { final ILogable logable = cache != null && cache.getListId() != 0 ? cache : waypoint; // If the cache is not stored for offline, cache seems to be null and waypoint may be null too if (logable==null || logable.getGeocode()==null ) { diff --git a/main/src/cgeo/geocaching/apps/cache/navi/CacheNavigationApp.java b/main/src/cgeo/geocaching/apps/cache/navi/CacheNavigationApp.java index e47150f..d47bdc0 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/CacheNavigationApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/CacheNavigationApp.java @@ -1,6 +1,6 @@ package cgeo.geocaching.apps.cache.navi; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.apps.App; import android.app.Activity; @@ -10,8 +10,8 @@ import android.app.Activity; * */ public interface CacheNavigationApp extends App { - void navigate(final Activity activity, final cgCache cache); + void navigate(final Activity activity, final Geocache cache); @Override - boolean isEnabled(final cgCache cache); + boolean isEnabled(final Geocache cache); }
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/apps/cache/navi/CompassApp.java b/main/src/cgeo/geocaching/apps/cache/navi/CompassApp.java index 330c338..1ded9ac 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/CompassApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/CompassApp.java @@ -1,8 +1,8 @@ package cgeo.geocaching.apps.cache.navi; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeonavigate; import cgeo.geocaching.apps.AbstractApp; import cgeo.geocaching.geopoint.Geopoint; @@ -38,13 +38,13 @@ class CompassApp extends AbstractApp implements CacheNavigationApp, WaypointNavi } @Override - public void navigate(Activity activity, cgCache cache) { + public void navigate(Activity activity, Geocache cache) { cgeonavigate.startActivity(activity, cache.getGeocode(), cache.getName(), cache.getCoords(), null, Formatter.formatCacheInfoShort(cache)); } @Override - public boolean isEnabled(cgCache cache) { + public boolean isEnabled(Geocache cache) { return cache.getGeocode() != null; } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/DownloadStaticMapsApp.java b/main/src/cgeo/geocaching/apps/cache/navi/DownloadStaticMapsApp.java index 846b9bc..bc422d4 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/DownloadStaticMapsApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/DownloadStaticMapsApp.java @@ -1,7 +1,7 @@ package cgeo.geocaching.apps.cache.navi; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; import cgeo.geocaching.Waypoint; import android.app.Activity; @@ -13,7 +13,7 @@ class DownloadStaticMapsApp extends AbstractStaticMapsApp { } @Override - public boolean isEnabled(cgCache cache) { + public boolean isEnabled(Geocache cache) { return !cache.hasStaticMap(); } @@ -23,7 +23,7 @@ class DownloadStaticMapsApp extends AbstractStaticMapsApp { } @Override - public void navigate(Activity activity, cgCache cache) { + public void navigate(Activity activity, Geocache cache) { invokeStaticMaps(activity, cache, null, true); } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/InternalMap.java b/main/src/cgeo/geocaching/apps/cache/navi/InternalMap.java index db842ad..2990f93 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/InternalMap.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/InternalMap.java @@ -1,8 +1,8 @@ package cgeo.geocaching.apps.cache.navi; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgCache; import cgeo.geocaching.apps.AbstractApp; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.geopoint.Geopoint; @@ -37,12 +37,12 @@ class InternalMap extends AbstractApp implements CacheNavigationApp, WaypointNav } @Override - public void navigate(Activity activity, cgCache cache) { + public void navigate(Activity activity, Geocache cache) { CGeoMap.startActivityGeoCode(activity, cache.getGeocode()); } @Override - public boolean isEnabled(cgCache cache) { + public boolean isEnabled(Geocache cache) { return cache.getCoords() != null; } } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/LocusApp.java b/main/src/cgeo/geocaching/apps/cache/navi/LocusApp.java index b326105..2d7702d 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/LocusApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/LocusApp.java @@ -1,6 +1,6 @@ package cgeo.geocaching.apps.cache.navi; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.Waypoint; import cgeo.geocaching.apps.AbstractLocusApp; @@ -26,7 +26,7 @@ class LocusApp extends AbstractLocusApp implements CacheNavigationApp, WaypointN } @Override - public void navigate(Activity activity, cgCache cache) { + public void navigate(Activity activity, Geocache cache) { showInLocus(Collections.singletonList(cache), true, false, activity); } } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java index 8effc05..5545936 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java @@ -1,9 +1,9 @@ package cgeo.geocaching.apps.cache.navi; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; import cgeo.geocaching.Settings; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.apps.AbstractAppFactory; @@ -96,7 +96,7 @@ public final class NavigationAppFactory extends AbstractAppFactory { * Default way to handle selection of navigation tool.<br /> * A dialog is created for tool selection and the selected tool is started afterwards. * <p /> - * Delegates to {@link #showNavigationMenu(Activity, cgCache, cgeo.geocaching.Waypoint, Geopoint, boolean, boolean)} with + * Delegates to {@link #showNavigationMenu(Activity, cgeo.geocaching.Geocache, cgeo.geocaching.Waypoint, Geopoint, boolean, boolean)} with * <code>showInternalMap = true</code> and <code>showDefaultNavigation = false</code> * * @param activity @@ -105,7 +105,7 @@ public final class NavigationAppFactory extends AbstractAppFactory { * @param destination */ public static void showNavigationMenu(final Activity activity, - final cgCache cache, final Waypoint waypoint, final Geopoint destination) { + final Geocache cache, final Waypoint waypoint, final Geopoint destination) { showNavigationMenu(activity, cache, waypoint, destination, true, false); } @@ -125,10 +125,10 @@ public final class NavigationAppFactory extends AbstractAppFactory { * @param showDefaultNavigation * should be <code>false</code> by default * - * @see #showNavigationMenu(Activity, cgCache, cgeo.geocaching.Waypoint, Geopoint) + * @see #showNavigationMenu(Activity, cgeo.geocaching.Geocache, cgeo.geocaching.Waypoint, Geopoint) */ public static void showNavigationMenu(final Activity activity, - final cgCache cache, final Waypoint waypoint, final Geopoint destination, + final Geocache cache, final Waypoint waypoint, final Geopoint destination, final boolean showInternalMap, final boolean showDefaultNavigation) { final AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(R.string.cache_menu_navigate); @@ -216,15 +216,15 @@ public final class NavigationAppFactory extends AbstractAppFactory { /** * Adds the installed navigation tools to the given menu. - * Use {@link #onMenuItemSelected(MenuItem, Activity, cgCache)} on + * Use {@link #onMenuItemSelected(MenuItem, Activity, cgeo.geocaching.Geocache)} on * selection event to start the selected navigation tool. * - * <b>Only use this way if {@link #showNavigationMenu(Activity, cgCache, cgeo.geocaching.Waypoint, Geopoint, boolean, boolean)} is + * <b>Only use this way if {@link #showNavigationMenu(Activity, cgeo.geocaching.Geocache, cgeo.geocaching.Waypoint, Geopoint, boolean, boolean)} is * not suitable for the given usecase.</b> * * @param menu */ - public static void addMenuItems(final Menu menu, final cgCache cache) { + public static void addMenuItems(final Menu menu, final Geocache cache) { for (NavigationAppsEnum navApp : getInstalledNavigationApps()) { if (navApp.app instanceof CacheNavigationApp) { CacheNavigationApp cacheApp = (CacheNavigationApp) navApp.app; @@ -247,20 +247,20 @@ public final class NavigationAppFactory extends AbstractAppFactory { } /** - * Handles menu selections for menu entries created with {@link #addMenuItems(Menu, cgCache)}. + * Handles menu selections for menu entries created with {@link #addMenuItems(Menu, cgeo.geocaching.Geocache)}. * * @param item * @param activity * @param cache * @return */ - public static boolean onMenuItemSelected(final MenuItem item, Activity activity, cgCache cache) { + public static boolean onMenuItemSelected(final MenuItem item, Activity activity, Geocache cache) { final App menuItem = getAppFromMenuItem(item); navigateCache(activity, cache, menuItem); return menuItem != null; } - private static void navigateCache(Activity activity, cgCache cache, App app) { + private static void navigateCache(Activity activity, Geocache cache, App app) { if (app instanceof CacheNavigationApp) { CacheNavigationApp cacheApp = (CacheNavigationApp) app; cacheApp.navigate(activity, cache); @@ -305,7 +305,7 @@ public final class NavigationAppFactory extends AbstractAppFactory { * @param activity * @param cache */ - public static void startDefaultNavigationApplication(int defaultNavigation, Activity activity, cgCache cache) { + public static void startDefaultNavigationApplication(int defaultNavigation, Activity activity, Geocache cache) { if (cache == null || cache.getCoords() == null) { ActivityMixin.showToast(activity, cgeoapplication.getInstance().getString(R.string.err_location_unknown)); return; diff --git a/main/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java b/main/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java index c94c4f4..2c6a8fc 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/RMapsApp.java @@ -2,7 +2,7 @@ package cgeo.geocaching.apps.cache.navi; import cgeo.geocaching.R; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.apps.AbstractApp; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter.Format; @@ -39,7 +39,7 @@ class RMapsApp extends AbstractApp implements CacheNavigationApp, WaypointNaviga } @Override - public void navigate(Activity activity, cgCache cache) { + public void navigate(Activity activity, Geocache cache) { navigate(activity, cache.getCoords(), cache.getGeocode(), cache.getName()); } diff --git a/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java b/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java index 4c3b87e..1dd57a3 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/StaticMapApp.java @@ -2,7 +2,7 @@ package cgeo.geocaching.apps.cache.navi; import cgeo.geocaching.R; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import android.app.Activity; @@ -13,7 +13,7 @@ class StaticMapApp extends AbstractStaticMapsApp { } @Override - public boolean isEnabled(cgCache cache) { + public boolean isEnabled(Geocache cache) { return cache.hasStaticMap(); } @@ -23,7 +23,7 @@ class StaticMapApp extends AbstractStaticMapsApp { } @Override - public void navigate(Activity activity, cgCache cache) { + public void navigate(Activity activity, Geocache cache) { invokeStaticMaps(activity, cache, null, false); } diff --git a/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java b/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java index 519b394..ac5809e 100644 --- a/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java +++ b/main/src/cgeo/geocaching/apps/cachelist/CacheListApp.java @@ -1,7 +1,7 @@ package cgeo.geocaching.apps.cachelist; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.apps.App; import android.app.Activity; @@ -10,7 +10,7 @@ import java.util.List; interface CacheListApp extends App { - boolean invoke(final List<cgCache> caches, + boolean invoke(final List<Geocache> caches, final Activity activity, final SearchResult search); } diff --git a/main/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java b/main/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java index b01c0ac..b747eee 100644 --- a/main/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java +++ b/main/src/cgeo/geocaching/apps/cachelist/CacheListAppFactory.java @@ -2,7 +2,7 @@ package cgeo.geocaching.apps.cachelist; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.activity.IAbstractActivity; import cgeo.geocaching.apps.AbstractAppFactory; import cgeo.geocaching.utils.Log; @@ -55,7 +55,7 @@ public final class CacheListAppFactory extends AbstractAppFactory { } } - public static boolean onMenuItemSelected(final MenuItem item, final List<cgCache> caches, final IAbstractActivity activity, + public static boolean onMenuItemSelected(final MenuItem item, final List<Geocache> caches, final IAbstractActivity activity, final SearchResult search) { final CacheListApp app = (CacheListApp) getAppFromMenuItem(item, LazyHolder.apps); if (app != null) { diff --git a/main/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java b/main/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java index d6e1fed..38fb499 100644 --- a/main/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java +++ b/main/src/cgeo/geocaching/apps/cachelist/InternalCacheListMap.java @@ -2,7 +2,7 @@ package cgeo.geocaching.apps.cachelist; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.apps.AbstractApp; import cgeo.geocaching.maps.CGeoMap; @@ -22,7 +22,7 @@ class InternalCacheListMap extends AbstractApp implements CacheListApp { } @Override - public boolean invoke(List<cgCache> caches, Activity activity, final SearchResult search) { + public boolean invoke(List<Geocache> caches, Activity activity, final SearchResult search) { CGeoMap.startActivitySearch(activity, search, null); return true; } diff --git a/main/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java b/main/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java index 65760c7..cd0289a 100644 --- a/main/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java +++ b/main/src/cgeo/geocaching/apps/cachelist/LocusCacheListApp.java @@ -2,7 +2,7 @@ package cgeo.geocaching.apps.cachelist; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.apps.AbstractLocusApp; import org.apache.commons.collections.CollectionUtils; @@ -27,7 +27,7 @@ class LocusCacheListApp extends AbstractLocusApp implements CacheListApp { * @see AbstractLocusApp#showInLocus */ @Override - public boolean invoke(List<cgCache> cacheList, Activity activity, final SearchResult search) { + public boolean invoke(List<Geocache> cacheList, Activity activity, final SearchResult search) { if (CollectionUtils.isEmpty(cacheList)) { return false; } diff --git a/main/src/cgeo/geocaching/backup/CentralBackupAgent.java b/main/src/cgeo/geocaching/backup/CentralBackupAgent.java index f6b9024..28a668c 100644 --- a/main/src/cgeo/geocaching/backup/CentralBackupAgent.java +++ b/main/src/cgeo/geocaching/backup/CentralBackupAgent.java @@ -1,6 +1,6 @@ package cgeo.geocaching.backup; -import cgeo.geocaching.Settings; +import cgeo.geocaching.utils.ApplicationSettings; import android.annotation.TargetApi; import android.app.backup.BackupAgentHelper; @@ -13,7 +13,7 @@ public class CentralBackupAgent extends BackupAgentHelper { @Override public void onCreate() { - final SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, Settings.getPreferencesName()); + final SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, ApplicationSettings.getPreferencesName()); addHelper(PREFS_BACKUP_KEY, helper); } diff --git a/main/src/cgeo/geocaching/cgData.java b/main/src/cgeo/geocaching/cgData.java index 3ec1d14..cbbd852 100644 --- a/main/src/cgeo/geocaching/cgData.java +++ b/main/src/cgeo/geocaching/cgData.java @@ -59,12 +59,19 @@ public class cgData { /** The list of fields needed for mapping. */ private static final String[] CACHE_COLUMNS = new String[] { - "_id", "updated", "reason", "detailed", "detailedupdate", "visiteddate", "geocode", "cacheid", "guid", "type", "name", "own", "owner", "owner_real", "hidden", "hint", "size", - "difficulty", "distance", "direction", "terrain", "latlon", "location", "latitude", "longitude", "elevation", "shortdesc", - "favourite_cnt", "rating", "votes", "myvote", "disabled", "archived", "members", "found", "favourite", "inventorycoins", "inventorytags", - "inventoryunknown", "onWatchlist", "personal_note", "reliable_latlon", "coordsChanged", "finalDefined" - // reason is replaced by listId in cgCache + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + "updated", "reason", "detailed", "detailedupdate", "visiteddate", "geocode", "cacheid", "guid", "type", "name", "owner", "owner_real", "hidden", "hint", "size", + // 15 16 17 18 19 20 21 22 23 + "difficulty", "direction", "distance", "terrain", "latlon", "location", "elevation", "personal_note", "shortdesc", + // 24 25 26 27 28 29 30 31 32 + "favourite_cnt", "rating", "votes", "myvote", "disabled", "archived", "members", "found", "favourite", + // 33 34 35 36 37 38 39 40 41 42 + "inventoryunknown", "onWatchlist", "reliable_latlon", "coordsChanged", "latitude", "longitude", "finalDefined", "_id", "inventorycoins", "inventorytags" + // reason is replaced by listId in Geocache }; + + //TODO: remove "latlon" field from cache table + /** The list of fields needed for mapping. */ private static final String[] WAYPOINT_COLUMNS = new String[] { "_id", "geocode", "updated", "type", "prefix", "lookup", "name", "latlon", "latitude", "longitude", "note", "own" }; @@ -104,7 +111,6 @@ public class cgData { + "guid text, " + "type text, " + "name text, " - + "own integer not null default 0, " + "owner text, " + "owner_real text, " + "hidden long, " @@ -686,7 +692,7 @@ public class cgData { // to NPE traces. final int staleHistorySearches = db.delete(dbTableSearchDestionationHistory, "date is null", null); if (staleHistorySearches > 0) { - Log.w(String.format("cgData.dbHelper.onOpen: removed %d bad search history entries", staleHistorySearches)); + Log.w(String.format(Locale.getDefault(), "cgData.dbHelper.onOpen: removed %d bad search history entries", staleHistorySearches)); } } @@ -940,7 +946,7 @@ public class cgData { * * @return true = cache saved successfully to the CacheCache/DB */ - public static boolean saveCache(cgCache cache, EnumSet<LoadFlags.SaveFlag> saveFlags) { + public static boolean saveCache(Geocache cache, EnumSet<LoadFlags.SaveFlag> saveFlags) { if (cache == null) { throw new IllegalArgumentException("cache must not be null"); } @@ -984,7 +990,6 @@ public class cgData { values.put("guid", cache.getGuid()); values.put("type", cache.getType().id); values.put("name", cache.getName()); - values.put("own", cache.isOwn() ? 1 : 0); values.put("owner", cache.getOwnerDisplayName()); values.put("owner_real", cache.getOwnerUserId()); if (cache.getHiddenDate() == null) { @@ -996,14 +1001,13 @@ public class cgData { values.put("size", cache.getSize() == null ? "" : cache.getSize().id); values.put("difficulty", cache.getDifficulty()); values.put("terrain", cache.getTerrain()); - values.put("latlon", cache.getLatlon()); values.put("location", cache.getLocation()); values.put("distance", cache.getDistance()); values.put("direction", cache.getDirection()); putCoords(values, cache.getCoords()); values.put("reliable_latlon", cache.isReliableLatLon() ? 1 : 0); values.put("elevation", cache.getElevation()); - values.put("shortdesc", cache.getShortdesc()); + values.put("shortdesc", cache.getShortDescription()); values.put("personal_note", cache.getPersonalNote()); values.put("description", cache.getDescription()); values.put("favourite_cnt", cache.getFavoritePoints()); @@ -1051,7 +1055,7 @@ public class cgData { return result; } - private static void saveAttributesWithoutTransaction(final cgCache cache) { + private static void saveAttributesWithoutTransaction(final Geocache cache) { String geocode = cache.getGeocode(); database.delete(dbTableAttributes, "geocode = ?", new String[]{geocode}); @@ -1091,7 +1095,7 @@ public class cgData { } } - public static boolean saveWaypoints(final cgCache cache) { + public static boolean saveWaypoints(final Geocache cache) { init(); database.beginTransaction(); @@ -1108,9 +1112,8 @@ public class cgData { return result; } - private static void saveOriginalWaypointsWithoutTransaction(final cgCache cache) { + private static void saveOriginalWaypointsWithoutTransaction(final Geocache cache) { String geocode = cache.getGeocode(); - database.delete(dbTableWaypoints, "geocode = ? and type <> ? and own = 0", new String[]{geocode, "own"}); List<Waypoint> waypoints = cache.getWaypoints(); if (CollectionUtils.isNotEmpty(waypoints)) { @@ -1133,8 +1136,12 @@ public class cgData { values.put("note", oneWaypoint.getNote()); values.put("own", oneWaypoint.isUserDefined() ? 1 : 0); - final long rowId = database.insert(dbTableWaypoints, null, values); - oneWaypoint.setId((int) rowId); + if (oneWaypoint.getId() < 0) { + final long rowId = database.insert(dbTableWaypoints, null, values); + oneWaypoint.setId((int) rowId); + } else { + database.update(dbTableWaypoints, values, "_id = ?", new String[] { Integer.toString(oneWaypoint.getId(), 10) }); + } } } } @@ -1219,7 +1226,7 @@ public class cgData { return database.delete(dbTableWaypoints, "_id = " + id, null) > 0; } - private static void saveSpoilersWithoutTransaction(final cgCache cache) { + private static void saveSpoilersWithoutTransaction(final Geocache cache) { String geocode = cache.getGeocode(); database.delete(dbTableSpoilers, "geocode = ?", new String[]{geocode}); @@ -1276,7 +1283,7 @@ public class cgData { } } - private static void saveLogCountsWithoutTransaction(final cgCache cache) { + private static void saveLogCountsWithoutTransaction(final Geocache cache) { String geocode = cache.getGeocode(); database.delete(dbTableLogCount, "geocode = ?", new String[]{geocode}); @@ -1352,7 +1359,7 @@ public class cgData { return null; } - final Set<cgCache> caches = loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB); + final Set<Geocache> caches = loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB); return Viewport.containing(caches); } @@ -1363,12 +1370,12 @@ public class cgData { * The Geocode GCXXXX * @return the loaded cache (if found). Can be null */ - public static cgCache loadCache(final String geocode, final EnumSet<LoadFlag> loadFlags) { + public static Geocache loadCache(final String geocode, final EnumSet<LoadFlag> loadFlags) { if (StringUtils.isBlank(geocode)) { throw new IllegalArgumentException("geocode must not be empty"); } - final Set<cgCache> caches = loadCaches(Collections.singleton(geocode), loadFlags); + final Set<Geocache> caches = loadCaches(Collections.singleton(geocode), loadFlags); return caches.isEmpty() ? null : caches.iterator().next(); } @@ -1378,17 +1385,17 @@ public class cgData { * @param geocodes * @return Set of loaded caches. Never null. */ - public static Set<cgCache> loadCaches(final Set<String> geocodes, final EnumSet<LoadFlag> loadFlags) { + public static Set<Geocache> loadCaches(final Set<String> geocodes, final EnumSet<LoadFlag> loadFlags) { if (CollectionUtils.isEmpty(geocodes)) { - return new HashSet<cgCache>(); + return new HashSet<Geocache>(); } - Set<cgCache> result = new HashSet<cgCache>(); + Set<Geocache> result = new HashSet<Geocache>(); Set<String> remaining = new HashSet<String>(geocodes); if (loadFlags.contains(LoadFlag.LOAD_CACHE_BEFORE)) { for (String geocode : new HashSet<String>(remaining)) { - cgCache cache = cacheCache.getCacheFromCache(geocode); + Geocache cache = cacheCache.getCacheFromCache(geocode); if (cache != null) { result.add(cache); remaining.remove(cache.getGeocode()); @@ -1404,16 +1411,16 @@ public class cgData { loadFlags.contains(LoadFlag.LOAD_INVENTORY) || loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) { - final Set<cgCache> cachesFromDB = loadCachesFromGeocodes(remaining, loadFlags); + final Set<Geocache> cachesFromDB = loadCachesFromGeocodes(remaining, loadFlags); result.addAll(cachesFromDB); - for (final cgCache cache : cachesFromDB) { + for (final Geocache cache : cachesFromDB) { remaining.remove(cache.getGeocode()); } } if (loadFlags.contains(LoadFlag.LOAD_CACHE_AFTER)) { for (String geocode : new HashSet<String>(remaining)) { - cgCache cache = cacheCache.getCacheFromCache(geocode); + Geocache cache = cacheCache.getCacheFromCache(geocode); if (cache != null) { result.add(cache); remaining.remove(cache.getGeocode()); @@ -1434,14 +1441,12 @@ public class cgData { * @param loadFlags * @return Set of loaded caches. Never null. */ - private static Set<cgCache> loadCachesFromGeocodes(final Set<String> geocodes, final EnumSet<LoadFlag> loadFlags) { + private static Set<Geocache> loadCachesFromGeocodes(final Set<String> geocodes, final EnumSet<LoadFlag> loadFlags) { if (CollectionUtils.isEmpty(geocodes)) { return Collections.emptySet(); } - - Log.d("cgData.loadCachesFromGeocodes(" + geocodes.toString() + ") from DB"); - + // do not log the entire collection of geo codes to the debug log. This can be more than 100 KB of text for large lists! init(); final StringBuilder query = new StringBuilder("SELECT "); @@ -1462,11 +1467,11 @@ public class cgData { Cursor cursor = database.rawQuery(query.toString(), null); try { - final Set<cgCache> caches = new HashSet<cgCache>(); + final Set<Geocache> caches = new HashSet<Geocache>(); int logIndex = -1; while (cursor.moveToNext()) { - cgCache cache = cgData.createCacheFromDatabaseContent(cursor); + Geocache cache = cgData.createCacheFromDatabaseContent(cursor); if (loadFlags.contains(LoadFlag.LOAD_ATTRIBUTES)) { cache.setAttributes(loadAttributes(cache.getGeocode())); @@ -1541,52 +1546,14 @@ public class cgData { * @param cursor * @return Cache from DB */ - private static cgCache createCacheFromDatabaseContent(Cursor cursor) { - cgCache cache = new cgCache(); + private static Geocache createCacheFromDatabaseContent(Cursor cursor) { + Geocache cache = new Geocache(); if (cacheColumnIndex == null) { - int[] local_cci = new int[41]; // use a local variable to avoid having the not yet fully initialized array be visible to other threads - local_cci[0] = cursor.getColumnIndex("updated"); - local_cci[1] = cursor.getColumnIndex("reason"); - local_cci[2] = cursor.getColumnIndex("detailed"); - local_cci[3] = cursor.getColumnIndex("detailedupdate"); - local_cci[4] = cursor.getColumnIndex("visiteddate"); - local_cci[5] = cursor.getColumnIndex("geocode"); - local_cci[6] = cursor.getColumnIndex("cacheid"); - local_cci[7] = cursor.getColumnIndex("guid"); - local_cci[8] = cursor.getColumnIndex("type"); - local_cci[9] = cursor.getColumnIndex("name"); - local_cci[10] = cursor.getColumnIndex("own"); - local_cci[11] = cursor.getColumnIndex("owner"); - local_cci[12] = cursor.getColumnIndex("owner_real"); - local_cci[13] = cursor.getColumnIndex("hidden"); - local_cci[14] = cursor.getColumnIndex("hint"); - local_cci[15] = cursor.getColumnIndex("size"); - local_cci[16] = cursor.getColumnIndex("difficulty"); - local_cci[17] = cursor.getColumnIndex("direction"); - local_cci[18] = cursor.getColumnIndex("distance"); - local_cci[19] = cursor.getColumnIndex("terrain"); - local_cci[20] = cursor.getColumnIndex("latlon"); - local_cci[21] = cursor.getColumnIndex("location"); - local_cci[22] = cursor.getColumnIndex("elevation"); - local_cci[23] = cursor.getColumnIndex("personal_note"); - local_cci[24] = cursor.getColumnIndex("shortdesc"); - local_cci[25] = cursor.getColumnIndex("favourite_cnt"); - local_cci[26] = cursor.getColumnIndex("rating"); - local_cci[27] = cursor.getColumnIndex("votes"); - local_cci[28] = cursor.getColumnIndex("myvote"); - local_cci[29] = cursor.getColumnIndex("disabled"); - local_cci[30] = cursor.getColumnIndex("archived"); - local_cci[31] = cursor.getColumnIndex("members"); - local_cci[32] = cursor.getColumnIndex("found"); - local_cci[33] = cursor.getColumnIndex("favourite"); - local_cci[34] = cursor.getColumnIndex("inventoryunknown"); - local_cci[35] = cursor.getColumnIndex("onWatchlist"); - local_cci[36] = cursor.getColumnIndex("reliable_latlon"); - local_cci[37] = cursor.getColumnIndex("coordsChanged"); - local_cci[38] = cursor.getColumnIndex("latitude"); - local_cci[39] = cursor.getColumnIndex("longitude"); - local_cci[40] = cursor.getColumnIndex("finalDefined"); + final int[] local_cci = new int[CACHE_COLUMNS.length]; // use a local variable to avoid having the not yet fully initialized array be visible to other threads + for (int i = 0; i < CACHE_COLUMNS.length; i++) { + local_cci[i] = cursor.getColumnIndex(CACHE_COLUMNS[i]); + } cacheColumnIndex = local_cci; } @@ -1600,55 +1567,53 @@ public class cgData { cache.setGuid(cursor.getString(cacheColumnIndex[7])); cache.setType(CacheType.getById(cursor.getString(cacheColumnIndex[8]))); cache.setName(cursor.getString(cacheColumnIndex[9])); - cache.setOwn(cursor.getInt(cacheColumnIndex[10]) == 1); - cache.setOwnerDisplayName(cursor.getString(cacheColumnIndex[11])); - cache.setOwnerUserId(cursor.getString(cacheColumnIndex[12])); - long dateValue = cursor.getLong(cacheColumnIndex[13]); + cache.setOwnerDisplayName(cursor.getString(cacheColumnIndex[10])); + cache.setOwnerUserId(cursor.getString(cacheColumnIndex[11])); + long dateValue = cursor.getLong(cacheColumnIndex[12]); if (dateValue != 0) { cache.setHidden(new Date(dateValue)); } - cache.setHint(cursor.getString(cacheColumnIndex[14])); - cache.setSize(CacheSize.getById(cursor.getString(cacheColumnIndex[15]))); - cache.setDifficulty(cursor.getFloat(cacheColumnIndex[16])); - int index = cacheColumnIndex[17]; + // do not set cache.hint + cache.setSize(CacheSize.getById(cursor.getString(cacheColumnIndex[14]))); + cache.setDifficulty(cursor.getFloat(cacheColumnIndex[15])); + int index = cacheColumnIndex[16]; if (cursor.isNull(index)) { cache.setDirection(null); } else { cache.setDirection(cursor.getFloat(index)); } - index = cacheColumnIndex[18]; + index = cacheColumnIndex[17]; if (cursor.isNull(index)) { cache.setDistance(null); } else { cache.setDistance(cursor.getFloat(index)); } - cache.setTerrain(cursor.getFloat(cacheColumnIndex[19])); - cache.setLatlon(cursor.getString(cacheColumnIndex[20])); - cache.setLocation(cursor.getString(cacheColumnIndex[21])); - cache.setCoords(getCoords(cursor, cacheColumnIndex[38], cacheColumnIndex[39])); - index = cacheColumnIndex[22]; + cache.setTerrain(cursor.getFloat(cacheColumnIndex[18])); + // do not set cache.location + cache.setCoords(getCoords(cursor, cacheColumnIndex[37], cacheColumnIndex[38])); + index = cacheColumnIndex[21]; if (cursor.isNull(index)) { cache.setElevation(null); } else { cache.setElevation(cursor.getDouble(index)); } - cache.setPersonalNote(cursor.getString(cacheColumnIndex[23])); - cache.setShortdesc(cursor.getString(cacheColumnIndex[24])); - // do not set cache.description ! - cache.setFavoritePoints(cursor.getInt(cacheColumnIndex[25])); - cache.setRating(cursor.getFloat(cacheColumnIndex[26])); - cache.setVotes(cursor.getInt(cacheColumnIndex[27])); - cache.setMyVote(cursor.getFloat(cacheColumnIndex[28])); - cache.setDisabled(cursor.getInt(cacheColumnIndex[29]) == 1); - cache.setArchived(cursor.getInt(cacheColumnIndex[30]) == 1); - cache.setPremiumMembersOnly(cursor.getInt(cacheColumnIndex[31]) == 1); - cache.setFound(cursor.getInt(cacheColumnIndex[32]) == 1); - cache.setFavorite(cursor.getInt(cacheColumnIndex[33]) == 1); - cache.setInventoryItems(cursor.getInt(cacheColumnIndex[34])); - cache.setOnWatchlist(cursor.getInt(cacheColumnIndex[35]) == 1); - cache.setReliableLatLon(cursor.getInt(cacheColumnIndex[36]) > 0); - cache.setUserModifiedCoords(cursor.getInt(cacheColumnIndex[37]) > 0); - cache.setFinalDefined(cursor.getInt(cacheColumnIndex[40]) > 0); + cache.setPersonalNote(cursor.getString(cacheColumnIndex[22])); + // do not set cache.shortdesc + // do not set cache.description + cache.setFavoritePoints(cursor.getInt(cacheColumnIndex[24])); + cache.setRating(cursor.getFloat(cacheColumnIndex[25])); + cache.setVotes(cursor.getInt(cacheColumnIndex[26])); + cache.setMyVote(cursor.getFloat(cacheColumnIndex[27])); + cache.setDisabled(cursor.getInt(cacheColumnIndex[28]) == 1); + cache.setArchived(cursor.getInt(cacheColumnIndex[29]) == 1); + cache.setPremiumMembersOnly(cursor.getInt(cacheColumnIndex[30]) == 1); + cache.setFound(cursor.getInt(cacheColumnIndex[31]) == 1); + cache.setFavorite(cursor.getInt(cacheColumnIndex[32]) == 1); + cache.setInventoryItems(cursor.getInt(cacheColumnIndex[33])); + cache.setOnWatchlist(cursor.getInt(cacheColumnIndex[34]) == 1); + cache.setReliableLatLon(cursor.getInt(cacheColumnIndex[35]) > 0); + cache.setUserModifiedCoords(cursor.getInt(cacheColumnIndex[36]) > 0); + cache.setFinalDefined(cursor.getInt(cacheColumnIndex[39]) > 0); Log.d("Loading " + cache.toString() + " (" + cache.getListId() + ") from DB"); @@ -2615,7 +2580,11 @@ public class cgData { return status; } - public static void moveToList(final List<cgCache> caches, final int listId) { + public static void moveToList(final Geocache cache, final int listId) { + moveToList(Collections.singletonList(cache), listId); + } + + public static void moveToList(final List<Geocache> caches, final int listId) { if (listId == StoredList.ALL_LIST_ID) { return; } @@ -2628,7 +2597,7 @@ public class cgData { database.beginTransaction(); try { - for (cgCache cache : caches) { + for (Geocache cache : caches) { move.bindLong(1, listId); move.bindString(2, cache.getGeocode()); move.execute(); @@ -2665,18 +2634,32 @@ public class cgData { return result; } - public static String getCacheDescription(String geocode) { + public static String loadCacheTexts(final Geocache cache) { + final String geocode = cache.getGeocode(); if (StringUtils.isBlank(geocode)) { return null; } init(); try { - final SQLiteStatement description = PreparedStatements.getDescriptionOfGeocode(); - synchronized (description) { - description.bindString(1, geocode); - return description.simpleQueryForString(); + final Cursor cursor = database.query( + dbTableCaches, + new String[] { "description", "shortdesc", "hint", "location" }, + "geocode = ?", + new String[] { geocode }, + null, + null, + null, + "1"); + + if (cursor.moveToFirst()) { + cache.setDescription(StringUtils.defaultString(cursor.getString(0))); + cache.setShortDescription(StringUtils.defaultString(cursor.getString(1))); + cache.setHint(StringUtils.defaultString(cursor.getString(2))); + cache.setLocation(StringUtils.defaultString(cursor.getString(3))); } + + cursor.close(); } catch (SQLiteDoneException e) { // Do nothing, it only means we have no information on the cache } catch (Exception e) { @@ -2702,14 +2685,14 @@ public class cgData { newlyCreatedDatabase = false; } - private static String whereGeocodeIn(Set<String> geocodes) { + private static StringBuilder whereGeocodeIn(Set<String> geocodes) { final StringBuilder where = new StringBuilder(); if (geocodes != null && !geocodes.isEmpty()) { StringBuilder all = new StringBuilder(); for (String geocode : geocodes) { if (all.length() > 0) { - all.append(", "); + all.append(','); } all.append(DatabaseUtils.sqlEscapeString(geocode)); } @@ -2717,7 +2700,7 @@ public class cgData { where.append("geocode in (").append(all).append(')'); } - return where.toString(); + return where; } /** @@ -2732,7 +2715,7 @@ public class cgData { public static Set<Waypoint> loadWaypoints(final Viewport viewport, boolean excludeMine, boolean excludeDisabled, CacheType type) { final StringBuilder where = new StringBuilder(buildCoordinateWhere(dbTableWaypoints, viewport)); if (excludeMine) { - where.append(" and ").append(dbTableCaches).append(".own == 0 and ").append(dbTableCaches).append(".found == 0"); + where.append(" and ").append(dbTableCaches).append(".found == 0"); } if (excludeDisabled) { where.append(" and ").append(dbTableCaches).append(".disabled == 0"); @@ -2787,7 +2770,7 @@ public class cgData { return result; } - public static boolean saveChangedCache(cgCache cache) { + public static boolean saveChangedCache(Geocache cache) { return cgData.saveCache(cache, cache.getStorageLocation().contains(StorageLocation.DATABASE) ? LoadFlags.SAVE_ALL : EnumSet.of(SaveFlag.SAVE_CACHE)); } @@ -2838,7 +2821,7 @@ public class cgData { private static synchronized SQLiteStatement getStatement(final String key, final String query) { SQLiteStatement statement = statements.get(key); if (statement == null) { - Log.d("Compiling " + key); + init(); statement = database.compileStatement(query); statements.put(key, statement); } @@ -2869,10 +2852,6 @@ public class cgData { return getStatement("InsertAttribute", "INSERT INTO " + dbTableAttributes + " (geocode, updated, attribute) VALUES (?, ?, ?)"); } - private static SQLiteStatement getDescriptionOfGeocode() { - return getStatement("descriptionFromGeocode", "SELECT description FROM " + dbTableCaches + " WHERE geocode = ?"); - } - private static SQLiteStatement getListIdOfGeocode() { return getStatement("listFromGeocode", "SELECT reason FROM " + dbTableCaches + " WHERE geocode = ?"); } @@ -2895,7 +2874,7 @@ public class cgData { setVisitDate(Collections.singletonList(geocode), System.currentTimeMillis()); } - public static void markDropped(List<cgCache> caches) { + public static void markDropped(List<Geocache> caches) { moveToList(caches, StoredList.TEMPORARY_LIST_ID); } @@ -2907,9 +2886,9 @@ public class cgData { return cgData.getBounds(Collections.singleton(geocode)); } - public static void clearVisitDate(List<cgCache> caches) { + public static void clearVisitDate(List<Geocache> caches) { ArrayList<String> geocodes = new ArrayList<String>(caches.size()); - for (cgCache cache : caches) { + for (Geocache cache : caches) { geocodes.add(cache.getGeocode()); } setVisitDate(geocodes, 0); diff --git a/main/src/cgeo/geocaching/cgSelectMapfile.java b/main/src/cgeo/geocaching/cgSelectMapfile.java index 3757c4f..ded81a7 100644 --- a/main/src/cgeo/geocaching/cgSelectMapfile.java +++ b/main/src/cgeo/geocaching/cgSelectMapfile.java @@ -31,7 +31,7 @@ public class cgSelectMapfile extends FileList<FileSelectionListAdapter> implemen public void close() { Intent intent = new Intent(); - intent.putExtra("mapfile", mapFile); + intent.putExtra(Intents.EXTRA_MAP_FILE, mapFile); setResult(RESULT_OK, intent); diff --git a/main/src/cgeo/geocaching/cgeocaches.java b/main/src/cgeo/geocaching/cgeocaches.java index fa83a60..7fbb112 100644 --- a/main/src/cgeo/geocaching/cgeocaches.java +++ b/main/src/cgeo/geocaching/cgeocaches.java @@ -72,12 +72,6 @@ import java.util.Set; public class cgeocaches extends AbstractListActivity implements FilteredActivity { - private static final String EXTRAS_USERNAME = "username"; - private static final String EXTRAS_ADDRESS = "address"; - private static final String EXTRAS_SEARCH = "search"; - private static final String EXTRAS_KEYWORD = "keyword"; - private static final String EXTRAS_LIST_TYPE = "type"; - private static final String EXTRAS_COORDS = "coords"; private static final int MAX_LIST_ITEMS = 1000; private static final int MENU_REFRESH_STORED = 2; private static final int MENU_CACHE_DETAILS = 4; @@ -114,7 +108,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity private Geopoint coords = null; private SearchResult search = null; /** The list of shown caches shared with Adapter. Don't manipulate outside of main thread only with Handler */ - private final List<cgCache> cacheList = new ArrayList<cgCache>(); + private final List<Geocache> cacheList = new ArrayList<Geocache>(); private CacheListAdapter adapter = null; private LayoutInflater inflater = null; private View listFooter = null; @@ -287,11 +281,15 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity private void replaceCacheListFromSearch() { if (search != null) { - final Set<cgCache> cachesFromSearchResult = search.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); runOnUiThread(new Runnable() { @Override public void run() { cacheList.clear(); + + // The database search was moved into the UI call intentionally. If this is done before the runOnUIThread, + // then we have 2 sets of caches in memory. This can lead to OOM for huge cache lists. + final Set<Geocache> cachesFromSearchResult = search.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); + cacheList.addAll(cachesFromSearchResult); adapter.reFilter(); updateTitle(); @@ -345,7 +343,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity startGeoAndDir(); } else { if (search != null) { - final Set<cgCache> cacheListTmp = search.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); + final Set<Geocache> cacheListTmp = search.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); if (CollectionUtils.isNotEmpty(cacheListTmp)) { cacheList.clear(); cacheList.addAll(cacheListTmp); @@ -455,9 +453,9 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity // get parameters Bundle extras = getIntent().getExtras(); if (extras != null) { - Object typeObject = extras.get(EXTRAS_LIST_TYPE); + Object typeObject = extras.get(Intents.EXTRA_LIST_TYPE); type = (typeObject instanceof CacheListType) ? (CacheListType) typeObject : CacheListType.OFFLINE; - coords = (Geopoint) extras.getParcelable(EXTRAS_COORDS); + coords = (Geopoint) extras.getParcelable(Intents.EXTRAS_COORDS); } else { extras = new Bundle(); @@ -480,7 +478,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity Thread threadPure; AbstractSearchThread thread; - final String username = extras.getString(EXTRAS_USERNAME); + final String username = extras.getString(Intents.EXTRA_USERNAME); switch (type) { case OFFLINE: listId = Settings.getLastList(); @@ -532,7 +530,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity thread.start(); break; case KEYWORD: - final String keyword = extras.getString(EXTRAS_KEYWORD); + final String keyword = extras.getString(Intents.EXTRA_KEYWORD); title = keyword; setTitle(title); showProgress(true); @@ -543,7 +541,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity thread.start(); break; case ADDRESS: - final String address = extras.getString(EXTRAS_ADDRESS); + final String address = extras.getString(Intents.EXTRA_ADDRESS); if (StringUtils.isNotBlank(address)) { title = address; } else { @@ -586,7 +584,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity title = res.getString(R.string.map_map); setTitle(title); showProgress(true); - search = (SearchResult) extras.get(EXTRAS_SEARCH); + search = (SearchResult) extras.get(Intents.EXTRA_SEARCH); replaceCacheListFromSearch(); loadCachesHandler.sendMessage(Message.obtain()); break; @@ -804,7 +802,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity } private boolean containsEvents() { - for (cgCache cache : adapter.getCheckedOrAllCaches()) { + for (Geocache cache : adapter.getCheckedOrAllCaches()) { if (cache.isEventCache()) { return true; } @@ -834,7 +832,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity invalidateOptionsMenuCompatible(); return true; case MENU_REFRESH_STORED: - refreshStored(); + refreshStored(adapter.getCheckedOrAllCaches()); invalidateOptionsMenuCompatible(); return true; case MENU_DROP_CACHES: @@ -904,8 +902,8 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity public void deletePastEvents() { progress.show(this, null, res.getString(R.string.caches_drop_progress), true, dropDetailsHandler.obtainMessage(MSG_CANCEL)); - final List<cgCache> deletion = new ArrayList<cgCache>(); - for (cgCache cache : adapter.getCheckedOrAllCaches()) { + final List<Geocache> deletion = new ArrayList<Geocache>(); + for (Geocache cache : adapter.getCheckedOrAllCaches()) { if (cache.isEventCache()) { final Date eventDate = cache.getHiddenDate(); if (DateUtils.daysSince(eventDate.getTime()) > 0) { @@ -953,7 +951,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity if (adapterInfo == null || adapterInfo.position >= adapter.getCount()) { return; } - final cgCache cache = adapter.getItem(adapterInfo.position); + final Geocache cache = adapter.getItem(adapterInfo.position); menu.setHeaderTitle(StringUtils.defaultIfBlank(cache.getName(), cache.getGeocode())); @@ -1006,7 +1004,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity Log.w("cgeocaches.onContextItemSelected", e); } - final cgCache cache = adapterInfo != null ? getCacheFromAdapter(adapterInfo) : null; + final Geocache cache = adapterInfo != null ? getCacheFromAdapter(adapterInfo) : null; // just in case the list got resorted while we are executing this code if (cache == null) { @@ -1023,8 +1021,8 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity break; case MENU_CACHE_DETAILS: final Intent cachesIntent = new Intent(this, CacheDetailActivity.class); - cachesIntent.putExtra("geocode", cache.getGeocode()); - cachesIntent.putExtra("name", cache.getName()); + cachesIntent.putExtra(Intents.EXTRA_GEOCODE, cache.getGeocode()); + cachesIntent.putExtra(Intents.EXTRA_NAME, cache.getName()); startActivity(cachesIntent); break; case MENU_DROP_CACHE: @@ -1048,8 +1046,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity }, true, listId); break; case MENU_STORE_CACHE: - //FIXME: this must use the same handler like in the CacheDetailActivity. Will be done by moving the handler into the store method. - cache.store(null); + refreshStored(Collections.singletonList(cache)); break; case MENU_EXPORT: ExportFactory.showExportMenu(Collections.singletonList(cache), this); @@ -1072,8 +1069,8 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity * an adapterInfo * @return the pointed cache */ - private cgCache getCacheFromAdapter(final AdapterContextMenuInfo adapterInfo) { - final cgCache cache = adapter.getItem(adapterInfo.position); + private Geocache getCacheFromAdapter(final AdapterContextMenuInfo adapterInfo) { + final Geocache cache = adapter.getItem(adapterInfo.position); if (cache.getGeocode().equalsIgnoreCase(contextMenuGeocode)) { return cache; } @@ -1181,8 +1178,27 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity refreshCurrentList(); } - public void refreshStored() { - detailTotal = adapter.getCheckedOrAllCount(); + public void refreshStored(final List<Geocache> caches) { + detailTotal = caches.size(); + if (detailTotal == 0) { + return; + } + + if (Settings.getChooseList() && type != CacheListType.OFFLINE) { + // let user select list to store cache in + new StoredList.UserInterface(this).promptForListSelection(R.string.list_title, + new RunnableWithArgument<Integer>() { + @Override + public void run(final Integer selectedListId) { + refreshStored(caches, selectedListId); + } + }, true, StoredList.TEMPORARY_LIST_ID); + } else { + refreshStored(caches, this.listId); + } + } + + private void refreshStored(final List<Geocache> caches, final int storeListId) { detailProgress = 0; showProgress(false); @@ -1200,7 +1216,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity detailProgressTime = System.currentTimeMillis(); - threadDetails = new LoadDetailsThread(loadDetailsHandler, listId); + threadDetails = new LoadDetailsThread(loadDetailsHandler, caches, storeListId); threadDetails.start(); } @@ -1419,11 +1435,11 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity final private int listIdLD; private volatile boolean needToStop = false; private long last = 0L; - final private List<cgCache> selected; + final private List<Geocache> caches; - public LoadDetailsThread(Handler handlerIn, int listId) { + public LoadDetailsThread(Handler handlerIn, List<Geocache> caches, int listId) { handler = handlerIn; - selected = adapter.getCheckedOrAllCaches(); + this.caches = caches; // in case of online lists, set the list id to the standard list this.listIdLD = Math.max(listId, StoredList.STANDARD_LIST_ID); @@ -1437,8 +1453,8 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity public void run() { removeGeoAndDir(); - final List<cgCache> cachesWithStaticMaps = new ArrayList<cgCache>(selected.size()); - for (cgCache cache : selected) { + final List<Geocache> cachesWithStaticMaps = new ArrayList<Geocache>(this.caches.size()); + for (Geocache cache : this.caches) { if (Settings.isStoreOfflineMaps() && cache.hasStaticMap()) { cachesWithStaticMaps.add(cache); continue; @@ -1450,7 +1466,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity } } - for (cgCache cache : cachesWithStaticMaps) { + for (Geocache cache : cachesWithStaticMaps) { if (!refreshCache(cache)) { break; } @@ -1468,7 +1484,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity * @return * <code>false</code> if the storing was interrupted, <code>true</code> otherwise */ - private boolean refreshCache(cgCache cache) { + private boolean refreshCache(Geocache cache) { try { if (needToStop) { throw new InterruptedException("Stopped storing process."); @@ -1550,7 +1566,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity handler.sendMessage(handler.obtainMessage(1, response)); yield(); - cgCache.storeCache(null, response, listIdLFW, false, null); + Geocache.storeCache(null, response, listIdLFW, false, null); handler.sendMessage(handler.obtainMessage(2, response)); yield(); @@ -1596,9 +1612,9 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity private class DropDetailsThread extends Thread { final private Handler handler; - final private List<cgCache> selected; + final private List<Geocache> selected; - public DropDetailsThread(Handler handlerIn, List<cgCache> selectedIn) { + public DropDetailsThread(Handler handlerIn, List<Geocache> selectedIn) { handler = handlerIn; selected = selectedIn; } @@ -1616,7 +1632,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity private class RemoveFromHistoryThread extends Thread { final private Handler handler; - final private List<cgCache> selected; + final private List<Geocache> selected; public RemoveFromHistoryThread(Handler handlerIn) { handler = handlerIn; @@ -1717,7 +1733,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity @Override public void run() { - final List<cgCache> caches = adapter.getCheckedCaches(); + final List<Geocache> caches = adapter.getCheckedCaches(); cgData.moveToList(caches, listId); handler.sendEmptyMessage(listId); } @@ -1789,7 +1805,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity // apply filter settings (if there's a filter) Set<String> geocodes = new HashSet<String>(); - for (cgCache cache : adapter.getFilteredList()) { + for (Geocache cache : adapter.getFilteredList()) { geocodes.add(cache.getGeocode()); } @@ -1823,7 +1839,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity public static void startActivityOffline(final Context context) { final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.OFFLINE); + cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.OFFLINE); context.startActivity(cachesIntent); } @@ -1832,8 +1848,8 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity return; } final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.OWNER); - cachesIntent.putExtra(EXTRAS_USERNAME, userName); + cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.OWNER); + cachesIntent.putExtra(Intents.EXTRA_USERNAME, userName); context.startActivity(cachesIntent); } @@ -1850,8 +1866,8 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity return; } final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.USERNAME); - cachesIntent.putExtra(EXTRAS_USERNAME, userName); + cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.USERNAME); + cachesIntent.putExtra(Intents.EXTRA_USERNAME, userName); context.startActivity(cachesIntent); } @@ -1879,7 +1895,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity private void setDateComparatorForEventList() { if (CollectionUtils.isNotEmpty(cacheList)) { boolean eventsOnly = true; - for (cgCache cache : cacheList) { + for (Geocache cache : cacheList) { if (!cache.isEventCache()) { eventsOnly = false; break; @@ -1902,22 +1918,22 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity return; } final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.NEAREST); - cachesIntent.putExtra(EXTRAS_COORDS, coordsNow); + cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.NEAREST); + cachesIntent.putExtra(Intents.EXTRAS_COORDS, coordsNow); context.startActivity(cachesIntent); } public static void startActivityHistory(Context context) { final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.HISTORY); + cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.HISTORY); context.startActivity(cachesIntent); } public static void startActivityAddress(final Context context, final Geopoint coords, final String address) { final Intent addressIntent = new Intent(context, cgeocaches.class); - addressIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.ADDRESS); - addressIntent.putExtra(EXTRAS_COORDS, coords); - addressIntent.putExtra(EXTRAS_ADDRESS, address); + addressIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.ADDRESS); + addressIntent.putExtra(Intents.EXTRAS_COORDS, coords); + addressIntent.putExtra(Intents.EXTRA_ADDRESS, address); context.startActivity(addressIntent); } @@ -1926,8 +1942,8 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity return; } final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.COORDINATE); - cachesIntent.putExtra(EXTRAS_COORDS, coords); + cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.COORDINATE); + cachesIntent.putExtra(Intents.EXTRAS_COORDS, coords); context.startActivity(cachesIntent); } @@ -1945,15 +1961,15 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity return; } final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.KEYWORD); - cachesIntent.putExtra(EXTRAS_KEYWORD, keyword); + cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.KEYWORD); + cachesIntent.putExtra(Intents.EXTRA_KEYWORD, keyword); context.startActivity(cachesIntent); } public static void startActivityMap(final Context context, final SearchResult search) { final Intent cachesIntent = new Intent(context, cgeocaches.class); - cachesIntent.putExtra(EXTRAS_LIST_TYPE, CacheListType.MAP); - cachesIntent.putExtra(EXTRAS_SEARCH, search); + cachesIntent.putExtra(Intents.EXTRA_LIST_TYPE, CacheListType.MAP); + cachesIntent.putExtra(Intents.EXTRA_SEARCH, search); context.startActivity(cachesIntent); } } diff --git a/main/src/cgeo/geocaching/cgeogpxes.java b/main/src/cgeo/geocaching/cgeogpxes.java index 909263f..d512618 100644 --- a/main/src/cgeo/geocaching/cgeogpxes.java +++ b/main/src/cgeo/geocaching/cgeogpxes.java @@ -10,21 +10,17 @@ import org.apache.commons.lang3.StringUtils; import android.app.Activity;
import android.content.Intent;
-import android.os.Bundle;
import java.io.File;
import java.util.Collections;
import java.util.List;
public class cgeogpxes extends FileList<GPXListAdapter> {
- private static final String EXTRAS_LIST_ID = "list";
public cgeogpxes() {
super(new String[] { "gpx", "loc", "zip" });
}
- private int listId = StoredList.STANDARD_LIST_ID;
-
@Override
protected GPXListAdapter getAdapter(List<File> files) {
return new GPXListAdapter(this, files);
@@ -36,26 +32,13 @@ public class cgeogpxes extends FileList<GPXListAdapter> { }
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- final Bundle extras = getIntent().getExtras();
- if (extras != null) {
- listId = extras.getInt(EXTRAS_LIST_ID);
- }
- if (listId <= StoredList.TEMPORARY_LIST_ID) {
- listId = StoredList.STANDARD_LIST_ID;
- }
- }
-
- @Override
protected void setTitle() {
setTitle(res.getString(R.string.gpx_import_title));
}
public static void startSubActivity(Activity fromActivity, int listId) {
final Intent intent = new Intent(fromActivity, cgeogpxes.class);
- intent.putExtra(EXTRAS_LIST_ID, listId);
+ intent.putExtra(Intents.EXTRA_LIST_ID, listId);
fromActivity.startActivityForResult(intent, 0);
}
diff --git a/main/src/cgeo/geocaching/cgeopoint.java b/main/src/cgeo/geocaching/cgeopoint.java index e399a97..9fb1905 100644 --- a/main/src/cgeo/geocaching/cgeopoint.java +++ b/main/src/cgeo/geocaching/cgeopoint.java @@ -6,6 +6,7 @@ import cgeo.geocaching.geopoint.DistanceParser; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; import cgeo.geocaching.ui.Formatter; +import cgeo.geocaching.ui.dialog.CoordinatesInputDialog; import cgeo.geocaching.utils.GeoDirHandler; import cgeo.geocaching.utils.Log; @@ -290,9 +291,9 @@ public class cgeopoint extends AbstractActivity { if (latButton.getText().length() > 0 && lonButton.getText().length() > 0) { gp = new Geopoint(latButton.getText().toString() + " " + lonButton.getText().toString()); } - cgeocoords coordsDialog = new cgeocoords(cgeopoint.this, null, gp, app.currentGeo()); + CoordinatesInputDialog coordsDialog = new CoordinatesInputDialog(cgeopoint.this, null, gp, app.currentGeo()); coordsDialog.setCancelable(true); - coordsDialog.setOnCoordinateUpdate(new cgeocoords.CoordinateUpdate() { + coordsDialog.setOnCoordinateUpdate(new CoordinatesInputDialog.CoordinateUpdate() { @Override public void update(Geopoint gp) { latButton.setText(gp.format(GeopointFormatter.Format.LAT_DECMINUTE)); diff --git a/main/src/cgeo/geocaching/connector/AbstractConnector.java b/main/src/cgeo/geocaching/connector/AbstractConnector.java index 9604b5f..1eb8fbb 100644 --- a/main/src/cgeo/geocaching/connector/AbstractConnector.java +++ b/main/src/cgeo/geocaching/connector/AbstractConnector.java @@ -1,6 +1,6 @@ package cgeo.geocaching.connector; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.enumerations.CacheRealm; import cgeo.geocaching.geopoint.Geopoint; @@ -31,7 +31,7 @@ public abstract class AbstractConnector implements IConnector { * @return success */ @Override - public boolean uploadModifiedCoordinates(cgCache cache, Geopoint wpt) { + public boolean uploadModifiedCoordinates(Geocache cache, Geopoint wpt) { throw new UnsupportedOperationException(); } @@ -39,7 +39,7 @@ public abstract class AbstractConnector implements IConnector { * {@link IConnector} */ @Override - public boolean deleteModifiedCoordinates(cgCache cache) { + public boolean deleteModifiedCoordinates(Geocache cache) { throw new UnsupportedOperationException(); } @@ -54,7 +54,7 @@ public abstract class AbstractConnector implements IConnector { } @Override - public String getLicenseText(final cgCache cache) { + public String getLicenseText(final Geocache cache) { return null; } diff --git a/main/src/cgeo/geocaching/connector/ConnectorFactory.java b/main/src/cgeo/geocaching/connector/ConnectorFactory.java index 6c8b7d9..561bae2 100644 --- a/main/src/cgeo/geocaching/connector/ConnectorFactory.java +++ b/main/src/cgeo/geocaching/connector/ConnectorFactory.java @@ -48,7 +48,7 @@ public final class ConnectorFactory { vpConns.add((ISearchByViewPort) conn); } } - searchByViewPortConns = vpConns.toArray(new ISearchByViewPort[] {}); + searchByViewPortConns = vpConns.toArray(new ISearchByViewPort[vpConns.size()]); List<ISearchByCenter> centerConns = new ArrayList<ISearchByCenter>(); for (IConnector conn : connectors) { @@ -57,7 +57,7 @@ public final class ConnectorFactory { centerConns.add((ISearchByCenter) conn); } } - searchByCenterConns = centerConns.toArray(new ISearchByCenter[] {}); + searchByCenterConns = centerConns.toArray(new ISearchByCenter[centerConns.size()]); } public static IConnector[] getConnectors() { diff --git a/main/src/cgeo/geocaching/connector/GeocachingAustraliaConnector.java b/main/src/cgeo/geocaching/connector/GeocachingAustraliaConnector.java index 30d1a4b..ac2fb37 100644 --- a/main/src/cgeo/geocaching/connector/GeocachingAustraliaConnector.java +++ b/main/src/cgeo/geocaching/connector/GeocachingAustraliaConnector.java @@ -1,6 +1,7 @@ package cgeo.geocaching.connector; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; +import cgeo.geocaching.ICache; import org.apache.commons.lang3.StringUtils; @@ -12,7 +13,7 @@ public class GeocachingAustraliaConnector extends AbstractConnector { } @Override - public String getCacheUrl(final cgCache cache) { + public String getCacheUrl(final Geocache cache) { return getCacheUrlPrefix() + cache.getGeocode(); } @@ -22,6 +23,11 @@ public class GeocachingAustraliaConnector extends AbstractConnector { } @Override + public boolean isOwner(final ICache cache) { + return false; + } + + @Override public boolean canHandle(final String geocode) { return (StringUtils.startsWithIgnoreCase(geocode, "GA") || StringUtils.startsWithIgnoreCase(geocode, "TP")) && isNumericId(geocode.substring(2)); } diff --git a/main/src/cgeo/geocaching/connector/GeopeitusConnector.java b/main/src/cgeo/geocaching/connector/GeopeitusConnector.java index 6ef91db..500f752 100644 --- a/main/src/cgeo/geocaching/connector/GeopeitusConnector.java +++ b/main/src/cgeo/geocaching/connector/GeopeitusConnector.java @@ -1,6 +1,7 @@ package cgeo.geocaching.connector; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; +import cgeo.geocaching.ICache; import org.apache.commons.lang3.StringUtils; @@ -12,7 +13,7 @@ public class GeopeitusConnector extends AbstractConnector { } @Override - public String getCacheUrl(final cgCache cache) { + public String getCacheUrl(final Geocache cache) { return getCacheUrlPrefix() + StringUtils.stripStart(cache.getGeocode().substring(2), "0"); } @@ -22,6 +23,11 @@ public class GeopeitusConnector extends AbstractConnector { } @Override + public boolean isOwner(final ICache cache) { + return false; + } + + @Override public boolean canHandle(String geocode) { return StringUtils.startsWith(geocode, "GE") && isNumericId(geocode.substring(2)); } diff --git a/main/src/cgeo/geocaching/connector/IConnector.java b/main/src/cgeo/geocaching/connector/IConnector.java index 2944bed..da626f2 100644 --- a/main/src/cgeo/geocaching/connector/IConnector.java +++ b/main/src/cgeo/geocaching/connector/IConnector.java @@ -1,6 +1,7 @@ package cgeo.geocaching.connector; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.ICache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.enumerations.CacheRealm; import cgeo.geocaching.geopoint.Geopoint; @@ -26,7 +27,7 @@ public interface IConnector { * @param cache * @return */ - public String getCacheUrl(final cgCache cache); + public String getCacheUrl(final Geocache cache); /** * enable/disable watchlist controls in cache details @@ -62,7 +63,7 @@ public interface IConnector { * @param cache * @return */ - public String getLicenseText(final cgCache cache); + public String getLicenseText(final Geocache cache); /** * enable/disable user actions in cache details @@ -117,7 +118,7 @@ public interface IConnector { * @param wpt * @return success */ - public boolean uploadModifiedCoordinates(cgCache cache, Geopoint wpt); + public boolean uploadModifiedCoordinates(Geocache cache, Geopoint wpt); /** * Reseting of modified coordinates on website to details @@ -125,7 +126,7 @@ public interface IConnector { * @param cache * @return success */ - public boolean deleteModifiedCoordinates(cgCache cache); + public boolean deleteModifiedCoordinates(Geocache cache); /** * The CacheRealm this cache belongs to @@ -140,5 +141,14 @@ public interface IConnector { * * @return */ + public boolean isActivated(); + + /** + * Check if the current user is the owner of the given cache. + * + * @param cache a cache that this connector must be able to handle + * @return <code>true</code> if the current user is the cache owner, <code>false</code> otherwise + */ + public boolean isOwner(final ICache cache); } diff --git a/main/src/cgeo/geocaching/connector/UnknownConnector.java b/main/src/cgeo/geocaching/connector/UnknownConnector.java index 991d31c..b6fc29a 100644 --- a/main/src/cgeo/geocaching/connector/UnknownConnector.java +++ b/main/src/cgeo/geocaching/connector/UnknownConnector.java @@ -1,6 +1,7 @@ package cgeo.geocaching.connector; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.ICache; +import cgeo.geocaching.Geocache; import org.apache.commons.lang3.StringUtils; @@ -12,7 +13,7 @@ public class UnknownConnector extends AbstractConnector { } @Override - public String getCacheUrl(cgCache cache) { + public String getCacheUrl(Geocache cache) { return null; // we have no url for these caches } @@ -22,6 +23,11 @@ public class UnknownConnector extends AbstractConnector { } @Override + public boolean isOwner(final ICache cache) { + return false; + } + + @Override public boolean canHandle(final String geocode) { return StringUtils.isNotBlank(geocode); } diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java index 8943835..2a38bd9 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java @@ -1,8 +1,10 @@ package cgeo.geocaching.connector.gc; +import cgeo.geocaching.Geocache; +import cgeo.geocaching.ICache; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Settings; import cgeo.geocaching.cgData; import cgeo.geocaching.connector.AbstractConnector; import cgeo.geocaching.connector.capability.ISearchByCenter; @@ -49,7 +51,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, } @Override - public String getCacheUrl(cgCache cache) { + public String getCacheUrl(Geocache cache) { // it would also be possible to use "http://www.geocaching.com/seek/cache_details.aspx?wp=" + cache.getGeocode(); return "http://www.geocaching.com//seek/cache_details.aspx?wp=" + cache.getGeocode(); } @@ -135,7 +137,13 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, return cacheHasReliableLatLon; } - public static boolean addToWatchlist(cgCache cache) { + @Override + public boolean isOwner(final ICache cache) { + return StringUtils.equalsIgnoreCase(cache.getOwnerUserId(), Settings.getUsername()); + + } + + public static boolean addToWatchlist(Geocache cache) { final boolean added = GCParser.addToWatchlist(cache); if (added) { cgData.saveChangedCache(cache); @@ -143,7 +151,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, return added; } - public static boolean removeFromWatchlist(cgCache cache) { + public static boolean removeFromWatchlist(Geocache cache) { final boolean removed = GCParser.removeFromWatchlist(cache); if (removed) { cgData.saveChangedCache(cache); @@ -160,7 +168,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, * @return <code>true</code> if the cache was sucessfully added, <code>false</code> otherwise */ - public static boolean addToFavorites(cgCache cache) { + public static boolean addToFavorites(Geocache cache) { final boolean added = GCParser.addToFavorites(cache); if (added) { cgData.saveChangedCache(cache); @@ -177,7 +185,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, * @return <code>true</code> if the cache was sucessfully added, <code>false</code> otherwise */ - public static boolean removeFromFavorites(cgCache cache) { + public static boolean removeFromFavorites(Geocache cache) { final boolean removed = GCParser.removeFromFavorites(cache); if (removed) { cgData.saveChangedCache(cache); @@ -186,7 +194,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, } @Override - public boolean uploadModifiedCoordinates(cgCache cache, Geopoint wpt) { + public boolean uploadModifiedCoordinates(Geocache cache, Geopoint wpt) { final boolean uploaded = GCParser.uploadModifiedCoordinates(cache, wpt); if (uploaded) { cgData.saveChangedCache(cache); @@ -195,7 +203,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, } @Override - public boolean deleteModifiedCoordinates(cgCache cache) { + public boolean deleteModifiedCoordinates(Geocache cache) { final boolean deleted = GCParser.deleteModifiedCoordinates(cache); if (deleted) { cgData.saveChangedCache(cache); diff --git a/main/src/cgeo/geocaching/connector/gc/GCConstants.java b/main/src/cgeo/geocaching/connector/gc/GCConstants.java index e67f6a8..8660ec4 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCConstants.java +++ b/main/src/cgeo/geocaching/connector/gc/GCConstants.java @@ -68,7 +68,7 @@ public final class GCConstants { public static final String MEMBER_STATUS_RENEW = "<a id=\"ctl00_hlRenew"; public static final String MEMBER_STATUS_PM = "Premium Member"; /** Use replaceAll("[,.]","") on the resulting string before converting to an int */ - public static final Pattern PATTERN_CACHES_FOUND = Pattern.compile("<strong style=\"display:block\">.*?([\\d,.]+) Caches Found"); + public static final Pattern PATTERN_CACHES_FOUND = Pattern.compile("<strong[^>]*>.*?([\\d,.]+) Caches Found"); public static final Pattern PATTERN_AVATAR_IMAGE_PROFILE_PAGE = Pattern.compile("<img src=\"(http://img.geocaching.com/user/avatar/[0-9a-f-]+\\.jpg)\"[^>]*\\salt=\"Avatar\""); public static final Pattern PATTERN_LOGIN_NAME_LOGIN_PAGE = Pattern.compile("<h4>Success:</h4> <p>You are logged in as[^<]*<strong><span id=\"ctl00_ContentBody_lbUsername\"[^>]*>([^<]+)[^<]*</span>"); public static final Pattern PATTERN_CUSTOMDATE = Pattern.compile("<option selected=\"selected\" value=\"([ /Mdy-]+)\">"); diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java index 9a8123d..2e1dff0 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCMap.java +++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java @@ -2,7 +2,7 @@ package cgeo.geocaching.connector.gc; import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheSize; @@ -68,7 +68,7 @@ public class GCMap { } for (int j = 0; j < dataArray.length(); j++) { - final cgCache cache = new cgCache(); + final Geocache cache = new Geocache(); JSONObject dataObject = dataArray.getJSONObject(j); cache.setName(dataObject.getString("name")); @@ -202,7 +202,7 @@ public class GCMap { String id = entry.getKey(); List<UTFGridPosition> pos = entry.getValue(); UTFGridPosition xy = UTFGrid.getPositionInGrid(pos); - cgCache cache = new cgCache(); + Geocache cache = new Geocache(); cache.setDetailed(false); cache.setReliableLatLon(false); cache.setGeocode(id); @@ -220,13 +220,13 @@ public class GCMap { } boolean exclude = false; - if (Settings.isExcludeMyCaches() && (cache.isFound() || cache.isOwn())) { // workaround for BM + if (Settings.isExcludeMyCaches() && (cache.isFound() || cache.isOwner())) { // workaround for BM exclude = true; } if (Settings.isExcludeDisabledCaches() && cache.isDisabled()) { exclude = true; } - if (Settings.getCacheType() != CacheType.ALL && Settings.getCacheType() != cache.getType() && cache.getType() != CacheType.UNKNOWN) { // workaround for BM + if (!Settings.getCacheType().contains(cache) && cache.getType() != CacheType.UNKNOWN) { // workaround for BM exclude = true; } if (!exclude) { diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java index e8de993..23102c9 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCParser.java +++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java @@ -1,5 +1,6 @@ package cgeo.geocaching.connector.gc; +import cgeo.geocaching.Geocache; import cgeo.geocaching.Image; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; @@ -8,7 +9,6 @@ import cgeo.geocaching.Settings; import cgeo.geocaching.Trackable; import cgeo.geocaching.TrackableLog; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheSize; @@ -30,7 +30,6 @@ import cgeo.geocaching.ui.DirectionImage; import cgeo.geocaching.utils.BaseUtils; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.HtmlUtils; -import cgeo.geocaching.utils.LazyInitializedList; import cgeo.geocaching.utils.Log; import cgeo.geocaching.utils.MatcherWrapper; @@ -122,7 +121,7 @@ public abstract class GCParser { final int rows_count = rows.length; for (int z = 1; z < rows_count; z++) { - final cgCache cache = new cgCache(); + final Geocache cache = new Geocache(); String row = rows[z]; // check for cache type presence @@ -203,9 +202,6 @@ public abstract class GCParser { // found it cache.setFound(row.contains("/images/icons/16/found.png")); - // own it - cache.setOwn(row.contains("/images/icons/16/placed.png")); - // id String result = BaseUtils.getMatch(row, GCConstants.PATTERN_SEARCH_ID, null); if (null != result) { @@ -293,8 +289,8 @@ public abstract class GCParser { // get direction images if (Settings.getLoadDirImg()) { - final Set<cgCache> caches = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); - for (cgCache cache : caches) { + final Set<Geocache> caches = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); + for (Geocache cache : caches) { if (cache.getCoords() == null && StringUtils.isNotEmpty(cache.getDirectionImg())) { DirectionImage.getDrawable(cache.getGeocode(), cache.getDirectionImg()); } @@ -307,7 +303,7 @@ public abstract class GCParser { static SearchResult parseCache(final String page, final CancellableHandler handler) { final SearchResult searchResult = parseCacheFromText(page, handler); if (searchResult != null && !searchResult.getGeocodes().isEmpty()) { - final cgCache cache = searchResult.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = searchResult.getFirstCacheFromResult(LoadFlags.LOAD_CACHE_OR_DB); getExtraOnlineInfo(cache, page, handler); cache.setDetailedUpdatedNow(); if (CancellableHandler.isCancelled(handler)) { @@ -351,7 +347,7 @@ public abstract class GCParser { return searchResult; } - final cgCache cache = new cgCache(); + final Geocache cache = new Geocache(); cache.setDisabled(page.contains(GCConstants.STRING_DISABLED)); cache.setArchived(page.contains(GCConstants.STRING_ARCHIVED)); @@ -375,8 +371,6 @@ public abstract class GCParser { // owner real name cache.setOwnerUserId(Network.decode(BaseUtils.getMatch(page, GCConstants.PATTERN_OWNER_USERID, true, cache.getOwnerUserId()))); - cache.setOwn(StringUtils.equalsIgnoreCase(cache.getOwnerUserId(), Settings.getUsername())); - cache.setUserModifiedCoords(false); String tableInside = page; @@ -463,10 +457,10 @@ public abstract class GCParser { cache.setOnWatchlist(BaseUtils.matches(page, GCConstants.PATTERN_WATCHLIST)); // latitude and longitude. Can only be retrieved if user is logged in - cache.setLatlon(BaseUtils.getMatch(page, GCConstants.PATTERN_LATLON, true, cache.getLatlon())); - if (StringUtils.isNotEmpty(cache.getLatlon())) { + String latlon = BaseUtils.getMatch(page, GCConstants.PATTERN_LATLON, true, ""); + if (StringUtils.isNotEmpty(latlon)) { try { - cache.setCoords(new Geopoint(cache.getLatlon())); + cache.setCoords(new Geopoint(latlon)); cache.setReliableLatLon(true); } catch (Geopoint.GeopointException e) { Log.w("GCParser.parseCache: Failed to parse cache coordinates", e); @@ -474,7 +468,7 @@ public abstract class GCParser { } // cache location - cache.setLocation(BaseUtils.getMatch(page, GCConstants.PATTERN_LOCATION, true, cache.getLocation())); + cache.setLocation(BaseUtils.getMatch(page, GCConstants.PATTERN_LOCATION, true, "")); // cache hint String result = BaseUtils.getMatch(page, GCConstants.PATTERN_HINT, false, null); @@ -492,7 +486,7 @@ public abstract class GCParser { cache.setPersonalNote(BaseUtils.getMatch(page, GCConstants.PATTERN_PERSONALNOTE, true, cache.getPersonalNote())); // cache short description - cache.setShortdesc(BaseUtils.getMatch(page, GCConstants.PATTERN_SHORTDESC, true, cache.getShortdesc())); + cache.setShortDescription(BaseUtils.getMatch(page, GCConstants.PATTERN_SHORTDESC, true, "")); // cache description cache.setDescription(BaseUtils.getMatch(page, GCConstants.PATTERN_DESC, true, "")); @@ -674,7 +668,7 @@ public abstract class GCParser { waypoint.setLookup(BaseUtils.getMatch(wp[5], GCConstants.PATTERN_WPPREFIXORLOOKUPORLATLON, true, 2, waypoint.getLookup(), false)); // waypoint latitude and logitude - String latlon = Html.fromHtml(BaseUtils.getMatch(wp[7], GCConstants.PATTERN_WPPREFIXORLOOKUPORLATLON, false, 2, "", false)).toString().trim(); + latlon = Html.fromHtml(BaseUtils.getMatch(wp[7], GCConstants.PATTERN_WPPREFIXORLOOKUPORLATLON, false, 2, "", false)).toString().trim(); if (!StringUtils.startsWith(latlon, "???")) { waypoint.setLatlon(latlon); waypoint.setCoords(new Geopoint(latlon)); @@ -752,7 +746,7 @@ public abstract class GCParser { } // search results don't need to be filtered so load GCVote ratings here - GCVote.loadRatings(new ArrayList<cgCache>(searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB))); + GCVote.loadRatings(new ArrayList<Geocache>(searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB))); // save to application search.setError(searchResult.getError()); @@ -1199,7 +1193,7 @@ public abstract class GCParser { * the cache to add * @return <code>false</code> if an error occurred, <code>true</code> otherwise */ - static boolean addToWatchlist(final cgCache cache) { + static boolean addToWatchlist(final Geocache cache) { final String uri = "http://www.geocaching.com/my/watchlist.aspx?w=" + cache.getCacheId(); String page = Login.postRequestLogged(uri, null); @@ -1225,7 +1219,7 @@ public abstract class GCParser { * the cache to remove * @return <code>false</code> if an error occurred, <code>true</code> otherwise */ - static boolean removeFromWatchlist(final cgCache cache) { + static boolean removeFromWatchlist(final Geocache cache) { final String uri = "http://www.geocaching.com/my/watchlist.aspx?ds=1&action=rem&id=" + cache.getCacheId(); String page = Login.postRequestLogged(uri, null); @@ -1274,11 +1268,11 @@ public abstract class GCParser { * the cache to add * @return <code>false</code> if an error occurred, <code>true</code> otherwise */ - static boolean addToFavorites(final cgCache cache) { + static boolean addToFavorites(final Geocache cache) { return changeFavorite(cache, true); } - private static boolean changeFavorite(final cgCache cache, final boolean add) { + private static boolean changeFavorite(final Geocache cache, final boolean add) { final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0"); final String userToken = BaseUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, ""); if (StringUtils.isEmpty(userToken)) { @@ -1308,7 +1302,7 @@ public abstract class GCParser { * the cache to remove * @return <code>false</code> if an error occurred, <code>true</code> otherwise */ - static boolean removeFromFavorites(final cgCache cache) { + static boolean removeFromFavorites(final Geocache cache) { return changeFavorite(cache, false); } @@ -1510,7 +1504,7 @@ public abstract class GCParser { * @param friends * retrieve friend logs */ - private static List<LogEntry> loadLogsFromDetails(final String page, final cgCache cache, final boolean friends, final boolean getDataFromPage) { + private static List<LogEntry> loadLogsFromDetails(final String page, final Geocache cache, final boolean friends, final boolean getDataFromPage) { String rawResponse; if (!getDataFromPage) { @@ -1697,7 +1691,7 @@ public abstract class GCParser { params.put("tx", cacheType.guid); } - private static void getExtraOnlineInfo(final cgCache cache, final String page, final CancellableHandler handler) { + private static void getExtraOnlineInfo(final Geocache cache, final String page, final CancellableHandler handler) { if (CancellableHandler.isCancelled(handler)) { return; } @@ -1705,7 +1699,7 @@ public abstract class GCParser { //cache.setLogs(loadLogsFromDetails(page, cache, false)); if (Settings.isFriendLogsWanted()) { CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_logs); - LazyInitializedList<LogEntry> allLogs = cache.getLogs(); + List<LogEntry> allLogs = cache.getLogs(); List<LogEntry> friendLogs = loadLogsFromDetails(page, cache, true, false); if (friendLogs != null) { for (LogEntry log : friendLogs) { @@ -1742,15 +1736,15 @@ public abstract class GCParser { } } - public static boolean uploadModifiedCoordinates(cgCache cache, Geopoint wpt) { + public static boolean uploadModifiedCoordinates(Geocache cache, Geopoint wpt) { return editModifiedCoordinates(cache, wpt); } - public static boolean deleteModifiedCoordinates(cgCache cache) { + public static boolean deleteModifiedCoordinates(Geocache cache) { return editModifiedCoordinates(cache, null); } - public static boolean editModifiedCoordinates(cgCache cache, Geopoint wpt) { + public static boolean editModifiedCoordinates(Geocache cache, Geopoint wpt) { final String page = requestHtmlPage(cache.getGeocode(), null, "n", "0"); final String userToken = BaseUtils.getMatch(page, GCConstants.PATTERN_USERTOKEN, ""); if (StringUtils.isEmpty(userToken)) { diff --git a/main/src/cgeo/geocaching/connector/gc/IconDecoder.java b/main/src/cgeo/geocaching/connector/gc/IconDecoder.java index 9c28048..98bd28a 100644 --- a/main/src/cgeo/geocaching/connector/gc/IconDecoder.java +++ b/main/src/cgeo/geocaching/connector/gc/IconDecoder.java @@ -1,6 +1,7 @@ package cgeo.geocaching.connector.gc; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Settings; +import cgeo.geocaching.Geocache; import cgeo.geocaching.enumerations.CacheType; import android.graphics.Bitmap; @@ -24,7 +25,7 @@ public abstract class IconDecoder { private static final int CT_VIRTUAL = 11; private static final int CT_LETTERBOX = 12; - public static boolean parseMapPNG(final cgCache cache, Bitmap bitmap, UTFGridPosition xy, int zoomlevel) { + public static boolean parseMapPNG(final Geocache cache, Bitmap bitmap, UTFGridPosition xy, int zoomlevel) { final int topX = xy.getX() * 4; final int topY = xy.getY() * 4; final int bitmapWidth = bitmap.getWidth(); @@ -105,7 +106,7 @@ public abstract class IconDecoder { cache.setFound(true); return true; case CT_OWN: - cache.setOwn(true); + cache.setOwnerUserId(Settings.getUsername()); return true; case CT_MEGAEVENT: cache.setType(CacheType.MEGA_EVENT); diff --git a/main/src/cgeo/geocaching/connector/gc/Login.java b/main/src/cgeo/geocaching/connector/gc/Login.java index 9a60f65..85b5272 100644 --- a/main/src/cgeo/geocaching/connector/gc/Login.java +++ b/main/src/cgeo/geocaching/connector/gc/Login.java @@ -132,6 +132,11 @@ public abstract class Login { return StatusCode.WRONG_LOGIN_DATA; // wrong login } + if (loginData.contains("You must validate your account before you can log in.")) { + Log.i("Failed to log in Geocaching.com as " + login.left + " because account needs to be validated first"); + return StatusCode.UNVALIDATED_ACCOUNT; + } + Log.i("Failed to log in Geocaching.com as " + login.left + " for some unknown reason"); if (retry) { Login.switchToEnglish(loginData); diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java index 73ded4d..0e5ffe7 100644 --- a/main/src/cgeo/geocaching/connector/gc/Tile.java +++ b/main/src/cgeo/geocaching/connector/gc/Tile.java @@ -53,11 +53,15 @@ public class Tile { private final Viewport viewPort; public Tile(Geopoint origin, int zoomlevel) { + this(calcX(origin, clippedZoomlevel(zoomlevel)), calcY(origin, clippedZoomlevel(zoomlevel)), clippedZoomlevel(zoomlevel)); + } + + private Tile(int tileX, int tileY, int zoomlevel) { - this.zoomlevel = Math.max(Math.min(zoomlevel, ZOOMLEVEL_MAX), ZOOMLEVEL_MIN); + this.zoomlevel = clippedZoomlevel(zoomlevel); - tileX = calcX(origin); - tileY = calcY(origin); + this.tileX = tileX; + this.tileY = tileY; viewPort = new Viewport(getCoord(new UTFGridPosition(0, 0)), getCoord(new UTFGridPosition(63, 63))); } @@ -66,28 +70,34 @@ public class Tile { return zoomlevel; } + private static int clippedZoomlevel(int zoomlevel) { + return Math.max(Math.min(zoomlevel, ZOOMLEVEL_MAX), ZOOMLEVEL_MIN); + } + /** * Calculate the tile for a Geopoint based on the Spherical Mercator. * * @see <a * href="http://developers.cloudmade.com/projects/tiles/examples/convert-coordinates-to-tile-numbers">Cloudmade</a> */ - private int calcX(final Geopoint origin) { - return (int) ((origin.getLongitude() + 180.0) / 360.0 * NUMBER_OF_TILES[this.zoomlevel]); + private static int calcX(final Geopoint origin, final int zoomlevel) { + // The cut of the fractional part instead of rounding to the nearest integer is intentional and part of the algorithm + return (int) ((origin.getLongitude() + 180.0) / 360.0 * NUMBER_OF_TILES[zoomlevel]); } /** * Calculate the tile for a Geopoint based on the Spherical Mercator. * */ - private int calcY(final Geopoint origin) { + private static int calcY(final Geopoint origin, final int zoomlevel) { // double latRad = Math.toRadians(origin.getLatitude()); // return (int) ((1 - (Math.log(Math.tan(latRad) + (1 / Math.cos(latRad))) / Math.PI)) / 2 * numberOfTiles); // Optimization from Bing double sinLatRad = Math.sin(Math.toRadians(origin.getLatitude())); - return (int) ((0.5 - Math.log((1 + sinLatRad) / (1 - sinLatRad)) / (4 * Math.PI)) * NUMBER_OF_TILES[this.zoomlevel]); + // The cut of the fractional part instead of rounding to the nearest integer is intentional and part of the algorithm + return (int) ((0.5 - Math.log((1 + sinLatRad) / (1 - sinLatRad)) / (4 * Math.PI)) * NUMBER_OF_TILES[zoomlevel]); } public int getX() { @@ -121,7 +131,12 @@ public class Tile { /** * Calculates the maximum possible zoom level where the supplied points - * are covered by adjacent tiles on the east/west axis. + * are covered by at least by the supplied number of + * adjacent tiles on the east/west axis. + * This criterion can be exactly met for even numbers of tiles + * while it may result in one more tile as requested for odd numbers + * of tiles. + * * The order of the points (left/right) is irrelevant. * * @param left @@ -130,17 +145,17 @@ public class Tile { * Second point * @return */ - public static int calcZoomLon(final Geopoint left, final Geopoint right) { + public static int calcZoomLon(final Geopoint left, final Geopoint right, final int numberOfTiles) { int zoom = (int) Math.floor( - Math.log(360.0 / Math.abs(left.getLongitude() - right.getLongitude())) + Math.log(360.0 * numberOfTiles / (2.0 * Math.abs(left.getLongitude() - right.getLongitude()))) / Math.log(2) ); Tile tileLeft = new Tile(left, zoom); Tile tileRight = new Tile(right, zoom); - if (tileLeft.tileX == tileRight.tileX) { + if (Math.abs(tileLeft.tileX - tileRight.tileX) < (numberOfTiles - 1)) { zoom += 1; } @@ -149,7 +164,12 @@ public class Tile { /** * Calculates the maximum possible zoom level where the supplied points - * are covered by adjacent tiles on the north/south axis. + * are covered by at least by the supplied number of + * adjacent tiles on the north/south axis. + * This criterion can be exactly met for even numbers of tiles + * while it may result in one more tile as requested for odd numbers + * of tiles. + * * The order of the points (bottom/top) is irrelevant. * * @param bottom @@ -158,21 +178,21 @@ public class Tile { * Second point * @return */ - public static int calcZoomLat(final Geopoint bottom, final Geopoint top) { + public static int calcZoomLat(final Geopoint bottom, final Geopoint top, final int numberOfTiles) { int zoom = (int) Math.ceil( - Math.log(2.0 * Math.PI / + Math.log(2.0 * Math.PI * numberOfTiles / ( Math.abs( asinh(tanGrad(bottom.getLatitude())) - asinh(tanGrad(top.getLatitude())) - ) + ) * 2.0) ) / Math.log(2) ); Tile tileBottom = new Tile(bottom, zoom); Tile tileTop = new Tile(top, zoom); - if (Math.abs(tileBottom.tileY - tileTop.tileY) > 1) { + if (Math.abs(tileBottom.tileY - tileTop.tileY) > (numberOfTiles - 1)) { zoom -= 1; } @@ -185,7 +205,7 @@ public class Tile { /** * Calculates the inverted hyperbolic sine - * (after Bronstein, Semendjajew: Taschenbuch der Mathematik + * (after Bronstein, Semendjajew: Taschenbuch der Mathematik) * * @param x * @return @@ -233,19 +253,48 @@ public class Tile { } /** - * Calculate needed tiles for the given viewport + * Calculate needed tiles for the given viewport to cover it with + * max 2x2 tiles * * @param viewport * @return */ protected static Set<Tile> getTilesForViewport(final Viewport viewport) { + return getTilesForViewport(viewport, 2, Tile.ZOOMLEVEL_MIN); + } + + /** + * Calculate needed tiles for the given viewport. + * You can define the minimum number of tiles on the longer axis + * and/or the minimum zoom level. + * + * @param viewport + * @param tilesOnAxis + * @param minZoom + * @return + */ + protected static Set<Tile> getTilesForViewport(final Viewport viewport, final int tilesOnAxis, final int minZoom) { Set<Tile> tiles = new HashSet<Tile>(); - int zoom = Math.min(Tile.calcZoomLon(viewport.bottomLeft, viewport.topRight), - Tile.calcZoomLat(viewport.bottomLeft, viewport.topRight)); - tiles.add(new Tile(viewport.bottomLeft, zoom)); - tiles.add(new Tile(new Geopoint(viewport.getLatitudeMin(), viewport.getLongitudeMax()), zoom)); - tiles.add(new Tile(new Geopoint(viewport.getLatitudeMax(), viewport.getLongitudeMin()), zoom)); - tiles.add(new Tile(viewport.topRight, zoom)); + int zoom = Math.max( + Math.min(Tile.calcZoomLon(viewport.bottomLeft, viewport.topRight, tilesOnAxis), + Tile.calcZoomLat(viewport.bottomLeft, viewport.topRight, tilesOnAxis)), + minZoom); + + Tile tileBottomLeft = new Tile(viewport.bottomLeft, zoom); + Tile tileTopRight = new Tile(viewport.topRight, zoom); + + int xLow = Math.min(tileBottomLeft.getX(), tileTopRight.getX()); + int xHigh = Math.max(tileBottomLeft.getX(), tileTopRight.getX()); + + int yLow = Math.min(tileBottomLeft.getY(), tileTopRight.getY()); + int yHigh = Math.max(tileBottomLeft.getY(), tileTopRight.getY()); + + for (int xNum = xLow; xNum <= xHigh; xNum++) { + for (int yNum = yLow; yNum <= yHigh; yNum++) { + tiles.add(new Tile(xNum, yNum, zoom)); + } + } + return tiles; } diff --git a/main/src/cgeo/geocaching/connector/oc/OC11XMLParser.java b/main/src/cgeo/geocaching/connector/oc/OC11XMLParser.java index 068ac88..6231c68 100644 --- a/main/src/cgeo/geocaching/connector/oc/OC11XMLParser.java +++ b/main/src/cgeo/geocaching/connector/oc/OC11XMLParser.java @@ -1,10 +1,15 @@ package cgeo.geocaching.connector.oc; +import cgeo.geocaching.Geocache; +import cgeo.geocaching.Image; import cgeo.geocaching.LogEntry; +import cgeo.geocaching.R; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; +import cgeo.geocaching.connector.gc.GCConnector; +import cgeo.geocaching.enumerations.CacheAttribute; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LogType; @@ -15,6 +20,7 @@ import org.apache.commons.lang3.StringUtils; import org.xml.sax.Attributes; import org.xml.sax.SAXException; +import android.content.res.Resources; import android.sax.Element; import android.sax.EndElementListener; import android.sax.EndTextElementListener; @@ -42,14 +48,18 @@ public class OC11XMLParser { private static Pattern STRIP_DATE = Pattern.compile("\\+0([0-9]){1}\\:00"); private static Pattern LOCAL_URL = Pattern.compile("href=\"(.*)\""); private static final int CACHE_PARSE_LIMIT = 250; + private static final Resources res = cgeoapplication.getInstance().getResources(); + + private static ImageHolder imageHolder = null; private static class CacheHolder { - public cgCache cache; + public Geocache cache; public String latitude; public String longitude; } private static class CacheLog { + public String id; public String cacheId; public LogEntry logEntry; } @@ -61,6 +71,13 @@ public class OC11XMLParser { public String hint; } + private static class ImageHolder { + public String url; + public String objectId; + protected String title; + protected boolean isSpoiler = false; + } + private static Date parseFullDate(final String date) { final SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); ISO8601DATEFORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); @@ -160,7 +177,7 @@ public class OC11XMLParser { } } - private static void setCacheStatus(final int statusId, final cgCache cache) { + private static void setCacheStatus(final int statusId, final Geocache cache) { switch (statusId) { case 1: cache.setArchived(false); @@ -178,7 +195,7 @@ public class OC11XMLParser { } private static void resetCache(final CacheHolder cacheHolder) { - cacheHolder.cache = new cgCache(null); + cacheHolder.cache = new Geocache(null); cacheHolder.cache.setReliableLatLon(true); cacheHolder.cache.setDescription(StringUtils.EMPTY); cacheHolder.latitude = "0.0"; @@ -197,9 +214,22 @@ public class OC11XMLParser { desc.hint = StringUtils.EMPTY; } - public static Collection<cgCache> parseCaches(final InputStream stream) throws IOException { + protected static int attributeId; + + public static Collection<Geocache> parseCaches(final InputStream stream) throws IOException { + // parse and return caches without filtering + return parseCaches(stream, true); + } + + public static Collection<Geocache> parseCachesFiltered(final InputStream stream) throws IOException { + // parse caches and filter result + return parseCaches(stream, false); + } + + private static Collection<Geocache> parseCaches(final InputStream stream, boolean ignoreFiltersIn) throws IOException { - final Map<String, cgCache> caches = new HashMap<String, cgCache>(); + final Map<String, Geocache> caches = new HashMap<String, Geocache>(); + final Map<String, LogEntry> logs = new HashMap<String, LogEntry>(); final CacheHolder cacheHolder = new CacheHolder(); final CacheLog logHolder = new CacheLog(); @@ -208,6 +238,8 @@ public class OC11XMLParser { final RootElement root = new RootElement("oc11xml"); final Element cacheNode = root.getChild("cache"); + final boolean ignoreFilters = ignoreFiltersIn; + // cache cacheNode.setStartElementListener(new StartElementListener() { @@ -222,17 +254,31 @@ public class OC11XMLParser { @Override public void end() { - cgCache cache = cacheHolder.cache; + Geocache cache = cacheHolder.cache; Geopoint coords = new Geopoint(cacheHolder.latitude, cacheHolder.longitude); - if (StringUtils.isNotBlank(cache.getGeocode()) - && !coords.equals(Geopoint.ZERO) - && !cache.isArchived() - && caches.size() < CACHE_PARSE_LIMIT) { - cache.setCoords(coords); + cache.setCoords(coords); + if (caches.size() < CACHE_PARSE_LIMIT && isValid(cache) && (ignoreFilters || !isExcluded(cache))) { cache.setDetailedUpdatedNow(); caches.put(cache.getCacheId(), cache); } } + + private boolean isExcluded(Geocache cache) { + if (cache.isArchived()) { + return true; + } + if (cache.isDisabled() && Settings.isExcludeDisabledCaches()) { + return true; + } + if ((cache.isFound() || cache.isOwner()) && Settings.isExcludeMyCaches()) { + return true; + } + return !Settings.getCacheType().contains(cache); + } + + private boolean isValid(Geocache cache) { + return StringUtils.isNotBlank(cache.getGeocode()) && !cache.getCoords().equals(Geopoint.ZERO); + } }); // cache.id @@ -289,7 +335,7 @@ public class OC11XMLParser { if (attrs.getIndex("gccom") > -1) { String gccode = attrs.getValue("gccom"); if (!StringUtils.isBlank(gccode)) { - cacheHolder.cache.setDescription(String.format("Listed on geocaching com: <a href=\"http://coord.info/%s\">%s</a><br /><br />", gccode, gccode)); + cacheHolder.cache.setDescription(res.getString(R.string.cache_listed_on, GCConnector.getInstance().getName()) + ": <a href=\"http://coord.info/" + gccode + "\">" + gccode + "</a><br /><br />"); } } } @@ -363,7 +409,7 @@ public class OC11XMLParser { } }); - // cache.terrain + // cache.datehidden cacheNode.getChild("datehidden").setEndTextElementListener(new EndTextElementListener() { @Override @@ -373,12 +419,56 @@ public class OC11XMLParser { } }); + // cache.userid + final Element useridNode = cacheNode.getChild("userid"); + + useridNode.setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attributes) { + if (attributes.getIndex("id") > -1) { + cacheHolder.cache.setOwnerUserId(attributes.getValue("id")); + } + } + }); + + useridNode.setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + cacheHolder.cache.setOwnerDisplayName(body); + } + }); + // cache.attributes.attribute - cacheNode.getChild("attributes").getChild("attribute").setEndTextElementListener(new EndTextElementListener() { + final Element attributeNode = cacheNode.getChild("attributes").getChild("attribute"); + + attributeNode.setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attributes) { + if (attributes.getIndex("id") > -1) { + try { + attributeId = Integer.parseInt(attributes.getValue("id")); + } catch (NumberFormatException e) { + Log.w(String.format("Failed to parse attribute id of cache '%s'.", cacheHolder.cache.getGeocode())); + } + } + } + }); + + attributeNode.setEndTextElementListener(new EndTextElementListener() { @Override public void end(String body) { - if (StringUtils.isNotBlank(body)) { - cacheHolder.cache.getAttributes().add(body.trim()); + CacheAttribute attribute = CacheAttribute.getByOcId(attributeId); + if (attribute != null) { + // semantic of attributes on opencaching is always "yes" + cacheHolder.cache.getAttributes().add(attribute.getAttributeName(true)); + } + else { + if (StringUtils.isNotBlank(body)) { + cacheHolder.cache.getAttributes().add(body.trim()); + } } } }); @@ -398,9 +488,9 @@ public class OC11XMLParser { @Override public void end() { - final cgCache cache = caches.get(descHolder.cacheId); + final Geocache cache = caches.get(descHolder.cacheId); if (cache != null) { - cache.setShortdesc(descHolder.shortDesc); + cache.setShortDescription(descHolder.shortDesc); cache.setDescription(cache.getDescription() + descHolder.desc); cache.setHint(descHolder.hint); } @@ -441,8 +531,7 @@ public class OC11XMLParser { @Override public void end(String body) { - final String content = body.trim(); - descHolder.hint = content; + descHolder.hint = body.trim(); } }); @@ -461,10 +550,11 @@ public class OC11XMLParser { @Override public void end() { - final cgCache cache = caches.get(logHolder.cacheId); + final Geocache cache = caches.get(logHolder.cacheId); if (cache != null && logHolder.logEntry.type != LogType.UNKNOWN) { - cache.getLogs().prepend(logHolder.logEntry); - if (logHolder.logEntry.type == LogType.FOUND_IT + logs.put(logHolder.id, logHolder.logEntry); + cache.getLogs().add(0, logHolder.logEntry); + if ((logHolder.logEntry.type == LogType.FOUND_IT || logHolder.logEntry.type == LogType.ATTENDED) && StringUtils.equalsIgnoreCase(logHolder.logEntry.author, Settings.getOCConnectorUserName())) { cache.setFound(true); cache.setVisitedDate(logHolder.logEntry.date); @@ -473,6 +563,15 @@ public class OC11XMLParser { } }); + // cachelog.id + cacheLog.getChild("id").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + logHolder.id = StringUtils.trim(body); + } + }); + // cachelog.cacheid cacheLog.getChild("cacheid").setEndTextElementListener(new EndTextElementListener() { @@ -530,6 +629,76 @@ public class OC11XMLParser { } }); + // pictures + final Element picture = root.getChild("picture"); + + picture.setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attrs) { + imageHolder = new ImageHolder(); + } + }); + + picture.setEndElementListener(new EndElementListener() { + + @Override + public void end() { + if (imageHolder.isSpoiler) { + final Geocache cache = caches.get(imageHolder.objectId); + if (cache != null) { + Image spoiler = new Image(imageHolder.url, imageHolder.title); + cache.addSpoiler(spoiler); + } + } + else { + final LogEntry log = logs.get(imageHolder.objectId); + if (log != null) { + log.addLogImage(new Image(imageHolder.url, imageHolder.title)); + } + } + } + }); + + // picture.object + picture.getChild("object").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + imageHolder.objectId = StringUtils.trim(body); + } + }); + + // picture.title + picture.getChild("title").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + imageHolder.title = StringUtils.trim(body); + } + }); + + // picture.url + picture.getChild("url").setEndTextElementListener(new EndTextElementListener() { + + @Override + public void end(String body) { + imageHolder.url = StringUtils.trim(body); + } + }); + + // picture.attributes + picture.getChild("attributes").setStartElementListener(new StartElementListener() { + + @Override + public void start(Attributes attributes) { + if (attributes.getIndex("spoiler") > -1) { + String spoiler = attributes.getValue("spoiler"); + imageHolder.isSpoiler = ("1".equals(spoiler)); + } + } + }); + try { Xml.parse(stream, Xml.Encoding.UTF_8, root.getContentHandler()); return caches.values(); @@ -539,6 +708,9 @@ public class OC11XMLParser { } } + /** + * Converts local links to absolute links targeting the OC website. + */ private static String linkify(String input) { String result = input; Matcher matcher = LOCAL_URL.matcher(result); @@ -561,8 +733,8 @@ public class OC11XMLParser { protected static String stripMarkup(String input) { if (StringUtils.startsWith(input, PARAGRAPH_BEGIN) && StringUtils.endsWith(input, PARAGRAPH_END)) { String inner = input.substring(PARAGRAPH_BEGIN.length(), input.length() - PARAGRAPH_END.length()); - if (inner.indexOf(PARAGRAPH_BEGIN) < 0) { - return inner; + if (!inner.contains(PARAGRAPH_BEGIN)) { + return inner.trim(); } } return input; diff --git a/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java b/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java index 74968e7..69cf8a4 100644 --- a/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java +++ b/main/src/cgeo/geocaching/connector/oc/OCApiConnector.java @@ -1,7 +1,7 @@ package cgeo.geocaching.connector.oc; +import cgeo.geocaching.Geocache; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgCache; import cgeo.geocaching.connector.capability.ISearchByGeocode; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.utils.CancellableHandler; @@ -21,14 +21,14 @@ public class OCApiConnector extends OCConnector implements ISearchByGeocode { } @Override - public String getLicenseText(final cgCache cache) { + public String getLicenseText(final Geocache cache) { // NOT TO BE TRANSLATED return "<a href=\"" + getCacheUrl(cache) + "\">" + getName() + "</a> data licensed under the Creative Commons BY-SA 3.0 License"; } @Override public SearchResult searchByGeocode(final String geocode, final String guid, final CancellableHandler handler) { - final cgCache cache = OkapiClient.getCache(geocode); + final Geocache cache = OkapiClient.getCache(geocode); if (cache == null) { return null; } diff --git a/main/src/cgeo/geocaching/connector/oc/OCConnector.java b/main/src/cgeo/geocaching/connector/oc/OCConnector.java index 24fd7d6..62dfb4c 100644 --- a/main/src/cgeo/geocaching/connector/oc/OCConnector.java +++ b/main/src/cgeo/geocaching/connector/oc/OCConnector.java @@ -1,6 +1,7 @@ package cgeo.geocaching.connector.oc; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; +import cgeo.geocaching.ICache; import cgeo.geocaching.connector.AbstractConnector; import cgeo.geocaching.enumerations.CacheRealm; @@ -33,7 +34,7 @@ public class OCConnector extends AbstractConnector { } @Override - public String getCacheUrl(cgCache cache) { + public String getCacheUrl(Geocache cache) { return getCacheUrlPrefix() + cache.getGeocode(); } @@ -48,6 +49,11 @@ public class OCConnector extends AbstractConnector { } @Override + public boolean isOwner(final ICache cache) { + return false; + } + + @Override protected String getCacheUrlPrefix() { return "http://" + host + "/viewcache.php?wp="; } diff --git a/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java b/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java index 3a2f42e..678654f 100644 --- a/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java +++ b/main/src/cgeo/geocaching/connector/oc/OCXMLApiConnector.java @@ -1,8 +1,9 @@ package cgeo.geocaching.connector.oc; +import cgeo.geocaching.Geocache; +import cgeo.geocaching.ICache; import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgCache; import cgeo.geocaching.connector.capability.ISearchByCenter; import cgeo.geocaching.connector.capability.ISearchByGeocode; import cgeo.geocaching.connector.capability.ISearchByViewPort; @@ -10,6 +11,8 @@ import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.Viewport; import cgeo.geocaching.utils.CancellableHandler; +import org.apache.commons.lang3.StringUtils; + public class OCXMLApiConnector extends OCConnector implements ISearchByGeocode, ISearchByCenter, ISearchByViewPort { private final static double SEARCH_DISTANCE_LIMIT = 15.0; @@ -21,7 +24,7 @@ public class OCXMLApiConnector extends OCConnector implements ISearchByGeocode, @Override public SearchResult searchByGeocode(final String geocode, final String guid, CancellableHandler handler) { - final cgCache cache = OCXMLClient.getCache(geocode); + final Geocache cache = OCXMLClient.getCache(geocode); if (cache == null) { return null; } @@ -49,4 +52,9 @@ public class OCXMLApiConnector extends OCConnector implements ISearchByGeocode, return Settings.isOCConnectorActive(); } + @Override + public boolean isOwner(ICache cache) { + return StringUtils.equalsIgnoreCase(cache.getOwnerDisplayName(), Settings.getOCConnectorUserName()); + } + } diff --git a/main/src/cgeo/geocaching/connector/oc/OCXMLClient.java b/main/src/cgeo/geocaching/connector/oc/OCXMLClient.java index 88ba5a1..6767b48 100644 --- a/main/src/cgeo/geocaching/connector/oc/OCXMLClient.java +++ b/main/src/cgeo/geocaching/connector/oc/OCXMLClient.java @@ -1,6 +1,6 @@ package cgeo.geocaching.connector.oc; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.cgData; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; @@ -29,9 +29,9 @@ public class OCXMLClient { // Url for single cache requests // http://www.opencaching.de/xml/ocxml11.php?modifiedsince=20060320000000&user=0&cache=1&cachedesc=1&cachelog=1&picture=1&removedobject=0&session=0&doctype=0&charset=utf-8&wp=OCC9BE - public static cgCache getCache(final String geoCode) { + public static Geocache getCache(final String geoCode) { try { - final Parameters params = getOCXmlQueryParameters(true, true); + final Parameters params = getOCXmlQueryParameters(true, true, true); params.put("wp", geoCode); final InputStream data = request(ConnectorFactory.getConnector(geoCode), SERVICE_CACHE, params); @@ -39,9 +39,9 @@ public class OCXMLClient { return null; } - Collection<cgCache> caches = OC11XMLParser.parseCaches(new GZIPInputStream(data)); + Collection<Geocache> caches = OC11XMLParser.parseCaches(new GZIPInputStream(data)); if (caches.iterator().hasNext()) { - cgCache cache = caches.iterator().next(); + Geocache cache = caches.iterator().next(); cgData.saveCache(cache, LoadFlags.SAVE_ALL); return cache; } @@ -52,9 +52,9 @@ public class OCXMLClient { } } - public static Collection<cgCache> getCachesAround(final Geopoint center, final double distance) { + public static Collection<Geocache> getCachesAround(final Geopoint center, final double distance) { try { - final Parameters params = getOCXmlQueryParameters(false, false); + final Parameters params = getOCXmlQueryParameters(false, false, false); params.put("lat", GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, center)); params.put("lon", GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, center)); params.put("distance", String.format(Locale.US, "%f", distance)); @@ -64,7 +64,7 @@ public class OCXMLClient { return Collections.emptyList(); } - return OC11XMLParser.parseCaches(new GZIPInputStream(data)); + return OC11XMLParser.parseCachesFiltered(new GZIPInputStream(data)); } catch (IOException e) { Log.e("Error parsing nearby search result", e); return Collections.emptyList(); @@ -98,11 +98,18 @@ public class OCXMLClient { return null; } - private static Parameters getOCXmlQueryParameters(final boolean withDescription, final boolean withLogs) { - final Parameters params = new Parameters("modifiedsince", "20060320000000", - "user", "0", "cache", "1", "cachedesc", withDescription ? "1" : "0", - "cachelog", withLogs ? "1" : "0", "picture", "0", "removedobject", "0", - "session", "0", "doctype", "0", "charset", "utf-8", "zip", "gzip"); - return params; + private static Parameters getOCXmlQueryParameters(final boolean withDescription, final boolean withLogs, final boolean withImages) { + return new Parameters("modifiedsince", "20000101000000", + "user", "0", + "cache", "1", + "cachedesc", withDescription ? "1" : "0", + "cachelog", withLogs ? "1" : "0", + "picture", withImages ? "1" : "0", + "removedobject", "0", + "session", "0", + "doctype", "0", + "charset", "utf-8", + "zip", "gzip", + "picturefromcachelog", withImages ? "1" : "0"); } } diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java index 508d0b5..dbcfea5 100644 --- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java +++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java @@ -1,8 +1,8 @@ package cgeo.geocaching.connector.oc; +import cgeo.geocaching.Geocache; import cgeo.geocaching.Image; import cgeo.geocaching.LogEntry; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgData; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; @@ -68,7 +68,7 @@ final public class OkapiClient { private static final String SERVICE_NEAREST = "/okapi/services/caches/search/nearest"; - public static cgCache getCache(final String geoCode) { + public static Geocache getCache(final String geoCode) { final Parameters params = new Parameters("cache_code", geoCode, "fields", SERVICE_CACHE_FIELDS); final JSONObject data = request(ConnectorFactory.getConnector(geoCode), SERVICE_CACHE, params); @@ -79,7 +79,7 @@ final public class OkapiClient { return parseCache(data); } - public static List<cgCache> getCachesAround(final Geopoint center, IConnector connector) { + public static List<Geocache> getCachesAround(final Geopoint center, IConnector connector) { String centerString = GeopointFormatter.format(GeopointFormatter.Format.LAT_DECDEGREE_RAW, center) + "|" + GeopointFormatter.format(GeopointFormatter.Format.LON_DECDEGREE_RAW, center); final Parameters params = new Parameters("center", centerString); final JSONObject data = request(connector, SERVICE_NEAREST, params); @@ -91,7 +91,7 @@ final public class OkapiClient { return parseCaches(data); } - private static List<cgCache> parseCaches(final JSONObject response) { + private static List<Geocache> parseCaches(final JSONObject response) { try { final JSONArray cachesResponse = response.getJSONArray("results"); if (cachesResponse != null) { @@ -102,9 +102,9 @@ final public class OkapiClient { geocodes.add(geocode); } } - List<cgCache> caches = new ArrayList<cgCache>(geocodes.size()); + List<Geocache> caches = new ArrayList<Geocache>(geocodes.size()); for (String geocode : geocodes) { - cgCache cache = getCache(geocode); + Geocache cache = getCache(geocode); if (cache != null) { caches.add(cache); } @@ -117,8 +117,8 @@ final public class OkapiClient { return null; } - private static cgCache parseCache(final JSONObject response) { - final cgCache cache = new cgCache(); + private static Geocache parseCache(final JSONObject response) { + final Geocache cache = new Geocache(); cache.setReliableLatLon(true); try { cache.setGeocode(response.getString(CACHE_CODE)); @@ -235,7 +235,7 @@ final public class OkapiClient { return null; } - private static void setLocation(final cgCache cache, final String location) { + private static void setLocation(final Geocache cache, final String location) { final String latitude = StringUtils.substringBefore(location, "|"); final String longitude = StringUtils.substringAfter(location, "|"); cache.setCoords(new Geopoint(latitude, longitude)); diff --git a/main/src/cgeo/geocaching/connector/ox/OXConnector.java b/main/src/cgeo/geocaching/connector/ox/OXConnector.java index 98b1656..eec07e3 100644 --- a/main/src/cgeo/geocaching/connector/ox/OXConnector.java +++ b/main/src/cgeo/geocaching/connector/ox/OXConnector.java @@ -1,8 +1,9 @@ package cgeo.geocaching.connector.ox; +import cgeo.geocaching.Geocache; +import cgeo.geocaching.ICache; import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgCache; import cgeo.geocaching.connector.AbstractConnector; import cgeo.geocaching.connector.capability.ISearchByCenter; import cgeo.geocaching.connector.capability.ISearchByGeocode; @@ -26,7 +27,7 @@ public class OXConnector extends AbstractConnector implements ISearchByCenter, I } @Override - public String getCacheUrl(cgCache cache) { + public String getCacheUrl(Geocache cache) { return getCacheUrlPrefix() + cache.getGeocode(); } @@ -41,14 +42,19 @@ public class OXConnector extends AbstractConnector implements ISearchByCenter, I } @Override - public String getLicenseText(cgCache cache) { + public String getLicenseText(Geocache cache) { // NOT TO BE TRANSLATED return "<a href=\"" + getCacheUrl(cache) + "\">" + getName() + "</a> data licensed under the Creative Commons BY-SA 3.0 License"; } @Override + public boolean isOwner(final ICache cache) { + return false; + } + + @Override public SearchResult searchByGeocode(String geocode, String guid, CancellableHandler handler) { - final cgCache cache = OpenCachingApi.searchByGeoCode(geocode); + final Geocache cache = OpenCachingApi.searchByGeoCode(geocode); if (cache == null) { return null; } @@ -58,7 +64,7 @@ public class OXConnector extends AbstractConnector implements ISearchByCenter, I @Override public SearchResult searchByCenter(Geopoint center) { - Collection<cgCache> caches = OpenCachingApi.searchByCenter(center); + Collection<Geocache> caches = OpenCachingApi.searchByCenter(center); if (caches == null) { return null; } diff --git a/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java b/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java index 377785a..f40a3e8 100644 --- a/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java +++ b/main/src/cgeo/geocaching/connector/ox/OXGPXParser.java @@ -1,6 +1,6 @@ package cgeo.geocaching.connector.ox; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.files.GPX10Parser; public class OXGPXParser extends GPX10Parser { @@ -13,7 +13,7 @@ public class OXGPXParser extends GPX10Parser { } @Override - protected void afterParsing(cgCache cache) { + protected void afterParsing(Geocache cache) { cache.setUpdated(System.currentTimeMillis()); if (isDetailed) { cache.setDetailedUpdate(cache.getUpdated()); diff --git a/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java b/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java index 17be540..f25e289 100644 --- a/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java +++ b/main/src/cgeo/geocaching/connector/ox/OpenCachingApi.java @@ -1,7 +1,7 @@ package cgeo.geocaching.connector.ox; +import cgeo.geocaching.Geocache; import cgeo.geocaching.StoredList; -import cgeo.geocaching.cgCache; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.GeopointFormatter; import cgeo.geocaching.network.Network; @@ -20,25 +20,25 @@ public class OpenCachingApi { private static final String DEV_KEY = CryptUtils.rot13("PtqQnHo9RUTht3Np"); - public static cgCache searchByGeoCode(final String geocode) { + public static Geocache searchByGeoCode(final String geocode) { final HttpResponse response = Network.getRequest("http://www.opencaching.com/api/geocache/" + geocode + ".gpx", new Parameters( "Authorization", DEV_KEY, "log_limit", "30", "hint", "true", "description", "html")); - final Collection<cgCache> caches = importCachesFromResponse(response, true); + final Collection<Geocache> caches = importCachesFromResponse(response, true); if (CollectionUtils.isNotEmpty(caches)) { return caches.iterator().next(); } return null; } - private static Collection<cgCache> importCachesFromResponse(final HttpResponse response, final boolean isDetailed) { + private static Collection<Geocache> importCachesFromResponse(final HttpResponse response, final boolean isDetailed) { if (response == null) { return Collections.emptyList(); } - Collection<cgCache> caches; + Collection<Geocache> caches; try { caches = new OXGPXParser(StoredList.STANDARD_LIST_ID, isDetailed).parse(response.getEntity().getContent(), null); } catch (Exception e) { @@ -48,7 +48,7 @@ public class OpenCachingApi { return caches; } - public static Collection<cgCache> searchByCenter(final Geopoint center) { + public static Collection<Geocache> searchByCenter(final Geopoint center) { final HttpResponse response = Network.getRequest("http://www.opencaching.com/api/geocache/.gpx", new Parameters( "Authorization", DEV_KEY, diff --git a/main/src/cgeo/geocaching/enumerations/CacheAttribute.java b/main/src/cgeo/geocaching/enumerations/CacheAttribute.java index 01d76f5..530869f 100644 --- a/main/src/cgeo/geocaching/enumerations/CacheAttribute.java +++ b/main/src/cgeo/geocaching/enumerations/CacheAttribute.java @@ -5,124 +5,190 @@ import cgeo.geocaching.cgeoapplication; import org.apache.commons.lang3.StringUtils; +import android.util.SparseArray; + import java.util.Collections; import java.util.HashMap; import java.util.Map; - public enum CacheAttribute { - UNKNOWN(0, "unknown", R.drawable.attribute__strikethru, R.string.attribute_unknown_yes, R.string.attribute_unknown_no), - DOGS(1, "dogs", R.drawable.attribute_dogs, R.string.attribute_dogs_yes, R.string.attribute_dogs_no), - FEE(2, "fee", R.drawable.attribute_fee, R.string.attribute_fee_yes, R.string.attribute_fee_no), - RAPPELLING(3, "rappelling", R.drawable.attribute_rappelling, R.string.attribute_rappelling_yes, R.string.attribute_rappelling_no), - BOAT(4, "boat", R.drawable.attribute_boat, R.string.attribute_boat_yes, R.string.attribute_boat_no), - SCUBA(5, "scuba", R.drawable.attribute_scuba, R.string.attribute_scuba_yes, R.string.attribute_scuba_no), - KIDS(6, "kids", R.drawable.attribute_kids, R.string.attribute_kids_yes, R.string.attribute_kids_no), - ONEHOUR(7, "onehour", R.drawable.attribute_onehour, R.string.attribute_onehour_yes, R.string.attribute_onehour_no), - SCENIC(8, "scenic", R.drawable.attribute_scenic, R.string.attribute_scenic_yes, R.string.attribute_scenic_no), - HIKING(9, "hiking", R.drawable.attribute_hiking, R.string.attribute_hiking_yes, R.string.attribute_hiking_no), - CLIMBING(10, "climbing", R.drawable.attribute_climbing, R.string.attribute_climbing_yes, R.string.attribute_climbing_no), - WADING(11, "wading", R.drawable.attribute_wading, R.string.attribute_wading_yes, R.string.attribute_wading_no), - SWIMMING(12, "swimming", R.drawable.attribute_swimming, R.string.attribute_swimming_yes, R.string.attribute_swimming_no), - AVAILABLE(13, "available", R.drawable.attribute_available, R.string.attribute_available_yes, R.string.attribute_available_no), - NIGHT(14, "night", R.drawable.attribute_night, R.string.attribute_night_yes, R.string.attribute_night_no), - WINTER(15, "winter", R.drawable.attribute_winter, R.string.attribute_winter_yes, R.string.attribute_winter_no), - POISONOAK(17, "poisonoak", R.drawable.attribute_poisonoak, R.string.attribute_poisonoak_yes, R.string.attribute_poisonoak_no), - DANGEROUSANIMALS(18, "dangerousanimals", R.drawable.attribute_dangerousanimals, R.string.attribute_dangerousanimals_yes, R.string.attribute_dangerousanimals_no), - TICKS(19, "ticks", R.drawable.attribute_ticks, R.string.attribute_ticks_yes, R.string.attribute_ticks_no), - MINE(29, "mine", R.drawable.attribute_mine, R.string.attribute_mine_yes, R.string.attribute_mine_no), - CLIFF(21, "cliff", R.drawable.attribute_cliff, R.string.attribute_cliff_yes, R.string.attribute_cliff_no), - HUNTING(22, "hunting", R.drawable.attribute_hunting, R.string.attribute_hunting_yes, R.string.attribute_hunting_no), - DANGER(23, "danger", R.drawable.attribute_danger, R.string.attribute_danger_yes, R.string.attribute_danger_no), - WHEELCHAIR(24, "wheelchair", R.drawable.attribute_wheelchair, R.string.attribute_wheelchair_yes, R.string.attribute_wheelchair_no), - PARKING(25, "parking", R.drawable.attribute_parking, R.string.attribute_parking_yes, R.string.attribute_parking_no), - PUBLIC(26, "public", R.drawable.attribute_public, R.string.attribute_public_yes, R.string.attribute_public_no), - WATER(27, "water", R.drawable.attribute_water, R.string.attribute_water_yes, R.string.attribute_water_no), - RESTROOMS(28, "restrooms", R.drawable.attribute_restrooms, R.string.attribute_restrooms_yes, R.string.attribute_restrooms_no), - PHONE(29, "phone", R.drawable.attribute_phone, R.string.attribute_phone_yes, R.string.attribute_phone_no), - PICNIC(30, "picnic", R.drawable.attribute_picnic, R.string.attribute_picnic_yes, R.string.attribute_picnic_no), - CAMPING(31, "camping", R.drawable.attribute_camping, R.string.attribute_camping_yes, R.string.attribute_camping_no), - BICYCLES(32, "bicycles", R.drawable.attribute_bicycles, R.string.attribute_bicycles_yes, R.string.attribute_bicycles_no), - MOTORCYCLES(33, "motorcycles", R.drawable.attribute_motorcycles, R.string.attribute_motorcycles_yes, R.string.attribute_motorcycles_no), - QUADS(34, "quads", R.drawable.attribute_quads, R.string.attribute_quads_yes, R.string.attribute_quads_no), - JEEPS(35, "jeeps", R.drawable.attribute_jeeps, R.string.attribute_jeeps_yes, R.string.attribute_jeeps_no), - SNOWMOBILES(36, "snowmobiles", R.drawable.attribute_snowmobiles, R.string.attribute_snowmobiles_yes, R.string.attribute_snowmobiles_no), - HORSES(37, "horses", R.drawable.attribute_horses, R.string.attribute_horses_yes, R.string.attribute_horses_no), - CAMPFIRES(38, "campfires", R.drawable.attribute_campfires, R.string.attribute_campfires_yes, R.string.attribute_campfires_no), - THORN(39, "thorn", R.drawable.attribute_thorn, R.string.attribute_thorn_yes, R.string.attribute_thorn_no), - STEALTH(40, "stealth", R.drawable.attribute_stealth, R.string.attribute_stealth_yes, R.string.attribute_stealth_no), - STROLLER(41, "stroller", R.drawable.attribute_stroller, R.string.attribute_stroller_yes, R.string.attribute_stroller_no), - FIRSTAID(42, "firstaid", R.drawable.attribute_firstaid, R.string.attribute_firstaid_yes, R.string.attribute_firstaid_no), - COW(43, "cow", R.drawable.attribute_cow, R.string.attribute_cow_yes, R.string.attribute_cow_no), - FLASHLIGHT(44, "flashlight", R.drawable.attribute_flashlight, R.string.attribute_flashlight_yes, R.string.attribute_flashlight_no), - LANDF(45, "landf", R.drawable.attribute_landf, R.string.attribute_landf_yes, R.string.attribute_landf_no), - RV(46, "rv", R.drawable.attribute_rv, R.string.attribute_rv_yes, R.string.attribute_rv_no), - FIELD_PUZZLE(47, "field_puzzle", R.drawable.attribute_field_puzzle, R.string.attribute_field_puzzle_yes, R.string.attribute_field_puzzle_no), - UV(48, "uv", R.drawable.attribute_uv, R.string.attribute_uv_yes, R.string.attribute_uv_no), - SNOWSHOES(49, "snowshoes", R.drawable.attribute_snowshoes, R.string.attribute_snowshoes_yes, R.string.attribute_snowshoes_no), - SKIIS(50, "skiis", R.drawable.attribute_skiis, R.string.attribute_skiis_yes, R.string.attribute_skiis_no), - SPECIAL_TOOLS(51, "s_tool", R.drawable.attribute_s_tool, R.string.attribute_s_tool_yes, R.string.attribute_s_tool_no), - NIGHTCACHE(52, "nightcache", R.drawable.attribute_nightcache, R.string.attribute_nightcache_yes, R.string.attribute_nightcache_no), - PARKNGRAB(53, "parkngrab", R.drawable.attribute_parkngrab, R.string.attribute_parkngrab_yes, R.string.attribute_parkngrab_no), - ABANDONED_BUILDING(54, "abandonedbuilding", R.drawable.attribute_abandonedbuilding, R.string.attribute_abandonedbuilding_yes, R.string.attribute_abandonedbuilding_no), - HIKE_SHORT(55, "hike_short", R.drawable.attribute_hike_short, R.string.attribute_hike_short_yes, R.string.attribute_hike_short_no), - HIKE_MED(56, "hike_med", R.drawable.attribute_hike_med, R.string.attribute_hike_med_yes, R.string.attribute_hike_med_no), - HIKE_LONG(57, "hike_long", R.drawable.attribute_hike_long, R.string.attribute_hike_long_yes, R.string.attribute_hike_long_no), - FUEL(58, "fuel", R.drawable.attribute_fuel, R.string.attribute_fuel_yes, R.string.attribute_fuel_no), - FOOD(59, "food", R.drawable.attribute_food, R.string.attribute_food_yes, R.string.attribute_food_no), - WIRELESS_BEACON(60, "wirelessbeacon", R.drawable.attribute_wirelessbeacon, R.string.attribute_wirelessbeacon_yes, R.string.attribute_wirelessbeacon_no), - PARTNERSHIP(61, "partnership", R.drawable.attribute_partnership, R.string.attribute_partnership_yes, R.string.attribute_partnership_no), - SEASONAL(62, "seasonal", R.drawable.attribute_seasonal, R.string.attribute_seasonal_yes, R.string.attribute_seasonal_no), - TOURIST_OK(63, "touristok", R.drawable.attribute_touristok, R.string.attribute_touristok_yes, R.string.attribute_touristok_no), - TREECLIMBING(64, "treeclimbing", R.drawable.attribute_treeclimbing, R.string.attribute_treeclimbing_yes, R.string.attribute_treeclimbing_no), - FRONTYARD(65, "frontyard", R.drawable.attribute_frontyard, R.string.attribute_frontyard_yes, R.string.attribute_frontyard_no), - TEAMWORK(66, "teamwork", R.drawable.attribute_teamwork, R.string.attribute_teamwork_yes, R.string.attribute_teamwork_no); - - private static final String INTERNAL_PRE = "attribute_"; + // THIS LIST IS GENERATED: don't change anything here but in + // project/attributes/makeEnum.sh + DOGS(1, -1, "dogs", R.drawable.attribute_dogs, R.string.attribute_dogs_yes, R.string.attribute_dogs_no), + BICYCLES(32, -1, "bicycles", R.drawable.attribute_bicycles, R.string.attribute_bicycles_yes, R.string.attribute_bicycles_no), + MOTORCYCLES(33, -1, "motorcycles", R.drawable.attribute_motorcycles, R.string.attribute_motorcycles_yes, R.string.attribute_motorcycles_no), + QUADS(34, -1, "quads", R.drawable.attribute_quads, R.string.attribute_quads_yes, R.string.attribute_quads_no), + JEEPS(35, -1, "jeeps", R.drawable.attribute_jeeps, R.string.attribute_jeeps_yes, R.string.attribute_jeeps_no), + SNOWMOBILES(36, -1, "snowmobiles", R.drawable.attribute_snowmobiles, R.string.attribute_snowmobiles_yes, R.string.attribute_snowmobiles_no), + HORSES(37, -1, "horses", R.drawable.attribute_horses, R.string.attribute_horses_yes, R.string.attribute_horses_no), + CAMPFIRES(38, -1, "campfires", R.drawable.attribute_campfires, R.string.attribute_campfires_yes, R.string.attribute_campfires_no), + RV(46, -1, "rv", R.drawable.attribute_rv, R.string.attribute_rv_yes, R.string.attribute_rv_no), + KIDS(6, 59, "kids", R.drawable.attribute_kids, R.string.attribute_kids_yes, R.string.attribute_kids_no), + ONEHOUR(7, -1, "onehour", R.drawable.attribute_onehour, R.string.attribute_onehour_yes, R.string.attribute_onehour_no), + SCENIC(8, -1, "scenic", R.drawable.attribute_scenic, R.string.attribute_scenic_yes, R.string.attribute_scenic_no), + HIKING(9, 25, "hiking", R.drawable.attribute_hiking, R.string.attribute_hiking_yes, R.string.attribute_hiking_no), + CLIMBING(10, 28, "climbing", R.drawable.attribute_climbing, R.string.attribute_climbing_yes, R.string.attribute_climbing_no), + WADING(11, -1, "wading", R.drawable.attribute_wading, R.string.attribute_wading_yes, R.string.attribute_wading_no), + SWIMMING(12, 29, "swimming", R.drawable.attribute_swimming, R.string.attribute_swimming_yes, R.string.attribute_swimming_no), + AVAILABLE(13, 38, "available", R.drawable.attribute_available, R.string.attribute_available_yes, R.string.attribute_available_no), + NIGHT(14, -1, "night", R.drawable.attribute_night, R.string.attribute_night_yes, R.string.attribute_night_no), + WINTER(15, -1, "winter", R.drawable.attribute_winter, R.string.attribute_winter_yes, R.string.attribute_winter_no), + STEALTH(40, -1, "stealth", R.drawable.attribute_stealth, R.string.attribute_stealth_yes, R.string.attribute_stealth_no), + FIRSTAID(42, -1, "firstaid", R.drawable.attribute_firstaid, R.string.attribute_firstaid_yes, R.string.attribute_firstaid_no), + COW(43, -1, "cow", R.drawable.attribute_cow, R.string.attribute_cow_yes, R.string.attribute_cow_no), + FIELD_PUZZLE(47, -1, "field_puzzle", R.drawable.attribute_field_puzzle, R.string.attribute_field_puzzle_yes, R.string.attribute_field_puzzle_no), + NIGHTCACHE(52, 1, "nightcache", R.drawable.attribute_nightcache, R.string.attribute_nightcache_yes, R.string.attribute_nightcache_no), + PARKNGRAB(53, 24, "parkngrab", R.drawable.attribute_parkngrab, R.string.attribute_parkngrab_yes, R.string.attribute_parkngrab_no), + ABANDONEDBUILDING(54, -1, "abandonedbuilding", R.drawable.attribute_abandonedbuilding, R.string.attribute_abandonedbuilding_yes, R.string.attribute_abandonedbuilding_no), + HIKE_SHORT(55, -1, "hike_short", R.drawable.attribute_hike_short, R.string.attribute_hike_short_yes, R.string.attribute_hike_short_no), + HIKE_MED(56, -1, "hike_med", R.drawable.attribute_hike_med, R.string.attribute_hike_med_yes, R.string.attribute_hike_med_no), + HIKE_LONG(57, -1, "hike_long", R.drawable.attribute_hike_long, R.string.attribute_hike_long_yes, R.string.attribute_hike_long_no), + SEASONAL(62, 60, "seasonal", R.drawable.attribute_seasonal, R.string.attribute_seasonal_yes, R.string.attribute_seasonal_no), + TOURISTOK(63, -1, "touristok", R.drawable.attribute_touristok, R.string.attribute_touristok_yes, R.string.attribute_touristok_no), + FRONTYARD(65, -1, "frontyard", R.drawable.attribute_frontyard, R.string.attribute_frontyard_yes, R.string.attribute_frontyard_no), + TEAMWORK(66, -1, "teamwork", R.drawable.attribute_teamwork, R.string.attribute_teamwork_yes, R.string.attribute_teamwork_no), + LANDF(45, -1, "landf", R.drawable.attribute_landf, R.string.attribute_landf_yes, R.string.attribute_landf_no), + PARTNERSHIP(61, -1, "partnership", R.drawable.attribute_partnership, R.string.attribute_partnership_yes, R.string.attribute_partnership_no), + FEE(2, 36, "fee", R.drawable.attribute_fee, R.string.attribute_fee_yes, R.string.attribute_fee_no), + RAPPELLING(3, 49, "rappelling", R.drawable.attribute_rappelling, R.string.attribute_rappelling_yes, R.string.attribute_rappelling_no), + BOAT(4, 52, "boat", R.drawable.attribute_boat, R.string.attribute_boat_yes, R.string.attribute_boat_no), + SCUBA(5, 51, "scuba", R.drawable.attribute_scuba, R.string.attribute_scuba_yes, R.string.attribute_scuba_no), + FLASHLIGHT(44, 48, "flashlight", R.drawable.attribute_flashlight, R.string.attribute_flashlight_yes, R.string.attribute_flashlight_no), + UV(48, -1, "uv", R.drawable.attribute_uv, R.string.attribute_uv_yes, R.string.attribute_uv_no), + SNOWSHOES(49, -1, "snowshoes", R.drawable.attribute_snowshoes, R.string.attribute_snowshoes_yes, R.string.attribute_snowshoes_no), + SKIIS(50, -1, "skiis", R.drawable.attribute_skiis, R.string.attribute_skiis_yes, R.string.attribute_skiis_no), + S_TOOL(51, 46, "s_tool", R.drawable.attribute_s_tool, R.string.attribute_s_tool_yes, R.string.attribute_s_tool_no), + WIRELESSBEACON(60, -1, "wirelessbeacon", R.drawable.attribute_wirelessbeacon, R.string.attribute_wirelessbeacon_yes, R.string.attribute_wirelessbeacon_no), + TREECLIMBING(64, -1, "treeclimbing", R.drawable.attribute_treeclimbing, R.string.attribute_treeclimbing_yes, R.string.attribute_treeclimbing_no), + POISONOAK(17, 16, "poisonoak", R.drawable.attribute_poisonoak, R.string.attribute_poisonoak_yes, R.string.attribute_poisonoak_no), + DANGEROUSANIMALS(18, 17, "dangerousanimals", R.drawable.attribute_dangerousanimals, R.string.attribute_dangerousanimals_yes, R.string.attribute_dangerousanimals_no), + TICKS(19, 14, "ticks", R.drawable.attribute_ticks, R.string.attribute_ticks_yes, R.string.attribute_ticks_no), + MINE(20, 15, "mine", R.drawable.attribute_mine, R.string.attribute_mine_yes, R.string.attribute_mine_no), + CLIFF(21, 11, "cliff", R.drawable.attribute_cliff, R.string.attribute_cliff_yes, R.string.attribute_cliff_no), + HUNTING(22, 12, "hunting", R.drawable.attribute_hunting, R.string.attribute_hunting_yes, R.string.attribute_hunting_no), + DANGER(23, 9, "danger", R.drawable.attribute_danger, R.string.attribute_danger_yes, R.string.attribute_danger_no), + THORN(39, 13, "thorn", R.drawable.attribute_thorn, R.string.attribute_thorn_yes, R.string.attribute_thorn_no), + WHEELCHAIR(24, -1, "wheelchair", R.drawable.attribute_wheelchair, R.string.attribute_wheelchair_yes, R.string.attribute_wheelchair_no), + PARKING(25, 18, "parking", R.drawable.attribute_parking, R.string.attribute_parking_yes, R.string.attribute_parking_no), + PUBLIC(26, 19, "public", R.drawable.attribute_public, R.string.attribute_public_yes, R.string.attribute_public_no), + WATER(27, 20, "water", R.drawable.attribute_water, R.string.attribute_water_yes, R.string.attribute_water_no), + RESTROOMS(28, 21, "restrooms", R.drawable.attribute_restrooms, R.string.attribute_restrooms_yes, R.string.attribute_restrooms_no), + PHONE(29, 22, "phone", R.drawable.attribute_phone, R.string.attribute_phone_yes, R.string.attribute_phone_no), + PICNIC(30, -1, "picnic", R.drawable.attribute_picnic, R.string.attribute_picnic_yes, R.string.attribute_picnic_no), + CAMPING(31, -1, "camping", R.drawable.attribute_camping, R.string.attribute_camping_yes, R.string.attribute_camping_no), + STROLLER(41, -1, "stroller", R.drawable.attribute_stroller, R.string.attribute_stroller_yes, R.string.attribute_stroller_no), + FUEL(58, -1, "fuel", R.drawable.attribute_fuel, R.string.attribute_fuel_yes, R.string.attribute_fuel_no), + FOOD(59, -1, "food", R.drawable.attribute_food, R.string.attribute_food_yes, R.string.attribute_food_no), + OC_ONLY(-1, 6, "oc_only", R.drawable.attribute_oc_only, R.string.attribute_oc_only_yes, R.string.attribute_oc_only_no), + LINK_ONLY(-1, 7, "link_only", R.drawable.attribute_link_only, R.string.attribute_link_only_yes, R.string.attribute_link_only_no), + LETTERBOX(-1, 8, "letterbox", R.drawable.attribute_letterbox, R.string.attribute_letterbox_yes, R.string.attribute_letterbox_no), + RAILWAY(-1, 10, "railway", R.drawable.attribute_railway, R.string.attribute_railway_yes, R.string.attribute_railway_no), + SYRINGE(-1, 23, "syringe", R.drawable.attribute_syringe, R.string.attribute_syringe_yes, R.string.attribute_syringe_no), + SWAMP(-1, 26, "swamp", R.drawable.attribute_swamp, R.string.attribute_swamp_yes, R.string.attribute_swamp_no), + HILLS(-1, 27, "hills", R.drawable.attribute_hills, R.string.attribute_hills_yes, R.string.attribute_hills_no), + POI(-1, 30, "poi", R.drawable.attribute_poi, R.string.attribute_poi_yes, R.string.attribute_poi_no), + MOVING_TARGET(-1, 31, "moving_target", R.drawable.attribute_moving_target, R.string.attribute_moving_target_yes, R.string.attribute_moving_target_no), + WEBCAM(-1, 32, "webcam", R.drawable.attribute_webcam, R.string.attribute_webcam_yes, R.string.attribute_webcam_no), + INSIDE(-1, 33, "inside", R.drawable.attribute_inside, R.string.attribute_inside_yes, R.string.attribute_inside_no), + IN_WATER(-1, 34, "in_water", R.drawable.attribute_in_water, R.string.attribute_in_water_yes, R.string.attribute_in_water_no), + NO_GPS(-1, 35, "no_gps", R.drawable.attribute_no_gps, R.string.attribute_no_gps_yes, R.string.attribute_no_gps_no), + OVERNIGHT(-1, 37, "overnight", R.drawable.attribute_overnight, R.string.attribute_overnight_yes, R.string.attribute_overnight_no), + SPECIFIC_TIMES(-1, 39, "specific_times", R.drawable.attribute_specific_times, R.string.attribute_specific_times_yes, R.string.attribute_specific_times_no), + DAY(-1, 40, "day", R.drawable.attribute_day, R.string.attribute_day_yes, R.string.attribute_day_no), + TIDE(-1, 41, "tide", R.drawable.attribute_tide, R.string.attribute_tide_yes, R.string.attribute_tide_no), + ALL_SEASONS(-1, 42, "all_seasons", R.drawable.attribute_all_seasons, R.string.attribute_all_seasons_yes, R.string.attribute_all_seasons_no), + BREEDING(-1, 43, "breeding", R.drawable.attribute_breeding, R.string.attribute_breeding_yes, R.string.attribute_breeding_no), + SNOW_PROOF(-1, 44, "snow_proof", R.drawable.attribute_snow_proof, R.string.attribute_snow_proof_yes, R.string.attribute_snow_proof_no), + COMPASS(-1, 47, "compass", R.drawable.attribute_compass, R.string.attribute_compass_yes, R.string.attribute_compass_no), + CAVE(-1, 50, "cave", R.drawable.attribute_cave, R.string.attribute_cave_yes, R.string.attribute_cave_no), + AIRCRAFT(-1, 53, "aircraft", R.drawable.attribute_aircraft, R.string.attribute_aircraft_yes, R.string.attribute_aircraft_no), + INVESTIGATION(-1, 54, "investigation", R.drawable.attribute_investigation, R.string.attribute_investigation_yes, R.string.attribute_investigation_no), + PUZZLE(-1, 55, "puzzle", R.drawable.attribute_puzzle, R.string.attribute_puzzle_yes, R.string.attribute_puzzle_no), + ARITHMETIC(-1, 56, "arithmetic", R.drawable.attribute_arithmetic, R.string.attribute_arithmetic_yes, R.string.attribute_arithmetic_no), + OTHER_CACHE(-1, 57, "other_cache", R.drawable.attribute_other_cache, R.string.attribute_other_cache_yes, R.string.attribute_other_cache_no), + ASK_OWNER(-1, 58, "ask_owner", R.drawable.attribute_ask_owner, R.string.attribute_ask_owner_yes, R.string.attribute_ask_owner_no), + UNKNOWN(-1, -1, "unknown", R.drawable.attribute_unknown, R.string.attribute_unknown_yes, R.string.attribute_unknown_no); + // THIS LIST IS GENERATED: don't change anything here but in + // project/attributes/makeEnum.sh + private static final String INTERNAL_YES = "_yes"; private static final String INTERNAL_NO = "_no"; - public final int id; - public final String gcRawName; + public static final int NO_ID = -1; + + public final int gcid; + public final int ocid; + public final String rawName; public final int drawableId; public final int stringIdYes; public final int stringIdNo; - CacheAttribute(final int id, final String gcRawName, final int drawableId, final int stringIdYes, final int stringIdNo) { - this.id = id; - this.gcRawName = gcRawName; + CacheAttribute(final int gcid, final int ocid, final String rawName, + final int drawableId, final int stringIdYes, final int stringIdNo) { + this.gcid = gcid; + this.ocid = ocid; + this.rawName = rawName; this.drawableId = drawableId; this.stringIdYes = stringIdYes; this.stringIdNo = stringIdNo; } + /** + * get localized text + * + * @param enabled + * true: for positive text, false: for negative text + * @return the localized text + */ public String getL10n(final boolean enabled) { - return cgeoapplication.getInstance().getResources().getString(enabled ? stringIdYes : stringIdNo); + return cgeoapplication.getInstance().getResources().getString( + enabled ? stringIdYes : stringIdNo); } private final static Map<String, CacheAttribute> FIND_BY_GCRAWNAME; - static { final HashMap<String, CacheAttribute> mapGcRawNames = new HashMap<String, CacheAttribute>(); for (CacheAttribute attr : values()) { - mapGcRawNames.put(attr.gcRawName, attr); + mapGcRawNames.put(attr.rawName, attr); } FIND_BY_GCRAWNAME = Collections.unmodifiableMap(mapGcRawNames); } - public static CacheAttribute getByGcRawName(final String gcRawName) { - final CacheAttribute result = gcRawName != null ? FIND_BY_GCRAWNAME.get(gcRawName) : null; - if (result == null) { - return UNKNOWN; + private final static SparseArray<CacheAttribute> FIND_BY_GCID = new SparseArray<CacheAttribute>(); + static { + for (CacheAttribute attr : values()) { + if (attr.gcid != NO_ID) { + FIND_BY_GCID.put(attr.gcid, attr); + } + } + } + + private final static SparseArray<CacheAttribute> FIND_BY_OCID = new SparseArray<CacheAttribute>(); + static { + for (CacheAttribute attr : values()) { + if (attr.ocid != NO_ID) { + FIND_BY_OCID.put(attr.ocid, attr); + } } - return result; + } + + public static CacheAttribute getByRawName(final String rawName) { + return rawName != null ? FIND_BY_GCRAWNAME.get(rawName) : null; + } + + public static CacheAttribute getByGcId(final int gcid) { + return FIND_BY_GCID.get(gcid); + } + + public static CacheAttribute getByOcId(final int ocid) { + return FIND_BY_OCID.get(ocid); } public static String trimAttributeName(String attributeName) { if (null == attributeName) { return ""; } - return attributeName.replace(INTERNAL_PRE, "").replace(INTERNAL_YES, "").replace(INTERNAL_NO, "").trim(); + return attributeName.replace(INTERNAL_YES, "").replace(INTERNAL_NO, "").trim(); } public static boolean isEnabled(final String attributeName) { @@ -130,6 +196,6 @@ public enum CacheAttribute { } public String getAttributeName(final boolean yes) { - return gcRawName + (yes ? INTERNAL_YES : INTERNAL_NO); + return rawName + (yes ? INTERNAL_YES : INTERNAL_NO); } } diff --git a/main/src/cgeo/geocaching/enumerations/CacheType.java b/main/src/cgeo/geocaching/enumerations/CacheType.java index 88bded2..528d3fa 100644 --- a/main/src/cgeo/geocaching/enumerations/CacheType.java +++ b/main/src/cgeo/geocaching/enumerations/CacheType.java @@ -1,5 +1,6 @@ package cgeo.geocaching.enumerations; +import cgeo.geocaching.ICache; import cgeo.geocaching.R; import cgeo.geocaching.cgeoapplication; @@ -94,4 +95,20 @@ public enum CacheType { public String toString() { return getL10n(); } + + /** + * Whether this type contains the given cache. + * + * @param cache + * @return true if this is the ALL type or if this type equals the type of the cache. + */ + public boolean contains(ICache cache) { + if (cache == null) { + return false; + } + if (this == ALL) { + return true; + } + return cache.getType() == this; + } } diff --git a/main/src/cgeo/geocaching/enumerations/StatusCode.java b/main/src/cgeo/geocaching/enumerations/StatusCode.java index 1a1f05d..dc62225 100644 --- a/main/src/cgeo/geocaching/enumerations/StatusCode.java +++ b/main/src/cgeo/geocaching/enumerations/StatusCode.java @@ -16,6 +16,7 @@ public enum StatusCode { COMMUNICATION_ERROR(R.string.err_comm), WRONG_LOGIN_DATA(R.string.err_wrong), UNAPPROVED_LICENSE(R.string.err_license), + UNVALIDATED_ACCOUNT(R.string.err_unvalidated_account), UNPUBLISHED_CACHE(R.string.err_unpublished), PREMIUM_ONLY(R.string.err_premium_only), MAINTENANCE(R.string.err_maintenance), diff --git a/main/src/cgeo/geocaching/export/Export.java b/main/src/cgeo/geocaching/export/Export.java index 7a2b075..a1a873f 100644 --- a/main/src/cgeo/geocaching/export/Export.java +++ b/main/src/cgeo/geocaching/export/Export.java @@ -1,24 +1,24 @@ package cgeo.geocaching.export; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import android.app.Activity; import java.util.List; /** - * Represents an exporter to export a {@link List} of {@link cgCache} to various formats. + * Represents an exporter to export a {@link List} of {@link cgeo.geocaching.Geocache} to various formats. */ interface Export { /** - * Export a {@link List} of {@link cgCache} to various formats. + * Export a {@link List} of {@link cgeo.geocaching.Geocache} to various formats. * * @param caches - * The {@link List} of {@link cgCache} to be exported + * The {@link List} of {@link cgeo.geocaching.Geocache} to be exported * @param activity * optional: Some exporters might have an UI which requires an {@link Activity} */ - public void export(List<cgCache> caches, Activity activity); + public void export(List<Geocache> caches, Activity activity); /** * Get the localized name of this exporter. diff --git a/main/src/cgeo/geocaching/export/ExportFactory.java b/main/src/cgeo/geocaching/export/ExportFactory.java index d32a751..a3ecb0c 100644 --- a/main/src/cgeo/geocaching/export/ExportFactory.java +++ b/main/src/cgeo/geocaching/export/ExportFactory.java @@ -1,7 +1,7 @@ package cgeo.geocaching.export; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; import cgeo.geocaching.utils.Log; import android.app.Activity; @@ -34,11 +34,11 @@ public abstract class ExportFactory { * Creates a dialog so that the user can select an exporter. * * @param caches - * The {@link List} of {@link cgCache} to be exported + * The {@link List} of {@link cgeo.geocaching.Geocache} to be exported * @param activity * The {@link Activity} in whose context the dialog should be shown */ - public static void showExportMenu(final List<cgCache> caches, final Activity activity) { + public static void showExportMenu(final List<Geocache> caches, final Activity activity) { final AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(R.string.export).setIcon(R.drawable.ic_menu_share); diff --git a/main/src/cgeo/geocaching/export/FieldnoteExport.java b/main/src/cgeo/geocaching/export/FieldnoteExport.java index de78c22..5e1805a 100644 --- a/main/src/cgeo/geocaching/export/FieldnoteExport.java +++ b/main/src/cgeo/geocaching/export/FieldnoteExport.java @@ -1,11 +1,11 @@ package cgeo.geocaching.export; +import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; +import cgeo.geocaching.cgData; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.activity.Progress; -import cgeo.geocaching.cgCache; -import cgeo.geocaching.cgData; import cgeo.geocaching.connector.gc.Login; import cgeo.geocaching.enumerations.StatusCode; import cgeo.geocaching.network.Network; @@ -18,8 +18,11 @@ import org.apache.commons.lang3.StringUtils; import android.app.Activity; import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; import android.os.AsyncTask; import android.os.Environment; +import android.view.ContextThemeWrapper; import android.view.View; import android.widget.CheckBox; @@ -53,57 +56,54 @@ class FieldnoteExport extends AbstractExport { super(getString(R.string.export_fieldnotes)); } - /** - * A dialog to allow the user to set options for the export. - * - * Currently available options are: upload field notes, only new logs since last export/upload - */ - private class ExportOptionsDialog extends AlertDialog { - public ExportOptionsDialog(final List<cgCache> caches, final Activity activity) { - super(activity); - - View layout = activity.getLayoutInflater().inflate(R.layout.fieldnote_export_dialog, null); - setView(layout); - - final CheckBox uploadOption = (CheckBox) layout.findViewById(R.id.upload); - final CheckBox onlyNewOption = (CheckBox) layout.findViewById(R.id.onlynew); - - uploadOption.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onlyNewOption.setEnabled(uploadOption.isChecked()); - } - }); - - layout.findViewById(R.id.export).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - new ExportTask( - caches, - activity, - uploadOption.isChecked(), - onlyNewOption.isChecked()) - .execute((Void) null); - } - }); - } - } - @Override - public void export(final List<cgCache> caches, final Activity activity) { + public void export(final List<Geocache> caches, final Activity activity) { if (null == activity) { // No activity given, so no user interaction possible. // Start export with default parameters. new ExportTask(caches, null, false, false).execute((Void) null); } else { // Show configuration dialog - new ExportOptionsDialog(caches, activity).show(); + getExportOptionsDialog(caches, activity).show(); } } + private Dialog getExportOptionsDialog(final List<Geocache> caches, final Activity activity) { + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + + // AlertDialog has always dark style, so we have to apply it as well always + View layout = View.inflate(new ContextThemeWrapper(activity, R.style.dark), R.layout.fieldnote_export_dialog, null); + builder.setView(layout); + + final CheckBox uploadOption = (CheckBox) layout.findViewById(R.id.upload); + final CheckBox onlyNewOption = (CheckBox) layout.findViewById(R.id.onlynew); + + uploadOption.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onlyNewOption.setEnabled(uploadOption.isChecked()); + } + }); + + builder.setPositiveButton(R.string.export, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + new ExportTask( + caches, + activity, + uploadOption.isChecked(), + onlyNewOption.isChecked()) + .execute((Void) null); + } + }); + + return builder.create(); + } + private class ExportTask extends AsyncTask<Void, Integer, Boolean> { - private final List<cgCache> caches; + private final List<Geocache> caches; private final Activity activity; private final boolean upload; private final boolean onlyNew; @@ -116,7 +116,7 @@ class FieldnoteExport extends AbstractExport { * Instantiates and configurates the task for exporting field notes. * * @param caches - * The {@link List} of {@link cgCache} to be exported + * The {@link List} of {@link cgeo.geocaching.Geocache} to be exported * @param activity * optional: Show a progress bar and toasts * @param upload @@ -124,7 +124,7 @@ class FieldnoteExport extends AbstractExport { * @param onlyNew * Upload/export only new logs since last export */ - public ExportTask(final List<cgCache> caches, final Activity activity, final boolean upload, final boolean onlyNew) { + public ExportTask(final List<Geocache> caches, final Activity activity, final boolean upload, final boolean onlyNew) { this.caches = caches; this.activity = activity; this.upload = upload; @@ -143,7 +143,7 @@ class FieldnoteExport extends AbstractExport { final StringBuilder fieldNoteBuffer = new StringBuilder(); try { int i = 0; - for (cgCache cache : caches) { + for (Geocache cache : caches) { if (cache.isLogOffline()) { appendFieldNote(fieldNoteBuffer, cache, cgData.loadLogOffline(cache.getGeocode())); publishProgress(++i); @@ -259,7 +259,7 @@ class FieldnoteExport extends AbstractExport { } } - static void appendFieldNote(final StringBuilder fieldNoteBuffer, final cgCache cache, final LogEntry log) { + static void appendFieldNote(final StringBuilder fieldNoteBuffer, final Geocache cache, final LogEntry log) { fieldNoteBuffer.append(cache.getGeocode()) .append(',') .append(fieldNoteDateFormat.format(new Date(log.date))) diff --git a/main/src/cgeo/geocaching/export/GpxExport.java b/main/src/cgeo/geocaching/export/GpxExport.java index 9f6642f..74ee072 100644 --- a/main/src/cgeo/geocaching/export/GpxExport.java +++ b/main/src/cgeo/geocaching/export/GpxExport.java @@ -1,10 +1,10 @@ package cgeo.geocaching.export; +import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; import cgeo.geocaching.Settings; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgData; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.activity.Progress; @@ -13,26 +13,29 @@ import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.utils.BaseUtils; import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.XmlUtils; -import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; +import org.xmlpull.v1.XmlSerializer; import android.app.Activity; import android.app.AlertDialog; +import android.app.Dialog; import android.app.ProgressDialog; +import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Environment; +import android.util.Xml; +import android.view.ContextThemeWrapper; import android.view.View; import android.widget.CheckBox; import android.widget.TextView; -import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.io.Writer; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -41,13 +44,16 @@ import java.util.Locale; class GpxExport extends AbstractExport { private static final SimpleDateFormat dateFormatZ = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); + public static final String PREFIX_XSI = "http://www.w3.org/2001/XMLSchema-instance"; + public static final String PREFIX_GPX = "http://www.topografix.com/GPX/1/0"; + public static final String PREFIX_GROUNDSPEAK = "http://www.groundspeak.com/cache/1/0"; protected GpxExport() { super(getString(R.string.export_gpx)); } @Override - public void export(final List<cgCache> caches, final Activity activity) { + public void export(final List<Geocache> caches, final Activity activity) { if (null == activity) { // No activity given, so no user interaction possible. // Start export with default parameters. @@ -55,62 +61,57 @@ class GpxExport extends AbstractExport { } else { // Show configuration dialog - new ExportOptionsDialog(caches, activity).show(); + getExportDialog(caches, activity).show(); } } - /** - * A dialog to allow the user to set options for the export. - * - * Currently available option is: opening of share menu after successful export - */ - private class ExportOptionsDialog extends AlertDialog { - public ExportOptionsDialog(final List<cgCache> caches, final Activity activity) { - super(activity); + private Dialog getExportDialog(final List<Geocache> caches, final Activity activity) { + AlertDialog.Builder builder = new AlertDialog.Builder(activity); - View layout = activity.getLayoutInflater().inflate(R.layout.gpx_export_dialog, null); - setView(layout); + // AlertDialog has always dark style, so we have to apply it as well always + View layout = View.inflate(new ContextThemeWrapper(activity, R.style.dark), R.layout.gpx_export_dialog, null); + builder.setView(layout); - final TextView text = (TextView) layout.findViewById(R.id.info); - text.setText(getString(R.string.export_gpx_info, Settings.getGpxExportDir())); + final TextView text = (TextView) layout.findViewById(R.id.info); + text.setText(getString(R.string.export_gpx_info, Settings.getGpxExportDir())); - final CheckBox shareOption = (CheckBox) layout.findViewById(R.id.share); + final CheckBox shareOption = (CheckBox) layout.findViewById(R.id.share); - shareOption.setChecked(Settings.getShareAfterExport()); + shareOption.setChecked(Settings.getShareAfterExport()); - shareOption.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Settings.setShareAfterExport(shareOption.isChecked()); - } - }); + shareOption.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Settings.setShareAfterExport(shareOption.isChecked()); + } + }); - layout.findViewById(R.id.export).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - new ExportTask(caches, activity).execute((Void) null); - } - }); - } + builder.setPositiveButton(R.string.export, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + new ExportTask(caches, activity).execute((Void) null); + } + }); + + return builder.create(); } - private class ExportTask extends AsyncTask<Void, Integer, Boolean> { - private final List<cgCache> caches; + private class ExportTask extends AsyncTask<Void, Integer, File> { + private final List<Geocache> caches; private final Activity activity; private final Progress progress = new Progress(); - private File exportFile; - private Writer gpx; /** * Instantiates and configures the task for exporting field notes. * * @param caches - * The {@link List} of {@link cgCache} to be exported + * The {@link List} of {@link cgeo.geocaching.Geocache} to be exported * @param activity * optional: Show a progress bar and toasts */ - public ExportTask(final List<cgCache> caches, final Activity activity) { + public ExportTask(final List<Geocache> caches, final Activity activity) { this.caches = caches; this.activity = activity; } @@ -124,164 +125,118 @@ class GpxExport extends AbstractExport { } @Override - protected Boolean doInBackground(Void... params) { + protected File doInBackground(Void... params) { // quick check for being able to write the GPX file if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - return false; + return null; } + final SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US); + final File exportFile = new File(Settings.getGpxExportDir() + File.separatorChar + "export_" + fileNameDateFormat.format(new Date()) + ".gpx"); + FileWriter writer = null; try { final File exportLocation = new File(Settings.getGpxExportDir()); exportLocation.mkdirs(); - final SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US); - exportFile = new File(Settings.getGpxExportDir() + File.separatorChar + "export_" + fileNameDateFormat.format(new Date()) + ".gpx"); - - gpx = new BufferedWriter(new FileWriter(exportFile)); - - gpx.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); - gpx.write("<gpx version=\"1.0\" creator=\"c:geo - http://www.cgeo.org\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/0\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.groundspeak.com/cache/1/0/1 http://www.groundspeak.com/cache/1/0/1/cache.xsd\">"); + final XmlSerializer gpx = Xml.newSerializer(); + writer = new FileWriter(exportFile); + gpx.setOutput(writer); + + gpx.startDocument("UTF-8", true); + gpx.setPrefix("", PREFIX_GPX); + gpx.setPrefix("xsi", PREFIX_XSI); + gpx.setPrefix("groundspeak", PREFIX_GROUNDSPEAK); + gpx.startTag(PREFIX_GPX, "gpx"); + gpx.attribute("", "version", "1.0"); + gpx.attribute("", "creator", "c:geo - http://www.cgeo.org/"); + gpx.attribute(PREFIX_XSI, "schemaLocation", + PREFIX_GPX + " http://www.topografix.com/GPX/1/0/gpx.xsd " + + PREFIX_GROUNDSPEAK + " http://www.groundspeak.com/cache/1/0/1/cache.xsd"); for (int i = 0; i < caches.size(); i++) { - final cgCache cache = cgData.loadCache(caches.get(i).getGeocode(), LoadFlags.LOAD_ALL_DB_ONLY); + final Geocache cache = cgData.loadCache(caches.get(i).getGeocode(), LoadFlags.LOAD_ALL_DB_ONLY); - gpx.write("<wpt "); - gpx.write("lat=\""); - gpx.write(Double.toString(cache.getCoords().getLatitude())); - gpx.write("\" "); - gpx.write("lon=\""); - gpx.write(Double.toString(cache.getCoords().getLongitude())); - gpx.write("\">"); + gpx.startTag(PREFIX_GPX, "wpt"); + gpx.attribute("", "lat", Double.toString(cache.getCoords().getLatitude())); + gpx.attribute("", "lon", Double.toString(cache.getCoords().getLongitude())); final Date hiddenDate = cache.getHiddenDate(); if (hiddenDate != null) { - gpx.write("<time>"); - gpx.write(StringEscapeUtils.escapeXml(dateFormatZ.format(hiddenDate))); - gpx.write("</time>"); + XmlUtils.simpleText(gpx, PREFIX_GPX, "time", dateFormatZ.format(hiddenDate)); } - gpx.write("<name>"); - gpx.write(StringEscapeUtils.escapeXml(cache.getGeocode())); - gpx.write("</name>"); - - gpx.write("<desc>"); - gpx.write(StringEscapeUtils.escapeXml(cache.getName())); - gpx.write("</desc>"); - - gpx.write("<url>"); - gpx.write(cache.getUrl()); - gpx.write("</url>"); - - gpx.write("<urlname>"); - gpx.write(StringEscapeUtils.escapeXml(cache.getName())); - gpx.write("</urlname>"); - - gpx.write("<sym>"); - gpx.write(cache.isFound() ? "Geocache Found" : "Geocache"); - gpx.write("</sym>"); - - gpx.write("<type>"); - gpx.write(StringEscapeUtils.escapeXml("Geocache|" + cache.getType().pattern)); - gpx.write("</type>"); - - gpx.write("<groundspeak:cache "); - gpx.write("id=\""); - gpx.write(cache.getCacheId()); - gpx.write("\" available=\""); - gpx.write(!cache.isDisabled() ? "True" : "False"); - gpx.write("\" archived=\""); - gpx.write(cache.isArchived() ? "True" : "False"); - gpx.write("\" "); - gpx.write("xmlns:groundspeak=\"http://www.groundspeak.com/cache/1/0/1\">"); - - gpx.write("<groundspeak:name>"); - gpx.write(StringEscapeUtils.escapeXml(cache.getName())); - gpx.write("</groundspeak:name>"); - - gpx.write("<groundspeak:placed_by>"); - gpx.write(StringEscapeUtils.escapeXml(cache.getOwnerDisplayName())); - gpx.write("</groundspeak:placed_by>"); - - gpx.write("<groundspeak:owner>"); - gpx.write(StringEscapeUtils.escapeXml(cache.getOwnerUserId())); - gpx.write("</groundspeak:owner>"); + XmlUtils.multipleTexts(gpx, PREFIX_GPX, + "name", cache.getGeocode(), + "desc", cache.getName(), + "url", cache.getUrl(), + "urlname", cache.getName(), + "sym", cache.isFound() ? "Geocache Found" : "Geocache", + "type", "Geocache|" + cache.getType().pattern); - gpx.write("<groundspeak:type>"); - gpx.write(StringEscapeUtils.escapeXml(cache.getType().pattern)); - gpx.write("</groundspeak:type>"); + gpx.startTag(PREFIX_GROUNDSPEAK, "cache"); + gpx.attribute("", "id", cache.getCacheId()); + gpx.attribute("", "available", !cache.isDisabled() ? "True" : "False"); + gpx.attribute("", "archives", cache.isArchived() ? "True" : "False"); - gpx.write("<groundspeak:container>"); - gpx.write(StringEscapeUtils.escapeXml(cache.getSize().id)); - gpx.write("</groundspeak:container>"); - writeAttributes(cache); + XmlUtils.multipleTexts(gpx, PREFIX_GROUNDSPEAK, + "name", cache.getName(), + "placed_by", cache.getOwnerDisplayName(), + "owner", cache.getOwnerUserId(), + "type", cache.getType().pattern, + "container", cache.getSize().id, + "difficulty", Float.toString(cache.getDifficulty()), + "terrain", Float.toString(cache.getTerrain()), + "country", cache.getLocation(), + "state", "", + "encoded_hints", cache.getHint()); - gpx.write("<groundspeak:difficulty>"); - gpx.write(Float.toString(cache.getDifficulty())); - gpx.write("</groundspeak:difficulty>"); + writeAttributes(gpx, cache); - gpx.write("<groundspeak:terrain>"); - gpx.write(Float.toString(cache.getTerrain())); - gpx.write("</groundspeak:terrain>"); + gpx.startTag(PREFIX_GROUNDSPEAK, "short_description"); + gpx.attribute("", "html", BaseUtils.containsHtml(cache.getShortDescription()) ? "True" : "False"); + gpx.text(cache.getShortDescription()); + gpx.endTag(PREFIX_GROUNDSPEAK, "short_description"); - gpx.write("<groundspeak:country>"); - gpx.write(StringEscapeUtils.escapeXml(cache.getLocation())); - gpx.write("</groundspeak:country>"); + gpx.startTag(PREFIX_GROUNDSPEAK, "long_description"); + gpx.attribute("", "html", BaseUtils.containsHtml(cache.getDescription()) ? "True" : "False"); + gpx.text(cache.getDescription()); + gpx.endTag(PREFIX_GROUNDSPEAK, "long_description"); - gpx.write("<groundspeak:state></groundspeak:state>"); // c:geo cannot manage 2 separate fields, so we export as country + writeLogs(gpx, cache); - gpx.write("<groundspeak:short_description html=\""); - gpx.write(BaseUtils.containsHtml(cache.getShortDescription()) ? "True" : "False"); - gpx.write("\">"); - gpx.write(StringEscapeUtils.escapeXml(cache.getShortDescription())); - gpx.write("</groundspeak:short_description>"); + gpx.endTag(PREFIX_GROUNDSPEAK, "cache"); + gpx.endTag(PREFIX_GPX, "wpt"); - gpx.write("<groundspeak:long_description html=\""); - gpx.write(BaseUtils.containsHtml(cache.getDescription()) ? "True" : "False"); - gpx.write("\">"); - gpx.write(StringEscapeUtils.escapeXml(cache.getDescription())); - gpx.write("</groundspeak:long_description>"); - - gpx.write("<groundspeak:encoded_hints>"); - gpx.write(StringEscapeUtils.escapeXml(cache.getHint())); - gpx.write("</groundspeak:encoded_hints>"); - - writeLogs(cache); - - gpx.write("</groundspeak:cache>"); - - gpx.write("</wpt>"); - - writeWaypoints(cache); + writeWaypoints(gpx, cache); publishProgress(i + 1); } - gpx.write("</gpx>"); - - gpx.close(); - } catch (Exception e) { + gpx.endTag(PREFIX_GPX, "gpx"); + gpx.endDocument(); + } catch (final IOException e) { Log.e("GpxExport.ExportTask export", e); - if (gpx != null) { + if (writer != null) { try { - gpx.close(); - } catch (IOException ee) { + writer.close(); + } catch (IOException e1) { + // Ignore double error } } - // delete partial gpx file on error if (exportFile.exists()) { exportFile.delete(); } - return false; + return null; } - return true; + return exportFile; } - private void writeWaypoints(final cgCache cache) throws IOException { + private void writeWaypoints(final XmlSerializer gpx, final Geocache cache) throws IOException { List<Waypoint> waypoints = cache.getWaypoints(); List<Waypoint> ownWaypoints = new ArrayList<Waypoint>(waypoints.size()); List<Waypoint> originWaypoints = new ArrayList<Waypoint>(waypoints.size()); @@ -300,12 +255,12 @@ class GpxExport extends AbstractExport { } catch (NumberFormatException ex) { Log.e("Unexpected origin waypoint prefix='" + prefix + "'", ex); } - writeCacheWaypoint(wp, prefix); + writeCacheWaypoint(gpx, wp, prefix); } for (Waypoint wp : ownWaypoints) { maxPrefix++; String prefix = StringUtils.leftPad(String.valueOf(maxPrefix), 2, '0'); - writeCacheWaypoint(wp, prefix); + writeCacheWaypoint(gpx, wp, prefix); } } @@ -318,103 +273,78 @@ class GpxExport extends AbstractExport { * @param prefix * @throws IOException */ - private void writeCacheWaypoint(final Waypoint wp, final String prefix) throws IOException { - gpx.write("<wpt lat=\""); + private void writeCacheWaypoint(final XmlSerializer gpx, final Waypoint wp, final String prefix) throws IOException { + gpx.startTag(PREFIX_GPX, "wpt"); final Geopoint coords = wp.getCoords(); - gpx.write(coords != null ? Double.toString(coords.getLatitude()) : ""); // TODO: check whether is the best way to handle unknown waypoint coordinates - gpx.write("\" lon=\""); - gpx.write(coords != null ? Double.toString(coords.getLongitude()) : ""); - gpx.write("\">"); - - gpx.write("<name>"); - gpx.write(StringEscapeUtils.escapeXml(prefix)); - gpx.write(StringEscapeUtils.escapeXml(wp.getGeocode().substring(2))); - gpx.write("</name>"); - - gpx.write("<cmt>"); - gpx.write(StringEscapeUtils.escapeXml(wp.getNote())); - gpx.write("</cmt>"); - - gpx.write("<desc>"); - gpx.write(StringEscapeUtils.escapeXml(wp.getName())); - gpx.write("</desc>"); - - gpx.write("<sym>"); - gpx.write(StringEscapeUtils.escapeXml(wp.getWaypointType().toString())); //TODO: Correct identifier string - gpx.write("</sym>"); - - gpx.write("<type>Waypoint|"); - gpx.write(StringEscapeUtils.escapeXml(wp.getWaypointType().toString())); //TODO: Correct identifier string - gpx.write("</type>"); - - gpx.write("</wpt>"); + gpx.attribute("", "lat", coords != null ? Double.toString(coords.getLatitude()) : ""); // TODO: check whether is the best way to handle unknown waypoint coordinates + gpx.attribute("", "lon", coords != null ? Double.toString(coords.getLongitude()) : ""); + XmlUtils.multipleTexts(gpx, PREFIX_GPX, + "name", prefix + wp.getGeocode().substring(2), + "cmt", wp.getNote(), + "desc", wp.getName(), + "sym", wp.getWaypointType().toString(), //TODO: Correct identifier string + "type", "Waypoint|" + wp.getWaypointType().toString()); //TODO: Correct identifier string + gpx.endTag(PREFIX_GPX, "wpt"); } - private void writeLogs(final cgCache cache) throws IOException { + private void writeLogs(final XmlSerializer gpx, final Geocache cache) throws IOException { if (cache.getLogs().isEmpty()) { return; } - gpx.write("<groundspeak:logs>"); + gpx.startTag(PREFIX_GROUNDSPEAK, "logs"); for (LogEntry log : cache.getLogs()) { - gpx.write("<groundspeak:log id=\""); - gpx.write(Integer.toString(log.id)); - gpx.write("\">"); + gpx.startTag(PREFIX_GROUNDSPEAK, "log"); + gpx.attribute("", "id", Integer.toString(log.id)); - gpx.write("<groundspeak:date>"); - gpx.write(StringEscapeUtils.escapeXml(dateFormatZ.format(new Date(log.date)))); - gpx.write("</groundspeak:date>"); + XmlUtils.multipleTexts(gpx, PREFIX_GROUNDSPEAK, + "date", dateFormatZ.format(new Date(log.date)), + "type", log.type.type); - gpx.write("<groundspeak:type>"); - gpx.write(StringEscapeUtils.escapeXml(log.type.type)); - gpx.write("</groundspeak:type>"); + gpx.startTag(PREFIX_GROUNDSPEAK, "finder"); + gpx.attribute("", "id", log.author); + gpx.endTag(PREFIX_GROUNDSPEAK, "finder"); - gpx.write("<groundspeak:finder id=\"\">"); - gpx.write(StringEscapeUtils.escapeXml(log.author)); - gpx.write("</groundspeak:finder>"); + gpx.startTag(PREFIX_GROUNDSPEAK, "text"); + gpx.attribute("", "encoded", "False"); + gpx.text(log.log); + gpx.endTag(PREFIX_GROUNDSPEAK, "text"); - gpx.write("<groundspeak:text encoded=\"False\">"); - gpx.write(StringEscapeUtils.escapeXml(log.log)); - gpx.write("</groundspeak:text>"); - - gpx.write("</groundspeak:log>"); + gpx.endTag(PREFIX_GROUNDSPEAK, "log"); } - gpx.write("</groundspeak:logs>"); + gpx.endTag(PREFIX_GROUNDSPEAK, "logs"); } - private void writeAttributes(final cgCache cache) throws IOException { + private void writeAttributes(final XmlSerializer gpx, final Geocache cache) throws IOException { if (cache.getAttributes().isEmpty()) { return; } //TODO: Attribute conversion required: English verbose name, gpx-id - gpx.write("<groundspeak:attributes>"); + gpx.startTag(PREFIX_GROUNDSPEAK, "attributes"); for (String attribute : cache.getAttributes()) { - final CacheAttribute attr = CacheAttribute.getByGcRawName(CacheAttribute.trimAttributeName(attribute)); + final CacheAttribute attr = CacheAttribute.getByRawName(CacheAttribute.trimAttributeName(attribute)); + if (attr == null) { + continue; + } final boolean enabled = CacheAttribute.isEnabled(attribute); - gpx.write("<groundspeak:attribute id=\""); - gpx.write(Integer.toString(attr.id)); - gpx.write("\" inc=\""); - if (enabled) { - gpx.write('1'); - } else { - gpx.write('0'); - } - gpx.write("\">"); - gpx.write(StringEscapeUtils.escapeXml(attr.getL10n(enabled))); - gpx.write("</groundspeak:attribute>"); + gpx.startTag(PREFIX_GROUNDSPEAK, "attribute"); + gpx.attribute("", "id", Integer.toString(attr.gcid)); + gpx.attribute("", "inc", enabled ? "1" : "0"); + gpx.text(attr.getL10n(enabled)); + gpx.endTag(PREFIX_GROUNDSPEAK, "attribute"); } - gpx.write("</groundspeak:attributes>"); + gpx.endTag(PREFIX_GROUNDSPEAK, "attributes"); } @Override - protected void onPostExecute(Boolean result) { + protected void onPostExecute(final File exportFile) { if (null != activity) { progress.dismiss(); - if (result) { + if (exportFile != null) { ActivityMixin.showToast(activity, getName() + ' ' + getString(R.string.export_exportedto) + ": " + exportFile.toString()); if (Settings.getShareAfterExport()) { Intent shareIntent = new Intent(); diff --git a/main/src/cgeo/geocaching/files/FileList.java b/main/src/cgeo/geocaching/files/FileList.java index 42c9f16..31daeb4 100644 --- a/main/src/cgeo/geocaching/files/FileList.java +++ b/main/src/cgeo/geocaching/files/FileList.java @@ -1,5 +1,6 @@ package cgeo.geocaching.files; +import cgeo.geocaching.Intents; import cgeo.geocaching.R; import cgeo.geocaching.StoredList; import cgeo.geocaching.activity.AbstractListActivity; @@ -34,7 +35,7 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis private T adapter = null; private ProgressDialog waitDialog = null; private SearchFilesThread searchingThread = null; - private int listId = StoredList.STANDARD_LIST_ID; + protected int listId = StoredList.STANDARD_LIST_ID; private String[] extensions; final private Handler changeWaitDialogHandler = new Handler() { @@ -92,7 +93,7 @@ public abstract class FileList<T extends ArrayAdapter<File>> extends AbstractLis Bundle extras = getIntent().getExtras(); if (extras != null) { - listId = extras.getInt("list"); + listId = extras.getInt(Intents.EXTRA_LIST_ID); } if (listId <= StoredList.TEMPORARY_LIST_ID) { listId = StoredList.STANDARD_LIST_ID; diff --git a/main/src/cgeo/geocaching/files/FileParser.java b/main/src/cgeo/geocaching/files/FileParser.java index 0308d81..50b65a1 100644 --- a/main/src/cgeo/geocaching/files/FileParser.java +++ b/main/src/cgeo/geocaching/files/FileParser.java @@ -1,6 +1,6 @@ package cgeo.geocaching.files; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.utils.CancellableHandler; import java.io.BufferedReader; @@ -26,7 +26,7 @@ public abstract class FileParser { * @throws ParserException * if the input stream contains data not matching the file format of the parser */ - public abstract Collection<cgCache> parse(final InputStream stream, final CancellableHandler progressHandler) throws IOException, ParserException; + public abstract Collection<Geocache> parse(final InputStream stream, final CancellableHandler progressHandler) throws IOException, ParserException; /** * Convenience method for parsing a file. @@ -37,7 +37,7 @@ public abstract class FileParser { * @throws IOException * @throws ParserException */ - public Collection<cgCache> parse(final File file, final CancellableHandler progressHandler) throws IOException, ParserException { + public Collection<Geocache> parse(final File file, final CancellableHandler progressHandler) throws IOException, ParserException { FileInputStream fis = new FileInputStream(file); try { return parse(fis, progressHandler); @@ -72,7 +72,7 @@ public abstract class FileParser { } } - protected static void fixCache(cgCache cache) { + protected static void fixCache(Geocache cache) { if (cache.getInventory() != null) { cache.setInventoryItems(cache.getInventory().size()); } else { diff --git a/main/src/cgeo/geocaching/files/GPXImporter.java b/main/src/cgeo/geocaching/files/GPXImporter.java index 750d5e0..b8dcbb3 100644 --- a/main/src/cgeo/geocaching/files/GPXImporter.java +++ b/main/src/cgeo/geocaching/files/GPXImporter.java @@ -1,10 +1,10 @@ package cgeo.geocaching.files;
+import cgeo.geocaching.Geocache;
import cgeo.geocaching.R;
import cgeo.geocaching.SearchResult;
import cgeo.geocaching.Settings;
import cgeo.geocaching.StaticMapsProvider;
-import cgeo.geocaching.cgCache;
import cgeo.geocaching.cgData;
import cgeo.geocaching.activity.IAbstractActivity;
import cgeo.geocaching.activity.Progress;
@@ -134,11 +134,11 @@ public class GPXImporter { public void run() {
try {
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_START));
- final Collection<cgCache> caches = doImport();
+ final Collection<Geocache> caches = doImport();
Log.i("Imported successfully " + caches.size() + " caches.");
final SearchResult search = new SearchResult();
- for (cgCache cache : caches) {
+ for (Geocache cache : caches) {
search.addCache(cache);
}
@@ -167,12 +167,12 @@ public class GPXImporter { }
}
- protected abstract Collection<cgCache> doImport() throws IOException, ParserException;
+ protected abstract Collection<Geocache> doImport() throws IOException, ParserException;
private boolean importStaticMaps(final SearchResult importedCaches) {
int storedCacheMaps = 0;
for (String geocode : importedCaches.getGeocodes()) {
- cgCache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS);
+ Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS);
Log.d("GPXImporter.ImportThread.importStaticMaps start downloadMaps for cache " + geocode);
StaticMapsProvider.downloadMaps(cache);
storedCacheMaps++;
@@ -194,7 +194,7 @@ public class GPXImporter { }
@Override
- protected Collection<cgCache> doImport() throws IOException, ParserException {
+ protected Collection<Geocache> doImport() throws IOException, ParserException {
Log.i("Import LOC file: " + file.getAbsolutePath());
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) file.length()));
LocParser parser = new LocParser(listId);
@@ -209,7 +209,7 @@ public class GPXImporter { }
@Override
- protected Collection<cgCache> doImport() throws IOException, ParserException {
+ protected Collection<Geocache> doImport() throws IOException, ParserException {
try {
// try to parse cache file as GPX 10
return doImport(new GPX10Parser(listId));
@@ -219,7 +219,7 @@ public class GPXImporter { }
}
- protected abstract Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException;
+ protected abstract Collection<Geocache> doImport(GPXParser parser) throws IOException, ParserException;
}
static class ImportGpxFileThread extends ImportGpxThread {
@@ -231,10 +231,10 @@ public class GPXImporter { }
@Override
- protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException {
+ protected Collection<Geocache> doImport(GPXParser parser) throws IOException, ParserException {
Log.i("Import GPX file: " + cacheFile.getAbsolutePath());
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, (int) cacheFile.length()));
- Collection<cgCache> caches = parser.parse(cacheFile, progressHandler);
+ Collection<Geocache> caches = parser.parse(cacheFile, progressHandler);
final String wptsFilename = getWaypointsFileNameForGpxFile(cacheFile);
if (wptsFilename != null) {
@@ -260,7 +260,7 @@ public class GPXImporter { }
@Override
- protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException {
+ protected Collection<Geocache> doImport(GPXParser parser) throws IOException, ParserException {
Log.i("Import GPX from uri: " + uri);
importStepHandler.sendMessage(importStepHandler.obtainMessage(IMPORT_STEP_READ_FILE, R.string.gpx_import_loading_caches, -1));
InputStream is = contentResolver.openInputStream(uri);
@@ -279,8 +279,8 @@ public class GPXImporter { }
@Override
- protected Collection<cgCache> doImport(GPXParser parser) throws IOException, ParserException {
- Collection<cgCache> caches = Collections.emptySet();
+ protected Collection<Geocache> doImport(GPXParser parser) throws IOException, ParserException {
+ Collection<Geocache> caches = Collections.emptySet();
// can't assume that GPX file comes before waypoint file in zip -> so we need two passes
// 1. parse GPX files
ZipInputStream zis = new ZipInputStream(getInputStream());
diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java index 22a7f41..5647d14 100644 --- a/main/src/cgeo/geocaching/files/GPXParser.java +++ b/main/src/cgeo/geocaching/files/GPXParser.java @@ -1,12 +1,12 @@ package cgeo.geocaching.files; +import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; import cgeo.geocaching.StoredList; +import cgeo.geocaching.Trackable; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgData; -import cgeo.geocaching.Trackable; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.enumerations.CacheSize; @@ -80,7 +80,7 @@ public abstract class GPXParser extends FileParser { final protected String namespace; final private String version; - private cgCache cache; + private Geocache cache; private Trackable trackable = new Trackable(); private LogEntry log = null; @@ -248,7 +248,7 @@ public abstract class GPXParser extends FileParser { } @Override - public Collection<cgCache> parse(final InputStream stream, final CancellableHandler progressHandler) throws IOException, ParserException { + public Collection<Geocache> parse(final InputStream stream, final CancellableHandler progressHandler) throws IOException, ParserException { resetCache(); final RootElement root = new RootElement(namespace, "gpx"); final Element waypoint = root.getChild(namespace, "wpt"); @@ -329,9 +329,9 @@ public abstract class GPXParser extends FileParser { if (cache.getName().length() > 2) { final String cacheGeocodeForWaypoint = "GC" + cache.getName().substring(2).toUpperCase(Locale.US); // lookup cache for waypoint in already parsed caches - final cgCache cacheForWaypoint = cgData.loadCache(cacheGeocodeForWaypoint, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cacheForWaypoint = cgData.loadCache(cacheGeocodeForWaypoint, LoadFlags.LOAD_CACHE_OR_DB); if (cacheForWaypoint != null) { - final Waypoint waypoint = new Waypoint(cache.getShortdesc(), convertWaypointSym2Type(sym), false); + final Waypoint waypoint = new Waypoint(cache.getShortDescription(), convertWaypointSym2Type(sym), false); waypoint.setId(-1); waypoint.setGeocode(cacheGeocodeForWaypoint); waypoint.setPrefix(cache.getName().substring(0, 2)); @@ -388,7 +388,7 @@ public abstract class GPXParser extends FileParser { public void end(String body) { desc = body; - cache.setShortdesc(validate(body)); + cache.setShortDescription(validate(body)); } }); @@ -638,7 +638,7 @@ public abstract class GPXParser extends FileParser { @Override public void end(String shortDesc) { - cache.setShortdesc(validate(shortDesc)); + cache.setShortDescription(validate(shortDesc)); } }); @@ -783,7 +783,7 @@ public abstract class GPXParser extends FileParser { * @param cache * currently imported cache */ - protected void afterParsing(cgCache cache) { + protected void afterParsing(Geocache cache) { // can be overridden by sub classes } @@ -858,7 +858,14 @@ public abstract class GPXParser extends FileParser { desc = null; cmt = null; - cache = new cgCache(this); + cache = new Geocache(this); + + // explicitly set all properties which could lead to database access, if left as null value + cache.setLocation(""); + cache.setDescription(""); + cache.setShortDescription(""); + cache.setHint(""); + for (int i = 0; i < userData.length; i++) { userData[i] = null; } diff --git a/main/src/cgeo/geocaching/files/LocParser.java b/main/src/cgeo/geocaching/files/LocParser.java index 730e224..fe290c3 100644 --- a/main/src/cgeo/geocaching/files/LocParser.java +++ b/main/src/cgeo/geocaching/files/LocParser.java @@ -1,7 +1,7 @@ package cgeo.geocaching.files; +import cgeo.geocaching.Geocache; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; @@ -56,7 +56,7 @@ public final class LocParser extends FileParser { private int listId; public static void parseLoc(final SearchResult searchResult, final String fileContent) { - final Map<String, cgCache> cidCoords = parseCoordinates(fileContent); + final Map<String, Geocache> cidCoords = parseCoordinates(fileContent); // save found cache coordinates final HashSet<String> contained = new HashSet<String>(); @@ -65,14 +65,14 @@ public final class LocParser extends FileParser { contained.add(geocode); } } - Set<cgCache> caches = cgData.loadCaches(contained, LoadFlags.LOAD_CACHE_OR_DB); - for (cgCache cache : caches) { - cgCache coord = cidCoords.get(cache.getGeocode()); + Set<Geocache> caches = cgData.loadCaches(contained, LoadFlags.LOAD_CACHE_OR_DB); + for (Geocache cache : caches) { + Geocache coord = cidCoords.get(cache.getGeocode()); copyCoordToCache(coord, cache); } } - private static void copyCoordToCache(final cgCache coord, final cgCache cache) { + private static void copyCoordToCache(final Geocache coord, final Geocache cache) { cache.setCoords(coord.getCoords()); cache.setDifficulty(coord.getDifficulty()); cache.setTerrain(coord.getTerrain()); @@ -84,8 +84,8 @@ public final class LocParser extends FileParser { } } - static Map<String, cgCache> parseCoordinates(final String fileContent) { - final Map<String, cgCache> coords = new HashMap<String, cgCache>(); + static Map<String, Geocache> parseCoordinates(final String fileContent) { + final Map<String, Geocache> coords = new HashMap<String, Geocache>(); if (StringUtils.isBlank(fileContent)) { return coords; } @@ -95,7 +95,7 @@ public final class LocParser extends FileParser { // parse coordinates for (String pointString : points) { - final cgCache pointCoord = parseCache(pointString); + final Geocache pointCoord = parseCache(pointString); if (StringUtils.isNotBlank(pointCoord.getGeocode())) { coords.put(pointCoord.getGeocode(), pointCoord); } @@ -121,17 +121,17 @@ public final class LocParser extends FileParser { } @Override - public Collection<cgCache> parse(InputStream stream, CancellableHandler progressHandler) throws IOException, ParserException { + public Collection<Geocache> parse(InputStream stream, CancellableHandler progressHandler) throws IOException, ParserException { // TODO: progress reporting happens during reading stream only, not during parsing String streamContent = readStream(stream, progressHandler).toString(); - final Map<String, cgCache> coords = parseCoordinates(streamContent); - final List<cgCache> caches = new ArrayList<cgCache>(); - for (Entry<String, cgCache> entry : coords.entrySet()) { - cgCache coord = entry.getValue(); + final Map<String, Geocache> coords = parseCoordinates(streamContent); + final List<Geocache> caches = new ArrayList<Geocache>(); + for (Entry<String, Geocache> entry : coords.entrySet()) { + Geocache coord = entry.getValue(); if (StringUtils.isBlank(coord.getGeocode()) || StringUtils.isBlank(coord.getName())) { continue; } - cgCache cache = new cgCache(); + Geocache cache = new Geocache(); cache.setReliableLatLon(true); copyCoordToCache(coord, cache); caches.add(cache); @@ -146,8 +146,8 @@ public final class LocParser extends FileParser { return caches; } - public static cgCache parseCache(final String pointString) { - final cgCache cache = new cgCache(); + public static Geocache parseCache(final String pointString) { + final Geocache cache = new Geocache(); final MatcherWrapper matcherGeocode = new MatcherWrapper(patternGeocode, pointString); if (matcherGeocode.find()) { cache.setGeocode(matcherGeocode.group(1).trim()); diff --git a/main/src/cgeo/geocaching/files/SimpleDirChooser.java b/main/src/cgeo/geocaching/files/SimpleDirChooser.java index c59b0cb..7520e2e 100644 --- a/main/src/cgeo/geocaching/files/SimpleDirChooser.java +++ b/main/src/cgeo/geocaching/files/SimpleDirChooser.java @@ -1,5 +1,6 @@ package cgeo.geocaching.files; +import cgeo.geocaching.Intents; import cgeo.geocaching.R; import cgeo.geocaching.activity.ActivityMixin; @@ -8,6 +9,7 @@ import org.apache.commons.lang3.StringUtils; import android.app.ListActivity; import android.content.Context; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.view.LayoutInflater; @@ -30,8 +32,6 @@ import java.util.List; * Dialog for choosing a file or directory. */ public class SimpleDirChooser extends ListActivity { - public static final String EXTRA_CHOSEN_DIR = "chosenDir"; - public static final String START_DIR = "start_dir"; private static final String PARENT_DIR = ".. "; private File currentDir; private FileArrayAdapter adapter; @@ -42,7 +42,7 @@ public class SimpleDirChooser extends ListActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Bundle extras = getIntent().getExtras(); - currentDir = dirContaining(extras.getString(START_DIR)); + currentDir = dirContaining(extras.getString(Intents.EXTRA_START_DIR)); ActivityMixin.setTheme(this); setContentView(R.layout.simple_dir_chooser); @@ -56,10 +56,8 @@ public class SimpleDirChooser extends ListActivity { okButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(); - String chosenDirName = File.separator + adapter.getItem(lastPosition).getName(); - intent.putExtra(EXTRA_CHOSEN_DIR, currentDir.getAbsolutePath() + chosenDirName); - setResult(RESULT_OK, intent); + setResult(RESULT_OK, new Intent() + .setData(Uri.fromFile(new File(currentDir, adapter.getItem(lastPosition).getName())))); finish(); } }); diff --git a/main/src/cgeo/geocaching/filter/AbstractFilter.java b/main/src/cgeo/geocaching/filter/AbstractFilter.java index f78a218..bc99959 100644 --- a/main/src/cgeo/geocaching/filter/AbstractFilter.java +++ b/main/src/cgeo/geocaching/filter/AbstractFilter.java @@ -1,6 +1,6 @@ package cgeo.geocaching.filter; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import java.util.ArrayList; import java.util.List; @@ -13,9 +13,9 @@ abstract class AbstractFilter implements IFilter { } @Override - public void filter(List<cgCache> list) { - final List<cgCache> itemsToRemove = new ArrayList<cgCache>(); - for (cgCache item : list) { + public void filter(List<Geocache> list) { + final List<Geocache> itemsToRemove = new ArrayList<Geocache>(); + for (Geocache item : list) { if (!accepts(item)) { itemsToRemove.add(item); } diff --git a/main/src/cgeo/geocaching/filter/AttributeFilter.java b/main/src/cgeo/geocaching/filter/AttributeFilter.java index 837e9d1..4b6f382 100644 --- a/main/src/cgeo/geocaching/filter/AttributeFilter.java +++ b/main/src/cgeo/geocaching/filter/AttributeFilter.java @@ -1,7 +1,7 @@ package cgeo.geocaching.filter; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.LoadFlags.LoadFlag; @@ -34,8 +34,8 @@ class AttributeFilter extends AbstractFilter { } @Override - public boolean accepts(final cgCache cache) { - cgCache fullCache = cgData.loadCache(cache.getGeocode(), EnumSet.of(LoadFlag.LOAD_ATTRIBUTES)); + public boolean accepts(final Geocache cache) { + Geocache fullCache = cgData.loadCache(cache.getGeocode(), EnumSet.of(LoadFlag.LOAD_ATTRIBUTES)); if (fullCache == null) { fullCache = cache; } diff --git a/main/src/cgeo/geocaching/filter/DifficultyFilter.java b/main/src/cgeo/geocaching/filter/DifficultyFilter.java index 368c20f..c0ec61a 100644 --- a/main/src/cgeo/geocaching/filter/DifficultyFilter.java +++ b/main/src/cgeo/geocaching/filter/DifficultyFilter.java @@ -1,7 +1,7 @@ package cgeo.geocaching.filter; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; import java.util.ArrayList; @@ -12,7 +12,7 @@ class DifficultyFilter extends AbstractRangeFilter { } @Override - public boolean accepts(cgCache cache) { + public boolean accepts(Geocache cache) { return rangeMin <= cache.getDifficulty() && cache.getDifficulty() < rangeMax; } diff --git a/main/src/cgeo/geocaching/filter/FilterUserInterface.java b/main/src/cgeo/geocaching/filter/FilterUserInterface.java index e2472fd..be63a08 100644 --- a/main/src/cgeo/geocaching/filter/FilterUserInterface.java +++ b/main/src/cgeo/geocaching/filter/FilterUserInterface.java @@ -53,6 +53,7 @@ public final class FilterUserInterface { 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); // sort by localized names Collections.sort(registry, new Comparator<FactoryEntry>() { diff --git a/main/src/cgeo/geocaching/filter/IFilter.java b/main/src/cgeo/geocaching/filter/IFilter.java index abc2d50..4a428f8 100644 --- a/main/src/cgeo/geocaching/filter/IFilter.java +++ b/main/src/cgeo/geocaching/filter/IFilter.java @@ -1,6 +1,6 @@ package cgeo.geocaching.filter; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import java.util.List; @@ -12,7 +12,7 @@ public interface IFilter { * @param cache * @return true if the filter accepts the cache, false otherwise */ - public abstract boolean accepts(final cgCache cache); + public abstract boolean accepts(final Geocache cache); - public void filter(final List<cgCache> list); + public void filter(final List<Geocache> list); }
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/filter/ModifiedFilter.java b/main/src/cgeo/geocaching/filter/ModifiedFilter.java index f74bb4d..f3e57de 100644 --- a/main/src/cgeo/geocaching/filter/ModifiedFilter.java +++ b/main/src/cgeo/geocaching/filter/ModifiedFilter.java @@ -1,7 +1,7 @@ package cgeo.geocaching.filter; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; class ModifiedFilter extends AbstractFilter implements IFilterFactory { @@ -11,7 +11,7 @@ class ModifiedFilter extends AbstractFilter implements IFilterFactory { } @Override - public boolean accepts(final cgCache cache) { + public boolean accepts(final Geocache cache) { // modified on GC return cache.hasUserModifiedCoords() || cache.hasFinalDefined(); } diff --git a/main/src/cgeo/geocaching/filter/OriginFilter.java b/main/src/cgeo/geocaching/filter/OriginFilter.java new file mode 100644 index 0000000..a880092 --- /dev/null +++ b/main/src/cgeo/geocaching/filter/OriginFilter.java @@ -0,0 +1,47 @@ +package cgeo.geocaching.filter; + +import cgeo.geocaching.Geocache; +import cgeo.geocaching.connector.ConnectorFactory; +import cgeo.geocaching.connector.IConnector; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +public class OriginFilter extends AbstractFilter { + + private final IConnector connector; + + public OriginFilter(IConnector connector) { + super(connector.getName()); + this.connector = connector; + } + + @Override + public boolean accepts(Geocache cache) { + return ConnectorFactory.getConnector(cache) == connector; + } + + public static final class Factory implements IFilterFactory { + + @Override + public IFilter[] getFilters() { + final ArrayList<OriginFilter> filters = new ArrayList<OriginFilter>(); + for (IConnector connector : ConnectorFactory.getConnectors()) { + filters.add(new OriginFilter(connector)); + } + + // sort connectors by name + Collections.sort(filters, new Comparator<OriginFilter>() { + + @Override + public int compare(OriginFilter lhs, OriginFilter rhs) { + return lhs.getName().compareToIgnoreCase(rhs.getName()); + } + }); + + return filters.toArray(new OriginFilter[filters.size()]); + } + + } +} diff --git a/main/src/cgeo/geocaching/filter/SizeFilter.java b/main/src/cgeo/geocaching/filter/SizeFilter.java index b08c2ae..7a34c83 100644 --- a/main/src/cgeo/geocaching/filter/SizeFilter.java +++ b/main/src/cgeo/geocaching/filter/SizeFilter.java @@ -1,6 +1,6 @@ package cgeo.geocaching.filter; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.enumerations.CacheSize; import java.util.ArrayList; @@ -14,7 +14,7 @@ class SizeFilter extends AbstractFilter { } @Override - public boolean accepts(cgCache cache) { + public boolean accepts(Geocache cache) { return cacheSize == cache.getSize(); } diff --git a/main/src/cgeo/geocaching/filter/StateFilter.java b/main/src/cgeo/geocaching/filter/StateFilter.java index f51329a..0df47c1 100644 --- a/main/src/cgeo/geocaching/filter/StateFilter.java +++ b/main/src/cgeo/geocaching/filter/StateFilter.java @@ -1,7 +1,7 @@ package cgeo.geocaching.filter; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import android.content.res.Resources; @@ -25,7 +25,7 @@ abstract class StateFilter extends AbstractFilter { } @Override - public boolean accepts(cgCache cache) { + public boolean accepts(Geocache cache) { return cache.isFound(); } @@ -37,7 +37,7 @@ abstract class StateFilter extends AbstractFilter { } @Override - public boolean accepts(cgCache cache) { + public boolean accepts(Geocache cache) { return cache.isArchived(); } } @@ -48,7 +48,7 @@ abstract class StateFilter extends AbstractFilter { } @Override - public boolean accepts(cgCache cache) { + public boolean accepts(Geocache cache) { return cache.isDisabled(); } } @@ -59,7 +59,7 @@ abstract class StateFilter extends AbstractFilter { } @Override - public boolean accepts(cgCache cache) { + public boolean accepts(Geocache cache) { return cache.isPremiumMembersOnly(); } } @@ -70,7 +70,7 @@ abstract class StateFilter extends AbstractFilter { } @Override - public boolean accepts(cgCache cache) { + public boolean accepts(Geocache cache) { return !cache.isPremiumMembersOnly(); } } @@ -81,7 +81,7 @@ abstract class StateFilter extends AbstractFilter { } @Override - public boolean accepts(cgCache cache) { + public boolean accepts(Geocache cache) { return cache.isLogOffline(); } } diff --git a/main/src/cgeo/geocaching/filter/TerrainFilter.java b/main/src/cgeo/geocaching/filter/TerrainFilter.java index 5cee87e..f7703d5 100644 --- a/main/src/cgeo/geocaching/filter/TerrainFilter.java +++ b/main/src/cgeo/geocaching/filter/TerrainFilter.java @@ -2,7 +2,7 @@ package cgeo.geocaching.filter; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import java.util.ArrayList; @@ -13,7 +13,7 @@ class TerrainFilter extends AbstractRangeFilter { } @Override - public boolean accepts(cgCache cache) { + public boolean accepts(Geocache cache) { return rangeMin <= cache.getTerrain() && cache.getTerrain() < rangeMax; } diff --git a/main/src/cgeo/geocaching/filter/TrackablesFilter.java b/main/src/cgeo/geocaching/filter/TrackablesFilter.java index 90def5b..3225daa 100644 --- a/main/src/cgeo/geocaching/filter/TrackablesFilter.java +++ b/main/src/cgeo/geocaching/filter/TrackablesFilter.java @@ -1,7 +1,7 @@ package cgeo.geocaching.filter; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.cgeoapplication; class TrackablesFilter extends AbstractFilter implements IFilterFactory { @@ -10,7 +10,7 @@ class TrackablesFilter extends AbstractFilter implements IFilterFactory { } @Override - public boolean accepts(cgCache cache) { + public boolean accepts(Geocache cache) { return cache.hasTrackables(); } diff --git a/main/src/cgeo/geocaching/filter/TypeFilter.java b/main/src/cgeo/geocaching/filter/TypeFilter.java index 05b97e0..eeab552 100644 --- a/main/src/cgeo/geocaching/filter/TypeFilter.java +++ b/main/src/cgeo/geocaching/filter/TypeFilter.java @@ -1,6 +1,6 @@ package cgeo.geocaching.filter; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.enumerations.CacheType; import java.util.ArrayList; @@ -14,7 +14,7 @@ class TypeFilter extends AbstractFilter { } @Override - public boolean accepts(final cgCache cache) { + public boolean accepts(final Geocache cache) { return cacheType == cache.getType(); } diff --git a/main/src/cgeo/geocaching/gcvote/GCVote.java b/main/src/cgeo/geocaching/gcvote/GCVote.java index fa17775..a053f31 100644 --- a/main/src/cgeo/geocaching/gcvote/GCVote.java +++ b/main/src/cgeo/geocaching/gcvote/GCVote.java @@ -1,7 +1,7 @@ package cgeo.geocaching.gcvote; +import cgeo.geocaching.Geocache; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgCache; import cgeo.geocaching.network.Network; import cgeo.geocaching.network.Parameters; import cgeo.geocaching.utils.LeastRecentlyUsedMap; @@ -13,6 +13,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,31 +39,16 @@ public final class GCVote { * @return */ public static GCVoteRating getRating(String guid, String geocode) { - List<String> guids = null; - List<String> geocodes = null; - - if (StringUtils.isNotBlank(guid)) { - - GCVoteRating rating = ratingsCache.get(guid); - if (rating != null) { - return rating; - } - guids = new ArrayList<String>(); - guids.add(guid); - } else if (StringUtils.isNotBlank(geocode)) { - geocodes = new ArrayList<String>(); - geocodes.add(geocode); - } else { - return null; + if (StringUtils.isNotBlank(guid) && ratingsCache.containsKey(guid)) { + return ratingsCache.get(guid); } - final Map<String, GCVoteRating> ratings = getRating(guids, geocodes); - - if (MapUtils.isEmpty(ratings)) { - return null; - } + final Map<String, GCVoteRating> ratings = getRating(singletonOrNull(guid), singletonOrNull(geocode)); + return MapUtils.isNotEmpty(ratings) ? ratings.values().iterator().next() : null; + } - return ratings.values().iterator().next(); + private static List<String> singletonOrNull(final String item) { + return StringUtils.isNotBlank(item) ? Collections.singletonList(item) : null; } /** @@ -192,7 +178,7 @@ public final class GCVote { * @param vote * @return */ - public static boolean setRating(cgCache cache, double vote) { + public static boolean setRating(Geocache cache, double vote) { if (!cache.supportsGCVote()) { return false; } @@ -221,13 +207,13 @@ public final class GCVote { return result.trim().equalsIgnoreCase("ok"); } - public static void loadRatings(ArrayList<cgCache> caches) { + public static void loadRatings(ArrayList<Geocache> caches) { if (!Settings.isRatingWanted()) { return; } final ArrayList<String> guids = new ArrayList<String>(caches.size()); - for (final cgCache cache : caches) { + for (final Geocache cache : caches) { String guid = cache.getGuid(); if (StringUtils.isNotBlank(guid)) { guids.add(guid); @@ -243,7 +229,7 @@ public final class GCVote { if (MapUtils.isNotEmpty(ratings)) { // save found cache coordinates - for (cgCache cache : caches) { + for (Geocache cache : caches) { if (ratings.containsKey(cache.getGuid())) { GCVoteRating rating = ratings.get(cache.getGuid()); diff --git a/main/src/cgeo/geocaching/geopoint/Geopoint.java b/main/src/cgeo/geocaching/geopoint/Geopoint.java index fc5bfbc..a4821b9 100644 --- a/main/src/cgeo/geocaching/geopoint/Geopoint.java +++ b/main/src/cgeo/geocaching/geopoint/Geopoint.java @@ -104,11 +104,9 @@ public final class Geopoint implements ICoordinates, Parcelable { * @param lonDegFrac */ public Geopoint(final String latDir, final String latDeg, final String latDegFrac, - final String lonDir, final String lonDeg, final String lonDegFrac) { - latitude = Double.parseDouble(latDeg + "." + addZeros(Integer.parseInt(latDegFrac), 5)) * - getLatSign(latDir); - longitude = Double.parseDouble(lonDeg + "." + addZeros(Integer.parseInt(lonDegFrac), 5)) * - getLonSign(lonDir); + final String lonDir, final String lonDeg, final String lonDegFrac) { + this(getLatSign(latDir) + latDeg + "." + addZeros(latDegFrac, 5), + getLonSign(lonDir) + lonDeg + "." + addZeros(lonDegFrac, 5)); } /** @@ -124,11 +122,9 @@ public final class Geopoint implements ICoordinates, Parcelable { * @param lonMinFrac */ public Geopoint(final String latDir, final String latDeg, final String latMin, final String latMinFrac, - final String lonDir, final String lonDeg, final String lonMin, final String lonMinFrac) { - latitude = (Double.parseDouble(latDeg) + Double.parseDouble(latMin + "." + addZeros(Integer.parseInt(latMinFrac), 3)) / 60) * - (getLatSign(latDir)); - longitude = (Double.parseDouble(lonDeg) + Double.parseDouble(lonMin + "." + addZeros(Integer.parseInt(lonMinFrac), 3)) / 60) * - (getLonSign(lonDir)); + final String lonDir, final String lonDeg, final String lonMin, final String lonMinFrac) { + this(latDir + " " + latDeg + " " + latMin + "." + addZeros(latMinFrac, 3), + lonDir + " " + lonDeg + " " + lonMin + "." + addZeros(lonMinFrac, 3)); } /** @@ -147,10 +143,8 @@ public final class Geopoint implements ICoordinates, Parcelable { */ public Geopoint(final String latDir, final String latDeg, final String latMin, final String latSec, final String latSecFrac, final String lonDir, final String lonDeg, final String lonMin, final String lonSec, final String lonSecFrac) { - latitude = (Double.parseDouble(latDeg) + Double.parseDouble(latMin) / 60 + Double.parseDouble(latSec + "." + addZeros(Integer.parseInt(latSecFrac), 3)) / 3600) * - (getLatSign(latDir)); - longitude = (Double.parseDouble(lonDeg) + Double.parseDouble(lonMin) / 60 + Double.parseDouble(lonSec + "." + addZeros(Integer.parseInt(lonSecFrac), 3)) / 3600) * - (getLonSign(lonDir)); + this(latDir + " " + latDeg + " " + latMin + " " + latSec + "." + addZeros(latSecFrac, 3), + lonDir + " " + lonDeg + " " + lonMin + " " + lonSec + "." + addZeros(lonSecFrac, 3)); } /** @@ -580,16 +574,15 @@ public final class Geopoint implements ICoordinates, Parcelable { return (Math.abs(deg) * 3600) % 60; } - private static String addZeros(final int value, final int len) { - return StringUtils.leftPad(Integer.toString(value), len, '0'); + private static String addZeros(final String value, final int len) { + return StringUtils.leftPad(value.trim(), len, '0'); } - private static int getLonSign(final String lonDir) { - return "W".equalsIgnoreCase(lonDir) ? -1 : 1; + private static String getLonSign(final String lonDir) { + return "W".equalsIgnoreCase(lonDir) ? "-" : ""; } - private static int getLatSign(final String latDir) { - return "S".equalsIgnoreCase(latDir) ? -1 : 1; + private static String getLatSign(final String latDir) { + return "S".equalsIgnoreCase(latDir) ? "-" : ""; } - } diff --git a/main/src/cgeo/geocaching/geopoint/GeopointParser.java b/main/src/cgeo/geocaching/geopoint/GeopointParser.java index 97a9ec8..ba86e70 100644 --- a/main/src/cgeo/geocaching/geopoint/GeopointParser.java +++ b/main/src/cgeo/geocaching/geopoint/GeopointParser.java @@ -11,6 +11,7 @@ import java.util.regex.Pattern; * Parse coordinates. */ class GeopointParser { + private static class ResultWrapper { final double result; final int matcherPos; @@ -23,12 +24,13 @@ class GeopointParser { } } - // ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 ) - private static final Pattern patternLat = Pattern.compile("\\b([NS])\\s*(\\d+)°?(?:\\s*(\\d+)(?:[.,](\\d+)|'?\\s*(\\d+(?:[.,]\\d+)?)(?:''|\")?)?)?", Pattern.CASE_INSENSITIVE); - private static final Pattern patternLon = Pattern.compile("\\b([WE])\\s*(\\d+)°?(?:\\s*(\\d+)(?:[.,](\\d+)|'?\\s*(\\d+(?:[.,]\\d+)?)(?:''|\")?)?)?", Pattern.CASE_INSENSITIVE); + // ( 1 ) ( 2 ) ( 3 ) ( 4 ) ( 5 ) + private static final Pattern PATTERN_LAT = Pattern.compile("\\b([NS])\\s*(\\d+)°?(?:\\s*(\\d+)(?:[.,](\\d+)|'?\\s*(\\d+(?:[.,]\\d+)?)(?:''|\")?)?)?", Pattern.CASE_INSENSITIVE); + private static final Pattern PATTERN_LON = Pattern.compile("\\b([WE])\\s*(\\d+)°?(?:\\s*(\\d+)(?:[.,](\\d+)|'?\\s*(\\d+(?:[.,]\\d+)?)(?:''|\")?)?)?", Pattern.CASE_INSENSITIVE); + + private static final Pattern PATTERN_BAD_BLANK = Pattern.compile("(\\d)[,.] (\\d{2,})"); - enum LatLon - { + enum LatLon { LAT, LON } @@ -53,8 +55,7 @@ class GeopointParser { * @throws Geopoint.ParseException * if lat or lon could not be parsed */ - public static Geopoint parse(final String text) - { + public static Geopoint parse(final String text) { final ResultWrapper latitudeWrapper = parseHelper(text, LatLon.LAT); final double lat = latitudeWrapper.result; // cut away the latitude part when parsing the longitude @@ -90,8 +91,7 @@ class GeopointParser { * @throws Geopoint.ParseException * if lat or lon could not be parsed */ - public static Geopoint parse(final String latitude, final String longitude) - { + public static Geopoint parse(final String latitude, final String longitude) { final double lat = parseLatitude(latitude); final double lon = parseLongitude(longitude); @@ -102,11 +102,13 @@ class GeopointParser { * (non JavaDoc) * Helper for coordinates-parsing. */ - private static ResultWrapper parseHelper(final String text, final LatLon latlon) - { + private static ResultWrapper parseHelper(final String text, final LatLon latlon) { + + MatcherWrapper matcher = new MatcherWrapper(PATTERN_BAD_BLANK, text); + String replaceSpaceAfterComma = matcher.replaceAll("$1.$2"); - final Pattern pattern = LatLon.LAT == latlon ? patternLat : patternLon; - final MatcherWrapper matcher = new MatcherWrapper(pattern, text); + final Pattern pattern = LatLon.LAT == latlon ? PATTERN_LAT : PATTERN_LON; + matcher = new MatcherWrapper(pattern, replaceSpaceAfterComma); if (matcher.find()) { final double sign = matcher.group(1).equalsIgnoreCase("S") || matcher.group(1).equalsIgnoreCase("W") ? -1.0 : 1.0; @@ -154,8 +156,7 @@ class GeopointParser { * @throws Geopoint.ParseException * if latitude could not be parsed */ - public static double parseLatitude(final String text) - { + public static double parseLatitude(final String text) { return parseHelper(text, LatLon.LAT).result; } @@ -169,8 +170,7 @@ class GeopointParser { * @throws Geopoint.ParseException * if longitude could not be parsed */ - public static double parseLongitude(final String text) - { + public static double parseLongitude(final String text) { return parseHelper(text, LatLon.LON).result; } } diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java index 47ca240..c917a37 100644 --- a/main/src/cgeo/geocaching/maps/CGeoMap.java +++ b/main/src/cgeo/geocaching/maps/CGeoMap.java @@ -1,15 +1,13 @@ package cgeo.geocaching.maps; import cgeo.geocaching.DirectionProvider; +import cgeo.geocaching.Geocache; import cgeo.geocaching.IGeoData; -import cgeo.geocaching.IWaypoint; -import cgeo.geocaching.LiveMapInfo; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; import cgeo.geocaching.Settings; import cgeo.geocaching.StoredList; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.cgeocaches; @@ -32,11 +30,13 @@ import cgeo.geocaching.maps.interfaces.MapProvider; import cgeo.geocaching.maps.interfaces.MapSource; import cgeo.geocaching.maps.interfaces.MapViewImpl; import cgeo.geocaching.maps.interfaces.OnMapDragListener; +import cgeo.geocaching.ui.dialog.LiveMapInfoDialogBuilder; import cgeo.geocaching.utils.AngleUtils; import cgeo.geocaching.utils.CancellableHandler; import cgeo.geocaching.utils.GeoDirHandler; import cgeo.geocaching.utils.LeastRecentlyUsedSet; import cgeo.geocaching.utils.Log; +import cgeo.geocaching.utils.RunnableWithArgument; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; @@ -178,7 +178,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto /** Count of caches currently visible */ private int cachesCnt = 0; /** List of caches in the viewport */ - private LeastRecentlyUsedSet<cgCache> caches = null; + private LeastRecentlyUsedSet<Geocache> caches = null; /** List of waypoints in the viewport */ private final LeastRecentlyUsedSet<Waypoint> waypoints = new LeastRecentlyUsedSet<Waypoint>(MAX_CACHES); // storing for offline @@ -336,13 +336,13 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } protected void countVisibleCaches() { - final List<cgCache> protectedCaches = caches.getAsList(); + final List<Geocache> protectedCaches = caches.getAsList(); int count = 0; if (!protectedCaches.isEmpty()) { final Viewport viewport = mapView.getViewport(); - for (final cgCache cache : protectedCaches) { + for (final Geocache cache : protectedCaches) { if (cache != null && cache.getCoords() != null) { if (viewport.contains(cache)) { count++; @@ -370,7 +370,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto app = (cgeoapplication) activity.getApplication(); int countBubbleCnt = cgData.getAllCachesCount(); - caches = new LeastRecentlyUsedSet<cgCache>(MAX_CACHES + countBubbleCnt); + caches = new LeastRecentlyUsedSet<Geocache>(MAX_CACHES + countBubbleCnt); final MapProvider mapProvider = Settings.getMapProvider(); mapItemFactory = mapProvider.getMapItemFactory(); @@ -470,9 +470,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto prepareFilterBar(); if (!app.isLiveMapHintShown() && !Settings.getHideLiveMapHint()) { - Intent hintIntent = new Intent(activity, LiveMapInfo.class); - activity.startActivity(hintIntent); - app.setLiveMapHintShown(); + LiveMapInfoDialogBuilder.create(activity).show(); } } @@ -495,10 +493,13 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto if (!CollectionUtils.isEmpty(dirtyCaches)) { for (String geocode : dirtyCaches) { - cgCache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); - // remove to update the cache - caches.remove(cache); - caches.add(cache); + Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); + if (cache != null) { + // new collection type needs to remove first + caches.remove(cache); + // re-add to update the freshness + caches.add(cache); + } } dirtyCaches.clear(); // Update display @@ -654,42 +655,18 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto return true; } - final LoadDetailsHandler loadDetailsHandler = new LoadDetailsHandler(); - - waitDialog = new ProgressDialog(activity); - waitDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - waitDialog.setCancelable(true); - waitDialog.setCancelMessage(loadDetailsHandler.cancelMessage()); - waitDialog.setMax(detailTotal); - waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - - @Override - public void onCancel(DialogInterface arg0) { - try { - if (loadDetailsThread != null) { - loadDetailsThread.stopIt(); - } - - geoDirUpdate.startDir(); - } catch (Exception e) { - Log.e("cgeocaches.onPrepareOptionsMenu.onCancel", e); - } - } - }); - - float etaTime = detailTotal * 7.0f / 60.0f; - int roundedEta = Math.round(etaTime); - if (etaTime < 0.4) { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); - } else { - waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + roundedEta + " " + res.getQuantityString(R.plurals.caches_eta_mins, roundedEta)); + if (Settings.getChooseList()) { + // let user select list to store cache in + new StoredList.UserInterface(activity).promptForListSelection(R.string.list_title, + new RunnableWithArgument<Integer>() { + @Override + public void run(final Integer selectedListId) { + storeCaches(geocodes, selectedListId); + } + }, true, StoredList.TEMPORARY_LIST_ID); + } else { + storeCaches(geocodes, StoredList.STANDARD_LIST_ID); } - waitDialog.show(); - - detailProgressTime = System.currentTimeMillis(); - - loadDetailsThread = new LoadDetails(loadDetailsHandler, geocodes); - loadDetailsThread.start(); } return true; case MENU_CIRCLE_MODE: @@ -794,11 +771,11 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto */ private Set<String> getGeocodesForCachesInViewport() { final Set<String> geocodes = new HashSet<String>(); - final List<cgCache> cachesProtected = caches.getAsList(); + final List<Geocache> cachesProtected = caches.getAsList(); final Viewport viewport = mapView.getViewport(); - for (final cgCache cache : cachesProtected) { + for (final Geocache cache : cachesProtected) { if (viewport.contains(cache)) { geocodes.add(cache.getGeocode()); } @@ -1051,22 +1028,11 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto // check if map moved or zoomed //TODO Portree Use Rectangle inside with bigger search window. That will stop reloading on every move - boolean moved = false; - - if (liveChanged) { - moved = true; - } else if (isLiveEnabled && !downloaded) { - moved = true; - } else if (viewport == null) { - moved = true; - } else if (zoomNow != zoom) { - moved = true; - } else if (mapMoved(viewport, viewportNow) && (cachesCnt <= 0 || CollectionUtils.isEmpty(caches) || !viewport.includes(viewportNow))) { - moved = true; - } + final boolean moved = liveChanged || (isLiveEnabled && !downloaded) || (viewport == null) || zoomNow != zoom || + (mapMoved(viewport, viewportNow) && (cachesCnt <= 0 || CollectionUtils.isEmpty(caches) || !viewport.includes(viewportNow))); // update title on any change - if (moved || zoomNow != zoom || !viewportNow.equals(viewport)) { + if (moved || !viewportNow.equals(viewport)) { displayHandler.sendEmptyMessage(UPDATE_TITLE); } zoom = zoomNow; @@ -1133,19 +1099,18 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } downloaded = true; - Set<cgCache> cachesFromSearchResult = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_WAYPOINTS); - // to update the caches they have to be removed first - caches.removeAll(cachesFromSearchResult); + Set<Geocache> cachesFromSearchResult = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_WAYPOINTS); + // update the caches caches.addAll(cachesFromSearchResult); if (mapMode == MapMode.LIVE) { final boolean excludeMine = Settings.isExcludeMyCaches(); final boolean excludeDisabled = Settings.isExcludeDisabledCaches(); - final List<cgCache> tempList = caches.getAsList(); + final List<Geocache> tempList = caches.getAsList(); - for (cgCache cache : tempList) { - if ((cache.isFound() && excludeMine) || (cache.isOwn() && excludeMine) || (cache.isDisabled() && excludeDisabled)) { + for (Geocache cache : tempList) { + if ((cache.isFound() && excludeMine) || (cache.isOwner() && excludeMine) || (cache.isDisabled() && excludeDisabled)) { caches.remove(cache); } } @@ -1162,7 +1127,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto else { //All waypoints from the viewed caches - for (cgCache c : caches.getAsList()) { + for (Geocache c : caches.getAsList()) { waypoints.addAll(c.getWaypoints()); } } @@ -1223,9 +1188,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } while (count < 2); if (searchResult != null) { - Set<cgCache> result = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); - // to update the caches they have to be removed first - caches.removeAll(result); + Set<Geocache> result = searchResult.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB); + // update the caches caches.addAll(result); lastSearchResult = searchResult; } @@ -1260,7 +1224,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } // display caches - final List<cgCache> cachesToDisplay = caches.getAsList(); + final List<Geocache> cachesToDisplay = caches.getAsList(); final List<Waypoint> waypointsToDisplay = new ArrayList<Waypoint>(waypoints); final List<CachesOverlayItemImpl> itemsToDisplay = new ArrayList<CachesOverlayItemImpl>(); @@ -1274,15 +1238,15 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto continue; } - itemsToDisplay.add(getItem(waypoint, null, waypoint)); + itemsToDisplay.add(getWaypointItem(waypoint)); } } - for (cgCache cache : cachesToDisplay) { + for (Geocache cache : cachesToDisplay) { if (cache == null || cache.getCoords() == null) { continue; } - itemsToDisplay.add(getItem(cache, cache, null)); + itemsToDisplay.add(getCacheItem(cache)); } overlayCaches.updateItems(itemsToDisplay); @@ -1319,7 +1283,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto final Waypoint waypoint = new Waypoint("some place", waypointTypeIntent != null ? waypointTypeIntent : WaypointType.WAYPOINT, false); waypoint.setCoords(coordsIntent); - final CachesOverlayItemImpl item = getItem(waypoint, null, waypoint); + final CachesOverlayItemImpl item = getWaypointItem(waypoint); overlayCaches.updateItems(item); displayHandler.sendEmptyMessage(INVALIDATE_MAP); @@ -1358,6 +1322,51 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } /** + * store caches, invoked by "store offline" menu item + * + * @param listId + * the list to store the caches in + */ + private void storeCaches(List<String> geocodes, int listId) { + final LoadDetailsHandler loadDetailsHandler = new LoadDetailsHandler(); + + waitDialog = new ProgressDialog(activity); + waitDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + waitDialog.setCancelable(true); + waitDialog.setCancelMessage(loadDetailsHandler.cancelMessage()); + waitDialog.setMax(detailTotal); + waitDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + + @Override + public void onCancel(DialogInterface arg0) { + try { + if (loadDetailsThread != null) { + loadDetailsThread.stopIt(); + } + + geoDirUpdate.startDir(); + } catch (Exception e) { + Log.e("cgeocaches.onPrepareOptionsMenu.onCancel", e); + } + } + }); + + float etaTime = detailTotal * 7.0f / 60.0f; + int roundedEta = Math.round(etaTime); + if (etaTime < 0.4) { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + res.getString(R.string.caches_eta_ltm)); + } else { + waitDialog.setMessage(res.getString(R.string.caches_downloading) + " " + roundedEta + " " + res.getQuantityString(R.plurals.caches_eta_mins, roundedEta)); + } + waitDialog.show(); + + detailProgressTime = System.currentTimeMillis(); + + loadDetailsThread = new LoadDetails(loadDetailsHandler, geocodes, listId); + loadDetailsThread.start(); + } + + /** * Thread to store the caches in the viewport. Started by Activity. */ @@ -1365,11 +1374,13 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto final private CancellableHandler handler; final private List<String> geocodes; + final private int listId; private long last = 0L; - public LoadDetails(final CancellableHandler handler, final List<String> geocodes) { + public LoadDetails(final CancellableHandler handler, final List<String> geocodes, final int listId) { this.handler = handler; this.geocodes = geocodes; + this.listId = listId; } public void stopIt() { @@ -1410,7 +1421,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto break; } - cgCache.storeCache(null, geocode, StoredList.STANDARD_LIST_ID, false, handler); + Geocache.storeCache(null, geocode, listId, false, handler); } } catch (Exception e) { Log.e("cgeocaches.LoadDetails.run", e); @@ -1615,117 +1626,100 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto dirtyCaches.add(geocode); } - /** - * Returns a OverlayItem represented by an icon - * - * @param coord - * The coords - * @param cache - * Cache - * @param waypoint - * Waypoint. Mutally exclusive with cache - * @return - */ - private CachesOverlayItemImpl getItem(final IWaypoint coord, final cgCache cache, final Waypoint waypoint) { - if (cache != null) { - final CachesOverlayItemImpl item = mapItemFactory.getCachesOverlayItem(coord, cache.getType()); - - final int hashcode = new HashCodeBuilder() - .append(cache.isReliableLatLon()) - .append(cache.getType().id) - .append(cache.isDisabled() || cache.isArchived()) - .append(cache.getCacheRealm().id) - .append(cache.isOwn()) - .append(cache.isFound()) - .append(cache.hasUserModifiedCoords()) - .append(cache.getPersonalNote()) - .append(cache.isLogOffline()) - .append(cache.getListId() > 0) - .toHashCode(); - - final LayerDrawable ldFromCache = overlaysCache.get(hashcode); - if (ldFromCache != null) { - item.setMarker(ldFromCache); - return item; - } - - // Set initial capacities to the maximum of layers and insets to avoid dynamic reallocation - final ArrayList<Drawable> layers = new ArrayList<Drawable>(9); - final ArrayList<int[]> insets = new ArrayList<int[]>(8); - - // background: disabled or not - final Drawable marker = getResources().getDrawable(cache.isDisabled() || cache.isArchived() ? cache.getCacheRealm().markerDisabledId : cache.getCacheRealm().markerId); - layers.add(marker); - final int resolution = marker.getIntrinsicWidth() > 40 ? 1 : 0; - // reliable or not - if (!cache.isReliableLatLon()) { - insets.add(INSET_RELIABLE[resolution]); - layers.add(getResources().getDrawable(R.drawable.marker_notreliable)); - } - // cache type - layers.add(getResources().getDrawable(cache.getType().markerId)); - insets.add(INSET_TYPE[resolution]); - // own - if (cache.isOwn()) { - layers.add(getResources().getDrawable(R.drawable.marker_own)); - insets.add(INSET_OWN[resolution]); - // if not, checked if stored - } else if (cache.getListId() > 0) { - layers.add(getResources().getDrawable(R.drawable.marker_stored)); - insets.add(INSET_OWN[resolution]); - } - // found - if (cache.isFound()) { - layers.add(getResources().getDrawable(R.drawable.marker_found)); - insets.add(INSET_FOUND[resolution]); - // if not, perhaps logged offline - } else if (cache.isLogOffline()) { - layers.add(getResources().getDrawable(R.drawable.marker_found_offline)); - insets.add(INSET_FOUND[resolution]); - } - // user modified coords - if (cache.hasUserModifiedCoords()) { - layers.add(getResources().getDrawable(R.drawable.marker_usermodifiedcoords)); - insets.add(INSET_USERMODIFIEDCOORDS[resolution]); - } - // personal note - if (cache.getPersonalNote() != null) { - layers.add(getResources().getDrawable(R.drawable.marker_personalnote)); - insets.add(INSET_PERSONALNOTE[resolution]); - } - - final LayerDrawable ld = new LayerDrawable(layers.toArray(new Drawable[layers.size()])); - - int index = 1; - for (final int[] inset : insets) { - ld.setLayerInset(index++, inset[0], inset[1], inset[2], inset[3]); - } - - overlaysCache.put(hashcode, ld); - - item.setMarker(ld); + private CachesOverlayItemImpl getCacheItem(final Geocache cache) { + final CachesOverlayItemImpl item = mapItemFactory.getCachesOverlayItem(cache, cache.getType()); + + final int hashcode = new HashCodeBuilder() + .append(cache.isReliableLatLon()) + .append(cache.getType().id) + .append(cache.isDisabled() || cache.isArchived()) + .append(cache.getCacheRealm().id) + .append(cache.isOwner()) + .append(cache.isFound()) + .append(cache.hasUserModifiedCoords()) + .append(cache.getPersonalNote()) + .append(cache.isLogOffline()) + .append(cache.getListId() > 0) + .toHashCode(); + + final LayerDrawable ldFromCache = overlaysCache.get(hashcode); + if (ldFromCache != null) { + item.setMarker(ldFromCache); return item; } - if (waypoint != null) { - - final CachesOverlayItemImpl item = mapItemFactory.getCachesOverlayItem(coord, null); - Drawable[] layers = new Drawable[2]; - layers[0] = getResources().getDrawable(R.drawable.marker); - layers[1] = getResources().getDrawable(waypoint.getWaypointType().markerId); + // Set initial capacities to the maximum of layers and insets to avoid dynamic reallocation + final ArrayList<Drawable> layers = new ArrayList<Drawable>(9); + final ArrayList<int[]> insets = new ArrayList<int[]>(8); + + // background: disabled or not + final Drawable marker = getResources().getDrawable(cache.isDisabled() || cache.isArchived() ? cache.getCacheRealm().markerDisabledId : cache.getCacheRealm().markerId); + layers.add(marker); + final int resolution = marker.getIntrinsicWidth() > 40 ? 1 : 0; + // reliable or not + if (!cache.isReliableLatLon()) { + insets.add(INSET_RELIABLE[resolution]); + layers.add(getResources().getDrawable(R.drawable.marker_notreliable)); + } + // cache type + layers.add(getResources().getDrawable(cache.getType().markerId)); + insets.add(INSET_TYPE[resolution]); + // own + if (cache.isOwner()) { + layers.add(getResources().getDrawable(R.drawable.marker_own)); + insets.add(INSET_OWN[resolution]); + // if not, checked if stored + } else if (cache.getListId() > 0) { + layers.add(getResources().getDrawable(R.drawable.marker_stored)); + insets.add(INSET_OWN[resolution]); + } + // found + if (cache.isFound()) { + layers.add(getResources().getDrawable(R.drawable.marker_found)); + insets.add(INSET_FOUND[resolution]); + // if not, perhaps logged offline + } else if (cache.isLogOffline()) { + layers.add(getResources().getDrawable(R.drawable.marker_found_offline)); + insets.add(INSET_FOUND[resolution]); + } + // user modified coords + if (cache.hasUserModifiedCoords()) { + layers.add(getResources().getDrawable(R.drawable.marker_usermodifiedcoords)); + insets.add(INSET_USERMODIFIEDCOORDS[resolution]); + } + // personal note + if (cache.getPersonalNote() != null) { + layers.add(getResources().getDrawable(R.drawable.marker_personalnote)); + insets.add(INSET_PERSONALNOTE[resolution]); + } + + final LayerDrawable ld = new LayerDrawable(layers.toArray(new Drawable[layers.size()])); + + int index = 1; + for (final int[] inset : insets) { + ld.setLayerInset(index++, inset[0], inset[1], inset[2], inset[3]); + } + + overlaysCache.put(hashcode, ld); + + item.setMarker(ld); + return item; + } - LayerDrawable ld = new LayerDrawable(layers); - if (layers[0].getIntrinsicWidth() > 40) { - ld.setLayerInset(1, 9, 12, 10, 13); - } else { - ld.setLayerInset(1, 9, 12, 8, 12); - } - item.setMarker(ld); - return item; + private CachesOverlayItemImpl getWaypointItem(final Waypoint waypoint) { + final CachesOverlayItemImpl item = mapItemFactory.getCachesOverlayItem(waypoint, null); + final Drawable[] layers = new Drawable[] { + getResources().getDrawable(R.drawable.marker), + getResources().getDrawable(waypoint.getWaypointType().markerId) + }; + final LayerDrawable ld = new LayerDrawable(layers); + if (layers[0].getIntrinsicWidth() > 40) { + ld.setLayerInset(1, 9, 12, 10, 13); + } else { + ld.setLayerInset(1, 9, 12, 8, 12); } - - return null; - + item.setMarker(ld); + return item; } } diff --git a/main/src/cgeo/geocaching/maps/CachesOverlay.java b/main/src/cgeo/geocaching/maps/CachesOverlay.java index fe1a19b..9bb4cef 100644 --- a/main/src/cgeo/geocaching/maps/CachesOverlay.java +++ b/main/src/cgeo/geocaching/maps/CachesOverlay.java @@ -5,7 +5,7 @@ import cgeo.geocaching.IWaypoint; import cgeo.geocaching.R; import cgeo.geocaching.Settings; import cgeo.geocaching.WaypointPopup; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.cgData; import cgeo.geocaching.activity.Progress; import cgeo.geocaching.connector.gc.GCMap; @@ -227,7 +227,7 @@ public class CachesOverlay extends AbstractItemizedOverlay { final IWaypoint coordinate = item.getCoord(); if (StringUtils.isNotBlank(coordinate.getCoordType()) && coordinate.getCoordType().equalsIgnoreCase("cache") && StringUtils.isNotBlank(coordinate.getGeocode())) { - cgCache cache = cgData.loadCache(coordinate.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB); + Geocache cache = cgData.loadCache(coordinate.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB); RequestDetailsThread requestDetailsThread = new RequestDetailsThread(cache); if (!requestDetailsThread.requestRequired()) { // don't show popup if we have enough details @@ -237,7 +237,7 @@ public class CachesOverlay extends AbstractItemizedOverlay { return true; } - if (coordinate.getCoordType() != null && coordinate.getCoordType().equalsIgnoreCase("waypoint") && coordinate.getId() > 0) { + if (coordinate.getCoordType() != null && coordinate.getCoordType().equalsIgnoreCase("waypoint") && coordinate.getId() >= 0) { CGeoMap.markCacheAsDirty(coordinate.getGeocode()); WaypointPopup.startActivity(context, coordinate.getId(), coordinate.getGeocode()); } else { @@ -280,9 +280,9 @@ public class CachesOverlay extends AbstractItemizedOverlay { private class RequestDetailsThread extends Thread { - private final cgCache cache; + private final Geocache cache; - public RequestDetailsThread(cgCache cache) { + public RequestDetailsThread(Geocache cache) { this.cache = cache; } diff --git a/main/src/cgeo/geocaching/network/Network.java b/main/src/cgeo/geocaching/network/Network.java index 2545f4d..a4155be 100644 --- a/main/src/cgeo/geocaching/network/Network.java +++ b/main/src/cgeo/geocaching/network/Network.java @@ -383,13 +383,21 @@ public abstract class Network { return response != null && response.getStatusLine().getStatusCode() == 200; } + /** + * Get the result of a GET HTTP request returning a JSON body. + * + * @param uri the base URI of the GET HTTP request + * @param params the query parameters, or <code>null</code> if there are none + * @return a JSON object if the request was successful and the body could be decoded, <code>null</code> otherwise + */ public static JSONObject requestJSON(final String uri, final Parameters params) { final HttpResponse response = request("GET", uri, params, new Parameters("Accept", "application/json, text/javascript, */*; q=0.01"), null); - if (isSuccess(response)) { + final String responseData = Network.getResponseData(response, false); + if (responseData != null) { try { - return new JSONObject(Network.getResponseData(response)); + return new JSONObject(responseData); } catch (final JSONException e) { - Log.e("Network.requestJSON", e); + Log.w("Network.requestJSON", e); } } @@ -406,10 +414,26 @@ public abstract class Network { } } + /** + * Get the body of a HTTP response. + * + * {@link BaseUtils#replaceWhitespace(String)} will be called on the result + * + * @param response a HTTP response, which can be null + * @return the body if the response comes from a successful HTTP request, <code>null</code> otherwise + */ public static String getResponseData(final HttpResponse response) { return Network.getResponseData(response, true); } + /** + * Get the body of a HTTP response. + * + * @param response a HTTP response, which can be null + * @param replaceWhitespace <code>true</code> if {@link BaseUtils#replaceWhitespace(String)} + * should be called on the body + * @return the body if the response comes from a successful HTTP request, <code>null</code> otherwise + */ public static String getResponseData(final HttpResponse response, boolean replaceWhitespace) { if (!isSuccess(response)) { return null; diff --git a/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java b/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java index aebecd2..2dee713 100644 --- a/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java +++ b/main/src/cgeo/geocaching/sorting/AbstractCacheComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.utils.Log; @@ -11,7 +11,7 @@ import cgeo.geocaching.utils.Log; public abstract class AbstractCacheComparator implements CacheComparator { @Override - public final int compare(final cgCache cache1, final cgCache cache2) { + public final int compare(final Geocache cache1, final Geocache cache2) { try { // first check that we have all necessary data for the comparison if (!canCompare(cache1, cache2)) { @@ -31,7 +31,7 @@ public abstract class AbstractCacheComparator implements CacheComparator { * @param cache2 * @return */ - protected abstract boolean canCompare(final cgCache cache1, final cgCache cache2); + protected abstract boolean canCompare(final Geocache cache1, final Geocache cache2); /** * Compares two caches. Logging and exception handling is implemented outside this method already. @@ -44,5 +44,5 @@ public abstract class AbstractCacheComparator implements CacheComparator { * @return an integer < 0 if cache1 is less than cache2, 0 if they are equal, and > 0 if cache1 is greater than * cache2. */ - protected abstract int compareCaches(final cgCache cache1, final cgCache cache2); + protected abstract int compareCaches(final Geocache cache1, final Geocache cache2); } diff --git a/main/src/cgeo/geocaching/sorting/CacheComparator.java b/main/src/cgeo/geocaching/sorting/CacheComparator.java index c9b5150..7932729 100644 --- a/main/src/cgeo/geocaching/sorting/CacheComparator.java +++ b/main/src/cgeo/geocaching/sorting/CacheComparator.java @@ -2,8 +2,8 @@ package cgeo.geocaching.sorting; import java.util.Comparator; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; -public interface CacheComparator extends Comparator<cgCache> { +public interface CacheComparator extends Comparator<Geocache> { } diff --git a/main/src/cgeo/geocaching/sorting/ComparatorUserInterface.java b/main/src/cgeo/geocaching/sorting/ComparatorUserInterface.java index bc63ef6..4d1a994 100644 --- a/main/src/cgeo/geocaching/sorting/ComparatorUserInterface.java +++ b/main/src/cgeo/geocaching/sorting/ComparatorUserInterface.java @@ -43,7 +43,7 @@ public class ComparatorUserInterface { register(R.string.caches_sort_date_hidden, DateComparator.class); register(R.string.caches_sort_difficulty, DifficultyComparator.class); register(R.string.caches_sort_finds, FindsComparator.class); - register(R.string.caches_sort_gccode, GeocodeComparator.class); + register(R.string.caches_sort_geocode, GeocodeComparator.class); register(R.string.caches_sort_inventory, InventoryComparator.class); register(R.string.caches_sort_name, NameComparator.class); register(R.string.caches_sort_favorites, PopularityComparator.class); diff --git a/main/src/cgeo/geocaching/sorting/DateComparator.java b/main/src/cgeo/geocaching/sorting/DateComparator.java index 3136d47..3464103 100644 --- a/main/src/cgeo/geocaching/sorting/DateComparator.java +++ b/main/src/cgeo/geocaching/sorting/DateComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.cgeoapplication; import java.util.ArrayList; @@ -12,19 +12,19 @@ import java.util.Date; public class DateComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { + protected boolean canCompare(Geocache cache1, Geocache cache2) { return true; } @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { + protected int compareCaches(Geocache cache1, Geocache cache2) { final Date date1 = cache1.getHiddenDate(); final Date date2 = cache2.getHiddenDate(); if (date1 != null && date2 != null) { final int dateDifference = date1.compareTo(date2); // for equal dates, sort by distance if (dateDifference == 0) { - final ArrayList<cgCache> list = new ArrayList<cgCache>(); + final ArrayList<Geocache> list = new ArrayList<Geocache>(); list.add(cache1); list.add(cache2); final DistanceComparator distanceComparator = new DistanceComparator(cgeoapplication.getInstance().currentGeo().getCoords(), list); diff --git a/main/src/cgeo/geocaching/sorting/DifficultyComparator.java b/main/src/cgeo/geocaching/sorting/DifficultyComparator.java index 123bab9..73d12fa 100644 --- a/main/src/cgeo/geocaching/sorting/DifficultyComparator.java +++ b/main/src/cgeo/geocaching/sorting/DifficultyComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; /** * sorts caches by difficulty @@ -9,12 +9,12 @@ import cgeo.geocaching.cgCache; public class DifficultyComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { + protected boolean canCompare(Geocache cache1, Geocache cache2) { return cache1.getDifficulty() != 0.0 && cache2.getDifficulty() != 0.0; } @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { + protected int compareCaches(final Geocache cache1, final Geocache cache2) { return Float.compare(cache1.getDifficulty(), cache2.getDifficulty()); } }
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/sorting/DistanceComparator.java b/main/src/cgeo/geocaching/sorting/DistanceComparator.java index 781359a..7b0afbb 100644 --- a/main/src/cgeo/geocaching/sorting/DistanceComparator.java +++ b/main/src/cgeo/geocaching/sorting/DistanceComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.geopoint.Geopoint; import java.util.List; @@ -12,10 +12,10 @@ import java.util.List; public class DistanceComparator extends AbstractCacheComparator { final private Geopoint coords; - final private List<cgCache> list; + final private List<Geocache> list; private boolean cachedDistances; - public DistanceComparator(final Geopoint coords, List<cgCache> list) { + public DistanceComparator(final Geopoint coords, List<Geocache> list) { this.coords = coords; this.list = list; } @@ -27,7 +27,7 @@ public class DistanceComparator extends AbstractCacheComparator { if (cachedDistances) { return; } - for (cgCache cache : list) { + for (Geocache cache : list) { if (cache.getCoords() != null) { cache.setDistance(coords.distanceTo(cache.getCoords())); } @@ -39,12 +39,12 @@ public class DistanceComparator extends AbstractCacheComparator { } @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { + protected boolean canCompare(Geocache cache1, Geocache cache2) { return true; } @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { + protected int compareCaches(final Geocache cache1, final Geocache cache2) { calculateAllDistances(); if (cache1.getCoords() == null && cache2.getCoords() == null) { return 0; diff --git a/main/src/cgeo/geocaching/sorting/FindsComparator.java b/main/src/cgeo/geocaching/sorting/FindsComparator.java index 47e3844..ba929b8 100644 --- a/main/src/cgeo/geocaching/sorting/FindsComparator.java +++ b/main/src/cgeo/geocaching/sorting/FindsComparator.java @@ -1,24 +1,24 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.LogType; public class FindsComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { + protected boolean canCompare(Geocache cache1, Geocache cache2) { return cache1.getLogCounts() != null && cache2.getLogCounts() != null; } @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { + protected int compareCaches(Geocache cache1, Geocache cache2) { int finds1 = getFindsCount(cache1); int finds2 = getFindsCount(cache2); return finds2 - finds1; } - private static int getFindsCount(cgCache cache) { + private static int getFindsCount(Geocache cache) { if (cache.getLogCounts().isEmpty()) { cache.setLogCounts(cgData.loadLogCounts(cache.getGeocode())); } diff --git a/main/src/cgeo/geocaching/sorting/GeocodeComparator.java b/main/src/cgeo/geocaching/sorting/GeocodeComparator.java index fb93c0e..412649a 100644 --- a/main/src/cgeo/geocaching/sorting/GeocodeComparator.java +++ b/main/src/cgeo/geocaching/sorting/GeocodeComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import org.apache.commons.lang3.StringUtils; @@ -11,13 +11,13 @@ import org.apache.commons.lang3.StringUtils; public class GeocodeComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { + protected boolean canCompare(Geocache cache1, Geocache cache2) { return StringUtils.isNotBlank(cache1.getGeocode()) && StringUtils.isNotBlank(cache2.getGeocode()); } @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { + protected int compareCaches(final Geocache cache1, final Geocache cache2) { final int lengthDiff = cache1.getGeocode().length() - cache2.getGeocode().length(); return lengthDiff != 0 ? lengthDiff : cache1.getGeocode().compareToIgnoreCase(cache2.getGeocode()); } diff --git a/main/src/cgeo/geocaching/sorting/InventoryComparator.java b/main/src/cgeo/geocaching/sorting/InventoryComparator.java index fb1360e..73ea2c5 100644 --- a/main/src/cgeo/geocaching/sorting/InventoryComparator.java +++ b/main/src/cgeo/geocaching/sorting/InventoryComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; /** * sorts caches by number of items in inventory @@ -8,12 +8,12 @@ import cgeo.geocaching.cgCache; public class InventoryComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(final cgCache cache1, final cgCache cache2) { + protected boolean canCompare(final Geocache cache1, final Geocache cache2) { return true; } @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { + protected int compareCaches(final Geocache cache1, final Geocache cache2) { return cache2.getInventoryItems() - cache1.getInventoryItems(); } } diff --git a/main/src/cgeo/geocaching/sorting/InverseComparator.java b/main/src/cgeo/geocaching/sorting/InverseComparator.java index d2fa085..1dc76e2 100644 --- a/main/src/cgeo/geocaching/sorting/InverseComparator.java +++ b/main/src/cgeo/geocaching/sorting/InverseComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; /** * comparator which inverses the sort order of the given other comparator @@ -15,7 +15,7 @@ public class InverseComparator implements CacheComparator { } @Override - public int compare(cgCache lhs, cgCache rhs) { + public int compare(Geocache lhs, Geocache rhs) { return originalComparator.compare(rhs, lhs); } diff --git a/main/src/cgeo/geocaching/sorting/NameComparator.java b/main/src/cgeo/geocaching/sorting/NameComparator.java index c32bc48..b432ad0 100644 --- a/main/src/cgeo/geocaching/sorting/NameComparator.java +++ b/main/src/cgeo/geocaching/sorting/NameComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import org.apache.commons.lang3.StringUtils; @@ -11,12 +11,12 @@ import org.apache.commons.lang3.StringUtils; public class NameComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { + protected boolean canCompare(Geocache cache1, Geocache cache2) { return StringUtils.isNotBlank(cache1.getName()) && StringUtils.isNotBlank(cache2.getName()); } @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { + protected int compareCaches(Geocache cache1, Geocache cache2) { return cache1.getNameForSorting().compareToIgnoreCase(cache2.getNameForSorting()); } } diff --git a/main/src/cgeo/geocaching/sorting/PopularityComparator.java b/main/src/cgeo/geocaching/sorting/PopularityComparator.java index 62ad9a9..e256654 100644 --- a/main/src/cgeo/geocaching/sorting/PopularityComparator.java +++ b/main/src/cgeo/geocaching/sorting/PopularityComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; /** * sorts caches by popularity (favorite count) @@ -9,12 +9,12 @@ import cgeo.geocaching.cgCache; public class PopularityComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(final cgCache cache1, final cgCache cache2) { + protected boolean canCompare(final Geocache cache1, final Geocache cache2) { return true; } @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { + protected int compareCaches(final Geocache cache1, final Geocache cache2) { return cache2.getFavoritePoints() - cache1.getFavoritePoints(); } } diff --git a/main/src/cgeo/geocaching/sorting/RatingComparator.java b/main/src/cgeo/geocaching/sorting/RatingComparator.java index be071c5..72cf6c8 100644 --- a/main/src/cgeo/geocaching/sorting/RatingComparator.java +++ b/main/src/cgeo/geocaching/sorting/RatingComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; /** * sorts caches by gcvote.com rating @@ -9,12 +9,12 @@ import cgeo.geocaching.cgCache; public class RatingComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(final cgCache cache1, final cgCache cache2) { + protected boolean canCompare(final Geocache cache1, final Geocache cache2) { return true; } @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { + protected int compareCaches(final Geocache cache1, final Geocache cache2) { final float rating1 = cache1.getRating(); final float rating2 = cache2.getRating(); // Voting can be disabled for caches, then assume an average rating instead diff --git a/main/src/cgeo/geocaching/sorting/SizeComparator.java b/main/src/cgeo/geocaching/sorting/SizeComparator.java index f946522..d128822 100644 --- a/main/src/cgeo/geocaching/sorting/SizeComparator.java +++ b/main/src/cgeo/geocaching/sorting/SizeComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; /** * sorts caches by size @@ -9,12 +9,12 @@ import cgeo.geocaching.cgCache; public class SizeComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { + protected boolean canCompare(Geocache cache1, Geocache cache2) { return cache1.getSize() != null && cache2.getSize() != null; } @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { + protected int compareCaches(Geocache cache1, Geocache cache2) { return cache2.getSize().comparable - cache1.getSize().comparable; } }
\ No newline at end of file diff --git a/main/src/cgeo/geocaching/sorting/StateComparator.java b/main/src/cgeo/geocaching/sorting/StateComparator.java index bda514f..b99c3c0 100644 --- a/main/src/cgeo/geocaching/sorting/StateComparator.java +++ b/main/src/cgeo/geocaching/sorting/StateComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; /** * sort caches by state (normal, disabled, archived) @@ -9,16 +9,16 @@ import cgeo.geocaching.cgCache; public class StateComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(final cgCache cache1, final cgCache cache2) { + protected boolean canCompare(final Geocache cache1, final Geocache cache2) { return true; } @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { + protected int compareCaches(final Geocache cache1, final Geocache cache2) { return getState(cache1) - getState(cache2); } - private static int getState(final cgCache cache) { + private static int getState(final Geocache cache) { if (cache.isDisabled()) { return 1; } diff --git a/main/src/cgeo/geocaching/sorting/StorageTimeComparator.java b/main/src/cgeo/geocaching/sorting/StorageTimeComparator.java index 32bef32..78ba742 100644 --- a/main/src/cgeo/geocaching/sorting/StorageTimeComparator.java +++ b/main/src/cgeo/geocaching/sorting/StorageTimeComparator.java @@ -1,16 +1,16 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; public class StorageTimeComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { + protected boolean canCompare(Geocache cache1, Geocache cache2) { return true; } @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { + protected int compareCaches(Geocache cache1, Geocache cache2) { if (cache1.getUpdated() < cache2.getUpdated()) { return -1; } diff --git a/main/src/cgeo/geocaching/sorting/TerrainComparator.java b/main/src/cgeo/geocaching/sorting/TerrainComparator.java index 9058a3c..be1e9bb 100644 --- a/main/src/cgeo/geocaching/sorting/TerrainComparator.java +++ b/main/src/cgeo/geocaching/sorting/TerrainComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; /** * sorts caches by terrain rating @@ -9,12 +9,12 @@ import cgeo.geocaching.cgCache; public class TerrainComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(final cgCache cache1, final cgCache cache2) { + protected boolean canCompare(final Geocache cache1, final Geocache cache2) { return cache1.getTerrain() != 0.0 && cache2.getTerrain() != 0.0; } @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { + protected int compareCaches(final Geocache cache1, final Geocache cache2) { return Float.compare(cache1.getTerrain(), cache2.getTerrain()); } } diff --git a/main/src/cgeo/geocaching/sorting/VisitComparator.java b/main/src/cgeo/geocaching/sorting/VisitComparator.java index 46d8c58..27d3170 100644 --- a/main/src/cgeo/geocaching/sorting/VisitComparator.java +++ b/main/src/cgeo/geocaching/sorting/VisitComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; /** * sorts caches by last visited date @@ -9,12 +9,12 @@ import cgeo.geocaching.cgCache; public class VisitComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(final cgCache cache1, final cgCache cache2) { + protected boolean canCompare(final Geocache cache1, final Geocache cache2) { return true; } @Override - protected int compareCaches(final cgCache cache1, final cgCache cache2) { + protected int compareCaches(final Geocache cache1, final Geocache cache2) { return Long.valueOf(cache2.getVisitedDate()).compareTo(cache1.getVisitedDate()); } } diff --git a/main/src/cgeo/geocaching/sorting/VoteComparator.java b/main/src/cgeo/geocaching/sorting/VoteComparator.java index 09d1620..dc0304b 100644 --- a/main/src/cgeo/geocaching/sorting/VoteComparator.java +++ b/main/src/cgeo/geocaching/sorting/VoteComparator.java @@ -1,6 +1,6 @@ package cgeo.geocaching.sorting; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; /** * sorts caches by the users own voting (if available at all) @@ -8,12 +8,12 @@ import cgeo.geocaching.cgCache; public class VoteComparator extends AbstractCacheComparator { @Override - protected boolean canCompare(cgCache cache1, cgCache cache2) { + protected boolean canCompare(Geocache cache1, Geocache cache2) { return true; } @Override - protected int compareCaches(cgCache cache1, cgCache cache2) { + protected int compareCaches(Geocache cache1, Geocache cache2) { // if there is no vote available, put that cache at the end of the list return Float.compare(cache2.getMyVote(), cache1.getMyVote()); } diff --git a/main/src/cgeo/geocaching/twitter/Twitter.java b/main/src/cgeo/geocaching/twitter/Twitter.java index 668502f..f30830e 100644 --- a/main/src/cgeo/geocaching/twitter/Twitter.java +++ b/main/src/cgeo/geocaching/twitter/Twitter.java @@ -1,8 +1,8 @@ package cgeo.geocaching.twitter; +import cgeo.geocaching.Geocache; import cgeo.geocaching.Settings; import cgeo.geocaching.Trackable; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.LoadFlags; @@ -56,7 +56,7 @@ public final class Twitter { } public static void postTweetCache(String geocode) { - final cgCache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); String status; final String url = cache.getUrl(); if (url.length() >= 100) { diff --git a/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java b/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java index 3bd6327..196d92d 100644 --- a/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java +++ b/main/src/cgeo/geocaching/twitter/TwitterAuthorizationActivity.java @@ -92,7 +92,7 @@ public class TwitterAuthorizationActivity extends AbstractActivity { super.onCreate(savedInstanceState); setTheme(); - setContentView(R.layout.auth); + setContentView(R.layout.twitter_authorization_activity); setTitle(res.getString(R.string.auth_twitter)); init(); diff --git a/main/src/cgeo/geocaching/ui/AnchorAwareLinkMovementMethod.java b/main/src/cgeo/geocaching/ui/AnchorAwareLinkMovementMethod.java new file mode 100644 index 0000000..db82e5c --- /dev/null +++ b/main/src/cgeo/geocaching/ui/AnchorAwareLinkMovementMethod.java @@ -0,0 +1,37 @@ +package cgeo.geocaching.ui; + +import android.text.Spannable; +import android.text.method.LinkMovementMethod; +import android.view.MotionEvent; +import android.widget.TextView; + +/** + * <code>LinkMovementMethod</code> with built-in suppression of errors for links, where the URL cannot be handled + * correctly by Android. + * + */ +public class AnchorAwareLinkMovementMethod extends LinkMovementMethod { + + private AnchorAwareLinkMovementMethod() { + // singleton + } + + private static final class Holder { + // initialization on demand holder + private static final AnchorAwareLinkMovementMethod INSTANCE = new AnchorAwareLinkMovementMethod(); + } + + public static AnchorAwareLinkMovementMethod getInstance() { + return Holder.INSTANCE; + } + + @Override + public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { + try { + return super.onTouchEvent(widget, buffer, event); + } catch (Exception e) { + // local links to anchors don't work + } + return false; + } +} diff --git a/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java b/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java index 9745d63..e98bd77 100644 --- a/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java +++ b/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java @@ -1,7 +1,7 @@ package cgeo.geocaching.ui; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.geopoint.Geopoint; import cgeo.geocaching.geopoint.Units; @@ -35,7 +35,7 @@ public final class CacheDetailsCreator { } public TextView add(final int nameId, final CharSequence value) { - final RelativeLayout layout = (RelativeLayout) activity.getLayoutInflater().inflate(R.layout.cache_layout, null); + final RelativeLayout layout = (RelativeLayout) activity.getLayoutInflater().inflate(R.layout.cache_information_item, null); final TextView nameView = (TextView) layout.findViewById(R.id.name); nameView.setText(res.getString(nameId)); lastValueView = (TextView) layout.findViewById(R.id.value); @@ -49,7 +49,7 @@ public final class CacheDetailsCreator { } public RelativeLayout addStars(final int nameId, final float value) { - final RelativeLayout layout = (RelativeLayout) activity.getLayoutInflater().inflate(R.layout.cache_layout, null); + final RelativeLayout layout = (RelativeLayout) activity.getLayoutInflater().inflate(R.layout.cache_information_item, null); final TextView nameView = (TextView) layout.findViewById(R.id.name); lastValueView = (TextView) layout.findViewById(R.id.value); final LinearLayout layoutStars = (LinearLayout) layout.findViewById(R.id.stars); @@ -79,7 +79,7 @@ public final class CacheDetailsCreator { } } - public void addCacheState(cgCache cache) { + public void addCacheState(Geocache cache) { if (cache.isLogOffline() || cache.isArchived() || cache.isDisabled() || cache.isPremiumMembersOnly() || cache.isFound()) { final List<String> states = new ArrayList<String>(5); if (cache.isLogOffline()) { @@ -101,7 +101,7 @@ public final class CacheDetailsCreator { } } - public void addRating(cgCache cache) { + public void addRating(Geocache cache) { if (cache.getRating() > 0) { final RelativeLayout itemLayout = addStars(R.string.cache_rating, cache.getRating()); if (cache.getVotes() > 0) { @@ -112,25 +112,25 @@ public final class CacheDetailsCreator { } } - public void addSize(cgCache cache) { + public void addSize(Geocache cache) { if (null != cache.getSize() && cache.showSize()) { add(R.string.cache_size, cache.getSize().getL10n()); } } - public void addDifficulty(cgCache cache) { + public void addDifficulty(Geocache cache) { if (cache.getDifficulty() > 0) { addStars(R.string.cache_difficulty, cache.getDifficulty()); } } - public void addTerrain(cgCache cache) { + public void addTerrain(Geocache cache) { if (cache.getTerrain() > 0) { addStars(R.string.cache_terrain, cache.getTerrain()); } } - public void addDistance(final cgCache cache, final TextView cacheDistanceView) { + public void addDistance(final Geocache cache, final TextView cacheDistanceView) { Float distance = null; if (cache.getCoords() != null) { final Geopoint currentCoords = cgeoapplication.getInstance().currentGeo().getCoords(); diff --git a/main/src/cgeo/geocaching/ui/CacheListAdapter.java b/main/src/cgeo/geocaching/ui/CacheListAdapter.java index d6224a9..41e27a6 100644 --- a/main/src/cgeo/geocaching/ui/CacheListAdapter.java +++ b/main/src/cgeo/geocaching/ui/CacheListAdapter.java @@ -1,10 +1,10 @@ package cgeo.geocaching.ui; import cgeo.geocaching.CacheDetailActivity; +import cgeo.geocaching.Geocache; import cgeo.geocaching.IGeoData; import cgeo.geocaching.R; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheListType; import cgeo.geocaching.enumerations.CacheType; @@ -49,7 +49,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -public class CacheListAdapter extends ArrayAdapter<cgCache> { +public class CacheListAdapter extends ArrayAdapter<Geocache> { private LayoutInflater inflater = null; private CacheComparator cacheComparator = null; @@ -58,14 +58,14 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { private long lastSort = 0L; private boolean selectMode = false; private IFilter currentFilter = null; - private List<cgCache> originalList = null; + private List<Geocache> originalList = null; final private Set<CompassMiniView> compasses = new LinkedHashSet<CompassMiniView>(); final private Set<DistanceView> distances = new LinkedHashSet<DistanceView>(); final private CacheListType cacheListType; final private Resources res; /** Resulting list of caches */ - final private List<cgCache> list; + final private List<Geocache> list; private boolean inverseSort = false; private static final int SWIPE_MIN_DISTANCE = 60; @@ -107,7 +107,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { ImageView dirImg; } - public CacheListAdapter(final Activity activity, final List<cgCache> list, CacheListType cacheListType) { + public CacheListAdapter(final Activity activity, final List<Geocache> list, CacheListType cacheListType) { super(activity, 0, list); final IGeoData currentGeo = cgeoapplication.getInstance().currentGeo(); if (currentGeo != null) { @@ -168,7 +168,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { return cacheComparator; } - public cgCache findCacheByGeocode(String geocode) { + public Geocache findCacheByGeocode(String geocode) { for (int i = 0; i < getCount(); i++) { if (getItem(i).getGeocode().equalsIgnoreCase(geocode)) { return getItem(i); @@ -183,7 +183,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { public void reFilter() { if (currentFilter != null) { // Back up the list again - originalList = new ArrayList<cgCache>(list); + originalList = new ArrayList<Geocache>(list); currentFilter.filter(list); } @@ -195,7 +195,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { public void setFilter(final IFilter filter) { // Backup current caches list if it isn't backed up yet if (originalList == null) { - originalList = new ArrayList<cgCache>(list); + originalList = new ArrayList<Geocache>(list); } // If there is already a filter in place, this is a request to change or clear the filter, so we have to @@ -224,7 +224,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { public int getCheckedCount() { int checked = 0; - for (cgCache cache : list) { + for (Geocache cache : list) { if (cache.isStatusChecked()) { checked++; } @@ -236,7 +236,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { this.selectMode = selectMode; if (!selectMode) { - for (final cgCache cache : list) { + for (final Geocache cache : list) { cache.setStatusChecked(false); } } @@ -252,7 +252,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { } public void invertSelection() { - for (cgCache cache : list) { + for (Geocache cache : list) { cache.setStatusChecked(!cache.isStatusChecked()); } notifyDataSetChanged(); @@ -302,7 +302,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { if (coords == null) { return; } - final ArrayList<cgCache> oldList = new ArrayList<cgCache>(list); + final ArrayList<Geocache> oldList = new ArrayList<Geocache>(list); Collections.sort(list, getPotentialInversion(new DistanceComparator(coords, list))); // avoid an update if the list has not changed due to location update @@ -313,7 +313,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { lastSort = System.currentTimeMillis(); } - private Comparator<? super cgCache> getPotentialInversion(final CacheComparator comparator) { + private Comparator<? super Geocache> getPotentialInversion(final CacheComparator comparator) { if (inverseSort) { return new InverseComparator(comparator); } @@ -346,7 +346,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { return null; } - final cgCache cache = getItem(position); + final Geocache cache = getItem(position); View v = rowView; @@ -533,7 +533,7 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { return v; } - private static Drawable getCacheIcon(cgCache cache) { + private static Drawable getCacheIcon(Geocache cache) { int hashCode = getIconHashCode(cache.getType(), cache.hasUserModifiedCoords() || cache.hasFinalDefined()); final Drawable drawable = gcIconDrawables.get(hashCode); if (drawable != null) { @@ -554,9 +554,9 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { private static class SelectionCheckBoxListener implements View.OnClickListener { - private final cgCache cache; + private final Geocache cache; - public SelectionCheckBoxListener(cgCache cache) { + public SelectionCheckBoxListener(Geocache cache) { this.cache = cache; } @@ -571,9 +571,9 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { private boolean touch = true; private final GestureDetector gestureDetector; - private final cgCache cache; + private final Geocache cache; - public TouchListener(final cgCache cache) { + public TouchListener(final Geocache cache) { this.cache = cache; final FlingGesture dGesture = new FlingGesture(cache); gestureDetector = new GestureDetector(getContext(), dGesture); @@ -622,9 +622,9 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { private class FlingGesture extends GestureDetector.SimpleOnGestureListener { - private final cgCache cache; + private final Geocache cache; - public FlingGesture(cgCache cache) { + public FlingGesture(Geocache cache) { this.cache = cache; } @@ -659,13 +659,13 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { } } - public List<cgCache> getFilteredList() { + public List<Geocache> getFilteredList() { return list; } - public List<cgCache> getCheckedCaches() { - final ArrayList<cgCache> result = new ArrayList<cgCache>(); - for (cgCache cache : list) { + public List<Geocache> getCheckedCaches() { + final ArrayList<Geocache> result = new ArrayList<Geocache>(); + for (Geocache cache : list) { if (cache.isStatusChecked()) { result.add(cache); } @@ -673,12 +673,12 @@ public class CacheListAdapter extends ArrayAdapter<cgCache> { return result; } - public List<cgCache> getCheckedOrAllCaches() { - final List<cgCache> result = getCheckedCaches(); + public List<Geocache> getCheckedOrAllCaches() { + final List<Geocache> result = getCheckedCaches(); if (!result.isEmpty()) { return result; } - return new ArrayList<cgCache>(list); + return new ArrayList<Geocache>(list); } public int getCheckedOrAllCount() { diff --git a/main/src/cgeo/geocaching/ui/Formatter.java b/main/src/cgeo/geocaching/ui/Formatter.java index 4d23952..412b993 100644 --- a/main/src/cgeo/geocaching/ui/Formatter.java +++ b/main/src/cgeo/geocaching/ui/Formatter.java @@ -1,7 +1,7 @@ package cgeo.geocaching.ui; +import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import cgeo.geocaching.cgCache; import cgeo.geocaching.Waypoint; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheListType; @@ -109,7 +109,7 @@ public abstract class Formatter { return DateUtils.formatDateTime(context, date, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_ALL); } - public static String formatCacheInfoLong(cgCache cache, CacheListType cacheListType) { + public static String formatCacheInfoLong(Geocache cache, CacheListType cacheListType) { final ArrayList<String> infos = new ArrayList<String>(); if (StringUtils.isNotBlank(cache.getGeocode())) { infos.add(cache.getGeocode()); @@ -126,7 +126,7 @@ public abstract class Formatter { return StringUtils.join(infos, Formatter.SEPARATOR); } - public static String formatCacheInfoShort(cgCache cache) { + public static String formatCacheInfoShort(Geocache cache) { final ArrayList<String> infos = new ArrayList<String>(); if (cache.hasDifficulty()) { infos.add("D " + String.format("%.1f", cache.getDifficulty())); @@ -144,7 +144,7 @@ public abstract class Formatter { return StringUtils.join(infos, Formatter.SEPARATOR); } - public static String formatCacheInfoHistory(cgCache cache) { + public static String formatCacheInfoHistory(Geocache cache) { final ArrayList<String> infos = new ArrayList<String>(3); infos.add(StringUtils.upperCase(cache.getGeocode())); infos.add(Formatter.formatDate(cache.getVisitedDate())); diff --git a/main/src/cgeo/geocaching/ui/LoggingUI.java b/main/src/cgeo/geocaching/ui/LoggingUI.java index eaa25ef..2615947 100644 --- a/main/src/cgeo/geocaching/ui/LoggingUI.java +++ b/main/src/cgeo/geocaching/ui/LoggingUI.java @@ -1,9 +1,9 @@ package cgeo.geocaching.ui; +import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; import cgeo.geocaching.Settings; -import cgeo.geocaching.cgCache; import cgeo.geocaching.cgData; import cgeo.geocaching.activity.IAbstractActivity; import cgeo.geocaching.enumerations.LogType; @@ -65,7 +65,7 @@ public class LoggingUI extends AbstractUIFactory { private static final int MENU_LOG_VISIT = 100; private static final int MENU_LOG_VISIT_OFFLINE = 101; - public static void addMenuItems(final Menu menu, final cgCache cache) { + public static void addMenuItems(final Menu menu, final Geocache cache) { if (cache == null) { return; } @@ -80,7 +80,7 @@ public class LoggingUI extends AbstractUIFactory { } } - public static boolean onMenuItemSelected(final MenuItem item, IAbstractActivity activity, cgCache cache) { + public static boolean onMenuItemSelected(final MenuItem item, IAbstractActivity activity, Geocache cache) { switch (item.getItemId()) { case MENU_LOG_VISIT: cache.logVisit(activity); @@ -93,7 +93,7 @@ public class LoggingUI extends AbstractUIFactory { } } - private static void showOfflineMenu(final cgCache cache, final Activity activity) { + private static void showOfflineMenu(final Geocache cache, final Activity activity) { final LogEntry currentLog = cgData.loadLogOffline(cache.getGeocode()); final LogType currentLogType = currentLog == null ? null : currentLog.type; diff --git a/main/src/cgeo/geocaching/cgeocoords.java b/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java index 0c2ffbf..dada8fd 100644 --- a/main/src/cgeo/geocaching/cgeocoords.java +++ b/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java @@ -1,5 +1,9 @@ -package cgeo.geocaching; +package cgeo.geocaching.ui.dialog; +import cgeo.geocaching.Geocache; +import cgeo.geocaching.IGeoData; +import cgeo.geocaching.R; +import cgeo.geocaching.Settings; import cgeo.geocaching.Settings.coordInputFormatEnum; import cgeo.geocaching.activity.AbstractActivity; import cgeo.geocaching.activity.ActivityMixin; @@ -24,11 +28,11 @@ import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; -public class cgeocoords extends Dialog { +public class CoordinatesInputDialog extends Dialog { final private AbstractActivity context; final private IGeoData geo; - final private cgCache cache; + final private Geocache cache; private Geopoint gp; private EditText eLat, eLon; @@ -42,8 +46,8 @@ public class cgeocoords extends Dialog { private coordInputFormatEnum currentFormat = null; - public cgeocoords(final AbstractActivity context, final cgCache cache, final Geopoint gp, final IGeoData geo) { - super(context); + public CoordinatesInputDialog(final AbstractActivity context, final Geocache cache, final Geopoint gp, final IGeoData geo) { + super(context, ActivityMixin.getTheme()); this.context = context; this.geo = geo; this.cache = cache; diff --git a/main/src/cgeo/geocaching/ui/CustomProgressDialog.java b/main/src/cgeo/geocaching/ui/dialog/CustomProgressDialog.java index f7772be..c2b722c 100644 --- a/main/src/cgeo/geocaching/ui/CustomProgressDialog.java +++ b/main/src/cgeo/geocaching/ui/dialog/CustomProgressDialog.java @@ -1,5 +1,6 @@ -package cgeo.geocaching.ui; +package cgeo.geocaching.ui.dialog; +import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.utils.Log; import android.app.ProgressDialog; @@ -18,7 +19,7 @@ import java.lang.reflect.Method; public class CustomProgressDialog extends ProgressDialog { public CustomProgressDialog(Context context) { - super(context); + super(context, ActivityMixin.getTheme()); } @Override diff --git a/main/src/cgeo/geocaching/ui/DateDialog.java b/main/src/cgeo/geocaching/ui/dialog/DateDialog.java index 5dfd9b9..a9c579c 100644 --- a/main/src/cgeo/geocaching/ui/DateDialog.java +++ b/main/src/cgeo/geocaching/ui/dialog/DateDialog.java @@ -1,4 +1,4 @@ -package cgeo.geocaching.ui; +package cgeo.geocaching.ui.dialog; import cgeo.geocaching.R; diff --git a/main/src/cgeo/geocaching/ui/EditorDialog.java b/main/src/cgeo/geocaching/ui/dialog/EditorDialog.java index 6dcf546..4db69e5 100644 --- a/main/src/cgeo/geocaching/ui/EditorDialog.java +++ b/main/src/cgeo/geocaching/ui/dialog/EditorDialog.java @@ -1,7 +1,8 @@ -package cgeo.geocaching.ui; +package cgeo.geocaching.ui.dialog; import cgeo.geocaching.CacheDetailActivity; import cgeo.geocaching.R; +import cgeo.geocaching.activity.ActivityMixin; import android.app.Dialog; import android.os.Bundle; @@ -17,7 +18,7 @@ public class EditorDialog extends Dialog { private EditorUpdate editorUpdate; public EditorDialog(CacheDetailActivity cacheDetailActivity, CharSequence editable) { - super(cacheDetailActivity); + super(cacheDetailActivity, ActivityMixin.getTheme()); this.editorText = editable; } diff --git a/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java b/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java new file mode 100644 index 0000000..862b1a0 --- /dev/null +++ b/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java @@ -0,0 +1,45 @@ +package cgeo.geocaching.ui.dialog; + +import cgeo.geocaching.R; +import cgeo.geocaching.Settings; +import cgeo.geocaching.cgeoapplication; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.view.ContextThemeWrapper; +import android.view.View; +import android.widget.CheckBox; + +public class LiveMapInfoDialogBuilder { + + public static AlertDialog create(Activity activity) { + final AlertDialog.Builder builder = new AlertDialog.Builder(activity); + + // AlertDialog has always dark style, so we have to apply it as well always + final View layout = View.inflate(new ContextThemeWrapper(activity, R.style.dark), R.layout.livemapinfo, null); + builder.setView(layout); + + final CheckBox checkBoxHide = (CheckBox) layout.findViewById(R.id.live_map_hint_hide); + + final int showCount = Settings.getLiveMapHintShowCount(); + if (showCount > 2) { + checkBoxHide.setVisibility(View.VISIBLE); + } + Settings.setLiveMapHintShowCount(showCount + 1); + + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + cgeoapplication.getInstance().setLiveMapHintShown(); + if (checkBoxHide.getVisibility() == View.VISIBLE && checkBoxHide.isChecked()) { + Settings.setHideLiveHint(true); + } + } + }); + return builder.create(); + } + +} diff --git a/main/src/cgeo/geocaching/utils/ApplicationSettings.java b/main/src/cgeo/geocaching/utils/ApplicationSettings.java new file mode 100644 index 0000000..99d3142 --- /dev/null +++ b/main/src/cgeo/geocaching/utils/ApplicationSettings.java @@ -0,0 +1,24 @@ +package cgeo.geocaching.utils; + +/** + * This utility class contains static settings that do not require a context or + * an application. It may not depend or use any other package from c:geo. + * <br/> + * It is used, for example, to get some settings for the BackupAgent. In this case, + * no application is instantiated by the OS. + */ + +public class ApplicationSettings { + + /** + * Get the name of the preferences file. + * + * @return the name of the shared preferences file without the extension + */ + public static String getPreferencesName() { + // There is currently no Android API to get the file name of the shared preferences. Let's hardcode + // it without needing a cgeoapplication instance. + return "cgeo.geocaching_preferences"; + } + +} diff --git a/main/src/cgeo/geocaching/utils/LazyInitializedList.java b/main/src/cgeo/geocaching/utils/LazyInitializedList.java index 25af811..27649e8 100644 --- a/main/src/cgeo/geocaching/utils/LazyInitializedList.java +++ b/main/src/cgeo/geocaching/utils/LazyInitializedList.java @@ -1,103 +1,63 @@ package cgeo.geocaching.utils; +import java.util.AbstractList; import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; import java.util.List; +import java.util.concurrent.Callable; -public abstract class LazyInitializedList<ElementType> implements Iterable<ElementType> { +public abstract class LazyInitializedList<ElementType> extends AbstractList<ElementType> implements Callable<List<ElementType>> { private volatile List<ElementType> list; - private void initializeList() { + private List<ElementType> getList() { if (list == null) { - synchronized (this) { - if (list == null) { - list = loadFromDatabase(); + synchronized(this) { + try { + list = call(); + if (list == null) { + Log.e("LazyInitializedList.getList: null result"); + } + } catch (final Exception e) { + Log.e("LazyInitializedList.getList", e); } } } + return list; } - protected abstract List<ElementType> loadFromDatabase(); - - public void add(final ElementType element) { - initializeList(); - list.add(element); - } - - public void prepend(final ElementType element) { - initializeList(); - list.add(0, element); - } - - public void set(final List<ElementType> elements) { - if (elements != null) { - list = new ArrayList<ElementType>(elements); - } else { - list = new ArrayList<ElementType>(); - } - } - - public void set(LazyInitializedList<ElementType> other) { - if (other != null) { - list = new ArrayList<ElementType>(other.asList()); - } else { - list = new ArrayList<ElementType>(); - } + @Override + public boolean add(final ElementType element) { + return getList().add(element); } - public boolean isEmpty() { - initializeList(); - return list.isEmpty(); + @Override + public ElementType set(final int index, final ElementType element) { + return getList().set(index, element); } + @Override public ElementType remove(final int index) { - initializeList(); - return list.remove(index); + return getList().remove(index); } + @Override public void add(int index, final ElementType element) { - initializeList(); - list.add(index, element); + getList().add(index, element); } + @Override public int size() { - initializeList(); - return list.size(); + return getList().size(); } @Override - public Iterator<ElementType> iterator() { - initializeList(); - return list.iterator(); - } - public ElementType get(final int index) { - initializeList(); - return list.get(index); + return getList().get(index); } - public boolean contains(final ElementType element) { - initializeList(); - return list.contains(element); - } - - public boolean isNotEmpty() { - initializeList(); - return !list.isEmpty(); - } - - /** - * @return an unmodifiable list of the elements - */ - public List<ElementType> asList() { - initializeList(); - return Collections.unmodifiableList(list); + @Override + public void clear() { + list = new ArrayList<ElementType>(); } - public int indexOf(ElementType element) { - initializeList(); - return list.indexOf(element); - } } diff --git a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java index aafce4f..698d38a 100644 --- a/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java +++ b/main/src/cgeo/geocaching/utils/LeastRecentlyUsedSet.java @@ -9,7 +9,7 @@ import java.util.List; /** * Synchronized set wrapper for the LeastRecentlyUsedMap. - * + * * This code is heavily based on the HashSet code that represent Map as a Set. * Unfortunately HashSet does not allow to use a custom Map as its Storage. * Therefore overriding removeEldestEntry() is impossible for a normal LinkedHashSet. @@ -50,7 +50,7 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E> /** * Synchronized access to set size * Copy of the HashSet code if size() - * + * * @see HashSet */ @Override @@ -61,7 +61,7 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E> /** * Synchronized check of set emptiness * Copy of the HashSet code if isEmpty() - * + * * @see HashSet */ @Override @@ -72,7 +72,7 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E> /** * Synchronized check for containment * Copy of the HashSet code if contains() - * + * * @see HashSet */ @Override @@ -83,18 +83,21 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E> /** * Synchronized addition of an item * Copy of the HashSet code if add() - * + * * @see HashSet */ @Override public synchronized boolean add(E e) { + if (e == null) { + throw new IllegalArgumentException("LeastRecentlyUsedSet cannot take null element"); + } return map.put(e, PRESENT) == null; } /** * Synchronized removal of a contained item * Copy of the HashSet code if remove() - * + * * @see HashSet */ @Override @@ -117,7 +120,7 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E> /** * Synchronized clearing of the set * Copy of the HashSet code if clear() - * + * * @see HashSet */ @Override @@ -128,7 +131,7 @@ public class LeastRecentlyUsedSet<E> extends AbstractSet<E> /** * (synchronized) Clone of the set * Copy of the HashSet code if clone() - * + * * @see HashSet */ @Override diff --git a/main/src/cgeo/geocaching/utils/Log.java b/main/src/cgeo/geocaching/utils/Log.java index 6213661..6d57b75 100644 --- a/main/src/cgeo/geocaching/utils/Log.java +++ b/main/src/cgeo/geocaching/utils/Log.java @@ -1,5 +1,11 @@ package cgeo.geocaching.utils; +import android.os.Environment; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; final public class Log { @@ -9,6 +15,7 @@ final public class Log { * the debug flag is cached here so that we don't need to access the settings every time we have to evaluate it */ private static boolean isDebug = true; + private static boolean first = true; public static boolean isDebug() { return isDebug; @@ -74,4 +81,31 @@ final public class Log { public static void e(final String msg, final Throwable t) { android.util.Log.e(TAG, msg, t); } + + /** + * Log the whole content of a string into "/sdcard/cgeo-debug.log". + * <br/> + * Sometimes, the string we want to work on while debugging or developing a new feature is too long to + * be fully stored in Android logcat. This method will log the content of the string in a file named + * "/sdcard/cgeo-debug.log". The file will be reset at every run, and if called several times during a run, + * the contents will be appended to one another. + * <br/> + * <strong>This method should never be called in production.</strong> + * + * @param msg the message to log, or to add to the log if other messages have been stored in the same run + */ + public synchronized static void logToFile(final String msg) { + final File file = new File(Environment.getExternalStorageDirectory(), "cgeo-debug.log"); + if (first) { + first = false; + file.delete(); + } + try { + final Writer writer = new FileWriter(file, true); + writer.write(msg); + writer.close(); + } catch (final IOException e) { + Log.e("logToFile: cannot write to " + file, e); + } + } } diff --git a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java index 7171fde..0a8e547 100644 --- a/main/src/cgeo/geocaching/utils/LogTemplateProvider.java +++ b/main/src/cgeo/geocaching/utils/LogTemplateProvider.java @@ -3,7 +3,7 @@ package cgeo.geocaching.utils; import cgeo.geocaching.R; import cgeo.geocaching.Settings; import cgeo.geocaching.Trackable; -import cgeo.geocaching.cgCache; +import cgeo.geocaching.Geocache; import cgeo.geocaching.connector.gc.GCConstants; import cgeo.geocaching.connector.gc.Login; import cgeo.geocaching.network.Network; @@ -28,11 +28,11 @@ public class LogTemplateProvider { * */ public static class LogContext { - private cgCache cache; + private Geocache cache; private Trackable trackable; private boolean offline = false; - public LogContext(final cgCache cache) { + public LogContext(final Geocache cache) { this(cache, false); } @@ -44,12 +44,12 @@ public class LogTemplateProvider { this(null, offline); } - public LogContext(final cgCache cache, boolean offline) { + public LogContext(final Geocache cache, boolean offline) { this.cache = cache; this.offline = offline; } - public cgCache getCache() { + public Geocache getCache() { return cache; } @@ -152,7 +152,7 @@ public class LogTemplateProvider { if (trackable != null) { return trackable.getOwner(); } - cgCache cache = context.getCache(); + Geocache cache = context.getCache(); if (cache != null) { return cache.getOwnerDisplayName(); } diff --git a/main/src/cgeo/geocaching/utils/XmlUtils.java b/main/src/cgeo/geocaching/utils/XmlUtils.java new file mode 100644 index 0000000..4e08f42 --- /dev/null +++ b/main/src/cgeo/geocaching/utils/XmlUtils.java @@ -0,0 +1,41 @@ +package cgeo.geocaching.utils; + +import org.xmlpull.v1.XmlSerializer; + +import java.io.IOException; + +public class XmlUtils { + + private XmlUtils() { + // Do not instantiate + } + + /** + * Insert an attribute-less tag with enclosed text in a XML serializer output. + * + * @param serializer an XML serializer + * @param prefix an XML prefix, see {@link XmlSerializer#startTag(String, String)} + * @param tag an XML tag + * @param text some text to insert + * @throws IOException + */ + public static void simpleText(final XmlSerializer serializer, final String prefix, final String tag, final String text) throws IOException { + serializer.startTag(prefix, tag); + serializer.text(text); + serializer.endTag(prefix, tag); + } + + /** + * Insert pairs of attribute-less tags and enclosed texts in a XML serializer output + * + * @param serializer an XML serializer + * @param prefix an XML prefix, see {@link XmlSerializer#startTag(String, String)} shared by all tags + * @param tagAndText an XML tag, the corresponding text, another XML tag, the corresponding text, … + * @throws IOException + */ + public static void multipleTexts(final XmlSerializer serializer, final String prefix, final String... tagAndText) throws IOException { + for (int i = 0; i < tagAndText.length; i += 2) { + simpleText(serializer, prefix, tagAndText[i], tagAndText[i+1]); + } + } +} |
