aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBananeweizen <bananeweizen@gmx.de>2013-06-22 20:51:14 +0200
committerBananeweizen <bananeweizen@gmx.de>2013-06-23 09:08:21 +0200
commit9e9e7c2f8ce38be8b1a02a8b8632f919fa81d203 (patch)
tree9739a96c9891a62745f7cee0dff5ed63ccf739dd
parentec9af65d1d5130b0c046c58b964dfd04944eb218 (diff)
downloadcgeo-9e9e7c2f8ce38be8b1a02a8b8632f919fa81d203.zip
cgeo-9e9e7c2f8ce38be8b1a02a8b8632f919fa81d203.tar.gz
cgeo-9e9e7c2f8ce38be8b1a02a8b8632f919fa81d203.tar.bz2
#2910: remove code duplication in logs views
-rw-r--r--main/res/layout/logs_page.xml (renamed from main/res/layout/cachedetail_logs_page.xml)0
-rw-r--r--main/res/layout/trackable_logs_view.xml13
-rw-r--r--main/src/cgeo/geocaching/CacheDetailActivity.java197
-rw-r--r--main/src/cgeo/geocaching/TrackableActivity.java174
-rw-r--r--main/src/cgeo/geocaching/ui/AbstractUserClickListener.java9
-rw-r--r--main/src/cgeo/geocaching/ui/HtmlImageCounter.java19
-rw-r--r--main/src/cgeo/geocaching/ui/OwnerActionsClickListener.java5
-rw-r--r--main/src/cgeo/geocaching/ui/UserActionsClickListener.java6
-rw-r--r--main/src/cgeo/geocaching/ui/logs/CacheLogsViewCreator.java101
-rw-r--r--main/src/cgeo/geocaching/ui/logs/LogViewHolder.java (renamed from main/src/cgeo/geocaching/LogViewHolder.java)3
-rw-r--r--main/src/cgeo/geocaching/ui/logs/LogsViewCreator.java175
-rw-r--r--main/src/cgeo/geocaching/ui/logs/TrackableLogsViewCreator.java70
12 files changed, 390 insertions, 382 deletions
diff --git a/main/res/layout/cachedetail_logs_page.xml b/main/res/layout/logs_page.xml
index 9aafd83..9aafd83 100644
--- a/main/res/layout/cachedetail_logs_page.xml
+++ b/main/res/layout/logs_page.xml
diff --git a/main/res/layout/trackable_logs_view.xml b/main/res/layout/trackable_logs_view.xml
deleted file mode 100644
index 0f89c31..0000000
--- a/main/res/layout/trackable_logs_view.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ListView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:cacheColorHint="?background_color"
- android:divider="?background_color"
- android:fastScrollEnabled="true"
- android:focusable="false"
- android:footerDividersEnabled="false"
- android:headerDividersEnabled="false"
- android:listSelector="?background_color" >
-
-</ListView> \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java
index d140be1..f39f215 100644
--- a/main/src/cgeo/geocaching/CacheDetailActivity.java
+++ b/main/src/cgeo/geocaching/CacheDetailActivity.java
@@ -14,7 +14,6 @@ import cgeo.geocaching.connector.gc.GCConnector;
import cgeo.geocaching.enumerations.CacheAttribute;
import cgeo.geocaching.enumerations.LoadFlags;
import cgeo.geocaching.enumerations.LoadFlags.SaveFlag;
-import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.enumerations.WaypointType;
import cgeo.geocaching.geopoint.GeopointFormatter;
import cgeo.geocaching.geopoint.Units;
@@ -27,12 +26,13 @@ import cgeo.geocaching.ui.CacheDetailsCreator;
import cgeo.geocaching.ui.CoordinatesFormatSwitcher;
import cgeo.geocaching.ui.DecryptTextClickListener;
import cgeo.geocaching.ui.EditNoteDialog;
+import cgeo.geocaching.ui.HtmlImageCounter;
import cgeo.geocaching.ui.EditNoteDialog.EditNoteDialogListener;
+import cgeo.geocaching.ui.logs.CacheLogsViewCreator;
import cgeo.geocaching.ui.Formatter;
import cgeo.geocaching.ui.ImagesList;
import cgeo.geocaching.ui.LoggingUI;
import cgeo.geocaching.ui.OwnerActionsClickListener;
-import cgeo.geocaching.ui.UserActionsClickListener;
import cgeo.geocaching.ui.WeakReferenceHandler;
import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.ClipboardUtils;
@@ -105,12 +105,9 @@ import android.widget.TextView.BufferType;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
import java.util.regex.Pattern;
/**
@@ -1684,7 +1681,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
}
}
-
}
protected class DescriptionViewCreator extends AbstractCachingPageViewCreator<ScrollView> {
@@ -1860,21 +1856,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
editNoteDialogListener.onFinishEditNoteDialog(note);
}
- private static class HtmlImageCounter implements Html.ImageGetter {
-
- private int imageCount = 0;
-
- @Override
- public Drawable getDrawable(String url) {
- imageCount++;
- return null;
- }
-
- public int getImageCount() {
- return imageCount;
- }
- }
-
/**
* Loads the description in background. <br />
* <br />
@@ -2018,176 +1999,6 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
}
}
- private class LogsViewCreator extends AbstractCachingPageViewCreator<ListView> {
- private final boolean allLogs;
-
- LogsViewCreator(boolean allLogs) {
- this.allLogs = allLogs;
- }
-
- @Override
- public ListView getDispatchedView() {
- if (cache == null) {
- // something is really wrong
- return null;
- }
-
- view = (ListView) getLayoutInflater().inflate(R.layout.cachedetail_logs_page, null);
-
- // log count
- final Map<LogType, Integer> logCounts = cache.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(CacheDetailActivity.this);
- countView.setText(res.getString(R.string.cache_log_types) + ": " + StringUtils.join(labels, ", "));
- view.addHeaderView(countView, null, false);
- }
- }
-
- final List<LogEntry> logs = allLogs ? cache.getLogs() : cache.getFriendsLogs();
- view.setAdapter(new ArrayAdapter<LogEntry>(CacheDetailActivity.this, R.layout.logs_item, logs) {
- final UserActionsClickListener userActionsClickListener = new UserActionsClickListener(cache);
- final DecryptTextClickListener decryptTextClickListener = new DecryptTextClickListener();
-
- @Override
- public View getView(final int position, final View convertView, final ViewGroup parent) {
- View rowView = convertView;
- if (null == rowView) {
- rowView = 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);
-
- 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));
-
- // finds count
- holder.countOrLocation.setVisibility(View.VISIBLE);
- if (log.found == -1) {
- holder.countOrLocation.setVisibility(View.GONE);
- } else {
- holder.countOrLocation.setText(res.getQuantityString(R.plurals.cache_counts, log.found, log.found));
- }
-
- // 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(CacheDetailActivity.this, cache.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) {
- // if convertView != null then this listeners are already set
- holder.author.setOnClickListener(userActionsClickListener);
- holder.text.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance());
- holder.text.setOnClickListener(decryptTextClickListener);
- registerForContextMenu(holder.text);
- }
-
- return rowView;
- }
- });
-
- return view;
- }
-
- /** 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(cache.getGeocode(), false, cache.getListId(), 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);
- }
- }
-
- }
-
- }
-
private class WaypointsViewCreator extends AbstractCachingPageViewCreator<ScrollView> {
@Override
@@ -2528,10 +2339,10 @@ public class CacheDetailActivity extends AbstractViewPagerActivity<CacheDetailAc
return new DescriptionViewCreator();
case LOGS:
- return new LogsViewCreator(true);
+ return new CacheLogsViewCreator(this, cache, true);
case LOGSFRIENDS:
- return new LogsViewCreator(false);
+ return new CacheLogsViewCreator(this, cache, false);
case WAYPOINTS:
return new WaypointsViewCreator();
diff --git a/main/src/cgeo/geocaching/TrackableActivity.java b/main/src/cgeo/geocaching/TrackableActivity.java
index 8dc29ee..9963d45 100644
--- a/main/src/cgeo/geocaching/TrackableActivity.java
+++ b/main/src/cgeo/geocaching/TrackableActivity.java
@@ -10,14 +10,14 @@ import cgeo.geocaching.connector.trackable.TrackableConnector;
import cgeo.geocaching.enumerations.LogType;
import cgeo.geocaching.geopoint.Units;
import cgeo.geocaching.network.HtmlImage;
-import cgeo.geocaching.network.Network;
import cgeo.geocaching.ui.AbstractCachingPageViewCreator;
import cgeo.geocaching.ui.AnchorAwareLinkMovementMethod;
import cgeo.geocaching.ui.CacheDetailsCreator;
import cgeo.geocaching.ui.Formatter;
+import cgeo.geocaching.ui.UserActionsClickListener;
+import cgeo.geocaching.ui.logs.TrackableLogsViewCreator;
import cgeo.geocaching.utils.HtmlUtils;
import cgeo.geocaching.utils.Log;
-import cgeo.geocaching.utils.TextUtils;
import cgeo.geocaching.utils.UnknownTagsHandler;
import org.apache.commons.lang3.StringUtils;
@@ -32,16 +32,12 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
-import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
@@ -61,12 +57,12 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
this.resId = resId;
}
}
+
private Trackable trackable = null;
private String geocode = null;
private String name = null;
private String guid = null;
private String id = null;
- private String contextMenuUser = null;
private LayoutInflater inflater = null;
private ProgressDialog waitDialog = null;
private final Handler loadTrackableHandler = new Handler() {
@@ -192,55 +188,6 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
}
@Override
- public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) {
-
- // FIXME: replace this context menu stuff by a UserActionsClickListener instead.
-
- super.onCreateContextMenu(menu, view, info);
- final int viewId = view.getId();
-
- if (viewId == R.id.author) { // Log item author
- contextMenuUser = ((TextView) view).getText().toString();
- } else { // Trackable owner, and user holding trackable now
- final RelativeLayout itemLayout = (RelativeLayout) view.getParent();
- final TextView itemName = (TextView) itemLayout.findViewById(R.id.name);
-
- final String selectedName = itemName.getText().toString();
- if (selectedName.equals(res.getString(R.string.trackable_owner))) {
- contextMenuUser = trackable.getOwner();
- } else if (selectedName.equals(res.getString(R.string.trackable_spotted))) {
- contextMenuUser = trackable.getSpottedName();
- }
- }
-
- menu.setHeaderTitle(res.getString(R.string.user_menu_title) + " " + contextMenuUser);
- menu.add(viewId, 1, 0, res.getString(R.string.user_menu_view_hidden));
- menu.add(viewId, 2, 0, res.getString(R.string.user_menu_view_found));
- menu.add(viewId, 3, 0, res.getString(R.string.user_menu_open_browser));
- menu.add(viewId, 4, 0, res.getString(R.string.user_menu_send_message));
- }
-
- @Override
- public boolean onContextItemSelected(final MenuItem item) {
- switch (item.getItemId()) {
- case 1:
- cgeocaches.startActivityOwner(this, contextMenuUser);
- return true;
- case 2:
- cgeocaches.startActivityUserName(this, contextMenuUser);
- return true;
- case 3:
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + Network.encode(contextMenuUser))));
- return true;
- case 4:
- startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/email/?u=" + Network.encode(contextMenuUser))));
- return true;
- default:
- return false;
- }
- }
-
- @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.trackable_activity, menu);
return true;
@@ -301,23 +248,6 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
}
}
- private class UserActionsListener implements View.OnClickListener {
-
- @Override
- public void onClick(View view) {
- if (view == null) {
- return;
- }
-
- try {
- registerForContextMenu(view);
- openContextMenu(view);
- } catch (final Exception e) {
- Log.e("TrackableActivity.UserActionsListener.onClick ", e);
- }
- }
- }
-
private class TrackableIconThread extends Thread {
final private String url;
final private Handler handler;
@@ -377,7 +307,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
case DETAILS:
return new DetailsViewCreator();
case LOGS:
- return new LogsViewCreator();
+ return new TrackableLogsViewCreator(this, trackable);
default:
throw new IllegalArgumentException();
}
@@ -398,98 +328,6 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
return new ImmutablePair<List<? extends Page>, Integer>(pages, 0);
}
- public class LogsViewCreator extends AbstractCachingPageViewCreator<ListView> {
-
- @Override
- public ListView getDispatchedView() {
- view = (ListView) getLayoutInflater().inflate(R.layout.trackable_logs_view, null);
-
- if (trackable != null && trackable.getLogs() != null) {
- view.setAdapter(new ArrayAdapter<LogEntry>(TrackableActivity.this, R.layout.logs_item, trackable.getLogs()) {
- @Override
- public View getView(int position, View convertView, android.view.ViewGroup parent) {
- View rowView = convertView;
- if (null == rowView) {
- rowView = getLayoutInflater().inflate(R.layout.logs_item, null);
- }
- LogViewHolder holder = (LogViewHolder) rowView.getTag();
- if (null == holder) {
- holder = new LogViewHolder(rowView);
- }
-
- final LogEntry log = getItem(position);
- fillViewHolder(holder, log);
- return rowView;
- }
- });
- }
- return view;
- }
-
- protected void fillViewHolder(LogViewHolder holder, final LogEntry log) {
- if (log.date > 0) {
- holder.date.setText(Formatter.formatShortDateVerbally(log.date));
- }
-
- holder.type.setText(log.type.getL10n());
- holder.author.setText(Html.fromHtml(log.author), TextView.BufferType.SPANNABLE);
-
- 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(TrackableActivity.this, cacheGuid, Html.fromHtml(cacheName).toString());
- }
- });
- }
-
- final TextView logView = holder.text;
- logView.setMovementMethod(AnchorAwareLinkMovementMethod.getInstance());
-
- String logText = log.log;
- if (TextUtils.containsHtml(logText)) {
- logText = log.getDisplayText();
- logView.setText(Html.fromHtml(logText, new HtmlImage(null, false, StoredList.TEMPORARY_LIST_ID, false), null), TextView.BufferType.SPANNABLE);
- }
- else {
- logView.setText(logText);
- }
-
- final ImageView statusMarker = holder.marker;
- // colored marker
- final int marker = log.type.markerId;
- if (marker != 0) {
- statusMarker.setVisibility(View.VISIBLE);
- statusMarker.setImageResource(marker);
- }
- else {
- statusMarker.setVisibility(View.GONE);
- }
-
- // 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(TrackableActivity.this, trackable.getGeocode(), new ArrayList<Image>(log.getLogImages()));
- }
- });
- } else {
- holder.images.setVisibility(View.GONE);
- }
-
- holder.author.setOnClickListener(new UserActionsListener());
- }
-
- }
-
public class DetailsViewCreator extends AbstractCachingPageViewCreator<ScrollView> {
@InjectView(R.id.goal_box) protected LinearLayout goalBox;
@@ -533,7 +371,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
final TextView owner = details.add(R.string.trackable_owner, res.getString(R.string.trackable_unknown));
if (StringUtils.isNotBlank(trackable.getOwner())) {
owner.setText(Html.fromHtml(trackable.getOwner()), TextView.BufferType.SPANNABLE);
- owner.setOnClickListener(new UserActionsListener());
+ owner.setOnClickListener(new UserActionsClickListener());
}
// trackable spotted
@@ -577,7 +415,7 @@ public class TrackableActivity extends AbstractViewPagerActivity<TrackableActivi
}
});
} else if (Trackable.SPOTTED_USER == trackable.getSpottedType()) {
- spotted.setOnClickListener(new UserActionsListener());
+ spotted.setOnClickListener(new UserActionsClickListener());
}
}
diff --git a/main/src/cgeo/geocaching/ui/AbstractUserClickListener.java b/main/src/cgeo/geocaching/ui/AbstractUserClickListener.java
index b5e5c9a..b717568 100644
--- a/main/src/cgeo/geocaching/ui/AbstractUserClickListener.java
+++ b/main/src/cgeo/geocaching/ui/AbstractUserClickListener.java
@@ -1,6 +1,5 @@
package cgeo.geocaching.ui;
-import cgeo.geocaching.Geocache;
import cgeo.geocaching.R;
import cgeo.geocaching.cgeocaches;
import cgeo.geocaching.activity.AbstractActivity;
@@ -15,10 +14,10 @@ import android.view.View;
abstract class AbstractUserClickListener implements View.OnClickListener {
- protected final Geocache cache;
+ private final boolean enabled;
- public AbstractUserClickListener(final Geocache cache) {
- this.cache = cache;
+ public AbstractUserClickListener(final boolean enabled) {
+ this.enabled = enabled;
}
@Override
@@ -26,7 +25,7 @@ abstract class AbstractUserClickListener implements View.OnClickListener {
if (view == null) {
return;
}
- if (!cache.supportsUserActions()) {
+ if (!enabled) {
return;
}
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/OwnerActionsClickListener.java b/main/src/cgeo/geocaching/ui/OwnerActionsClickListener.java
index e7b04a5..45ce237 100644
--- a/main/src/cgeo/geocaching/ui/OwnerActionsClickListener.java
+++ b/main/src/cgeo/geocaching/ui/OwnerActionsClickListener.java
@@ -12,8 +12,11 @@ import android.widget.TextView;
*/
public class OwnerActionsClickListener extends AbstractUserClickListener {
+ private final Geocache cache;
+
public OwnerActionsClickListener(Geocache cache) {
- super(cache);
+ super(cache.supportsUserActions());
+ this.cache = cache;
}
@Override
diff --git a/main/src/cgeo/geocaching/ui/UserActionsClickListener.java b/main/src/cgeo/geocaching/ui/UserActionsClickListener.java
index 8235446..292074e 100644
--- a/main/src/cgeo/geocaching/ui/UserActionsClickListener.java
+++ b/main/src/cgeo/geocaching/ui/UserActionsClickListener.java
@@ -11,7 +11,11 @@ import android.widget.TextView;
public class UserActionsClickListener extends AbstractUserClickListener {
public UserActionsClickListener(Geocache cache) {
- super(cache);
+ super(cache.supportsUserActions());
+ }
+
+ public UserActionsClickListener() {
+ super(true);
}
@Override
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..a785681
--- /dev/null
+++ b/main/src/cgeo/geocaching/ui/logs/CacheLogsViewCreator.java
@@ -0,0 +1,101 @@
+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 Geocache cache;
+ private final Resources res = cgeoapplication.getInstance().getResources();
+
+ public CacheLogsViewCreator(CacheDetailActivity cacheDetailActivity, final Geocache cache, boolean allLogs) {
+ super(cacheDetailActivity);
+ this.cache = cache;
+ this.allLogs = allLogs;
+ }
+
+ @Override
+ protected List<LogEntry> getLogs() {
+ return allLogs ? cache.getLogs() : cache.getFriendsLogs();
+ }
+
+ @Override
+ protected void addHeaderView() {
+ // adds the log counts
+ final Map<LogType, Integer> logCounts = cache.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 cache != null;
+ }
+
+ @Override
+ protected String getGeocode() {
+ return cache.getGeocode();
+ }
+
+ @Override
+ protected UserActionsClickListener createUserActionsListener() {
+ return new UserActionsClickListener(cache);
+ }
+
+} \ No newline at end of file
diff --git a/main/src/cgeo/geocaching/LogViewHolder.java b/main/src/cgeo/geocaching/ui/logs/LogViewHolder.java
index 14148d0..16f5537 100644
--- a/main/src/cgeo/geocaching/LogViewHolder.java
+++ b/main/src/cgeo/geocaching/ui/logs/LogViewHolder.java
@@ -1,7 +1,8 @@
-package cgeo.geocaching;
+package cgeo.geocaching.ui.logs;
import butterknife.InjectView;
+import cgeo.geocaching.R;
import cgeo.geocaching.ui.AbstractViewHolder;
import android.view.View;
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