Download all button implementation

This commit is contained in:
nazar-kutz 2021-02-12 21:38:28 +02:00
parent 9f42fc48df
commit 357ab00ed6
17 changed files with 763 additions and 249 deletions

View file

@ -10,6 +10,7 @@ import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.QuadRect; import net.osmand.data.QuadRect;
import net.osmand.data.QuadTree; import net.osmand.data.QuadTree;
import net.osmand.map.WorldRegion.RegionBoundingBox;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapAlgorithms; import net.osmand.util.MapAlgorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
@ -436,6 +437,7 @@ public class OsmandRegions {
cx /= object.getPointsLength(); cx /= object.getPointsLength();
cy /= object.getPointsLength(); cy /= object.getPointsLength();
rd.regionCenter = new LatLon(MapUtils.get31LatitudeY((int) cy), MapUtils.get31LongitudeX((int) cx)); rd.regionCenter = new LatLon(MapUtils.get31LatitudeY((int) cy), MapUtils.get31LongitudeX((int) cx));
rd.boundingBox = findBoundingBox(object);
} }
rd.regionParentFullName = mapIndexFields.get(mapIndexFields.parentFullName, object); rd.regionParentFullName = mapIndexFields.get(mapIndexFields.parentFullName, object);
@ -461,6 +463,43 @@ public class OsmandRegions {
return rd; return rd;
} }
private RegionBoundingBox findBoundingBox(BinaryMapDataObject object) {
if (object.getPointsLength() == 0) {
return new RegionBoundingBox(0, 0, 0, 0);
}
double currentX = object.getPoint31XTile(0);
double currentY = object.getPoint31YTile(0);
double minX = currentX;
double maxX = currentX;
double minY = currentY;
double maxY = currentY;
if (object.getPointsLength() > 1) {
for (int i = 1; i < object.getPointsLength(); i++) {
currentX = object.getPoint31XTile(i);
currentY = object.getPoint31YTile(i);
if (currentX > maxX) {
maxX = currentX;
} else if (currentX < minX) {
minX = currentX;
}
if (currentY > maxY) {
maxY = currentY;
} else if (currentY < minY) {
minY = currentY;
}
}
}
minX = MapUtils.get31LongitudeX((int) minX);
maxX = MapUtils.get31LongitudeX((int) maxX);
double revertedMinY = MapUtils.get31LatitudeY((int) maxY);
double revertedMaxY = MapUtils.get31LatitudeY((int) minY);
return new RegionBoundingBox(minX, maxX, revertedMinY, revertedMaxY);
}
private String getSearchIndex(BinaryMapDataObject object) { private String getSearchIndex(BinaryMapDataObject object) {
MapIndex mi = object.getMapIndex(); MapIndex mi = object.getMapIndex();
TIntObjectIterator<String> it = object.getObjectNames().iterator(); TIntObjectIterator<String> it = object.getObjectNames().iterator();

View file

@ -40,6 +40,7 @@ public class WorldRegion implements Serializable {
protected String regionDownloadName; protected String regionDownloadName;
protected boolean regionMapDownload; protected boolean regionMapDownload;
protected LatLon regionCenter; protected LatLon regionCenter;
protected RegionBoundingBox boundingBox;
public static class RegionParams { public static class RegionParams {
protected String regionLeftHandDriving; protected String regionLeftHandDriving;
@ -182,4 +183,32 @@ public class WorldRegion implements Serializable {
} }
return res; return res;
} }
public static boolean isFirstRegionInsideTheSecond(WorldRegion first,
WorldRegion second) {
RegionBoundingBox bbox1 = first.boundingBox;
RegionBoundingBox bbox2 = second.boundingBox;
if ((bbox1.minX > bbox2.minX) && (bbox1.maxX < bbox2.maxX)) {
if ((bbox1.minY > bbox2.minY) && (bbox1.maxY < bbox2.maxY)) {
return true;
}
}
return false;
}
public static class RegionBoundingBox {
double minX;
double maxX;
double minY;
double maxY;
public RegionBoundingBox(double minX, double maxX, double minY, double maxY) {
this.minX = minX;
this.maxX = maxX;
this.minY = minY;
this.maxY = maxY;
}
}
} }

View file

@ -12,6 +12,8 @@
--> -->
<string name="delete_number_files_question">Delete %1$d files?</string>
<string name="shared_strings_all_regions">All regions</string>
<string name="activity_type_car_name">Car</string> <string name="activity_type_car_name">Car</string>
<string name="activity_type_motorbike_name">Motorbike</string> <string name="activity_type_motorbike_name">Motorbike</string>
<string name="activity_type_offroad_name">Off-road</string> <string name="activity_type_offroad_name">Off-road</string>

View file

@ -17,7 +17,7 @@ public class AbstractDownloadActivity extends ActionBarProgressActivity {
downloadValidationManager.startDownload(this, indexItem); downloadValidationManager.startDownload(this, indexItem);
} }
public void makeSureUserCancelDownload(IndexItem item) { public void makeSureUserCancelDownload(DownloadItem item) {
downloadValidationManager.makeSureUserCancelDownload(this, item); downloadValidationManager.makeSureUserCancelDownload(this, item);
} }
} }

View file

@ -56,7 +56,8 @@ public class CustomIndexItem extends IndexItem {
} }
@Override @Override
public File getTargetFile(OsmandApplication ctx) { @NonNull
public File getTargetFile(@NonNull OsmandApplication ctx) {
String basename = getTranslatedBasename(); String basename = getTranslatedBasename();
if (!Algorithms.isEmpty(subfolder)) { if (!Algorithms.isEmpty(subfolder)) {
basename = subfolder + "/" + basename; basename = subfolder + "/" + basename;

View file

@ -1,7 +1,6 @@
package net.osmand.plus.download; package net.osmand.plus.download;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;

View file

@ -18,6 +18,7 @@ import java.io.IOException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
@ -113,6 +114,10 @@ public class DownloadActivityType {
public static DownloadActivityType getIndexType(String tagName) { public static DownloadActivityType getIndexType(String tagName) {
return byTag.get(tagName); return byTag.get(tagName);
} }
public static Collection<DownloadActivityType> values() {
return byTag.values();
}
protected static String addVersionToExt(String ext, int version) { protected static String addVersionToExt(String ext, int version) {
return "_" + version + ext; return "_" + version + ext;
@ -318,7 +323,7 @@ public class DownloadActivityType {
} }
} }
public String getVisibleDescription(IndexItem indexItem, Context ctx) { public String getVisibleDescription(DownloadItem downloadItem, Context ctx) {
if (this == SRTM_COUNTRY_FILE) { if (this == SRTM_COUNTRY_FILE) {
return ctx.getString(R.string.download_srtm_maps); return ctx.getString(R.string.download_srtm_maps);
} else if (this == WIKIPEDIA_FILE) { } else if (this == WIKIPEDIA_FILE) {
@ -337,20 +342,20 @@ public class DownloadActivityType {
return ""; return "";
} }
public String getVisibleName(IndexItem indexItem, Context ctx, OsmandRegions osmandRegions, boolean includingParent) { public String getVisibleName(DownloadItem downloadItem, Context ctx, OsmandRegions osmandRegions, boolean includingParent) {
if (this == VOICE_FILE) { if (this == VOICE_FILE) {
String fileName = indexItem.fileName; String fileName = downloadItem.getFileName();
if (fileName.endsWith(IndexConstants.VOICE_INDEX_EXT_ZIP)) { if (fileName.endsWith(IndexConstants.VOICE_INDEX_EXT_ZIP)) {
return FileNameTranslationHelper.getVoiceName(ctx, getBasename(indexItem)); return FileNameTranslationHelper.getVoiceName(ctx, getBasename(downloadItem));
} else if (fileName.endsWith(IndexConstants.TTSVOICE_INDEX_EXT_JS)) { } else if (fileName.endsWith(IndexConstants.TTSVOICE_INDEX_EXT_JS)) {
return FileNameTranslationHelper.getVoiceName(ctx, getBasename(indexItem)); return FileNameTranslationHelper.getVoiceName(ctx, getBasename(downloadItem));
} }
return getBasename(indexItem); return getBasename(downloadItem);
} }
if (this == FONT_FILE) { if (this == FONT_FILE) {
return FileNameTranslationHelper.getFontName(ctx, getBasename(indexItem)); return FileNameTranslationHelper.getFontName(ctx, getBasename(downloadItem));
} }
final String basename = getBasename(indexItem); final String basename = getBasename(downloadItem);
if (basename.endsWith(FileNameTranslationHelper.WIKI_NAME)) { if (basename.endsWith(FileNameTranslationHelper.WIKI_NAME)) {
return FileNameTranslationHelper.getWikiName(ctx, basename); return FileNameTranslationHelper.getWikiName(ctx, basename);
} }
@ -442,8 +447,8 @@ public class DownloadActivityType {
} }
public String getBasename(IndexItem indexItem) { public String getBasename(DownloadItem downloadItem) {
String fileName = indexItem.fileName; String fileName = downloadItem.getFileName();
if (fileName.endsWith(IndexConstants.EXTRA_ZIP_EXT)) { if (fileName.endsWith(IndexConstants.EXTRA_ZIP_EXT)) {
return fileName.substring(0, fileName.length() - IndexConstants.EXTRA_ZIP_EXT.length()); return fileName.substring(0, fileName.length() - IndexConstants.EXTRA_ZIP_EXT.length());
} }
@ -458,7 +463,7 @@ public class DownloadActivityType {
if (fileName.endsWith(IndexConstants.SQLITE_EXT)) { if (fileName.endsWith(IndexConstants.SQLITE_EXT)) {
return fileName.substring(0, fileName.length() - IndexConstants.SQLITE_EXT.length()); return fileName.substring(0, fileName.length() - IndexConstants.SQLITE_EXT.length());
} }
if (indexItem.getType() == WIKIVOYAGE_FILE && if (downloadItem.getType() == WIKIVOYAGE_FILE &&
fileName.endsWith(IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT)) { fileName.endsWith(IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT)) {
return fileName.substring(0, fileName.length() - IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT.length()); return fileName.substring(0, fileName.length() - IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT.length());
} }

View file

@ -239,6 +239,16 @@ public class DownloadIndexesThread {
} }
} }
public void cancelDownload(DownloadItem item) {
if (item instanceof MultipleIndexItem) {
MultipleIndexItem multipleIndexItem = (MultipleIndexItem) item;
cancelDownload(multipleIndexItem.getAllIndexes());
} else if (item instanceof IndexItem) {
IndexItem indexItem = (IndexItem) item;
cancelDownload(indexItem);
}
}
public void cancelDownload(IndexItem item) { public void cancelDownload(IndexItem item) {
app.logMapDownloadEvent("cancel", item); app.logMapDownloadEvent("cancel", item);
if (currentDownloadingItem == item) { if (currentDownloadingItem == item) {

View file

@ -0,0 +1,76 @@
package net.osmand.plus.download;
import android.content.Context;
import androidx.annotation.NonNull;
import net.osmand.map.OsmandRegions;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import java.io.File;
import java.util.List;
import java.util.Locale;
public abstract class DownloadItem {
protected DownloadActivityType type;
protected DownloadResourceGroup relatedGroup;
public DownloadItem(DownloadActivityType type) {
this.type = type;
}
public DownloadActivityType getType() {
return type;
}
public void setRelatedGroup(DownloadResourceGroup relatedGroup) {
this.relatedGroup = relatedGroup;
}
public DownloadResourceGroup getRelatedGroup() {
return relatedGroup;
}
@NonNull
public String getSizeDescription(Context ctx) {
String pattern = ctx.getString(R.string.ltr_or_rtl_combine_via_space);
String size = String.format(Locale.US, "%.2f", getSizeToDownloadInMb());
return String.format(pattern, size, "MB");
}
public String getVisibleName(Context ctx, OsmandRegions osmandRegions) {
return type.getVisibleName(this, ctx, osmandRegions, true);
}
public String getVisibleName(Context ctx, OsmandRegions osmandRegions, boolean includingParent) {
return type.getVisibleName(this, ctx, osmandRegions, includingParent);
}
public String getVisibleDescription(OsmandApplication clctx) {
return type.getVisibleDescription(this, clctx);
}
public String getBasename() {
return type.getBasename(this);
}
protected abstract double getSizeToDownloadInMb();
public abstract double getArchiveSizeMB();
public abstract boolean isDownloaded();
public abstract boolean isOutdated();
public abstract boolean hasActualDataToDownload();
public abstract boolean isDownloading(DownloadIndexesThread thread);
public abstract String getFileName();
@NonNull
public abstract List<File> getDownloadedFiles(OsmandApplication app);
}

View file

@ -8,6 +8,7 @@ import net.osmand.map.OsmandRegions;
import net.osmand.map.WorldRegion; import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.util.Algorithms;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -20,8 +21,8 @@ public class DownloadResourceGroup {
private final DownloadResourceGroupType type; private final DownloadResourceGroupType type;
private final DownloadResourceGroup parentGroup; private final DownloadResourceGroup parentGroup;
// ASSERT: individualResources are not empty if and only if groups are empty // ASSERT: individualDisplayItems are not empty if and only if groups are empty
private final List<IndexItem> individualResources; private final List<DownloadItem> individualDownloadItems;
private final List<DownloadResourceGroup> groups; private final List<DownloadResourceGroup> groups;
protected final String id; protected final String id;
@ -107,10 +108,10 @@ public class DownloadResourceGroup {
public DownloadResourceGroup(DownloadResourceGroup parentGroup, DownloadResourceGroupType type, String id) { public DownloadResourceGroup(DownloadResourceGroup parentGroup, DownloadResourceGroupType type, String id) {
boolean flat = type.containsIndexItem(); boolean flat = type.containsIndexItem();
if (flat) { if (flat) {
this.individualResources = new ArrayList<IndexItem>(); this.individualDownloadItems = new ArrayList<DownloadItem>();
this.groups = null; this.groups = null;
} else { } else {
this.individualResources = null; this.individualDownloadItems = null;
this.groups = new ArrayList<DownloadResourceGroup>(); this.groups = new ArrayList<DownloadResourceGroup>();
} }
this.id = id; this.id = id;
@ -173,7 +174,7 @@ public class DownloadResourceGroup {
DownloadResourceGroup regionMaps = getSubGroupById(DownloadResourceGroupType.REGION_MAPS.getDefaultId()); DownloadResourceGroup regionMaps = getSubGroupById(DownloadResourceGroupType.REGION_MAPS.getDefaultId());
if(regionMaps != null && regionMaps.size() == 1 && parentGroup != null && parentGroup.getParentGroup() != null && if(regionMaps != null && regionMaps.size() == 1 && parentGroup != null && parentGroup.getParentGroup() != null &&
isEmpty(getSubGroupById(DownloadResourceGroupType.SUBREGIONS.getDefaultId()))) { isEmpty(getSubGroupById(DownloadResourceGroupType.SUBREGIONS.getDefaultId()))) {
IndexItem item = regionMaps.individualResources.get(0); IndexItem item = regionMaps.getIndividualResources().get(0);
DownloadResourceGroup screenParent = parentGroup.getParentGroup(); DownloadResourceGroup screenParent = parentGroup.getParentGroup();
if(item.getType() == DownloadActivityType.HILLSHADE_FILE) { if(item.getType() == DownloadActivityType.HILLSHADE_FILE) {
DownloadResourceGroup hillshades = DownloadResourceGroup hillshades =
@ -183,7 +184,7 @@ public class DownloadResourceGroup {
screenParent.addGroup(hillshades); screenParent.addGroup(hillshades);
} }
hillshades.addItem(item); hillshades.addItem(item);
regionMaps.individualResources.remove(0); regionMaps.individualDownloadItems.remove(0);
} else if (item.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) { } else if (item.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) {
DownloadResourceGroup hillshades = screenParent DownloadResourceGroup hillshades = screenParent
.getSubGroupById(DownloadResourceGroupType.SRTM_HEADER.getDefaultId()); .getSubGroupById(DownloadResourceGroupType.SRTM_HEADER.getDefaultId());
@ -192,7 +193,7 @@ public class DownloadResourceGroup {
screenParent.addGroup(hillshades); screenParent.addGroup(hillshades);
} }
hillshades.addItem(item); hillshades.addItem(item);
regionMaps.individualResources.remove(0); regionMaps.individualDownloadItems.remove(0);
} }
} }
@ -221,35 +222,38 @@ public class DownloadResourceGroup {
} }
} }
groups.add(g); groups.add(g);
if (g.individualResources != null) { sortDownloadItems(g.individualDownloadItems);
final net.osmand.Collator collator = OsmAndCollator.primaryCollator(); }
final OsmandApplication app = getRoot().app;
final OsmandRegions osmandRegions = app.getRegions();
Collections.sort(g.individualResources, new Comparator<IndexItem>() {
@Override
public int compare(IndexItem lhs, IndexItem rhs) {
int lli = lhs.getType().getOrderIndex();
int rri = rhs.getType().getOrderIndex();
if(lli < rri) {
return -1;
} else if(lli > rri) {
return 1;
}
return collator.compare(lhs.getVisibleName(app.getApplicationContext(), osmandRegions), protected void sortDownloadItems(List<DownloadItem> items) {
rhs.getVisibleName(app.getApplicationContext(), osmandRegions)); if (Algorithms.isEmpty(items)) return;
final net.osmand.Collator collator = OsmAndCollator.primaryCollator();
final OsmandApplication app = getRoot().app;
final OsmandRegions osmandRegions = app.getRegions();
Collections.sort(items, new Comparator<DownloadItem>() {
@Override
public int compare(DownloadItem firstItem, DownloadItem secondItem) {
int firstOrder = firstItem.getType().getOrderIndex();
int secondOrder = secondItem.getType().getOrderIndex();
if(firstOrder < secondOrder) {
return -1;
} else if(firstOrder > secondOrder) {
return 1;
} }
}); String firstName = firstItem.getVisibleName(app, osmandRegions);
} String secondName = secondItem.getVisibleName(app, osmandRegions);
return collator.compare(firstName, secondName);
}
});
} }
public void addItem(IndexItem i) { public void addItem(DownloadItem i) {
i.setRelatedGroup(this); i.setRelatedGroup(this);
individualResources.add(i); individualDownloadItems.add(i);
} }
public boolean isEmpty() { public boolean isEmpty() {
return isEmpty(individualResources) && isEmpty(groups); return isEmpty(individualDownloadItems) && isEmpty(groups);
} }
private boolean isEmpty(List<?> l) { private boolean isEmpty(List<?> l) {
@ -265,7 +269,7 @@ public class DownloadResourceGroup {
} }
public int size() { public int size() {
return groups != null ? groups.size() : individualResources.size(); return groups != null ? groups.size() : individualDownloadItems.size();
} }
public DownloadResourceGroup getGroupByIndex(int ind) { public DownloadResourceGroup getGroupByIndex(int ind) {
@ -275,9 +279,9 @@ public class DownloadResourceGroup {
return null; return null;
} }
public IndexItem getItemByIndex(int ind) { public DownloadItem getItemByIndex(int ind) {
if (individualResources != null && ind >= 0 && ind < individualResources.size()) { if (individualDownloadItems != null && ind >= 0 && ind < individualDownloadItems.size()) {
return individualResources.get(ind); return individualDownloadItems.get(ind);
} }
return null; return null;
} }
@ -306,8 +310,20 @@ public class DownloadResourceGroup {
} }
public List<IndexItem> getIndividualResources() { public List<IndexItem> getIndividualResources() {
List<IndexItem> individualResources = new ArrayList<>();
if (individualDownloadItems != null) {
for (DownloadItem item : individualDownloadItems) {
if (item instanceof IndexItem) {
individualResources.add((IndexItem) item);
}
}
}
return individualResources; return individualResources;
} }
public List<DownloadItem> getIndividualDownloadItems() {
return individualDownloadItems;
}
public WorldRegion getRegion() { public WorldRegion getRegion() {
return region; return region;

View file

@ -25,10 +25,14 @@ import java.io.InputStream;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import static net.osmand.plus.download.DownloadResourceGroup.DownloadResourceGroupType.REGION_MAPS;
public class DownloadResources extends DownloadResourceGroup { public class DownloadResources extends DownloadResourceGroup {
private static final String TAG = DownloadResources.class.getSimpleName(); private static final String TAG = DownloadResources.class.getSimpleName();
@ -40,7 +44,7 @@ public class DownloadResources extends DownloadResourceGroup {
private Map<String, String> indexFileNames = new LinkedHashMap<>(); private Map<String, String> indexFileNames = new LinkedHashMap<>();
private Map<String, String> indexActivatedFileNames = new LinkedHashMap<>(); private Map<String, String> indexActivatedFileNames = new LinkedHashMap<>();
private List<IndexItem> rawResources; private List<IndexItem> rawResources;
private Map<WorldRegion, List<IndexItem> > groupByRegion; private Map<WorldRegion, List<IndexItem>> groupByRegion;
private List<IndexItem> itemsToUpdate = new ArrayList<>(); private List<IndexItem> itemsToUpdate = new ArrayList<>();
public static final String WORLD_SEAMARKS_KEY = "world_seamarks"; public static final String WORLD_SEAMARKS_KEY = "world_seamarks";
public static final String WORLD_SEAMARKS_NAME = "World_seamarks"; public static final String WORLD_SEAMARKS_NAME = "World_seamarks";
@ -55,7 +59,7 @@ public class DownloadResources extends DownloadResourceGroup {
this.region = app.getRegions().getWorldRegion(); this.region = app.getRegions().getWorldRegion();
this.app = app; this.app = app;
} }
public List<IndexItem> getItemsToUpdate() { public List<IndexItem> getItemsToUpdate() {
return itemsToUpdate; return itemsToUpdate;
} }
@ -260,7 +264,7 @@ public class DownloadResources extends DownloadResourceGroup {
} }
private Map<String, String> listWithAlternatives(final java.text.DateFormat dateFormat, File file, private Map<String, String> listWithAlternatives(final java.text.DateFormat dateFormat, File file,
final String ext, final Map<String, String> files) { final String ext, final Map<String, String> files) {
if (file.isDirectory()) { if (file.isDirectory()) {
file.list(new FilenameFilter() { file.list(new FilenameFilter() {
@Override @Override
@ -292,7 +296,7 @@ public class DownloadResources extends DownloadResourceGroup {
} }
return file; return file;
} }
private void prepareFilesToUpdate() { private void prepareFilesToUpdate() {
List<IndexItem> filtered = rawResources; List<IndexItem> filtered = rawResources;
if (filtered != null) { if (filtered != null) {
@ -307,7 +311,7 @@ public class DownloadResources extends DownloadResourceGroup {
} }
} }
} }
protected boolean prepareData(List<IndexItem> resources) { protected boolean prepareData(List<IndexItem> resources) {
this.rawResources = resources; this.rawResources = resources;
@ -332,18 +336,18 @@ public class DownloadResources extends DownloadResourceGroup {
DownloadResourceGroup nauticalMapsGroup = new DownloadResourceGroup(this, DownloadResourceGroupType.NAUTICAL_MAPS_GROUP); DownloadResourceGroup nauticalMapsGroup = new DownloadResourceGroup(this, DownloadResourceGroupType.NAUTICAL_MAPS_GROUP);
DownloadResourceGroup nauticalMapsScreen = new DownloadResourceGroup(nauticalMapsGroup, DownloadResourceGroupType.NAUTICAL_MAPS); DownloadResourceGroup nauticalMapsScreen = new DownloadResourceGroup(nauticalMapsGroup, DownloadResourceGroupType.NAUTICAL_MAPS);
DownloadResourceGroup nauticalMaps = new DownloadResourceGroup(nauticalMapsGroup, DownloadResourceGroupType.NAUTICAL_MAPS_HEADER); DownloadResourceGroup nauticalMaps = new DownloadResourceGroup(nauticalMapsGroup, DownloadResourceGroupType.NAUTICAL_MAPS_HEADER);
DownloadResourceGroup wikivoyageMapsGroup = new DownloadResourceGroup(this, DownloadResourceGroupType.TRAVEL_GROUP); DownloadResourceGroup wikivoyageMapsGroup = new DownloadResourceGroup(this, DownloadResourceGroupType.TRAVEL_GROUP);
DownloadResourceGroup wikivoyageMapsScreen = new DownloadResourceGroup(wikivoyageMapsGroup, DownloadResourceGroupType.WIKIVOYAGE_MAPS); DownloadResourceGroup wikivoyageMapsScreen = new DownloadResourceGroup(wikivoyageMapsGroup, DownloadResourceGroupType.WIKIVOYAGE_MAPS);
DownloadResourceGroup wikivoyageMaps = new DownloadResourceGroup(wikivoyageMapsGroup, DownloadResourceGroupType.WIKIVOYAGE_HEADER); DownloadResourceGroup wikivoyageMaps = new DownloadResourceGroup(wikivoyageMapsGroup, DownloadResourceGroupType.WIKIVOYAGE_HEADER);
Map<WorldRegion, List<IndexItem> > groupByRegion = new LinkedHashMap<WorldRegion, List<IndexItem>>(); Map<WorldRegion, List<IndexItem>> groupByRegion = new LinkedHashMap<>();
OsmandRegions regs = app.getRegions(); OsmandRegions regs = app.getRegions();
for (IndexItem ii : resources) { for (IndexItem ii : resources) {
if (ii.getType() == DownloadActivityType.VOICE_FILE) { if (ii.getType() == DownloadActivityType.VOICE_FILE) {
if (ii.getFileName().endsWith(IndexConstants.TTSVOICE_INDEX_EXT_JS)){ if (ii.getFileName().endsWith(IndexConstants.TTSVOICE_INDEX_EXT_JS)) {
voiceTTS.addItem(ii); voiceTTS.addItem(ii);
} else if (ii.getFileName().endsWith(IndexConstants.VOICE_INDEX_EXT_ZIP)){ } else if (ii.getFileName().endsWith(IndexConstants.VOICE_INDEX_EXT_ZIP)) {
voiceRec.addItem(ii); voiceRec.addItem(ii);
} }
continue; continue;
@ -377,7 +381,7 @@ public class DownloadResources extends DownloadResourceGroup {
groupByRegion.get(wg).add(ii); groupByRegion.get(wg).add(ii);
} else { } else {
if (ii.getFileName().startsWith("World_")) { if (ii.getFileName().startsWith("World_")) {
if (ii.getFileName().toLowerCase().startsWith(WORLD_SEAMARKS_KEY) || if (ii.getFileName().toLowerCase().startsWith(WORLD_SEAMARKS_KEY) ||
ii.getFileName().toLowerCase().startsWith(WORLD_SEAMARKS_OLD_KEY)) { ii.getFileName().toLowerCase().startsWith(WORLD_SEAMARKS_OLD_KEY)) {
nauticalMaps.addItem(ii); nauticalMaps.addItem(ii);
} else { } else {
@ -402,22 +406,22 @@ public class DownloadResources extends DownloadResourceGroup {
LinkedList<DownloadResourceGroup> parent = new LinkedList<DownloadResourceGroup>(); LinkedList<DownloadResourceGroup> parent = new LinkedList<DownloadResourceGroup>();
DownloadResourceGroup worldSubregions = new DownloadResourceGroup(this, DownloadResourceGroupType.SUBREGIONS); DownloadResourceGroup worldSubregions = new DownloadResourceGroup(this, DownloadResourceGroupType.SUBREGIONS);
addGroup(worldSubregions); addGroup(worldSubregions);
for(WorldRegion rg : region.getSubregions()) { for (WorldRegion rg : region.getSubregions()) {
queue.add(rg); queue.add(rg);
parent.add(worldSubregions); parent.add(worldSubregions);
} }
while(!queue.isEmpty()) { while (!queue.isEmpty()) {
WorldRegion reg = queue.pollFirst(); WorldRegion reg = queue.pollFirst();
DownloadResourceGroup parentGroup = parent.pollFirst(); DownloadResourceGroup parentGroup = parent.pollFirst();
List<WorldRegion> subregions = reg.getSubregions(); List<WorldRegion> subregions = reg.getSubregions();
DownloadResourceGroup mainGrp = new DownloadResourceGroup(parentGroup, DownloadResourceGroupType.REGION, reg.getRegionId()); DownloadResourceGroup mainGrp = new DownloadResourceGroup(parentGroup, DownloadResourceGroupType.REGION, reg.getRegionId());
mainGrp.region = reg; mainGrp.region = reg;
parentGroup.addGroup(mainGrp); parentGroup.addGroup(mainGrp);
List<IndexItem> list = groupByRegion.get(reg); List<IndexItem> list = groupByRegion.get(reg);
if(list != null) { if (list != null) {
DownloadResourceGroup flatFiles = new DownloadResourceGroup(mainGrp, DownloadResourceGroupType.REGION_MAPS); DownloadResourceGroup flatFiles = new DownloadResourceGroup(mainGrp, REGION_MAPS);
for(IndexItem ii : list) { for (IndexItem ii : list) {
flatFiles.addItem(ii); flatFiles.addItem(ii);
} }
mainGrp.addGroup(flatFiles); mainGrp.addGroup(flatFiles);
@ -425,10 +429,10 @@ public class DownloadResources extends DownloadResourceGroup {
DownloadResourceGroup subRegions = new DownloadResourceGroup(mainGrp, DownloadResourceGroupType.SUBREGIONS); DownloadResourceGroup subRegions = new DownloadResourceGroup(mainGrp, DownloadResourceGroupType.SUBREGIONS);
mainGrp.addGroup(subRegions); mainGrp.addGroup(subRegions);
// add to processing queue // add to processing queue
for(WorldRegion rg : subregions) { for (WorldRegion rg : subregions) {
queue.add(rg); queue.add(rg);
parent.add(subRegions); parent.add(subRegions);
} }
} }
// Possible improvements // Possible improvements
// 1. if there is no subregions no need to create resource group REGIONS_MAPS - objection raise diversity and there is no value // 1. if there is no subregions no need to create resource group REGIONS_MAPS - objection raise diversity and there is no value
@ -455,8 +459,8 @@ public class DownloadResources extends DownloadResourceGroup {
} }
otherGroup.addGroup(voiceScreenTTS); otherGroup.addGroup(voiceScreenTTS);
otherGroup.addGroup(voiceScreenRec); otherGroup.addGroup(voiceScreenRec);
if (fonts.getIndividualResources() != null) { if (fonts.getIndividualResources() != null) {
otherGroup.addGroup(fontScreen); otherGroup.addGroup(fontScreen);
} }
@ -465,9 +469,87 @@ public class DownloadResources extends DownloadResourceGroup {
createHillshadeSRTMGroups(); createHillshadeSRTMGroups();
trimEmptyGroups(); trimEmptyGroups();
updateLoadedFiles(); updateLoadedFiles();
collectMultipleIndexesItems(region);
return true; return true;
} }
private void collectMultipleIndexesItems(@NonNull WorldRegion region) {
List<WorldRegion> subRegions = region.getSubregions();
if (Algorithms.isEmpty(subRegions)) return;
DownloadResourceGroup group = getRegionMapsGroup(region);
if (group != null) {
boolean listModified = false;
List<IndexItem> indexesList = group.getIndividualResources();
for (DownloadActivityType type : DownloadActivityType.values()) {
if (!doesListContainIndexWithType(indexesList, type)) {
List<IndexItem> indexesFromSubRegions = collectIndexesOfType(subRegions, type);
if (indexesFromSubRegions != null) {
group.addItem(new MultipleIndexItem(region, indexesFromSubRegions, type));
listModified = true;
}
}
}
if (listModified) {
sortDownloadItems(group.getIndividualDownloadItems());
}
}
for (WorldRegion subRegion : subRegions) {
collectMultipleIndexesItems(subRegion);
}
}
private DownloadResourceGroup getRegionMapsGroup(WorldRegion region) {
DownloadResourceGroup group = getRegionGroup(region);
if (group != null) {
return group.getSubGroupById(REGION_MAPS.getDefaultId());
}
return null;
}
@Nullable
private List<IndexItem> collectIndexesOfType(@NonNull List<WorldRegion> regions,
@NonNull DownloadActivityType type) {
Map<WorldRegion, IndexItem> collectedIndexes = new LinkedHashMap<>();
for (WorldRegion region : regions) {
List<IndexItem> regionIndexes = getIndexItems(region);
boolean found = false;
if (regionIndexes != null) {
for (IndexItem index : regionIndexes) {
if (index.getType() == type) {
found = true;
collectedIndexes.put(region, index);
break;
}
}
}
if (!found) return null;
}
return removeDuplicates(collectedIndexes);
}
private List<IndexItem> removeDuplicates(Map<WorldRegion, IndexItem> collectedIndexes) {
List<WorldRegion> regions = new ArrayList<>(collectedIndexes.keySet());
// collect duplicates
Set<WorldRegion> duplicates = new HashSet<>();
for (int i = 0; i < regions.size() - 1; i++) {
WorldRegion firstRegion = regions.get(i);
for (int j = i + 1; j < regions.size(); j++) {
WorldRegion secondRegion = regions.get(j);
if (WorldRegion.isFirstRegionInsideTheSecond(firstRegion, secondRegion)) {
duplicates.add(firstRegion);
} else if (WorldRegion.isFirstRegionInsideTheSecond(secondRegion, firstRegion)) {
duplicates.add(secondRegion);
}
}
}
// remove duplicates
for (WorldRegion key : duplicates) {
collectedIndexes.remove(key);
}
return new ArrayList<>(collectedIndexes.values());
}
private void buildRegionsGroups(WorldRegion region, DownloadResourceGroup group) { private void buildRegionsGroups(WorldRegion region, DownloadResourceGroup group) {
LinkedList<WorldRegion> queue = new LinkedList<WorldRegion>(); LinkedList<WorldRegion> queue = new LinkedList<WorldRegion>();
LinkedList<DownloadResourceGroup> parent = new LinkedList<DownloadResourceGroup>(); LinkedList<DownloadResourceGroup> parent = new LinkedList<DownloadResourceGroup>();
@ -485,7 +567,7 @@ public class DownloadResources extends DownloadResourceGroup {
CustomRegion customRegion = (CustomRegion) reg; CustomRegion customRegion = (CustomRegion) reg;
List<IndexItem> indexItems = customRegion.loadIndexItems(); List<IndexItem> indexItems = customRegion.loadIndexItems();
if (!Algorithms.isEmpty(indexItems)) { if (!Algorithms.isEmpty(indexItems)) {
DownloadResourceGroup flatFiles = new DownloadResourceGroup(mainGrp, DownloadResourceGroupType.REGION_MAPS); DownloadResourceGroup flatFiles = new DownloadResourceGroup(mainGrp, REGION_MAPS);
for (IndexItem ii : indexItems) { for (IndexItem ii : indexItems) {
flatFiles.addItem(ii); flatFiles.addItem(ii);
} }
@ -557,7 +639,11 @@ public class DownloadResources extends DownloadResourceGroup {
return res; return res;
} }
public static List<IndexItem> findIndexItemsAt(OsmandApplication app, List<String> names, DownloadActivityType type, boolean includeDownloaded, int limit) { public static List<IndexItem> findIndexItemsAt(OsmandApplication app,
List<String> names,
DownloadActivityType type,
boolean includeDownloaded,
int limit) {
List<IndexItem> res = new ArrayList<>(); List<IndexItem> res = new ArrayList<>();
OsmandRegions regions = app.getRegions(); OsmandRegions regions = app.getRegions();
DownloadIndexesThread downloadThread = app.getDownloadThread(); DownloadIndexesThread downloadThread = app.getDownloadThread();
@ -573,8 +659,12 @@ public class DownloadResources extends DownloadResourceGroup {
return res; return res;
} }
private static boolean isIndexItemDownloaded(DownloadIndexesThread downloadThread, DownloadActivityType type, WorldRegion downloadRegion, List<IndexItem> res) { private static boolean isIndexItemDownloaded(DownloadIndexesThread downloadThread,
List<IndexItem> otherIndexItems = new ArrayList<>(downloadThread.getIndexes().getIndexItems(downloadRegion)); DownloadActivityType type,
WorldRegion downloadRegion,
List<IndexItem> res) {
List<IndexItem> otherIndexItems =
new ArrayList<>(downloadThread.getIndexes().getIndexItems(downloadRegion));
for (IndexItem indexItem : otherIndexItems) { for (IndexItem indexItem : otherIndexItems) {
if (indexItem.getType() == type && indexItem.isDownloaded()) { if (indexItem.getType() == type && indexItem.isDownloaded()) {
return true; return true;
@ -584,8 +674,24 @@ public class DownloadResources extends DownloadResourceGroup {
&& isIndexItemDownloaded(downloadThread, type, downloadRegion.getSuperregion(), res); && isIndexItemDownloaded(downloadThread, type, downloadRegion.getSuperregion(), res);
} }
private static boolean addIndexItem(DownloadIndexesThread downloadThread, DownloadActivityType type, WorldRegion downloadRegion, List<IndexItem> res) { private boolean doesListContainIndexWithType(List<IndexItem> indexItems,
List<IndexItem> otherIndexItems = new ArrayList<>(downloadThread.getIndexes().getIndexItems(downloadRegion)); DownloadActivityType type) {
if (indexItems != null) {
for (IndexItem indexItem : indexItems) {
if (indexItem.getType() == type) {
return true;
}
}
}
return false;
}
private static boolean addIndexItem(DownloadIndexesThread downloadThread,
DownloadActivityType type,
WorldRegion downloadRegion,
List<IndexItem> res) {
List<IndexItem> otherIndexItems =
new ArrayList<>(downloadThread.getIndexes().getIndexItems(downloadRegion));
for (IndexItem indexItem : otherIndexItems) { for (IndexItem indexItem : otherIndexItems) {
if (indexItem.getType() == type if (indexItem.getType() == type
&& !res.contains(indexItem)) { && !res.contains(indexItem)) {

View file

@ -192,7 +192,7 @@ public class DownloadValidationManager {
} }
public void makeSureUserCancelDownload(FragmentActivity ctx, final IndexItem item) { public void makeSureUserCancelDownload(FragmentActivity ctx, final DownloadItem item) {
AlertDialog.Builder bld = new AlertDialog.Builder(ctx); AlertDialog.Builder bld = new AlertDialog.Builder(ctx);
bld.setTitle(ctx.getString(R.string.shared_string_cancel)); bld.setTitle(ctx.getString(R.string.shared_string_cancel));
bld.setMessage(R.string.confirm_interrupt_download); bld.setMessage(R.string.confirm_interrupt_download);

View file

@ -1,12 +1,9 @@
package net.osmand.plus.download; package net.osmand.plus.download;
import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.map.OsmandRegions;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.helpers.FileNameTranslationHelper; import net.osmand.plus.helpers.FileNameTranslationHelper;
@ -16,9 +13,11 @@ import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List;
public class IndexItem implements Comparable<IndexItem> { public class IndexItem extends DownloadItem implements Comparable<IndexItem> {
private static final Log log = PlatformUtil.getLog(IndexItem.class); private static final Log log = PlatformUtil.getLog(IndexItem.class);
String description; String description;
@ -27,43 +26,44 @@ public class IndexItem implements Comparable<IndexItem> {
long timestamp; long timestamp;
long contentSize; long contentSize;
long containerSize; long containerSize;
DownloadActivityType type;
boolean extra; boolean extra;
// Update information // Update information
boolean outdated; boolean outdated;
boolean downloaded; boolean downloaded;
long localTimestamp; long localTimestamp;
DownloadResourceGroup relatedGroup;
public IndexItem(String fileName,
public IndexItem(String fileName, String description, long timestamp, String size, long contentSize, String description,
long containerSize, @NonNull DownloadActivityType tp) { long timestamp,
String size,
long contentSize,
long containerSize,
@NonNull DownloadActivityType type) {
super(type);
this.fileName = fileName; this.fileName = fileName;
this.description = description; this.description = description;
this.timestamp = timestamp; this.timestamp = timestamp;
this.size = size; this.size = size;
this.contentSize = contentSize; this.contentSize = contentSize;
this.containerSize = containerSize; this.containerSize = containerSize;
this.type = tp;
}
public DownloadActivityType getType() {
return type;
}
public void setRelatedGroup(DownloadResourceGroup relatedGroup) {
this.relatedGroup = relatedGroup;
}
public DownloadResourceGroup getRelatedGroup() {
return relatedGroup;
} }
@Override
public String getFileName() { public String getFileName() {
return fileName; return fileName;
} }
@NonNull
@Override
public List<File> getDownloadedFiles(OsmandApplication app) {
File targetFile = getTargetFile(app);
List<File> result = new ArrayList<>();
if (targetFile.exists()) {
result.add(targetFile);
}
return result;
}
public String getDescription() { public String getDescription() {
return description; return description;
@ -89,10 +89,14 @@ public class IndexItem implements Comparable<IndexItem> {
return ((double)containerSize) / (1 << 20); return ((double)containerSize) / (1 << 20);
} }
public String getSizeDescription(Context ctx) { @Override
return ctx.getString(R.string.ltr_or_rtl_combine_via_space, size, "MB"); protected double getSizeToDownloadInMb() {
try {
return Double.parseDouble(size);
} catch (Exception e) {
return 0;
}
} }
public DownloadEntry createDownloadEntry(OsmandApplication ctx) { public DownloadEntry createDownloadEntry(OsmandApplication ctx) {
String fileName = this.fileName; String fileName = this.fileName;
@ -132,11 +136,8 @@ public class IndexItem implements Comparable<IndexItem> {
return type.getTargetFileName(this); return type.getTargetFileName(this);
} }
public String getBasename() { @NonNull
return type.getBasename(this); public File getTargetFile(@NonNull OsmandApplication ctx) {
}
public File getTargetFile(OsmandApplication ctx) {
String basename = getTranslatedBasename(); String basename = getTranslatedBasename();
return new File(type.getDownloadFolder(ctx, this), basename + type.getUnzipExtension(ctx, this)); return new File(type.getDownloadFolder(ctx, this), basename + type.getUnzipExtension(ctx, this));
} }
@ -190,7 +191,7 @@ public class IndexItem implements Comparable<IndexItem> {
&& getType() != DownloadActivityType.HILLSHADE_FILE && getType() != DownloadActivityType.HILLSHADE_FILE
&& getType() != DownloadActivityType.SLOPE_FILE; && getType() != DownloadActivityType.SLOPE_FILE;
} }
public void setOutdated(boolean outdated) { public void setOutdated(boolean outdated) {
this.outdated = outdated; this.outdated = outdated;
} }
@ -198,7 +199,12 @@ public class IndexItem implements Comparable<IndexItem> {
public void setDownloaded(boolean downloaded) { public void setDownloaded(boolean downloaded) {
this.downloaded = downloaded; this.downloaded = downloaded;
} }
@Override
public boolean hasActualDataToDownload() {
return !isDownloaded() || isOutdated();
}
public void setLocalTimestamp(long localTimestamp) { public void setLocalTimestamp(long localTimestamp) {
this.localTimestamp = localTimestamp; this.localTimestamp = localTimestamp;
} }
@ -211,20 +217,11 @@ public class IndexItem implements Comparable<IndexItem> {
return downloaded; return downloaded;
} }
public String getVisibleName(Context ctx, OsmandRegions osmandRegions) { @Override
return type.getVisibleName(this, ctx, osmandRegions, true); public boolean isDownloading(DownloadIndexesThread thread) {
return thread.isDownloading(this);
} }
public String getVisibleName(Context ctx, OsmandRegions osmandRegions, boolean includingParent) {
return type.getVisibleName(this, ctx, osmandRegions, includingParent);
}
public String getVisibleDescription(OsmandApplication clctx) {
return type.getVisibleDescription(this, clctx);
}
public String getDate(java.text.DateFormat format) { public String getDate(java.text.DateFormat format) {
return format.format(new Date(timestamp)); return format.format(new Date(timestamp));
} }

View file

@ -0,0 +1,122 @@
package net.osmand.plus.download;
import androidx.annotation.NonNull;
import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class MultipleIndexItem extends DownloadItem {
private final List<IndexItem> items;
public MultipleIndexItem(@NonNull WorldRegion region,
@NonNull List<IndexItem> items,
@NonNull DownloadActivityType type) {
super(type);
this.items = items;
}
public List<IndexItem> getAllIndexes() {
return items;
}
@Override
public boolean isOutdated() {
for (IndexItem item : items) {
if (item.isOutdated()) {
return true;
}
}
return false;
}
@Override
public boolean isDownloaded() {
for (IndexItem item : items) {
if (item.isDownloaded()) {
return true;
}
}
return false;
}
@Override
public boolean isDownloading(DownloadIndexesThread thread) {
for (IndexItem item : items) {
if (thread.isDownloading(item)) {
return true;
}
}
return false;
}
@Override
public String getFileName() {
// The file name is used in many places.
// But in the case of a Multiple Indexes element it's not use in most cases.
// File is not created for Multiple Indexes element,
// and all file names are available in internal IndexItem elements.
// The only one place where a filename may be needed
// is to generate the base and display names.
// Since these names are generated based on the filename.
// But now we don't need a name for display,
// because on all screens where we now use multiple elements item,
// for display used a type name instead of a file name.
// Later, if you need a file name,
// you can try to create it based on the WorldRegion
// and file name of one of the internal IndexItem elements.
return "";
}
@NonNull
@Override
public List<File> getDownloadedFiles(OsmandApplication app) {
List<File> result = new ArrayList<>();
for (IndexItem item : items) {
result.addAll(item.getDownloadedFiles(app));
}
return result;
}
public List<IndexItem> getIndexesToDownload() {
List<IndexItem> indexesToDownload = new ArrayList<>();
for (IndexItem item : items) {
if (item.hasActualDataToDownload()) {
indexesToDownload.add(item);
}
}
return indexesToDownload;
}
@Override
public boolean hasActualDataToDownload() {
return getIndexesToDownload().size() > 0;
}
@Override
public double getSizeToDownloadInMb() {
double totalSizeMb = 0.0d;
for (IndexItem item : items) {
if (item.hasActualDataToDownload()) {
totalSizeMb += Double.parseDouble(item.size);
}
}
return totalSizeMb;
}
@Override
public double getArchiveSizeMB() {
double result = 0.0d;
for (IndexItem item : items) {
result += item.getArchiveSizeMB();
}
return result;
}
}

View file

@ -10,9 +10,9 @@ import android.widget.TextView;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
import net.osmand.plus.download.CustomIndexItem; import net.osmand.plus.download.CustomIndexItem;
import net.osmand.plus.download.DownloadItem;
import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadResourceGroup; import net.osmand.plus.download.DownloadResourceGroup;
import net.osmand.plus.download.IndexItem;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -52,9 +52,9 @@ public class DownloadResourceGroupAdapter extends OsmandBaseExpandableListAdapte
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild,
View convertView, ViewGroup parent) { View convertView, ViewGroup parent) {
final Object child = getChild(groupPosition, childPosition); final Object child = getChild(groupPosition, childPosition);
if (child instanceof IndexItem) { if (child instanceof DownloadItem) {
IndexItem item = (IndexItem) child; DownloadItem item = (DownloadItem) child;
DownloadResourceGroup group = getGroupObj(groupPosition); DownloadResourceGroup group = getGroupObj(groupPosition);
ItemViewHolder viewHolder; ItemViewHolder viewHolder;
if (convertView != null && convertView.getTag() instanceof ItemViewHolder) { if (convertView != null && convertView.getTag() instanceof ItemViewHolder) {

View file

@ -17,11 +17,14 @@ import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu; import androidx.appcompat.widget.PopupMenu;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import net.osmand.map.OsmandRegions;
import net.osmand.map.WorldRegion; import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.activities.LocalIndexHelper.LocalIndexType; import net.osmand.plus.activities.LocalIndexHelper.LocalIndexType;
@ -31,11 +34,13 @@ import net.osmand.plus.activities.PluginsFragment;
import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; import net.osmand.plus.chooseplan.ChoosePlanDialogFragment;
import net.osmand.plus.download.CityItem; import net.osmand.plus.download.CityItem;
import net.osmand.plus.download.CustomIndexItem; import net.osmand.plus.download.CustomIndexItem;
import net.osmand.plus.download.DownloadItem;
import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadActivityType; import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.DownloadResourceGroup; import net.osmand.plus.download.DownloadResourceGroup;
import net.osmand.plus.download.DownloadResources; import net.osmand.plus.download.DownloadResources;
import net.osmand.plus.download.IndexItem; import net.osmand.plus.download.IndexItem;
import net.osmand.plus.download.MultipleIndexItem;
import net.osmand.plus.download.ui.LocalIndexesFragment.LocalIndexOperationTask; import net.osmand.plus.download.ui.LocalIndexesFragment.LocalIndexOperationTask;
import net.osmand.plus.helpers.FileNameTranslationHelper; import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
@ -43,6 +48,8 @@ import net.osmand.util.Algorithms;
import java.io.File; import java.io.File;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
public class ItemViewHolder { public class ItemViewHolder {
@ -137,24 +144,24 @@ public class ItemViewHolder {
depthContoursPurchased = InAppPurchaseHelper.isDepthContoursPurchased(context.getMyApplication()); depthContoursPurchased = InAppPurchaseHelper.isDepthContoursPurchased(context.getMyApplication());
} }
public void bindIndexItem(final IndexItem indexItem) { public void bindIndexItem(final DownloadItem downloadItem) {
bindIndexItem(indexItem, null); bindIndexItem(downloadItem, null);
} }
public void bindIndexItem(final IndexItem indexItem, final String cityName) { public void bindIndexItem(final DownloadItem downloadItem, final String cityName) {
initAppStatusVariables(); initAppStatusVariables();
boolean isDownloading = context.getDownloadThread().isDownloading(indexItem); boolean isDownloading = downloadItem.isDownloading(context.getDownloadThread());
int progress = -1; int progress = -1;
if (context.getDownloadThread().getCurrentDownloadingItem() == indexItem) { if (context.getDownloadThread().getCurrentDownloadingItem() == downloadItem) {
progress = context.getDownloadThread().getCurrentDownloadingItemProgress(); progress = context.getDownloadThread().getCurrentDownloadingItemProgress();
} }
boolean disabled = checkDisabledAndClickAction(indexItem); boolean disabled = checkDisabledAndClickAction(downloadItem);
/// name and left item /// name and left item
String name; String name;
if(showTypeInName) { if(showTypeInName) {
name = indexItem.getType().getString(context); name = downloadItem.getType().getString(context);
} else { } else {
name = indexItem.getVisibleName(context, context.getMyApplication().getRegions(), showParentRegionName); name = downloadItem.getVisibleName(context, context.getMyApplication().getRegions(), showParentRegionName);
} }
String text = (!Algorithms.isEmpty(cityName) && !cityName.equals(name) ? cityName + "\n" : "") + name; String text = (!Algorithms.isEmpty(cityName) && !cityName.equals(name) ? cityName + "\n" : "") + name;
nameTextView.setText(text); nameTextView.setText(text);
@ -164,43 +171,78 @@ public class ItemViewHolder {
nameTextView.setTextColor(textColorSecondary); nameTextView.setTextColor(textColorSecondary);
} }
int color = textColorSecondary; int color = textColorSecondary;
if(indexItem.isDownloaded() && !isDownloading) { if(downloadItem.isDownloaded() && !isDownloading) {
int colorId = indexItem.isOutdated() ? R.color.color_distance : R.color.color_ok; int colorId = downloadItem.isOutdated() ? R.color.color_distance : R.color.color_ok;
color = context.getResources().getColor(colorId); color = context.getResources().getColor(colorId);
} }
if (indexItem.isDownloaded()) { if (downloadItem.isDownloaded()) {
leftImageView.setImageDrawable(getContentIcon(context, leftImageView.setImageDrawable(getContentIcon(context,
indexItem.getType().getIconResource(), color)); downloadItem.getType().getIconResource(), color));
} else if (disabled) { } else if (disabled) {
leftImageView.setImageDrawable(getContentIcon(context, leftImageView.setImageDrawable(getContentIcon(context,
indexItem.getType().getIconResource(), textColorSecondary)); downloadItem.getType().getIconResource(), textColorSecondary));
} else { } else {
leftImageView.setImageDrawable(getContentIcon(context, leftImageView.setImageDrawable(getContentIcon(context,
indexItem.getType().getIconResource())); downloadItem.getType().getIconResource()));
} }
descrTextView.setTextColor(textColorSecondary); descrTextView.setTextColor(textColorSecondary);
if (!isDownloading) { if (!isDownloading) {
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
descrTextView.setVisibility(View.VISIBLE); descrTextView.setVisibility(View.VISIBLE);
if (indexItem instanceof CustomIndexItem && (((CustomIndexItem) indexItem).getSubName(context) != null)) { if (downloadItem instanceof CustomIndexItem && (((CustomIndexItem) downloadItem).getSubName(context) != null)) {
descrTextView.setText(((CustomIndexItem) indexItem).getSubName(context)); descrTextView.setText(((CustomIndexItem) downloadItem).getSubName(context));
} else if (indexItem.getType() == DownloadActivityType.DEPTH_CONTOUR_FILE && !depthContoursPurchased) { } else if (downloadItem.getType() == DownloadActivityType.DEPTH_CONTOUR_FILE && !depthContoursPurchased) {
descrTextView.setText(context.getString(R.string.depth_contour_descr)); descrTextView.setText(context.getString(R.string.depth_contour_descr));
} else if ((indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE } else if ((downloadItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE
|| indexItem.getType() == DownloadActivityType.HILLSHADE_FILE || downloadItem.getType() == DownloadActivityType.HILLSHADE_FILE
|| indexItem.getType() == DownloadActivityType.SLOPE_FILE) && srtmDisabled) { || downloadItem.getType() == DownloadActivityType.SLOPE_FILE) && srtmDisabled) {
if (showTypeInName) { if (showTypeInName) {
descrTextView.setText(""); descrTextView.setText("");
} else { } else {
descrTextView.setText(indexItem.getType().getString(context)); descrTextView.setText(downloadItem.getType().getString(context));
} }
} else if (showTypeInDesc) { } else if (downloadItem instanceof MultipleIndexItem) {
descrTextView.setText(indexItem.getType().getString(context) + MultipleIndexItem item = (MultipleIndexItem) downloadItem;
"" + indexItem.getSizeDescription(context) + String allRegionsHeader = context.getString(R.string.shared_strings_all_regions);
"" + (showRemoteDate ? indexItem.getRemoteDate(dateFormat) : indexItem.getLocalDate(dateFormat))); String regionsHeader = context.getString(R.string.regions);
String allRegionsCount = String.valueOf(item.getAllIndexes().size());
String leftToDownloadCount = String.valueOf(item.getIndexesToDownload().size());
String header;
String count;
if (item.hasActualDataToDownload()) {
if (!item.isDownloaded()) {
header = allRegionsHeader;
count = leftToDownloadCount;
} else {
header = regionsHeader;
count = String.format(
context.getString(R.string.ltr_or_rtl_combine_via_slash),
leftToDownloadCount,
allRegionsCount);
}
} else {
header = allRegionsHeader;
count = allRegionsCount;
}
String fullDescription =
context.getString(R.string.ltr_or_rtl_combine_via_colon, header, count);
if (item.hasActualDataToDownload()) {
fullDescription = context.getString(
R.string.ltr_or_rtl_combine_via_bold_point, fullDescription,
item.getSizeDescription(context));
}
descrTextView.setText(fullDescription);
} else { } else {
descrTextView.setText(indexItem.getSizeDescription(context) + "" + IndexItem item = (IndexItem) downloadItem;
(showRemoteDate ? indexItem.getRemoteDate(dateFormat) : indexItem.getLocalDate(dateFormat))); String pattern = context.getString(R.string.ltr_or_rtl_combine_via_bold_point);
String type = item.getType().getString(context);
String size = item.getSizeDescription(context);
String date = showRemoteDate ? item.getRemoteDate(dateFormat) : item.getLocalDate(dateFormat);
String fullDescription = String.format(pattern, size, date);
if (showTypeInDesc) {
fullDescription = String.format(pattern, type, fullDescription);
}
descrTextView.setText(fullDescription);
} }
} else { } else {
@ -209,18 +251,19 @@ public class ItemViewHolder {
progressBar.setProgress(progress); progressBar.setProgress(progress);
if (showProgressInDesc) { if (showProgressInDesc) {
double mb = indexItem.getArchiveSizeMB(); double mb = downloadItem.getArchiveSizeMB();
String v ; String v ;
if (progress != -1) { if (progress != -1) {
v = context.getString(R.string.value_downloaded_of_max, mb * progress / 100, mb); v = context.getString(R.string.value_downloaded_of_max, mb * progress / 100, mb);
} else { } else {
v = context.getString(R.string.file_size_in_mb, mb); v = context.getString(R.string.file_size_in_mb, mb);
} }
if(showTypeInDesc && indexItem.getType() == DownloadActivityType.ROADS_FILE) { String fullDescription = v;
descrTextView.setText(indexItem.getType().getString(context) + "" + v); if(showTypeInDesc && downloadItem.getType() == DownloadActivityType.ROADS_FILE) {
} else { fullDescription = context.getString(R.string.ltr_or_rtl_combine_via_bold_point,
descrTextView.setText(v); downloadItem.getType().getString(context), fullDescription);
} }
descrTextView.setText(fullDescription);
descrTextView.setVisibility(View.VISIBLE); descrTextView.setVisibility(View.VISIBLE);
} else { } else {
descrTextView.setVisibility(View.GONE); descrTextView.setVisibility(View.GONE);
@ -241,44 +284,7 @@ public class ItemViewHolder {
} }
} }
protected void download(IndexItem indexItem, DownloadResourceGroup parentOptional) { private boolean checkDisabledAndClickAction(final DownloadItem item) {
boolean handled = false;
if(parentOptional != null) {
WorldRegion region = DownloadResourceGroup.getRegion(parentOptional);
context.setDownloadItem(region, indexItem.getTargetFile(context.getMyApplication()).getAbsolutePath());
}
if (indexItem.getType() == DownloadActivityType.ROADS_FILE && parentOptional != null) {
for (IndexItem ii : parentOptional.getIndividualResources()) {
if (ii.getType() == DownloadActivityType.NORMAL_FILE) {
if (ii.isDownloaded()) {
handled = true;
confirmDownload(indexItem);
}
break;
}
}
}
if(!handled) {
context.startDownload(indexItem);
}
}
private void confirmDownload(final IndexItem indexItem) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.are_you_sure);
builder.setMessage(R.string.confirm_download_roadmaps);
builder.setNegativeButton(R.string.shared_string_cancel, null).setPositiveButton(
R.string.shared_string_download, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (indexItem != null) {
context.startDownload(indexItem);
}
}
});
builder.show();
}
private boolean checkDisabledAndClickAction(final IndexItem item) {
RightButtonAction clickAction = getClickAction(item); RightButtonAction clickAction = getClickAction(item);
boolean disabled = clickAction != RightButtonAction.DOWNLOAD; boolean disabled = clickAction != RightButtonAction.DOWNLOAD;
OnClickListener action = getRightButtonAction(item, clickAction); OnClickListener action = getRightButtonAction(item, clickAction);
@ -290,15 +296,15 @@ public class ItemViewHolder {
} else { } else {
rightButton.setVisibility(View.GONE); rightButton.setVisibility(View.GONE);
rightImageButton.setVisibility(View.VISIBLE); rightImageButton.setVisibility(View.VISIBLE);
final boolean isDownloading = context.getDownloadThread().isDownloading(item); final boolean isDownloading = item.isDownloading(context.getDownloadThread());
if (isDownloading) { if (isDownloading) {
rightImageButton.setImageDrawable(getContentIcon(context, R.drawable.ic_action_remove_dark)); rightImageButton.setImageDrawable(getContentIcon(context, R.drawable.ic_action_remove_dark));
rightImageButton.setContentDescription(context.getString(R.string.shared_string_cancel)); rightImageButton.setContentDescription(context.getString(R.string.shared_string_cancel));
} else if(item.isDownloaded() && !item.isOutdated()) { } else if(!item.hasActualDataToDownload()) {
rightImageButton.setImageDrawable(getContentIcon(context, R.drawable.ic_overflow_menu_white)); rightImageButton.setImageDrawable(getContentIcon(context, R.drawable.ic_overflow_menu_white));
rightImageButton.setContentDescription(context.getString(R.string.shared_string_more)); rightImageButton.setContentDescription(context.getString(R.string.shared_string_more));
} else { } else {
rightImageButton.setImageDrawable(getContentIcon(context, R.drawable.ic_action_import)); rightImageButton.setImageDrawable(getContentIcon(context, getDownloadActionIconId(item)));
rightImageButton.setContentDescription(context.getString(R.string.shared_string_download)); rightImageButton.setContentDescription(context.getString(R.string.shared_string_download));
} }
rightImageButton.setOnClickListener(action); rightImageButton.setOnClickListener(action);
@ -307,31 +313,37 @@ public class ItemViewHolder {
return disabled; return disabled;
} }
private int getDownloadActionIconId(@NonNull DownloadItem item) {
return item instanceof MultipleIndexItem ?
R.drawable.ic_action_multi_download :
R.drawable.ic_action_import;
}
@SuppressLint("DefaultLocale") @SuppressLint("DefaultLocale")
public RightButtonAction getClickAction(final IndexItem indexItem) { public RightButtonAction getClickAction(final DownloadItem item) {
RightButtonAction clickAction = RightButtonAction.DOWNLOAD; RightButtonAction clickAction = RightButtonAction.DOWNLOAD;
if (indexItem.getBasename().toLowerCase().equals(DownloadResources.WORLD_SEAMARKS_KEY) if (item.getBasename().toLowerCase().equals(DownloadResources.WORLD_SEAMARKS_KEY)
&& nauticalPluginDisabled) { && nauticalPluginDisabled) {
clickAction = RightButtonAction.ASK_FOR_SEAMARKS_PLUGIN; clickAction = RightButtonAction.ASK_FOR_SEAMARKS_PLUGIN;
} else if ((indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE } else if ((item.getType() == DownloadActivityType.SRTM_COUNTRY_FILE
|| indexItem.getType() == DownloadActivityType.HILLSHADE_FILE || item.getType() == DownloadActivityType.HILLSHADE_FILE
|| indexItem.getType() == DownloadActivityType.SLOPE_FILE) && srtmDisabled) { || item.getType() == DownloadActivityType.SLOPE_FILE) && srtmDisabled) {
if (srtmNeedsInstallation) { if (srtmNeedsInstallation) {
clickAction = RightButtonAction.ASK_FOR_SRTM_PLUGIN_PURCHASE; clickAction = RightButtonAction.ASK_FOR_SRTM_PLUGIN_PURCHASE;
} else { } else {
clickAction = RightButtonAction.ASK_FOR_SRTM_PLUGIN_ENABLE; clickAction = RightButtonAction.ASK_FOR_SRTM_PLUGIN_ENABLE;
} }
} else if (indexItem.getType() == DownloadActivityType.WIKIPEDIA_FILE } else if (item.getType() == DownloadActivityType.WIKIPEDIA_FILE
&& !Version.isPaidVersion(context.getMyApplication())) { && !Version.isPaidVersion(context.getMyApplication())) {
clickAction = RightButtonAction.ASK_FOR_FULL_VERSION_PURCHASE; clickAction = RightButtonAction.ASK_FOR_FULL_VERSION_PURCHASE;
} else if (indexItem.getType() == DownloadActivityType.DEPTH_CONTOUR_FILE && !depthContoursPurchased) { } else if (item.getType() == DownloadActivityType.DEPTH_CONTOUR_FILE && !depthContoursPurchased) {
clickAction = RightButtonAction.ASK_FOR_DEPTH_CONTOURS_PURCHASE; clickAction = RightButtonAction.ASK_FOR_DEPTH_CONTOURS_PURCHASE;
} }
return clickAction; return clickAction;
} }
public OnClickListener getRightButtonAction(final IndexItem item, final RightButtonAction clickAction) { public OnClickListener getRightButtonAction(final DownloadItem item, final RightButtonAction clickAction) {
if (clickAction != RightButtonAction.DOWNLOAD) { if (clickAction != RightButtonAction.DOWNLOAD) {
return new View.OnClickListener() { return new View.OnClickListener() {
@Override @Override
@ -370,7 +382,7 @@ public class ItemViewHolder {
} }
}; };
} else { } else {
final boolean isDownloading = context.getDownloadThread().isDownloading(item); final boolean isDownloading = item.isDownloading(context.getDownloadThread());
return new View.OnClickListener() { return new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -380,8 +392,8 @@ public class ItemViewHolder {
} else { } else {
context.makeSureUserCancelDownload(item); context.makeSureUserCancelDownload(item);
} }
} else if(item.isDownloaded() && !item.isOutdated()){ } else if(!item.hasActualDataToDownload()){
contextMenu(v, item, item.getRelatedGroup()); showContextMenu(v, item, item.getRelatedGroup());
} else { } else {
download(item, item.getRelatedGroup()); download(item, item.getRelatedGroup());
} }
@ -390,52 +402,21 @@ public class ItemViewHolder {
} }
} }
protected void contextMenu(View v, final IndexItem indexItem, final DownloadResourceGroup parentOptional) { protected void showContextMenu(View v,
final PopupMenu optionsMenu = new PopupMenu(context, v); final DownloadItem downloadItem,
final DownloadResourceGroup parentOptional) {
OsmandApplication app = context.getMyApplication();
PopupMenu optionsMenu = new PopupMenu(context, v);
MenuItem item; MenuItem item;
final File fl = indexItem.getTargetFile(context.getMyApplication()); final List<File> downloadedFiles = downloadItem.getDownloadedFiles(app);
if (fl.exists()) { if (!Algorithms.isEmpty(downloadedFiles)) {
item = optionsMenu.getMenu().add(R.string.shared_string_remove).setIcon( item = optionsMenu.getMenu().add(R.string.shared_string_remove)
context.getMyApplication().getUIUtilities().getThemedIcon(R.drawable.ic_action_remove_dark)); .setIcon(getThemedIcon(context, R.drawable.ic_action_remove_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
LocalIndexType tp = LocalIndexType.MAP_DATA; confirmRemove(downloadItem, downloadedFiles);
if (indexItem.getType() == DownloadActivityType.HILLSHADE_FILE) {
tp = LocalIndexType.TILES_DATA;
} else if (indexItem.getType() == DownloadActivityType.SLOPE_FILE) {
tp = LocalIndexType.TILES_DATA;
} else if (indexItem.getType() == DownloadActivityType.ROADS_FILE) {
tp = LocalIndexType.MAP_DATA;
} else if (indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) {
tp = LocalIndexType.SRTM_DATA;
} else if (indexItem.getType() == DownloadActivityType.WIKIPEDIA_FILE) {
tp = LocalIndexType.MAP_DATA;
} else if (indexItem.getType() == DownloadActivityType.WIKIVOYAGE_FILE) {
tp = LocalIndexType.MAP_DATA;
} else if (indexItem.getType() == DownloadActivityType.TRAVEL_FILE) {
tp = LocalIndexType.MAP_DATA;
} else if (indexItem.getType() == DownloadActivityType.FONT_FILE) {
tp = LocalIndexType.FONT_DATA;
} else if (indexItem.getType() == DownloadActivityType.VOICE_FILE) {
tp = indexItem.getBasename().contains("tts") ? LocalIndexType.TTS_VOICE_DATA
: LocalIndexType.VOICE_DATA;
}
final LocalIndexInfo info = new LocalIndexInfo(tp, fl, false, context.getMyApplication());
AlertDialog.Builder confirm = new AlertDialog.Builder(context);
confirm.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
new LocalIndexOperationTask(context, null, LocalIndexOperationTask.DELETE_OPERATION)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, info);
}
});
confirm.setNegativeButton(R.string.shared_string_no, null);
String fn = FileNameTranslationHelper.getFileName(context, context.getMyApplication().getRegions(),
indexItem.getVisibleName(context, context.getMyApplication().getRegions()));
confirm.setMessage(context.getString(R.string.delete_confirmation_msg, fn));
confirm.show();
return true; return true;
} }
}); });
@ -445,14 +426,144 @@ public class ItemViewHolder {
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override @Override
public boolean onMenuItemClick(MenuItem item) { public boolean onMenuItemClick(MenuItem item) {
download(indexItem, parentOptional); download(downloadItem, parentOptional);
return true; return true;
} }
}); });
optionsMenu.show(); optionsMenu.show();
} }
protected void download(DownloadItem item, DownloadResourceGroup parentOptional) {
boolean handled = false;
if (parentOptional != null && item instanceof IndexItem) {
IndexItem indexItem = (IndexItem) item;
WorldRegion region = DownloadResourceGroup.getRegion(parentOptional);
context.setDownloadItem(region, indexItem.getTargetFile(context.getMyApplication()).getAbsolutePath());
}
if (item.getType() == DownloadActivityType.ROADS_FILE && parentOptional != null) {
for (IndexItem ii : parentOptional.getIndividualResources()) {
if (ii.getType() == DownloadActivityType.NORMAL_FILE) {
if (ii.isDownloaded()) {
handled = true;
confirmDownload(item);
}
break;
}
}
}
if(!handled) {
startDownload(item);
}
}
private void confirmDownload(final DownloadItem item) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.are_you_sure);
builder.setMessage(R.string.confirm_download_roadmaps);
builder.setNegativeButton(R.string.shared_string_cancel, null).setPositiveButton(
R.string.shared_string_download, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (item != null) {
startDownload(item);
}
}
});
builder.show();
}
private void startDownload(DownloadItem item) {
if (item instanceof MultipleIndexItem) {
MultipleIndexItem multipleIndexItem = (MultipleIndexItem) item;
List<IndexItem> indexes;
if (multipleIndexItem.hasActualDataToDownload()) {
// download left regions
indexes = multipleIndexItem.getIndexesToDownload();
} else {
// download all regions again
indexes = multipleIndexItem.getAllIndexes();
}
IndexItem[] indexesArray = new IndexItem[indexes.size()];
context.startDownload(indexes.toArray(indexesArray));
} else if (item instanceof IndexItem) {
IndexItem indexItem = (IndexItem) item;
context.startDownload(indexItem);
}
}
private void confirmRemove(@NonNull final DownloadItem downloadItem,
@NonNull final List<File> downloadedFiles) {
OsmandApplication app = context.getMyApplication();
AlertDialog.Builder confirm = new AlertDialog.Builder(context);
String message;
if (downloadedFiles.size() > 1) {
message = context.getString(R.string.delete_number_files_question, downloadedFiles.size());
} else {
OsmandRegions regions = app.getRegions();
String visibleName = downloadItem.getVisibleName(context, regions);
String fileName = FileNameTranslationHelper.getFileName(context, regions, visibleName);
message = context.getString(R.string.delete_confirmation_msg, fileName);
}
confirm.setMessage(message);
confirm.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
LocalIndexType type = getLocalIndexType(downloadItem);
remove(type, downloadedFiles);
}
});
confirm.setNegativeButton(R.string.shared_string_no, null);
confirm.show();
}
private void remove(@NonNull LocalIndexType type,
@NonNull List<File> filesToDelete) {
OsmandApplication app = context.getMyApplication();
LocalIndexOperationTask removeTask = new LocalIndexOperationTask(
context,
null,
LocalIndexOperationTask.DELETE_OPERATION);
LocalIndexInfo[] params = new LocalIndexInfo[filesToDelete.size()];
for (int i = 0; i < filesToDelete.size(); i++) {
File file = filesToDelete.get(i);
params[i] = new LocalIndexInfo(type, file, false, app);
}
removeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
}
@NonNull
private LocalIndexType getLocalIndexType(@NonNull DownloadItem downloadItem) {
LocalIndexType type = LocalIndexType.MAP_DATA;
if (downloadItem.getType() == DownloadActivityType.HILLSHADE_FILE) {
type = LocalIndexType.TILES_DATA;
} else if (downloadItem.getType() == DownloadActivityType.SLOPE_FILE) {
type = LocalIndexType.TILES_DATA;
} else if (downloadItem.getType() == DownloadActivityType.ROADS_FILE) {
type = LocalIndexType.MAP_DATA;
} else if (downloadItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) {
type = LocalIndexType.SRTM_DATA;
} else if (downloadItem.getType() == DownloadActivityType.WIKIPEDIA_FILE) {
type = LocalIndexType.MAP_DATA;
} else if (downloadItem.getType() == DownloadActivityType.WIKIVOYAGE_FILE) {
type = LocalIndexType.MAP_DATA;
} else if (downloadItem.getType() == DownloadActivityType.TRAVEL_FILE) {
type = LocalIndexType.MAP_DATA;
} else if (downloadItem.getType() == DownloadActivityType.FONT_FILE) {
type = LocalIndexType.FONT_DATA;
} else if (downloadItem.getType() == DownloadActivityType.VOICE_FILE) {
type = downloadItem.getBasename().contains("tts") ? LocalIndexType.TTS_VOICE_DATA
: LocalIndexType.VOICE_DATA;
}
return type;
}
private Drawable getThemedIcon(DownloadActivity context, int resourceId) {
return context.getMyApplication().getUIUtilities().getThemedIcon(resourceId);
}
private Drawable getContentIcon(DownloadActivity context, int resourceId) { private Drawable getContentIcon(DownloadActivity context, int resourceId) {
return context.getMyApplication().getUIUtilities().getThemedIcon(resourceId); return context.getMyApplication().getUIUtilities().getThemedIcon(resourceId);
} }

View file

@ -153,7 +153,8 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download
for (IndexItem indexItem : indexItems) { for (IndexItem indexItem : indexItems) {
downloadsSize += indexItem.getSize(); downloadsSize += indexItem.getSize();
} }
String updateAllText = getActivity().getString(R.string.update_all, downloadsSize >> 20); String updateAllText = getActivity().getString(
R.string.update_all, String.valueOf(downloadsSize >> 20));
updateAllButton.setText(updateAllText); updateAllButton.setText(updateAllText);
updateAllButton.setOnClickListener(new View.OnClickListener() { updateAllButton.setOnClickListener(new View.OnClickListener() {
@Override @Override