Merge branch 'master' of https://github.com/osmandapp/Osmand
This commit is contained in:
commit
81b2fcee4d
18 changed files with 788 additions and 612 deletions
|
@ -8,9 +8,11 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
@ -27,6 +29,7 @@ public class OpeningHoursParser {
|
|||
private static final String[] localDaysStr;
|
||||
private static final String[] monthsStr;
|
||||
private static final String[] localMothsStr;
|
||||
private static final Map<String, String> additionalStrings = new HashMap<>();
|
||||
|
||||
private static final int LOW_TIME_LIMIT = 120;
|
||||
private static final int WITHOUT_TIME_LIMIT = -1;
|
||||
|
@ -39,6 +42,23 @@ public class OpeningHoursParser {
|
|||
dateFormatSymbols = DateFormatSymbols.getInstance();
|
||||
localMothsStr = dateFormatSymbols.getShortMonths();
|
||||
localDaysStr = getTwoLettersStringArray(dateFormatSymbols.getShortWeekdays());
|
||||
|
||||
additionalStrings.put("off", "off");
|
||||
additionalStrings.put("is_open", "Open");
|
||||
additionalStrings.put("is_open_24_7", "Open 24/7");
|
||||
additionalStrings.put("will_open_at", "Will open at");
|
||||
additionalStrings.put("open_from", "Open from");
|
||||
additionalStrings.put("will_close_at", "Will close at");
|
||||
additionalStrings.put("open_till", "Open till");
|
||||
additionalStrings.put("will_open_tomorrow_at", "Will open tomorrow at");
|
||||
additionalStrings.put("will_open_on", "Will open on");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set additional localized strings like "off", etc.
|
||||
*/
|
||||
public static void setAdditionalString(String key, String value) {
|
||||
additionalStrings.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,11 +109,61 @@ public class OpeningHoursParser {
|
|||
*/
|
||||
public static class OpeningHours implements Serializable {
|
||||
|
||||
public static final int ALL_SEQUENCES = -1;
|
||||
|
||||
/**
|
||||
* list of the different rules
|
||||
*/
|
||||
private ArrayList<OpeningHoursRule> rules;
|
||||
private String original;
|
||||
private int sequenceCount;
|
||||
|
||||
public static class Info {
|
||||
|
||||
private boolean opened;
|
||||
private boolean opened24_7;
|
||||
private String openingTime;
|
||||
private String nearToOpeningTime;
|
||||
private String closingTime;
|
||||
private String nearToClosingTime;
|
||||
private String openingTomorrow;
|
||||
private String openingDay;
|
||||
private String ruleString;
|
||||
|
||||
public boolean isOpened() {
|
||||
return opened;
|
||||
}
|
||||
|
||||
public boolean isOpened24_7() {
|
||||
return opened24_7;
|
||||
}
|
||||
|
||||
public String getInfo() {
|
||||
if (isOpened24_7()) {
|
||||
if (!Algorithms.isEmpty(ruleString)) {
|
||||
return additionalStrings.get("is_open") + " " + ruleString;
|
||||
} else {
|
||||
return additionalStrings.get("is_open_24_7");
|
||||
}
|
||||
} else if (!Algorithms.isEmpty(nearToOpeningTime)) {
|
||||
return additionalStrings.get("will_open_at") + " " + nearToOpeningTime;
|
||||
} else if (!Algorithms.isEmpty(openingTime)) {
|
||||
return additionalStrings.get("open_from") + " " + openingTime;
|
||||
} else if (!Algorithms.isEmpty(nearToClosingTime)) {
|
||||
return additionalStrings.get("will_close_at") + " " + nearToClosingTime;
|
||||
} else if (!Algorithms.isEmpty(closingTime)) {
|
||||
return additionalStrings.get("open_till") + " " + closingTime;
|
||||
} else if (!Algorithms.isEmpty(openingTomorrow)) {
|
||||
return additionalStrings.get("will_open_tomorrow_at") + " " + openingTomorrow;
|
||||
} else if (!Algorithms.isEmpty(openingDay)) {
|
||||
return additionalStrings.get("will_open_on") + " " + openingDay + ".";
|
||||
} else if (!Algorithms.isEmpty(ruleString)) {
|
||||
return ruleString;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -111,6 +181,45 @@ public class OpeningHoursParser {
|
|||
rules = new ArrayList<OpeningHoursRule>();
|
||||
}
|
||||
|
||||
public List<Info> getInfo() {
|
||||
return getInfo(Calendar.getInstance());
|
||||
}
|
||||
|
||||
public List<Info> getInfo(Calendar cal) {
|
||||
List<Info> res = new ArrayList<>();
|
||||
for (int i = 0; i < sequenceCount; i++) {
|
||||
Info info = getInfo(cal, i);
|
||||
res.add(info);
|
||||
}
|
||||
return res.isEmpty() ? null : res;
|
||||
}
|
||||
|
||||
public Info getCombinedInfo() {
|
||||
return getCombinedInfo(Calendar.getInstance());
|
||||
}
|
||||
|
||||
public Info getCombinedInfo(Calendar cal) {
|
||||
return getInfo(cal, ALL_SEQUENCES);
|
||||
}
|
||||
|
||||
private Info getInfo(Calendar cal, int sequenceIndex) {
|
||||
Info info = new Info();
|
||||
boolean opened = isOpenedForTimeV2(cal, sequenceIndex);
|
||||
info.opened = opened;
|
||||
info.ruleString = getCurrentRuleTime(cal, sequenceIndex);
|
||||
if (opened) {
|
||||
info.opened24_7 = isOpened24_7(sequenceIndex);
|
||||
info.closingTime = getClosingTime(cal, sequenceIndex);
|
||||
info.nearToClosingTime = getNearToClosingTime(cal, sequenceIndex);
|
||||
} else {
|
||||
info.openingTime = getOpeningTime(cal, sequenceIndex);
|
||||
info.nearToOpeningTime = getNearToOpeningTime(cal, sequenceIndex);
|
||||
info.openingTomorrow = getOpeningTomorrow(cal, sequenceIndex);
|
||||
info.openingDay = getOpeningDay(cal, sequenceIndex);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* add a rule to the opening hours
|
||||
*
|
||||
|
@ -125,10 +234,18 @@ public class OpeningHoursParser {
|
|||
*
|
||||
* @param rules to add
|
||||
*/
|
||||
public void addRules(List<OpeningHoursRule> rules) {
|
||||
public void addRules(List<? extends OpeningHoursRule> rules) {
|
||||
this.rules.addAll(rules);
|
||||
}
|
||||
|
||||
public int getSequenceCount() {
|
||||
return sequenceCount;
|
||||
}
|
||||
|
||||
public void setSequenceCount(int sequenceCount) {
|
||||
this.sequenceCount = sequenceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the list of rules
|
||||
*
|
||||
|
@ -137,32 +254,47 @@ public class OpeningHoursParser {
|
|||
public ArrayList<OpeningHoursRule> getRules() {
|
||||
return rules;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<OpeningHoursRule> getRules(int sequenceIndex) {
|
||||
if (sequenceIndex == ALL_SEQUENCES) {
|
||||
return rules;
|
||||
} else {
|
||||
ArrayList<OpeningHoursRule> sequenceRules = new ArrayList<>();
|
||||
for (OpeningHoursRule r : rules) {
|
||||
if (r.getSequenceIndex() == sequenceIndex) {
|
||||
sequenceRules.add(r);
|
||||
}
|
||||
}
|
||||
return sequenceRules;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the feature is opened at time "cal"
|
||||
*
|
||||
* @param cal the time to check
|
||||
* @return true if feature is open
|
||||
*/
|
||||
public boolean isOpenedForTimeV2(Calendar cal) {
|
||||
public boolean isOpenedForTimeV2(Calendar cal, int sequenceIndex) {
|
||||
// make exception for overlapping times i.e.
|
||||
// (1) Mo 14:00-16:00; Tu off
|
||||
// (2) Mo 14:00-02:00; Tu off
|
||||
// in (2) we need to check first rule even though it is against specification
|
||||
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
|
||||
boolean overlap = false;
|
||||
for(int i = rules.size() - 1; i >= 0 ; i--) {
|
||||
for (int i = rules.size() - 1; i >= 0 ; i--) {
|
||||
OpeningHoursRule r = rules.get(i);
|
||||
if(r.hasOverlapTimes()) {
|
||||
if (r.hasOverlapTimes()) {
|
||||
overlap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// start from the most specific rule
|
||||
for(int i = rules.size() - 1; i >= 0 ; i--) {
|
||||
for (int i = rules.size() - 1; i >= 0 ; i--) {
|
||||
OpeningHoursRule r = rules.get(i);
|
||||
if(r.contains(cal)) {
|
||||
if (r.contains(cal)) {
|
||||
boolean open = r.isOpenedForTime(cal);
|
||||
if(!open && overlap ) {
|
||||
if (!open && overlap ) {
|
||||
continue;
|
||||
} else {
|
||||
return open;
|
||||
|
@ -179,12 +311,24 @@ public class OpeningHoursParser {
|
|||
* @return true if feature is open
|
||||
*/
|
||||
public boolean isOpenedForTime(Calendar cal) {
|
||||
return isOpenedForTimeV2(cal, ALL_SEQUENCES);
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the feature is opened at time "cal"
|
||||
*
|
||||
* @param cal the time to check
|
||||
* @param sequenceIndex the sequence index to check
|
||||
* @return true if feature is open
|
||||
*/
|
||||
public boolean isOpenedForTime(Calendar cal, int sequenceIndex) {
|
||||
/*
|
||||
* first check for rules that contain the current day
|
||||
* afterwards check for rules that contain the previous
|
||||
* day with overlapping times (times after midnight)
|
||||
*/
|
||||
boolean isOpenDay = false;
|
||||
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
|
||||
for (OpeningHoursRule r : rules) {
|
||||
if (r.containsDay(cal) && r.containsMonth(cal)) {
|
||||
isOpenDay = r.isOpenedForTime(cal, false);
|
||||
|
@ -199,33 +343,48 @@ public class OpeningHoursParser {
|
|||
return isOpenDay || isOpenPrevious;
|
||||
}
|
||||
|
||||
public boolean isOpened24_7() {
|
||||
public boolean isOpened24_7(int sequenceIndex) {
|
||||
boolean opened24_7 = false;
|
||||
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
|
||||
for (OpeningHoursRule r : rules) {
|
||||
opened24_7 = r.isOpened24_7();
|
||||
}
|
||||
return opened24_7;
|
||||
}
|
||||
|
||||
public String getNearToOpeningTime(Calendar cal) {
|
||||
return getTime(cal, LOW_TIME_LIMIT, true);
|
||||
public String getNearToOpeningTime(Calendar cal, int sequenceIndex) {
|
||||
return getTime(cal, LOW_TIME_LIMIT, true, sequenceIndex);
|
||||
}
|
||||
|
||||
public String getOpeningTime(Calendar cal) {
|
||||
return getTime(cal, CURRENT_DAY_TIME_LIMIT, true);
|
||||
public String getOpeningTime(Calendar cal, int sequenceIndex) {
|
||||
return getTime(cal, CURRENT_DAY_TIME_LIMIT, true, sequenceIndex);
|
||||
}
|
||||
|
||||
public String getNearToClosingTime(Calendar cal) {
|
||||
return getTime(cal, LOW_TIME_LIMIT, false);
|
||||
public String getNearToClosingTime(Calendar cal, int sequenceIndex) {
|
||||
return getTime(cal, LOW_TIME_LIMIT, false, sequenceIndex);
|
||||
}
|
||||
|
||||
public String getClosingTime(Calendar cal) {
|
||||
return getTime(cal, WITHOUT_TIME_LIMIT, false);
|
||||
public String getClosingTime(Calendar cal, int sequenceIndex) {
|
||||
return getTime(cal, WITHOUT_TIME_LIMIT, false, sequenceIndex);
|
||||
}
|
||||
|
||||
public String getOpeningDay(Calendar calendar) {
|
||||
public String getOpeningTomorrow(Calendar calendar, int sequenceIndex) {
|
||||
Calendar cal = (Calendar) calendar.clone();
|
||||
String openingTime = "";
|
||||
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
|
||||
cal.add(Calendar.DAY_OF_MONTH, 1);
|
||||
for (OpeningHoursRule r : rules) {
|
||||
if (r.containsDay(cal) && r.containsMonth(cal)) {
|
||||
openingTime = r.getTime(cal, false, WITHOUT_TIME_LIMIT, true);
|
||||
}
|
||||
}
|
||||
return openingTime;
|
||||
}
|
||||
|
||||
public String getOpeningDay(Calendar calendar, int sequenceIndex) {
|
||||
Calendar cal = (Calendar) calendar.clone();
|
||||
String openingTime = "";
|
||||
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
cal.add(Calendar.DAY_OF_MONTH, 1);
|
||||
for (OpeningHoursRule r : rules) {
|
||||
|
@ -241,16 +400,17 @@ public class OpeningHoursParser {
|
|||
return openingTime;
|
||||
}
|
||||
|
||||
private String getTime(Calendar cal, int limit, boolean opening) {
|
||||
String time = getTimeDay(cal, limit, opening);
|
||||
private String getTime(Calendar cal, int limit, boolean opening, int sequenceIndex) {
|
||||
String time = getTimeDay(cal, limit, opening, sequenceIndex);
|
||||
if (Algorithms.isEmpty(time)) {
|
||||
time = getTimeAnotherDay(cal, limit, opening);
|
||||
time = getTimeAnotherDay(cal, limit, opening, sequenceIndex);
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
private String getTimeDay(Calendar cal, int limit, boolean opening) {
|
||||
private String getTimeDay(Calendar cal, int limit, boolean opening, int sequenceIndex) {
|
||||
String atTime = "";
|
||||
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
|
||||
for (OpeningHoursRule r : rules) {
|
||||
if (r.containsDay(cal) && r.containsMonth(cal)) {
|
||||
atTime = r.getTime(cal, false, limit, opening);
|
||||
|
@ -259,8 +419,9 @@ public class OpeningHoursParser {
|
|||
return atTime;
|
||||
}
|
||||
|
||||
private String getTimeAnotherDay(Calendar cal, int limit, boolean opening) {
|
||||
private String getTimeAnotherDay(Calendar cal, int limit, boolean opening, int sequenceIndex) {
|
||||
String atTime = "";
|
||||
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
|
||||
for (OpeningHoursRule r : rules) {
|
||||
if (((opening && r.containsPreviousDay(cal)) || (!opening && r.containsNextDay(cal))) && r.containsMonth(cal)) {
|
||||
atTime = r.getTime(cal, true, limit, opening);
|
||||
|
@ -270,10 +431,15 @@ public class OpeningHoursParser {
|
|||
}
|
||||
|
||||
public String getCurrentRuleTime(Calendar cal) {
|
||||
return getCurrentRuleTime(cal, ALL_SEQUENCES);
|
||||
}
|
||||
|
||||
public String getCurrentRuleTime(Calendar cal, int sequenceIndex) {
|
||||
// make exception for overlapping times i.e.
|
||||
// (1) Mo 14:00-16:00; Tu off
|
||||
// (2) Mo 14:00-02:00; Tu off
|
||||
// in (2) we need to check first rule even though it is against specification
|
||||
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
|
||||
String ruleClosed = null;
|
||||
boolean overlap = false;
|
||||
for (int i = rules.size() - 1; i >= 0; i--) {
|
||||
|
@ -428,6 +594,7 @@ public class OpeningHoursParser {
|
|||
*/
|
||||
public boolean contains(Calendar cal);
|
||||
|
||||
public int getSequenceIndex();
|
||||
|
||||
public String toRuleString();
|
||||
|
||||
|
@ -475,6 +642,26 @@ public class OpeningHoursParser {
|
|||
*/
|
||||
private boolean off = false;
|
||||
|
||||
/**
|
||||
* Aadditional information or limitation.
|
||||
* https://wiki.openstreetmap.org/wiki/Key:opening_hours/specification#explain:comment
|
||||
*/
|
||||
private String comment;
|
||||
|
||||
private int sequenceIndex;
|
||||
|
||||
public BasicOpeningHourRule() {
|
||||
this.sequenceIndex = 0;
|
||||
}
|
||||
|
||||
public BasicOpeningHourRule(int sequenceIndex) {
|
||||
this.sequenceIndex = sequenceIndex;
|
||||
}
|
||||
|
||||
public int getSequenceIndex() {
|
||||
return sequenceIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* return an array representing the days of the rule
|
||||
*
|
||||
|
@ -511,7 +698,14 @@ public class OpeningHoursParser {
|
|||
public boolean appliesToSchoolHolidays() {
|
||||
return schoolHoliday;
|
||||
}
|
||||
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* set a single start time, erase all previously added start times
|
||||
|
@ -786,27 +980,45 @@ public class OpeningHoursParser {
|
|||
appendDaysString(b, dayNames);
|
||||
// Time
|
||||
if (startTimes == null || startTimes.size() == 0) {
|
||||
b.append("off");
|
||||
if (isOpened24_7()) {
|
||||
b.setLength(0);
|
||||
b.append("24/7 ");
|
||||
}
|
||||
if (off) {
|
||||
b.append(additionalStrings.get("off"));
|
||||
}
|
||||
} else {
|
||||
if (isOpened24_7()) {
|
||||
return "24/7";
|
||||
}
|
||||
for (int i = 0; i < startTimes.size(); i++) {
|
||||
int startTime = startTimes.get(i);
|
||||
int endTime = endTimes.get(i);
|
||||
if(i > 0) {
|
||||
b.append(", ");
|
||||
b.setLength(0);
|
||||
b.append("24/7");
|
||||
} else {
|
||||
for (int i = 0; i < startTimes.size(); i++) {
|
||||
int startTime = startTimes.get(i);
|
||||
int endTime = endTimes.get(i);
|
||||
if (i > 0) {
|
||||
b.append(", ");
|
||||
}
|
||||
int stHour = startTime / 60;
|
||||
int stTime = startTime - stHour * 60;
|
||||
int enHour = endTime / 60;
|
||||
int enTime = endTime - enHour * 60;
|
||||
formatTime(stHour, stTime, b);
|
||||
b.append("-"); //$NON-NLS-1$
|
||||
formatTime(enHour, enTime, b);
|
||||
}
|
||||
if (off) {
|
||||
b.append(" ").append(additionalStrings.get("off"));
|
||||
}
|
||||
int stHour = startTime / 60;
|
||||
int stTime = startTime - stHour * 60;
|
||||
int enHour = endTime / 60;
|
||||
int enTime = endTime - enHour * 60;
|
||||
formatTime(stHour, stTime, b);
|
||||
b.append("-"); //$NON-NLS-1$
|
||||
formatTime(enHour, enTime, b);
|
||||
}
|
||||
if(off) {
|
||||
b.append(" off");
|
||||
}
|
||||
if (!Algorithms.isEmpty(comment)) {
|
||||
if (b.length() > 0) {
|
||||
if (b.charAt(b.length() - 1) != ' ') {
|
||||
b.append(" ");
|
||||
}
|
||||
b.append("(").append(comment).append(")");
|
||||
} else {
|
||||
b.append(comment);
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
|
@ -853,13 +1065,17 @@ public class OpeningHoursParser {
|
|||
}
|
||||
}
|
||||
|
||||
if (opened24_7 && startTimes != null && startTimes.size() > 0) {
|
||||
for (int i = 0; i < startTimes.size(); i++) {
|
||||
int startTime = startTimes.get(i);
|
||||
int endTime = endTimes.get(i);
|
||||
if (startTime == 0 && endTime / 60 == 24) {
|
||||
return true;
|
||||
if (opened24_7) {
|
||||
if (startTimes != null && startTimes.size() > 0) {
|
||||
for (int i = 0; i < startTimes.size(); i++) {
|
||||
int startTime = startTimes.get(i);
|
||||
int endTime = endTimes.get(i);
|
||||
if (startTime == 0 && endTime / 60 == 24) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -918,7 +1134,11 @@ public class OpeningHoursParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
String res = sb.toString();
|
||||
if (res.length() > 0 && !Algorithms.isEmpty(comment)) {
|
||||
res += " (" + comment + ")";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1015,7 +1235,7 @@ public class OpeningHoursParser {
|
|||
int c = calculate(cal);
|
||||
return c != 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasOverlapTimes() {
|
||||
for (int i = 0; i < startTimes.size(); i++) {
|
||||
|
@ -1062,14 +1282,16 @@ public class OpeningHoursParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (thisDay && (startTimes == null || startTimes.isEmpty() || !off)) {
|
||||
if (thisDay && (startTimes == null || startTimes.isEmpty()) && !off) {
|
||||
return 1;
|
||||
} else if (thisDay && (startTimes == null || startTimes.isEmpty() || !off)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static class UnparseableRule implements OpeningHoursParser.OpeningHoursRule {
|
||||
public static class UnparseableRule implements OpeningHoursRule {
|
||||
private String ruleString;
|
||||
|
||||
public UnparseableRule(String ruleString) {
|
||||
|
@ -1140,6 +1362,11 @@ public class OpeningHoursParser {
|
|||
public boolean contains(Calendar cal) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSequenceIndex() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private enum TokenType {
|
||||
|
@ -1185,8 +1412,22 @@ public class OpeningHoursParser {
|
|||
}
|
||||
}
|
||||
|
||||
public static void parseRuleV2(String r, List<OpeningHoursParser.OpeningHoursRule> rules) {
|
||||
r = r.toLowerCase();
|
||||
public static void parseRuleV2(String r, int sequenceIndex, List<OpeningHoursRule> rules) {
|
||||
String comment = null;
|
||||
int q1Index = r.indexOf('"');
|
||||
if (q1Index >= 0) {
|
||||
int q2Index = r.indexOf('"', q1Index + 1);
|
||||
if (q2Index >= 0) {
|
||||
comment = r.substring(q1Index + 1, q2Index);
|
||||
String a = r.substring(0, q1Index);
|
||||
String b = "";
|
||||
if (r.length() > q2Index + 1) {
|
||||
b = r.substring(q2Index + 1);
|
||||
}
|
||||
r = a + b;
|
||||
}
|
||||
}
|
||||
r = r.toLowerCase().trim();
|
||||
|
||||
final String[] daysStr = new String[]{"mo", "tu", "we", "th", "fr", "sa", "su"};
|
||||
final String[] monthsStr = new String[]{"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"};
|
||||
|
@ -1198,7 +1439,8 @@ public class OpeningHoursParser {
|
|||
r = r.replace(')', ' ');
|
||||
String localRuleString = r.replaceAll("sunset", sunset).replaceAll("sunrise", sunrise)
|
||||
.replaceAll("\\+", "-" + endOfDay);
|
||||
BasicOpeningHourRule basic = new BasicOpeningHourRule();
|
||||
BasicOpeningHourRule basic = new BasicOpeningHourRule(sequenceIndex);
|
||||
basic.setComment(comment);
|
||||
boolean[] days = basic.getDays();
|
||||
boolean[] months = basic.getMonths();
|
||||
boolean[] dayMonths = basic.getDayMonths();
|
||||
|
@ -1211,32 +1453,32 @@ public class OpeningHoursParser {
|
|||
}
|
||||
List<Token> tokens = new ArrayList<>();
|
||||
int startWord = 0;
|
||||
for(int i = 0; i <= localRuleString.length(); i++) {
|
||||
for (int i = 0; i <= localRuleString.length(); i++) {
|
||||
char ch = i == localRuleString.length() ? ' ' : localRuleString.charAt(i);
|
||||
boolean delimiter = false;
|
||||
Token del = null;
|
||||
if(Character.isWhitespace(ch)) {
|
||||
if (Character.isWhitespace(ch)) {
|
||||
delimiter = true;
|
||||
} else if(ch == ':') {
|
||||
} else if (ch == ':') {
|
||||
del = new Token(TokenType.TOKEN_COLON, ":");
|
||||
} else if(ch == '-') {
|
||||
} else if (ch == '-') {
|
||||
del = new Token(TokenType.TOKEN_DASH, "-");
|
||||
} else if(ch == ',') {
|
||||
} else if (ch == ',') {
|
||||
del = new Token(TokenType.TOKEN_COMMA, ",");
|
||||
}
|
||||
if(delimiter || del != null) {
|
||||
if (delimiter || del != null) {
|
||||
String wrd = localRuleString.substring(startWord, i).trim();
|
||||
if(wrd.length() > 0) {
|
||||
tokens.add(new Token(TokenType.TOKEN_UNKNOWN, wrd));
|
||||
}
|
||||
startWord = i + 1;
|
||||
if(del != null) {
|
||||
if (del != null) {
|
||||
tokens.add(del);
|
||||
}
|
||||
}
|
||||
}
|
||||
// recognize day of week
|
||||
for(Token t : tokens) {
|
||||
for (Token t : tokens) {
|
||||
if(t.type == TokenType.TOKEN_UNKNOWN) {
|
||||
findInArray(t, daysStr, TokenType.TOKEN_DAY_WEEK);
|
||||
}
|
||||
|
@ -1360,7 +1602,9 @@ public class OpeningHoursParser {
|
|||
currentParse = t.type;
|
||||
}
|
||||
} else if (t.type.ord() < currentParse.ord() && indexP == 0 && tokens.size() > i) {
|
||||
buildRule(new BasicOpeningHourRule(), tokens.subList(i, tokens.size()), rules);
|
||||
BasicOpeningHourRule newRule = new BasicOpeningHourRule(basic.getSequenceIndex());
|
||||
newRule.setComment(basic.getComment());
|
||||
buildRule(newRule, tokens.subList(i, tokens.size()), rules);
|
||||
tokens = tokens.subList(0, i + 1);
|
||||
} else if (t.type == TokenType.TOKEN_COMMA) {
|
||||
if (tokens.size() > i + 1 && tokens.get(i + 1) != null && tokens.get(i + 1).type.ord() < currentParse.ord()) {
|
||||
|
@ -1405,14 +1649,55 @@ public class OpeningHoursParser {
|
|||
}
|
||||
}
|
||||
|
||||
private static List<List<String>> splitSequences(String format) {
|
||||
if (format == null) {
|
||||
return null;
|
||||
}
|
||||
List<List<String>> res = new ArrayList<>();
|
||||
String[] sequences = format.split("\\|\\|");
|
||||
for (String seq : sequences) {
|
||||
seq = seq.trim();
|
||||
if (seq.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> rules = new ArrayList<>();
|
||||
boolean comment = false;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < seq.length(); i++) {
|
||||
char c = seq.charAt(i);
|
||||
if (c == '"') {
|
||||
comment = !comment;
|
||||
sb.append(c);
|
||||
} else if (c == ';' && !comment) {
|
||||
if (sb.length() > 0) {
|
||||
String s = sb.toString().trim();
|
||||
if (s.length() > 0) {
|
||||
rules.add(s);
|
||||
}
|
||||
sb.setLength(0);
|
||||
}
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
if (sb.length() > 0) {
|
||||
rules.add(sb.toString());
|
||||
sb.setLength(0);
|
||||
}
|
||||
res.add(rules);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an opening_hours string from OSM to an OpeningHours object which can be used to check
|
||||
*
|
||||
* @param r the string to parse
|
||||
* @return BasicRule if the String is successfully parsed and UnparseableRule otherwise
|
||||
*/
|
||||
public static void parseRules(String r, List<OpeningHoursParser.OpeningHoursRule> rules) {
|
||||
parseRuleV2(r, rules);
|
||||
public static void parseRules(String r, int sequenceIndex, List<OpeningHoursRule> rules) {
|
||||
parseRuleV2(r, sequenceIndex, rules);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1425,25 +1710,38 @@ public class OpeningHoursParser {
|
|||
if (format == null) {
|
||||
return null;
|
||||
}
|
||||
// split the OSM string in multiple rules
|
||||
String[] rules = format.split(";"); //$NON-NLS-1$
|
||||
// FIXME: What if the semicolon is inside a quoted string?
|
||||
OpeningHours rs = new OpeningHours();
|
||||
rs.setOriginal(format);
|
||||
for (String r : rules) {
|
||||
r = r.trim();
|
||||
if (r.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
// check if valid
|
||||
List<OpeningHoursParser.OpeningHoursRule> rList = new ArrayList<>();
|
||||
parseRules(r, rList);
|
||||
for (OpeningHoursParser.OpeningHoursRule rule : rList) {
|
||||
if (rule instanceof BasicOpeningHourRule) {
|
||||
rs.addRule(rule);
|
||||
// split the OSM string in multiple rules
|
||||
List<List<String>> sequences = splitSequences(format);
|
||||
for (int i = 0; i < sequences.size(); i++) {
|
||||
List<String> rules = sequences.get(i);
|
||||
List<BasicOpeningHourRule> basicRules = new ArrayList<>();
|
||||
for (String r : rules) {
|
||||
// check if valid
|
||||
List<OpeningHoursRule> rList = new ArrayList<>();
|
||||
parseRules(r, i, rList);
|
||||
for (OpeningHoursRule rule : rList) {
|
||||
if (rule instanceof BasicOpeningHourRule) {
|
||||
basicRules.add((BasicOpeningHourRule) rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
String basicRuleComment = null;
|
||||
for (BasicOpeningHourRule bRule : basicRules) {
|
||||
if (!Algorithms.isEmpty(bRule.getComment())) {
|
||||
basicRuleComment = bRule.getComment();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!Algorithms.isEmpty(basicRuleComment)) {
|
||||
for (BasicOpeningHourRule bRule : basicRules) {
|
||||
bRule.setComment(basicRuleComment);
|
||||
}
|
||||
}
|
||||
rs.addRules(basicRules);
|
||||
}
|
||||
rs.setSequenceCount(sequences.size());
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
@ -1459,22 +1757,35 @@ public class OpeningHoursParser {
|
|||
if (format == null) {
|
||||
return null;
|
||||
}
|
||||
String[] rules = format.split(";"); //$NON-NLS-1$
|
||||
OpeningHoursParser.OpeningHours rs = new OpeningHoursParser.OpeningHours();
|
||||
rs.setOriginal(format);
|
||||
for (String r : rules) {
|
||||
r = r.trim();
|
||||
if (r.length() == 0) {
|
||||
continue;
|
||||
List<List<String>> sequences = splitSequences(format);
|
||||
for (int i = sequences.size() - 1; i >= 0; i--) {
|
||||
List<String> rules = sequences.get(i);
|
||||
for (String r : rules) {
|
||||
r = r.trim();
|
||||
if (r.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
// check if valid
|
||||
List<OpeningHoursRule> rList = new ArrayList<>();
|
||||
parseRules(r, i, rList);
|
||||
rs.addRules(rList);
|
||||
}
|
||||
// check if valid
|
||||
List<OpeningHoursParser.OpeningHoursRule> rList = new ArrayList<>();
|
||||
parseRules(r, rList);
|
||||
rs.addRules(rList);
|
||||
}
|
||||
rs.setSequenceCount(sequences.size());
|
||||
return rs;
|
||||
}
|
||||
|
||||
public static List<OpeningHours.Info> getInfo(String format) {
|
||||
OpeningHours openingHours = OpeningHoursParser.parseOpenedHours(format);
|
||||
if (openingHours == null) {
|
||||
return null;
|
||||
} else {
|
||||
return openingHours.getInfo();
|
||||
}
|
||||
}
|
||||
|
||||
private static void formatTime(int h, int t, StringBuilder b) {
|
||||
if (h < 10) {
|
||||
b.append("0"); //$NON-NLS-1$
|
||||
|
@ -1502,9 +1813,9 @@ public class OpeningHoursParser {
|
|||
private static void testOpened(String time, OpeningHours hours, boolean expected) throws ParseException {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.US).parse(time));
|
||||
boolean calculated = hours.isOpenedForTimeV2(cal);
|
||||
boolean calculated = hours.isOpenedForTimeV2(cal, OpeningHours.ALL_SEQUENCES);
|
||||
System.out.printf(" %sok: Expected %s: %b = %b (rule %s)\n",
|
||||
((calculated != expected) ? "NOT " : ""), time, expected, calculated, hours.getCurrentRuleTime(cal));
|
||||
((calculated != expected) ? "NOT " : ""), time, expected, calculated, hours.getCurrentRuleTime(cal, OpeningHours.ALL_SEQUENCES));
|
||||
if (calculated != expected) {
|
||||
throw new IllegalArgumentException("BUG!!!");
|
||||
}
|
||||
|
@ -1521,50 +1832,49 @@ public class OpeningHoursParser {
|
|||
* "Open till HH:mm" - close in 5 hours
|
||||
* "Will close at HH:mm" - close in 2 hours
|
||||
* "Will open on HH:mm (Mo,Tu,We,Th,Fr,Sa,Su)" - open in >5 hours
|
||||
* "Will open tomorrow at HH:mm" - open in >5 hours tomorrow
|
||||
* "Open 24/7" - open 24/7
|
||||
*/
|
||||
private static void testInfo(String time, OpeningHours hours, String expected) throws ParseException
|
||||
{
|
||||
testInfo(time, hours, expected, OpeningHours.ALL_SEQUENCES);
|
||||
}
|
||||
|
||||
/**
|
||||
* test if the calculated opening hours are what you expect
|
||||
*
|
||||
* @param time the time to test in the format "dd.MM.yyyy HH:mm"
|
||||
* @param hours the OpeningHours object
|
||||
* @param expected the expected string in format:
|
||||
* "Open from HH:mm" - open in 5 hours
|
||||
* "Will open at HH:mm" - open in 2 hours
|
||||
* "Open till HH:mm" - close in 5 hours
|
||||
* "Will close at HH:mm" - close in 2 hours
|
||||
* "Will open on HH:mm (Mo,Tu,We,Th,Fr,Sa,Su)" - open in >5 hours
|
||||
* "Will open tomorrow at HH:mm" - open in >5 hours tomorrow
|
||||
* "Open 24/7" - open 24/7
|
||||
* @param sequenceIndex sequence index of rules separated by ||
|
||||
*/
|
||||
private static void testInfo(String time, OpeningHours hours, String expected, int sequenceIndex) throws ParseException
|
||||
{
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.US).parse(time));
|
||||
|
||||
boolean opened24_calc = false;
|
||||
boolean openFrom_calc = false;
|
||||
boolean willOpenAt_calc = false;
|
||||
boolean openTill_calc = false;
|
||||
boolean willCloseAt_calc = false;
|
||||
boolean willOpenOn_calc = false;
|
||||
|
||||
boolean opened = hours.isOpenedForTimeV2(cal);
|
||||
if (opened) {
|
||||
opened24_calc = hours.isOpened24_7();
|
||||
openTill_calc = !Algorithms.isEmpty(hours.getClosingTime(cal));
|
||||
willCloseAt_calc = !Algorithms.isEmpty(hours.getNearToClosingTime(cal));
|
||||
} else {
|
||||
openFrom_calc = !Algorithms.isEmpty(hours.getOpeningTime(cal));
|
||||
willOpenAt_calc = !Algorithms.isEmpty(hours.getNearToOpeningTime(cal));
|
||||
willOpenOn_calc = !Algorithms.isEmpty(hours.getOpeningDay(cal));
|
||||
}
|
||||
|
||||
String description = "Unknown";
|
||||
if (opened24_calc) {
|
||||
description = "Open 24/7";
|
||||
} else if (willOpenAt_calc) {
|
||||
description = "Will open at " + hours.getNearToOpeningTime(cal);
|
||||
} else if (openFrom_calc) {
|
||||
description = "Open from " + hours.getOpeningTime(cal);
|
||||
} else if (willCloseAt_calc) {
|
||||
description = "Will close at " + hours.getNearToClosingTime(cal);
|
||||
} else if (openTill_calc) {
|
||||
description = "Open till " + hours.getClosingTime(cal);
|
||||
} else if (willOpenOn_calc) {
|
||||
description = "Will open on " + hours.getOpeningDay(cal);
|
||||
}
|
||||
|
||||
boolean result = expected.equalsIgnoreCase(description);
|
||||
|
||||
|
||||
String description;
|
||||
boolean result;
|
||||
if (sequenceIndex == OpeningHours.ALL_SEQUENCES) {
|
||||
OpeningHours.Info info = hours.getCombinedInfo(cal);
|
||||
description = info.getInfo();
|
||||
result = expected.equalsIgnoreCase(description);
|
||||
} else {
|
||||
List<OpeningHours.Info> infos = hours.getInfo(cal);
|
||||
OpeningHours.Info info = infos.get(sequenceIndex);
|
||||
description = info.getInfo();
|
||||
result = expected.equalsIgnoreCase(description);
|
||||
}
|
||||
|
||||
System.out.printf(" %sok: Expected %s (%s): %s (rule %s)\n",
|
||||
(!result ? "NOT " : ""), time, expected, description, hours.getCurrentRuleTime(cal));
|
||||
(!result ? "NOT " : ""), time, expected, description, hours.getCurrentRuleTime(cal, sequenceIndex));
|
||||
|
||||
if (!result)
|
||||
throw new IllegalArgumentException("BUG!!!");
|
||||
|
@ -1584,22 +1894,15 @@ public class OpeningHoursParser {
|
|||
// 0. not supported MON DAY-MON DAY (only supported Feb 2-14 or Feb-Oct: 09:00-17:30)
|
||||
// parseOpenedHours("Feb 16-Oct 15: 09:00-18:30; Oct 16-Nov 15: 09:00-17:30; Nov 16-Feb 15: 09:00-16:30");
|
||||
|
||||
// 1. not supported (,)
|
||||
// hours = parseOpenedHours("Mo-Su 07:00-23:00, Fr 08:00-20:00");
|
||||
|
||||
// 2. not supported break properly
|
||||
// parseOpenedHours("Sa-Su 10:00-17:00 || \"by appointment\"");
|
||||
// comment is dropped
|
||||
|
||||
// 3. not properly supported
|
||||
// 1. not properly supported
|
||||
// hours = parseOpenedHours("Mo-Su (sunrise-00:30)-(sunset+00:30)");
|
||||
|
||||
// Test basic case
|
||||
// test basic case
|
||||
OpeningHours hours = parseOpenedHours("Mo-Fr 08:30-14:40"); //$NON-NLS-1$
|
||||
System.out.println(hours);
|
||||
testOpened("09.08.2012 11:00", hours, true);
|
||||
testOpened("09.08.2012 16:00", hours, false);
|
||||
hours = parseOpenedHours("mo-fr 07:00-19:00; sa 12:00-18:00");
|
||||
System.out.println(hours);
|
||||
|
||||
String string = "Mo-Fr 11:30-15:00, 17:30-23:00; Sa, Su, PH 11:30-23:00";
|
||||
hours = parseOpenedHours(string);
|
||||
|
@ -1793,11 +2096,11 @@ public class OpeningHoursParser {
|
|||
testInfo("15.01.2018 13:10", hours, "Will open at 14:00");
|
||||
testInfo("15.01.2018 14:00", hours, "Open till 18:00");
|
||||
testInfo("15.01.2018 16:00", hours, "Will close at 18:00");
|
||||
testInfo("15.01.2018 18:10", hours, "Will open on 09:00 Tu");
|
||||
testInfo("15.01.2018 18:10", hours, "Will open tomorrow at 09:00");
|
||||
|
||||
hours = parseOpenedHours("Mo-Sa 02:00-10:00; Th off");
|
||||
System.out.println(hours);
|
||||
testInfo("15.01.2018 23:00", hours, "Will open on 02:00 Tu");
|
||||
testInfo("15.01.2018 23:00", hours, "Will open tomorrow at 02:00");
|
||||
|
||||
hours = parseOpenedHours("Mo-Sa 23:00-02:00; Th off");
|
||||
System.out.println(hours);
|
||||
|
@ -1808,10 +2111,10 @@ public class OpeningHoursParser {
|
|||
|
||||
hours = parseOpenedHours("Mo-Sa 08:30-17:00; Th off");
|
||||
System.out.println(hours);
|
||||
testInfo("17.01.2018 20:00", hours, "Will open on 08:30 Fr");
|
||||
testInfo("18.01.2018 05:00", hours, "Will open on 08:30 Fr");
|
||||
testInfo("17.01.2018 20:00", hours, "Will open on 08:30 Fr.");
|
||||
testInfo("18.01.2018 05:00", hours, "Will open tomorrow at 08:30");
|
||||
testInfo("20.01.2018 05:00", hours, "Open from 08:30");
|
||||
testInfo("21.01.2018 05:00", hours, "Will open on 08:30 Mo");
|
||||
testInfo("21.01.2018 05:00", hours, "Will open tomorrow at 08:30");
|
||||
testInfo("22.01.2018 02:00", hours, "Open from 08:30");
|
||||
testInfo("22.01.2018 04:00", hours, "Open from 08:30");
|
||||
testInfo("22.01.2018 07:00", hours, "Will open at 08:30");
|
||||
|
@ -1830,6 +2133,31 @@ public class OpeningHoursParser {
|
|||
testOpened("19.01.2018 07:45", hours, false);
|
||||
testOpened("19.01.2018 08:45", hours, true);
|
||||
testOpened("19.01.2018 20:45", hours, false);
|
||||
|
||||
|
||||
// test fallback case
|
||||
hours = parseOpenedHours("07:00-01:00 open \"Restaurant\" || Mo 00:00-04:00,07:00-04:00; Tu-Th 07:00-04:00; Fr 07:00-24:00; Sa,Su 00:00-24:00 open \"McDrive\"");
|
||||
System.out.println(hours);
|
||||
testOpened("22.01.2018 00:30", hours, true);
|
||||
testOpened("22.01.2018 08:00", hours, true);
|
||||
testOpened("22.01.2018 03:30", hours, true);
|
||||
testOpened("22.01.2018 05:00", hours, false);
|
||||
testOpened("23.01.2018 05:00", hours, false);
|
||||
testOpened("27.01.2018 05:00", hours, true);
|
||||
testOpened("28.01.2018 05:00", hours, true);
|
||||
|
||||
testInfo("22.01.2018 05:00", hours, "Will open at 07:00 (Restaurant)", 0);
|
||||
testInfo("26.01.2018 00:00", hours, "Will close at 01:00 (Restaurant)", 0);
|
||||
testInfo("22.01.2018 05:00", hours, "Will open at 07:00 (McDrive)", 1);
|
||||
testInfo("22.01.2018 00:00", hours, "Open till 04:00 (McDrive)", 1);
|
||||
testInfo("22.01.2018 02:00", hours, "Will close at 04:00 (McDrive)", 1);
|
||||
testInfo("27.01.2018 02:00", hours, "Open till 24:00 (McDrive)", 1);
|
||||
|
||||
hours = parseOpenedHours("07:00-03:00 open \"Restaurant\" || 24/7 open \"McDrive\"");
|
||||
System.out.println(hours);
|
||||
testOpened("22.01.2018 02:00", hours, true);
|
||||
testOpened("22.01.2018 17:00", hours, true);
|
||||
testInfo("22.01.2018 05:00", hours, "Will open at 07:00 (Restaurant)", 0);
|
||||
testInfo("22.01.2018 04:00", hours, "Open 24/7 (McDrive)", 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
android:id="@+id/context_menu_layout"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/context_menu_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent"
|
||||
xmlns:osmand="http://schemas.android.com/apk/res-auto">
|
||||
android:background="@android:color/transparent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_main"
|
||||
|
@ -18,47 +18,47 @@
|
|||
android:id="@+id/context_menu_top_shadow_all"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:background="?attr/bg_map_context_menu"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_top_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingRight="@dimen/context_menu_padding_margin_default"
|
||||
android:orientation="horizontal">
|
||||
android:paddingRight="@dimen/context_menu_padding_margin_default">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginTop="@dimen/context_menu_first_line_top_margin"
|
||||
android:layout_marginRight="@dimen/context_menu_padding_margin_default"
|
||||
android:layout_marginEnd="@dimen/context_menu_padding_margin_default"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/context_menu_padding_margin_default"
|
||||
android:layout_marginRight="@dimen/context_menu_padding_margin_default"
|
||||
android:layout_marginTop="@dimen/context_menu_first_line_top_margin"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/context_menu_line1"
|
||||
style="@style/TextAppearance.ContextMenuTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/search_address_building"
|
||||
style="@style/TextAppearance.ContextMenuTitle"/>
|
||||
android:text="@string/search_address_building"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginTop="@dimen/context_menu_subtitle_margin"
|
||||
android:id="@+id/context_menu_line2_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/context_menu_subtitle_margin">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/context_menu_line2"
|
||||
style="@style/TextAppearance.ContextMenuSubtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/amenity_type_finance"
|
||||
style="@style/TextAppearance.ContextMenuSubtitle"/>
|
||||
android:text="@string/amenity_type_finance"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -80,40 +80,42 @@
|
|||
android:columnWidth="@dimen/context_menu_transport_grid_item_width"
|
||||
android:horizontalSpacing="@dimen/context_menu_transport_grid_spacing"
|
||||
android:numColumns="auto_fit"
|
||||
android:paddingBottom="@dimen/context_menu_transport_grid_spacing"
|
||||
android:paddingLeft="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingRight="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingTop="@dimen/context_menu_transport_padding_top"
|
||||
android:paddingBottom="@dimen/context_menu_transport_grid_spacing"
|
||||
android:verticalSpacing="@dimen/context_menu_transport_grid_spacing"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<LinearLayout
|
||||
android:paddingLeft="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingRight="@dimen/context_menu_padding_margin_default"
|
||||
android:layout_marginTop="@dimen/context_menu_padding_margin_tiny"
|
||||
android:layout_marginBottom="@dimen/context_menu_direction_margin"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/context_menu_sub_info_height"
|
||||
android:orientation="horizontal">
|
||||
android:layout_height= "wrap_content"
|
||||
android:layout_marginBottom="@dimen/context_menu_direction_margin"
|
||||
android:layout_marginTop="@dimen/context_menu_padding_margin_tiny"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="3dp"
|
||||
android:paddingBottom="3dp"
|
||||
android:paddingLeft="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingRight="@dimen/context_menu_padding_margin_default">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
||||
android:layout_marginEnd="@dimen/context_menu_padding_margin_small"
|
||||
tools:text="Museum"
|
||||
android:id="@+id/context_menu_line3"
|
||||
style="@style/TextAppearance.ContextMenuSubtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/context_menu_line3"
|
||||
android:layout_marginEnd="@dimen/context_menu_padding_margin_small"
|
||||
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
style="@style/TextAppearance.ContextMenuSubtitle"/>
|
||||
tools:text="Museum"/>
|
||||
|
||||
<TextView
|
||||
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
||||
android:layout_marginEnd="@dimen/context_menu_padding_margin_small"
|
||||
tools:text="Closed till 10:00"
|
||||
android:id="@+id/additional_info_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/context_menu_padding_margin_small"
|
||||
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
||||
tools:text="Closed till 10:00"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/compass_layout"
|
||||
|
@ -122,12 +124,12 @@
|
|||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
tools:src="@drawable/ic_direction_arrow"
|
||||
android:id="@+id/direction"
|
||||
android:layout_width="@dimen/directionIconSize"
|
||||
android:layout_height="@dimen/directionIconSize"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginTop="1sp"
|
||||
android:layout_gravity="center_vertical"/>
|
||||
tools:src="@drawable/ic_direction_arrow"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/distance"
|
||||
|
@ -136,9 +138,9 @@
|
|||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="2dp"
|
||||
android:layout_marginStart="2dp"
|
||||
tools:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="100500 km"/>
|
||||
tools:text="100500 km"
|
||||
tools:textColor="?android:textColorSecondary"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -155,17 +157,16 @@
|
|||
tools:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/title_button_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/context_menu_controller_height"
|
||||
android:layout_marginLeft="@dimen/context_menu_padding_margin_small"
|
||||
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
||||
android:id="@+id/title_button_view"
|
||||
tools:background="?attr/ctx_menu_controller_bg"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="@dimen/context_menu_controller_height"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
tools:background="?attr/ctx_menu_controller_bg">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:id="@+id/title_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -173,10 +174,11 @@
|
|||
android:gravity="center_vertical"
|
||||
android:paddingLeft="@dimen/context_menu_button_padding_x"
|
||||
android:paddingRight="@dimen/context_menu_button_padding_x"
|
||||
android:textAllCaps="true"
|
||||
android:text="@string/recording_context_menu_play"
|
||||
tools:textColor="?attr/ctx_menu_controller_text_color"
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
android:textAllCaps="true"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:textColor="?attr/ctx_menu_controller_text_color"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_button_right_text"
|
||||
|
@ -190,18 +192,16 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/title_button_right_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/context_menu_controller_height"
|
||||
android:layout_marginLeft="@dimen/context_menu_padding_margin_small"
|
||||
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
||||
android:id="@+id/title_button_right_view"
|
||||
tools:background="?attr/ctx_menu_controller_bg"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="@dimen/context_menu_controller_height"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
tools:background="?attr/ctx_menu_controller_bg">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:textAllCaps="true"
|
||||
android:id="@+id/title_button_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -210,8 +210,10 @@
|
|||
android:paddingLeft="@dimen/context_menu_button_padding_x"
|
||||
android:paddingRight="@dimen/context_menu_button_padding_x"
|
||||
android:text="@string/shared_string_delete"
|
||||
tools:textColor="?attr/ctx_menu_controller_text_color"
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
android:textAllCaps="true"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:textColor="?attr/ctx_menu_controller_text_color"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -229,16 +231,14 @@
|
|||
|
||||
<LinearLayout
|
||||
android:id="@+id/download_button_left_view"
|
||||
tools:background="?attr/ctx_menu_controller_bg"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/context_menu_controller_height"
|
||||
android:layout_marginLeft="@dimen/context_menu_padding_margin_small"
|
||||
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="@dimen/context_menu_controller_height">
|
||||
tools:background="?attr/ctx_menu_controller_bg">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:textAllCaps="true"
|
||||
android:id="@+id/download_button_left"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -247,23 +247,23 @@
|
|||
android:paddingLeft="@dimen/context_menu_button_padding_x"
|
||||
android:paddingRight="@dimen/context_menu_button_padding_x"
|
||||
android:text="@string/shared_string_download"
|
||||
tools:textColor="?attr/ctx_menu_controller_text_color"
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
android:textAllCaps="true"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:textColor="?attr/ctx_menu_controller_text_color"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/download_button_right_view"
|
||||
tools:background="?attr/ctx_menu_controller_bg"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/context_menu_controller_height"
|
||||
android:layout_marginLeft="@dimen/context_menu_padding_margin_small"
|
||||
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="@dimen/context_menu_controller_height">
|
||||
tools:background="?attr/ctx_menu_controller_bg">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:textAllCaps="true"
|
||||
android:id="@+id/download_button_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -272,8 +272,10 @@
|
|||
android:paddingLeft="@dimen/context_menu_button_padding_x"
|
||||
android:paddingRight="@dimen/context_menu_button_padding_x"
|
||||
android:text="@string/shared_string_others"
|
||||
tools:textColor="?attr/ctx_menu_controller_text_color"
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
android:textAllCaps="true"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:textColor="?attr/ctx_menu_controller_text_color"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -308,9 +310,9 @@
|
|||
android:paddingRight="@dimen/context_menu_button_padding_x"
|
||||
android:text="@string/shared_string_delete"
|
||||
android:textAllCaps="true"
|
||||
tools:textColor="?attr/ctx_menu_controller_text_color"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"/>
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
tools:textColor="?attr/ctx_menu_controller_text_color"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -325,10 +327,10 @@
|
|||
android:minHeight="@dimen/context_menu_action_buttons_h"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="@dimen/context_menu_padding_margin_small"
|
||||
android:paddingLeft="@dimen/context_menu_progress_padding_left"
|
||||
android:paddingStart="@dimen/context_menu_progress_padding_left"
|
||||
android:paddingRight="@dimen/context_menu_progress_padding_right"
|
||||
android:paddingEnd="@dimen/context_menu_progress_padding_right"
|
||||
android:paddingLeft="@dimen/context_menu_progress_padding_left"
|
||||
android:paddingRight="@dimen/context_menu_progress_padding_right"
|
||||
android:paddingStart="@dimen/context_menu_progress_padding_left"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
|
@ -364,11 +366,11 @@
|
|||
|
||||
<ImageView
|
||||
android:id="@+id/progressButton"
|
||||
android:contentDescription="@string/shared_string_close"
|
||||
android:layout_width="@dimen/context_menu_progress_cancel_button_size"
|
||||
android:layout_height="@dimen/context_menu_progress_cancel_button_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:contentDescription="@string/shared_string_close"
|
||||
android:scaleType="center"
|
||||
tools:src="@drawable/map_action_cancel"/>
|
||||
|
||||
|
@ -383,73 +385,73 @@
|
|||
android:background="?attr/ctx_menu_divider"/>
|
||||
|
||||
<LinearLayout
|
||||
android:paddingLeft="@dimen/map_widget_icon_margin"
|
||||
android:paddingRight="@dimen/map_widget_icon_margin"
|
||||
android:id="@+id/context_menu_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="@dimen/map_widget_icon_margin"
|
||||
android:paddingRight="@dimen/map_widget_icon_margin">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_fav_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:id="@+id/context_menu_fav_view"
|
||||
android:gravity="center"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/context_menu_main_actions_padding_top"
|
||||
android:paddingBottom="@dimen/context_menu_main_actions_padding_bottom">
|
||||
android:paddingBottom="@dimen/context_menu_main_actions_padding_bottom"
|
||||
android:paddingTop="@dimen/context_menu_main_actions_padding_top">
|
||||
|
||||
<ImageView
|
||||
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
|
||||
android:id="@+id/context_menu_fav_image_view"
|
||||
android:contentDescription="@string/shared_string_add_to_favorites"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
|
||||
android:contentDescription="@string/shared_string_add_to_favorites"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/map_action_fav_dark"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:id="@+id/context_menu_fav_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="@string/shared_string_add"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/ctx_menu_buttons_text_color"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_regular"/>
|
||||
osmand:typeface="@string/font_roboto_regular"
|
||||
tools:text="@string/shared_string_add"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_route_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:id="@+id/context_menu_route_view"
|
||||
android:gravity="center"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/context_menu_main_actions_padding_top"
|
||||
android:paddingBottom="@dimen/context_menu_main_actions_padding_bottom">
|
||||
android:paddingBottom="@dimen/context_menu_main_actions_padding_bottom"
|
||||
android:paddingTop="@dimen/context_menu_main_actions_padding_top">
|
||||
|
||||
<ImageView
|
||||
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
|
||||
android:id="@+id/context_menu_route_image_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/map_action_flag_dark"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:id="@+id/context_menu_route_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/shared_string_marker"
|
||||
android:textColor="@color/ctx_menu_buttons_text_color"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
|
@ -458,32 +460,32 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_share_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:id="@+id/context_menu_share_view"
|
||||
android:gravity="center"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/context_menu_main_actions_padding_top"
|
||||
android:paddingBottom="@dimen/context_menu_main_actions_padding_bottom">
|
||||
android:paddingBottom="@dimen/context_menu_main_actions_padding_bottom"
|
||||
android:paddingTop="@dimen/context_menu_main_actions_padding_top">
|
||||
|
||||
<ImageView
|
||||
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
|
||||
android:id="@+id/context_menu_share_image_view"
|
||||
android:contentDescription="@string/context_menu_item_share_location"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
|
||||
android:contentDescription="@string/context_menu_item_share_location"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/map_action_gshare_dark"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:id="@+id/context_menu_share_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/shared_string_share"
|
||||
android:textColor="@color/ctx_menu_buttons_text_color"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
|
@ -492,32 +494,32 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_more_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:id="@+id/context_menu_more_view"
|
||||
android:gravity="center"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/context_menu_main_actions_padding_top"
|
||||
android:paddingBottom="@dimen/context_menu_main_actions_padding_bottom">
|
||||
android:paddingBottom="@dimen/context_menu_main_actions_padding_bottom"
|
||||
android:paddingTop="@dimen/context_menu_main_actions_padding_top">
|
||||
|
||||
<ImageView
|
||||
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
|
||||
android:id="@+id/context_menu_more_image_view"
|
||||
android:contentDescription="@string/shared_string_more"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
|
||||
android:contentDescription="@string/shared_string_more"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/map_overflow_menu_white"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:id="@+id/context_menu_more_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/shared_string_actions"
|
||||
android:textColor="@color/ctx_menu_buttons_text_color"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
|
@ -539,35 +541,35 @@
|
|||
android:layout_height="@dimen/context_menu_buttons_bottom_height">
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:textAllCaps="true"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:id="@+id/context_menu_details_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingLeft="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingRight="@dimen/context_menu_padding_margin_default"
|
||||
android:gravity="start|center_vertical"
|
||||
android:layout_gravity="center_vertical"
|
||||
tools:textColor="?attr/contextMenuButtonColor"
|
||||
android:text="@string/description"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:text="@string/description"/>
|
||||
tools:textColor="?attr/contextMenuButtonColor"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:textAllCaps="true"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:id="@+id/context_menu_directions_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="end|center_vertical"
|
||||
android:paddingLeft="@dimen/context_menu_padding_margin_default"
|
||||
android:paddingRight="@dimen/context_menu_padding_margin_default"
|
||||
android:gravity="end|center_vertical"
|
||||
tools:textColor="?attr/contextMenuButtonColor"
|
||||
android:text="@string/get_directions"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:text="@string/get_directions"/>
|
||||
tools:textColor="?attr/contextMenuButtonColor"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -589,8 +591,8 @@
|
|||
android:id="@+id/context_menu_bottom_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:background="?attr/ctx_menu_info_view_bg"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
tools:background="?attr/ctx_menu_info_view_bg">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -610,8 +612,8 @@
|
|||
android:layout_width="@dimen/fab_size_with_shadow"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
android:gravity="center"
|
||||
android:layout_marginRight="@dimen/fab_margin_right"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
|
|
@ -9,6 +9,23 @@
|
|||
android:descendantFocusability="blocksDescendants"
|
||||
android:minHeight="50dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/info_move"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:clickable="false"
|
||||
android:contentDescription="@string/shared_string_more"
|
||||
android:focusable="false"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingStart="12dp"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_flat_list_dark"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/waypoint_icon"
|
||||
android:layout_width="56dp"
|
||||
|
@ -106,19 +123,4 @@
|
|||
android:scaleType="center"
|
||||
android:src="@drawable/ic_action_remove_dark"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/info_move"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:clickable="false"
|
||||
android:contentDescription="@string/shared_string_more"
|
||||
android:focusable="false"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_flat_list_dark"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
|
||||
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
|
||||
-->
|
||||
<string name="will_open_tomorrow_at">Will open tomorrow at</string>
|
||||
<string name="rendering_attr_hidePOILabels_name">POI labels</string>
|
||||
<string name="shared_string_without_name">Without name</string>
|
||||
<string name="what_is_here">What\'s here:</string>
|
||||
|
|
|
@ -47,6 +47,7 @@ import net.osmand.plus.voice.TTSCommandPlayerImpl;
|
|||
import net.osmand.render.RenderingRulesStorage;
|
||||
import net.osmand.router.RoutingConfiguration;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.OpeningHoursParser;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
|
@ -378,8 +379,21 @@ public class AppInitializer implements IProgress {
|
|||
app.mapMarkersDbHelper = startupInit(new MapMarkersDbHelper(app), MapMarkersDbHelper.class);
|
||||
app.mapMarkersHelper = startupInit(new MapMarkersHelper(app), MapMarkersHelper.class);
|
||||
app.searchUICore = startupInit(new QuickSearchHelper(app), QuickSearchHelper.class);
|
||||
|
||||
initOpeningHoursParser();
|
||||
}
|
||||
|
||||
private void initOpeningHoursParser() {
|
||||
OpeningHoursParser.setAdditionalString("off", app.getString(R.string.day_off_label));
|
||||
OpeningHoursParser.setAdditionalString("is_open", app.getString(R.string.poi_dialog_opening_hours));
|
||||
OpeningHoursParser.setAdditionalString("is_open_24_7", app.getString(R.string.shared_string_is_open_24_7));
|
||||
OpeningHoursParser.setAdditionalString("will_open_at", app.getString(R.string.will_open_at));
|
||||
OpeningHoursParser.setAdditionalString("open_from", app.getString(R.string.open_from));
|
||||
OpeningHoursParser.setAdditionalString("will_close_at", app.getString(R.string.will_close_at));
|
||||
OpeningHoursParser.setAdditionalString("open_till", app.getString(R.string.open_till));
|
||||
OpeningHoursParser.setAdditionalString("will_open_tomorrow_at", app.getString(R.string.will_open_tomorrow_at));
|
||||
OpeningHoursParser.setAdditionalString("will_open_on", app.getString(R.string.will_open_on));
|
||||
}
|
||||
|
||||
private void updateRegionVars() {
|
||||
app.regions.setTranslator(new RegionTranslation() {
|
||||
|
|
|
@ -55,6 +55,7 @@ import net.osmand.plus.OsmandApplication;
|
|||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.TargetPointsHelper;
|
||||
import net.osmand.plus.TargetPointsHelper.TargetPoint;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.dashboard.tools.DashFragmentData;
|
||||
|
@ -244,6 +245,10 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
|
|||
&& (visibleType == DashboardType.WAYPOINTS || visibleType == DashboardType.WAYPOINTS_FLAT)) {
|
||||
List<Object> activeObjects = ((StableArrayAdapter) listAdapter).getActiveObjects();
|
||||
Object obj = listAdapter.getItem(position);
|
||||
if (obj instanceof LocationPointWrapper) {
|
||||
LocationPointWrapper w = (LocationPointWrapper) obj;
|
||||
return !((TargetPoint) w.getPoint()).start;
|
||||
}
|
||||
return activeObjects.contains(obj);
|
||||
}
|
||||
return false;
|
||||
|
@ -287,10 +292,11 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
|
|||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
List<Object> activeObjects;
|
||||
if ((visibleType == DashboardType.WAYPOINTS || visibleType == DashboardType.WAYPOINTS_FLAT)
|
||||
&& (getMyApplication().getRoutingHelper().isRoutePlanningMode() || getMyApplication().getRoutingHelper().isFollowingMode())
|
||||
&& item != null
|
||||
&& stableAdapter.getActiveObjects().size() == 0) {
|
||||
&& ((activeObjects = stableAdapter.getActiveObjects()).isEmpty() || isContainsOnlyStart(activeObjects))) {
|
||||
return mapActivity.getResources().getString(R.string.cancel_navigation);
|
||||
} else {
|
||||
return null;
|
||||
|
@ -307,7 +313,8 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
|
|||
if (visibleType == DashboardType.WAYPOINTS || visibleType == DashboardType.WAYPOINTS_FLAT) {
|
||||
onItemsSwapped(stableAdapter.getActiveObjects());
|
||||
}
|
||||
if (stableAdapter.getActiveObjects().size() == 0) {
|
||||
List<Object> activeObjects = stableAdapter.getActiveObjects();
|
||||
if (activeObjects.isEmpty() || isContainsOnlyStart(activeObjects)) {
|
||||
hideDashboard();
|
||||
if (visibleType == DashboardType.WAYPOINTS || visibleType == DashboardType.WAYPOINTS_FLAT) {
|
||||
mapActivity.getMapActions().stopNavigationWithoutConfirm();
|
||||
|
@ -319,6 +326,17 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isContainsOnlyStart(List<Object> items) {
|
||||
if (items.size() == 1) {
|
||||
Object item = items.get(0);
|
||||
if (item instanceof LocationPointWrapper) {
|
||||
LocationPointWrapper w = (LocationPointWrapper) item;
|
||||
return ((TargetPoint) w.getPoint()).start;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
gradientToolbar = ContextCompat.getDrawable(mapActivity, R.drawable.gradient_toolbar).mutate();
|
||||
|
@ -1471,10 +1489,8 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
|
|||
LocationPointWrapper p = (LocationPointWrapper) obj;
|
||||
if (p.getPoint() instanceof TargetPoint) {
|
||||
TargetPoint t = (TargetPoint) p.getPoint();
|
||||
if (!t.start) {
|
||||
t.intermediate = true;
|
||||
allTargets.add(t);
|
||||
}
|
||||
t.intermediate = true;
|
||||
allTargets.add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1482,9 +1498,15 @@ public class DashboardOnMap implements ObservableScrollViewCallbacks, DynamicLis
|
|||
allTargets.get(allTargets.size() - 1).intermediate = false;
|
||||
}
|
||||
}
|
||||
getMyApplication().getTargetPointsHelper().reorderAllTargetPoints(allTargets, false);
|
||||
TargetPointsHelper targetPointsHelper = getMyApplication().getTargetPointsHelper();
|
||||
if (allTargets.size() > 0) {
|
||||
TargetPoint start = allTargets.remove(0);
|
||||
targetPointsHelper.setStartPoint(new LatLon(start.getLatitude(), start.getLongitude()),
|
||||
false, start.getPointDescription(getMyApplication()));
|
||||
}
|
||||
targetPointsHelper.reorderAllTargetPoints(allTargets, false);
|
||||
newRouteIsCalculated(false, new ValueHolder<Boolean>());
|
||||
getMyApplication().getTargetPointsHelper().updateRouteAndRefresh(true);
|
||||
targetPointsHelper.updateRouteAndRefresh(true);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ public class WaypointDialogHelper {
|
|||
for (Object p : points) {
|
||||
if (p instanceof LocationPointWrapper) {
|
||||
LocationPointWrapper w = (LocationPointWrapper) p;
|
||||
if (w.type == WaypointHelper.TARGETS && !((TargetPoint) w.point).start) {
|
||||
if (w.type == WaypointHelper.TARGETS) {
|
||||
activePoints.add(p);
|
||||
}
|
||||
}
|
||||
|
@ -222,31 +222,20 @@ public class WaypointDialogHelper {
|
|||
}
|
||||
|
||||
private List<Drawable> getCustomDividers(Context ctx, List<Object> points, boolean nightMode) {
|
||||
int color;
|
||||
int pointColor;
|
||||
if (nightMode) {
|
||||
color = ContextCompat.getColor(ctx, R.color.dashboard_divider_dark);
|
||||
pointColor = ContextCompat.getColor(ctx, R.color.dashboard_divider_dark);
|
||||
} else {
|
||||
color = ContextCompat.getColor(ctx, R.color.dashboard_divider_light);
|
||||
pointColor = ContextCompat.getColor(ctx, R.color.ctx_menu_info_divider_light);
|
||||
}
|
||||
int color = ContextCompat.getColor(ctx, nightMode
|
||||
? R.color.dashboard_divider_dark : R.color.dashboard_divider_light);
|
||||
|
||||
Shape fullDividerShape = new ListDividerShape(color, 0);
|
||||
Shape halfDividerShape = new ListDividerShape(color, AndroidUtils.dpToPx(ctx, 56f));
|
||||
Shape halfPointDividerShape = new ListDividerShape(color, AndroidUtils.dpToPx(ctx, 56f),
|
||||
pointColor, AndroidUtils.dpToPx(ctx, 1.5f), true);
|
||||
Shape headerDividerShape = new ListDividerShape(color, AndroidUtils.dpToPx(ctx, 16f));
|
||||
|
||||
final ShapeDrawable fullDivider = new ShapeDrawable(fullDividerShape);
|
||||
final ShapeDrawable halfDivider = new ShapeDrawable(halfDividerShape);
|
||||
final ShapeDrawable halfPointDivider = new ShapeDrawable(halfPointDividerShape);
|
||||
final ShapeDrawable headerDivider = new ShapeDrawable(headerDividerShape);
|
||||
|
||||
int divHeight = AndroidUtils.dpToPx(ctx, 1f);
|
||||
fullDivider.setIntrinsicHeight(divHeight);
|
||||
halfDivider.setIntrinsicHeight(divHeight);
|
||||
halfPointDivider.setIntrinsicHeight(divHeight);
|
||||
headerDivider.setIntrinsicHeight(divHeight);
|
||||
|
||||
List<Drawable> res = new ArrayList<>();
|
||||
|
@ -267,16 +256,7 @@ public class WaypointDialogHelper {
|
|||
Drawable d = null;
|
||||
|
||||
if (locationPointNext) {
|
||||
if (locationPoint) {
|
||||
LocationPointWrapper w = (LocationPointWrapper) obj;
|
||||
if (w.type == WaypointHelper.TARGETS) {
|
||||
d = halfPointDivider;
|
||||
} else {
|
||||
d = halfDivider;
|
||||
}
|
||||
} else {
|
||||
d = fullDivider;
|
||||
}
|
||||
d = locationPoint ? halfDivider : fullDivider;
|
||||
} else if (objNext instanceof RadiusItem && labelView) {
|
||||
d = headerDivider;
|
||||
} else if (locationPoint && !bottomDividerViewNext) {
|
||||
|
@ -398,108 +378,61 @@ public class WaypointDialogHelper {
|
|||
v = ctx.getLayoutInflater().inflate(R.layout.waypoint_reached, null);
|
||||
}
|
||||
updatePointInfoView(app, ctx, v, point, true, nightMode, edit, false);
|
||||
final View more = v.findViewById(R.id.all_points);
|
||||
final View move = v.findViewById(R.id.info_move);
|
||||
final View remove = v.findViewById(R.id.info_close);
|
||||
|
||||
v.findViewById(R.id.all_points).setVisibility(View.GONE);
|
||||
final ImageView move = (ImageView) v.findViewById(R.id.info_move);
|
||||
final ImageButton remove = (ImageButton) v.findViewById(R.id.info_close);
|
||||
|
||||
if (!edit) {
|
||||
remove.setVisibility(View.GONE);
|
||||
move.setVisibility(View.GONE);
|
||||
more.setVisibility(View.GONE);
|
||||
} else if (point.type == WaypointHelper.TARGETS && !flat) {
|
||||
if (((TargetPoint) point.point).start) {
|
||||
remove.setVisibility(View.GONE);
|
||||
move.setVisibility(View.GONE);
|
||||
more.setVisibility(View.GONE);
|
||||
} else {
|
||||
remove.setVisibility(View.GONE);
|
||||
move.setVisibility(View.VISIBLE);
|
||||
more.setVisibility(View.GONE);
|
||||
((ImageView) move).setImageDrawable(app.getIconsCache().getIcon(
|
||||
R.drawable.ic_action_reorder, !nightMode));
|
||||
if (app.accessibilityEnabled()) {
|
||||
move.setOnClickListener(new View.OnClickListener() {
|
||||
} else {
|
||||
boolean notFlatTargets = point.type == WaypointHelper.TARGETS && !flat;
|
||||
boolean startPoint = ((TargetPoint) point.point).start;
|
||||
final TargetPointsHelper targetPointsHelper = app.getTargetPointsHelper();
|
||||
boolean canRemove = !targetPointsHelper.getIntermediatePoints().isEmpty();
|
||||
|
||||
remove.setVisibility(View.VISIBLE);
|
||||
remove.setImageDrawable(app.getIconsCache().getIcon(R.drawable.ic_action_remove_dark, !nightMode));
|
||||
remove.setEnabled(canRemove);
|
||||
remove.setAlpha(canRemove ? 1 : .5f);
|
||||
if (canRemove) {
|
||||
if (notFlatTargets && startPoint) {
|
||||
remove.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
((DragIcon) view.getTag()).onClick();
|
||||
public void onClick(View v) {
|
||||
if (targetPointsHelper.getPointToStart() == null) {
|
||||
if (!targetPointsHelper.getIntermediatePoints().isEmpty()) {
|
||||
replaceStartWithFirstIntermediate(targetPointsHelper, ctx, helper);
|
||||
}
|
||||
} else {
|
||||
targetPointsHelper.setStartPoint(null, true, null);
|
||||
updateControls(ctx, helper);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
remove.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
deletePoint(app, ctx, adapter, helper, point, deletedPoints, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
move.setVisibility(notFlatTargets ? View.VISIBLE : View.GONE);
|
||||
if (notFlatTargets) {
|
||||
move.setImageDrawable(app.getIconsCache().getIcon(R.drawable.ic_action_reorder, !nightMode));
|
||||
move.setTag(new DragIcon() {
|
||||
@Override
|
||||
public void onClick() {
|
||||
final PopupMenu optionsMenu = new PopupMenu(ctx, move);
|
||||
DirectionsDialogs.setupPopUpMenuIcon(optionsMenu);
|
||||
List<Object> activeObjects = ((StableArrayAdapter) adapter).getActiveObjects();
|
||||
int count = activeObjects.size();
|
||||
int t = -1;
|
||||
for (int i = 0; i < activeObjects.size(); i++) {
|
||||
Object o = activeObjects.get(i);
|
||||
if (point == o) {
|
||||
t = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
final int index = t;
|
||||
MenuItem item;
|
||||
final TargetPointsHelper targetPointsHelper = app.getTargetPointsHelper();
|
||||
final TargetPoint start = targetPointsHelper.getPointToStart();
|
||||
if (count > 1 && (index > 0 || start != null)) {
|
||||
item = optionsMenu.getMenu().add(R.string.shared_string_move_up)
|
||||
.setIcon(app.getIconsCache().getThemedIcon(R.drawable.ic_action_arrow_drop_up));
|
||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (index == 0) {
|
||||
switchStartAndFirstIntermediate(targetPointsHelper, ctx, start, helper);
|
||||
} else if (helper != null && helper.helperCallbacks != null) {
|
||||
helper.helperCallbacks.exchangeWaypoints(index, index - 1);
|
||||
}
|
||||
updateRouteInfoMenu(ctx);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (index < count - 1 && count > 1) {
|
||||
item = optionsMenu.getMenu().add(R.string.shared_string_move_down)
|
||||
.setIcon(app.getIconsCache().getThemedIcon(R.drawable.ic_action_arrow_drop_down));
|
||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
if (helper != null && helper.helperCallbacks != null) {
|
||||
helper.helperCallbacks.exchangeWaypoints(index, index + 1);
|
||||
}
|
||||
updateRouteInfoMenu(ctx);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
item = optionsMenu.getMenu().add(R.string.shared_string_remove)
|
||||
.setIcon(app.getIconsCache().getThemedIcon(R.drawable.ic_action_remove_dark));
|
||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
deletePoint(app, ctx, adapter, helper, point, deletedPoints, true);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
optionsMenu.show();
|
||||
// do nothing
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
remove.setVisibility(View.VISIBLE);
|
||||
move.setVisibility(View.GONE);
|
||||
more.setVisibility(View.GONE);
|
||||
((ImageButton) remove).setImageDrawable(app.getIconsCache().getIcon(
|
||||
R.drawable.ic_action_remove_dark, !nightMode));
|
||||
remove.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
deletePoint(app, ctx, adapter, helper, point, deletedPoints, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -535,6 +468,17 @@ public class WaypointDialogHelper {
|
|||
updateRouteInfoMenu(ctx);
|
||||
}
|
||||
|
||||
private static void replaceStartWithFirstIntermediate(TargetPointsHelper targetPointsHelper, Activity ctx,
|
||||
WaypointDialogHelper helper) {
|
||||
List<TargetPoint> intermediatePoints = targetPointsHelper.getIntermediatePointsWithTarget();
|
||||
TargetPoint firstIntermediate = intermediatePoints.remove(0);
|
||||
targetPointsHelper.setStartPoint(new LatLon(firstIntermediate.getLatitude(),
|
||||
firstIntermediate.getLongitude()), false, firstIntermediate.getPointDescription(ctx));
|
||||
targetPointsHelper.reorderAllTargetPoints(intermediatePoints, true);
|
||||
|
||||
updateControls(ctx, helper);
|
||||
}
|
||||
|
||||
// switch start & first intermediate point
|
||||
private static void switchStartAndFirstIntermediate(TargetPointsHelper targetPointsHelper, Activity ctx,
|
||||
TargetPoint start, WaypointDialogHelper helper) {
|
||||
|
@ -675,7 +619,20 @@ public class WaypointDialogHelper {
|
|||
public void onClick(View v) {
|
||||
boolean hasActivePoints = false;
|
||||
if (thisAdapter instanceof StableArrayAdapter) {
|
||||
hasActivePoints = ((StableArrayAdapter) thisAdapter).getActiveObjects().size() > 0;
|
||||
List<Object> items = ((StableArrayAdapter) thisAdapter).getActiveObjects();
|
||||
if (items.size() > 0) {
|
||||
if (items.size() > 1) {
|
||||
hasActivePoints = true;
|
||||
} else {
|
||||
Object item = items.get(0);
|
||||
if (item instanceof LocationPointWrapper) {
|
||||
LocationPointWrapper w = (LocationPointWrapper) item;
|
||||
hasActivePoints = !((TargetPoint) w.point).start;
|
||||
} else {
|
||||
hasActivePoints = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final PopupMenu optionsMenu = new PopupMenu(ctx, moreBtn);
|
||||
|
|
|
@ -1175,7 +1175,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
|
|||
return 0;
|
||||
}
|
||||
|
||||
public String getAdditionalInfo() {
|
||||
public CharSequence getAdditionalInfo() {
|
||||
if (menuController != null) {
|
||||
return menuController.getAdditionalInfoStr();
|
||||
}
|
||||
|
|
|
@ -1196,7 +1196,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
|
|||
}
|
||||
|
||||
TextView additionalInfoTextView = (TextView) view.findViewById(R.id.additional_info_text_view);
|
||||
String additionalInfoStr = menu.getAdditionalInfo();
|
||||
CharSequence additionalInfoStr = menu.getAdditionalInfo();
|
||||
if (!TextUtils.isEmpty(additionalInfoStr)) {
|
||||
int colorId = menu.getAdditionalInfoColor();
|
||||
int additionalInfoIconRes = menu.getAdditionalInfoIconRes();
|
||||
|
|
|
@ -8,6 +8,8 @@ import android.support.annotation.DrawableRes;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.LinearLayout;
|
||||
|
@ -29,9 +31,7 @@ import net.osmand.map.WorldRegion;
|
|||
import net.osmand.plus.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
|
||||
import net.osmand.plus.MapMarkersHelper.MapMarker;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.TargetPointsHelper.TargetPoint;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
|
@ -74,6 +74,7 @@ import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControll
|
|||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
import net.osmand.util.OpeningHoursParser.OpeningHours;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
@ -117,6 +118,8 @@ public abstract class MenuController extends BaseMenuController {
|
|||
private WorldRegion downloadRegion;
|
||||
private DownloadIndexesThread downloadThread;
|
||||
|
||||
protected List<OpeningHours.Info> openingHoursInfo;
|
||||
|
||||
public MenuController(MenuBuilder builder, PointDescription pointDescription, MapActivity mapActivity) {
|
||||
super(mapActivity);
|
||||
this.pointDescription = pointDescription;
|
||||
|
@ -243,12 +246,8 @@ public abstract class MenuController extends BaseMenuController {
|
|||
}
|
||||
|
||||
protected void addMyLocationToPlainItems(LatLon latLon) {
|
||||
OsmandSettings st = ((OsmandApplication) getMapActivity().getApplicationContext()).getSettings();
|
||||
addPlainMenuItem(R.drawable.ic_action_get_my_location, null, PointDescription.getLocationName(getMapActivity(),
|
||||
latLon.getLatitude(), latLon.getLongitude(), true).replaceAll("\n", " "), false, false, null);
|
||||
//if (st.COORDINATES_FORMAT.get() != PointDescription.OLC_FORMAT)
|
||||
// addPlainMenuItem(R.drawable.ic_action_get_my_location, PointDescription.getLocationOlcName(
|
||||
// latLon.getLatitude(), latLon.getLongitude()).replaceAll("\n", " "), false, false, null);
|
||||
}
|
||||
|
||||
public PointDescription getPointDescription() {
|
||||
|
@ -442,21 +441,47 @@ public abstract class MenuController extends BaseMenuController {
|
|||
}
|
||||
|
||||
public int getAdditionalInfoColor() {
|
||||
if (indexItem != null) {
|
||||
if (openingHoursInfo != null) {
|
||||
return 0;
|
||||
} else if (indexItem != null) {
|
||||
return R.color.icon_color;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getAdditionalInfoStr() {
|
||||
if (indexItem != null) {
|
||||
public CharSequence getAdditionalInfoStr() {
|
||||
if (openingHoursInfo != null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int colorOpen = getMapActivity().getResources().getColor(R.color.ctx_menu_amenity_opened_text_color);
|
||||
int colorClosed = getMapActivity().getResources().getColor(R.color.ctx_menu_amenity_closed_text_color);
|
||||
int[] pos = new int[openingHoursInfo.size()];
|
||||
for (int i = 0; i < openingHoursInfo.size(); i++) {
|
||||
OpeningHours.Info info = openingHoursInfo.get(i);
|
||||
if (sb.length() > 0) {
|
||||
sb.append("\n");
|
||||
}
|
||||
sb.append(info.getInfo());
|
||||
pos[i] = sb.length();
|
||||
}
|
||||
SpannableString infoStr = new SpannableString(sb.toString());
|
||||
int k = 0;
|
||||
for (int i = 0; i < openingHoursInfo.size(); i++) {
|
||||
OpeningHours.Info info = openingHoursInfo.get(i);
|
||||
infoStr.setSpan(new ForegroundColorSpan(info.isOpened() ? colorOpen : colorClosed), k, pos[i], 0);
|
||||
k = pos[i];
|
||||
}
|
||||
return infoStr;
|
||||
|
||||
} else if (indexItem != null) {
|
||||
return getMapActivity().getString(R.string.file_size_in_mb, indexItem.getArchiveSizeMB());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public int getAdditionalInfoIconRes() {
|
||||
if (indexItem != null) {
|
||||
if (openingHoursInfo != null) {
|
||||
return R.drawable.ic_action_opening_hour_16;
|
||||
} else if (indexItem != null) {
|
||||
return R.drawable.ic_sdcard_16;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
package net.osmand.plus.mapcontextmenu;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class OpeningHoursInfo {
|
||||
|
||||
private boolean opened;
|
||||
private boolean opened24_7;
|
||||
private String openingTime = "";
|
||||
private String nearToOpeningTime = "";
|
||||
private String closingTime = "";
|
||||
private String nearToClosingTime = "";
|
||||
private String openingDay = "";
|
||||
|
||||
public boolean isOpened() {
|
||||
return opened;
|
||||
}
|
||||
|
||||
public void setOpened(boolean opened) {
|
||||
this.opened = opened;
|
||||
}
|
||||
|
||||
public boolean isOpened24_7() {
|
||||
return opened24_7;
|
||||
}
|
||||
|
||||
public void setOpened24_7(boolean opened24_7) {
|
||||
this.opened24_7 = opened24_7;
|
||||
}
|
||||
|
||||
public String getOpeningTime() {
|
||||
return openingTime;
|
||||
}
|
||||
|
||||
public void setOpeningTime(String openFromTime) {
|
||||
this.openingTime = openFromTime;
|
||||
}
|
||||
|
||||
public String getNearToOpeningTime() {
|
||||
return nearToOpeningTime;
|
||||
}
|
||||
|
||||
public void setNearToOpeningTime(String nearToOpeningTime) {
|
||||
this.nearToOpeningTime = nearToOpeningTime;
|
||||
}
|
||||
|
||||
public String getClosingTime() {
|
||||
return closingTime;
|
||||
}
|
||||
|
||||
public void setClosingTime(String closingTime) {
|
||||
this.closingTime = closingTime;
|
||||
}
|
||||
|
||||
public String getNearToClosingTime() {
|
||||
return nearToClosingTime;
|
||||
}
|
||||
|
||||
public void setNearToClosingTime(String nearToClosingTime) {
|
||||
this.nearToClosingTime = nearToClosingTime;
|
||||
}
|
||||
|
||||
public String getOpeningDay() {
|
||||
return openingDay;
|
||||
}
|
||||
|
||||
public void setOpeningDay(String openingDay) {
|
||||
this.openingDay = openingDay;
|
||||
}
|
||||
|
||||
public String getInfo(Context context) {
|
||||
if (isOpened24_7()) {
|
||||
return context.getString(R.string.shared_string_is_open_24_7);
|
||||
} else if (!Algorithms.isEmpty(getNearToOpeningTime())) {
|
||||
return context.getString(R.string.will_open_at) + " " + getNearToOpeningTime();
|
||||
} else if (!Algorithms.isEmpty(getOpeningTime())) {
|
||||
return context.getString(R.string.open_from) + " " + getOpeningTime();
|
||||
} else if (!Algorithms.isEmpty(getNearToClosingTime())) {
|
||||
return context.getString(R.string.will_close_at) + " " + getNearToClosingTime();
|
||||
} else if (!Algorithms.isEmpty(getClosingTime())) {
|
||||
return context.getString(R.string.open_till) + " " + getClosingTime();
|
||||
} else if (!Algorithms.isEmpty(getOpeningDay())) {
|
||||
return context.getString(R.string.will_open_on) + " " + getOpeningDay() + ".";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
|
@ -529,11 +529,6 @@ public class AmenityMenuBuilder extends MenuBuilder {
|
|||
buildRow(view, R.drawable.ic_action_get_my_location, null, PointDescription.getLocationName(app,
|
||||
amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(), true)
|
||||
.replaceAll("\n", " "), 0, false, null, false, 0, false, null, false);
|
||||
//if (st.COORDINATES_FORMAT.get() != PointDescription.OLC_FORMAT)
|
||||
// buildRow(view, R.drawable.ic_action_get_my_location, PointDescription.getLocationOlcName(
|
||||
// amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude())
|
||||
// .replaceAll("\n", " "), 0, false, null, false, 0, false, null);
|
||||
|
||||
}
|
||||
|
||||
public void buildAmenityRow(View view, AmenityInfoRow info) {
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
package net.osmand.plus.mapcontextmenu.builders;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.FavouritePoint;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.PointDescription;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.data.TransportStop;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
|
@ -19,7 +14,6 @@ import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
|
|||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.mapcontextmenu.MenuBuilder;
|
||||
import net.osmand.plus.widgets.TextViewEx;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -36,7 +30,7 @@ public class FavouritePointMenuBuilder extends MenuBuilder {
|
|||
acquireOriginObject();
|
||||
}
|
||||
|
||||
public void acquireOriginObject()
|
||||
private void acquireOriginObject()
|
||||
{
|
||||
String originObjectName = fav.getOriginObjectName();
|
||||
if (originObjectName.length() > 0) {
|
||||
|
|
|
@ -14,19 +14,17 @@ import net.osmand.plus.R;
|
|||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.mapcontextmenu.MenuBuilder;
|
||||
import net.osmand.plus.mapcontextmenu.MenuController;
|
||||
import net.osmand.plus.mapcontextmenu.OpeningHoursInfo;
|
||||
import net.osmand.plus.mapcontextmenu.WikipediaDialogFragment;
|
||||
import net.osmand.plus.mapcontextmenu.builders.AmenityMenuBuilder;
|
||||
import net.osmand.plus.transport.TransportStopRoute;
|
||||
import net.osmand.plus.render.RenderingIcons;
|
||||
import net.osmand.plus.resources.TransportIndexRepository;
|
||||
import net.osmand.plus.transport.TransportStopRoute;
|
||||
import net.osmand.plus.transport.TransportStopType;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
import net.osmand.util.OpeningHoursParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
@ -36,7 +34,6 @@ public class AmenityMenuController extends MenuController {
|
|||
|
||||
private Amenity amenity;
|
||||
private List<TransportStopRoute> routes = new ArrayList<>();
|
||||
private OpeningHoursInfo openingHoursInfo;
|
||||
|
||||
private MapMarker marker;
|
||||
|
||||
|
@ -77,7 +74,7 @@ public class AmenityMenuController extends MenuController {
|
|||
leftTitleButtonController.updateStateListDrawableIcon(R.drawable.ic_action_read_text, true);
|
||||
}
|
||||
|
||||
openingHoursInfo = processOpeningHours(amenity);
|
||||
openingHoursInfo = OpeningHoursParser.getInfo(amenity.getOpeningHours());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -146,30 +143,6 @@ public class AmenityMenuController extends MenuController {
|
|||
return getTypeStr(amenity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAdditionalInfoColor() {
|
||||
if (openingHoursInfo != null) {
|
||||
return openingHoursInfo.isOpened() ? R.color.ctx_menu_amenity_opened_text_color : R.color.ctx_menu_amenity_closed_text_color;
|
||||
}
|
||||
return super.getAdditionalInfoColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAdditionalInfoStr() {
|
||||
if (openingHoursInfo != null) {
|
||||
return openingHoursInfo.getInfo(getMapActivity());
|
||||
}
|
||||
return super.getAdditionalInfoStr();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAdditionalInfoIconRes() {
|
||||
if (openingHoursInfo != null) {
|
||||
return R.drawable.ic_action_opening_hour_16;
|
||||
}
|
||||
return super.getAdditionalInfoIconRes();
|
||||
}
|
||||
|
||||
public static String getTypeStr(Amenity amenity) {
|
||||
PoiCategory pc = amenity.getType();
|
||||
PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType());
|
||||
|
@ -182,28 +155,6 @@ public class AmenityMenuController extends MenuController {
|
|||
return typeStr;
|
||||
}
|
||||
|
||||
public static OpeningHoursInfo processOpeningHours(Amenity amenity) {
|
||||
OpeningHoursParser.OpeningHours openingHours = OpeningHoursParser.parseOpenedHours(amenity.getOpeningHours());
|
||||
if (openingHours == null) {
|
||||
return null;
|
||||
} else {
|
||||
OpeningHoursInfo info = new OpeningHoursInfo();
|
||||
Calendar cal = Calendar.getInstance();
|
||||
boolean opened = openingHours.isOpenedForTime(cal);
|
||||
info.setOpened(opened);
|
||||
if (opened) {
|
||||
info.setOpened24_7(openingHours.isOpened24_7());
|
||||
info.setClosingTime(openingHours.getClosingTime(cal));
|
||||
info.setNearToClosingTime(openingHours.getNearToClosingTime(cal));
|
||||
} else {
|
||||
info.setOpeningTime(openingHours.getOpeningTime(cal));
|
||||
info.setNearToOpeningTime(openingHours.getNearToOpeningTime(cal));
|
||||
info.setOpeningDay(openingHours.getOpeningDay(cal));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommonTypeStr() {
|
||||
PoiCategory pc = amenity.getType();
|
||||
|
@ -219,7 +170,8 @@ public class AmenityMenuController extends MenuController {
|
|||
public void addPlainMenuItems(String typeStr, PointDescription pointDescription, LatLon latLon) {
|
||||
}
|
||||
|
||||
public static void addPlainMenuItems(Amenity amenity, String typeStr, MenuBuilder builder) {
|
||||
public static void addTypeMenuItem(Amenity amenity, MenuBuilder builder) {
|
||||
String typeStr = getTypeStr(amenity);
|
||||
if (!Algorithms.isEmpty(typeStr)) {
|
||||
int resId = getRightIconId(amenity);
|
||||
if (resId == 0) {
|
||||
|
|
|
@ -14,12 +14,12 @@ import net.osmand.plus.R;
|
|||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.base.FavoriteImageDrawable;
|
||||
import net.osmand.plus.mapcontextmenu.MenuController;
|
||||
import net.osmand.plus.mapcontextmenu.OpeningHoursInfo;
|
||||
import net.osmand.plus.mapcontextmenu.builders.FavouritePointMenuBuilder;
|
||||
import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditor;
|
||||
import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditorFragment;
|
||||
import net.osmand.plus.transport.TransportStopRoute;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.OpeningHoursParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -29,7 +29,6 @@ public class FavouritePointMenuController extends MenuController {
|
|||
private FavouritePoint fav;
|
||||
private MapMarker mapMarker;
|
||||
private List<TransportStopRoute> routes = new ArrayList<>();
|
||||
private OpeningHoursInfo openingHoursInfo;
|
||||
|
||||
public FavouritePointMenuController(MapActivity mapActivity, PointDescription pointDescription, final FavouritePoint fav) {
|
||||
super(new FavouritePointMenuBuilder(mapActivity, fav), pointDescription, mapActivity);
|
||||
|
@ -55,7 +54,7 @@ public class FavouritePointMenuController extends MenuController {
|
|||
|
||||
Object originObject = getBuilder().getOriginObject();
|
||||
if (originObject instanceof Amenity) {
|
||||
openingHoursInfo = AmenityMenuController.processOpeningHours((Amenity) originObject);
|
||||
openingHoursInfo = OpeningHoursParser.getInfo(((Amenity) originObject).getOpeningHours());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,35 +143,10 @@ public class FavouritePointMenuController extends MenuController {
|
|||
Object originObject = getBuilder().getOriginObject();
|
||||
if (originObject != null) {
|
||||
if (originObject instanceof Amenity) {
|
||||
Amenity amenity = (Amenity) originObject;
|
||||
AmenityMenuController.addPlainMenuItems(amenity, AmenityMenuController.getTypeStr(amenity), builder);
|
||||
AmenityMenuController.addTypeMenuItem((Amenity) originObject, builder);
|
||||
}
|
||||
} else {
|
||||
addMyLocationToPlainItems(latLon);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAdditionalInfoColor() {
|
||||
if (openingHoursInfo != null) {
|
||||
return openingHoursInfo.isOpened() ? R.color.ctx_menu_amenity_opened_text_color : R.color.ctx_menu_amenity_closed_text_color;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAdditionalInfoStr() {
|
||||
if (openingHoursInfo != null) {
|
||||
return openingHoursInfo.getInfo(getMapActivity());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAdditionalInfoIconRes() {
|
||||
if (openingHoursInfo != null) {
|
||||
return R.drawable.ic_action_opening_hour_16;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,7 +190,7 @@ public class MapDataMenuController extends MenuController {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getAdditionalInfoStr() {
|
||||
public CharSequence getAdditionalInfoStr() {
|
||||
double mb = 0;
|
||||
if (backuped) {
|
||||
if (localIndexInfo != null) {
|
||||
|
|
|
@ -131,7 +131,7 @@ public class EditPOIMenuController extends MenuController {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getAdditionalInfoStr() {
|
||||
public CharSequence getAdditionalInfoStr() {
|
||||
return actionStr;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ public class ParkingPositionMenuController extends MenuController {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getAdditionalInfoStr() {
|
||||
public CharSequence getAdditionalInfoStr() {
|
||||
return parkingLeftDescription;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue