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/CacheListAdapter.java24
-rw-r--r--main/src/cgeo/geocaching/ui/CompassMiniView.java2
-rw-r--r--main/src/cgeo/geocaching/ui/CompassView.java44
-rw-r--r--main/src/cgeo/geocaching/ui/DistanceView.java4
-rw-r--r--main/src/cgeo/geocaching/ui/EditNoteDialog.java60
-rw-r--r--main/src/cgeo/geocaching/ui/HtmlImageCounter.java19
-rw-r--r--main/src/cgeo/geocaching/ui/IndexOutOfBoundsAvoidingTextView.java55
-rw-r--r--main/src/cgeo/geocaching/ui/LoggingUI.java2
-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.java46
-rw-r--r--main/src/cgeo/geocaching/ui/dialog/DateDialog.java12
-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
19 files changed, 735 insertions, 102 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/CacheListAdapter.java b/main/src/cgeo/geocaching/ui/CacheListAdapter.java
index d95363e..3179857 100644
--- a/main/src/cgeo/geocaching/ui/CacheListAdapter.java
+++ b/main/src/cgeo/geocaching/ui/CacheListAdapter.java
@@ -6,7 +6,7 @@ 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;
@@ -14,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;
@@ -642,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 c926057..b73a2a9 100644
--- a/main/src/cgeo/geocaching/ui/CompassView.java
+++ b/main/src/cgeo/geocaching/ui/CompassView.java
@@ -171,12 +171,12 @@ public class CompassView extends View implements PeriodicHandlerListener {
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);
@@ -217,38 +217,36 @@ public class CompassView extends View implements PeriodicHandlerListener {
}
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/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
index bbf0618..9a122e2 100644
--- a/main/src/cgeo/geocaching/ui/EditNoteDialog.java
+++ b/main/src/cgeo/geocaching/ui/EditNoteDialog.java
@@ -1,21 +1,17 @@
package cgeo.geocaching.ui;
import cgeo.geocaching.R;
-import cgeo.geocaching.R.string;
+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.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager.LayoutParams;
-import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
-public class EditNoteDialog extends DialogFragment implements OnEditorActionListener {
+public class EditNoteDialog extends DialogFragment {
public interface EditNoteDialogListener {
void onFinishEditNoteDialog(final String inputText);
@@ -24,7 +20,6 @@ public class EditNoteDialog extends DialogFragment implements OnEditorActionList
public static final String ARGUMENT_INITIAL_NOTE = "initialNote";
private EditText mEditText;
- private String initialNote;
public static EditNoteDialog newInstance(final String initialNote) {
EditNoteDialog dialog = new EditNoteDialog();
@@ -37,34 +32,35 @@ public class EditNoteDialog extends DialogFragment implements OnEditorActionList
}
@Override
- public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
- final Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_edit_note, container);
+ 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);
- initialNote = getArguments().getString(ARGUMENT_INITIAL_NOTE);
+ String initialNote = getArguments().getString(ARGUMENT_INITIAL_NOTE);
if (initialNote != null) {
mEditText.setText(initialNote);
initialNote = null;
}
- getDialog().setTitle(string.cache_personal_note);
- mEditText.requestFocus();
- getDialog().getWindow().setSoftInputMode(
- LayoutParams.SOFT_INPUT_STATE_VISIBLE);
- mEditText.setOnEditorActionListener(this);
- return view;
+ 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();
}
-
- @Override
- public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event) {
- if (EditorInfo.IME_ACTION_DONE == actionId) {
- final EditNoteDialogListener activity = (EditNoteDialogListener) getActivity();
- activity.onFinishEditNoteDialog(mEditText.getText().toString());
- dismiss();
- return true;
- }
- return false;
- }
-
-
}
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/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 ac74dd3..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;
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 4ab9af0..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;
@@ -65,13 +62,6 @@ 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.coordinatesinput_dialog);
final Spinner spinner = (Spinner) findViewById(R.id.spinnerCoordinateFormats);
@@ -338,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));
}
@@ -347,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/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/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