aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/ui
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo/geocaching/ui')
-rw-r--r--main/src/cgeo/geocaching/ui/AbstractUserClickListener.java76
-rw-r--r--main/src/cgeo/geocaching/ui/AbstractViewHolder.java19
-rw-r--r--main/src/cgeo/geocaching/ui/AddressListAdapter.java21
-rw-r--r--main/src/cgeo/geocaching/ui/CacheDetailsCreator.java23
-rw-r--r--main/src/cgeo/geocaching/ui/CacheListAdapter.java87
-rw-r--r--main/src/cgeo/geocaching/ui/CompassMiniView.java2
-rw-r--r--main/src/cgeo/geocaching/ui/CompassView.java77
-rw-r--r--main/src/cgeo/geocaching/ui/CoordinatesFormatSwitcher.java38
-rw-r--r--main/src/cgeo/geocaching/ui/DecryptTextClickListener.java6
-rw-r--r--main/src/cgeo/geocaching/ui/DistanceView.java4
-rw-r--r--main/src/cgeo/geocaching/ui/EditNoteDialog.java66
-rw-r--r--main/src/cgeo/geocaching/ui/FileSelectionListAdapter.java30
-rw-r--r--main/src/cgeo/geocaching/ui/GPXListAdapter.java32
-rw-r--r--main/src/cgeo/geocaching/ui/HtmlImageCounter.java19
-rw-r--r--main/src/cgeo/geocaching/ui/ImagesList.java54
-rw-r--r--main/src/cgeo/geocaching/ui/IndexOutOfBoundsAvoidingTextView.java55
-rw-r--r--main/src/cgeo/geocaching/ui/LoggingUI.java44
-rw-r--r--main/src/cgeo/geocaching/ui/OwnerActionsClickListener.java31
-rw-r--r--main/src/cgeo/geocaching/ui/UserActionsClickListener.java26
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java58
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/CustomProgressDialog.java2
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/DateDialog.java12
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/EditorDialog.java60
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java2
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/NoTitleDialog.java30
-rw-r--r--main/src/cgeo/geocaching/ui/logs/CacheLogsViewCreator.java112
-rw-r--r--main/src/cgeo/geocaching/ui/logs/LogViewHolder.java47
-rw-r--r--main/src/cgeo/geocaching/ui/logs/LogsViewCreator.java175
-rw-r--r--main/src/cgeo/geocaching/ui/logs/TrackableLogsViewCreator.java70
29 files changed, 973 insertions, 305 deletions
diff --git a/main/src/cgeo/geocaching/ui/AbstractUserClickListener.java b/main/src/cgeo/geocaching/ui/AbstractUserClickListener.java
new file mode 100644
index 0000000..b717568
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/AbstractUserClickListener.java
@@ -0,0 +1,76 @@
+package cgeo.geocaching.ui;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.cgeocaches;
+import cgeo.geocaching.activity.AbstractActivity;
+import cgeo.geocaching.network.Network;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.view.View;
+
+abstract class AbstractUserClickListener implements View.OnClickListener {
+
+ private final boolean enabled;
+
+ public AbstractUserClickListener(final boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (view == null) {
+ return;
+ }
+ if (!enabled) {
+ return;
+ }
+
+ showUserActionsDialog(getUserName(view), view);
+ }
+
+ protected abstract CharSequence getUserName(View view);
+
+ /**
+ * Opens a dialog to do actions on an user name
+ */
+ protected static void showUserActionsDialog(final CharSequence name, final View view) {
+ final AbstractActivity context = (AbstractActivity) view.getContext();
+ final Resources res = context.getResources();
+ 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_send_message)
+ };
+
+ final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(res.getString(R.string.user_menu_title) + " " + name);
+ builder.setItems(items, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int item) {
+ switch (item) {
+ case 0:
+ cgeocaches.startActivityOwner(context, name.toString());
+ return;
+ case 1:
+ cgeocaches.startActivityUserName(context, name.toString());
+ return;
+ case 2:
+ context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + Network.encode(name.toString()))));
+ return;
+ case 3:
+ context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/email/?u=" + Network.encode(name.toString()))));
+ return;
+ default:
+ break;
+ }
+ }
+ });
+ final AlertDialog alert = builder.create();
+ alert.show();
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/ui/AbstractViewHolder.java b/main/src/cgeo/geocaching/ui/AbstractViewHolder.java
new file mode 100644
index 0000000..cc5cd4d
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/AbstractViewHolder.java
@@ -0,0 +1,19 @@
+package cgeo.geocaching.ui;
+
+import butterknife.Views;
+
+import android.view.View;
+
+/**
+ * Abstract super class for all view holders. It is responsible for the invocation of the view injection code and for
+ * the tagging of views.
+ *
+ */
+public abstract class AbstractViewHolder {
+
+ protected AbstractViewHolder(View view) {
+ Views.inject(this, view);
+ view.setTag(this);
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/ui/AddressListAdapter.java b/main/src/cgeo/geocaching/ui/AddressListAdapter.java
index eb8b516..736c036 100644
--- a/main/src/cgeo/geocaching/ui/AddressListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/AddressListAdapter.java
@@ -1,5 +1,7 @@
package cgeo.geocaching.ui;
+import butterknife.InjectView;
+
import cgeo.geocaching.R;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.cgeocaches;
@@ -24,9 +26,13 @@ public class AddressListAdapter extends ArrayAdapter<Address> {
final private LayoutInflater inflater;
final private Geopoint location;
- private static final class ViewHolder {
- TextView label;
- TextView distance;
+ protected static final class ViewHolder extends AbstractViewHolder {
+ @InjectView(R.id.label) protected TextView label;
+ @InjectView(R.id.distance) protected TextView distance;
+
+ public ViewHolder(View view) {
+ super(view);
+ }
}
public AddressListAdapter(final Context context) {
@@ -44,13 +50,8 @@ public class AddressListAdapter extends ArrayAdapter<Address> {
// holder pattern implementation
final ViewHolder holder;
if (view == null) {
- view = inflater.inflate(R.layout.addresses_item, null);
-
- holder = new ViewHolder();
- holder.label = (TextView) view.findViewById(R.id.label);
- holder.distance = (TextView) view.findViewById(R.id.distance);
-
- view.setTag(holder);
+ view = inflater.inflate(R.layout.addresslist_item, null);
+ holder = new ViewHolder(view);
} else {
holder = (ViewHolder) view.getTag();
}
diff --git a/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java b/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java
index e98bd77..9059a6b 100644
--- a/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java
+++ b/main/src/cgeo/geocaching/ui/CacheDetailsCreator.java
@@ -2,6 +2,7 @@ package cgeo.geocaching.ui;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.R;
+import cgeo.geocaching.Waypoint;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Units;
@@ -67,7 +68,7 @@ public final class CacheDetailsCreator {
final LayoutInflater inflater = LayoutInflater.from(activity);
for (int i = 0; i < 5; i++) {
- ImageView star = (ImageView) inflater.inflate(R.layout.star, null);
+ ImageView star = (ImageView) inflater.inflate(R.layout.star_image, null);
if (value - i >= 0.75) {
star.setImageResource(R.drawable.star_on);
} else if (value - i >= 0.25) {
@@ -154,4 +155,24 @@ public final class CacheDetailsCreator {
}
add(R.string.cache_distance, text);
}
+
+ public void addDistance(final Waypoint wpt, final TextView waypointDistanceView) {
+ Float distance = null;
+ if (wpt.getCoords() != null) {
+ final Geopoint currentCoords = cgeoapplication.getInstance().currentGeo().getCoords();
+ if (currentCoords != null) {
+ distance = currentCoords.distanceTo(wpt);
+ }
+ }
+ String text = "--";
+ if (distance != null) {
+ text = Units.getDistanceFromKilometers(distance);
+ }
+ else if (waypointDistanceView != null) {
+ // if there is already a distance in waypointDistance, use it instead of resetting to default.
+ // this prevents displaying "--" while waiting for a new position update (See bug #1468)
+ text = waypointDistanceView.getText().toString();
+ }
+ add(R.string.cache_distance, text);
+ }
}
diff --git a/main/src/cgeo/geocaching/ui/CacheListAdapter.java b/main/src/cgeo/geocaching/ui/CacheListAdapter.java
index 42b774e..3179857 100644
--- a/main/src/cgeo/geocaching/ui/CacheListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/CacheListAdapter.java
@@ -1,10 +1,12 @@
package cgeo.geocaching.ui;
+import butterknife.InjectView;
+
import cgeo.geocaching.CacheDetailActivity;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.IGeoData;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.CacheListType;
import cgeo.geocaching.enumerations.CacheType;
@@ -12,6 +14,7 @@ import cgeo.geocaching.filter.IFilter;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.sorting.CacheComparator;
import cgeo.geocaching.sorting.DistanceComparator;
+import cgeo.geocaching.sorting.EventDateComparator;
import cgeo.geocaching.sorting.InverseComparator;
import cgeo.geocaching.sorting.VisitComparator;
import cgeo.geocaching.utils.AngleUtils;
@@ -77,13 +80,13 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> {
private static final int[] RATING_BACKGROUND = new int[3];
static {
if (Settings.isLightSkin()) {
- RATING_BACKGROUND[0] = R.drawable.favourite_background_red_light;
- RATING_BACKGROUND[1] = R.drawable.favourite_background_orange_light;
- RATING_BACKGROUND[2] = R.drawable.favourite_background_green_light;
+ RATING_BACKGROUND[0] = R.drawable.favorite_background_red_light;
+ RATING_BACKGROUND[1] = R.drawable.favorite_background_orange_light;
+ RATING_BACKGROUND[2] = R.drawable.favorite_background_green_light;
} else {
- RATING_BACKGROUND[0] = R.drawable.favourite_background_red_dark;
- RATING_BACKGROUND[1] = R.drawable.favourite_background_orange_dark;
- RATING_BACKGROUND[2] = R.drawable.favourite_background_green_dark;
+ RATING_BACKGROUND[0] = R.drawable.favorite_background_red_dark;
+ RATING_BACKGROUND[1] = R.drawable.favorite_background_orange_dark;
+ RATING_BACKGROUND[2] = R.drawable.favorite_background_green_dark;
}
}
@@ -91,16 +94,20 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> {
* view holder for the cache list adapter
*
*/
- private static class ViewHolder {
- CheckBox checkbox;
- ImageView logStatusMark;
- TextView text;
- TextView favourite;
- TextView info;
- ImageView inventory;
- DistanceView distance;
- CompassMiniView direction;
- ImageView dirImg;
+ protected static class ViewHolder extends AbstractViewHolder {
+ @InjectView(R.id.checkbox) protected CheckBox checkbox;
+ @InjectView(R.id.log_status_mark) protected ImageView logStatusMark;
+ @InjectView(R.id.text) protected TextView text;
+ @InjectView(R.id.distance) protected DistanceView distance;
+ @InjectView(R.id.favorite) protected TextView favorite;
+ @InjectView(R.id.info) protected TextView info;
+ @InjectView(R.id.inventory) protected ImageView inventory;
+ @InjectView(R.id.direction) protected CompassMiniView direction;
+ @InjectView(R.id.dirimg) protected ImageView dirImg;
+
+ public ViewHolder(View view) {
+ super(view);
+ }
}
public CacheListAdapter(final Activity activity, final List<Geocache> list, CacheListType cacheListType) {
@@ -348,20 +355,9 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> {
final ViewHolder holder;
if (v == null) {
- v = inflater.inflate(R.layout.caches_item, null);
-
- holder = new ViewHolder();
- holder.checkbox = (CheckBox) v.findViewById(R.id.checkbox);
- holder.logStatusMark = (ImageView) v.findViewById(R.id.log_status_mark);
- holder.text = (TextView) v.findViewById(R.id.text);
- holder.distance = (DistanceView) v.findViewById(R.id.distance);
- holder.direction = (CompassMiniView) v.findViewById(R.id.direction);
- holder.dirImg = (ImageView) v.findViewById(R.id.dirimg);
- holder.inventory = (ImageView) v.findViewById(R.id.inventory);
- holder.favourite = (TextView) v.findViewById(R.id.favourite);
- holder.info = (TextView) v.findViewById(R.id.info);
-
- v.setTag(holder);
+ v = inflater.inflate(R.layout.cacheslist_item, null);
+
+ holder = new ViewHolder(v);
} else {
holder = (ViewHolder) v.getTag();
}
@@ -453,14 +449,14 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> {
holder.direction.setVisibility(View.GONE);
}
- holder.favourite.setText(Integer.toString(cache.getFavoritePoints()));
+ holder.favorite.setText(Integer.toString(cache.getFavoritePoints()));
int favoriteBack;
// set default background, neither vote nor rating may be available
if (lightSkin) {
- favoriteBack = R.drawable.favourite_background_light;
+ favoriteBack = R.drawable.favorite_background_light;
} else {
- favoriteBack = R.drawable.favourite_background_dark;
+ favoriteBack = R.drawable.favorite_background_dark;
}
final float myVote = cache.getMyVote();
if (myVote > 0) { // use my own rating for display, if I have voted
@@ -481,7 +477,7 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> {
favoriteBack = RATING_BACKGROUND[0];
}
}
- holder.favourite.setBackgroundResource(favoriteBack);
+ holder.favorite.setBackgroundResource(favoriteBack);
if (cacheListType == CacheListType.HISTORY && cache.getVisitedDate() > 0) {
holder.info.setText(Formatter.formatCacheInfoHistory(cache));
@@ -647,4 +643,25 @@ public class CacheListAdapter extends ArrayAdapter<Geocache> {
}
return list.size();
}
+
+ public void setInitialComparator() {
+ CacheComparator comparator = null; // a null comparator will automatically sort by distance
+ if (cacheListType == CacheListType.HISTORY) {
+ comparator = new VisitComparator();
+ } else {
+ if (CollectionUtils.isNotEmpty(list)) {
+ boolean eventsOnly = true;
+ for (final Geocache cache : list) {
+ if (!cache.isEventCache()) {
+ eventsOnly = false;
+ break;
+ }
+ }
+ if (eventsOnly) {
+ comparator = new EventDateComparator();
+ }
+ }
+ }
+ setComparator(comparator);
+ }
}
diff --git a/main/src/cgeo/geocaching/ui/CompassMiniView.java b/main/src/cgeo/geocaching/ui/CompassMiniView.java
index da8f69e..92280dc 100644
--- a/main/src/cgeo/geocaching/ui/CompassMiniView.java
+++ b/main/src/cgeo/geocaching/ui/CompassMiniView.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.ui;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.utils.AngleUtils;
diff --git a/main/src/cgeo/geocaching/ui/CompassView.java b/main/src/cgeo/geocaching/ui/CompassView.java
index 0ef3a43..b73a2a9 100644
--- a/main/src/cgeo/geocaching/ui/CompassView.java
+++ b/main/src/cgeo/geocaching/ui/CompassView.java
@@ -3,6 +3,7 @@ package cgeo.geocaching.ui;
import cgeo.geocaching.R;
import cgeo.geocaching.utils.AngleUtils;
import cgeo.geocaching.utils.PeriodicHandler;
+import cgeo.geocaching.utils.PeriodicHandler.PeriodicHandlerListener;
import android.content.Context;
import android.graphics.Bitmap;
@@ -14,7 +15,7 @@ import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.View;
-public class CompassView extends View {
+public class CompassView extends View implements PeriodicHandlerListener {
private Context context = null;
private Bitmap compassUnderlay = null;
@@ -48,7 +49,7 @@ public class CompassView extends View {
private int compassOverlayWidth = 0;
private int compassOverlayHeight = 0;
private boolean initialDisplay;
- private final RedrawHandler redrawHandler = new RedrawHandler();
+ private final PeriodicHandler redrawHandler = new PeriodicHandler(40, this);
public CompassView(Context contextIn) {
super(contextIn);
@@ -145,26 +146,18 @@ public class CompassView extends View {
return AngleUtils.normalize(actual + offset);
}
- private class RedrawHandler extends PeriodicHandler {
-
- public RedrawHandler() {
- super(40);
- }
-
- @Override
- public void act() {
- final float newAzimuthShown = smoothUpdate(northMeasured, azimuthShown);
- final float newCacheHeadingShown = smoothUpdate(cacheHeadingMeasured, cacheHeadingShown);
- if (Math.abs(AngleUtils.difference(azimuthShown, newAzimuthShown)) >= 2 ||
- Math.abs(AngleUtils.difference(cacheHeadingShown, newCacheHeadingShown)) >= 2) {
- synchronized(CompassView.this) {
- azimuthShown = newAzimuthShown;
- cacheHeadingShown = newCacheHeadingShown;
- }
- invalidate();
+ @Override
+ public void onPeriodic() {
+ final float newAzimuthShown = smoothUpdate(northMeasured, azimuthShown);
+ final float newCacheHeadingShown = smoothUpdate(cacheHeadingMeasured, cacheHeadingShown);
+ if (Math.abs(AngleUtils.difference(azimuthShown, newAzimuthShown)) >= 2 ||
+ Math.abs(AngleUtils.difference(cacheHeadingShown, newCacheHeadingShown)) >= 2) {
+ synchronized(this) {
+ azimuthShown = newAzimuthShown;
+ cacheHeadingShown = newCacheHeadingShown;
}
+ invalidate();
}
-
}
@Override
@@ -178,12 +171,12 @@ public class CompassView extends View {
headingDrawn = cacheHeadingShown;
}
- float azimuthTemp = azimuthDrawn;
+ final float azimuthTemp = azimuthDrawn;
final float azimuthRelative = AngleUtils.normalize(azimuthTemp - headingDrawn);
// compass margins
- int canvasCenterX = (compassRoseWidth / 2) + ((getWidth() - compassRoseWidth) / 2);
- int canvasCenterY = (compassRoseHeight / 2) + ((getHeight() - compassRoseHeight) / 2);
+ final int canvasCenterX = (compassRoseWidth / 2) + ((getWidth() - compassRoseWidth) / 2);
+ final int canvasCenterY = (compassRoseHeight / 2) + ((getHeight() - compassRoseHeight) / 2);
super.onDraw(canvas);
@@ -224,38 +217,36 @@ public class CompassView extends View {
}
private int measureWidth(int measureSpec) {
- int result;
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
+ final int specMode = MeasureSpec.getMode(measureSpec);
+ final int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
- result = specSize;
- } else {
- result = compassArrow.getWidth() + getPaddingLeft() + getPaddingRight();
+ return specSize;
+ }
- if (specMode == MeasureSpec.AT_MOST) {
- result = Math.min(result, specSize);
- }
+ final int desired = compassArrow.getWidth() + getPaddingLeft() + getPaddingRight();
+ if (specMode == MeasureSpec.AT_MOST) {
+ return Math.min(desired, specSize);
}
- return result;
+ return desired;
}
private int measureHeight(int measureSpec) {
- int result;
- int specMode = MeasureSpec.getMode(measureSpec);
- int specSize = MeasureSpec.getSize(measureSpec);
+ // The duplicated code in measureHeight and measureWidth cannot be avoided.
+ // Those methods must be efficient, therefore we cannot extract the code differences and unify the remainder.
+ final int specMode = MeasureSpec.getMode(measureSpec);
+ final int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
- result = specSize;
- } else {
- result = compassArrow.getHeight() + getPaddingTop() + getPaddingBottom();
+ return specSize;
+ }
- if (specMode == MeasureSpec.AT_MOST) {
- result = Math.min(result, specSize);
- }
+ final int desired = compassArrow.getHeight() + getPaddingTop() + getPaddingBottom();
+ if (specMode == MeasureSpec.AT_MOST) {
+ return Math.min(desired, specSize);
}
- return result;
+ return desired;
}
}
diff --git a/main/src/cgeo/geocaching/ui/CoordinatesFormatSwitcher.java b/main/src/cgeo/geocaching/ui/CoordinatesFormatSwitcher.java
new file mode 100644
index 0000000..afadb33
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/CoordinatesFormatSwitcher.java
@@ -0,0 +1,38 @@
+package cgeo.geocaching.ui;
+
+import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.geopoint.GeopointFormatter;
+
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.TextView;
+
+/**
+ * view click listener to automatically switch different coordinate formats
+ *
+ */
+public class CoordinatesFormatSwitcher implements OnClickListener {
+
+ private static GeopointFormatter.Format[] availableFormats = new GeopointFormatter.Format[] {
+ GeopointFormatter.Format.LAT_LON_DECMINUTE,
+ GeopointFormatter.Format.LAT_LON_DECSECOND,
+ GeopointFormatter.Format.LAT_LON_DECDEGREE
+ };
+
+ private int position = 0;
+
+ private final Geopoint coordinates;
+
+ public CoordinatesFormatSwitcher(final Geopoint coordinates) {
+ this.coordinates = coordinates;
+ }
+
+ @Override
+ public void onClick(View view) {
+ position = (position + 1) % availableFormats.length;
+ TextView textView = (TextView) view;
+ // rotate coordinate formats on click
+ textView.setText(coordinates.format(availableFormats[position]));
+ }
+
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/ui/DecryptTextClickListener.java b/main/src/cgeo/geocaching/ui/DecryptTextClickListener.java
index 4ba88ae..f10e13a 100644
--- a/main/src/cgeo/geocaching/ui/DecryptTextClickListener.java
+++ b/main/src/cgeo/geocaching/ui/DecryptTextClickListener.java
@@ -16,6 +16,12 @@ public class DecryptTextClickListener implements View.OnClickListener {
try {
final TextView logView = (TextView) view;
+
+ // do not run the click listener if a link was clicked
+ if (logView.getSelectionStart() != -1 || logView.getSelectionEnd() != -1) {
+ return;
+ }
+
CharSequence text = logView.getText();
if (text instanceof Spannable) {
Spannable span = (Spannable) text;
diff --git a/main/src/cgeo/geocaching/ui/DistanceView.java b/main/src/cgeo/geocaching/ui/DistanceView.java
index 9611511..b36166d 100644
--- a/main/src/cgeo/geocaching/ui/DistanceView.java
+++ b/main/src/cgeo/geocaching/ui/DistanceView.java
@@ -36,8 +36,4 @@ public class DistanceView extends TextView {
public void setDistance(Float distance) {
setText("~" + Units.getDistanceFromKilometers(distance));
}
-
- public void clear() {
- setText(null);
- }
} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/ui/EditNoteDialog.java b/main/src/cgeo/geocaching/ui/EditNoteDialog.java
new file mode 100644
index 0000000..9a122e2
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/EditNoteDialog.java
@@ -0,0 +1,66 @@
+package cgeo.geocaching.ui;
+
+import cgeo.geocaching.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+
+public class EditNoteDialog extends DialogFragment {
+
+ public interface EditNoteDialogListener {
+ void onFinishEditNoteDialog(final String inputText);
+ }
+
+ public static final String ARGUMENT_INITIAL_NOTE = "initialNote";
+
+ private EditText mEditText;
+
+ public static EditNoteDialog newInstance(final String initialNote) {
+ EditNoteDialog dialog = new EditNoteDialog();
+
+ Bundle arguments = new Bundle();
+ arguments.putString(EditNoteDialog.ARGUMENT_INITIAL_NOTE, initialNote);
+ dialog.setArguments(arguments);
+
+ return dialog;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View view = inflater.inflate(R.layout.fragment_edit_note, null);
+ mEditText = (EditText) view.findViewById(R.id.note);
+ String initialNote = getArguments().getString(ARGUMENT_INITIAL_NOTE);
+ if (initialNote != null) {
+ mEditText.setText(initialNote);
+ initialNote = null;
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.cache_personal_note);
+ builder.setView(view);
+ builder.setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int whichButton) {
+ final EditNoteDialogListener activity = (EditNoteDialogListener) getActivity();
+ activity.onFinishEditNoteDialog(mEditText.getText().toString());
+ dialog.dismiss();
+ }
+ });
+ builder.setNegativeButton(android.R.string.cancel,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int whichButton) {
+ dialog.dismiss();
+ }
+ });
+ return builder.create();
+ }
+}
diff --git a/main/src/cgeo/geocaching/ui/FileSelectionListAdapter.java b/main/src/cgeo/geocaching/ui/FileSelectionListAdapter.java
index 1db3f21..c325f50 100644
--- a/main/src/cgeo/geocaching/ui/FileSelectionListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/FileSelectionListAdapter.java
@@ -1,5 +1,7 @@
package cgeo.geocaching.ui;
+import butterknife.InjectView;
+
import cgeo.geocaching.R;
import cgeo.geocaching.files.IFileSelectionView;
import cgeo.geocaching.utils.Log;
@@ -17,23 +19,20 @@ import java.util.List;
public class FileSelectionListAdapter extends ArrayAdapter<File> {
- private IFileSelectionView parentView;
- private LayoutInflater inflater;
+ private final IFileSelectionView parentView;
+ private final LayoutInflater inflater;
public FileSelectionListAdapter(IFileSelectionView parentIn, List<File> listIn) {
super(parentIn.getContext(), 0, listIn);
parentView = parentIn;
+ inflater = ((Activity) getContext()).getLayoutInflater();
}
@Override
public View getView(final int position, final View rowView, final ViewGroup parent) {
- if (inflater == null) {
- inflater = ((Activity) getContext()).getLayoutInflater();
- }
-
if (position > getCount()) {
- Log.w("cgGPXListAdapter.getView: Attempt to access missing item #" + position);
+ Log.w("FileSelectionListAdapter.getView: Attempt to access missing item #" + position);
return null;
}
@@ -44,12 +43,7 @@ public class FileSelectionListAdapter extends ArrayAdapter<File> {
ViewHolder holder;
if (v == null) {
v = inflater.inflate(R.layout.mapfile_item, null);
-
- holder = new ViewHolder();
- holder.filepath = (TextView) v.findViewById(R.id.mapfilepath);
- holder.filename = (TextView) v.findViewById(R.id.mapfilename);
-
- v.setTag(holder);
+ holder = new ViewHolder(v);
} else {
holder = (ViewHolder) v.getTag();
}
@@ -85,8 +79,12 @@ public class FileSelectionListAdapter extends ArrayAdapter<File> {
}
}
- private static final class ViewHolder {
- TextView filepath;
- TextView filename;
+ protected static final class ViewHolder extends AbstractViewHolder {
+ @InjectView(R.id.mapfilepath) protected TextView filepath;
+ @InjectView(R.id.mapfilename) protected TextView filename;
+
+ public ViewHolder(View view) {
+ super(view);
+ }
}
}
diff --git a/main/src/cgeo/geocaching/ui/GPXListAdapter.java b/main/src/cgeo/geocaching/ui/GPXListAdapter.java
index 9f6c14c..7f3c33f 100644
--- a/main/src/cgeo/geocaching/ui/GPXListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/GPXListAdapter.java
@@ -1,7 +1,9 @@
package cgeo.geocaching.ui;
-import cgeo.geocaching.R;
+import butterknife.InjectView;
+
import cgeo.geocaching.GpxFileListActivity;
+import cgeo.geocaching.R;
import cgeo.geocaching.files.GPXImporter;
import cgeo.geocaching.utils.Log;
@@ -18,28 +20,29 @@ import java.io.File;
import java.util.List;
public class GPXListAdapter extends ArrayAdapter<File> {
- private GpxFileListActivity activity = null;
- private LayoutInflater inflater = null;
+ private final GpxFileListActivity activity;
+ private final LayoutInflater inflater;
- private static class ViewHolder {
- TextView filepath;
- TextView filename;
+ protected static class ViewHolder extends AbstractViewHolder {
+ @InjectView(R.id.filepath) protected TextView filepath;
+ @InjectView(R.id.filename) protected TextView filename;
+
+ public ViewHolder(View view) {
+ super(view);
+ }
}
public GPXListAdapter(GpxFileListActivity parentIn, List<File> listIn) {
super(parentIn, 0, listIn);
activity = parentIn;
+ inflater = ((Activity) getContext()).getLayoutInflater();
}
@Override
public View getView(final int position, final View rowView, final ViewGroup parent) {
- if (inflater == null) {
- inflater = ((Activity) getContext()).getLayoutInflater();
- }
-
if (position > getCount()) {
- Log.w("cgGPXListAdapter.getView: Attempt to access missing item #" + position);
+ Log.w("GPXListAdapter.getView: Attempt to access missing item #" + position);
return null;
}
@@ -50,12 +53,7 @@ public class GPXListAdapter extends ArrayAdapter<File> {
final ViewHolder holder;
if (view == null) {
view = inflater.inflate(R.layout.gpx_item, null);
-
- holder = new ViewHolder();
- holder.filepath = (TextView) view.findViewById(R.id.filepath);
- holder.filename = (TextView) view.findViewById(R.id.filename);
-
- view.setTag(holder);
+ holder = new ViewHolder(view);
} else {
holder = (ViewHolder) view.getTag();
}
diff --git a/main/src/cgeo/geocaching/ui/HtmlImageCounter.java b/main/src/cgeo/geocaching/ui/HtmlImageCounter.java
new file mode 100644
index 0000000..24b70ea
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/HtmlImageCounter.java
@@ -0,0 +1,19 @@
+package cgeo.geocaching.ui;
+
+import android.graphics.drawable.Drawable;
+import android.text.Html;
+
+public class HtmlImageCounter implements Html.ImageGetter {
+
+ private int imageCount = 0;
+
+ @Override
+ public Drawable getDrawable(String url) {
+ imageCount++;
+ return null;
+ }
+
+ public int getImageCount() {
+ return imageCount;
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/ui/ImagesList.java b/main/src/cgeo/geocaching/ui/ImagesList.java
index 9464114..0f860c4 100644
--- a/main/src/cgeo/geocaching/ui/ImagesList.java
+++ b/main/src/cgeo/geocaching/ui/ImagesList.java
@@ -11,7 +11,6 @@ import cgeo.geocaching.utils.Log;
import org.apache.commons.lang3.StringUtils;
import android.app.Activity;
-import android.app.ProgressDialog;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -31,6 +30,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
+import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Collection;
@@ -39,23 +39,18 @@ import java.util.List;
public class ImagesList {
- private static final int MENU_FILE = 201;
- private static final int MENU_BROWSER = 202;
-
private BitmapDrawable currentDrawable;
private Image currentImage;
public enum ImageType {
- LogImages(R.string.cache_log_images_title, R.string.cache_log_images_loading),
- SpoilerImages(R.string.cache_spoiler_images_title, R.string.cache_spoiler_images_loading),
- AllImages(R.string.cache_images_title, R.string.cache_images_loading);
+ LogImages(R.string.cache_log_images_title),
+ SpoilerImages(R.string.cache_spoiler_images_title),
+ AllImages(R.string.cache_images_title);
private final int titleResId;
- private final int loadingResId;
- ImageType(final int title, final int loading) {
+ ImageType(final int title) {
this.titleResId = title;
- this.loadingResId = loading;
}
public int getTitle() {
@@ -64,9 +59,6 @@ public class ImagesList {
}
private LayoutInflater inflater = null;
- private ProgressDialog progressDialog = null;
- private int count = 0;
- private int countDone = 0;
private final Activity activity;
// We could use a Set here, but we will insert no duplicates, so there is no need to check for uniqueness.
private final Collection<Bitmap> bitmaps = new LinkedList<Bitmap>();
@@ -83,18 +75,10 @@ public class ImagesList {
inflater = activity.getLayoutInflater();
}
- public void loadImages(final View parentView, final List<Image> images, ImageType imageType, final boolean offline) {
+ public void loadImages(final View parentView, final List<Image> images, final boolean offline) {
imagesView = (LinearLayout) parentView.findViewById(R.id.spoiler_list);
- count = images.size();
- progressDialog = new ProgressDialog(activity);
- progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- progressDialog.setMessage(activity.getString(imageType.loadingResId));
- progressDialog.setCancelable(true);
- progressDialog.setMax(count);
- progressDialog.show();
-
for (final Image img : images) {
LinearLayout rowView = (LinearLayout) inflater.inflate(R.layout.cache_image_item, null);
@@ -154,19 +138,12 @@ public class ImagesList {
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new LayoutParams(bounds.width(), bounds.height()));
+ view.findViewById(R.id.progress_bar).setVisibility(View.GONE);
view.addView(imageView);
imageView.setId(image.hashCode());
images.put(imageView.getId(), img);
}
-
- synchronized (activity) {
- countDone++;
- progressDialog.setProgress(countDone);
- if (progressDialog.getProgress() >= count) {
- progressDialog.dismiss();
- }
- }
}
}
@@ -179,10 +156,9 @@ public class ImagesList {
}
public void onCreateContextMenu(ContextMenu menu, View v) {
+ activity.getMenuInflater().inflate(R.menu.images_list_context, menu);
final Resources res = activity.getResources();
menu.setHeaderTitle(res.getString(R.string.cache_image));
- menu.add(0, MENU_FILE, 0, res.getString(R.string.cache_image_open_file));
- menu.add(0, MENU_BROWSER, 0, res.getString(R.string.cache_image_open_browser));
final ImageView view = (ImageView) v;
currentDrawable = (BitmapDrawable) view.getDrawable();
currentImage = images.get(view.getId());
@@ -190,10 +166,10 @@ public class ImagesList {
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
- case MENU_FILE:
+ case R.id.image_open_file:
viewImageInStandardApp(currentDrawable);
return true;
- case MENU_BROWSER:
+ case R.id.image_open_browser:
if (currentImage != null) {
currentImage.openInBrowser(activity);
}
@@ -205,15 +181,15 @@ public class ImagesList {
private void viewImageInStandardApp(final BitmapDrawable image) {
final File file = LocalStorage.getStorageFile(null, "temp.jpg", false, true);
- FileOutputStream fos = null;
+ BufferedOutputStream stream = null;
try {
- fos = new FileOutputStream(file);
- image.getBitmap().compress(CompressFormat.JPEG, 100, fos);
+ stream = new BufferedOutputStream(new FileOutputStream(file));
+ image.getBitmap().compress(CompressFormat.JPEG, 100, stream);
} catch (Exception e) {
- Log.e("ImagesActivity.handleMessage.onClick", e);
+ Log.e("ImagesList.viewImageInStandardApp", e);
return;
} finally {
- IOUtils.closeQuietly(fos);
+ IOUtils.closeQuietly(stream);
}
final Intent intent = new Intent();
diff --git a/main/src/cgeo/geocaching/ui/IndexOutOfBoundsAvoidingTextView.java b/main/src/cgeo/geocaching/ui/IndexOutOfBoundsAvoidingTextView.java
new file mode 100644
index 0000000..a0c8b52
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/IndexOutOfBoundsAvoidingTextView.java
@@ -0,0 +1,55 @@
+package cgeo.geocaching.ui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+/**
+ * Jelly beans can crash when calculating the layout of a textview.
+ *
+ * https://code.google.com/p/android/issues/detail?id=35466
+ *
+ */
+public class IndexOutOfBoundsAvoidingTextView extends TextView {
+
+ public IndexOutOfBoundsAvoidingTextView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public IndexOutOfBoundsAvoidingTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public IndexOutOfBoundsAvoidingTextView(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ try{
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ } catch (IndexOutOfBoundsException e) {
+ setText(getText().toString());
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+ }
+
+ @Override
+ public void setGravity(int gravity){
+ try{
+ super.setGravity(gravity);
+ } catch (IndexOutOfBoundsException e) {
+ setText(getText().toString());
+ super.setGravity(gravity);
+ }
+ }
+
+ @Override
+ public void setText(CharSequence text, BufferType type) {
+ try{
+ super.setText(text, type);
+ } catch (IndexOutOfBoundsException e) {
+ setText(text.toString());
+ }
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/ui/LoggingUI.java b/main/src/cgeo/geocaching/ui/LoggingUI.java
index 2615947..0ee724a 100644
--- a/main/src/cgeo/geocaching/ui/LoggingUI.java
+++ b/main/src/cgeo/geocaching/ui/LoggingUI.java
@@ -3,7 +3,7 @@ package cgeo.geocaching.ui;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.LogEntry;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.cgData;
import cgeo.geocaching.activity.IAbstractActivity;
import cgeo.geocaching.enumerations.LogType;
@@ -61,31 +61,12 @@ public class LoggingUI extends AbstractUIFactory {
}
}
- private static final int MENU_ICON_LOG_VISIT = R.drawable.ic_menu_edit;
- 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 Geocache cache) {
- if (cache == null) {
- return;
- }
- if (!cache.supportsLogging()) {
- return;
- }
- if (Settings.getLogOffline()) {
- menu.add(0, MENU_LOG_VISIT_OFFLINE, 0, res.getString(R.string.cache_menu_visit_offline)).setIcon(MENU_ICON_LOG_VISIT);
- }
- else {
- menu.add(0, MENU_LOG_VISIT, 0, res.getString(R.string.cache_menu_visit)).setIcon(MENU_ICON_LOG_VISIT);
- }
- }
-
public static boolean onMenuItemSelected(final MenuItem item, IAbstractActivity activity, Geocache cache) {
switch (item.getItemId()) {
- case MENU_LOG_VISIT:
+ case R.id.menu_log_visit:
cache.logVisit(activity);
return true;
- case MENU_LOG_VISIT_OFFLINE:
+ case R.id.menu_log_visit_offline:
showOfflineMenu(cache, (Activity) activity);
return true;
default:
@@ -123,7 +104,7 @@ public class LoggingUI extends AbstractUIFactory {
break;
case CLEAR_LOG:
- cgData.clearLogOffline(cache.getGeocode());
+ cache.clearOfflineLog();
break;
}
} else {
@@ -136,10 +117,17 @@ public class LoggingUI extends AbstractUIFactory {
}
- public static void onPrepareOptionsMenu(Menu menu) {
- final MenuItem item = menu.findItem(MENU_LOG_VISIT);
- if (item != null) {
- item.setEnabled(Settings.isLogin());
- }
+ public static void onPrepareOptionsMenu(Menu menu, Geocache cache) {
+ final MenuItem itemLog = menu.findItem(R.id.menu_log_visit);
+ itemLog.setVisible(cache.supportsLogging() && !Settings.getLogOffline());
+ itemLog.setEnabled(Settings.isLogin());
+
+ final MenuItem itemOffline = menu.findItem(R.id.menu_log_visit_offline);
+ itemOffline.setVisible(cache.supportsLogging() && Settings.getLogOffline());
+ }
+
+ public static void addMenuItems(Activity activity, Menu menu, Geocache cache) {
+ activity.getMenuInflater().inflate(R.menu.logging_ui, menu);
+ onPrepareOptionsMenu(menu, cache);
}
}
diff --git a/main/src/cgeo/geocaching/ui/OwnerActionsClickListener.java b/main/src/cgeo/geocaching/ui/OwnerActionsClickListener.java
new file mode 100644
index 0000000..45ce237
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/OwnerActionsClickListener.java
@@ -0,0 +1,31 @@
+package cgeo.geocaching.ui;
+
+import cgeo.geocaching.Geocache;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * Listener for clicks on owner name
+ */
+public class OwnerActionsClickListener extends AbstractUserClickListener {
+
+ private final Geocache cache;
+
+ public OwnerActionsClickListener(Geocache cache) {
+ super(cache.supportsUserActions());
+ this.cache = cache;
+ }
+
+ @Override
+ protected String getUserName(View view) {
+ // Use real owner name vice the one owner chose to display
+ if (StringUtils.isNotBlank(cache.getOwnerUserId())) {
+ return cache.getOwnerUserId();
+ }
+ return ((TextView) view).getText().toString();
+ }
+}
+
diff --git a/main/src/cgeo/geocaching/ui/UserActionsClickListener.java b/main/src/cgeo/geocaching/ui/UserActionsClickListener.java
new file mode 100644
index 0000000..292074e
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/UserActionsClickListener.java
@@ -0,0 +1,26 @@
+package cgeo.geocaching.ui;
+
+import cgeo.geocaching.Geocache;
+
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * Listener for clicks on user name
+ */
+public class UserActionsClickListener extends AbstractUserClickListener {
+
+ public UserActionsClickListener(Geocache cache) {
+ super(cache.supportsUserActions());
+ }
+
+ public UserActionsClickListener() {
+ super(true);
+ }
+
+ @Override
+ protected CharSequence getUserName(View view) {
+ return ((TextView) view).getText().toString();
+ }
+}
+
diff --git a/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java b/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java
index dada8fd..959cb14 100644
--- a/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java
+++ b/main/src/cgeo/geocaching/ui/dialog/CoordinatesInputDialog.java
@@ -3,8 +3,8 @@ 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.settings.Settings;
+import cgeo.geocaching.settings.Settings.coordInputFormatEnum;
import cgeo.geocaching.activity.AbstractActivity;
import cgeo.geocaching.activity.ActivityMixin;
import cgeo.geocaching.compatibility.Compatibility;
@@ -13,13 +13,10 @@ import cgeo.geocaching.geopoint.GeopointFormatter;
import org.apache.commons.lang3.StringUtils;
-import android.app.Dialog;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
@@ -28,7 +25,7 @@ import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
-public class CoordinatesInputDialog extends Dialog {
+public class CoordinatesInputDialog extends NoTitleDialog {
final private AbstractActivity context;
final private IGeoData geo;
@@ -47,7 +44,7 @@ public class CoordinatesInputDialog extends Dialog {
private coordInputFormatEnum currentFormat = null;
public CoordinatesInputDialog(final AbstractActivity context, final Geocache cache, final Geopoint gp, final IGeoData geo) {
- super(context, ActivityMixin.getTheme());
+ super(context, ActivityMixin.getDialogTheme());
this.context = context;
this.geo = geo;
this.cache = cache;
@@ -65,22 +62,7 @@ public class CoordinatesInputDialog extends Dialog {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- try {
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
- } catch (Exception e) {
- // nothing
- }
-
- setContentView(R.layout.coords);
-
- findViewById(R.id.actionBarManualbutton).setOnClickListener(new View.OnClickListener() {
-
- @Override
- public void onClick(View view) {
- ActivityMixin.goManual(context, "c:geo-geocoordinate-input");
- }
- });
+ setContentView(R.layout.coordinatesinput_dialog);
final Spinner spinner = (Spinner) findViewById(R.id.spinnerCoordinateFormats);
final ArrayAdapter<CharSequence> adapter =
@@ -346,7 +328,7 @@ public class CoordinatesInputDialog extends Dialog {
if (currentFormat == coordInputFormatEnum.Plain) {
try {
gp = new Geopoint(eLat.getText().toString(), eLon.getText().toString());
- } catch (Geopoint.ParseException e) {
+ } catch (final Geopoint.ParseException e) {
if (signalError) {
context.showToast(context.getResources().getString(R.string.err_parse_lat_lon));
}
@@ -355,20 +337,20 @@ public class CoordinatesInputDialog extends Dialog {
return true;
}
- String latDir = bLat.getText().toString();
- String lonDir = bLon.getText().toString();
- String latDeg = eLatDeg.getText().toString();
- String lonDeg = eLonDeg.getText().toString();
- String latDegFrac = eLatMin.getText().toString();
- String lonDegFrac = eLonMin.getText().toString();
- String latMin = eLatMin.getText().toString();
- String lonMin = eLonMin.getText().toString();
- String latMinFrac = eLatSec.getText().toString();
- String lonMinFrac = eLonSec.getText().toString();
- String latSec = eLatSec.getText().toString();
- String lonSec = eLonSec.getText().toString();
- String latSecFrac = eLatSub.getText().toString();
- String lonSecFrac = eLonSub.getText().toString();
+ final String latDir = bLat.getText().toString();
+ final String lonDir = bLon.getText().toString();
+ final String latDeg = eLatDeg.getText().toString();
+ final String lonDeg = eLonDeg.getText().toString();
+ final String latDegFrac = eLatMin.getText().toString();
+ final String lonDegFrac = eLonMin.getText().toString();
+ final String latMin = eLatMin.getText().toString();
+ final String lonMin = eLonMin.getText().toString();
+ final String latMinFrac = eLatSec.getText().toString();
+ final String lonMinFrac = eLonSec.getText().toString();
+ final String latSec = eLatSec.getText().toString();
+ final String lonSec = eLonSec.getText().toString();
+ final String latSecFrac = eLatSub.getText().toString();
+ final String lonSecFrac = eLonSub.getText().toString();
switch (currentFormat) {
case Deg:
diff --git a/main/src/cgeo/geocaching/ui/dialog/CustomProgressDialog.java b/main/src/cgeo/geocaching/ui/dialog/CustomProgressDialog.java
index c2b722c..e80c446 100644
--- a/main/src/cgeo/geocaching/ui/dialog/CustomProgressDialog.java
+++ b/main/src/cgeo/geocaching/ui/dialog/CustomProgressDialog.java
@@ -19,7 +19,7 @@ import java.lang.reflect.Method;
public class CustomProgressDialog extends ProgressDialog {
public CustomProgressDialog(Context context) {
- super(context, ActivityMixin.getTheme());
+ super(context, ActivityMixin.getDialogTheme());
}
@Override
diff --git a/main/src/cgeo/geocaching/ui/dialog/DateDialog.java b/main/src/cgeo/geocaching/ui/dialog/DateDialog.java
index a9c579c..18f8e2e 100644
--- a/main/src/cgeo/geocaching/ui/dialog/DateDialog.java
+++ b/main/src/cgeo/geocaching/ui/dialog/DateDialog.java
@@ -3,15 +3,12 @@ package cgeo.geocaching.ui.dialog;
import cgeo.geocaching.R;
import android.app.Activity;
-import android.app.Dialog;
import android.os.Bundle;
-import android.view.ViewGroup.LayoutParams;
-import android.view.Window;
import android.widget.DatePicker;
import java.util.Calendar;
-public class DateDialog extends Dialog {
+public class DateDialog extends NoTitleDialog {
public interface DateDialogParent {
abstract public void setDate(final Calendar date);
@@ -32,13 +29,6 @@ public class DateDialog extends Dialog {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- try {
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
- } catch (Exception e) {
- // nothing
- }
-
setContentView(R.layout.date);
final DatePicker picker = (DatePicker) findViewById(R.id.picker);
diff --git a/main/src/cgeo/geocaching/ui/dialog/EditorDialog.java b/main/src/cgeo/geocaching/ui/dialog/EditorDialog.java
deleted file mode 100644
index 4db69e5..0000000
--- a/main/src/cgeo/geocaching/ui/dialog/EditorDialog.java
+++ /dev/null
@@ -1,60 +0,0 @@
-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;
-import android.view.View;
-import android.view.ViewGroup.LayoutParams;
-import android.view.Window;
-import android.widget.Button;
-import android.widget.EditText;
-
-public class EditorDialog extends Dialog {
-
- private CharSequence editorText;
- private EditorUpdate editorUpdate;
-
- public EditorDialog(CacheDetailActivity cacheDetailActivity, CharSequence editable) {
- super(cacheDetailActivity, ActivityMixin.getTheme());
- this.editorText = editable;
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.editor);
-
- final EditText editText = (EditText) findViewById(R.id.editorEditText);
- editText.setText(editorText);
-
- final Button buttonSave = (Button) findViewById(R.id.editorSave);
- buttonSave.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- editorUpdate.update(editText.getEditableText());
- EditorDialog.this.hide();
- }
- });
- }
-
- public interface EditorUpdate {
- public void update(CharSequence editorText);
- }
-
- public void setOnEditorUpdate(EditorUpdate editorUpdate) {
- this.editorUpdate = editorUpdate;
-
- }
-
- @Override
- public void show() {
- super.show();
- getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
- }
-
-}
diff --git a/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java b/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java
index 862b1a0..2c4f38d 100644
--- a/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java
+++ b/main/src/cgeo/geocaching/ui/dialog/LiveMapInfoDialogBuilder.java
@@ -1,7 +1,7 @@
package cgeo.geocaching.ui.dialog;
import cgeo.geocaching.R;
-import cgeo.geocaching.Settings;
+import cgeo.geocaching.settings.Settings;
import cgeo.geocaching.cgeoapplication;
import android.app.Activity;
diff --git a/main/src/cgeo/geocaching/ui/dialog/NoTitleDialog.java b/main/src/cgeo/geocaching/ui/dialog/NoTitleDialog.java
new file mode 100644
index 0000000..fc5ebe6
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/dialog/NoTitleDialog.java
@@ -0,0 +1,30 @@
+package cgeo.geocaching.ui.dialog;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.ViewGroup.LayoutParams;
+import android.view.Window;
+
+public abstract class NoTitleDialog extends Dialog {
+
+ public NoTitleDialog(Context context) {
+ super(context);
+ }
+
+ public NoTitleDialog(Context context, int theme) {
+ super(context, theme);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ try {
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ } catch (final Exception e) {
+ // nothing
+ }
+ }
+}
diff --git a/main/src/cgeo/geocaching/ui/logs/CacheLogsViewCreator.java b/main/src/cgeo/geocaching/ui/logs/CacheLogsViewCreator.java
new file mode 100644
index 0000000..8da711e
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/logs/CacheLogsViewCreator.java
@@ -0,0 +1,112 @@
+package cgeo.geocaching.ui.logs;
+
+import cgeo.geocaching.CacheDetailActivity;
+import cgeo.geocaching.Geocache;
+import cgeo.geocaching.LogEntry;
+import cgeo.geocaching.R;
+import cgeo.geocaching.cgeoapplication;
+import cgeo.geocaching.enumerations.LogType;
+import cgeo.geocaching.ui.UserActionsClickListener;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.content.res.Resources;
+import android.view.View;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class CacheLogsViewCreator extends LogsViewCreator {
+ private final boolean allLogs;
+ private final Resources res = cgeoapplication.getInstance().getResources();
+
+ public CacheLogsViewCreator(CacheDetailActivity cacheDetailActivity, boolean allLogs) {
+ super(cacheDetailActivity);
+ this.allLogs = allLogs;
+ }
+
+ /**
+ * May return null!
+ *
+ * @return
+ */
+ private Geocache getCache() {
+ if (this.activity instanceof CacheDetailActivity) {
+ CacheDetailActivity details = (CacheDetailActivity) this.activity;
+ return details.getCache();
+ }
+ return null;
+ }
+
+ @Override
+ protected List<LogEntry> getLogs() {
+ return allLogs ? getCache().getLogs() : getCache().getFriendsLogs();
+ }
+
+ @Override
+ protected void addHeaderView() {
+ // adds the log counts
+ final Map<LogType, Integer> logCounts = getCache().getLogCounts();
+ if (logCounts != null) {
+ final List<Entry<LogType, Integer>> sortedLogCounts = new ArrayList<Entry<LogType, Integer>>(logCounts.size());
+ for (final Entry<LogType, Integer> entry : logCounts.entrySet()) {
+ // it may happen that the label is unknown -> then avoid any output for this type
+ if (entry.getKey() != LogType.PUBLISH_LISTING && entry.getKey().getL10n() != null) {
+ sortedLogCounts.add(entry);
+ }
+ }
+
+ if (!sortedLogCounts.isEmpty()) {
+ // sort the log counts by type id ascending. that way the FOUND, DNF log types are the first and most visible ones
+ Collections.sort(sortedLogCounts, new Comparator<Entry<LogType, Integer>>() {
+
+ @Override
+ public int compare(Entry<LogType, Integer> logCountItem1, Entry<LogType, Integer> logCountItem2) {
+ return logCountItem1.getKey().compareTo(logCountItem2.getKey());
+ }
+ });
+
+ final ArrayList<String> labels = new ArrayList<String>(sortedLogCounts.size());
+ for (final Entry<LogType, Integer> pair : sortedLogCounts) {
+ labels.add(pair.getValue() + "× " + pair.getKey().getL10n());
+ }
+
+ final TextView countView = new TextView(activity);
+ countView.setText(res.getString(R.string.cache_log_types) + ": " + StringUtils.join(labels, ", "));
+ view.addHeaderView(countView, null, false);
+ }
+ }
+ }
+
+ @Override
+ protected void fillCountOrLocation(LogViewHolder holder, final LogEntry log) {
+ // finds count
+ if (log.found == -1) {
+ holder.countOrLocation.setVisibility(View.GONE);
+ } else {
+ holder.countOrLocation.setVisibility(View.VISIBLE);
+ holder.countOrLocation.setText(res.getQuantityString(R.plurals.cache_counts, log.found, log.found));
+ }
+ }
+
+ @Override
+ protected boolean isValid() {
+ return getCache() != null;
+ }
+
+ @Override
+ protected String getGeocode() {
+ return getCache().getGeocode();
+ }
+
+ @Override
+ protected UserActionsClickListener createUserActionsListener() {
+ return new UserActionsClickListener(getCache());
+ }
+
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/ui/logs/LogViewHolder.java b/main/src/cgeo/geocaching/ui/logs/LogViewHolder.java
new file mode 100644
index 0000000..16f5537
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/logs/LogViewHolder.java
@@ -0,0 +1,47 @@
+package cgeo.geocaching.ui.logs;
+
+import butterknife.InjectView;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.ui.AbstractViewHolder;
+
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class LogViewHolder extends AbstractViewHolder {
+ @InjectView(R.id.added) protected TextView date ;
+ @InjectView(R.id.type) protected TextView type;
+ @InjectView(R.id.author) protected TextView author;
+ @InjectView(R.id.count_or_location) protected TextView countOrLocation;
+ @InjectView(R.id.log) protected TextView text;
+ @InjectView(R.id.log_images) protected TextView images;
+ @InjectView(R.id.log_mark) protected ImageView marker;
+
+ private int position;
+
+ public LogViewHolder(View rowView) {
+ super(rowView);
+ }
+
+ /**
+ * Read the position of the cursor pointed to by this holder. <br/>
+ * This must be called by the UI thread.
+ *
+ * @return the cursor position
+ */
+ public int getPosition() {
+ return position;
+ }
+
+ /**
+ * Set the position of the cursor pointed to by this holder. <br/>
+ * This must be called by the UI thread.
+ *
+ * @param position
+ * the cursor position
+ */
+ public void setPosition(final int position) {
+ this.position = position;
+ }
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/ui/logs/LogsViewCreator.java b/main/src/cgeo/geocaching/ui/logs/LogsViewCreator.java
new file mode 100644
index 0000000..ee2713a
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/logs/LogsViewCreator.java
@@ -0,0 +1,175 @@
+package cgeo.geocaching.ui.logs;
+
+import cgeo.geocaching.Image;
+import cgeo.geocaching.ImagesActivity;
+import cgeo.geocaching.LogEntry;
+import cgeo.geocaching.R;
+import cgeo.geocaching.StoredList;
+import cgeo.geocaching.activity.AbstractActivity;
+import cgeo.geocaching.activity.Progress;
+import cgeo.geocaching.network.HtmlImage;
+import cgeo.geocaching.ui.AbstractCachingPageViewCreator;
+import cgeo.geocaching.ui.AnchorAwareLinkMovementMethod;
+import cgeo.geocaching.ui.DecryptTextClickListener;
+import cgeo.geocaching.ui.Formatter;
+import cgeo.geocaching.ui.HtmlImageCounter;
+import cgeo.geocaching.ui.UserActionsClickListener;
+import cgeo.geocaching.utils.TextUtils;
+import cgeo.geocaching.utils.UnknownTagsHandler;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+
+import android.os.AsyncTask;
+import android.text.Html;
+import android.text.Spanned;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class LogsViewCreator extends AbstractCachingPageViewCreator<ListView> {
+
+ protected final AbstractActivity activity;
+
+ public LogsViewCreator(AbstractActivity activity) {
+ this.activity = activity;
+ }
+
+ @Override
+ public ListView getDispatchedView() {
+ if (!isValid()) {
+ return null;
+ }
+
+ final List<LogEntry> logs = getLogs();
+
+ view = (ListView) activity.getLayoutInflater().inflate(R.layout.logs_page, null);
+ addHeaderView();
+ view.setAdapter(new ArrayAdapter<LogEntry>(activity, R.layout.logs_item, logs) {
+
+ @Override
+ public View getView(final int position, final View convertView, final android.view.ViewGroup parent) {
+ View rowView = convertView;
+ if (null == rowView) {
+ rowView = activity.getLayoutInflater().inflate(R.layout.logs_item, null);
+ }
+ LogViewHolder holder = (LogViewHolder) rowView.getTag();
+ if (null == holder) {
+ holder = new LogViewHolder(rowView);
+ }
+ holder.setPosition(position);
+
+ final LogEntry log = getItem(position);
+ fillViewHolder(convertView, holder, log);
+ return rowView;
+ }
+ });
+
+ return view;
+ }
+
+ protected void fillViewHolder(final View convertView, LogViewHolder holder, final LogEntry log) {
+ if (log.date > 0) {
+ holder.date.setText(Formatter.formatShortDateVerbally(log.date));
+ holder.date.setVisibility(View.VISIBLE);
+ } else {
+ holder.date.setVisibility(View.GONE);
+ }
+
+ holder.type.setText(log.type.getL10n());
+ holder.author.setText(StringEscapeUtils.unescapeHtml4(log.author));
+
+ fillCountOrLocation(holder, log);
+
+ // logtext, avoid parsing HTML if not necessary
+ String logText = log.log;
+ if (TextUtils.containsHtml(logText)) {
+ logText = log.getDisplayText();
+ // Fast preview: parse only HTML without loading any images
+ final HtmlImageCounter imageCounter = new HtmlImageCounter();
+ final UnknownTagsHandler unknownTagsHandler = new UnknownTagsHandler();
+ holder.text.setText(Html.fromHtml(logText, imageCounter, unknownTagsHandler), TextView.BufferType.SPANNABLE);
+ if (imageCounter.getImageCount() > 0) {
+ // Complete view: parse again with loading images - if necessary ! If there are any images causing problems the user can see at least the preview
+ final LogImageLoader loader = new LogImageLoader(holder);
+ loader.execute(logText);
+ }
+ }
+ else {
+ holder.text.setText(logText, TextView.BufferType.SPANNABLE);
+ }
+
+ // images
+ if (log.hasLogImages()) {
+ holder.images.setText(log.getImageTitles());
+ holder.images.setVisibility(View.VISIBLE);
+ holder.images.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ ImagesActivity.startActivityLogImages(activity, getGeocode(), new ArrayList<Image>(log.getLogImages()));
+ }
+ });
+ } else {
+ holder.images.setVisibility(View.GONE);
+ }
+
+ // colored marker
+ final int marker = log.type.markerId;
+ if (marker != 0) {
+ holder.marker.setVisibility(View.VISIBLE);
+ holder.marker.setImageResource(marker);
+ }
+ else {
+ holder.marker.setVisibility(View.GONE);
+ }
+
+ if (null == convertView) {
+ holder.author.setOnClickListener(createUserActionsListener());
+ holder.text.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance());
+ holder.text.setOnClickListener(new DecryptTextClickListener());
+ activity.registerForContextMenu(holder.text);
+ }
+ }
+
+ abstract protected UserActionsClickListener createUserActionsListener();
+
+ abstract protected String getGeocode();
+
+ abstract protected List<LogEntry> getLogs();
+
+ abstract protected void addHeaderView();
+
+ abstract protected void fillCountOrLocation(LogViewHolder holder, final LogEntry log);
+
+ abstract protected boolean isValid();
+
+ /** Loads the Log Images outside the ui thread. */
+
+ private class LogImageLoader extends AsyncTask<String, Progress, Spanned> {
+ final private LogViewHolder holder;
+ final private int position;
+
+ public LogImageLoader(LogViewHolder holder) {
+ this.holder = holder;
+ this.position = holder.getPosition();
+ }
+
+ @Override
+ protected Spanned doInBackground(String... logtext) {
+ return Html.fromHtml(logtext[0], new HtmlImage(getGeocode(), false, StoredList.STANDARD_LIST_ID, false), null); //, TextView.BufferType.SPANNABLE)
+ }
+
+ @Override
+ protected void onPostExecute(Spanned result) {
+ // Ensure that this holder and its view still references the right item before updating the text.
+ if (position == holder.getPosition()) {
+ holder.text.setText(result);
+ }
+ }
+
+ }
+
+}
diff --git a/main/src/cgeo/geocaching/ui/logs/TrackableLogsViewCreator.java b/main/src/cgeo/geocaching/ui/logs/TrackableLogsViewCreator.java
new file mode 100644
index 0000000..4c57406
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/logs/TrackableLogsViewCreator.java
@@ -0,0 +1,70 @@
+package cgeo.geocaching.ui.logs;
+
+import cgeo.geocaching.CacheDetailActivity;
+import cgeo.geocaching.LogEntry;
+import cgeo.geocaching.Trackable;
+import cgeo.geocaching.TrackableActivity;
+import cgeo.geocaching.ui.UserActionsClickListener;
+
+import org.apache.commons.lang3.StringUtils;
+
+import android.text.Html;
+import android.view.View;
+
+import java.util.List;
+
+public class TrackableLogsViewCreator extends LogsViewCreator {
+
+ private final Trackable trackable;
+
+ /**
+ * @param trackableActivity
+ */
+ public TrackableLogsViewCreator(TrackableActivity trackableActivity, final Trackable trackable) {
+ super(trackableActivity);
+ this.trackable = trackable;
+ }
+
+ @Override
+ protected boolean isValid() {
+ return trackable != null;
+ }
+
+ @Override
+ protected List<LogEntry> getLogs() {
+ return trackable.getLogs();
+ }
+
+ @Override
+ protected void addHeaderView() {
+ // empty
+ }
+
+ @Override
+ protected void fillCountOrLocation(LogViewHolder holder, final LogEntry log) {
+ if (StringUtils.isBlank(log.cacheName)) {
+ holder.countOrLocation.setVisibility(View.GONE);
+ } else {
+ holder.countOrLocation.setText(Html.fromHtml(log.cacheName));
+ final String cacheGuid = log.cacheGuid;
+ final String cacheName = log.cacheName;
+ holder.countOrLocation.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ CacheDetailActivity.startActivityGuid(activity, cacheGuid, Html.fromHtml(cacheName).toString());
+ }
+ });
+ }
+ }
+
+ @Override
+ protected String getGeocode() {
+ return trackable.getGeocode();
+ }
+
+ @Override
+ protected UserActionsClickListener createUserActionsListener() {
+ return new UserActionsClickListener();
+ }
+
+} \ No newline at end of file