Fix opening hours parser (added || handling)

This commit is contained in:
Alexey Kulish 2018-01-25 18:53:38 +03:00
parent a2b0790565
commit fc704a7005
15 changed files with 670 additions and 476 deletions

View file

@ -8,9 +8,11 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Set; import java.util.Set;
import gnu.trove.list.array.TIntArrayList; import gnu.trove.list.array.TIntArrayList;
@ -27,6 +29,7 @@ public class OpeningHoursParser {
private static final String[] localDaysStr; private static final String[] localDaysStr;
private static final String[] monthsStr; private static final String[] monthsStr;
private static final String[] localMothsStr; 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 LOW_TIME_LIMIT = 120;
private static final int WITHOUT_TIME_LIMIT = -1; private static final int WITHOUT_TIME_LIMIT = -1;
@ -39,6 +42,23 @@ public class OpeningHoursParser {
dateFormatSymbols = DateFormatSymbols.getInstance(); dateFormatSymbols = DateFormatSymbols.getInstance();
localMothsStr = dateFormatSymbols.getShortMonths(); localMothsStr = dateFormatSymbols.getShortMonths();
localDaysStr = getTwoLettersStringArray(dateFormatSymbols.getShortWeekdays()); 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 class OpeningHours implements Serializable {
public static final int ALL_SEQUENCES = -1;
/** /**
* list of the different rules * list of the different rules
*/ */
private ArrayList<OpeningHoursRule> rules; private ArrayList<OpeningHoursRule> rules;
private String original; 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 * Constructor
@ -111,6 +181,45 @@ public class OpeningHoursParser {
rules = new ArrayList<OpeningHoursRule>(); 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 * add a rule to the opening hours
* *
@ -125,10 +234,18 @@ public class OpeningHoursParser {
* *
* @param rules to add * @param rules to add
*/ */
public void addRules(List<OpeningHoursRule> rules) { public void addRules(List<? extends OpeningHoursRule> rules) {
this.rules.addAll(rules); this.rules.addAll(rules);
} }
public int getSequenceCount() {
return sequenceCount;
}
public void setSequenceCount(int sequenceCount) {
this.sequenceCount = sequenceCount;
}
/** /**
* return the list of rules * return the list of rules
* *
@ -138,31 +255,46 @@ public class OpeningHoursParser {
return rules; 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" * check if the feature is opened at time "cal"
* *
* @param cal the time to check * @param cal the time to check
* @return true if feature is open * @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. // make exception for overlapping times i.e.
// (1) Mo 14:00-16:00; Tu off // (1) Mo 14:00-16:00; Tu off
// (2) Mo 14:00-02: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 // in (2) we need to check first rule even though it is against specification
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
boolean overlap = false; 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); OpeningHoursRule r = rules.get(i);
if(r.hasOverlapTimes()) { if (r.hasOverlapTimes()) {
overlap = true; overlap = true;
break; break;
} }
} }
// start from the most specific rule // 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); OpeningHoursRule r = rules.get(i);
if(r.contains(cal)) { if (r.contains(cal)) {
boolean open = r.isOpenedForTime(cal); boolean open = r.isOpenedForTime(cal);
if(!open && overlap ) { if (!open && overlap ) {
continue; continue;
} else { } else {
return open; return open;
@ -179,12 +311,24 @@ public class OpeningHoursParser {
* @return true if feature is open * @return true if feature is open
*/ */
public boolean isOpenedForTime(Calendar cal) { 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 * first check for rules that contain the current day
* afterwards check for rules that contain the previous * afterwards check for rules that contain the previous
* day with overlapping times (times after midnight) * day with overlapping times (times after midnight)
*/ */
boolean isOpenDay = false; boolean isOpenDay = false;
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
for (OpeningHoursRule r : rules) { for (OpeningHoursRule r : rules) {
if (r.containsDay(cal) && r.containsMonth(cal)) { if (r.containsDay(cal) && r.containsMonth(cal)) {
isOpenDay = r.isOpenedForTime(cal, false); isOpenDay = r.isOpenedForTime(cal, false);
@ -199,33 +343,48 @@ public class OpeningHoursParser {
return isOpenDay || isOpenPrevious; return isOpenDay || isOpenPrevious;
} }
public boolean isOpened24_7() { public boolean isOpened24_7(int sequenceIndex) {
boolean opened24_7 = false; boolean opened24_7 = false;
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
for (OpeningHoursRule r : rules) { for (OpeningHoursRule r : rules) {
opened24_7 = r.isOpened24_7(); opened24_7 = r.isOpened24_7();
} }
return opened24_7; return opened24_7;
} }
public String getNearToOpeningTime(Calendar cal) { public String getNearToOpeningTime(Calendar cal, int sequenceIndex) {
return getTime(cal, LOW_TIME_LIMIT, true); return getTime(cal, LOW_TIME_LIMIT, true, sequenceIndex);
} }
public String getOpeningTime(Calendar cal) { public String getOpeningTime(Calendar cal, int sequenceIndex) {
return getTime(cal, CURRENT_DAY_TIME_LIMIT, true); return getTime(cal, CURRENT_DAY_TIME_LIMIT, true, sequenceIndex);
} }
public String getNearToClosingTime(Calendar cal) { public String getNearToClosingTime(Calendar cal, int sequenceIndex) {
return getTime(cal, LOW_TIME_LIMIT, false); return getTime(cal, LOW_TIME_LIMIT, false, sequenceIndex);
} }
public String getClosingTime(Calendar cal) { public String getClosingTime(Calendar cal, int sequenceIndex) {
return getTime(cal, WITHOUT_TIME_LIMIT, false); 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(); Calendar cal = (Calendar) calendar.clone();
String openingTime = ""; 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++) { for (int i = 0; i < 7; i++) {
cal.add(Calendar.DAY_OF_MONTH, 1); cal.add(Calendar.DAY_OF_MONTH, 1);
for (OpeningHoursRule r : rules) { for (OpeningHoursRule r : rules) {
@ -241,16 +400,17 @@ public class OpeningHoursParser {
return openingTime; return openingTime;
} }
private String getTime(Calendar cal, int limit, boolean opening) { private String getTime(Calendar cal, int limit, boolean opening, int sequenceIndex) {
String time = getTimeDay(cal, limit, opening); String time = getTimeDay(cal, limit, opening, sequenceIndex);
if (Algorithms.isEmpty(time)) { if (Algorithms.isEmpty(time)) {
time = getTimeAnotherDay(cal, limit, opening); time = getTimeAnotherDay(cal, limit, opening, sequenceIndex);
} }
return time; return time;
} }
private String getTimeDay(Calendar cal, int limit, boolean opening) { private String getTimeDay(Calendar cal, int limit, boolean opening, int sequenceIndex) {
String atTime = ""; String atTime = "";
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
for (OpeningHoursRule r : rules) { for (OpeningHoursRule r : rules) {
if (r.containsDay(cal) && r.containsMonth(cal)) { if (r.containsDay(cal) && r.containsMonth(cal)) {
atTime = r.getTime(cal, false, limit, opening); atTime = r.getTime(cal, false, limit, opening);
@ -259,8 +419,9 @@ public class OpeningHoursParser {
return atTime; return atTime;
} }
private String getTimeAnotherDay(Calendar cal, int limit, boolean opening) { private String getTimeAnotherDay(Calendar cal, int limit, boolean opening, int sequenceIndex) {
String atTime = ""; String atTime = "";
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
for (OpeningHoursRule r : rules) { for (OpeningHoursRule r : rules) {
if (((opening && r.containsPreviousDay(cal)) || (!opening && r.containsNextDay(cal))) && r.containsMonth(cal)) { if (((opening && r.containsPreviousDay(cal)) || (!opening && r.containsNextDay(cal))) && r.containsMonth(cal)) {
atTime = r.getTime(cal, true, limit, opening); atTime = r.getTime(cal, true, limit, opening);
@ -270,10 +431,15 @@ public class OpeningHoursParser {
} }
public String getCurrentRuleTime(Calendar cal) { public String getCurrentRuleTime(Calendar cal) {
return getCurrentRuleTime(cal, ALL_SEQUENCES);
}
public String getCurrentRuleTime(Calendar cal, int sequenceIndex) {
// make exception for overlapping times i.e. // make exception for overlapping times i.e.
// (1) Mo 14:00-16:00; Tu off // (1) Mo 14:00-16:00; Tu off
// (2) Mo 14:00-02: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 // in (2) we need to check first rule even though it is against specification
ArrayList<OpeningHoursRule> rules = getRules(sequenceIndex);
String ruleClosed = null; String ruleClosed = null;
boolean overlap = false; boolean overlap = false;
for (int i = rules.size() - 1; i >= 0; i--) { for (int i = rules.size() - 1; i >= 0; i--) {
@ -428,6 +594,7 @@ public class OpeningHoursParser {
*/ */
public boolean contains(Calendar cal); public boolean contains(Calendar cal);
public int getSequenceIndex();
public String toRuleString(); public String toRuleString();
@ -475,6 +642,26 @@ public class OpeningHoursParser {
*/ */
private boolean off = false; 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 * return an array representing the days of the rule
* *
@ -512,6 +699,13 @@ public class OpeningHoursParser {
return schoolHoliday; 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 * set a single start time, erase all previously added start times
@ -786,27 +980,44 @@ public class OpeningHoursParser {
appendDaysString(b, dayNames); appendDaysString(b, dayNames);
// Time // Time
if (startTimes == null || startTimes.size() == 0) { if (startTimes == null || startTimes.size() == 0) {
b.append("off"); if (isOpened24_7()) {
b.setLength(0);
b.append("24/7 ");
} else if (off) {
b.append(additionalStrings.get("off"));
}
} else { } else {
if (isOpened24_7()) { if (isOpened24_7()) {
return "24/7"; b.setLength(0);
} b.append("24/7");
for (int i = 0; i < startTimes.size(); i++) { } else {
int startTime = startTimes.get(i); for (int i = 0; i < startTimes.size(); i++) {
int endTime = endTimes.get(i); int startTime = startTimes.get(i);
if(i > 0) { int endTime = endTimes.get(i);
b.append(", "); 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(); return b.toString();
@ -853,13 +1064,17 @@ public class OpeningHoursParser {
} }
} }
if (opened24_7 && startTimes != null && startTimes.size() > 0) { if (opened24_7) {
for (int i = 0; i < startTimes.size(); i++) { if (startTimes != null && startTimes.size() > 0) {
int startTime = startTimes.get(i); for (int i = 0; i < startTimes.size(); i++) {
int endTime = endTimes.get(i); int startTime = startTimes.get(i);
if (startTime == 0 && endTime / 60 == 24) { int endTime = endTimes.get(i);
return true; if (startTime == 0 && endTime / 60 == 24) {
return true;
}
} }
} else {
return true;
} }
} }
return false; return false;
@ -918,7 +1133,11 @@ public class OpeningHoursParser {
} }
} }
} }
return sb.toString(); String res = sb.toString();
if (res.length() > 0 && !Algorithms.isEmpty(comment)) {
res += " (" + comment + ")";
}
return res;
} }
@Override @Override
@ -1062,14 +1281,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 -1;
} }
return 0; return 0;
} }
} }
public static class UnparseableRule implements OpeningHoursParser.OpeningHoursRule { public static class UnparseableRule implements OpeningHoursRule {
private String ruleString; private String ruleString;
public UnparseableRule(String ruleString) { public UnparseableRule(String ruleString) {
@ -1140,6 +1361,11 @@ public class OpeningHoursParser {
public boolean contains(Calendar cal) { public boolean contains(Calendar cal) {
return false; return false;
} }
@Override
public int getSequenceIndex() {
return 0;
}
} }
private enum TokenType { private enum TokenType {
@ -1185,8 +1411,22 @@ public class OpeningHoursParser {
} }
} }
public static void parseRuleV2(String r, List<OpeningHoursParser.OpeningHoursRule> rules) { public static void parseRuleV2(String r, int sequenceIndex, List<OpeningHoursRule> rules) {
r = r.toLowerCase(); 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[] 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"}; final String[] monthsStr = new String[]{"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"};
@ -1198,7 +1438,8 @@ public class OpeningHoursParser {
r = r.replace(')', ' '); r = r.replace(')', ' ');
String localRuleString = r.replaceAll("sunset", sunset).replaceAll("sunrise", sunrise) String localRuleString = r.replaceAll("sunset", sunset).replaceAll("sunrise", sunrise)
.replaceAll("\\+", "-" + endOfDay); .replaceAll("\\+", "-" + endOfDay);
BasicOpeningHourRule basic = new BasicOpeningHourRule(); BasicOpeningHourRule basic = new BasicOpeningHourRule(sequenceIndex);
basic.setComment(comment);
boolean[] days = basic.getDays(); boolean[] days = basic.getDays();
boolean[] months = basic.getMonths(); boolean[] months = basic.getMonths();
boolean[] dayMonths = basic.getDayMonths(); boolean[] dayMonths = basic.getDayMonths();
@ -1211,32 +1452,32 @@ public class OpeningHoursParser {
} }
List<Token> tokens = new ArrayList<>(); List<Token> tokens = new ArrayList<>();
int startWord = 0; 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); char ch = i == localRuleString.length() ? ' ' : localRuleString.charAt(i);
boolean delimiter = false; boolean delimiter = false;
Token del = null; Token del = null;
if(Character.isWhitespace(ch)) { if (Character.isWhitespace(ch)) {
delimiter = true; delimiter = true;
} else if(ch == ':') { } else if (ch == ':') {
del = new Token(TokenType.TOKEN_COLON, ":"); del = new Token(TokenType.TOKEN_COLON, ":");
} else if(ch == '-') { } else if (ch == '-') {
del = new Token(TokenType.TOKEN_DASH, "-"); del = new Token(TokenType.TOKEN_DASH, "-");
} else if(ch == ',') { } else if (ch == ',') {
del = new Token(TokenType.TOKEN_COMMA, ","); del = new Token(TokenType.TOKEN_COMMA, ",");
} }
if(delimiter || del != null) { if (delimiter || del != null) {
String wrd = localRuleString.substring(startWord, i).trim(); String wrd = localRuleString.substring(startWord, i).trim();
if(wrd.length() > 0) { if(wrd.length() > 0) {
tokens.add(new Token(TokenType.TOKEN_UNKNOWN, wrd)); tokens.add(new Token(TokenType.TOKEN_UNKNOWN, wrd));
} }
startWord = i + 1; startWord = i + 1;
if(del != null) { if (del != null) {
tokens.add(del); tokens.add(del);
} }
} }
} }
// recognize day of week // recognize day of week
for(Token t : tokens) { for (Token t : tokens) {
if(t.type == TokenType.TOKEN_UNKNOWN) { if(t.type == TokenType.TOKEN_UNKNOWN) {
findInArray(t, daysStr, TokenType.TOKEN_DAY_WEEK); findInArray(t, daysStr, TokenType.TOKEN_DAY_WEEK);
} }
@ -1360,7 +1601,9 @@ public class OpeningHoursParser {
currentParse = t.type; currentParse = t.type;
} }
} else if (t.type.ord() < currentParse.ord() && indexP == 0 && tokens.size() > i) { } 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); tokens = tokens.subList(0, i + 1);
} else if (t.type == TokenType.TOKEN_COMMA) { } 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()) { if (tokens.size() > i + 1 && tokens.get(i + 1) != null && tokens.get(i + 1).type.ord() < currentParse.ord()) {
@ -1405,14 +1648,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 * Parse an opening_hours string from OSM to an OpeningHours object which can be used to check
* *
* @param r the string to parse * @param r the string to parse
* @return BasicRule if the String is successfully parsed and UnparseableRule otherwise * @return BasicRule if the String is successfully parsed and UnparseableRule otherwise
*/ */
public static void parseRules(String r, List<OpeningHoursParser.OpeningHoursRule> rules) { public static void parseRules(String r, int sequenceIndex, List<OpeningHoursRule> rules) {
parseRuleV2(r, rules); parseRuleV2(r, sequenceIndex, rules);
} }
/** /**
@ -1425,25 +1709,38 @@ public class OpeningHoursParser {
if (format == null) { if (format == null) {
return 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(); OpeningHours rs = new OpeningHours();
rs.setOriginal(format); rs.setOriginal(format);
for (String r : rules) { // split the OSM string in multiple rules
r = r.trim(); List<List<String>> sequences = splitSequences(format);
if (r.length() == 0) { for (int i = 0; i < sequences.size(); i++) {
continue; List<String> rules = sequences.get(i);
} List<BasicOpeningHourRule> basicRules = new ArrayList<>();
// check if valid for (String r : rules) {
List<OpeningHoursParser.OpeningHoursRule> rList = new ArrayList<>(); // check if valid
parseRules(r, rList); List<OpeningHoursRule> rList = new ArrayList<>();
for (OpeningHoursParser.OpeningHoursRule rule : rList) { parseRules(r, i, rList);
if (rule instanceof BasicOpeningHourRule) { for (OpeningHoursRule rule : rList) {
rs.addRule(rule); 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; return rs;
} }
@ -1459,22 +1756,35 @@ public class OpeningHoursParser {
if (format == null) { if (format == null) {
return null; return null;
} }
String[] rules = format.split(";"); //$NON-NLS-1$
OpeningHoursParser.OpeningHours rs = new OpeningHoursParser.OpeningHours(); OpeningHoursParser.OpeningHours rs = new OpeningHoursParser.OpeningHours();
rs.setOriginal(format); rs.setOriginal(format);
for (String r : rules) { List<List<String>> sequences = splitSequences(format);
r = r.trim(); for (int i = sequences.size() - 1; i >= 0; i--) {
if (r.length() == 0) { List<String> rules = sequences.get(i);
continue; 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; 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) { private static void formatTime(int h, int t, StringBuilder b) {
if (h < 10) { if (h < 10) {
b.append("0"); //$NON-NLS-1$ b.append("0"); //$NON-NLS-1$
@ -1502,9 +1812,9 @@ public class OpeningHoursParser {
private static void testOpened(String time, OpeningHours hours, boolean expected) throws ParseException { private static void testOpened(String time, OpeningHours hours, boolean expected) throws ParseException {
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
cal.setTime(new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.US).parse(time)); 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", 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) { if (calculated != expected) {
throw new IllegalArgumentException("BUG!!!"); throw new IllegalArgumentException("BUG!!!");
} }
@ -1521,50 +1831,49 @@ public class OpeningHoursParser {
* "Open till HH:mm" - close in 5 hours * "Open till HH:mm" - close in 5 hours
* "Will close at HH:mm" - close in 2 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 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 * "Open 24/7" - open 24/7
*/ */
private static void testInfo(String time, OpeningHours hours, String expected) throws ParseException 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(); Calendar cal = Calendar.getInstance();
cal.setTime(new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.US).parse(time)); cal.setTime(new SimpleDateFormat("dd.MM.yyyy HH:mm", Locale.US).parse(time));
boolean opened24_calc = false; String description;
boolean openFrom_calc = false; boolean result;
boolean willOpenAt_calc = false; if (sequenceIndex == OpeningHours.ALL_SEQUENCES) {
boolean openTill_calc = false; OpeningHours.Info info = hours.getCombinedInfo(cal);
boolean willCloseAt_calc = false; description = info.getInfo();
boolean willOpenOn_calc = false; result = expected.equalsIgnoreCase(description);
} else {
boolean opened = hours.isOpenedForTimeV2(cal); List<OpeningHours.Info> infos = hours.getInfo(cal);
if (opened) { OpeningHours.Info info = infos.get(sequenceIndex);
opened24_calc = hours.isOpened24_7(); description = info.getInfo();
openTill_calc = !Algorithms.isEmpty(hours.getClosingTime(cal)); result = expected.equalsIgnoreCase(description);
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);
System.out.printf(" %sok: Expected %s (%s): %s (rule %s)\n", 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) if (!result)
throw new IllegalArgumentException("BUG!!!"); throw new IllegalArgumentException("BUG!!!");
@ -1584,22 +1893,15 @@ public class OpeningHoursParser {
// 0. not supported MON DAY-MON DAY (only supported Feb 2-14 or Feb-Oct: 09:00-17:30) // 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"); // 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 (,) // 1. not properly 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
// hours = parseOpenedHours("Mo-Su (sunrise-00:30)-(sunset+00:30)"); // 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$ 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 11:00", hours, true);
testOpened("09.08.2012 16:00", hours, false); testOpened("09.08.2012 16:00", hours, false);
hours = parseOpenedHours("mo-fr 07:00-19:00; sa 12:00-18:00"); 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"; String string = "Mo-Fr 11:30-15:00, 17:30-23:00; Sa, Su, PH 11:30-23:00";
hours = parseOpenedHours(string); hours = parseOpenedHours(string);
@ -1793,11 +2095,11 @@ public class OpeningHoursParser {
testInfo("15.01.2018 13:10", hours, "Will open at 14:00"); 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 14:00", hours, "Open till 18:00");
testInfo("15.01.2018 16:00", hours, "Will close at 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"); hours = parseOpenedHours("Mo-Sa 02:00-10:00; Th off");
System.out.println(hours); 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"); hours = parseOpenedHours("Mo-Sa 23:00-02:00; Th off");
System.out.println(hours); System.out.println(hours);
@ -1808,10 +2110,10 @@ public class OpeningHoursParser {
hours = parseOpenedHours("Mo-Sa 08:30-17:00; Th off"); hours = parseOpenedHours("Mo-Sa 08:30-17:00; Th off");
System.out.println(hours); System.out.println(hours);
testInfo("17.01.2018 20: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 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("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 02:00", hours, "Open from 08:30");
testInfo("22.01.2018 04: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"); testInfo("22.01.2018 07:00", hours, "Will open at 08:30");
@ -1831,5 +2133,30 @@ public class OpeningHoursParser {
testOpened("19.01.2018 08:45", hours, true); testOpened("19.01.2018 08:45", hours, true);
testOpened("19.01.2018 20:45", hours, false); 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);
} }
} }

View file

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout <FrameLayout
android:id="@+id/context_menu_layout"
xmlns:android="http://schemas.android.com/apk/res/android" 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" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/context_menu_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@android:color/transparent" android:background="@android:color/transparent">
xmlns:osmand="http://schemas.android.com/apk/res-auto">
<LinearLayout <LinearLayout
android:id="@+id/context_menu_main" android:id="@+id/context_menu_main"
@ -18,47 +18,47 @@
android:id="@+id/context_menu_top_shadow_all" android:id="@+id/context_menu_top_shadow_all"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clickable="true"
android:background="?attr/bg_map_context_menu" android:background="?attr/bg_map_context_menu"
android:clickable="true"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
android:id="@+id/context_menu_top_view" android:id="@+id/context_menu_top_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="@dimen/context_menu_padding_margin_default" android:paddingLeft="@dimen/context_menu_padding_margin_default"
android:paddingRight="@dimen/context_menu_padding_margin_default" android:paddingRight="@dimen/context_menu_padding_margin_default">
android:orientation="horizontal">
<LinearLayout <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_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" 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"> android:orientation="vertical">
<TextView <TextView
android:id="@+id/context_menu_line1" android:id="@+id/context_menu_line1"
style="@style/TextAppearance.ContextMenuTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/search_address_building" android:text="@string/search_address_building"/>
style="@style/TextAppearance.ContextMenuTitle"/>
<LinearLayout <LinearLayout
android:layout_marginTop="@dimen/context_menu_subtitle_margin"
android:id="@+id/context_menu_line2_layout" android:id="@+id/context_menu_line2_layout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:layout_marginTop="@dimen/context_menu_subtitle_margin">
<TextView <TextView
android:id="@+id/context_menu_line2" android:id="@+id/context_menu_line2"
style="@style/TextAppearance.ContextMenuSubtitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:text="@string/amenity_type_finance" android:text="@string/amenity_type_finance"/>
style="@style/TextAppearance.ContextMenuSubtitle"/>
</LinearLayout> </LinearLayout>
@ -80,40 +80,42 @@
android:columnWidth="@dimen/context_menu_transport_grid_item_width" android:columnWidth="@dimen/context_menu_transport_grid_item_width"
android:horizontalSpacing="@dimen/context_menu_transport_grid_spacing" android:horizontalSpacing="@dimen/context_menu_transport_grid_spacing"
android:numColumns="auto_fit" android:numColumns="auto_fit"
android:paddingBottom="@dimen/context_menu_transport_grid_spacing"
android:paddingLeft="@dimen/context_menu_padding_margin_default" android:paddingLeft="@dimen/context_menu_padding_margin_default"
android:paddingRight="@dimen/context_menu_padding_margin_default" android:paddingRight="@dimen/context_menu_padding_margin_default"
android:paddingTop="@dimen/context_menu_transport_padding_top" 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:verticalSpacing="@dimen/context_menu_transport_grid_spacing"
android:visibility="gone"/> android:visibility="gone"/>
<LinearLayout <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_width="wrap_content"
android:layout_height="@dimen/context_menu_sub_info_height" android:layout_height= "wrap_content"
android:orientation="horizontal"> 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 <net.osmand.plus.widgets.TextViewEx
android:layout_marginRight="@dimen/context_menu_padding_margin_small" android:id="@+id/context_menu_line3"
android:layout_marginEnd="@dimen/context_menu_padding_margin_small" style="@style/TextAppearance.ContextMenuSubtitle"
tools:text="Museum"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="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" osmand:typeface="@string/font_roboto_medium"
style="@style/TextAppearance.ContextMenuSubtitle"/> tools:text="Museum"/>
<TextView <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:id="@+id/additional_info_text_view"
android:layout_width="wrap_content" 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 <LinearLayout
android:id="@+id/compass_layout" android:id="@+id/compass_layout"
@ -122,12 +124,12 @@
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <ImageView
tools:src="@drawable/ic_direction_arrow"
android:id="@+id/direction" android:id="@+id/direction"
android:layout_width="@dimen/directionIconSize" android:layout_width="@dimen/directionIconSize"
android:layout_height="@dimen/directionIconSize" android:layout_height="@dimen/directionIconSize"
android:layout_gravity="center_vertical"
android:layout_marginTop="1sp" android:layout_marginTop="1sp"
android:layout_gravity="center_vertical"/> tools:src="@drawable/ic_direction_arrow"/>
<TextView <TextView
android:id="@+id/distance" android:id="@+id/distance"
@ -136,9 +138,9 @@
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginLeft="2dp" android:layout_marginLeft="2dp"
android:layout_marginStart="2dp" android:layout_marginStart="2dp"
tools:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
tools:text="100500 km"/> tools:text="100500 km"
tools:textColor="?android:textColorSecondary"/>
</LinearLayout> </LinearLayout>
@ -155,17 +157,16 @@
tools:visibility="visible"> tools:visibility="visible">
<LinearLayout <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_marginLeft="@dimen/context_menu_padding_margin_small"
android:layout_marginRight="@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_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 <net.osmand.plus.widgets.TextViewEx
osmand:typeface="@string/font_roboto_medium"
android:id="@+id/title_button" android:id="@+id/title_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -173,10 +174,11 @@
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingLeft="@dimen/context_menu_button_padding_x" android:paddingLeft="@dimen/context_menu_button_padding_x"
android:paddingRight="@dimen/context_menu_button_padding_x" android:paddingRight="@dimen/context_menu_button_padding_x"
android:textAllCaps="true"
android:text="@string/recording_context_menu_play" android:text="@string/recording_context_menu_play"
tools:textColor="?attr/ctx_menu_controller_text_color" android:textAllCaps="true"
android:textSize="@dimen/default_desc_text_size"/> android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:textColor="?attr/ctx_menu_controller_text_color"/>
<TextView <TextView
android:id="@+id/title_button_right_text" android:id="@+id/title_button_right_text"
@ -190,18 +192,16 @@
</LinearLayout> </LinearLayout>
<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_marginLeft="@dimen/context_menu_padding_margin_small"
android:layout_marginRight="@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_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 <net.osmand.plus.widgets.TextViewEx
osmand:typeface="@string/font_roboto_medium"
android:textAllCaps="true"
android:id="@+id/title_button_right" android:id="@+id/title_button_right"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -210,8 +210,10 @@
android:paddingLeft="@dimen/context_menu_button_padding_x" android:paddingLeft="@dimen/context_menu_button_padding_x"
android:paddingRight="@dimen/context_menu_button_padding_x" android:paddingRight="@dimen/context_menu_button_padding_x"
android:text="@string/shared_string_delete" android:text="@string/shared_string_delete"
tools:textColor="?attr/ctx_menu_controller_text_color" android:textAllCaps="true"
android:textSize="@dimen/default_desc_text_size"/> android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:textColor="?attr/ctx_menu_controller_text_color"/>
</LinearLayout> </LinearLayout>
@ -229,16 +231,14 @@
<LinearLayout <LinearLayout
android:id="@+id/download_button_left_view" 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_marginLeft="@dimen/context_menu_padding_margin_small"
android:layout_marginRight="@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_weight="1"
android:layout_height="@dimen/context_menu_controller_height"> tools:background="?attr/ctx_menu_controller_bg">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
osmand:typeface="@string/font_roboto_medium"
android:textAllCaps="true"
android:id="@+id/download_button_left" android:id="@+id/download_button_left"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -247,23 +247,23 @@
android:paddingLeft="@dimen/context_menu_button_padding_x" android:paddingLeft="@dimen/context_menu_button_padding_x"
android:paddingRight="@dimen/context_menu_button_padding_x" android:paddingRight="@dimen/context_menu_button_padding_x"
android:text="@string/shared_string_download" android:text="@string/shared_string_download"
tools:textColor="?attr/ctx_menu_controller_text_color" android:textAllCaps="true"
android:textSize="@dimen/default_desc_text_size"/> android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:textColor="?attr/ctx_menu_controller_text_color"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/download_button_right_view" 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_marginLeft="@dimen/context_menu_padding_margin_small"
android:layout_marginRight="@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_weight="1"
android:layout_height="@dimen/context_menu_controller_height"> tools:background="?attr/ctx_menu_controller_bg">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
osmand:typeface="@string/font_roboto_medium"
android:textAllCaps="true"
android:id="@+id/download_button_right" android:id="@+id/download_button_right"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -272,8 +272,10 @@
android:paddingLeft="@dimen/context_menu_button_padding_x" android:paddingLeft="@dimen/context_menu_button_padding_x"
android:paddingRight="@dimen/context_menu_button_padding_x" android:paddingRight="@dimen/context_menu_button_padding_x"
android:text="@string/shared_string_others" android:text="@string/shared_string_others"
tools:textColor="?attr/ctx_menu_controller_text_color" android:textAllCaps="true"
android:textSize="@dimen/default_desc_text_size"/> android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:textColor="?attr/ctx_menu_controller_text_color"/>
</LinearLayout> </LinearLayout>
@ -308,9 +310,9 @@
android:paddingRight="@dimen/context_menu_button_padding_x" android:paddingRight="@dimen/context_menu_button_padding_x"
android:text="@string/shared_string_delete" android:text="@string/shared_string_delete"
android:textAllCaps="true" android:textAllCaps="true"
tools:textColor="?attr/ctx_menu_controller_text_color"
android:textSize="@dimen/default_desc_text_size" 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> </LinearLayout>
@ -325,10 +327,10 @@
android:minHeight="@dimen/context_menu_action_buttons_h" android:minHeight="@dimen/context_menu_action_buttons_h"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingBottom="@dimen/context_menu_padding_margin_small" 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: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" android:visibility="gone"
tools:visibility="visible"> tools:visibility="visible">
@ -364,11 +366,11 @@
<ImageView <ImageView
android:id="@+id/progressButton" android:id="@+id/progressButton"
android:contentDescription="@string/shared_string_close"
android:layout_width="@dimen/context_menu_progress_cancel_button_size" android:layout_width="@dimen/context_menu_progress_cancel_button_size"
android:layout_height="@dimen/context_menu_progress_cancel_button_size" android:layout_height="@dimen/context_menu_progress_cancel_button_size"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:contentDescription="@string/shared_string_close"
android:scaleType="center" android:scaleType="center"
tools:src="@drawable/map_action_cancel"/> tools:src="@drawable/map_action_cancel"/>
@ -383,73 +385,73 @@
android:background="?attr/ctx_menu_divider"/> android:background="?attr/ctx_menu_divider"/>
<LinearLayout <LinearLayout
android:paddingLeft="@dimen/map_widget_icon_margin"
android:paddingRight="@dimen/map_widget_icon_margin"
android:id="@+id/context_menu_buttons" android:id="@+id/context_menu_buttons"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" 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 <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:background="?selectableItemBackground"
android:clickable="true" android:clickable="true"
android:id="@+id/context_menu_fav_view"
android:gravity="center" android:gravity="center"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical" 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 <ImageView
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
android:id="@+id/context_menu_fav_image_view" android:id="@+id/context_menu_fav_image_view"
android:contentDescription="@string/shared_string_add_to_favorites"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="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:scaleType="center"
android:src="@drawable/map_action_fav_dark"/> android:src="@drawable/map_action_fav_dark"/>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:maxLines="1"
android:ellipsize="end"
android:id="@+id/context_menu_fav_text_view" android:id="@+id/context_menu_fav_text_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="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:textColor="@color/ctx_menu_buttons_text_color"
android:textSize="@dimen/default_desc_text_size" 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>
<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:background="?selectableItemBackground"
android:clickable="true" android:clickable="true"
android:id="@+id/context_menu_route_view"
android:gravity="center" android:gravity="center"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical" 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 <ImageView
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
android:id="@+id/context_menu_route_image_view" android:id="@+id/context_menu_route_image_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
android:scaleType="center" android:scaleType="center"
android:src="@drawable/map_action_flag_dark"/> android:src="@drawable/map_action_flag_dark"/>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:maxLines="1"
android:ellipsize="end"
android:id="@+id/context_menu_route_text_view" android:id="@+id/context_menu_route_text_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/shared_string_marker" android:text="@string/shared_string_marker"
android:textColor="@color/ctx_menu_buttons_text_color" android:textColor="@color/ctx_menu_buttons_text_color"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
@ -458,32 +460,32 @@
</LinearLayout> </LinearLayout>
<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:background="?selectableItemBackground"
android:clickable="true" android:clickable="true"
android:id="@+id/context_menu_share_view"
android:gravity="center" android:gravity="center"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical" 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 <ImageView
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
android:id="@+id/context_menu_share_image_view" android:id="@+id/context_menu_share_image_view"
android:contentDescription="@string/context_menu_item_share_location"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="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:scaleType="center"
android:src="@drawable/map_action_gshare_dark"/> android:src="@drawable/map_action_gshare_dark"/>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:maxLines="1"
android:ellipsize="end"
android:id="@+id/context_menu_share_text_view" android:id="@+id/context_menu_share_text_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/shared_string_share" android:text="@string/shared_string_share"
android:textColor="@color/ctx_menu_buttons_text_color" android:textColor="@color/ctx_menu_buttons_text_color"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
@ -492,32 +494,32 @@
</LinearLayout> </LinearLayout>
<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:background="?selectableItemBackground"
android:clickable="true" android:clickable="true"
android:id="@+id/context_menu_more_view"
android:gravity="center" android:gravity="center"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical" 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 <ImageView
android:layout_marginBottom="@dimen/context_menu_main_actions_icon_margin"
android:id="@+id/context_menu_more_image_view" android:id="@+id/context_menu_more_image_view"
android:contentDescription="@string/shared_string_more"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="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:scaleType="center"
android:src="@drawable/map_overflow_menu_white"/> android:src="@drawable/map_overflow_menu_white"/>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:maxLines="1"
android:ellipsize="end"
android:id="@+id/context_menu_more_text_view" android:id="@+id/context_menu_more_text_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/shared_string_actions" android:text="@string/shared_string_actions"
android:textColor="@color/ctx_menu_buttons_text_color" android:textColor="@color/ctx_menu_buttons_text_color"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
@ -539,35 +541,35 @@
android:layout_height="@dimen/context_menu_buttons_bottom_height"> android:layout_height="@dimen/context_menu_buttons_bottom_height">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:textAllCaps="true"
android:background="?attr/selectableItemBackground"
android:id="@+id/context_menu_details_button" android:id="@+id/context_menu_details_button"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" 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:paddingLeft="@dimen/context_menu_padding_margin_default"
android:paddingRight="@dimen/context_menu_padding_margin_default" android:paddingRight="@dimen/context_menu_padding_margin_default"
android:gravity="start|center_vertical" android:text="@string/description"
android:layout_gravity="center_vertical" android:textAllCaps="true"
tools:textColor="?attr/contextMenuButtonColor"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium" osmand:typeface="@string/font_roboto_medium"
android:text="@string/description"/> tools:textColor="?attr/contextMenuButtonColor"/>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:textAllCaps="true"
android:background="?attr/selectableItemBackground"
android:id="@+id/context_menu_directions_button" android:id="@+id/context_menu_directions_button"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent" 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:paddingLeft="@dimen/context_menu_padding_margin_default"
android:paddingRight="@dimen/context_menu_padding_margin_default" android:paddingRight="@dimen/context_menu_padding_margin_default"
android:gravity="end|center_vertical" android:text="@string/get_directions"
tools:textColor="?attr/contextMenuButtonColor" android:textAllCaps="true"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_medium" osmand:typeface="@string/font_roboto_medium"
android:text="@string/get_directions"/> tools:textColor="?attr/contextMenuButtonColor"/>
</LinearLayout> </LinearLayout>
@ -589,8 +591,8 @@
android:id="@+id/context_menu_bottom_view" android:id="@+id/context_menu_bottom_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" 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> </LinearLayout>
@ -610,8 +612,8 @@
android:layout_width="@dimen/fab_size_with_shadow" android:layout_width="@dimen/fab_size_with_shadow"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="right" android:layout_gravity="right"
android:gravity="center"
android:layout_marginRight="@dimen/fab_margin_right" android:layout_marginRight="@dimen/fab_margin_right"
android:gravity="center"
android:orientation="vertical" android:orientation="vertical"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"> tools:visibility="visible">

View file

@ -9,6 +9,7 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). 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 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="rendering_attr_hidePOILabels_name">POI labels</string>
<string name="shared_string_without_name">Without name</string> <string name="shared_string_without_name">Without name</string>
<string name="what_is_here">What\'s here:</string> <string name="what_is_here">What\'s here:</string>

View file

@ -47,6 +47,7 @@ import net.osmand.plus.voice.TTSCommandPlayerImpl;
import net.osmand.render.RenderingRulesStorage; import net.osmand.render.RenderingRulesStorage;
import net.osmand.router.RoutingConfiguration; import net.osmand.router.RoutingConfiguration;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.OpeningHoursParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -378,8 +379,21 @@ public class AppInitializer implements IProgress {
app.mapMarkersDbHelper = startupInit(new MapMarkersDbHelper(app), MapMarkersDbHelper.class); app.mapMarkersDbHelper = startupInit(new MapMarkersDbHelper(app), MapMarkersDbHelper.class);
app.mapMarkersHelper = startupInit(new MapMarkersHelper(app), MapMarkersHelper.class); app.mapMarkersHelper = startupInit(new MapMarkersHelper(app), MapMarkersHelper.class);
app.searchUICore = startupInit(new QuickSearchHelper(app), QuickSearchHelper.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() { private void updateRegionVars() {
app.regions.setTranslator(new RegionTranslation() { app.regions.setTranslator(new RegionTranslation() {

View file

@ -1175,7 +1175,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL
return 0; return 0;
} }
public String getAdditionalInfo() { public CharSequence getAdditionalInfo() {
if (menuController != null) { if (menuController != null) {
return menuController.getAdditionalInfoStr(); return menuController.getAdditionalInfoStr();
} }

View file

@ -1196,7 +1196,7 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
} }
TextView additionalInfoTextView = (TextView) view.findViewById(R.id.additional_info_text_view); TextView additionalInfoTextView = (TextView) view.findViewById(R.id.additional_info_text_view);
String additionalInfoStr = menu.getAdditionalInfo(); CharSequence additionalInfoStr = menu.getAdditionalInfo();
if (!TextUtils.isEmpty(additionalInfoStr)) { if (!TextUtils.isEmpty(additionalInfoStr)) {
int colorId = menu.getAdditionalInfoColor(); int colorId = menu.getAdditionalInfoColor();
int additionalInfoIconRes = menu.getAdditionalInfoIconRes(); int additionalInfoIconRes = menu.getAdditionalInfoIconRes();

View file

@ -8,6 +8,8 @@ import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -29,9 +31,7 @@ import net.osmand.map.WorldRegion;
import net.osmand.plus.GPXUtilities.WptPt; import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.MapMarkersHelper.MapMarker; import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper.TargetPoint; import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.activities.MapActivity; 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.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import net.osmand.util.OpeningHoursParser.OpeningHours;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
@ -117,6 +118,8 @@ public abstract class MenuController extends BaseMenuController {
private WorldRegion downloadRegion; private WorldRegion downloadRegion;
private DownloadIndexesThread downloadThread; private DownloadIndexesThread downloadThread;
protected List<OpeningHours.Info> openingHoursInfo;
public MenuController(MenuBuilder builder, PointDescription pointDescription, MapActivity mapActivity) { public MenuController(MenuBuilder builder, PointDescription pointDescription, MapActivity mapActivity) {
super(mapActivity); super(mapActivity);
this.pointDescription = pointDescription; this.pointDescription = pointDescription;
@ -243,12 +246,8 @@ public abstract class MenuController extends BaseMenuController {
} }
protected void addMyLocationToPlainItems(LatLon latLon) { protected void addMyLocationToPlainItems(LatLon latLon) {
OsmandSettings st = ((OsmandApplication) getMapActivity().getApplicationContext()).getSettings();
addPlainMenuItem(R.drawable.ic_action_get_my_location, null, PointDescription.getLocationName(getMapActivity(), addPlainMenuItem(R.drawable.ic_action_get_my_location, null, PointDescription.getLocationName(getMapActivity(),
latLon.getLatitude(), latLon.getLongitude(), true).replaceAll("\n", " "), false, false, null); 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() { public PointDescription getPointDescription() {
@ -442,21 +441,47 @@ public abstract class MenuController extends BaseMenuController {
} }
public int getAdditionalInfoColor() { public int getAdditionalInfoColor() {
if (indexItem != null) { if (openingHoursInfo != null) {
return 0;
} else if (indexItem != null) {
return R.color.icon_color; return R.color.icon_color;
} }
return 0; return 0;
} }
public String getAdditionalInfoStr() { public CharSequence getAdditionalInfoStr() {
if (indexItem != null) { 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 getMapActivity().getString(R.string.file_size_in_mb, indexItem.getArchiveSizeMB());
} }
return ""; return "";
} }
public int getAdditionalInfoIconRes() { 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 R.drawable.ic_sdcard_16;
} }
return 0; return 0;

View file

@ -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 "";
}
}

View file

@ -529,11 +529,6 @@ public class AmenityMenuBuilder extends MenuBuilder {
buildRow(view, R.drawable.ic_action_get_my_location, null, PointDescription.getLocationName(app, buildRow(view, R.drawable.ic_action_get_my_location, null, PointDescription.getLocationName(app,
amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(), true) amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(), true)
.replaceAll("\n", " "), 0, false, null, false, 0, false, null, false); .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) { public void buildAmenityRow(View view, AmenityInfoRow info) {

View file

@ -1,17 +1,12 @@
package net.osmand.plus.mapcontextmenu.builders; package net.osmand.plus.mapcontextmenu.builders;
import android.graphics.Color; import android.graphics.Color;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View; import android.view.View;
import android.widget.LinearLayout;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.data.FavouritePoint; import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect; import net.osmand.data.QuadRect;
import net.osmand.data.TransportStop; import net.osmand.data.TransportStop;
import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiCategory;
@ -19,7 +14,6 @@ import net.osmand.plus.FavouritesDbHelper.FavoriteGroup;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.widgets.TextViewEx;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import java.util.List; import java.util.List;
@ -36,7 +30,7 @@ public class FavouritePointMenuBuilder extends MenuBuilder {
acquireOriginObject(); acquireOriginObject();
} }
public void acquireOriginObject() private void acquireOriginObject()
{ {
String originObjectName = fav.getOriginObjectName(); String originObjectName = fav.getOriginObjectName();
if (originObjectName.length() > 0) { if (originObjectName.length() > 0) {

View file

@ -14,19 +14,17 @@ import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.mapcontextmenu.MenuController; import net.osmand.plus.mapcontextmenu.MenuController;
import net.osmand.plus.mapcontextmenu.OpeningHoursInfo;
import net.osmand.plus.mapcontextmenu.WikipediaDialogFragment; import net.osmand.plus.mapcontextmenu.WikipediaDialogFragment;
import net.osmand.plus.mapcontextmenu.builders.AmenityMenuBuilder; import net.osmand.plus.mapcontextmenu.builders.AmenityMenuBuilder;
import net.osmand.plus.transport.TransportStopRoute;
import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.resources.TransportIndexRepository; import net.osmand.plus.resources.TransportIndexRepository;
import net.osmand.plus.transport.TransportStopRoute;
import net.osmand.plus.transport.TransportStopType; import net.osmand.plus.transport.TransportStopType;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import net.osmand.util.OpeningHoursParser; import net.osmand.util.OpeningHoursParser;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -36,7 +34,6 @@ public class AmenityMenuController extends MenuController {
private Amenity amenity; private Amenity amenity;
private List<TransportStopRoute> routes = new ArrayList<>(); private List<TransportStopRoute> routes = new ArrayList<>();
private OpeningHoursInfo openingHoursInfo;
private MapMarker marker; private MapMarker marker;
@ -77,7 +74,7 @@ public class AmenityMenuController extends MenuController {
leftTitleButtonController.updateStateListDrawableIcon(R.drawable.ic_action_read_text, true); leftTitleButtonController.updateStateListDrawableIcon(R.drawable.ic_action_read_text, true);
} }
openingHoursInfo = processOpeningHours(amenity); openingHoursInfo = OpeningHoursParser.getInfo(amenity.getOpeningHours());
} }
@Override @Override
@ -146,30 +143,6 @@ public class AmenityMenuController extends MenuController {
return getTypeStr(amenity); 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) { public static String getTypeStr(Amenity amenity) {
PoiCategory pc = amenity.getType(); PoiCategory pc = amenity.getType();
PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType()); PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType());
@ -182,28 +155,6 @@ public class AmenityMenuController extends MenuController {
return typeStr; 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 @Override
public String getCommonTypeStr() { public String getCommonTypeStr() {
PoiCategory pc = amenity.getType(); PoiCategory pc = amenity.getType();
@ -219,7 +170,8 @@ public class AmenityMenuController extends MenuController {
public void addPlainMenuItems(String typeStr, PointDescription pointDescription, LatLon latLon) { 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)) { if (!Algorithms.isEmpty(typeStr)) {
int resId = getRightIconId(amenity); int resId = getRightIconId(amenity);
if (resId == 0) { if (resId == 0) {

View file

@ -14,12 +14,12 @@ import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.FavoriteImageDrawable; import net.osmand.plus.base.FavoriteImageDrawable;
import net.osmand.plus.mapcontextmenu.MenuController; import net.osmand.plus.mapcontextmenu.MenuController;
import net.osmand.plus.mapcontextmenu.OpeningHoursInfo;
import net.osmand.plus.mapcontextmenu.builders.FavouritePointMenuBuilder; import net.osmand.plus.mapcontextmenu.builders.FavouritePointMenuBuilder;
import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditor; import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditor;
import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditorFragment; import net.osmand.plus.mapcontextmenu.editors.FavoritePointEditorFragment;
import net.osmand.plus.transport.TransportStopRoute; import net.osmand.plus.transport.TransportStopRoute;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.OpeningHoursParser;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -29,7 +29,6 @@ public class FavouritePointMenuController extends MenuController {
private FavouritePoint fav; private FavouritePoint fav;
private MapMarker mapMarker; private MapMarker mapMarker;
private List<TransportStopRoute> routes = new ArrayList<>(); private List<TransportStopRoute> routes = new ArrayList<>();
private OpeningHoursInfo openingHoursInfo;
public FavouritePointMenuController(MapActivity mapActivity, PointDescription pointDescription, final FavouritePoint fav) { public FavouritePointMenuController(MapActivity mapActivity, PointDescription pointDescription, final FavouritePoint fav) {
super(new FavouritePointMenuBuilder(mapActivity, fav), pointDescription, mapActivity); super(new FavouritePointMenuBuilder(mapActivity, fav), pointDescription, mapActivity);
@ -55,7 +54,7 @@ public class FavouritePointMenuController extends MenuController {
Object originObject = getBuilder().getOriginObject(); Object originObject = getBuilder().getOriginObject();
if (originObject instanceof Amenity) { 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(); Object originObject = getBuilder().getOriginObject();
if (originObject != null) { if (originObject != null) {
if (originObject instanceof Amenity) { if (originObject instanceof Amenity) {
Amenity amenity = (Amenity) originObject; AmenityMenuController.addTypeMenuItem((Amenity) originObject, builder);
AmenityMenuController.addPlainMenuItems(amenity, AmenityMenuController.getTypeStr(amenity), builder);
} }
} else { } else {
addMyLocationToPlainItems(latLon); 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;
}
} }

View file

@ -190,7 +190,7 @@ public class MapDataMenuController extends MenuController {
} }
@Override @Override
public String getAdditionalInfoStr() { public CharSequence getAdditionalInfoStr() {
double mb = 0; double mb = 0;
if (backuped) { if (backuped) {
if (localIndexInfo != null) { if (localIndexInfo != null) {

View file

@ -131,7 +131,7 @@ public class EditPOIMenuController extends MenuController {
} }
@Override @Override
public String getAdditionalInfoStr() { public CharSequence getAdditionalInfoStr() {
return actionStr; return actionStr;
} }

View file

@ -68,7 +68,7 @@ public class ParkingPositionMenuController extends MenuController {
} }
@Override @Override
public String getAdditionalInfoStr() { public CharSequence getAdditionalInfoStr() {
return parkingLeftDescription; return parkingLeftDescription;
} }