Created dialog as a visual representation of unsuccessful upload of OSM edit operation. Issue #1291

This commit is contained in:
GaidamakUA 2015-07-30 12:37:26 +03:00
parent 5a495b1913
commit 87320663ad
12 changed files with 505 additions and 219 deletions

View file

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="@dimen/list_item_height">
<TextView
android:id="@+id/nameTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/dialog_elements_vertical_margin"
android:layout_marginRight="@dimen/dialog_elements_vertical_margin"
android:layout_weight="1"
android:gravity="center_vertical"
android:textSize="@dimen/default_list_text_size"
tools:text="@string/lorem_ipsum"/>
<ImageView
android:id="@+id/iconImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="3dp"
android:layout_marginRight="@dimen/dialog_elements_vertical_margin"
android:gravity="center_vertical"
android:maxLines="2"
android:src="@drawable/ic_action_remove_dark"
android:textSize="@dimen/default_desc_text_size"/>
</LinearLayout>

View file

@ -2221,4 +2221,9 @@ Afghanistan, Albania, Algeria, Andorra, Angola, Anguilla, Antigua and Barbuda, A
<string name="rate_this_app_long">Please give OsmAnd a score on Google Play</string> <string name="rate_this_app_long">Please give OsmAnd a score on Google Play</string>
<string name="user_hates_app_get_feedback">Tell us why.</string> <string name="user_hates_app_get_feedback">Tell us why.</string>
<string name="user_hates_app_get_feedback_long">Please tell us what would you want to change in this app.</string> <string name="user_hates_app_get_feedback_long">Please tell us what would you want to change in this app.</string>
<string name="failed_to_upload">Failed to upload</string>
<string name="delete_change">Delete change</string>
<string name="successfully_uploaded_pattern">Successfully uploaded {0}/{1}</string>
<string name="try_again">Try again</string>
<string name="error_message_pattern">Error: {0}</string>
</resources> </resources>

View file

