mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-21 19:50:01 +00:00
Merge branch 'master' into bug2564
This commit is contained in:
commit
f2b586ea4b
35 files changed
+386
-121
No files matched your search
+7
-1
@@ -1464,7 +1464,13 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
private RaceLogEvent loadRaceLogProtestStartTimeEvent(TimePoint createdAt, AbstractLogEventAuthor author,
|
||||
TimePoint logicalTimePoint, Serializable id, Integer passId, List<Competitor> competitors, DBObject dbObject) {
|
||||
TimePoint protestStartTime = loadTimePoint(dbObject, FieldNames.RACE_LOG_PROTEST_START_TIME);
|
||||
return new RaceLogProtestStartTimeEventImpl(createdAt, logicalTimePoint, author, id, passId, protestStartTime);
|
||||
TimePoint protestEndTime = loadTimePoint(dbObject, FieldNames.RACE_LOG_PROTEST_END_TIME);
|
||||
if (protestEndTime == null) {
|
||||
// fallback old data
|
||||
protestEndTime = protestStartTime.plus(Duration.ONE_MINUTE.times(90));
|
||||
}
|
||||
TimeRange protestTime = new TimeRangeImpl(protestStartTime, protestEndTime);
|
||||
return new RaceLogProtestStartTimeEventImpl(createdAt, logicalTimePoint, author, id, passId, protestTime);
|
||||
}
|
||||
|
||||
private RaceLogEvent loadRaceLogStartProcedureChangedEvent(TimePoint createdAt, AbstractLogEventAuthor author,
|
||||
|
||||
+2
-2
@@ -97,8 +97,8 @@ public enum FieldNames {
|
||||
WAYPOINT_PASSINGINSTRUCTIONS, CONTROLPOINT, CONTROLPOINT_CLASS, MARK_ID, MARK_COLOR, MARK_NAME, MARK_PATTERN, MARK_SHAPE, MARK_TYPE,
|
||||
CONTROLPOINT_VALUE, CONTROLPOINTWITHTWOMARKS_ID, CONTROLPOINTWITHTWOMARKS_NAME, CONTROLPOINTWITHTWOMARKS_LEFT, CONTROLPOINTWITHTWOMARKS_RIGHT,
|
||||
RACE_LOG_POSITIONED_COMPETITORS, RACE_LOG_PATHFINDER_ID, RACE_LOG_GATE_LINE_OPENING_TIME, RACE_LOG_GOLF_DOWN_TIME, RACE_LOG_START_PROCEDURE_TYPE,
|
||||
RACE_LOG_PROTEST_START_TIME, RACE_LOG_COURSE_DESIGN_NAME, RACE_LOG_REVOKED_EVENT_ID, RACE_LOG_REVOKED_EVENT_TYPE, RACE_LOG_REVOKED_EVENT_SHORT_INFO,
|
||||
RACE_LOG_REVOKED_REASON, RACE_LOG_DEVICE_MAPPING_EVENT_ID,
|
||||
RACE_LOG_PROTEST_START_TIME, RACE_LOG_PROTEST_END_TIME, RACE_LOG_COURSE_DESIGN_NAME, RACE_LOG_REVOKED_EVENT_ID, RACE_LOG_REVOKED_EVENT_TYPE,
|
||||
RACE_LOG_REVOKED_EVENT_SHORT_INFO, RACE_LOG_REVOKED_REASON, RACE_LOG_DEVICE_MAPPING_EVENT_ID,
|
||||
RACE_LOG_CLOSING_TIMEPOINT, TIMEPOINT_OF_FIXED_MARKPASSING, INDEX_OF_PASSED_WAYPOINT,INDEX_OF_FIRST_SUPPRESSED_WAYPOINT, MARK, RACE_LOG_COMPETITOR_ID,
|
||||
RACE_LOG_DEPDENDENT_ON_FLEET, RACE_LOG_DEPDENDENT_ON_RACECOLUMN, RACE_LOG_DEPDENDENT_ON_REGATTALIKE,
|
||||
RACE_LOG_START_TIME_DIFFERENCE_IN_MS, RACE_LOG_FINISHING_TIME_AS_MILLIS,
|
||||
|
||||
+2
-1
@@ -924,7 +924,8 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
DBObject result = new BasicDBObject();
|
||||
storeRaceLogEventProperties(event, result);
|
||||
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogProtestStartTimeEvent.class.getSimpleName());
|
||||
storeTimePoint(event.getProtestStartTime(), result, FieldNames.RACE_LOG_PROTEST_START_TIME);
|
||||
storeTimePoint(event.getProtestTime().from(), result, FieldNames.RACE_LOG_PROTEST_START_TIME);
|
||||
storeTimePoint(event.getProtestTime().to(), result, FieldNames.RACE_LOG_PROTEST_END_TIME);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -13,21 +13,21 @@ import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ProtestStartTimeFinder;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ProtestTimeFinder;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
|
||||
public class ProtestStartTimeFinderTest extends PassAwareRaceLogAnalyzerTest<ProtestStartTimeFinder, TimePoint> {
|
||||
public class ProtestStartTimeFinderTest extends PassAwareRaceLogAnalyzerTest<ProtestTimeFinder, TimeRange> {
|
||||
|
||||
@Override
|
||||
protected ProtestStartTimeFinder createAnalyzer(RaceLog raceLog) {
|
||||
return new ProtestStartTimeFinder(raceLog);
|
||||
protected ProtestTimeFinder createAnalyzer(RaceLog raceLog) {
|
||||
return new ProtestTimeFinder(raceLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TargetPair getTargetEventsAndResultForPassAwareTests(int passId, AbstractLogEventAuthor author) {
|
||||
RaceLogProtestStartTimeEvent event = createEvent(RaceLogProtestStartTimeEvent.class, 1, passId, author);
|
||||
when(event.getProtestStartTime()).thenReturn(mock(TimePoint.class));
|
||||
return new TargetPair(Arrays.asList(event), event.getProtestStartTime());
|
||||
when(event.getProtestTime()).thenReturn(mock(TimeRange.class));
|
||||
return new TargetPair(Arrays.asList(event), event.getProtestTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -40,13 +40,13 @@ public class ProtestStartTimeFinderTest extends PassAwareRaceLogAnalyzerTest<Pro
|
||||
@Test
|
||||
public void testMostRecent() {
|
||||
RaceLogProtestStartTimeEvent event1 = createEvent(RaceLogProtestStartTimeEvent.class, 1);
|
||||
when(event1.getProtestStartTime()).thenReturn(mock(TimePoint.class));
|
||||
when(event1.getProtestTime()).thenReturn(mock(TimeRange.class));
|
||||
RaceLogProtestStartTimeEvent event2 = createEvent(RaceLogProtestStartTimeEvent.class, 2);
|
||||
when(event2.getProtestStartTime()).thenReturn(mock(TimePoint.class));
|
||||
when(event2.getProtestTime()).thenReturn(mock(TimeRange.class));
|
||||
|
||||
raceLog.add(event1);
|
||||
raceLog.add(event2);
|
||||
|
||||
assertEquals(event2.getProtestStartTime(), analyzer.analyze());
|
||||
assertEquals(event2.getProtestTime(), analyzer.analyze());
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -1,6 +1,6 @@
|
||||
package com.sap.sailing.domain.abstractlog.race;
|
||||
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
|
||||
/**
|
||||
* Indicates that the protest start time for the related race has changed.
|
||||
@@ -9,7 +9,9 @@ import com.sap.sse.common.TimePoint;
|
||||
public interface RaceLogProtestStartTimeEvent extends RaceLogEvent {
|
||||
|
||||
/**
|
||||
* Returns the start time of the race's protest time.
|
||||
* Returns the time range of the race's protest time. The result is never {@code null}
|
||||
* and the {@link TimeRange} returned always has a valid {@link TimeRange#from() start}
|
||||
* and {@link TimeRange#to() end}.
|
||||
*/
|
||||
TimePoint getProtestStartTime();
|
||||
TimeRange getProtestTime();
|
||||
}
|
||||
+6
-5
@@ -3,19 +3,20 @@ package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
|
||||
public class ProtestStartTimeFinder extends RaceLogAnalyzer<TimePoint> {
|
||||
public class ProtestTimeFinder extends RaceLogAnalyzer<TimeRange> {
|
||||
|
||||
public ProtestStartTimeFinder(RaceLog raceLog) {
|
||||
public ProtestTimeFinder(RaceLog raceLog) {
|
||||
super(raceLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TimePoint performAnalysis() {
|
||||
protected TimeRange performAnalysis() {
|
||||
for (RaceLogEvent event : getPassEventsDescending()) {
|
||||
if (event instanceof RaceLogProtestStartTimeEvent) {
|
||||
return ((RaceLogProtestStartTimeEvent) event).getProtestStartTime();
|
||||
RaceLogProtestStartTimeEvent protestEvent = (RaceLogProtestStartTimeEvent) event;
|
||||
return protestEvent.getProtestTime();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
+11
-9
@@ -6,21 +6,23 @@ import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogProtestStartTimeEvent;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
|
||||
public class RaceLogProtestStartTimeEventImpl extends RaceLogEventImpl implements RaceLogProtestStartTimeEvent {
|
||||
private static final long serialVersionUID = -1800827552916395996L;
|
||||
|
||||
private final TimePoint protestStartTime;
|
||||
|
||||
private final TimeRange protestTime;
|
||||
|
||||
public RaceLogProtestStartTimeEventImpl(TimePoint createdAt, TimePoint pTimePoint, AbstractLogEventAuthor author,
|
||||
Serializable pId, int pPassId, TimePoint protestStartTime) {
|
||||
Serializable pId, int pPassId, TimeRange protestTime) {
|
||||
super(createdAt, pTimePoint, author, pId, pPassId);
|
||||
this.protestStartTime = protestStartTime;
|
||||
assert protestTime != null && protestTime.from() != null && protestTime.to() != null;
|
||||
this.protestTime = protestTime;
|
||||
}
|
||||
|
||||
public RaceLogProtestStartTimeEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author, int pPassId,
|
||||
TimePoint protestStartTime) {
|
||||
this(now(), logicalTimePoint, author, randId(), pPassId, protestStartTime);
|
||||
TimeRange protestTime) {
|
||||
this(now(), logicalTimePoint, author, randId(), pPassId, protestTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -29,13 +31,13 @@ public class RaceLogProtestStartTimeEventImpl extends RaceLogEventImpl implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getProtestStartTime() {
|
||||
return protestStartTime;
|
||||
public TimeRange getProtestTime() {
|
||||
return protestTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortInfo() {
|
||||
return "protestStartTime=" + protestStartTime;
|
||||
return "protestStartTime=" + protestTime.from() + ", protestEndTime=" + protestTime.to();
|
||||
}
|
||||
|
||||
}
|
||||
+3
-2
@@ -19,6 +19,7 @@ import com.sap.sailing.domain.common.racelog.Flags;
|
||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
|
||||
/**
|
||||
* Extension to the {@link ReadonlyRaceState} allowing write-access to the state of a race.
|
||||
@@ -142,9 +143,9 @@ public interface RaceState extends ReadonlyRaceState {
|
||||
void setFinishedTime(TimePoint now);
|
||||
|
||||
/**
|
||||
* Sets the protest (start) time.
|
||||
* Sets the protest time.
|
||||
*/
|
||||
void setProtestTime(TimePoint now, TimePoint protestStartTime);
|
||||
void setProtestTime(TimePoint now, TimeRange protestTime);
|
||||
|
||||
/**
|
||||
* Signals the abort of this race.
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
|
||||
import com.sap.sailing.domain.common.Wind;
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
|
||||
/**
|
||||
* This interface gives you reading access to the state of a race. You can query various properties of the race
|
||||
@@ -134,7 +135,7 @@ public interface ReadonlyRaceState extends RaceStateEventProcessor {
|
||||
/**
|
||||
* If there is a protest time set, returns the most recent one. Otherwise <code>null</code>.
|
||||
*/
|
||||
TimePoint getProtestTime();
|
||||
TimeRange getProtestTime();
|
||||
|
||||
/**
|
||||
* If there is a course set, returns the most recent one. Otherwise <code>null</code>.
|
||||
|
||||
+4
-2
@@ -45,6 +45,7 @@ import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
|
||||
/**
|
||||
* Write-enabled {@link RaceState}.
|
||||
@@ -169,8 +170,9 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtestTime(TimePoint now, TimePoint timePoint) {
|
||||
raceLog.add(new RaceLogProtestStartTimeEventImpl(now, author, raceLog.getCurrentPassId(), timePoint));
|
||||
public void setProtestTime(TimePoint now, TimeRange protestTime) {
|
||||
assert protestTime != null && protestTime.from() != null && protestTime.to() != null;
|
||||
raceLog.add(new RaceLogProtestStartTimeEventImpl(now, author, raceLog.getCurrentPassId(), protestTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
-9
@@ -18,7 +18,7 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishedTimeFinder
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishingTimeFinder;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastPublishedCourseDesignFinder;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastWindFixFinder;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ProtestStartTimeFinder;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ProtestTimeFinder;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer.Clock;
|
||||
@@ -42,6 +42,7 @@ import com.sap.sailing.domain.common.Wind;
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
@@ -116,7 +117,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
private final StartTimeFinder startTimeAnalyzer;
|
||||
private final FinishingTimeFinder finishingTimeAnalyzer;
|
||||
private final FinishedTimeFinder finishedTimeAnalyzer;
|
||||
private final ProtestStartTimeFinder protestTimeAnalyzer;
|
||||
private final ProtestTimeFinder protestTimeAnalyzer;
|
||||
|
||||
private final FinishPositioningListFinder finishPositioningListAnalyzer;
|
||||
private final ConfirmedFinishPositioningListFinder confirmedFinishPositioningListAnalyzer;
|
||||
@@ -141,7 +142,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
private StartTimeFinderResult cachedStartTimeFinderResult;
|
||||
private TimePoint cachedFinishingTime;
|
||||
private TimePoint cachedFinishedTime;
|
||||
private TimePoint cachedProtestTime;
|
||||
private TimeRange cachedProtest;
|
||||
private CompetitorResults cachedPositionedCompetitors;
|
||||
private CompetitorResults cachedConfirmedPositionedCompetitors;
|
||||
private CourseBase cachedCourseDesign;
|
||||
@@ -184,7 +185,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
this.startTimeAnalyzer = new StartTimeFinder(raceLogResolver, raceLog);
|
||||
this.finishingTimeAnalyzer = new FinishingTimeFinder(raceLog);
|
||||
this.finishedTimeAnalyzer = new FinishedTimeFinder(raceLog);
|
||||
this.protestTimeAnalyzer = new ProtestStartTimeFinder(raceLog);
|
||||
this.protestTimeAnalyzer = new ProtestTimeFinder(raceLog);
|
||||
this.finishPositioningListAnalyzer = new FinishPositioningListFinder(raceLog);
|
||||
this.confirmedFinishPositioningListAnalyzer = new ConfirmedFinishPositioningListFinder(raceLog);
|
||||
this.courseDesignerAnalyzer = new LastPublishedCourseDesignFinder(raceLog, /* onlyCoursesWithValidWaypointList */ false);
|
||||
@@ -318,8 +319,8 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getProtestTime() {
|
||||
return cachedProtestTime;
|
||||
public TimeRange getProtestTime() {
|
||||
return cachedProtest;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -459,9 +460,9 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
|
||||
changedListeners.onFinishedTimeChanged(this);
|
||||
}
|
||||
|
||||
TimePoint protestTime = protestTimeAnalyzer.analyze();
|
||||
if (!Util.equalsWithNull(cachedProtestTime, protestTime)) {
|
||||
cachedProtestTime = protestTime;
|
||||
TimeRange protest = protestTimeAnalyzer.analyze();
|
||||
if (!Util.equalsWithNull(cachedProtest, protest)) {
|
||||
cachedProtest = protest;
|
||||
changedListeners.onProtestTimeChanged(this);
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -65,6 +65,7 @@ import com.sap.sailing.gwt.server.HomeServiceUtil;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.media.MediaType;
|
||||
@@ -287,8 +288,8 @@ public class RaceContext {
|
||||
}
|
||||
switch (state.getStatus()) {
|
||||
case FINISHED:
|
||||
TimePoint protestStartTime = state.getProtestTime();
|
||||
if (protestStartTime != null) {
|
||||
TimeRange protestTime = state.getProtestTime();
|
||||
if (protestTime != null) {
|
||||
lastUpperFlag = Flags.BRAVO;
|
||||
lastLowerFlag = Flags.NONE;
|
||||
lastFlagsAreDisplayed = true;
|
||||
|
||||
+24
-11
@@ -51,8 +51,10 @@ public class RaceDetailPanel extends SimplePanel {
|
||||
private final Label startDateLabel = new Label();
|
||||
private final Label finishTimeLabel = new Label();
|
||||
private final Label finishDurationLabel = new Label();
|
||||
private final Label protestTimeLabel = new Label();
|
||||
private final Label protestDateLabel = new Label();
|
||||
private final Label protestStartTimeLabel = new Label();
|
||||
private final Label protestFinishTimeLabel = new Label();
|
||||
private final Label protestStartDateLabel = new Label();
|
||||
private final Label protestFinishDateLabel = new Label();
|
||||
private final Label updateTimeLabel = new Label();
|
||||
private final Label updateDateLabel = new Label();
|
||||
private final Label vesselPositionLabel = new Label();
|
||||
@@ -88,17 +90,20 @@ public class RaceDetailPanel extends SimplePanel {
|
||||
|
||||
int cellSpacing = 3;
|
||||
|
||||
Grid basicsGrid = new Grid(3, 3);
|
||||
Grid basicsGrid = new Grid(4, 3);
|
||||
basicsGrid.setCellSpacing(cellSpacing);
|
||||
basicsGrid.setWidget(0, 0, new Label(stringMessages.startAt()));
|
||||
basicsGrid.setWidget(1, 0, new Label(stringMessages.finishAt()));
|
||||
basicsGrid.setWidget(2, 0, new Label(stringMessages.protestEndsAt()));
|
||||
basicsGrid.setWidget(2, 0, new Label(stringMessages.protestStartsAt()));
|
||||
basicsGrid.setWidget(3, 0, new Label(stringMessages.protestEndsAt()));
|
||||
basicsGrid.setWidget(0, 1, startTimeLabel);
|
||||
basicsGrid.setWidget(1, 1, finishTimeLabel);
|
||||
basicsGrid.setWidget(2, 1, protestTimeLabel);
|
||||
basicsGrid.setWidget(2, 1, protestStartTimeLabel);
|
||||
basicsGrid.setWidget(3, 1, protestFinishTimeLabel);
|
||||
basicsGrid.setWidget(0, 2, startDateLabel);
|
||||
basicsGrid.setWidget(1, 2, finishDurationLabel);
|
||||
basicsGrid.setWidget(2, 2, protestDateLabel);
|
||||
basicsGrid.setWidget(2, 2, protestStartDateLabel);
|
||||
basicsGrid.setWidget(3, 2, protestFinishDateLabel);
|
||||
|
||||
Grid managementGrid = new Grid(3, 3);
|
||||
managementGrid.setCellSpacing(cellSpacing);
|
||||
@@ -167,13 +172,21 @@ public class RaceDetailPanel extends SimplePanel {
|
||||
}
|
||||
finishDurationLabel.setText(finishDurationText);
|
||||
|
||||
String protestTimeText = data.raceInfo.protestFinishTime == null ? "-" : timeFormatter
|
||||
.format(data.raceInfo.protestFinishTime);
|
||||
protestTimeLabel.setText(protestTimeText);
|
||||
String protestStartTimeText = data.raceInfo.protestStartTime == null ? "-" : timeFormatter
|
||||
.format(data.raceInfo.protestStartTime);
|
||||
protestStartTimeLabel.setText(protestStartTimeText);
|
||||
|
||||
String protestDateText = data.raceInfo.protestFinishTime == null ? "" : dateFormatter
|
||||
String protestFinishTimeText = data.raceInfo.protestFinishTime == null ? "-" : timeFormatter
|
||||
.format(data.raceInfo.protestFinishTime);
|
||||
protestDateLabel.setText(protestDateText);
|
||||
protestFinishTimeLabel.setText(protestFinishTimeText);
|
||||
|
||||
String protestStartDateText = data.raceInfo.protestStartTime == null ? "" : dateFormatter
|
||||
.format(data.raceInfo.protestStartTime);
|
||||
protestStartDateLabel.setText(protestStartDateText);
|
||||
|
||||
String protestFinishDateText = data.raceInfo.protestFinishTime == null ? "" : dateFormatter
|
||||
.format(data.raceInfo.protestFinishTime);
|
||||
protestFinishDateLabel.setText(protestFinishDateText);
|
||||
|
||||
String updateTimeText = data.raceInfo.lastUpdateTime == null ? "-" : timeFormatter
|
||||
.format(data.raceInfo.lastUpdateTime);
|
||||
|
||||
+1
-2
@@ -83,9 +83,8 @@ public class RegattaOverviewEntryPoint extends AbstractSailingEntryPoint {
|
||||
}
|
||||
|
||||
private void toggleDetailPanel(boolean visibile) {
|
||||
containerPanel.setWidgetSize(detailPanel, visibile ? 110 : 0);
|
||||
containerPanel.setWidgetSize(detailPanel, visibile ? 125 : 0);
|
||||
containerPanel.animate(500);
|
||||
// containerPanel.setWidgetHidden(detailPanel, !visibile);
|
||||
}
|
||||
|
||||
private void createAndAddRegattaPanel(UUID eventId, boolean ignoreLocalSettings) {
|
||||
|
||||
+1
@@ -811,6 +811,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
|
||||
String showingDetailsOfRace(String raceName);
|
||||
String startAt();
|
||||
String finishAt();
|
||||
String protestStartsAt();
|
||||
String protestEndsAt();
|
||||
String unknown();
|
||||
String raceLog();
|
||||
|
||||
+1
@@ -793,6 +793,7 @@ earlyStarters=Early starters
|
||||
showingDetailsOfRace=Showing details for race {0}
|
||||
startAt=Start at
|
||||
finishAt=Finish at
|
||||
protestStartsAt=Protest starts at
|
||||
protestEndsAt=Protest ends at
|
||||
unknown=Unknown
|
||||
raceLog=Race log
|
||||
|
||||
+1
@@ -786,6 +786,7 @@ earlyStarters=Frühstarter
|
||||
showingDetailsOfRace=Informationen zu Rennen {0}
|
||||
startAt=Start
|
||||
finishAt=Rennende
|
||||
protestStartsAt=Protestzeit beginnt
|
||||
protestEndsAt=Protestzeit endet
|
||||
unknown=Unbekannt
|
||||
raceLog=RaceLog
|
||||
|
||||
+11
-8
@@ -943,14 +943,17 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
|
||||
if (raceInfoDTO.lastStatus.equals(RaceLogRaceStatus.FINISHED)) {
|
||||
TimePoint protestStartTime = state.getProtestTime();
|
||||
if (protestStartTime != null) {
|
||||
final Duration protestDuration = Duration.ONE_MINUTE.times(90); // 90 min protest duration; see bug 3089 (make protest time variable)
|
||||
raceInfoDTO.protestFinishTime = protestStartTime.plus(protestDuration).asDate();
|
||||
raceInfoDTO.lastUpperFlag = Flags.BRAVO;
|
||||
raceInfoDTO.lastLowerFlag = Flags.NONE;
|
||||
raceInfoDTO.lastFlagsAreDisplayed = true;
|
||||
raceInfoDTO.lastFlagsDisplayedStateChanged = true;
|
||||
if (state.getProtestTime() != null) {
|
||||
final TimePoint protestEndTime = state.getProtestTime().to();
|
||||
if (protestEndTime != null) {
|
||||
final TimePoint protestStartTime = state.getProtestTime().from();
|
||||
raceInfoDTO.protestStartTime = protestStartTime == null ? null : protestStartTime.asDate();
|
||||
raceInfoDTO.protestFinishTime = protestEndTime.asDate();
|
||||
raceInfoDTO.lastUpperFlag = Flags.BRAVO;
|
||||
raceInfoDTO.lastLowerFlag = Flags.NONE;
|
||||
raceInfoDTO.lastFlagsAreDisplayed = true;
|
||||
raceInfoDTO.lastFlagsDisplayedStateChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -45,6 +45,7 @@ public class RaceInfoDTO implements IsSerializable {
|
||||
public RaceLogRaceStatus lastStatus;
|
||||
public Date startTime;
|
||||
public Date finishedTime;
|
||||
public Date protestStartTime;
|
||||
public Date protestFinishTime;
|
||||
public Date lastUpdateTime;
|
||||
public Flags lastUpperFlag;
|
||||
|
||||
+8
@@ -4,6 +4,14 @@
|
||||
<div id="mainContent">
|
||||
<h4 class="articleHeadline">What's New - SAP Sailing Race Manager</h4>
|
||||
<div class="innerContent">
|
||||
<h5 class="articleSubheadline">November 2016</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
<li>The protest time is now more configurable. You can set the start time and
|
||||
the duration. The default protest duration is 90 min and the last duration is
|
||||
stored in the settings, so you don't need to change it the next time.</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="articleSubheadline">October 2016</h5>
|
||||
|
||||
<ul class="bulletList">
|
||||
|
||||
+5
-1
@@ -17,8 +17,11 @@ import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.impl.FleetImpl;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
|
||||
public class TestRaceLogRemovalInRegatta extends AbstractTestStoringAndRetrievingRaceLogInRegatta {
|
||||
private final String blueFleetName = "Blue";
|
||||
@@ -51,7 +54,8 @@ public class TestRaceLogRemovalInRegatta extends AbstractTestStoringAndRetrievin
|
||||
Fleet blueFleet = qualification.getFleetByName(blueFleetName);
|
||||
RaceLog yellowLog = qualification.getRaceColumnByName(raceColumnName).getRaceLog(yellowFleet);
|
||||
RaceLog blueLog = qualification.getRaceColumnByName(raceColumnName).getRaceLog(blueFleet);
|
||||
RaceLogProtestStartTimeEvent expectedEventYellow = new RaceLogProtestStartTimeEventImpl(now, author, 0, MillisecondsTimePoint.now());
|
||||
TimeRange protestTime = new TimeRangeImpl(MillisecondsTimePoint.now(), MillisecondsTimePoint.now().plus(Duration.ONE_MINUTE.times(90)));
|
||||
RaceLogProtestStartTimeEvent expectedEventYellow = new RaceLogProtestStartTimeEventImpl(now, author, 0, protestTime);
|
||||
yellowLog.add(expectedEventYellow);
|
||||
RaceLogStartTimeEvent expectedEventBlue = new RaceLogStartTimeEventImpl(now, author, 0, MillisecondsTimePoint.now());
|
||||
blueLog.add(expectedEventBlue);
|
||||
|
||||
+14
-5
@@ -81,8 +81,10 @@ import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
|
||||
public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoDBTest {
|
||||
|
||||
@@ -121,8 +123,10 @@ public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoD
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreAndRetrieveSimpleLeaderboardWithRaceLogProtestStartTimeEvent() {
|
||||
RaceLogProtestStartTimeEvent expectedEvent = new RaceLogProtestStartTimeEventImpl(now, author, 0, MillisecondsTimePoint.now());
|
||||
public void testStoreAndRetrieveSimpleLeaderboardWithRaceLogProtestStartTimeEvent() {
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
TimeRange protestTime = new TimeRangeImpl(now, now.plus(Duration.ONE_MINUTE.times(90)));
|
||||
RaceLogProtestStartTimeEvent expectedEvent = new RaceLogProtestStartTimeEventImpl(now, author, 0, protestTime);
|
||||
addAndStoreRaceLogEvent(leaderboard, raceColumnName, expectedEvent);
|
||||
RaceLog loadedRaceLog = retrieveRaceLog();
|
||||
loadedRaceLog.lockForRead();
|
||||
@@ -132,7 +136,8 @@ public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoD
|
||||
assertEquals(expectedEvent.getLogicalTimePoint(), actualEvent.getLogicalTimePoint());
|
||||
assertEquals(expectedEvent.getPassId(), actualEvent.getPassId());
|
||||
assertEquals(expectedEvent.getId(), actualEvent.getId());
|
||||
assertEquals(expectedEvent.getProtestStartTime(), actualEvent.getProtestStartTime());
|
||||
assertEquals(expectedEvent.getProtestTime().from(), actualEvent.getProtestTime().from());
|
||||
assertEquals(expectedEvent.getProtestTime().to(), actualEvent.getProtestTime().to());
|
||||
assertEquals(1, Util.size(loadedRaceLog.getFixes()));
|
||||
} finally {
|
||||
loadedRaceLog.unlockAfterRead();
|
||||
@@ -141,7 +146,9 @@ public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoD
|
||||
|
||||
@Test
|
||||
public void testThatRemoveRaceColumnAlsoRemovesPersistentRaceLog() {
|
||||
RaceLogProtestStartTimeEvent expectedEvent = new RaceLogProtestStartTimeEventImpl(now, author, 0, MillisecondsTimePoint.now());
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
TimeRange protestTime = new TimeRangeImpl(now, now.plus(Duration.ONE_MINUTE.times(90)));
|
||||
RaceLogProtestStartTimeEvent expectedEvent = new RaceLogProtestStartTimeEventImpl(now, author, 0, protestTime);
|
||||
Fleet defaultFleet = leaderboard.getFleet(null);
|
||||
RaceColumn raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
|
||||
raceColumn.getRaceLog(defaultFleet).add(expectedEvent);
|
||||
@@ -167,7 +174,9 @@ public class TestStoringAndRetrievingRaceLogInLeaderboards extends RaceLogMongoD
|
||||
when(service.getMongoObjectFactory()).thenReturn(mongoObjectFactory);
|
||||
when(service.getLeaderboardByName(leaderboardName)).thenReturn(leaderboard);
|
||||
doCallRealMethod().when(service).renameLeaderboardColumn(Matchers.anyString(), Matchers.anyString(), Matchers.anyString());
|
||||
RaceLogProtestStartTimeEvent expectedEvent = new RaceLogProtestStartTimeEventImpl(now, author, 0, MillisecondsTimePoint.now());
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
TimeRange protestTime = new TimeRangeImpl(now, now.plus(Duration.ONE_MINUTE.times(90)));
|
||||
RaceLogProtestStartTimeEvent expectedEvent = new RaceLogProtestStartTimeEventImpl(now, author, 0, protestTime);
|
||||
Fleet defaultFleet = leaderboard.getFleet(null);
|
||||
RaceColumn raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
|
||||
raceColumn.getRaceLog(defaultFleet).add(expectedEvent);
|
||||
|
||||
+10
-3
@@ -63,8 +63,12 @@ import com.sap.sailing.domain.persistence.impl.FieldNames;
|
||||
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
||||
import com.sap.sailing.domain.persistence.impl.TripleSerializer;
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
|
||||
public class TestStoringAndRetrievingRaceLogInRegatta extends AbstractTestStoringAndRetrievingRaceLogInRegatta {
|
||||
public TestStoringAndRetrievingRaceLogInRegatta() throws UnknownHostException, MongoException {
|
||||
@@ -96,8 +100,10 @@ public class TestStoringAndRetrievingRaceLogInRegatta extends AbstractTestStorin
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStoreAndRetrieveRegattaWithRaceLogProtestStartTimeEvent() {
|
||||
RaceLogProtestStartTimeEvent expectedEvent = new RaceLogProtestStartTimeEventImpl(now, author, 0, MillisecondsTimePoint.now());
|
||||
public void testStoreAndRetrieveRegattaWithRaceLogProtestStartTimeEvent() {
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
TimeRange protestTime = new TimeRangeImpl(now, now.plus(Duration.ONE_MINUTE.times(90)));
|
||||
RaceLogProtestStartTimeEvent expectedEvent = new RaceLogProtestStartTimeEventImpl(now, author, 0, protestTime);
|
||||
addAndStoreRaceLogEvent(regatta, raceColumnName, expectedEvent);
|
||||
RaceLog loadedRaceLog = retrieveRaceLog();
|
||||
loadedRaceLog.lockForRead();
|
||||
@@ -107,7 +113,8 @@ public class TestStoringAndRetrievingRaceLogInRegatta extends AbstractTestStorin
|
||||
assertEquals(expectedEvent.getLogicalTimePoint(), actualEvent.getLogicalTimePoint());
|
||||
assertEquals(expectedEvent.getPassId(), actualEvent.getPassId());
|
||||
assertEquals(expectedEvent.getId(), actualEvent.getId());
|
||||
assertEquals(expectedEvent.getProtestStartTime(), actualEvent.getProtestStartTime());
|
||||
assertEquals(expectedEvent.getProtestTime().from(), actualEvent.getProtestTime().from());
|
||||
assertEquals(expectedEvent.getProtestTime().to(), actualEvent.getProtestTime().to());
|
||||
assertEquals(1, Util.size(loadedRaceLog.getFixes()));
|
||||
} finally {
|
||||
loadedRaceLog.unlockAfterRead();
|
||||
|
||||
+6
-3
@@ -13,7 +13,9 @@ import com.sap.sailing.server.gateway.deserialization.JsonDeserializationExcepti
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.serialization.racelog.impl.RaceLogProtestStartTimeEventSerializer;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
|
||||
public class RaceLogProtestStartTimeEventDeserializer extends BaseRaceLogEventDeserializer {
|
||||
|
||||
@@ -24,9 +26,10 @@ public class RaceLogProtestStartTimeEventDeserializer extends BaseRaceLogEventDe
|
||||
@Override
|
||||
protected RaceLogEvent deserialize(JSONObject object, Serializable id, TimePoint createdAt, AbstractLogEventAuthor author,
|
||||
TimePoint timePoint, int passId, List<Competitor> competitors) throws JsonDeserializationException {
|
||||
Long protestStartTime = (Long) object.get(RaceLogProtestStartTimeEventSerializer.FIELD_PROTEST_START_TIME);
|
||||
return new RaceLogProtestStartTimeEventImpl(createdAt, timePoint, author, id,
|
||||
passId, new MillisecondsTimePoint(protestStartTime));
|
||||
Long protestStart = (Long) object.get(RaceLogProtestStartTimeEventSerializer.FIELD_PROTEST_START_TIME);
|
||||
Long protestEnd = (Long) object.get(RaceLogProtestStartTimeEventSerializer.FIELD_PROTEST_END_TIME);
|
||||
TimeRange protestTime = new TimeRangeImpl(new MillisecondsTimePoint(protestStart), new MillisecondsTimePoint(protestEnd));
|
||||
return new RaceLogProtestStartTimeEventImpl(createdAt, timePoint, author, id, passId, protestTime);
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -11,6 +11,7 @@ public class RaceLogProtestStartTimeEventSerializer extends BaseRaceLogEventSeri
|
||||
|
||||
public static final String VALUE_CLASS = RaceLogProtestStartTimeEvent.class.getSimpleName();
|
||||
public static final String FIELD_PROTEST_START_TIME = "protestStartTime";
|
||||
public static final String FIELD_PROTEST_END_TIME = "protestEndTime";
|
||||
|
||||
public RaceLogProtestStartTimeEventSerializer(JsonSerializer<Competitor> competitorSerializer) {
|
||||
super(competitorSerializer);
|
||||
@@ -25,7 +26,8 @@ public class RaceLogProtestStartTimeEventSerializer extends BaseRaceLogEventSeri
|
||||
public JSONObject serialize(RaceLogEvent object) {
|
||||
RaceLogProtestStartTimeEvent event = (RaceLogProtestStartTimeEvent) object;
|
||||
JSONObject result = super.serialize(event);
|
||||
result.put(FIELD_PROTEST_START_TIME, event.getProtestStartTime().asMillis());
|
||||
result.put(FIELD_PROTEST_START_TIME, event.getProtestTime().from().asMillis());
|
||||
result.put(FIELD_PROTEST_END_TIME, event.getProtestTime().to().asMillis());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/protest_duration"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="24dp"
|
||||
android:inputType="number"
|
||||
android:textColor="?black" />
|
||||
</FrameLayout>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
@@ -10,22 +10,57 @@
|
||||
android:id="@+id/protest_time_races_list"
|
||||
android:layout_width="400dp"
|
||||
android:layout_height="match_parent"
|
||||
android:verticalSpacing="2dp"/>
|
||||
android:verticalSpacing="2dp" />
|
||||
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleX="@integer/picker_scale"
|
||||
android:scaleY="@integer/picker_scale"
|
||||
android:layout_marginLeft="@dimen/default_margin_twice"
|
||||
android:paddingRight="@dimen/default_padding"
|
||||
android:paddingLeft="@dimen/default_padding">
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/protest_time_time_picker"
|
||||
layout="@layout/time_picker"
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
</RelativeLayout>
|
||||
android:layout_marginLeft="@dimen/default_margin_twice"
|
||||
android:paddingLeft="@dimen/default_padding"
|
||||
android:paddingRight="@dimen/default_padding"
|
||||
android:scaleX="@integer/picker_scale"
|
||||
android:scaleY="@integer/picker_scale">
|
||||
|
||||
<include
|
||||
android:id="@+id/protest_time_time_picker"
|
||||
layout="@layout/time_picker"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/protest_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textAppearance="?attr/textXSmall"
|
||||
tools:text="@string/protest_duration" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/change_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:src="?attr/create" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/protest_end"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?attr/textXSmall"
|
||||
tools:text="@string/protest_end_time" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -27,7 +26,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="?attr/chevron_left_24dp"/>
|
||||
android:src="?attr/chevron_left_24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/header_caption"
|
||||
@@ -35,7 +34,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/protest_dialog_title"
|
||||
android:textAppearance="?attr/textHeader"/>
|
||||
android:textAppearance="?attr/textHeader" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
@@ -43,7 +42,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/header_line"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="?attr/black"/>
|
||||
android:background="?attr/black" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
@@ -60,7 +59,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/thin_line"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="?attr/sap_gray"/>
|
||||
android:background="?attr/sap_gray" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/choose"
|
||||
@@ -71,7 +70,7 @@
|
||||
android:layout_marginBottom="@dimen/default_margin_half"
|
||||
android:layout_marginTop="@dimen/default_margin_half"
|
||||
android:text="@string/choose"
|
||||
android:textSize="@dimen/textSize_18"/>
|
||||
android:textSize="@dimen/textSize_18" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
@@ -93,7 +92,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="?attr/button_prev"/>
|
||||
android:src="?attr/button_prev" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/nav_next"
|
||||
@@ -101,7 +100,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="?attr/button_next"/>
|
||||
android:src="?attr/button_next" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
@@ -114,13 +113,13 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="5dp"
|
||||
tools:src="@drawable/ic_dot"/>
|
||||
tools:src="@drawable/ic_dot" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/dot_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:src="@drawable/ic_dot"/>
|
||||
tools:src="@drawable/ic_dot" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -138,26 +137,71 @@
|
||||
android:layout_height="match_parent"
|
||||
android:verticalSpacing="2dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="gone"/>
|
||||
tools:visibility="gone" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/protest_time_time_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleX="@integer/picker_scale"
|
||||
android:scaleY="@integer/picker_scale"
|
||||
android:visibility="gone"
|
||||
tools:visibility="gone">
|
||||
tools:visibility="visible">
|
||||
|
||||
<include
|
||||
android:id="@+id/protest_time_time_picker"
|
||||
layout="@layout/time_picker"
|
||||
<RelativeLayout
|
||||
android:id="@+id/time_picker"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_gravity="center"
|
||||
android:paddingLeft="@dimen/default_padding"
|
||||
android:paddingRight="@dimen/default_padding"/>
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_centerHorizontal="true">
|
||||
|
||||
<include
|
||||
android:id="@+id/protest_time_time_picker"
|
||||
layout="@layout/time_picker"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:paddingLeft="@dimen/default_padding"
|
||||
android:paddingRight="@dimen/default_padding"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/protest_time_time_picker"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/protest_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textAppearance="?attr/textXSmall"
|
||||
tools:text="@string/protest_duration" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/change_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:src="?attr/create" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/protest_end"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?attr/textXSmall"
|
||||
tools:text="@string/protest_end_time" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
</FrameLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -66,6 +66,9 @@
|
||||
<string name="protest_dialog_title">Beginn der Protestzeit</string>
|
||||
<string name="finished_dialog_title">Rennende setzen</string>
|
||||
<string name="protest_start_time">Protestzeit beginnt: %s</string>
|
||||
<string name="protest_duration">Protestdauer: %d Min</string>
|
||||
<string name="protest_end_time">Protestzeit endet: %s</string>
|
||||
<string name="protest_duration_dialog_title">Dauer in Minuten</string>
|
||||
<string name="no_pathfinder_selected">Kein Pathfinder gesetzt</string>
|
||||
<string name="set_line_opening_time">Gate Launch</string>
|
||||
<string name="no_line_opening_time_selected">Keine Zeit gesetzt</string>
|
||||
@@ -439,6 +442,7 @@
|
||||
<string name="preference_allow_dependent_races_description">Aktiviert relative Startzeiten zwischen Rennen</string>
|
||||
<string name="preference_dependent_races_offset_header">Standard Offset der relativen Startzeit (Minuten)</string>
|
||||
<string name="preference_allow_edit_race_factor_header">Rennfaktor ändern</string>
|
||||
<string name="preference_protest_time_header">Protestzeit Dauer (Minuten)</string>
|
||||
<string name="preference_allow_edit_race_factor_description">Rennleiter können den Rennfaktor je Rennen ändern</string>
|
||||
<string name="error_finished_time">Die ausgewählte Zielzeit liegt vor der Zeit, der ersten Schiffeinfahrt. Bitte überprüfe die Uhrzeit.</string>
|
||||
<string name="error_finishing_time">Die ausgewählte Zeit is vor dem Rennstart. Bitte überprüfe die Uhrzeit.</string>
|
||||
|
||||
@@ -100,6 +100,8 @@
|
||||
<integer name="preference_dependent_races_offset_default">5</integer>
|
||||
<string name="preference_allow_edit_race_factor_key" translatable="false">raceFactor</string>
|
||||
<bool name="preference_allow_edit_race_factor_default">true</bool>
|
||||
<string name="preference_protest_time_duration_key">protestTimeDuration</string>
|
||||
<integer name="preference_protest_time_duration_default">90</integer>
|
||||
|
||||
<string name="preference_allow_demo_key" translatable="false">allow_demo</string>
|
||||
<bool name="preference_allow_demo_default">false</bool>
|
||||
|
||||
@@ -81,6 +81,9 @@
|
||||
<string name="protest_dialog_title">Protest start time</string>
|
||||
<string name="finished_dialog_title">Set the time when the race finished</string>
|
||||
<string name="protest_start_time">Protest start time: %s</string>
|
||||
<string name="protest_duration">Protest duration: %d min</string>
|
||||
<string name="protest_end_time">Protest end time: %s</string>
|
||||
<string name="protest_duration_dialog_title">Duration in Minutes</string>
|
||||
<string name="no_pathfinder_selected">No Pathfinder selected</string>
|
||||
<string name="set_line_opening_time">Gate Launch</string>
|
||||
<string name="no_line_opening_time_selected">No time selected</string>
|
||||
@@ -461,8 +464,9 @@
|
||||
<string name="data_reload_message">Data has to be reloaded. Possible data loss is possible.</string>
|
||||
<string name="preference_allow_dependent_races_header">Relative Start Time (Minutes)</string>
|
||||
<string name="preference_allow_dependent_races_description">Enable Relative Start Time between Races</string>
|
||||
<string name="preference_dependent_races_offset_header">Default Relative Start Time Offset</string>
|
||||
<string name="preference_dependent_races_offset_header">Default Relative Start Time Offset (Minutes)</string>
|
||||
<string name="preference_allow_edit_race_factor_header">Race factor change</string>
|
||||
<string name="preference_protest_time_header">Protest Time Duration (Minutes)</string>
|
||||
<string name="preference_allow_edit_race_factor_description">Race managers can change the race factor per race</string>
|
||||
<string name="error_finished_time">The given finish time is earlier than the first finisher time. Please recheck the time.</string>
|
||||
<string name="error_finishing_time">The selected time is before the race start.</string>
|
||||
|
||||
@@ -40,6 +40,12 @@
|
||||
android:key="@string/preference_allow_edit_race_factor_key"
|
||||
android:summary="@string/preference_allow_edit_race_factor_description"
|
||||
android:title="@string/preference_allow_edit_race_factor_header" />
|
||||
|
||||
<com.sap.sailing.racecommittee.app.ui.views.IntegerEditTextPreference
|
||||
android:defaultValue="@integer/preference_protest_time_duration_default"
|
||||
android:key="@string/preference_protest_time_duration_key"
|
||||
android:numeric="integer"
|
||||
android:title="@string/preference_protest_time_header"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="RRS26">
|
||||
|
||||
+9
@@ -474,6 +474,15 @@ public class AppPreferences {
|
||||
.getInteger(R.integer.preference_dependent_races_offset_default));
|
||||
}
|
||||
|
||||
public int getProtestTimeDuration() {
|
||||
return helper.getInt(context.getString(R.string.preference_protest_time_duration_key), context.getResources()
|
||||
.getInteger(R.integer.preference_protest_time_duration_default));
|
||||
}
|
||||
|
||||
public void setProtestTimeDuration(int value) {
|
||||
helper.getEditor().putInt(context.getString(R.string.preference_protest_time_duration_key), value).commit();
|
||||
}
|
||||
|
||||
public String getTheme() {
|
||||
return helper.getString(context.getString(R.string.preference_theme_key), context.getResources().getString(R.string.preference_theme_default));
|
||||
}
|
||||
|
||||
+76
-3
@@ -7,6 +7,8 @@ import java.util.List;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
@@ -18,8 +20,11 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TimePicker;
|
||||
|
||||
import com.sap.sailing.android.shared.util.BitmapHelper;
|
||||
@@ -30,14 +35,18 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishedTimeFinder
|
||||
import com.sap.sailing.domain.base.racegroup.RaceGroupSeriesFleet;
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
import com.sap.sailing.racecommittee.app.AppConstants;
|
||||
import com.sap.sailing.racecommittee.app.AppPreferences;
|
||||
import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.data.DataManager;
|
||||
import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager;
|
||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||
import com.sap.sailing.racecommittee.app.utils.ThemeHelper;
|
||||
import com.sap.sailing.racecommittee.app.utils.TimeUtils;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
|
||||
public class ProtestTimeDialogFragment extends AttachedDialogFragment implements View.OnClickListener {
|
||||
|
||||
@@ -51,9 +60,12 @@ public class ProtestTimeDialogFragment extends AttachedDialogFragment implements
|
||||
private List<ManagedRace> races;
|
||||
private ListView mRacesList;
|
||||
private TimePicker mTimePicker;
|
||||
private TextView mProtestDuration;
|
||||
private TextView mProtestEndTime;
|
||||
private View customView;
|
||||
private View mHome;
|
||||
private Button mChoose;
|
||||
private AppPreferences mPreferences;
|
||||
|
||||
public ProtestTimeDialogFragment() {
|
||||
races = new ArrayList<>();
|
||||
@@ -88,6 +100,7 @@ public class ProtestTimeDialogFragment extends AttachedDialogFragment implements
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
mPreferences = AppPreferences.on(getActivity());
|
||||
View layout = super.onCreateView(inflater, container, savedInstanceState);
|
||||
if (customView == null) {
|
||||
layout = inflater.inflate(R.layout.protest_time_fragment, container, false);
|
||||
@@ -146,6 +159,14 @@ public class ProtestTimeDialogFragment extends AttachedDialogFragment implements
|
||||
});
|
||||
}
|
||||
|
||||
mProtestDuration = ViewHelper.get(layout, R.id.protest_duration);
|
||||
mProtestEndTime = ViewHelper.get(layout, R.id.protest_end);
|
||||
View changeDuration = ViewHelper.get(layout, R.id.change_duration);
|
||||
if (changeDuration != null) {
|
||||
changeDuration.setOnClickListener(new DurationChangeListener());
|
||||
}
|
||||
updateProtestRange();
|
||||
|
||||
viewPanel(MOVE_NONE);
|
||||
}
|
||||
return layout;
|
||||
@@ -189,12 +210,20 @@ public class ProtestTimeDialogFragment extends AttachedDialogFragment implements
|
||||
}
|
||||
|
||||
private View setupView() {
|
||||
mPreferences = AppPreferences.on(getActivity());
|
||||
LayoutInflater inflater = LayoutInflater.from(getActivity());
|
||||
View view = inflater.inflate(R.layout.protest_time_dialog, null);
|
||||
mRacesList = (ListView) view.findViewById(R.id.protest_time_races_list);
|
||||
setupRacesList(mRacesList);
|
||||
mTimePicker = (TimePicker) view.findViewById(R.id.protest_time_time_picker);
|
||||
setupTimePicker(mTimePicker);
|
||||
mProtestDuration = (TextView) view.findViewById(R.id.protest_duration);
|
||||
mProtestEndTime = (TextView) view.findViewById(R.id.protest_end);
|
||||
View changeDuration = view.findViewById(R.id.change_duration);
|
||||
if (changeDuration != null) {
|
||||
changeDuration.setOnClickListener(new DurationChangeListener());
|
||||
}
|
||||
updateProtestRange();
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
// TODO: @Samuel -> please check, why we did this, because I can't remember
|
||||
@@ -249,6 +278,13 @@ public class ProtestTimeDialogFragment extends AttachedDialogFragment implements
|
||||
timePicker.setCurrentHour(hours);
|
||||
timePicker.setCurrentMinute(minutes);
|
||||
|
||||
timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
|
||||
@Override
|
||||
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
|
||||
updateProtestRange();
|
||||
}
|
||||
});
|
||||
|
||||
ThemeHelper.setPickerColor(getActivity(), timePicker, ThemeHelper.getColor(getActivity(), R.attr.white), ThemeHelper
|
||||
.getColor(getActivity(), R.attr.sap_yellow_1));
|
||||
}
|
||||
@@ -270,9 +306,11 @@ public class ProtestTimeDialogFragment extends AttachedDialogFragment implements
|
||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
|
||||
private void setAndAnnounceProtestTime() {
|
||||
List<ManagedRace> selectedRaces = getSelectedRaces();
|
||||
TimePoint protestTime = TimeUtils.getTime(mTimePicker);
|
||||
TimePoint startTime = TimeUtils.getTime(mTimePicker);
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
for (ManagedRace race : selectedRaces) {
|
||||
Duration duration = Duration.ONE_MINUTE.times(AppPreferences.on(getActivity()).getProtestTimeDuration());
|
||||
TimeRange protestTime = new TimeRangeImpl(startTime, startTime.plus(duration));
|
||||
race.getState().setProtestTime(now, protestTime);
|
||||
}
|
||||
if (mHome != null) {
|
||||
@@ -306,7 +344,6 @@ public class ProtestTimeDialogFragment extends AttachedDialogFragment implements
|
||||
viewPanel(MOVE_UP);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void viewPanel(int direction) {
|
||||
@@ -353,6 +390,18 @@ public class ProtestTimeDialogFragment extends AttachedDialogFragment implements
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProtestRange() {
|
||||
int duration = mPreferences.getProtestTimeDuration();
|
||||
if (mProtestDuration != null) {
|
||||
mProtestDuration.setText(getString(R.string.protest_duration, duration));
|
||||
}
|
||||
if (mProtestEndTime != null) {
|
||||
TimePoint startTime = TimeUtils.getTime(mTimePicker);
|
||||
TimePoint endTime = startTime.plus(Duration.ONE_MINUTE.times(duration));
|
||||
mProtestEndTime.setText(getString(R.string.protest_end_time, TimeUtils.formatTime(endTime)));
|
||||
}
|
||||
}
|
||||
|
||||
private static class ProtestTimeAdapter extends ArrayAdapter<ManagedRaceItem> {
|
||||
|
||||
public ProtestTimeAdapter(Context context, List<ManagedRace> objects) {
|
||||
@@ -360,7 +409,7 @@ public class ProtestTimeDialogFragment extends AttachedDialogFragment implements
|
||||
}
|
||||
|
||||
private static List<ManagedRaceItem> wrap(List<ManagedRace> races) {
|
||||
List<ManagedRaceItem> wrapped = new ArrayList<ManagedRaceItem>();
|
||||
List<ManagedRaceItem> wrapped = new ArrayList<>();
|
||||
for (ManagedRace race : races) {
|
||||
wrapped.add(new ManagedRaceItem(race));
|
||||
}
|
||||
@@ -384,4 +433,28 @@ public class ProtestTimeDialogFragment extends AttachedDialogFragment implements
|
||||
return String.format("%s - %s", group.getDisplayName(true), race.getRaceColumnName());
|
||||
}
|
||||
}
|
||||
|
||||
private class DurationChangeListener implements View.OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
FrameLayout layout = (FrameLayout) LayoutInflater.from(v.getContext()).inflate(R.layout.protest_duration, null);
|
||||
final EditText duration = (EditText) layout.findViewById(R.id.protest_duration);
|
||||
duration.setText(String.valueOf(mPreferences.getProtestTimeDuration()));
|
||||
duration.setSelection(duration.length());
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextWrapper(v.getContext()), R.style.AppTheme_AlertDialog);
|
||||
builder.setTitle(v.getContext().getString(R.string.protest_duration_dialog_title));
|
||||
builder.setView(layout);
|
||||
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
int value = Integer.parseInt(duration.getText().toString());
|
||||
mPreferences.setProtestTimeDuration(value);
|
||||
updateProtestRange();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -77,6 +77,7 @@ public class RegattaPreferenceFragment extends BasePreferenceFragment {
|
||||
setupRacingProcedureTypePreference();
|
||||
setupCourseDesignerTypePreference();
|
||||
setupDependentRacesPreference();
|
||||
setupProtestTimePreference();
|
||||
}
|
||||
|
||||
private void setupRacingProcedureTypePreference() {
|
||||
@@ -117,6 +118,10 @@ public class RegattaPreferenceFragment extends BasePreferenceFragment {
|
||||
bindPreferenceSummaryToInteger(findPreference(R.string.preference_dependent_races_offset_key));
|
||||
}
|
||||
|
||||
private void setupProtestTimePreference() {
|
||||
bindPreferenceSummaryToInteger(findPreference(R.string.preference_protest_time_duration_key));
|
||||
}
|
||||
|
||||
private void setupRRS26StartmodeFlagsList() {
|
||||
MultiSelectListPreference preference = findPreference(R.string.preference_racing_procedure_rrs26_startmode_flags_key);
|
||||
List<String> flags = new ArrayList<>();
|
||||
|
||||
Reference in new issue
Block a user