@ -1,16 +1,5 @@
package net.osmand.plus.osmedit; package net.osmand.plus.osmedit;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import net.osmand.access.AccessibleToast;
import net.osmand.data.PointDescription;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.ProgressImplementation;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dashboard.DashBaseFragment;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -22,13 +11,23 @@ import android.widget.Button;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import net.osmand.data.PointDescription;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.ProgressImplementation;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dashboard.DashBaseFragment;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/** /**
* Created by Denis * Created by Denis
* on 20.01.2015. * on 20.01.2015.
*/ */
public class DashOsmEditsFragment extends DashBaseFragment implements OsmEditsUploadListener { public class DashOsmEditsFragment extends DashBaseFragment {
public static final String TAG = "DASH_OSM_EDITS_FRAGMENT"; public static final String TAG = "DASH_OSM_EDITS_FRAGMENT";
OsmEditingPlugin plugin; OsmEditingPlugin plugin;
@ -64,14 +63,14 @@ public class DashOsmEditsFragment extends DashBaseFragment implements OsmEditsUp
private void setupEditings() { private void setupEditings() {
View mainView = getView(); View mainView = getView();
if (plugin == null){ if (plugin == null) {
mainView.setVisibility(View.GONE); mainView.setVisibility(View.GONE);
return; return;
} }
ArrayList<OsmPoint> dataPoints = new ArrayList<>(); ArrayList<OsmPoint> dataPoints = new ArrayList<>();
getOsmPoints(dataPoints); getOsmPoints(dataPoints);
if (dataPoints.size() == 0){ if (dataPoints.size() == 0) {
mainView.setVisibility(View.GONE); mainView.setVisibility(View.GONE);
return; return;
} else { } else {
@ -114,7 +113,7 @@ public class DashOsmEditsFragment extends DashBaseFragment implements OsmEditsUp
} }
} }
private void uploadItem(final OsmPoint point){ private void uploadItem(final OsmPoint point) {
AlertDialog.Builder b = new AlertDialog.Builder(getActivity()); AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
b.setMessage(getString(R.string.local_osm_changes_upload_all_confirm, 1)); b.setMessage(getString(R.string.local_osm_changes_upload_all_confirm, 1));
b.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { b.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@ -129,13 +128,31 @@ public class DashOsmEditsFragment extends DashBaseFragment implements OsmEditsUp
private void showProgressDialog(OsmPoint point) { private void showProgressDialog(OsmPoint point) {
OpenstreetmapRemoteUtil remotepoi = new OpenstreetmapRemoteUtil(getActivity()); OpenstreetmapRemoteUtil remotepoi = new OpenstreetmapRemoteUtil(getActivity());
OsmPoint[] toUpload = new OsmPoint[] { point }; OsmPoint[] toUpload = new OsmPoint[]{point};
OsmBugsRemoteUtil remotebug = new OsmBugsRemoteUtil(getMyApplication()); OsmBugsRemoteUtil remotebug = new OsmBugsRemoteUtil(getMyApplication());
ProgressDialog dialog = ProgressImplementation.createProgressDialog(getActivity(), ProgressDialog dialog = ProgressImplementation.createProgressDialog(getActivity(),
getString(R.string.uploading), getString(R.string.local_openstreetmap_uploading), getString(R.string.uploading), getString(R.string.local_openstreetmap_uploading),
ProgressDialog.STYLE_HORIZONTAL).getDialog(); ProgressDialog.STYLE_HORIZONTAL).getDialog();
OsmEditsUploadListener listener = new OsmEditUploadListenerHelper(getActivity(),
getString(R.string.local_openstreetmap_were_uploaded)) {
@Override
public void uploadUpdated(OsmPoint point) {
super.uploadUpdated(point);
if (!DashOsmEditsFragment.this.isDetached()) {
onOpenDash();
}
}
@Override
public void uploadEnded(Map<OsmPoint, String> loadErrorsMap) {
super.uploadEnded(loadErrorsMap);
if (!DashOsmEditsFragment.this.isDetached()) {
onOpenDash();
}
}
};
UploadOpenstreetmapPointAsyncTask uploadTask = new UploadOpenstreetmapPointAsyncTask(dialog, UploadOpenstreetmapPointAsyncTask uploadTask = new UploadOpenstreetmapPointAsyncTask(dialog,
DashOsmEditsFragment.this, plugin, remotepoi, remotebug, toUpload.length); listener, plugin, remotepoi, remotebug, toUpload.length);
uploadTask.execute(toUpload); uploadTask.execute(toUpload);
dialog.show(); dialog.show();
} }
@ -143,9 +160,9 @@ public class DashOsmEditsFragment extends DashBaseFragment implements OsmEditsUp
private void getOsmPoints(ArrayList<OsmPoint> dataPoints) { private void getOsmPoints(ArrayList<OsmPoint> dataPoints) {
List<OpenstreetmapPoint> l1 = plugin.getDBPOI().getOpenstreetmapPoints(); List<OpenstreetmapPoint> l1 = plugin.getDBPOI().getOpenstreetmapPoints();
List<OsmNotesPoint> l2 = plugin.getDBBug().getOsmbugsPoints(); List<OsmNotesPoint> l2 = plugin.getDBBug().getOsmbugsPoints();
if (l1.isEmpty()){ if (l1.isEmpty()) {
int i = 0; int i = 0;
for(OsmPoint point : l2){ for (OsmPoint point : l2) {
if (i > 2) { if (i > 2) {
break; break;
} }
@ -154,7 +171,7 @@ public class DashOsmEditsFragment extends DashBaseFragment implements OsmEditsUp
} }
} else if (l2.isEmpty()) { } else if (l2.isEmpty()) {
int i = 0; int i = 0;
for(OsmPoint point : l1){ for (OsmPoint point : l1) {
if (i > 2) { if (i > 2) {
break; break;
} }
@ -164,30 +181,11 @@ public class DashOsmEditsFragment extends DashBaseFragment implements OsmEditsUp
} else { } else {
dataPoints.add(l1.get(0)); dataPoints.add(l1.get(0));
dataPoints.add(l2.get(0)); dataPoints.add(l2.get(0));
if (l1.size() > 1){ if (l1.size() > 1) {
dataPoints.add(l1.get(1)); dataPoints.add(l1.get(1));
} else if (l2.size() > 1){ } else if (l2.size() > 1) {
dataPoints.add(l2.get(1)); dataPoints.add(l2.get(1));
} }
} }
} }
@Override
public void uploadUpdated(OsmPoint point) {
if (!this.isDetached()){
onOpenDash();
}
}
@Override
public void uploadEnded(Integer result) {
if (result != null) {
AccessibleToast.makeText(getActivity(),
MessageFormat.format(getString(R.string.local_openstreetmap_were_uploaded), result), Toast.LENGTH_LONG)
.show();
}
if (!this.isDetached()){
onOpenDash();
}
}
} }

View file

@ -1,11 +1,9 @@
package net.osmand.plus.osmedit; package net.osmand.plus.osmedit;
import java.io.Serializable;
import net.osmand.osm.edit.Node; import net.osmand.osm.edit.Node;
import net.osmand.osm.edit.OSMSettings.OSMTagKey; import net.osmand.osm.edit.OSMSettings.OSMTagKey;
public class OpenstreetmapPoint extends OsmPoint implements Serializable { public class OpenstreetmapPoint extends OsmPoint {
private static final long serialVersionUID = 729654300829771467L; private static final long serialVersionUID = 729654300829771467L;
private Node entity; private Node entity;
private String comment; private String comment;

View file

@ -1,20 +1,8 @@
package net.osmand.plus.osmedit; package net.osmand.plus.osmedit;
import java.io.BufferedReader; import android.content.Context;
import java.io.BufferedWriter; import android.util.Xml;
import java.io.ByteArrayInputStream; import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.access.AccessibleToast; import net.osmand.access.AccessibleToast;
@ -37,9 +25,21 @@ import org.apache.commons.logging.Log;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;
import android.content.Context; import java.io.BufferedReader;
import android.util.Xml; import java.io.BufferedWriter;
import android.widget.Toast; import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.Map;
public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil { public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
@ -335,11 +335,7 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
return entityInfo; return entityInfo;
} }
} catch (IOException e) { } catch (IOException | SAXException e) {
log.error("Loading node failed " + nodeId, e); //$NON-NLS-1$
AccessibleToast.makeText(ctx, ctx.getResources().getString(R.string.shared_string_io_error),
Toast.LENGTH_LONG).show();
} catch (SAXException e) {
log.error("Loading node failed " + nodeId, e); //$NON-NLS-1$ log.error("Loading node failed " + nodeId, e); //$NON-NLS-1$
AccessibleToast.makeText(ctx, ctx.getResources().getString(R.string.shared_string_io_error), AccessibleToast.makeText(ctx, ctx.getResources().getString(R.string.shared_string_io_error),
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();

View file

@ -1,14 +1,5 @@
package net.osmand.plus.osmedit; package net.osmand.plus.osmedit;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.osm.io.Base64; import net.osmand.osm.io.Base64;
import net.osmand.osm.io.NetworkUtils; import net.osmand.osm.io.NetworkUtils;
@ -19,20 +10,26 @@ import net.osmand.plus.Version;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URLEncoder;
public class OsmBugsRemoteUtil implements OsmBugsUtil { public class OsmBugsRemoteUtil implements OsmBugsUtil {
private static final Log log = PlatformUtil.getLog(OsmBugsRemoteUtil.class); private static final Log log = PlatformUtil.getLog(OsmBugsRemoteUtil.class);
static String getNotesApi() static String getNotesApi() {
{
final int deviceApiVersion = android.os.Build.VERSION.SDK_INT; final int deviceApiVersion = android.os.Build.VERSION.SDK_INT;
String RETURN_API; String RETURN_API;
if (deviceApiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { if (deviceApiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) {
RETURN_API = "https://api.openstreetmap.org/api/0.6/notes"; RETURN_API = "https://api.openstreetmap.org/api/0.6/notes";
} } else {
else {
RETURN_API = "http://api.openstreetmap.org/api/0.6/notes"; RETURN_API = "http://api.openstreetmap.org/api/0.6/notes";
} }
@ -48,7 +45,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
} }
@Override @Override
public String createNewBug(double latitude, double longitude, String text, String author){ public String createNewBug(double latitude, double longitude, String text, String author) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append(getNotesApi()).append("?"); //$NON-NLS-1$ b.append(getNotesApi()).append("?"); //$NON-NLS-1$
b.append("lat=").append(latitude); //$NON-NLS-1$ b.append("lat=").append(latitude); //$NON-NLS-1$
@ -58,7 +55,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
} }
@Override @Override
public String addingComment(long id, String text, String author){ public String addingComment(long id, String text, String author) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append(getNotesApi()).append("/"); b.append(getNotesApi()).append("/");
b.append(id); //$NON-NLS-1$ b.append(id); //$NON-NLS-1$
@ -67,12 +64,12 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
} }
@Override @Override
public String closingBug(long id, String text, String author){ public String closingBug(long id, String text, String author) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append(getNotesApi()).append("/"); b.append(getNotesApi()).append("/");
b.append(id); //$NON-NLS-1$ b.append(id); //$NON-NLS-1$
b.append("/close?text=").append(URLEncoder.encode(text)); //$NON-NLS-1$ b.append("/close?text=").append(URLEncoder.encode(text)); //$NON-NLS-1$
return editingPOI(b.toString(), "POST", "close bug") ; //$NON-NLS-1$ return editingPOI(b.toString(), "POST", "close bug"); //$NON-NLS-1$
} }
private String editingPOI(String url, String requestMethod, String userOperation) { private String editingPOI(String url, String requestMethod, String userOperation) {
@ -106,24 +103,22 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
// populate return fields. // populate return fields.
StringBuilder responseBody = new StringBuilder(); StringBuilder responseBody = new StringBuilder();
if (true) { responseBody.setLength(0);
responseBody.setLength(0); InputStream i = connection.getInputStream();
InputStream i = connection.getInputStream(); if (i != null) {
if (i != null) { BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256); //$NON-NLS-1$
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256); //$NON-NLS-1$ String s;
String s; boolean f = true;
boolean f = true; while ((s = in.readLine()) != null) {
while ((s = in.readLine()) != null) { if (!f) {
if (!f) { responseBody.append("\n"); //$NON-NLS-1$
responseBody.append("\n"); //$NON-NLS-1$ } else {
} else { f = false;
f = false;
}
responseBody.append(s);
} }
responseBody.append(s);
} }
log.info("Response : " + responseBody); //$NON-NLS-1$
} }
log.info("Response : " + responseBody); //$NON-NLS-1$
connection.disconnect(); connection.disconnect();
if (!ok) { if (!ok) {
return msg + "\n" + responseBody; return msg + "\n" + responseBody;
@ -138,7 +133,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
return e.getMessage() + ""; return e.getMessage() + "";
} catch (IOException e) { } catch (IOException e) {
log.error(userOperation + " " + app.getString(R.string.failed_op), e); //$NON-NLS-1$ log.error(userOperation + " " + app.getString(R.string.failed_op), e); //$NON-NLS-1$
return e.getMessage() + ""; return e.getMessage() + " link unavailable";
} }
return null; return null;
} }

View file

@ -0,0 +1,289 @@
package net.osmand.plus.osmedit;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.MainThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import net.osmand.access.AccessibleToast;
import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.ProgressImplementation;
import net.osmand.plus.R;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Map;
public class OsmEditUploadListenerHelper implements OsmEditsUploadListener {
public static final String TAG = "OsmEditUploadListenerHe";
private final FragmentActivity activity;
private final String numberFormat;
public OsmEditUploadListenerHelper(FragmentActivity activity, String numberFormat) {
this.activity = activity;
this.numberFormat = numberFormat;
}
@Override
public void uploadUpdated(OsmPoint point) {
}
@MainThread
@Override
public void uploadEnded(Map<OsmPoint, String> loadErrorsMap) {
int uploaded = 0;
int pointsNum = loadErrorsMap.keySet().size();
for (OsmPoint point : loadErrorsMap.keySet()) {
if (loadErrorsMap.get(point) == null) {
uploaded++;
}
}
if (uploaded == pointsNum) {
AccessibleToast.makeText(activity,
MessageFormat.format(numberFormat, uploaded),
Toast.LENGTH_LONG)
.show();
} else if (pointsNum == 1) {
Log.v(TAG, "in if1");
OsmPoint point = loadErrorsMap.keySet().iterator().next();
String message = loadErrorsMap.get(point);
DialogFragment dialogFragment =
UploadingErrorDialogFragment.getInstance(message, point);
dialogFragment.show(activity.getSupportFragmentManager(), "error_loading");
} else {
Log.v(TAG, "in if2");
String[] pointNames = new String[loadErrorsMap.keySet().size()];
boolean[] hasErrors = new boolean[loadErrorsMap.keySet().size()];
ArrayList<OsmPoint> pointsWithErrors = new ArrayList<>();
int i = 0;
for (OsmPoint point : loadErrorsMap.keySet()) {
pointNames[i] = point.getGroup() == OsmPoint.Group.BUG ?
((OsmNotesPoint) point).getText() :
((OpenstreetmapPoint) point).getName();
pointNames[i] = TextUtils.isEmpty(pointNames[i]) ?
"id:" + point.getId() : pointNames[i];
hasErrors[i] = loadErrorsMap.get(point) != null;
if (hasErrors[i]) {
pointsWithErrors.add(point);
}
i++;
}
UploadingMultipleErrorDialogFragment dialogFragment =
UploadingMultipleErrorDialogFragment.getInstance(pointNames, hasErrors);
dialogFragment.setPointsToUpload(
pointsWithErrors.toArray(new OsmPoint[pointsWithErrors.size()]));
dialogFragment.show(activity.getSupportFragmentManager(), "multiple_error_loading");
}
}
private static void showUploadItemsProgressDialog(Fragment fragment, OsmPoint[] toUpload) {
FragmentActivity activity = fragment.getActivity();
OsmEditingPlugin plugin = OsmandPlugin.getEnabledPlugin(OsmEditingPlugin.class);
OpenstreetmapRemoteUtil remotepoi = new OpenstreetmapRemoteUtil(activity);
OsmBugsRemoteUtil remotebug = new OsmBugsRemoteUtil((OsmandApplication) activity.getApplication());
OsmEditUploadListenerHelper helper = new OsmEditUploadListenerHelper(activity,
activity.getResources().getString(R.string.local_openstreetmap_were_uploaded));
Resources resources = activity.getResources();
ProgressDialog dialog = ProgressImplementation.createProgressDialog(
activity,
resources.getString(R.string.uploading),
resources.getString(R.string.local_openstreetmap_uploading),
ProgressDialog.STYLE_HORIZONTAL).getDialog();
UploadOpenstreetmapPointAsyncTask uploadTask = new UploadOpenstreetmapPointAsyncTask(
dialog, helper, plugin, remotepoi, remotebug, toUpload.length);
uploadTask.execute(toUpload);
dialog.show();
}
public static final class UploadingErrorDialogFragment extends DialogFragment {
private static final String ERROR_MESSAGE = "error_message";
private static final String POINT = "point";
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle argument = getArguments();
String errorMessage = argument.getString(ERROR_MESSAGE);
final OsmPoint point = (OsmPoint) argument.getSerializable(POINT);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(getResources().getString(R.string.failed_to_upload))
.setMessage(MessageFormat.format(
getResources().getString(R.string.error_message_pattern), errorMessage))
.setPositiveButton(R.string.shared_string_ok, null)
.setNeutralButton(getResources().getString(R.string.delete_change),
new DialogInterface.OnClickListener() {
public void onClick(@Nullable DialogInterface dialog, int id) {
OsmEditingPlugin plugin =
OsmandPlugin.getEnabledPlugin(OsmEditingPlugin.class);
if (point.getGroup() == OsmPoint.Group.BUG) {
plugin.getDBBug().deleteAllBugModifications(
(OsmNotesPoint) point);
} else if (point.getGroup() == OsmPoint.Group.POI) {
plugin.getDBPOI().deletePOI((OpenstreetmapPoint) point);
}
}
});
return builder.create();
}
public static UploadingErrorDialogFragment getInstance(String errorMessage,
OsmPoint point) {
UploadingErrorDialogFragment fragment = new UploadingErrorDialogFragment();
Bundle bundle = new Bundle();
bundle.putString(ERROR_MESSAGE, errorMessage);
bundle.putSerializable(POINT, point);
fragment.setArguments(bundle);
return fragment;
}
}
public static final class UploadingMultipleErrorDialogFragment extends DialogFragment {
private static final String HAS_ERROR = "has_error";
private static final String POINT_NAMES = "point_names";
OsmPoint[] points;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle arguments = getArguments();
String[] pointNames = arguments.getStringArray(POINT_NAMES);
boolean[] hasErrors = arguments.getBooleanArray(HAS_ERROR);
int successfulUploads = 0;
for (boolean hasError : hasErrors) {
if (!hasError) {
successfulUploads++;
}
}
PointsWithErrorsAdapter adapter =
PointsWithErrorsAdapter.createInstance(getActivity(), pointNames, hasErrors);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(MessageFormat.format(getResources()
.getString(R.string.successfully_uploaded_pattern),
successfulUploads, hasErrors.length))
.setAdapter(adapter, null)
.setPositiveButton(R.string.shared_string_ok, null)
.setNeutralButton(getResources().getString(R.string.try_again),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
OsmEditUploadListenerHelper
.showUploadItemsProgressDialog(
UploadingMultipleErrorDialogFragment.this,
points);
}
});
return builder.create();
}
public void setPointsToUpload(OsmPoint[] points) {
this.points = points;
}
public static UploadingMultipleErrorDialogFragment getInstance(String[] pointNames,
boolean[] hasError) {
if (pointNames.length != hasError.length) {
throw new IllegalArgumentException("pointNames and hasError arrays " +
"must me of equal length");
}
UploadingMultipleErrorDialogFragment fragment =
new UploadingMultipleErrorDialogFragment();
Bundle bundle = new Bundle();
bundle.putStringArray(POINT_NAMES, pointNames);
bundle.putBooleanArray(HAS_ERROR, hasError);
fragment.setArguments(bundle);
return fragment;
}
}
private static final class PointWithPotentialError {
String point;
boolean hasError;
public PointWithPotentialError(String point, boolean hasError) {
this.point = point;
this.hasError = hasError;
}
}
private static final class PointsWithErrorsAdapter extends ArrayAdapter<PointWithPotentialError> {
private final int layoutResourceId;
PointWithPotentialError[] data;
Activity context;
private PointsWithErrorsAdapter(Activity context, int layoutResourceId,
PointWithPotentialError[] objects) {
super(context, layoutResourceId, objects);
data = objects;
this.context = context;
this.layoutResourceId = layoutResourceId;
}
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
View row = convertView;
PointHolder holder = null;
if (row == null) {
LayoutInflater inflater = context.getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new PointHolder();
holder.checkedUncheckedImageView = (ImageView) row.findViewById(R.id.iconImageView);
holder.pointNameTextView = (TextView) row.findViewById(R.id.nameTextView);
row.setTag(holder);
} else {
holder = (PointHolder) row.getTag();
}
PointWithPotentialError pointWrapper = data[position];
holder.pointNameTextView.setText(pointWrapper.point);
IconsCache cache = ((OsmandApplication) context.getApplication()).getIconsCache();
holder.checkedUncheckedImageView.setImageDrawable(pointWrapper.hasError ?
cache.getContentIcon(R.drawable.ic_action_remove_dark) :
cache.getContentIcon(R.drawable.ic_action_done));
return row;
}
public static PointsWithErrorsAdapter createInstance(Activity activity,
String[] pointNames,
boolean[] hasError) {
PointWithPotentialError[] array = new PointWithPotentialError[pointNames.length];
for (int i = 0; i < pointNames.length; i++) {
array[i] = new PointWithPotentialError(pointNames[i], hasError[i]);
}
return new PointsWithErrorsAdapter(activity, R.layout.osm_edit_list_item, array);
}
private static class PointHolder {
TextView pointNameTextView;
ImageView checkedUncheckedImageView;
}
}
}

View file

@ -1,12 +1,29 @@
package net.osmand.plus.osmedit; package net.osmand.plus.osmedit;
import java.io.File; import android.app.AlertDialog;
import java.io.FileOutputStream; import android.app.ProgressDialog;
import java.io.IOException; import android.content.DialogInterface;
import java.text.MessageFormat; import android.content.Intent;
import java.util.ArrayList; import android.net.Uri;
import java.util.Iterator; import android.os.AsyncTask;
import java.util.List; import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.PopupMenu;
import android.util.Xml;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import net.osmand.access.AccessibleToast; import net.osmand.access.AccessibleToast;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
@ -25,37 +42,18 @@ import net.osmand.plus.myplaces.FavoritesActivity;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;
import android.app.AlertDialog; import java.io.File;
import android.app.ProgressDialog; import java.io.FileOutputStream;
import android.content.DialogInterface; import java.io.IOException;
import android.content.Intent; import java.util.ArrayList;
import android.net.Uri; import java.util.Iterator;
import android.os.AsyncTask; import java.util.List;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.PopupMenu;
import android.util.Xml;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
/** /**
* Created by Denis * Created by Denis
* on 06.03.2015. * on 06.03.2015.
*/ */
public class OsmEditsFragment extends OsmAndListFragment implements OsmEditsUploadListener { public class OsmEditsFragment extends OsmAndListFragment {
OsmEditingPlugin plugin; OsmEditingPlugin plugin;
private ArrayList<OsmPoint> dataPoints; private ArrayList<OsmPoint> dataPoints;
private OsmEditsAdapter listAdapter; private OsmEditsAdapter listAdapter;
@ -100,17 +98,17 @@ public class OsmEditsFragment extends OsmAndListFragment implements OsmEditsUplo
return view; return view;
} }
private void selectAll(){ private void selectAll() {
for(int i =0 ;i < listAdapter.getCount(); i++){ for (int i = 0; i < listAdapter.getCount(); i++) {
OsmPoint point = listAdapter.getItem(i); OsmPoint point = listAdapter.getItem(i);
if (!osmEditsSelected.contains(point)){ if (!osmEditsSelected.contains(point)) {
osmEditsSelected.add(point); osmEditsSelected.add(point);
} }
} }
listAdapter.notifyDataSetInvalidated(); listAdapter.notifyDataSetInvalidated();
} }
private void deselectAll(){ private void deselectAll() {
osmEditsSelected.clear(); osmEditsSelected.clear();
listAdapter.notifyDataSetInvalidated(); listAdapter.notifyDataSetInvalidated();
} }
@ -199,8 +197,8 @@ public class OsmEditsFragment extends OsmAndListFragment implements OsmEditsUplo
}); });
} }
private void enterSelectionMode(int type){ private void enterSelectionMode(int type) {
switch (type){ switch (type) {
case MODE_DELETE: case MODE_DELETE:
enterDeleteMode(); enterDeleteMode();
break; break;
@ -256,10 +254,10 @@ public class OsmEditsFragment extends OsmAndListFragment implements OsmEditsUplo
refreshSelectAll(); refreshSelectAll();
} }
private void updateSelectionTitle(ActionMode m){ private void updateSelectionTitle(ActionMode m) {
if(osmEditsSelected.size() > 0) { if (osmEditsSelected.size() > 0) {
m.setTitle(osmEditsSelected.size() + " " + getMyApplication().getString(R.string.shared_string_selected_lowercase)); m.setTitle(osmEditsSelected.size() + " " + getMyApplication().getString(R.string.shared_string_selected_lowercase));
} else{ } else {
m.setTitle(""); m.setTitle("");
} }
} }
@ -282,8 +280,8 @@ public class OsmEditsFragment extends OsmAndListFragment implements OsmEditsUplo
private void enableSelectionMode(boolean selectionMode) { private void enableSelectionMode(boolean selectionMode) {
this.selectionMode = selectionMode; this.selectionMode = selectionMode;
getView().findViewById(R.id.select_all).setVisibility(selectionMode? View.VISIBLE : View.GONE); getView().findViewById(R.id.select_all).setVisibility(selectionMode ? View.VISIBLE : View.GONE);
((FavoritesActivity)getActivity()).setToolbarVisibility(!selectionMode); ((FavoritesActivity) getActivity()).setToolbarVisibility(!selectionMode);
} }
public OsmandActionBarActivity getActionBarActivity() { public OsmandActionBarActivity getActionBarActivity() {
@ -389,7 +387,7 @@ public class OsmEditsFragment extends OsmAndListFragment implements OsmEditsUplo
final CheckBox ch = (CheckBox) v.findViewById(R.id.check_local_index); final CheckBox ch = (CheckBox) v.findViewById(R.id.check_local_index);
View options = v.findViewById(R.id.options); View options = v.findViewById(R.id.options);
if(selectionMode) { if (selectionMode) {
options.setVisibility(View.GONE); options.setVisibility(View.GONE);
ch.setVisibility(View.VISIBLE); ch.setVisibility(View.VISIBLE);
ch.setChecked(osmEditsSelected.contains(child)); ch.setChecked(osmEditsSelected.contains(child));
@ -482,7 +480,7 @@ public class OsmEditsFragment extends OsmAndListFragment implements OsmEditsUplo
return (OsmandApplication) getActivity().getApplication(); return (OsmandApplication) getActivity().getApplication();
} }
private void uploadItems(final OsmPoint[] items){ private void uploadItems(final OsmPoint[] items) {
AlertDialog.Builder b = new AlertDialog.Builder(getActivity()); AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
b.setMessage(getString(R.string.local_osm_changes_upload_all_confirm, items.length)); b.setMessage(getString(R.string.local_osm_changes_upload_all_confirm, items.length));
b.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { b.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@ -502,8 +500,10 @@ public class OsmEditsFragment extends OsmAndListFragment implements OsmEditsUplo
getString(R.string.uploading), getString(R.string.uploading),
getString(R.string.local_openstreetmap_uploading), getString(R.string.local_openstreetmap_uploading),
ProgressDialog.STYLE_HORIZONTAL).getDialog(); ProgressDialog.STYLE_HORIZONTAL).getDialog();
UploadOpenstreetmapPointAsyncTask uploadTask = new UploadOpenstreetmapPointAsyncTask(dialog, this, plugin, remotepoi, OsmEditsUploadListener listener = new OsmEditUploadListenerHelper(getActivity(),
remotebug, toUpload.length); getString(R.string.local_openstreetmap_were_uploaded));
UploadOpenstreetmapPointAsyncTask uploadTask = new UploadOpenstreetmapPointAsyncTask(
dialog, listener, plugin, remotepoi, remotebug, toUpload.length);
uploadTask.execute(toUpload); uploadTask.execute(toUpload);
dialog.show(); dialog.show();
@ -614,21 +614,6 @@ public class OsmEditsFragment extends OsmAndListFragment implements OsmEditsUplo
} }
} }
@Override
public void uploadUpdated(OsmPoint point) {
listAdapter.delete(point);
}
@Override
public void uploadEnded(Integer result) {
listAdapter.notifyDataSetChanged();
if (result != null) {
AccessibleToast.makeText(getActivity(),
MessageFormat.format(getString(R.string.local_openstreetmap_were_uploaded), result), Toast.LENGTH_LONG)
.show();
}
}
private void showOnMap(OsmPoint osmPoint) { private void showOnMap(OsmPoint osmPoint) {
boolean isOsmPoint = osmPoint instanceof OpenstreetmapPoint; boolean isOsmPoint = osmPoint instanceof OpenstreetmapPoint;
String type = osmPoint.getGroup() == OsmPoint.Group.POI ? PointDescription.POINT_TYPE_POI : PointDescription.POINT_TYPE_OSM_BUG; String type = osmPoint.getGroup() == OsmPoint.Group.POI ? PointDescription.POINT_TYPE_POI : PointDescription.POINT_TYPE_OSM_BUG;
@ -637,6 +622,4 @@ public class OsmEditsFragment extends OsmAndListFragment implements OsmEditsUplo
new PointDescription(type, name), true, osmPoint); //$NON-NLS-1$ new PointDescription(type, name), true, osmPoint); //$NON-NLS-1$
MapActivity.launchMapActivityMoveToTop(getActivity()); MapActivity.launchMapActivityMoveToTop(getActivity());
} }
} }

View file

@ -1,12 +1,12 @@
package net.osmand.plus.osmedit; package net.osmand.plus.osmedit;
import java.util.Map;
/** /**
* Created by Denis * Created by Denis
* on 11.03.2015. * on 11.03.2015.
*/ */
public interface OsmEditsUploadListener { public interface OsmEditsUploadListener {
void uploadUpdated(OsmPoint point);
public void uploadUpdated(OsmPoint point); void uploadEnded(Map<OsmPoint, String> loadErrorsMap);
public void uploadEnded(Integer result);
} }

View file

@ -1,8 +1,6 @@
package net.osmand.plus.osmedit; package net.osmand.plus.osmedit;
import java.io.Serializable; public class OsmNotesPoint extends OsmPoint {
public class OsmNotesPoint extends OsmPoint implements Serializable {
private static final long serialVersionUID = 729654300829771468L; private static final long serialVersionUID = 729654300829771468L;
private long id; private long id;

View file

@ -1,9 +1,10 @@
package net.osmand.plus.osmedit; package net.osmand.plus.osmedit;
import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public abstract class OsmPoint { public abstract class OsmPoint implements Serializable {
public static enum Group {BUG, POI}; public static enum Group {BUG, POI};

View file

@ -3,47 +3,44 @@ package net.osmand.plus.osmedit;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.support.v4.app.Fragment;
import net.osmand.osm.edit.EntityInfo; import net.osmand.osm.edit.EntityInfo;
import net.osmand.osm.edit.Node; import net.osmand.osm.edit.Node;
import java.util.HashMap;
import java.util.Map;
/** /**
* Created by Denis * Created by Denis
* on 11.03.2015. * on 11.03.2015.
*/ */
public class UploadOpenstreetmapPointAsyncTask extends AsyncTask<OsmPoint, OsmPoint, Integer> { public class UploadOpenstreetmapPointAsyncTask
extends AsyncTask<OsmPoint, OsmPoint, Map<OsmPoint, String>> {
private ProgressDialog progress; private ProgressDialog progress;
private OpenstreetmapRemoteUtil remotepoi; private OpenstreetmapRemoteUtil remotepoi;
private OsmBugsRemoteUtil remotebug; private OsmBugsRemoteUtil remotebug;
private int listSize = 0; private int listSize = 0;
private boolean interruptUploading = false; private boolean interruptUploading = false;
private OsmEditsUploadListener listener;
private Fragment ctx;
private OsmEditingPlugin plugin; private OsmEditingPlugin plugin;
public UploadOpenstreetmapPointAsyncTask(ProgressDialog progress,Fragment ctx, public UploadOpenstreetmapPointAsyncTask(ProgressDialog progress,
OsmEditingPlugin plugin, OsmEditsUploadListener listener,
OpenstreetmapRemoteUtil remotepoi, OsmBugsRemoteUtil remotebug, OsmEditingPlugin plugin,
OpenstreetmapRemoteUtil remotepoi,
OsmBugsRemoteUtil remotebug,
int listSize) { int listSize) {
this.progress = progress; this.progress = progress;
this.plugin = plugin; this.plugin = plugin;
this.remotepoi = remotepoi; this.remotepoi = remotepoi;
this.remotebug = remotebug; this.remotebug = remotebug;
this.listSize = listSize; this.listSize = listSize;
this.ctx = ctx; this.listener = listener;
} }
@Override @Override
protected Integer doInBackground(OsmPoint... points) { protected Map<OsmPoint, String> doInBackground(OsmPoint... points) {
int uploaded = 0; Map<OsmPoint, String> loadErrorsMap = new HashMap<>();
for (OsmPoint point : points) { for (OsmPoint point : points) {
if (interruptUploading) if (interruptUploading)
@ -57,31 +54,29 @@ public class UploadOpenstreetmapPointAsyncTask extends AsyncTask<OsmPoint, OsmPo
} }
Node n = remotepoi.commitNodeImpl(p.getAction(), p.getEntity(), entityInfo, p.getComment(), false); Node n = remotepoi.commitNodeImpl(p.getAction(), p.getEntity(), entityInfo, p.getComment(), false);
if (n != null) { if (n != null) {
plugin.getDBPOI().deletePOI(p); plugin.getDBPOI().deletePOI(p);
publishProgress(p); publishProgress(p);
uploaded++;
} }
loadErrorsMap.put(point, n != null ? null : "Unknown problem");
} else if (point.getGroup() == OsmPoint.Group.BUG) { } else if (point.getGroup() == OsmPoint.Group.BUG) {
OsmNotesPoint p = (OsmNotesPoint) point; OsmNotesPoint p = (OsmNotesPoint) point;
boolean success = false; String errorMessage = null;
if (p.getAction() == OsmPoint.Action.CREATE) { if (p.getAction() == OsmPoint.Action.CREATE) {
success = remotebug.createNewBug(p.getLatitude(), p.getLongitude(), p.getText(), p.getAuthor()) == null; errorMessage = remotebug.createNewBug(p.getLatitude(), p.getLongitude(), p.getText(), p.getAuthor());
} else if (p.getAction() == OsmPoint.Action.MODIFY) { } else if (p.getAction() == OsmPoint.Action.MODIFY) {
success = remotebug.addingComment(p.getId(), p.getText(), p.getAuthor()) == null; errorMessage = remotebug.addingComment(p.getId(), p.getText(), p.getAuthor());
} else if (p.getAction() == OsmPoint.Action.DELETE) { } else if (p.getAction() == OsmPoint.Action.DELETE) {
success = remotebug.closingBug(p.getId(), p.getText(), p.getAuthor()) == null; errorMessage = remotebug.closingBug(p.getId(), p.getText(), p.getAuthor());
} }
if (success) { if (errorMessage == null) {
plugin.getDBBug().deleteAllBugModifications(p); plugin.getDBBug().deleteAllBugModifications(p);
uploaded++;
publishProgress(p); publishProgress(p);
} }
loadErrorsMap.put(point, errorMessage);
} }
} }
return uploaded; return loadErrorsMap;
} }
@Override @Override
@ -100,11 +95,9 @@ public class UploadOpenstreetmapPointAsyncTask extends AsyncTask<OsmPoint, OsmPo
} }
@Override @Override
protected void onPostExecute(Integer result) { protected void onPostExecute(Map<OsmPoint, String> loadErrorsMap) {
progress.dismiss(); progress.dismiss();
if (ctx instanceof OsmEditsUploadListener){ listener.uploadEnded(loadErrorsMap);
((OsmEditsUploadListener)ctx).uploadEnded(result);
}
} }
public void setInterruptUploading(boolean b) { public void setInterruptUploading(boolean b) {
@ -113,10 +106,8 @@ public class UploadOpenstreetmapPointAsyncTask extends AsyncTask<OsmPoint, OsmPo
@Override @Override
protected void onProgressUpdate(OsmPoint... points) { protected void onProgressUpdate(OsmPoint... points) {
for(OsmPoint p : points) { for (OsmPoint p : points) {
if (ctx instanceof OsmEditsUploadListener){ listener.uploadUpdated(p);
((OsmEditsUploadListener)ctx).uploadUpdated(p);
}
progress.incrementProgressBy(1); progress.incrementProgressBy(1);
} }
} }