Merge remote-tracking branch 'origin/master' into design2015

This commit is contained in:
Steffen Schaefer committed 2015-07-20 13:30:45 +02:00
commit af3d40ab47
112 files changed
+2837 -1547

No files matched your search

Binary file not shown.
@@ -4,7 +4,7 @@ import com.sap.sailing.domain.common.impl.MeterDistance;
public enum BoatClassMasterdata { public enum BoatClassMasterdata {
_18Footer ("18Footer", true, 8.90, 2.00, BoatHullType.MONOHULL, true, "18.Footer", "18ft", "18ft Skiff"), _18Footer ("18Footer", true, 8.90, 2.00, BoatHullType.MONOHULL, true, "18.Footer", "18ft", "18ft Skiff", "18. Footer"),
_2_4M ("2.4 Meter", true, 4.11, 0.81, BoatHullType.MONOHULL, false, "2.4M", "2.4mR", "2.4 Metre", "2.4-metre"), _2_4M ("2.4 Meter", true, 4.11, 0.81, BoatHullType.MONOHULL, false, "2.4M", "2.4mR", "2.4 Metre", "2.4-metre"),
_5O5 ("5O5", true, 5.03, 1.88, BoatHullType.MONOHULL, true, "505", "5o5", "505er", "5o5er"), _5O5 ("5O5", true, 5.03, 1.88, BoatHullType.MONOHULL, true, "505", "5o5", "505er", "5o5er"),
_12M ("12 Meter", true, 5.97, 1.43, BoatHullType.MONOHULL, true, "12M", "12mR", "12SQM", "12-metre", "12 metre"), _12M ("12 Meter", true, 5.97, 1.43, BoatHullType.MONOHULL, true, "12M", "12mR", "12SQM", "12-metre", "12 metre"),
@@ -31,7 +31,7 @@ public enum BoatClassMasterdata {
FINN ("Finn", true, 4.50, 1.51, BoatHullType.MONOHULL, false), FINN ("Finn", true, 4.50, 1.51, BoatHullType.MONOHULL, false),
FLYING_PHANTOM ("Flying Phantom", true, 5.52, 3.00, BoatHullType.CATAMARAN, true), FLYING_PHANTOM ("Flying Phantom", true, 5.52, 3.00, BoatHullType.CATAMARAN, true),
FOLKBOAT ("Folkboat", true, 7.68, 2.20, BoatHullType.MONOHULL, false, "Folke", "Folkeboot"), FOLKBOAT ("Folkboat", true, 7.68, 2.20, BoatHullType.MONOHULL, false, "Folke", "Folkeboot"),
FUN ("FUN", true, 7.20, 2.45, BoatHullType.MONOHULL, true, "FUN O.D.", "FUN OD"), FUN ("FUN", true, 7.20, 2.45, BoatHullType.MONOHULL, true, "FUN O.D.", "FUN OD", "Open FUN"),
F_16 ("Formula 16", true, 5.00, 2.50, BoatHullType.CATAMARAN, true, "F16", "F-16"), F_16 ("Formula 16", true, 5.00, 2.50, BoatHullType.CATAMARAN, true, "F16", "F-16"),
HOBIE_16 ("Hobie 16", true, 5.05, 2.41, BoatHullType.CATAMARAN, false, "H16"), HOBIE_16 ("Hobie 16", true, 5.05, 2.41, BoatHullType.CATAMARAN, false, "H16"),
H_BOAT ("H-Boat", true, 8.28, 2.18, BoatHullType.MONOHULL, true, "HB"), H_BOAT ("H-Boat", true, 8.28, 2.18, BoatHullType.MONOHULL, true, "HB"),
@@ -6,7 +6,7 @@ package com.sap.sailing.domain.common.racelog;
* *
*/ */
public enum RaceLogRaceStatus { public enum RaceLogRaceStatus {
UNKNOWN(0), UNSCHEDULED(1), SCHEDULED(2), STARTPHASE(3), RUNNING(4), FINISHING(5), FINISHED(6); UNKNOWN(0), UNSCHEDULED(1), PRESCHEDULED(2), SCHEDULED(3), STARTPHASE(4), RUNNING(5), FINISHING(6), FINISHED(7);
/** the order number represents the natural order of the states */ /** the order number represents the natural order of the states */
private int orderNumber; private int orderNumber;
@@ -16,11 +16,9 @@ public enum RaceLogRaceStatus {
} }
public static boolean isActive(RaceLogRaceStatus status) { public static boolean isActive(RaceLogRaceStatus status) {
if (status == null) { return status != null &&
return false; (status.equals(PRESCHEDULED) || status.equals(SCHEDULED) || status.equals(STARTPHASE) || status.equals(RUNNING) || status.equals(FINISHING));
}
return status.equals(SCHEDULED) || status.equals(STARTPHASE) || status.equals(RUNNING) || status.equals(FINISHING);
} }
public int getOrderNumber() { public int getOrderNumber() {
@@ -34,13 +34,13 @@ public class DependentStartTimeFinderTest {
private AbstractLogEventAuthor author; private AbstractLogEventAuthor author;
private TimePoint nowMock; private TimePoint nowMock;
private RaceLogResolver raceLogResolver; private RaceLogResolver raceLogResolver;
@Before @Before
public void setUp() { public void setUp() {
author = new LogEventAuthorImpl("Test", 1); author = new LogEventAuthorImpl("Test", 1);
raceLogA = new RaceLogImpl("raceLogA"); raceLogA = new RaceLogImpl("raceLogA");
raceLogB = new RaceLogImpl("raceLogB"); raceLogB = new RaceLogImpl("raceLogB");
raceLogC = new RaceLogImpl("raceLogC"); raceLogC = new RaceLogImpl("raceLogC");
@@ -63,108 +63,137 @@ public class DependentStartTimeFinderTest {
@Test @Test
public void testDependentStartTimeUpdate() { public void testDependentStartTimeUpdate() {
raceLogC.add(new RaceLogDependentStartTimeEventImpl(nowMock, author, nowMock, "12", null, 12, final MillisecondsDurationImpl cAfterB = new MillisecondsDurationImpl(5000);
new SimpleRaceLogIdentifierImpl("B", "", ""), new MillisecondsDurationImpl(5000))); raceLogC.add(new RaceLogDependentStartTimeEventImpl(nowMock, author, nowMock, "12", null, 12,
new SimpleRaceLogIdentifierImpl("B", "", ""), cAfterB));
StartTimeFinder finder = new StartTimeFinder(raceLogResolver, raceLogC); StartTimeFinder finder = new StartTimeFinder(raceLogResolver, raceLogC);
//Tests for correct behaviour, when race depending on has no starttime set // Tests for correct behaviour, when race depending on has no start time set
assertNull(finder.analyze().getStartTime()); assertNull(finder.analyze().getStartTime());
raceLogB.add(new RaceLogDependentStartTimeEventImpl(nowMock, author, nowMock, "12", null, 12, final MillisecondsDurationImpl bAfterA = new MillisecondsDurationImpl(6000);
new SimpleRaceLogIdentifierImpl("A", "", ""), new MillisecondsDurationImpl(5000))); raceLogB.add(new RaceLogDependentStartTimeEventImpl(nowMock, author, nowMock, "12", null, 12,
new SimpleRaceLogIdentifierImpl("A", "", ""), bAfterA));
finder = new StartTimeFinder(raceLogResolver, raceLogB);
StartTimeFinderResult result = finder.analyze(); finder = new StartTimeFinder(raceLogResolver, raceLogB);
StartTimeFinderResult result = finder.analyze();
List<SimpleRaceLogIdentifier> expectedDependingOnRaces = new ArrayList<SimpleRaceLogIdentifier>();
expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("A", "", "")); List<SimpleRaceLogIdentifier> expectedDependingOnRaces = new ArrayList<>();
assertNull(result.getStartTime()); expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("A", "", ""));
assertEquals(expectedDependingOnRaces, result.getRacesDependingOn()); assertNull(result.getStartTime());
assertEquals(bAfterA, result.getStartTimeDiff());
finder = new StartTimeFinder(raceLogResolver, raceLogC); assertEquals(expectedDependingOnRaces, result.getRacesDependingOn());
//Tests for correct behaviour, when race depending on has a DependentStartTimeEvent and its parent start time is unknown // assertEquals(5000, result.getStartTimeDiff().asMillis());
expectedDependingOnRaces = new ArrayList<SimpleRaceLogIdentifier>();
expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("B", "", "")); finder = new StartTimeFinder(raceLogResolver, raceLogC);
expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("A", "", "")); // Tests for correct behaviour, when race depending on has a DependentStartTimeEvent and its parent start time
// is unknown
result = finder.analyze(); expectedDependingOnRaces = new ArrayList<>();
assertNull(result.getStartTime()); expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("B", "", ""));
assertEquals(expectedDependingOnRaces, result.getRacesDependingOn()); expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("A", "", ""));
MillisecondsTimePoint now = MillisecondsTimePoint.now(); result = finder.analyze();
raceLogA.add(new RaceLogStartTimeEventImpl(now, author, now, "12", null, 12, new MillisecondsTimePoint(5000))); assertNull(result.getStartTime());
assertEquals(cAfterB, result.getStartTimeDiff());
finder = new StartTimeFinder(raceLogResolver, raceLogB); assertEquals(expectedDependingOnRaces, result.getRacesDependingOn());
assertEquals(10000, finder.analyze().getStartTime().asMillis());
finder = new StartTimeFinder(raceLogResolver, raceLogC); MillisecondsTimePoint now = MillisecondsTimePoint.now();
assertEquals(15000, finder.analyze().getStartTime().asMillis()); raceLogA.add(new RaceLogStartTimeEventImpl(now, author, now, "12", null, 12, new MillisecondsTimePoint(5000)));
//Test correct behaviour, when middle element changes finder = new StartTimeFinder(raceLogResolver, raceLogB);
raceLogB.add(new RaceLogStartTimeEventImpl(now, author, now, "12", null, 12, new MillisecondsTimePoint(15000))); result = finder.analyze();
finder = new StartTimeFinder(raceLogResolver, raceLogA); assertEquals(11000, result.getStartTime().asMillis());
assertEquals(5000, finder.analyze().getStartTime().asMillis()); assertEquals(6000, result.getStartTimeDiff().asMillis());
finder = new StartTimeFinder(raceLogResolver, raceLogB);
assertEquals(15000, finder.analyze().getStartTime().asMillis()); finder = new StartTimeFinder(raceLogResolver, raceLogC);
finder = new StartTimeFinder(raceLogResolver, raceLogC); result = finder.analyze();
assertEquals(20000, finder.analyze().getStartTime().asMillis()); assertEquals(16000, result.getStartTime().asMillis());
assertEquals(5000, result.getStartTimeDiff().asMillis());
// Test correct behaviour, when middle element changes
raceLogB.add(new RaceLogStartTimeEventImpl(now, author, now, "12", null, 12, new MillisecondsTimePoint(15000)));
finder = new StartTimeFinder(raceLogResolver, raceLogA);
result = finder.analyze();
assertEquals(5000, result.getStartTime().asMillis());
assertNull(result.getStartTimeDiff());
finder = new StartTimeFinder(raceLogResolver, raceLogB);
result = finder.analyze();
assertEquals(15000, result.getStartTime().asMillis());
assertNull(result.getStartTimeDiff());
finder = new StartTimeFinder(raceLogResolver, raceLogC);
result = finder.analyze();
assertEquals(20000, result.getStartTime().asMillis());
assertEquals(5000, result.getStartTimeDiff().asMillis());
} }
@Test @Test
public void testDependentStartTimeCycle() { public void testDependentStartTimeCycle() {
final MillisecondsDurationImpl cAfterB = new MillisecondsDurationImpl(6000);
raceLogC.add(new RaceLogDependentStartTimeEventImpl(nowMock, author, nowMock, "12", null, 12, raceLogC.add(new RaceLogDependentStartTimeEventImpl(nowMock, author, nowMock, "12", null, 12,
new SimpleRaceLogIdentifierImpl("B", "", ""), new MillisecondsDurationImpl(5000))); new SimpleRaceLogIdentifierImpl("B", "", ""), cAfterB));
raceLogB.add(new RaceLogDependentStartTimeEventImpl(nowMock, author, nowMock, "12", null, 12,
new SimpleRaceLogIdentifierImpl("A", "", ""), new MillisecondsDurationImpl(5000)));
raceLogA.add(new RaceLogDependentStartTimeEventImpl(nowMock, author, nowMock, "12", null, 12,
new SimpleRaceLogIdentifierImpl("C", "", ""), new MillisecondsDurationImpl(5000)));
final MillisecondsDurationImpl bAfterA = new MillisecondsDurationImpl(7000);
//Check that all resolve to null in case of a cycle raceLogB.add(new RaceLogDependentStartTimeEventImpl(nowMock, author, nowMock, "12", null, 12,
StartTimeFinder finder = new StartTimeFinder(raceLogResolver, raceLogC); new SimpleRaceLogIdentifierImpl("A", "", ""), bAfterA));
assertNull(finder.analyze().getStartTime());
final MillisecondsDurationImpl aAfterC = new MillisecondsDurationImpl(8000);
finder = new StartTimeFinder(raceLogResolver, raceLogB); raceLogA.add(new RaceLogDependentStartTimeEventImpl(nowMock, author, nowMock, "12", null, 12,
assertNull(finder.analyze().getStartTime()); new SimpleRaceLogIdentifierImpl("C", "", ""), aAfterC));
finder = new StartTimeFinder(raceLogResolver, raceLogA); // Check that all resolve to null in case of a cycle
assertNull(finder.analyze().getStartTime()); StartTimeFinder finder = new StartTimeFinder(raceLogResolver, raceLogC);
assertNull(finder.analyze().getStartTime());
//Check that all resolve correctly after changing some element in cycle assertEquals(cAfterB, finder.analyze().getStartTimeDiff());
MillisecondsTimePoint now = MillisecondsTimePoint.now();
raceLogB.add(new RaceLogStartTimeEventImpl(now, author, now, "12", null, 12, finder = new StartTimeFinder(raceLogResolver, raceLogB);
new MillisecondsTimePoint(5000))); assertNull(finder.analyze().getStartTime());
assertEquals(bAfterA, finder.analyze().getStartTimeDiff());
//now A -> C -> B
finder = new StartTimeFinder(raceLogResolver, raceLogA); finder = new StartTimeFinder(raceLogResolver, raceLogA);
//Tests for correct behaviour, when race depending on has a DependentStartTimeEvent and its parent start time is unknown assertNull(finder.analyze().getStartTime());
List<SimpleRaceLogIdentifier> expectedDependingOnRaces = new ArrayList<SimpleRaceLogIdentifier>(); assertEquals(aAfterC, finder.analyze().getStartTimeDiff());
expectedDependingOnRaces = new ArrayList<SimpleRaceLogIdentifier>();
expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("C", "", "")); // Check that all resolve correctly after changing some element in cycle
expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("B", "", "")); MillisecondsTimePoint now = MillisecondsTimePoint.now();
raceLogB.add(new RaceLogStartTimeEventImpl(now, author, now, "12", null, 12, new MillisecondsTimePoint(5000)));
StartTimeFinderResult result = finder.analyze();
assertEquals(15000, result.getStartTime().asMillis()); // now A -> C -> B
assertEquals(expectedDependingOnRaces, result.getRacesDependingOn()); finder = new StartTimeFinder(raceLogResolver, raceLogA);
// Tests for correct behaviour, when race depending on has a DependentStartTimeEvent and its parent start time
//now C -> B // is unknown
finder = new StartTimeFinder(raceLogResolver, raceLogC); List<SimpleRaceLogIdentifier> expectedDependingOnRaces;
//Tests for correct behaviour, when race depending on has a DependentStartTimeEvent and its parent start time is unknown expectedDependingOnRaces = new ArrayList<>();
expectedDependingOnRaces = new ArrayList<SimpleRaceLogIdentifier>(); expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("C", "", ""));
expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("B", "", "")); expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("B", "", ""));
result = finder.analyze(); StartTimeFinderResult result = finder.analyze();
assertEquals(10000, result.getStartTime().asMillis()); assertEquals(19000, result.getStartTime().asMillis());
assertEquals(expectedDependingOnRaces, result.getRacesDependingOn()); assertEquals(8000, result.getStartTimeDiff().asMillis());
assertEquals(expectedDependingOnRaces, result.getRacesDependingOn());
//now B
finder = new StartTimeFinder(raceLogResolver, raceLogB); // now C -> B
//Tests for correct behaviour, when race depending on has a DependentStartTimeEvent and its parent start time is unknown finder = new StartTimeFinder(raceLogResolver, raceLogC);
expectedDependingOnRaces = new ArrayList<SimpleRaceLogIdentifier>(); // Tests for correct behaviour, when race depending on has a DependentStartTimeEvent and its parent start time
// is unknown
result = finder.analyze(); expectedDependingOnRaces = new ArrayList<>();
assertEquals(5000, result.getStartTime().asMillis()); expectedDependingOnRaces.add(new SimpleRaceLogIdentifierImpl("B", "", ""));
assertEquals(expectedDependingOnRaces, result.getRacesDependingOn());
result = finder.analyze();
assertEquals(11000, result.getStartTime().asMillis());
assertEquals(6000, result.getStartTimeDiff().asMillis());
assertEquals(expectedDependingOnRaces, result.getRacesDependingOn());
// now B
finder = new StartTimeFinder(raceLogResolver, raceLogB);
// Tests for correct behaviour, when race depending on has a DependentStartTimeEvent and its parent start time
// is unknown
expectedDependingOnRaces = new ArrayList<>();
result = finder.analyze();
assertEquals(5000, result.getStartTime().asMillis());
assertNull(result.getStartTimeDiff());
assertEquals(expectedDependingOnRaces, result.getRacesDependingOn());
} }
} }
@@ -13,13 +13,12 @@ import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
public class StartTimeFinderTest extends public class StartTimeFinderTest extends PassAwareRaceLogAnalyzerTest<StartTimeFinder, StartTimeFinderResult> {
PassAwareRaceLogAnalyzerTest<StartTimeFinder, StartTimeFinderResult> {
@Override @Override
protected StartTimeFinder createAnalyzer(RaceLog raceLog) { protected StartTimeFinder createAnalyzer(RaceLog raceLog) {
@@ -30,7 +29,7 @@ public class StartTimeFinderTest extends
protected TargetPair getTargetEventsAndResultForPassAwareTests(int passId, AbstractLogEventAuthor author) { protected TargetPair getTargetEventsAndResultForPassAwareTests(int passId, AbstractLogEventAuthor author) {
RaceLogStartTimeEvent event = createEvent(RaceLogStartTimeEvent.class, 1, passId, author); RaceLogStartTimeEvent event = createEvent(RaceLogStartTimeEvent.class, 1, passId, author);
when(event.getStartTime()).thenReturn(mock(TimePoint.class)); when(event.getStartTime()).thenReturn(mock(TimePoint.class));
return new TargetPair(Arrays.asList(event), new StartTimeFinderResult(event.getStartTime())); return new TargetPair(Arrays.asList(event), new StartTimeFinderResult(event.getStartTime(), null));
} }
@Test @Test
@@ -1,8 +1,10 @@
package com.sap.sailing.domain.abstractlog.race; package com.sap.sailing.domain.abstractlog.race;
import java.io.Serializable;
import com.sap.sse.common.Util.Triple; import com.sap.sse.common.Util.Triple;
public interface SimpleRaceLogIdentifier { public interface SimpleRaceLogIdentifier extends Serializable {
String getRegattaLikeParentName(); String getRegattaLikeParentName();
String getRaceColumnName(); String getRaceColumnName();
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.abstractlog.race.analyzing.impl; package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -16,33 +17,37 @@ public class DependentStartTimeResolver {
public DependentStartTimeResolver(RaceLogResolver raceLogResolver) { public DependentStartTimeResolver(RaceLogResolver raceLogResolver) {
this.raceLogResolver = raceLogResolver; this.raceLogResolver = raceLogResolver;
} }
public StartTimeFinderResult resolve(RaceLogDependentStartTimeEvent event) { public StartTimeFinderResult resolve(RaceLogDependentStartTimeEvent event) {
List<SimpleRaceLogIdentifier> dependingOnRaces = new ArrayList<SimpleRaceLogIdentifier>(); List<SimpleRaceLogIdentifier> dependingOnRaces = Collections.emptyList();
return internalResolve(event, dependingOnRaces); return internalResolve(event, dependingOnRaces);
} }
StartTimeFinderResult internalResolve(RaceLogDependentStartTimeEvent event, Iterable<SimpleRaceLogIdentifier> dependingOnRaces) { StartTimeFinderResult internalResolve(RaceLogDependentStartTimeEvent event,Iterable<SimpleRaceLogIdentifier> dependingOnRaces) {
SimpleRaceLogIdentifier identifier = event.getDependentOnRaceIdentifier(); SimpleRaceLogIdentifier identifier = event.getDependentOnRaceIdentifier();
Duration startTimeDifference = event.getStartTimeDifference(); Duration startTimeDifference = event.getStartTimeDifference();
RaceLog raceLog = raceLogResolver.resolve(identifier); RaceLog raceLog = raceLogResolver.resolve(identifier);
List<SimpleRaceLogIdentifier> extendedDependingOnRaces = new ArrayList<>();
Util.addAll(dependingOnRaces, extendedDependingOnRaces);
extendedDependingOnRaces.add(identifier);
final StartTimeFinderResult result; final StartTimeFinderResult result;
if (containsCycle(extendedDependingOnRaces)) { if (raceLog == null) {
result = new StartTimeFinderResult(extendedDependingOnRaces, null); result = new StartTimeFinderResult(dependingOnRaces, null, startTimeDifference);
} else { } else {
StartTimeFinder dependentStartTimeFinder = new StartTimeFinder(raceLogResolver, raceLog); List<SimpleRaceLogIdentifier> extendedDependingOnRaces = new ArrayList<>();
StartTimeFinderResult resultOfDependentRace = dependentStartTimeFinder.analyze(extendedDependingOnRaces); Util.addAll(dependingOnRaces, extendedDependingOnRaces);
if (resultOfDependentRace.getStartTime() == null) { extendedDependingOnRaces.add(identifier);
result = resultOfDependentRace; if (containsCycle(extendedDependingOnRaces)) {
result = new StartTimeFinderResult(extendedDependingOnRaces, null, null);
} else { } else {
result = new StartTimeFinderResult(resultOfDependentRace.getRacesDependingOn(), StartTimeFinder dependentStartTimeFinder = new StartTimeFinder(raceLogResolver, raceLog);
resultOfDependentRace.getStartTime() == null ? null : resultOfDependentRace.getStartTime() StartTimeFinderResult resultOfDependentRace = dependentStartTimeFinder.analyze(extendedDependingOnRaces);
.plus(startTimeDifference)); if (resultOfDependentRace.getStartTime() == null) {
resultOfDependentRace.setStartTimeDiff(startTimeDifference);
result = resultOfDependentRace;
} else {
result = new StartTimeFinderResult(resultOfDependentRace.getRacesDependingOn(),
resultOfDependentRace.getStartTime().plus(startTimeDifference), startTimeDifference);
}
} }
} }
return result; return result;
@@ -44,15 +44,14 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer<RaceLogRaceStatus> {
@Override @Override
protected RaceLogRaceStatus performAnalysis() { protected RaceLogRaceStatus performAnalysis() {
ArrayListNavigableSet<RaceLogRaceStatusEvent> statusEvents = new ArrayListNavigableSet<RaceLogRaceStatusEvent>(RaceLogRaceStatusEventComparator.INSTANCE); ArrayListNavigableSet<RaceLogRaceStatusEvent> statusEvents = new ArrayListNavigableSet<>(RaceLogRaceStatusEventComparator.INSTANCE);
for(RaceLogEvent event: getPassEvents()) { for(RaceLogEvent event: getPassEvents()) {
if(event instanceof RaceLogRaceStatusEvent) { if(event instanceof RaceLogRaceStatusEvent) {
statusEvents.add((RaceLogRaceStatusEvent) event); statusEvents.add((RaceLogRaceStatusEvent) event);
} }
} }
for (RaceLogRaceStatusEvent event : statusEvents.descendingSet()) { for (RaceLogRaceStatusEvent event : statusEvents.descendingSet()) {
RaceLogRaceStatusEvent statusEvent = (RaceLogRaceStatusEvent) event; event.accept(eventDispatcher);
statusEvent.accept(eventDispatcher);
return eventDispatcher.nextStatus; return eventDispatcher.nextStatus;
} }
@@ -79,7 +78,7 @@ public class RaceStatusAnalyzer extends RaceLogAnalyzer<RaceLogRaceStatus> {
private void setRaceLogStatusBasedOnStartTime(TimePoint startTime) { private void setRaceLogStatusBasedOnStartTime(TimePoint startTime) {
if (startTime == null) { if (startTime == null) {
nextStatus = RaceLogRaceStatus.UNKNOWN; nextStatus = RaceLogRaceStatus.PRESCHEDULED;
return; return;
} }
TimePoint now = clock.now(); TimePoint now = clock.now();
@@ -29,13 +29,13 @@ public class StartTimeFinder extends RaceLogAnalyzer<StartTimeFinderResult> {
for (RaceLogEvent event : getPassEventsDescending()) { for (RaceLogEvent event : getPassEventsDescending()) {
if (event instanceof RaceLogStartTimeEvent) { if (event instanceof RaceLogStartTimeEvent) {
TimePoint startTime = ((RaceLogStartTimeEvent) event).getStartTime(); TimePoint startTime = ((RaceLogStartTimeEvent) event).getStartTime();
return new StartTimeFinderResult(dependingOnRaces, startTime); return new StartTimeFinderResult(dependingOnRaces, startTime, null);
} else if (event instanceof RaceLogDependentStartTimeEvent) { } else if (event instanceof RaceLogDependentStartTimeEvent) {
DependentStartTimeResolver dependentStartTimeResolver = new DependentStartTimeResolver(resolver); DependentStartTimeResolver dependentStartTimeResolver = new DependentStartTimeResolver(resolver);
return dependentStartTimeResolver.internalResolve((RaceLogDependentStartTimeEvent) event, dependingOnRaces); return dependentStartTimeResolver.internalResolve((RaceLogDependentStartTimeEvent) event, dependingOnRaces);
} }
} }
return new StartTimeFinderResult(dependingOnRaces, null); return new StartTimeFinderResult(dependingOnRaces, null, null);
} finally { } finally {
log.unlockAfterRead(); log.unlockAfterRead();
} }
@@ -1,29 +1,25 @@
package com.sap.sailing.domain.abstractlog.race.analyzing.impl; package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
import java.util.ArrayList; import java.util.Collections;
import java.util.List;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
public class StartTimeFinderResult { public class StartTimeFinderResult {
private final Iterable<SimpleRaceLogIdentifier> racesDependingOn; private final Iterable<SimpleRaceLogIdentifier> racesDependingOn;
private final TimePoint startTime; private final TimePoint startTime;
private Duration startTimeDiff;
public StartTimeFinderResult(final Iterable<SimpleRaceLogIdentifier> racesDependingOn, final TimePoint startTime) { public StartTimeFinderResult(Iterable<SimpleRaceLogIdentifier> racesDependingOn, TimePoint startTime, Duration startTimeDiff) {
this.racesDependingOn = racesDependingOn;
this.startTime = startTime; this.startTime = startTime;
this.startTimeDiff = startTimeDiff;
this.racesDependingOn = racesDependingOn;
} }
public StartTimeFinderResult(TimePoint startTime) { public StartTimeFinderResult(TimePoint startTime, Duration startTimeDiff) {
racesDependingOn = new ArrayList<SimpleRaceLogIdentifier>(); this(/* racesDependingOn */ Collections.<SimpleRaceLogIdentifier>emptyList(), startTime, startTimeDiff);
this.startTime = startTime;
}
public StartTimeFinderResult(List<SimpleRaceLogIdentifier> racesDependingOn, TimePoint startTime) {
this.racesDependingOn = racesDependingOn;
this.startTime = startTime;
} }
public Iterable<SimpleRaceLogIdentifier> getRacesDependingOn() { public Iterable<SimpleRaceLogIdentifier> getRacesDependingOn() {
@@ -34,11 +30,16 @@ public class StartTimeFinderResult {
return startTime; return startTime;
} }
public Duration getStartTimeDiff() {
return startTimeDiff;
}
public void setStartTimeDiff(Duration startTimeDiff) {
this.startTimeDiff = startTimeDiff;
}
public boolean isDependentStartTime() { public boolean isDependentStartTime() {
if (racesDependingOn == null) { return racesDependingOn != null && !Util.isEmpty(racesDependingOn);
return false;
}
return Util.isEmpty(racesDependingOn);
} }
@Override @Override
@@ -47,6 +48,7 @@ public class StartTimeFinderResult {
int result = 1; int result = 1;
result = prime * result + ((racesDependingOn == null) ? 0 : racesDependingOn.hashCode()); result = prime * result + ((racesDependingOn == null) ? 0 : racesDependingOn.hashCode());
result = prime * result + ((startTime == null) ? 0 : startTime.hashCode()); result = prime * result + ((startTime == null) ? 0 : startTime.hashCode());
result = prime * result + ((startTimeDiff == null) ? 0 : startTimeDiff.hashCode());
return result; return result;
} }
@@ -69,6 +71,11 @@ public class StartTimeFinderResult {
return false; return false;
} else if (!startTime.equals(other.startTime)) } else if (!startTime.equals(other.startTime))
return false; return false;
if (startTimeDiff == null) {
if (other.startTimeDiff != null)
return false;
} else if (!startTimeDiff.equals(other.startTimeDiff))
return false;
return true; return true;
} }
} }
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.abstractlog.race.impl;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
public class SimpleRaceLogIdentifierImpl implements SimpleRaceLogIdentifier { public class SimpleRaceLogIdentifierImpl implements SimpleRaceLogIdentifier {
private static final long serialVersionUID = 5377117723950808853L;
protected final String regattaLikeParentName; protected final String regattaLikeParentName;
protected final String raceColumnName; protected final String raceColumnName;
protected final String fleetName; protected final String fleetName;
@@ -187,4 +187,9 @@ public interface RaceState extends ReadonlyRaceState {
void setAdditionalScoringInformationEnabled(TimePoint creationTimePoint, boolean enable, AdditionalScoringInformationType informationType); void setAdditionalScoringInformationEnabled(TimePoint creationTimePoint, boolean enable, AdditionalScoringInformationType informationType);
boolean isAdditionalScoringInformationEnabled(AdditionalScoringInformationType informationType); boolean isAdditionalScoringInformationEnabled(AdditionalScoringInformationType informationType);
/**
* forces a RaceStateUpdate
*/
void forceUpdate();
} }
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.abstractlog.race.state.impl; package com.sap.sailing.domain.abstractlog.race.state.impl;
import java.util.Collections;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -17,6 +18,7 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer
import com.sap.sailing.domain.abstractlog.race.scoring.AdditionalScoringInformationType; import com.sap.sailing.domain.abstractlog.race.scoring.AdditionalScoringInformationType;
import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent; import com.sap.sailing.domain.abstractlog.race.scoring.RaceLogAdditionalScoringInformationEvent;
import com.sap.sailing.domain.abstractlog.race.state.RaceState; import com.sap.sailing.domain.abstractlog.race.state.RaceState;
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedureFactory; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedureFactory;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite;
@@ -42,6 +44,10 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState {
private final AbstractLogEventAuthor author; private final AbstractLogEventAuthor author;
private final RaceLogEventFactory factory; private final RaceLogEventFactory factory;
public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog) {
return create(raceLogResolver, raceLog, /* forRaceLogIdentifier */ null, Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState>emptyMap());
}
/** /**
* Creates a {@link RaceState} with the initial racing procedure type set to a fallback value and an empty configuration. * Creates a {@link RaceState} with the initial racing procedure type set to a fallback value and an empty configuration.
*/ */
@@ -63,9 +69,11 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState {
this(raceLogResolver, raceLog, author, eventFactory, new RaceStatusAnalyzer.StandardClock(), procedureFactory); this(raceLogResolver, raceLog, author, eventFactory, new RaceStatusAnalyzer.StandardClock(), procedureFactory);
} }
private RaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog, AbstractLogEventAuthor author, RaceLogEventFactory eventFactory, RaceStatusAnalyzer.Clock analyzersClock, private RaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog, AbstractLogEventAuthor author,
RaceLogEventFactory eventFactory, RaceStatusAnalyzer.Clock analyzersClock,
RacingProcedureFactory procedureFactory) { RacingProcedureFactory procedureFactory) {
super(raceLogResolver, raceLog, analyzersClock, procedureFactory, /* update */ true); super(raceLogResolver, raceLog, /* forRaceLogIdentifier */ null, analyzersClock, procedureFactory,
Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState>emptyMap(), /* update */ true);
this.author = author; this.author = author;
this.factory = eventFactory; this.factory = eventFactory;
} }
@@ -221,4 +229,10 @@ public class RaceStateImpl extends ReadonlyRaceStateImpl implements RaceState {
return event != null; return event != null;
} }
@Override
public void forceUpdate() {
super.update();
registerListenerOnDependentRaceIfDependentStartTime(Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState>emptyMap());
}
} }
@@ -1,11 +1,16 @@
package com.sap.sailing.domain.abstractlog.race.state.impl; package com.sap.sailing.domain.abstractlog.race.state.impl;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.sap.sailing.domain.abstractlog.race.CompetitorResults; import com.sap.sailing.domain.abstractlog.race.CompetitorResults;
import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogChangedListener; import com.sap.sailing.domain.abstractlog.race.RaceLogChangedListener;
import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogDependentStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ConfirmedFinishPositioningListFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.ConfirmedFinishPositioningListFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishPositioningListFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishPositioningListFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishedTimeFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishedTimeFinder;
@@ -15,10 +20,10 @@ 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.ProtestStartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; 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;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer.Clock; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceStatusAnalyzer.Clock;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RacingProcedureTypeAnalyzer; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RacingProcedureTypeAnalyzer;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult;
import com.sap.sailing.domain.abstractlog.race.impl.WeakRaceLogChangedVisitor; import com.sap.sailing.domain.abstractlog.race.impl.WeakRaceLogChangedVisitor;
import com.sap.sailing.domain.abstractlog.race.state.RaceStateChangedListener; import com.sap.sailing.domain.abstractlog.race.state.RaceStateChangedListener;
import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent; import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent;
@@ -49,21 +54,41 @@ import com.sap.sse.common.Util;
*/ */
public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedListener { public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedListener {
public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog) {
return create(raceLogResolver, raceLog, /* forRaceLogIdentifier */null,
Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState> emptyMap());
}
/** /**
* Creates a {@link ReadonlyRaceState}. * Creates a {@link ReadonlyRaceState}.
*
* @param forRaceLogIdentifier
* If known, callers can specify the simple race log identifier for the race log to be wrapped by this
* new race state. This can help avoid endless recursions because this race state can be passed along
* together with the identifier so that when again along a dependent call chain a race state is required
* for that race log identifier, this one can be used.
*/ */
public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog, public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog,
ConfigurationLoader<RegattaConfiguration> configurationLoader) { SimpleRaceLogIdentifier forRaceLogIdentifier,
return new ReadonlyRaceStateImpl(raceLogResolver, raceLog, new ReadonlyRacingProcedureFactory( ConfigurationLoader<RegattaConfiguration> configurationLoader,
configurationLoader)); Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
return new ReadonlyRaceStateImpl(raceLogResolver, raceLog, forRaceLogIdentifier, new ReadonlyRacingProcedureFactory(
configurationLoader), dependentRaceStates);
} }
/** /**
* Creates a {@link ReadonlyRaceState} with an empty configuration ( {@link EmptyRegattaConfiguration} ). * Creates a {@link ReadonlyRaceState} with an empty configuration ( {@link EmptyRegattaConfiguration} ).
*
* @param forRaceLogIdentifier
* If known, callers can specify the simple race log identifier for the race log to be wrapped by this
* new race state. This can help avoid endless recursions because this race state can be passed along
* together with the identifier so that when again along a dependent call chain a race state is required
* for that race log identifier, this one can be used.
*/ */
public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog) { public static ReadonlyRaceState create(RaceLogResolver raceLogResolver, RaceLog raceLog,
return new ReadonlyRaceStateImpl(raceLogResolver, raceLog, new ReadonlyRacingProcedureFactory( SimpleRaceLogIdentifier forRaceLogIdentifier, Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
new EmptyRegattaConfiguration())); return new ReadonlyRaceStateImpl(raceLogResolver, raceLog, forRaceLogIdentifier, new ReadonlyRacingProcedureFactory(
new EmptyRegattaConfiguration()), dependentRaceStates);
} }
/** /**
@@ -127,18 +152,26 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
private RaceStateChangedListener raceStateToObserveListener; private RaceStateChangedListener raceStateToObserveListener;
private ReadonlyRaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog, private ReadonlyRaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog,
RacingProcedureFactory procedureFactory) { SimpleRaceLogIdentifier forRaceLogIdentifier, RacingProcedureFactory procedureFactory,
this(raceLogResolver, raceLog, new RaceStatusAnalyzer.StandardClock(), procedureFactory, /* update */true); Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
this(raceLogResolver, raceLog, forRaceLogIdentifier, new RaceStatusAnalyzer.StandardClock(),
procedureFactory, dependentRaceStates, /* update */true);
} }
/** /**
* @param raceLogResolver * @param forRaceLogIdentifier
* If known, callers can specify the simple race log identifier for the race log to be wrapped by this
* new race state. This can help avoid endless recursions because this race state can be passed along
* together with the identifier so that when again along a dependent call chain a race state is required
* for that race log identifier, this one can be used.
* @param update * @param update
* if <code>true</code>, the race state will be updated whenever the underlying <code>raceLog</code> * if <code>true</code>, the race state will be updated whenever the underlying <code>raceLog</code>
* changes. * changes.
*/ */
protected ReadonlyRaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog, Clock analyzersClock, protected ReadonlyRaceStateImpl(RaceLogResolver raceLogResolver, RaceLog raceLog,
RacingProcedureFactory procedureFactory, boolean update) { SimpleRaceLogIdentifier forRaceLogIdentifier, Clock analyzersClock,
RacingProcedureFactory procedureFactory,
Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates, boolean update) {
this.raceLog = raceLog; this.raceLog = raceLog;
this.raceLogResolver = raceLogResolver; this.raceLogResolver = raceLogResolver;
this.procedureFactory = procedureFactory; this.procedureFactory = procedureFactory;
@@ -178,8 +211,18 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
// We known that recreateRacingProcedure calls update() when done, therefore this RaceState // We known that recreateRacingProcedure calls update() when done, therefore this RaceState
// will be fully initialized after this line // will be fully initialized after this line
recreateRacingProcedure(); recreateRacingProcedure();
final Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStatesAndMe;
if (forRaceLogIdentifier != null) {
dependentRaceStatesAndMe = new HashMap<>(dependentRaceStates);
dependentRaceStatesAndMe.put(forRaceLogIdentifier, this);
} else {
dependentRaceStatesAndMe = dependentRaceStates;
}
registerListenerOnDependentRaceIfDependentStartTime(dependentRaceStatesAndMe);
}
// Check wether the latest known StartTimeEvent is a non-dependent or dependent start time in case of a protected void registerListenerOnDependentRaceIfDependentStartTime(Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
// Check whether the latest known StartTimeEvent is a non-dependent or dependent start time in case of a
// dependent startTime setup listeners // dependent startTime setup listeners
this.raceLog.lockForRead(); this.raceLog.lockForRead();
try { try {
@@ -187,7 +230,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
if (event instanceof RaceLogStartTimeEvent) { if (event instanceof RaceLogStartTimeEvent) {
break; break;
} else if (event instanceof RaceLogDependentStartTimeEvent) { } else if (event instanceof RaceLogDependentStartTimeEvent) {
setupListenersOnDependentRace(event); setupListenersOnDependentRace(event, dependentRaceStates);
break; break;
} }
} }
@@ -319,7 +362,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
@Override @Override
public void eventAdded(RaceLogEvent event) { public void eventAdded(RaceLogEvent event) {
if (event instanceof RaceLogDependentStartTimeEvent) { if (event instanceof RaceLogDependentStartTimeEvent) {
setupListenersOnDependentRace(event); setupListenersOnDependentRace(event, Collections.<SimpleRaceLogIdentifier, ReadonlyRaceState>emptyMap());
} else if (event instanceof RaceLogStartTimeEvent) { } else if (event instanceof RaceLogStartTimeEvent) {
if (raceStateToObserve != null) { if (raceStateToObserve != null) {
raceStateToObserve.removeChangedListener(raceStateToObserveListener); raceStateToObserve.removeChangedListener(raceStateToObserveListener);
@@ -329,15 +372,25 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
update(); update();
} }
private void setupListenersOnDependentRace(RaceLogEvent event) { private void setupListenersOnDependentRace(RaceLogEvent event, Map<SimpleRaceLogIdentifier, ReadonlyRaceState> dependentRaceStates) {
if (raceStateToObserve != null) { if (raceStateToObserve != null) {
// Remove previous listeners // Remove previous listeners
raceStateToObserve.removeChangedListener(raceStateToObserveListener); raceStateToObserve.removeChangedListener(raceStateToObserveListener);
raceStateToObserve = null;
} }
RaceLogDependentStartTimeEvent dependentStartTimeEvent = (RaceLogDependentStartTimeEvent) event; RaceLogDependentStartTimeEvent dependentStartTimeEvent = (RaceLogDependentStartTimeEvent) event;
RaceLog resolvedRaceLog = raceLogResolver.resolve(dependentStartTimeEvent.getDependentOnRaceIdentifier()); final SimpleRaceLogIdentifier dependentOnRaceIdentifier = dependentStartTimeEvent.getDependentOnRaceIdentifier();
raceStateToObserve = ReadonlyRaceStateImpl.create(raceLogResolver, resolvedRaceLog); if (dependentRaceStates.containsKey(dependentOnRaceIdentifier)) {
raceStateToObserve.addChangedListener(raceStateToObserveListener); raceStateToObserve = dependentRaceStates.get(dependentOnRaceIdentifier);
raceStateToObserve.addChangedListener(raceStateToObserveListener);
} else {
RaceLog resolvedRaceLog = raceLogResolver.resolve(dependentOnRaceIdentifier);
if (resolvedRaceLog != null) {
raceStateToObserve = ReadonlyRaceStateImpl.create(raceLogResolver, resolvedRaceLog,
dependentOnRaceIdentifier, dependentRaceStates);
raceStateToObserve.addChangedListener(raceStateToObserveListener);
}
}
} }
@Override @Override
@@ -350,7 +403,7 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL
return false; return false;
} }
private void update() { protected void update() {
RacingProcedureType type = racingProcedureAnalyzer.analyze(); RacingProcedureType type = racingProcedureAnalyzer.analyze();
if (!Util.equalsWithNull(cachedRacingProcedureType, type) && type != RacingProcedureType.UNKNOWN) { if (!Util.equalsWithNull(cachedRacingProcedureType, type) && type != RacingProcedureType.UNKNOWN) {
cachedRacingProcedureType = type; cachedRacingProcedureType = type;
@@ -90,6 +90,11 @@ public abstract class AbstractMarkPassingTest extends OnlineTracTracBasedTest {
protected void testRace(String raceNumber) throws IOException, InterruptedException, URISyntaxException, ParseException, SubscriberInitializationException, CreateModelException { protected void testRace(String raceNumber) throws IOException, InterruptedException, URISyntaxException, ParseException, SubscriberInitializationException, CreateModelException {
setUp(raceNumber); setUp(raceNumber);
synchronized (getSemaphor()) {
while (!isStoredDataLoaded()) {
getSemaphor().wait();
}
}
testWholeRace(); testWholeRace();
testMiddleOfRace(0); testMiddleOfRace(0);
testMiddleOfRace(2); testMiddleOfRace(2);
@@ -11,6 +11,6 @@
</listAttribute> </listAttribute>
<stringAttribute key="projectName" value="com.sap.sailing.gwt.ui"/> <stringAttribute key="projectName" value="com.sap.sailing.gwt.ui"/>
<booleanAttribute key="showLaunchOutput" value="false"/> <booleanAttribute key="showLaunchOutput" value="false"/>
<stringAttribute key="url" value="http://127.0.0.1:8888/gwt/Home.html"/> <stringAttribute key="url" value="http://127.0.0.1:8888/gwt/AdminConsole.html"/>
<stringAttribute key="urlQueryParams" value=""/> <stringAttribute key="urlQueryParams" value=""/>
</launchConfiguration> </launchConfiguration>
+76 -76
View File
@@ -1,76 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp"> <launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/> <booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/> <stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/> <booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/> <booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES"> <listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/> <listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
<listEntry value="com.sap.sailing.gwt.ui.DataMining"/> <listEntry value="com.sap.sailing.gwt.ui.DataMining"/>
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/> <listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/> <listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
<listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/> <listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/> <listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
<listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/> <listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/>
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/> <listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/> <listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/> <listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/> <listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.home.Home"/> <listEntry value="com.sap.sailing.gwt.home.Home"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/> <listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
</listAttribute> </listAttribute>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/> <stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.sap.sailing.gwt.ui"/> <listEntry value="/com.sap.sailing.gwt.ui"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/> <listEntry value="4"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute> </listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/> <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> <listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.theme/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.theme/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.googlecode.java-diff-utils/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.googlecode.java-diff-utils/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.json.simple/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.json.simple/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.expeditionconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.expeditionconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.udpconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.udpconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.mongodb/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.mongodb/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.operationaltransformation/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.operationaltransformation/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.geocoding/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.geocoding/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.gwt.ui&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.gwt.ui&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.adminconsole/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.adminconsole/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/> <stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/> <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.home.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/> <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
</launchConfiguration> </launchConfiguration>
@@ -21,6 +21,13 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
private RegattaAndRaceIdentifier selectedRace; private RegattaAndRaceIdentifier selectedRace;
private boolean autoAdjustPlayMode; private boolean autoAdjustPlayMode;
private RaceTimesInfoDTO lastRaceTimesInfo; private RaceTimesInfoDTO lastRaceTimesInfo;
/**
* When a marker update is required but min/max are not yet initialized, this flag is set. If later
* {@link #setMinMax(Date, Date, boolean)} is invoked and this flag is set, a {@link #redrawAllMarkers(RaceTimesInfoDTO)}
* will be issued and the flag is cleared.
*/
private boolean redrawAllMarkersPendingForMinMaxBeingInitialized;
public RaceTimePanel(Timer timer, TimeRangeWithZoomProvider timeRangeProvider, StringMessages stringMessages, public RaceTimePanel(Timer timer, TimeRangeWithZoomProvider timeRangeProvider, StringMessages stringMessages,
RaceTimesInfoProvider raceTimesInfoProvider, boolean canReplayWhileLiveIsPossible) { RaceTimesInfoProvider raceTimesInfoProvider, boolean canReplayWhileLiveIsPossible) {
@@ -105,7 +112,7 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
// maybe show a special state for this like "Race did not start yet" // maybe show a special state for this like "Race did not start yet"
} }
} }
lastRaceTimesInfo = raceTimesInfo; lastRaceTimesInfo = raceTimesInfo; // TODO bug 3122: when not redrawn yet because min/max not initialized yet, further redraw is disabled by this.
} }
@Override @Override
@@ -181,6 +188,15 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
} }
} }
@Override
public void setMinMax(Date min, Date max, boolean fireEvent) {
super.setMinMax(min, max, fireEvent);
if (redrawAllMarkersPendingForMinMaxBeingInitialized && timeSlider.isMinMaxInitialized()) {
redrawAllMarkers(lastRaceTimesInfo);
redrawAllMarkersPendingForMinMaxBeingInitialized = false;
}
}
/** /**
* When in {@link PlayModes#Replay} mode, tries to put the {@link #timer} to the time point when the last leg was * When in {@link PlayModes#Replay} mode, tries to put the {@link #timer} to the time point when the last leg was
* finished first. If this time point is not (yet?) known, tries to put the {@link #timer} to the * finished first. If this time point is not (yet?) known, tries to put the {@link #timer} to the
@@ -239,8 +255,12 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
requiresMarkerUpdate = true; requiresMarkerUpdate = true;
} }
} }
if (requiresMarkerUpdate && timeSlider.isMinMaxInitialized()) { if (requiresMarkerUpdate) {
redrawAllMarkers(newRaceTimesInfo); if (timeSlider.isMinMaxInitialized()) { // TODO bug 3122 later, the lastRaceTimesInfo will be updated even if not redrawn because min/max not initialized
redrawAllMarkers(newRaceTimesInfo);
} else {
redrawAllMarkersPendingForMinMaxBeingInitialized = true;
}
} }
} }
@@ -1319,4 +1319,4 @@ degreesToWind={0}° to wind
miniLeeaderboardLegendText=Shows the points along with the number of races per competitor miniLeeaderboardLegendText=Shows the points along with the number of races per competitor
currentOfTotal={0,number}/{1,number} currentOfTotal={0,number}/{1,number}
noFinishedRaces=There are no finished races yet noFinishedRaces=There are no finished races yet
racesOverview=Races overview racesOverview=Races overview
@@ -1309,4 +1309,4 @@ degreesToWind={0}° zum Wind
miniLeeaderboardLegendText=Es werden die Punkte und die Anzahl Rennen je Team angezeigt miniLeeaderboardLegendText=Es werden die Punkte und die Anzahl Rennen je Team angezeigt
currentOfTotal={0,number}/{1,number} currentOfTotal={0,number}/{1,number}
noFinishedRaces=Es wurden noch keine Wettfahrten beendet. noFinishedRaces=Es wurden noch keine Wettfahrten beendet.
racesOverview=Wettfahrtübersicht racesOverview=Wettfahrtübersicht
@@ -1256,4 +1256,4 @@ degreesToWind={0}° to wind
miniLeeaderboardLegendText=Shows points along with the number of races per competitor miniLeeaderboardLegendText=Shows points along with the number of races per competitor
currentOfTotal={0,number}/{1,number} currentOfTotal={0,number}/{1,number}
noFinishedRaces=There are no finished races yet noFinishedRaces=There are no finished races yet
racesOverview=Races overview racesOverview=Races overview
@@ -1305,4 +1305,4 @@ degreesToWind={0}° to wind
miniLeeaderboardLegendText=Shows points along with the number of races per competitor miniLeeaderboardLegendText=Shows points along with the number of races per competitor
currentOfTotal={0,number}/{1,number} currentOfTotal={0,number}/{1,number}
noFinishedRaces=There are no finished races yet noFinishedRaces=There are no finished races yet
racesOverview=Races overview racesOverview=Races overview
@@ -420,16 +420,12 @@ public class TimePanel<T extends TimePanelSettings> extends SimplePanel implemen
assert min != null && max != null; assert min != null && max != null;
boolean changed = false; boolean changed = false;
if (!max.equals(timeRangeProvider.getToTime())) { if (!max.equals(timeRangeProvider.getToTime()) || !min.equals(timeRangeProvider.getFromTime())) {
changed = true; changed = true;
timeSlider.setMaxValue(new Double(max.getTime()), fireEvent); timeSlider.setMinAndMaxValue(new Double(min.getTime()),new Double(max.getTime()), fireEvent);
}
if (!min.equals(timeRangeProvider.getFromTime())) {
changed = true;
timeSlider.setMinValue(new Double(min.getTime()), fireEvent);
} }
if (changed) { if (changed) {
if(!timeRangeProvider.isZoomed()) { if (!timeRangeProvider.isZoomed()) {
timeRangeProvider.setTimeRange(min, max, this); timeRangeProvider.setTimeRange(min, max, this);
} }
@@ -103,8 +103,6 @@ public class EditMarkPassingsPanel extends AbsolutePanel implements Component<Ab
this.stringMessages = stringMessages; this.stringMessages = stringMessages;
competitorSelectionModel.addCompetitorSelectionChangeListener(this); competitorSelectionModel.addCompetitorSelectionChangeListener(this);
setVisible(false);
// Waypoint list // Waypoint list
currentWaypoints = new ArrayList<>(); currentWaypoints = new ArrayList<>();
waypointList = new ListDataProvider<>(); waypointList = new ListDataProvider<>();
@@ -269,6 +267,7 @@ public class EditMarkPassingsPanel extends AbsolutePanel implements Component<Ab
}); });
selectCompetitorLabel.setText(stringMessages.selectCompetitor()); selectCompetitorLabel.setText(stringMessages.selectCompetitor());
refreshWaypoints(); refreshWaypoints();
setVisible(false);
HorizontalPanel tableAndButtons = new HorizontalPanel(); HorizontalPanel tableAndButtons = new HorizontalPanel();
add(tableAndButtons, 0, 0); add(tableAndButtons, 0, 0);
tableAndButtons.setSpacing(3); tableAndButtons.setSpacing(3);
@@ -283,20 +282,27 @@ public class EditMarkPassingsPanel extends AbsolutePanel implements Component<Ab
buttonPanel.add(selectCompetitorLabel); buttonPanel.add(selectCompetitorLabel);
enableButtons(); enableButtons();
} }
@Override
public void setVisible(boolean visible) {
processCompetitorSelectionChange(visible);
super.setVisible(visible);
}
@Override @Override
public void addedToSelection(CompetitorDTO competitor) { public void addedToSelection(CompetitorDTO competitor) {
processCompetitorSelectionChange(); processCompetitorSelectionChange(isVisible());
} }
@Override @Override
public void removedFromSelection(CompetitorDTO competitor) { public void removedFromSelection(CompetitorDTO competitor) {
processCompetitorSelectionChange(); processCompetitorSelectionChange(isVisible());
} }
private void processCompetitorSelectionChange() { private void processCompetitorSelectionChange(boolean visible) {
waypointSelectionModel.clear(); waypointSelectionModel.clear();
if (isVisible() && Util.size(competitorSelectionModel.getSelectedCompetitors()) == 1) { if (visible && Util.size(competitorSelectionModel.getSelectedCompetitors()) == 1) {
selectCompetitorLabel.setText(""); selectCompetitorLabel.setText("");
refillList(); refillList();
} else { } else {
@@ -309,6 +315,7 @@ public class EditMarkPassingsPanel extends AbsolutePanel implements Component<Ab
waypointList.getList().clear(); waypointList.getList().clear();
clearInfo(); clearInfo();
} }
private void refillList() { private void refillList() {
clearInfo(); clearInfo();
@@ -1196,10 +1196,10 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
// this only works because the quickRanks are sorted // this only works because the quickRanks are sorted
for (Entry<CompetitorDTO, Integer> competitorsByWindwardDistanceTraveledAndOneBasedLegNumber : for (Entry<CompetitorDTO, Integer> competitorsByWindwardDistanceTraveledAndOneBasedLegNumber :
competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber.entrySet()) { competitorsInOrderOfWindwardDistanceTraveledWithOneBasedLegNumber.entrySet()) {
if (Util.contains(competitorsToShow, competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getKey())) { if (Util.contains(competitorsToShow, competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getKey()) &&
competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getValue() != null) {
leadingCompetitorDTO = competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getKey(); leadingCompetitorDTO = competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getKey();
legOfLeaderCompetitor = competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getValue() == null ? legOfLeaderCompetitor = competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getValue();
0 : competitorsByWindwardDistanceTraveledAndOneBasedLegNumber.getValue();
return new com.sap.sse.common.Util.Pair<Integer, CompetitorDTO>(legOfLeaderCompetitor, leadingCompetitorDTO); return new com.sap.sse.common.Util.Pair<Integer, CompetitorDTO>(legOfLeaderCompetitor, leadingCompetitorDTO);
} }
} }
@@ -1378,14 +1378,12 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
private void showStartAndFinishAndCourseMiddleLines(final CoursePositionsDTO courseDTO) { private void showStartAndFinishAndCourseMiddleLines(final CoursePositionsDTO courseDTO) {
if (map != null && courseDTO != null && courseDTO.course != null && courseDTO.course.waypoints != null && if (map != null && courseDTO != null && courseDTO.course != null && courseDTO.course.waypoints != null &&
!courseDTO.course.waypoints.isEmpty()) { !courseDTO.course.waypoints.isEmpty()) {
com.sap.sse.common.Util.Pair<Integer, CompetitorDTO> leadingVisibleCompetitorInfo = getFarthestAheadVisibleCompetitorWithOneBasedLegNumber(getCompetitorsToShow());
int oneBasedLegOfLeadingCompetitor = leadingVisibleCompetitorInfo == null ? -1 : leadingVisibleCompetitorInfo.getA();
int numberOfLegs = courseDTO.course.waypoints.size()-1;
// draw the start line // draw the start line
final WaypointDTO startWaypoint = courseDTO.course.waypoints.get(0); final WaypointDTO startWaypoint = courseDTO.course.waypoints.get(0);
updateCountdownCanvas(startWaypoint); updateCountdownCanvas(startWaypoint);
final Position startLineLeftPosition = courseDTO.getStartMarkPositions().get(0); final int numberOfStartWaypointMarks = courseDTO.getStartMarkPositions() == null ? 0 : courseDTO.getStartMarkPositions().size();
final Position startLineRightPosition = courseDTO.getStartMarkPositions().get(1); final Position startLineLeftPosition = numberOfStartWaypointMarks == 0 ? null : courseDTO.getStartMarkPositions().get(0);
final Position startLineRightPosition = numberOfStartWaypointMarks < 2 ? null : courseDTO.getStartMarkPositions().get(1);
if (courseDTO.startLineAngleToCombinedWind != null) { if (courseDTO.startLineAngleToCombinedWind != null) {
startLineAdvantageText.replace(0, startLineAdvantageText.length(), " "+stringMessages.lineAngleToWindAndAdvantage( startLineAdvantageText.replace(0, startLineAdvantageText.length(), " "+stringMessages.lineAngleToWindAndAdvantage(
NumberFormat.getFormat("0.0").format(courseDTO.startLineLengthInMeters), NumberFormat.getFormat("0.0").format(courseDTO.startLineLengthInMeters),
@@ -1395,19 +1393,16 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
} else { } else {
startLineAdvantageText.delete(0, startLineAdvantageText.length()); startLineAdvantageText.delete(0, startLineAdvantageText.length());
} }
startLine = showOrRemoveOrUpdateLine(startLine, /* showLine */ courseDTO.getStartMarkPositions() != null && startLine = showOrRemoveOrUpdateLine(startLine, /* showLine */ numberOfStartWaypointMarks == 2 &&
courseDTO.getStartMarkPositions().size() == 2 && ((courseDTO.currentLegNumber <= 1 &&
((oneBasedLegOfLeadingCompetitor <= 1 && settings.getHelpLinesSettings().isVisible(HelpLineTypes.STARTLINE)) ||
settings.getHelpLinesSettings().isVisible(HelpLineTypes.STARTLINE)) ||
settings.getHelpLinesSettings().isVisible(HelpLineTypes.COURSEGEOMETRY)), settings.getHelpLinesSettings().isVisible(HelpLineTypes.COURSEGEOMETRY)),
startLineLeftPosition, startLineRightPosition, startLineInfoProvider, "#ffffff"); startLineLeftPosition, startLineRightPosition, startLineInfoProvider, "#ffffff");
// TODO bug3027: show SmallTransparentInfoOverlay in addition to tooltip if course geometry option is true; remove it if option is false
// TODO bug3027: show *all* course middle lines if course geometry option is true
// draw the finish line // draw the finish line
final Position finishLineLeftPosition = courseDTO.getFinishMarkPositions().get(0); final int numberOfFinishWaypointMarks = courseDTO.getFinishMarkPositions() == null ? 0 : courseDTO.getFinishMarkPositions().size();
final Position finishLineRightPosition = courseDTO.getFinishMarkPositions().get(1); final Position finishLineLeftPosition = numberOfFinishWaypointMarks == 0 ? null : courseDTO.getFinishMarkPositions().get(0);
if (courseDTO.startLineAngleToCombinedWind != null) { final Position finishLineRightPosition = numberOfFinishWaypointMarks < 2 ? null : courseDTO.getFinishMarkPositions().get(1);
if (courseDTO.finishLineAngleToCombinedWind != null) {
finishLineAdvantageText.replace(0, finishLineAdvantageText.length(), " "+stringMessages.lineAngleToWindAndAdvantage( finishLineAdvantageText.replace(0, finishLineAdvantageText.length(), " "+stringMessages.lineAngleToWindAndAdvantage(
NumberFormat.getFormat("0.0").format(courseDTO.finishLineLengthInMeters), NumberFormat.getFormat("0.0").format(courseDTO.finishLineLengthInMeters),
NumberFormat.getFormat("0.0").format(Math.abs(courseDTO.finishLineAngleToCombinedWind)), NumberFormat.getFormat("0.0").format(Math.abs(courseDTO.finishLineAngleToCombinedWind)),
@@ -1416,8 +1411,9 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
} else { } else {
finishLineAdvantageText.delete(0, finishLineAdvantageText.length()); finishLineAdvantageText.delete(0, finishLineAdvantageText.length());
} }
finishLine = showOrRemoveOrUpdateLine(finishLine, /* showLine */ courseDTO.getFinishMarkPositions() != null && courseDTO.getFinishMarkPositions().size() == 2 && finishLine = showOrRemoveOrUpdateLine(finishLine, /* showLine */ numberOfFinishWaypointMarks == 2 &&
(oneBasedLegOfLeadingCompetitor > 0 && oneBasedLegOfLeadingCompetitor == numberOfLegs && settings.getHelpLinesSettings().isVisible(HelpLineTypes.FINISHLINE)) (courseDTO.currentLegNumber == courseDTO.totalLegsCount &&
settings.getHelpLinesSettings().isVisible(HelpLineTypes.FINISHLINE))
|| settings.getHelpLinesSettings().isVisible(HelpLineTypes.COURSEGEOMETRY), || settings.getHelpLinesSettings().isVisible(HelpLineTypes.COURSEGEOMETRY),
finishLineLeftPosition, finishLineRightPosition, finishLineInfoProvider, "#000000"); finishLineLeftPosition, finishLineRightPosition, finishLineInfoProvider, "#000000");
// the control point pairs for which we already decided whether or not // the control point pairs for which we already decided whether or not
@@ -1430,8 +1426,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
boolean showCourseMiddleLine = keysAlreadyHandled.containsKey(key) && keysAlreadyHandled.get(key).getA() || boolean showCourseMiddleLine = keysAlreadyHandled.containsKey(key) && keysAlreadyHandled.get(key).getA() ||
settings.getHelpLinesSettings().isVisible(HelpLineTypes.COURSEGEOMETRY) || settings.getHelpLinesSettings().isVisible(HelpLineTypes.COURSEGEOMETRY) ||
(settings.getHelpLinesSettings().isVisible(HelpLineTypes.COURSEMIDDLELINE) (settings.getHelpLinesSettings().isVisible(HelpLineTypes.COURSEMIDDLELINE)
&& oneBasedLegOfLeadingCompetitor > 0 && courseDTO.currentLegNumber > 0
&& oneBasedLegOfLeadingCompetitor-1 == zeroBasedIndexOfStartWaypoint); && courseDTO.currentLegNumber-1 == zeroBasedIndexOfStartWaypoint);
keysAlreadyHandled.put(key, new Pair<>(showCourseMiddleLine, zeroBasedIndexOfStartWaypoint)); keysAlreadyHandled.put(key, new Pair<>(showCourseMiddleLine, zeroBasedIndexOfStartWaypoint));
} }
Set<Set<ControlPointDTO>> keysToConsider = new HashSet<>(keysAlreadyHandled.keySet()); Set<Set<ControlPointDTO>> keysToConsider = new HashSet<>(keysAlreadyHandled.keySet());
@@ -460,6 +460,8 @@ import com.sapsailing.xrr.structureimport.eventimport.RegattaJSON;
* The server side implementation of the RPC service. * The server side implementation of the RPC service.
*/ */
public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements SailingService, RaceFetcher, RegattaFetcher { public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements SailingService, RaceFetcher, RegattaFetcher {
private static final int MAX_NUMBER_OF_WIND_FIXES_TO_DELIVER_IN_ONE_CALL = 10000;
private static final Logger logger = Logger.getLogger(SailingServiceImpl.class.getName()); private static final Logger logger = Logger.getLogger(SailingServiceImpl.class.getName());
private static final long serialVersionUID = 9031688830194537489L; private static final long serialVersionUID = 9031688830194537489L;
@@ -1416,7 +1418,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
TimePoint toTimePoint = to == null ? trackedRace.getEndOfRace() == null ? TimePoint toTimePoint = to == null ? trackedRace.getEndOfRace() == null ?
MillisecondsTimePoint.now().minus(trackedRace.getDelayToLiveInMillis()) : trackedRace.getEndOfRace() : new MillisecondsTimePoint(to); MillisecondsTimePoint.now().minus(trackedRace.getDelayToLiveInMillis()) : trackedRace.getEndOfRace() : new MillisecondsTimePoint(to);
if (fromTimePoint != null && toTimePoint != null) { if (fromTimePoint != null && toTimePoint != null) {
int numberOfFixes = (int) ((toTimePoint.asMillis() - fromTimePoint.asMillis())/resolutionInMilliseconds); int numberOfFixes = Math.min(MAX_NUMBER_OF_WIND_FIXES_TO_DELIVER_IN_ONE_CALL,
(int) ((toTimePoint.asMillis() - fromTimePoint.asMillis())/resolutionInMilliseconds));
result = getAveragedWindInfo(fromTimePoint, resolutionInMilliseconds, numberOfFixes, result = getAveragedWindInfo(fromTimePoint, resolutionInMilliseconds, numberOfFixes,
windSourceTypeNames, trackedRace, onlyUpToNewestEvent, /* includeCombinedWindForAllLegMiddles */ false); windSourceTypeNames, trackedRace, onlyUpToNewestEvent, /* includeCombinedWindForAllLegMiddles */ false);
} }
@@ -4003,7 +4006,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
Map<String, List<RegattaOverviewEntryDTO>> entriesPerFleet = new HashMap<String, List<RegattaOverviewEntryDTO>>(); Map<String, List<RegattaOverviewEntryDTO>> entriesPerFleet = new HashMap<String, List<RegattaOverviewEntryDTO>>();
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) { for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
getRegattaOverviewEntries(showOnlyRacesOfSameDay, dayToCheck, usedCourseArea, getRegattaOverviewEntries(showOnlyRacesOfSameDay, dayToCheck, usedCourseArea,
leaderboard, boatClass.getName(), regattaName, LeaderboardNameConstants.DEFAULT_SERIES_NAME, raceColumn, entriesPerFleet); leaderboard, boatClass == null ? "" : boatClass.getName(), regattaName, LeaderboardNameConstants.DEFAULT_SERIES_NAME, raceColumn, entriesPerFleet);
} }
result.addAll(getRegattaOverviewEntriesToBeShown(showOnlyCurrentlyRunningRaces, entriesPerFleet)); result.addAll(getRegattaOverviewEntriesToBeShown(showOnlyCurrentlyRunningRaces, entriesPerFleet));
} }
@@ -261,6 +261,7 @@ public class RaceContext {
case FINISHING: case FINISHING:
case RUNNING: case RUNNING:
case SCHEDULED: case SCHEDULED:
case PRESCHEDULED:
case STARTPHASE: case STARTPHASE:
case UNKNOWN: case UNKNOWN:
break; break;
@@ -45,6 +45,7 @@ import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HasValue; import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RequiresResize; import com.google.gwt.user.client.ui.RequiresResize;
import com.sap.sse.common.Util;
/** /**
* A widget that allows the user to select a value within a range of possible values using a sliding bar that responds * A widget that allows the user to select a value within a range of possible values using a sliding bar that responds
@@ -704,9 +705,10 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
* the current value * the current value
*/ */
public void setMaxValue(Double maxValue, boolean fireEvent) { public void setMaxValue(Double maxValue, boolean fireEvent) {
this.maxValue = maxValue; if (!Util.equalsWithNull(maxValue, this.maxValue)) {
drawTickLabels(); this.maxValue = maxValue;
resetCurrentValue(fireEvent); onMinMaxValueChanged(fireEvent);
}
} }
/** /**
@@ -716,8 +718,40 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
* the current value * the current value
*/ */
public void setMinValue(Double minValue, boolean fireEvent) { public void setMinValue(Double minValue, boolean fireEvent) {
this.minValue = minValue; if (!Util.equalsWithNull(minValue, this.minValue)) {
drawTickLabels(); this.minValue = minValue;
onMinMaxValueChanged(fireEvent);
}
}
/**
* Set the minimum and maximum value
*
* @param minValue
* the current value for min
* @param maxValue
* the current valuefor max
*/
public void setMinAndMaxValue(Double minValue, Double maxValue, boolean fireEvent) {
boolean changed = false;
if (!Util.equalsWithNull(minValue, this.minValue)) {
this.minValue = minValue;
changed = true;
}
if (!Util.equalsWithNull(maxValue, this.maxValue)) {
this.maxValue = maxValue;
changed = true;
}
if (changed) {
onMinMaxValueChanged(fireEvent);
}
}
/**
* Handle value changes of min and/or max value
*/
protected void onMinMaxValueChanged(boolean fireEvent) {
redraw();
resetCurrentValue(fireEvent); resetCurrentValue(fireEvent);
} }
@@ -1037,6 +1071,7 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
int lineWidth = lineElement.getOffsetWidth(); int lineWidth = lineElement.getOffsetWidth();
if (numMarkers > 0) { if (numMarkers > 0) {
Element lastMarkerLabel = null; Element lastMarkerLabel = null;
Marker lastMarker = null;
int lastMarkerLabelOffsetLeft = 0; int lastMarkerLabelOffsetLeft = 0;
// Create the labels or make them visible // Create the labels or make them visible
for (int i = 0; i < numMarkers; i++) { for (int i = 0; i < numMarkers; i++) {
@@ -1076,9 +1111,9 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
// hide last marker label if it is too close to the one just created // hide last marker label if it is too close to the one just created
if (lastMarkerLabelOffsetLeft > 0 && (labelLeftOffset-lastMarkerLabelOffsetLeft) <= 20) { if (lastMarkerLabelOffsetLeft > 0 && (labelLeftOffset-lastMarkerLabelOffsetLeft) <= 20) {
if (lastMarkerLabel != null) { if (lastMarkerLabel != null && lastMarker != null) {
lastMarkerLabel.setPropertyString("className", "gwt-SliderBar-markerlabel-tooClose"); lastMarkerLabel.setPropertyString("className", "gwt-SliderBar-markerlabel-tooClose");
lastMarkerLabel.setPropertyString("innerHTML", "M"); // no space for more lastMarkerLabel.setPropertyString("innerHTML", lastMarker.name); // no space for more
int currentMarkerOffsetLeft = labelLeftOffset; int currentMarkerOffsetLeft = labelLeftOffset;
try { try {
currentMarkerOffsetLeft = Integer.parseInt(markerElements.get(i).getStyle().getLeft().replace("px", "")); currentMarkerOffsetLeft = Integer.parseInt(markerElements.get(i).getStyle().getLeft().replace("px", ""));
@@ -1088,6 +1123,7 @@ public class SliderBar extends FocusPanel implements RequiresResize, HasValue<Do
lastMarkerLabel.getStyle().setLeft(currentMarkerOffsetLeft-8, Unit.PX); lastMarkerLabel.getStyle().setLeft(currentMarkerOffsetLeft-8, Unit.PX);
} }
} }
lastMarker = marker;
lastMarkerLabel = label; lastMarkerLabel = label;
lastMarkerLabelOffsetLeft = labelLeftOffset; lastMarkerLabelOffsetLeft = labelLeftOffset;
} }
@@ -3,12 +3,12 @@ package com.sap.sse.gwt.client.controls.slider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.google.gwt.user.client.DOM;
import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Display; import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Position; import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.Visibility; import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.user.client.DOM;
import com.sap.sse.gwt.client.controls.slider.TimeTicksCalculator.NormalizedInterval; import com.sap.sse.gwt.client.controls.slider.TimeTicksCalculator.NormalizedInterval;
import com.sap.sse.gwt.client.controls.slider.TimeTicksCalculator.TickPosition; import com.sap.sse.gwt.client.controls.slider.TimeTicksCalculator.TickPosition;
@@ -182,7 +182,7 @@ public class TimeSlider extends SliderBar {
return; return;
Element knobElement = knobImage.getElement(); Element knobElement = knobImage.getElement();
if(curValue >= minValue && curValue <= maxValue) { if (curValue != null && minValue != null && maxValue != null && curValue >= minValue && curValue <= maxValue) {
// Move the knob to the correct position // Move the knob to the correct position
int lineWidth = lineElement.getOffsetWidth(); int lineWidth = lineElement.getOffsetWidth();
int knobWidth = knobElement.getOffsetWidth(); int knobWidth = knobElement.getOffsetWidth();
@@ -199,21 +199,35 @@ public class TimeSlider extends SliderBar {
} }
public void setMaxValue(Double maxValue, boolean fireEvent) { public void setMaxValue(Double maxValue, boolean fireEvent) {
if(!isZoomed) { if (!isZoomed) {
super.setMaxValue(maxValue, fireEvent); super.setMaxValue(maxValue, fireEvent);
} else { } else {
this.maxValue = maxValue; this.maxValue = maxValue;
} }
calculateTicks();
} }
public void setMinValue(Double minValue, boolean fireEvent) { public void setMinValue(Double minValue, boolean fireEvent) {
if(!isZoomed) { if (!isZoomed) {
super.setMinValue(minValue, fireEvent); super.setMinValue(minValue, fireEvent);
} else { } else {
this.minValue = minValue; this.minValue = minValue;
}
}
@Override
public void setMinAndMaxValue(Double minValue, Double maxValue, boolean fireEvent) {
if (!isZoomed) {
super.setMinAndMaxValue(minValue, maxValue, fireEvent);
} else {
this.minValue = minValue;
this.maxValue = maxValue;
} }
}
@Override
protected void onMinMaxValueChanged(boolean fireEvent) {
calculateTicks(); calculateTicks();
super.onMinMaxValueChanged(fireEvent);
} }
public void setStepSize(double stepSize, boolean fireEvent) { public void setStepSize(double stepSize, boolean fireEvent) {
@@ -1,49 +1,49 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp"> <launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/> <booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/> <stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/> <booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
<stringAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT" value="9875"/> <stringAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT" value="9875"/>
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/> <booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES"> <listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sse.security.ui.UserManagement"/> <listEntry value="com.sap.sse.security.ui.UserManagement"/>
</listAttribute> </listAttribute>
<booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/> <booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/security/ui/Login.html"/> <stringAttribute key="com.google.gwt.eclipse.core.URL" value="/security/ui/Login.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.sap.sse.security.ui"/> <listEntry value="/com.sap.sse.security.ui"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/> <listEntry value="4"/>
</listAttribute> </listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> <listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> <listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute> </listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/> <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> <listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;com.sap.sse.security.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;com.sap.sse.security.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.googlecode.java-diff-utils/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.googlecode.java-diff-utils/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.json.simple/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.json.simple/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.operationaltransformation/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.operationaltransformation/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sse.security.ui&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sse.security.ui&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.adminconsole/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.adminconsole/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/> <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
</listAttribute> </listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/> <stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir &quot;${project_loc:com.sap.sse.security.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sse.security.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /security/ui/Login.html com.sap.sse.security.ui.Login -startupUrl /security/ui/EditProfile.html com.sap.sse.security.ui.EditProfile -startupUrl /security/ui/EmailValidation.html com.sap.sse.security.ui.EmailValidation -startupUrl /security/ui/UserManagement.html com.sap.sse.security.ui.UserManagement"/> <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -workDir &quot;${project_loc:com.sap.sse.security.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sse.security.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /security/ui/Login.html com.sap.sse.security.ui.Login -startupUrl /security/ui/EditProfile.html com.sap.sse.security.ui.EditProfile -startupUrl /security/ui/EmailValidation.html com.sap.sse.security.ui.EmailValidation -startupUrl /security/ui/UserManagement.html com.sap.sse.security.ui.UserManagement"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sse.security.ui"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sse.security.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/> <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/>
</launchConfiguration> </launchConfiguration>
Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 769 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/dark_sap_gray_black_30" android:state_selected="true"/>
<item android:drawable="@color/dark_black"/>
</selector>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/light_sap_gray_black_30" android:state_selected="true"/>
<item android:drawable="@color/light_black"/>
</selector>
@@ -4,5 +4,5 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:datePickerMode="spinner" android:datePickerMode="spinner"
android:scaleX="1.55" android:scaleX="@integer/picker_scale"
android:scaleY="1.55"/> android:scaleY="@integer/picker_scale"/>
@@ -4,6 +4,6 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:scaleX="1.55" android:scaleX="@integer/picker_scale"
android:scaleY="1.55" android:scaleY="@integer/picker_scale"
android:timePickerMode="spinner"/> android:timePickerMode="spinner"/>
@@ -4,5 +4,5 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:calendarViewShown="false" android:calendarViewShown="false"
android:scaleX="1.55" android:scaleX="@integer/picker_scale"
android:scaleY="1.55"/> android:scaleY="@integer/picker_scale"/>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?sap_gray_black_30"
android:orientation="vertical"
android:padding="@dimen/default_padding_half">
<TextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?textLarge"
tools:text="Singapore"/>
<TextView
android:id="@android:id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?textNormal"
android:visibility="gone"
tools:text="Day 2"
tools:visibility="visible"/>
</LinearLayout>
@@ -20,6 +20,6 @@
android:layout_gravity="center" android:layout_gravity="center"
android:paddingLeft="@dimen/default_padding" android:paddingLeft="@dimen/default_padding"
android:paddingRight="@dimen/default_padding" android:paddingRight="@dimen/default_padding"
android:scaleX="1.55" android:scaleX="@integer/picker_scale"
android:scaleY="1.55"/> android:scaleY="@integer/picker_scale"/>
</LinearLayout> </LinearLayout>
@@ -25,7 +25,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:src="?chevron_left_24dp" android:src="?chevron_left_24dp"
android:visibility="gone"/> android:visibility="gone"
tools:visibility="visible"/>
<ImageView <ImageView
android:id="@+id/header_flag" android:id="@+id/header_flag"
@@ -112,8 +113,8 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="11" android:layout_weight="11"
android:scaleX="1.55" android:scaleX="@integer/picker_scale"
android:scaleY="1.55"> android:scaleY="@integer/picker_scale">
<include <include
android:id="@+id/time_picker" android:id="@+id/time_picker"
@@ -71,47 +71,53 @@
android:src="?marker_race"/> android:src="?marker_race"/>
<LinearLayout <LinearLayout
android:id="@+id/race_flag" android:id="@+id/additional_info"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_centerVertical="true" android:layout_centerVertical="true">
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical">
<ImageView <ImageView
android:id="@+id/current_flag" android:id="@+id/has_dependent_races"
android:layout_width="40dp"
android:layout_height="25dp"
android:layout_gravity="center_horizontal"
android:scaleType="centerInside"
tools:src="@drawable/alpha_flag"/>
<LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:layout_gravity="center_vertical"
android:layout_margin="5dp"
android:src="?link_24dp"
android:visibility="gone"
tools:visibility="visible"/>
<LinearLayout
android:id="@+id/race_flag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<ImageView <ImageView
android:id="@+id/arrow_direction" android:id="@+id/current_flag"
android:layout_width="wrap_content" android:layout_width="40dp"
android:layout_height="wrap_content" android:layout_height="25dp"
tools:src="?arrow_down"/> android:layout_gravity="center_horizontal"
android:scaleType="centerInside"
tools:src="@drawable/alpha_flag"/>
<TextView <TextView
android:id="@+id/flag_timer" android:id="@+id/flag_timer"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:drawableLeft="?arrow_down"
android:textAppearance="?textXSmall" android:textAppearance="?textXSmall"
tools:text="01:12"/> tools:text="01:12"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<TextView <LinearLayout
android:id="@+id/race_name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
@@ -119,12 +125,28 @@
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/default_margin" android:layout_marginLeft="@dimen/default_margin"
android:layout_marginStart="@dimen/default_margin" android:layout_marginStart="@dimen/default_margin"
android:layout_toLeftOf="@id/race_flag" android:layout_toLeftOf="@id/additional_info"
android:layout_toStartOf="@id/race_flag" android:layout_toStartOf="@id/additional_info"
android:orientation="vertical" android:orientation="vertical">
android:singleLine="true"
android:textAppearance="?textNormal" <TextView
tools:text="Race 3"/> android:id="@+id/race_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?textNormal"
tools:text="Race 3"/>
<TextView
android:id="@+id/depends_on"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?textXSmall"
android:visibility="gone"
tools:text="5 minutes after ABC"
tools:visibility="visible"/>
</LinearLayout>
</RelativeLayout> </RelativeLayout>
<ImageView <ImageView
@@ -8,7 +8,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@color/constant_black" /> android:src="@color/constant_black"/>
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -27,7 +27,7 @@
android:layout_margin="@dimen/default_margin" android:layout_margin="@dimen/default_margin"
android:background="@drawable/round_button" android:background="@drawable/round_button"
android:padding="10dp" android:padding="10dp"
android:src="@drawable/ic_power_settings_new_white_48dp" /> android:src="@drawable/ic_power_settings_new_white_48dp"/>
<TextView <TextView
android:id="@+id/regatta_data" android:id="@+id/regatta_data"
@@ -36,24 +36,23 @@
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_toLeftOf="@id/nav_button" android:layout_toLeftOf="@id/nav_button"
android:layout_toStartOf="@id/nav_button" android:layout_toStartOf="@id/nav_button"
tools:text="Marina Bay / Viewer"
android:textSize="@dimen/textSize_32"
android:paddingLeft="@dimen/default_padding_half" android:paddingLeft="@dimen/default_padding_half"
android:paddingRight="@dimen/default_padding_half" android:paddingRight="@dimen/default_padding_half"
android:textColor="@color/constant_white" android:textColor="@color/constant_white"
/> android:textSize="@dimen/textSize_32"
tools:text="Marina Bay / Viewer"/>
<TextView <TextView
android:id="@+id/regatta_course" android:id="@+id/regatta_course"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_above="@id/regatta_data"
android:layout_toLeftOf="@id/nav_button" android:layout_toLeftOf="@id/nav_button"
android:layout_toStartOf="@id/nav_button" android:layout_toStartOf="@id/nav_button"
android:layout_above="@id/regatta_data"
android:paddingLeft="@dimen/default_padding_half" android:paddingLeft="@dimen/default_padding_half"
android:paddingRight="@dimen/default_padding_half" android:paddingRight="@dimen/default_padding_half"
android:singleLine="true" android:singleLine="true"
android:textColor="@color/constant_white" android:textColor="@color/constant_white"
tools:text="Extreme Sailing Series 2015 Act 1 Singapore" android:textSize="@dimen/textSize_32"
android:textSize="@dimen/textSize_32" /> tools:text="Extreme Sailing Series 2015 Act 1 Singapore"/>
</RelativeLayout> </RelativeLayout>
@@ -20,7 +20,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:text="@string/races_current" android:text="@string/races_current"
android:textColor="?sap_light_gray" android:textColor="?sap_yellow_1"
android:textSize="@dimen/textSize_20" android:textSize="@dimen/textSize_20"
android:textStyle="bold"/> android:textStyle="bold"/>
@@ -49,10 +49,10 @@
android:dividerHeight="1dp"/> android:dividerHeight="1dp"/>
<ProgressBar <ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:id="@+id/progress"
android:visibility="gone"/> android:visibility="gone"/>
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/race_content_header" android:id="@+id/race_content_header"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?sap_gray"> android:background="?sap_gray">
@@ -14,14 +15,14 @@
android:gravity="center" android:gravity="center"
android:textColor="?white" android:textColor="?white"
android:textSize="@dimen/textSize_40" android:textSize="@dimen/textSize_40"
tools:text="@string/time" /> tools:text="@string/time"/>
<ImageView <ImageView
android:id="@+id/time_marker" android:id="@+id/time_marker"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/thin_line" android:layout_height="@dimen/thin_line"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:src="?marker" /> android:src="?marker"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -43,19 +44,36 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:textAppearance="?textSmall" android:textAppearance="?textSmall"
tools:text="@string/time_start" /> tools:text="@string/time_start"/>
<ImageView <LinearLayout
android:id="@+id/time_start_lock"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginRight="@dimen/default_margin_half" android:layout_marginRight="@dimen/default_margin_half"
android:layout_toLeftOf="@+id/time_start" android:layout_toLeftOf="@+id/time_start"
android:layout_toStartOf="@+id/time_start" android:layout_toStartOf="@+id/time_start"
android:src="?lock_outline" android:orientation="horizontal">
android:visibility="gone" />
<ImageView
android:id="@+id/time_start_lock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="?lock_outline"
android:visibility="gone"
tools:visibility="visible"/>
<ImageView
android:id="@+id/linked_race"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="?link_24dp"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout>
</RelativeLayout> </RelativeLayout>
<RelativeLayout <RelativeLayout
@@ -76,7 +94,8 @@
android:gravity="center" android:gravity="center"
android:textAppearance="?textSmall" android:textAppearance="?textSmall"
android:visibility="invisible" android:visibility="invisible"
tools:text="@string/time" /> tools:text="@string/time"
tools:visibility="visible"/>
</RelativeLayout> </RelativeLayout>
<RelativeLayout <RelativeLayout
@@ -93,7 +112,8 @@
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:text="@string/time_finish" android:text="@string/time_finish"
android:textAppearance="?textSmall" android:textAppearance="?textSmall"
android:visibility="invisible" /> android:visibility="invisible"
tools:visibility="visible"/>
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>
@@ -82,8 +82,8 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="75dp" android:layout_marginLeft="75dp"
android:scaleX="1.55" android:scaleX="@integer/picker_scale"
android:scaleY="1.55" /> android:scaleY="@integer/picker_scale" />
</LinearLayout> </LinearLayout>
@@ -4,5 +4,5 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:scaleX="1.55" android:scaleX="@integer/picker_scale"
android:scaleY="1.55"/> android:scaleY="@integer/picker_scale"/>
@@ -80,8 +80,8 @@
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/default_margin_twice" android:layout_marginBottom="@dimen/default_margin_twice"
android:layout_marginTop="@dimen/default_margin_twice" android:layout_marginTop="@dimen/default_margin_twice"
android:scaleX="1.55" android:scaleX="@integer/picker_scale"
android:scaleY="1.55"/> android:scaleY="@integer/picker_scale"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
@@ -123,8 +123,8 @@
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginBottom="@dimen/default_margin_twice" android:layout_marginBottom="@dimen/default_margin_twice"
android:layout_marginTop="@dimen/default_margin_twice" android:layout_marginTop="@dimen/default_margin_twice"
android:scaleX="1.55" android:scaleX="@integer/picker_scale"
android:scaleY="1.55"/> android:scaleY="@integer/picker_scale"/>
</LinearLayout> </LinearLayout>
<TextView <TextView
@@ -34,67 +34,209 @@
android:text="@string/set_time" android:text="@string/set_time"
android:textAppearance="?textNormal"/> android:textAppearance="?textNormal"/>
</LinearLayout> </LinearLayout>
<View
android:id="@+id/line_top"
android:layout_width="match_parent"
android:layout_height="@dimen/thick_line"
android:layout_alignParentBottom="true"
android:background="?black"/>
</RelativeLayout> </RelativeLayout>
<RelativeLayout <LinearLayout
android:id="@+id/buttonBar" android:id="@+id/tab_button"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/selector_header_height"> android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="?black"
android:orientation="horizontal"
android:visibility="gone"
tools:visibility="visible">
<LinearLayout <Button
android:layout_width="wrap_content" android:id="@+id/absolute"
style="?android:attr/borderlessButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_weight="1"
android:layout_marginTop="@dimen/default_margin_half" android:text="@string/dependent_races_absolute"
android:orientation="horizontal"> android:textAllCaps="true"
android:textColor="?sap_yellow_1"
android:textSize="@dimen/textSize_26"/>
<Button <Button
android:id="@+id/minute_inc" android:id="@+id/relative"
android:layout_width="wrap_content" style="?android:attr/borderlessButtonStyle"
android:layout_height="wrap_content" android:layout_width="0dp"
android:layout_gravity="center_vertical" android:layout_height="wrap_content"
android:background="?button_filled_bordered" android:layout_weight="1"
android:drawableLeft="?chevron_left_36dp" android:text="@string/dependent_races_relative"
android:paddingRight="@dimen/default_padding_half" android:textAllCaps="true"
android:textAppearance="?textLarge" android:textColor="?sap_light_gray"
android:textColor="?white" android:textSize="@dimen/textSize_26"/>
tools:text="@string/race_start_time_in"/> </LinearLayout>
<TextView <FrameLayout
android:id="@+id/start_countdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin"
android:textAppearance="?textXLarge"
android:visibility="visible"
tools:text="@string/race_start_time_in"/>
<Button
android:id="@+id/minute_dec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?button_filled_bordered"
android:drawableRight="?chevron_right_36dp"
android:paddingLeft="@dimen/default_padding_half"
android:textAppearance="?textLarge"
android:textColor="?white"
tools:text="@string/race_start_time_in"/>
</LinearLayout>
</RelativeLayout>
<View
android:id="@+id/line_top"
android:layout_width="match_parent"
android:layout_height="@dimen/thick_line"
android:layout_below="@id/buttonBar"
android:background="?black"/>
<include
layout="@layout/race_time_picker"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@id/buttonBar"/> android:layout_above="@id/tab_button"
android:layout_below="@id/header">
<RelativeLayout
android:id="@+id/time_absolute"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?sap_gray_black_30"
android:visibility="gone"
tools:visibility="visible">
<RelativeLayout
android:id="@+id/buttonBar"
android:layout_width="match_parent"
android:layout_height="@dimen/selector_header_height"
android:layout_alignParentTop="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginTop="@dimen/default_margin_half"
android:orientation="horizontal">
<Button
android:id="@+id/minute_inc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?button_filled_bordered"
android:drawableLeft="?chevron_left_36dp"
android:paddingRight="@dimen/default_padding_half"
android:textAppearance="?textLarge"
android:textColor="?white"
tools:text="@string/race_start_time_in"/>
<TextView
android:id="@+id/start_countdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin"
android:textAppearance="?textXLarge"
android:visibility="visible"
tools:text="@string/race_start_time_in"/>
<Button
android:id="@+id/minute_dec"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="?button_filled_bordered"
android:drawableRight="?chevron_right_36dp"
android:paddingLeft="@dimen/default_padding_half"
android:textAppearance="?textLarge"
android:textColor="?white"
tools:text="@string/race_start_time_in"/>
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:id="@+id/start_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:scaleX="@integer/picker_scale"
android:scaleY="@integer/picker_scale">
<NumberPicker
android:id="@+id/start_date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:descendantFocusability="blocksDescendants"/>
<include
android:id="@+id/start_time_picker"
layout="@layout/time_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<Button
android:id="@+id/set_start_time_absolute"
style="?attr/buttonSolidSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:layout_margin="@dimen/default_margin_twice"
android:maxWidth="200dp"
android:text="@string/race_set_time"/>
<TextView
android:id="@+id/debug_time"
style="?textSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:visibility="gone"
tools:text="12:12:12"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/time_relative"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?sap_gray_black_30"
android:visibility="gone"
tools:visibility="visible">
<LinearLayout
android:id="@+id/relative_input"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<NumberPicker
android:id="@+id/time_offset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/default_margin"
android:layout_marginTop="@dimen/default_margin"
android:scaleX="@integer/picker_scale"
android:scaleY="@integer/picker_scale"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="@dimen/default_padding"
android:text="@string/minutes_after"
android:textAppearance="?textLarge"/>
<Spinner
android:id="@+id/dependent_race"
android:layout_width="470dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:dropDownWidth="wrap_content"
android:prompt="@string/dependent_races_prompt"
android:spinnerMode="dropdown"/>
</LinearLayout>
<Button
android:id="@+id/set_start_time_relative"
style="?attr/buttonSolidSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/relative_input"
android:layout_centerInParent="true"
android:maxWidth="200dp"
android:text="@string/race_set_time"/>
</RelativeLayout>
</FrameLayout>
</RelativeLayout> </RelativeLayout>
@@ -10,7 +10,7 @@
android:orientation="vertical"> android:orientation="vertical">
<RelativeLayout <RelativeLayout
android:id="@+id/header" android:id="@+id/header_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/selector_header_height" android:layout_height="@dimen/selector_header_height"
android:background="?sap_gray"> android:background="?sap_gray">
@@ -54,8 +54,9 @@
android:src="?wind_on" android:src="?wind_on"
android:visibility="gone"/> android:visibility="gone"/>
<LinearLayout <TextView
android:id="@+id/header_text" android:id="@+id/header_text"
android:drawableLeft="?chevron_left_24dp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
@@ -65,28 +66,18 @@
android:layout_marginStart="@dimen/default_margin" android:layout_marginStart="@dimen/default_margin"
android:layout_toLeftOf="@id/wind_off" android:layout_toLeftOf="@id/wind_off"
android:layout_toStartOf="@id/wind_off" android:layout_toStartOf="@id/wind_off"
android:orientation="horizontal"> android:layout_gravity="center_vertical"
android:orientation="horizontal"
android:text="@string/wind"
android:textAppearance="?textNormal" />
<ImageView
android:id="@+id/header_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="?chevron_left_24dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/wind"
android:textAppearance="?textNormal"/>
</LinearLayout>
</RelativeLayout> </RelativeLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/content_layout"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@id/header" android:layout_below="@id/header_layout"
android:background="?sap_gray_black_30" android:background="?sap_gray_black_30"
android:orientation="vertical" android:orientation="vertical"
android:paddingLeft="@dimen/default_padding" android:paddingLeft="@dimen/default_padding"
@@ -140,10 +131,11 @@
android:visibility="visible"/> android:visibility="visible"/>
<com.sap.sailing.racecommittee.app.ui.views.CompassView <com.sap.sailing.racecommittee.app.ui.views.CompassView
android:id="@+id/compassView" android:id="@+id/compass_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true"/> android:layout_centerInParent="true"/>
</RelativeLayout> </RelativeLayout>
<RelativeLayout <RelativeLayout
@@ -169,15 +161,20 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:scaleX="1.55" android:scaleX="@integer/picker_scale"
android:scaleY="1.55"/> android:scaleY="@integer/picker_scale"/>
</RelativeLayout> </RelativeLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/layout_map" android:id="@+id/layout_position"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:layout_marginEnd="@dimen/default_margin"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin"
android:layout_marginStart="@dimen/default_margin"
android:orientation="vertical">
<TextView <TextView
android:id="@+id/position_header" android:id="@+id/position_header"
@@ -189,77 +186,119 @@
android:textAppearance="?textSmall"/> android:textAppearance="?textSmall"/>
<RelativeLayout <RelativeLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/position_header"> android:layout_below="@+id/position_header">
<FrameLayout <TextView
android:id="@+id/windMap" android:id="@+id/position_latitude"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/welcome"/>
<RelativeLayout
android:id="@+id/address"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin" android:layout_margin="@dimen/default_margin"
android:background="?white" android:text="@string/wind_latitude"
android:orientation="horizontal" android:textAppearance="?textSmall"/>
android:visibility="gone"
tools:visibility="visible">
<ImageButton <TextView
android:id="@+id/address_search" android:id="@+id/position_longitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@android:color/transparent"
android:padding="@dimen/default_padding_half"
android:src="?search_24dp_invert"/>
<EditText
android:id="@+id/address_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/default_margin_half"
android:layout_marginStart="@dimen/default_margin_half"
android:layout_toLeftOf="@id/address_search"
android:layout_toStartOf="@id/address_search"
android:hint="@string/wind_address_hint"
android:padding="@dimen/default_padding_half"
android:singleLine="true"
android:textAppearance="?textNormal"
android:textColor="?white_invert"
android:textColorHint="?sap_light_gray"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/dark_layer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin"
android:layout_below="@+id/position_latitude"
android:text="@string/wind_longitude"
android:textAppearance="?textSmall"/>
<View <TextView
android:layout_width="match_parent" android:id="@+id/position_accuracy"
android:layout_height="match_parent" android:layout_width="match_parent"
android:background="@color/constant_black_transparent"/> android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin"
android:layout_below="@+id/position_longitude"
android:text="@string/wind_accuracy"
android:textAppearance="?textSmall"/>
<Button
android:id="@+id/position_show"
style="?attr/buttonSolidNormal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/position_accuracy"
android:layout_centerHorizontal="true"
android:text="@string/wind_map_button_show"/>
<Button
android:id="@+id/enter_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/button_border_light"
android:padding="@dimen/default_padding"
android:text="@string/wind_enter_position"
android:textAllCaps="true"
android:textAppearance="?textNormal"
android:textColor="?white"/>
</RelativeLayout>
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>
<RelativeLayout
android:id="@+id/map_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/content_layout"
android:visibility="gone">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<!-- the following layout is for a future implementation -->
<!--<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:visibility="gone">
<Button
style="?attr/buttonSolidNormal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Overall"/>
<Button
style="?attr/buttonSolidNormal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#1"/>
<Button
style="?attr/buttonSolidNormal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#2"/>
<Button
style="?attr/buttonSolidNormal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#3"/>
</LinearLayout>-->
</LinearLayout>
<Button
android:id="@+id/position_hide"
style="?attr/buttonSolidNormal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="@dimen/wind_hide_button_right_margin"
android:layout_marginEnd="@dimen/wind_hide_button_right_margin"
android:layout_marginTop="@dimen/wind_hide_button_top_margin"
android:text="@string/wind_map_button_hide"/>
</RelativeLayout>
</RelativeLayout> </RelativeLayout>
@@ -39,6 +39,7 @@
<string name="label_login_position">Position</string> <string name="label_login_position">Position</string>
<string name="login_type_viewer">Im Demo-Modus anmelden</string> <string name="login_type_viewer">Im Demo-Modus anmelden</string>
<string name="racelist_unscheduled">Noch nicht geplant</string> <string name="racelist_unscheduled">Noch nicht geplant</string>
<string name="racelist_prescheduled">Geplant für %s</string>
<string name="racelist_scheduled">Geplant für %s</string> <string name="racelist_scheduled">Geplant für %s</string>
<string name="racelist_startphase">Start um %s läuft</string> <string name="racelist_startphase">Start um %s läuft</string>
<string name="racelist_running">Gestartet um %s</string> <string name="racelist_running">Gestartet um %s</string>
@@ -300,7 +301,7 @@
<string name="time_down">Runter in #TIME#</string> <string name="time_down">Runter in #TIME#</string>
<string name="time_up">Hoch in #TIME#</string> <string name="time_up">Hoch in #TIME#</string>
<string name="time_finish">Ende N/A</string> <string name="time_finish">Ende N/A</string>
<string name="time_start">Start #TIME#</string> <string name="time_start">Start %s</string>
<string name="time">#TIME#</string> <string name="time">#TIME#</string>
<string name="set_signal">Signal setzen</string> <string name="set_signal">Signal setzen</string>
<string name="flag_ap_desc">Rennen verschieben</string> <string name="flag_ap_desc">Rennen verschieben</string>
@@ -323,13 +324,13 @@
<string name="race_reset_cancel">Nein danke</string> <string name="race_reset_cancel">Nein danke</string>
<string name="race_reset_message">Möchten Sie wirklich das Rennen inklusive aller Einstellungen und getätigten Aktionen zurücksetzen? Das kann nicht rückgängig gemacht werden!</string> <string name="race_reset_message">Möchten Sie wirklich das Rennen inklusive aller Einstellungen und getätigten Aktionen zurücksetzen? Das kann nicht rückgängig gemacht werden!</string>
<string name="race_set_time">Zeit setzen</string> <string name="race_set_time">Zeit setzen</string>
<string name="race_start_time_in">-#TIME#</string> <string name="race_start_time_in">-%s</string>
<string name="race_start_time_ago">#TIME#</string> <string name="race_start_time_ago">%s</string>
<string name="tomorrow">Morgen</string> <string name="tomorrow">Morgen</string>
<string name="race_begin_finish_header">Beginn des Zieleinlaufs</string> <string name="race_begin_finish_header">Beginn des Zieleinlaufs</string>
<string name="race_begin_finish_current">Aktuelle Zeit verwenden</string> <string name="race_begin_finish_current">Aktuelle Zeit verwenden</string>
<string name="race_begin_finish_custom">Angegebene Zeit verwenden</string> <string name="race_begin_finish_custom">Angegebene Zeit verwenden</string>
<string name="wind_sensor"><![CDATA[um #AT# / von #FROM#° / #SPEED# kn]]></string> <string name="wind_sensor"><![CDATA[um %1$s / von %2$.0f° / %3$.1f kn]]></string>
<string name="wind_no_data">Keine Daten</string> <string name="wind_no_data">Keine Daten</string>
<string name="wind_panel"><![CDATA[von %1$.0f°\n%2$.1f kn]]></string> <string name="wind_panel"><![CDATA[von %1$.0f°\n%2$.1f kn]]></string>
<string name="settings_category_developer">Entwickler Optionen</string> <string name="settings_category_developer">Entwickler Optionen</string>
@@ -341,7 +342,7 @@
<string name="gate_start_set_pathfinder">Pathfinder setzen</string> <string name="gate_start_set_pathfinder">Pathfinder setzen</string>
<string name="gate_start_set">Gate Time setzen</string> <string name="gate_start_set">Gate Time setzen</string>
<string name="race_setup_confirm">Setup bestätigen</string> <string name="race_setup_confirm">Setup bestätigen</string>
<string name="race_end_finish_header">Ende des Zieleinlaufs</string> <string name="race_end_finish_header">Ende des Zieleinlaufs (Beginn Zieleinlauf: %s)</string>
<string name="race_summary_finish_begin">Beginn des Zieleinlaufs</string> <string name="race_summary_finish_begin">Beginn des Zieleinlaufs</string>
<string name="race_summary_finish_duration">Dauer des Zieleinlaufs</string> <string name="race_summary_finish_duration">Dauer des Zieleinlaufs</string>
<string name="race_summary_finish_end">Ende des Zieleinlaufs</string> <string name="race_summary_finish_end">Ende des Zieleinlaufs</string>
@@ -372,7 +373,7 @@
<string name="delete_file_title">Datei löschen</string> <string name="delete_file_title">Datei löschen</string>
<string name="degrees">Grad</string> <string name="degrees">Grad</string>
<string name="start_time">Startzeit</string> <string name="start_time">Startzeit</string>
<string name="start_time_value">Um #TIME# in #COUNTDOWN#</string> <string name="start_time_value">Um %1$s in %2$s</string>
<!--Extracted locales --> <!--Extracted locales -->
<string name="selected_course_area_lost">Die ausgewählte Kursumgebung ist nicht mehr verfügbar.</string> <string name="selected_course_area_lost">Die ausgewählte Kursumgebung ist nicht mehr verfügbar.</string>
@@ -419,13 +420,27 @@
<string name="change_cancel">Abbrechen</string> <string name="change_cancel">Abbrechen</string>
<string name="change_message">Nach den Wettfahrtregeln sind diese Daten im aktuellen Rennenstatus nicht veränderbar.\nSie könnten jedoch die falschen Eingaben korrigieren.</string> <string name="change_message">Nach den Wettfahrtregeln sind diese Daten im aktuellen Rennenstatus nicht veränderbar.\nSie könnten jedoch die falschen Eingaben korrigieren.</string>
<string name="change_title">Warnung</string> <string name="change_title">Warnung</string>
<string name="send_mail">Sende Email...</string> <string name="send_mail">Sende Email…</string>
<string name="data_reload_title">Daten wurden extern verändert</string> <string name="data_reload_title">Daten wurden extern verändert</string>
<string name="data_reload_message">Daten müssen neu geladen werden. Eventueller Datenverlust ist möglich.</string> <string name="data_reload_message">Daten müssen neu geladen werden. Eventueller Datenverlust ist möglich.</string>
<string name="preference_allow_dependent_races_header">Relative Startzeit</string>
<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="error_finished_time">Die ausgewählte Zielzeit liegt vor der Zeit, der ersten Schiffeinfahrt. Bitte überprüfe die Uhrzeit.</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> <string name="error_finishing_time">Die ausgewählte Zeit is vor dem Rennstart. Bitte überprüfe die Uhrzeit.</string>
<string name="error_time_in_future">Die ausgewählte Zeit liegt in der Zukunft. Bitte überprüfe die Uhrzeit.</string> <string name="error_time_in_future">Die ausgewählte Zeit liegt in der Zukunft. Bitte überprüfe die Uhrzeit.</string>
<string name="error_wrong_race_state">Der RaceState hat nicht den korrekten Status (benötigt: %1$s - aktuell: %2$s)</string> <string name="error_wrong_race_state">Der RaceState hat nicht den korrekten Status (benötigt: %1$s - aktuell: %2$s)</string>
<string name="wind_map_button_show">Windkarte</string>
<string name="wind_map_button_hide">Schließen</string>
<string name="wind_latitude">Breite</string>
<string name="wind_longitude">Länge</string>
<string name="wind_accuracy">Genauigkeit</string>
<string name="dependent_races_absolute">Absolute Startzeit</string>
<string name="dependent_races_relative">Relative Startzeit</string>
<string name="dependent_races_prompt">Bitte Rennen auswählen</string>
<string name="minutes_after">Minuten nach</string>
<string name="minutes_after_long">%1$.0f Minuten nach %2$s</string>
<string name="wind_accuracy_ago">alt</string>
</resources> </resources>
@@ -19,6 +19,7 @@
<attr name="buttonSolidXSmall" format="reference"/> <attr name="buttonSolidXSmall" format="reference"/>
<attr name="buttonSolidSmall" format="reference"/> <attr name="buttonSolidSmall" format="reference"/>
<attr name="buttonSolidNormal" format="reference"/> <attr name="buttonSolidNormal" format="reference"/>
<attr name="text" format="reference"/>
<attr name="textXXSmall" format="reference"/> <attr name="textXXSmall" format="reference"/>
<attr name="textXSmall" format="reference"/> <attr name="textXSmall" format="reference"/>
<attr name="textSmall" format="reference"/> <attr name="textSmall" format="reference"/>
@@ -53,6 +54,7 @@
<attr name="course_updown_64dp" format="reference"/> <attr name="course_updown_64dp" format="reference"/>
<attr name="dns_48dp" format="reference"/> <attr name="dns_48dp" format="reference"/>
<attr name="hearing_48dp" format="reference"/> <attr name="hearing_48dp" format="reference"/>
<attr name="link_24dp" format="reference"/>
<attr name="lock_outline" format="reference"/> <attr name="lock_outline" format="reference"/>
<attr name="marker" format="reference"/> <attr name="marker" format="reference"/>
<attr name="marker_race" format="reference"/> <attr name="marker_race" format="reference"/>
@@ -63,6 +65,7 @@
<attr name="swipe_idle" format="reference"/> <attr name="swipe_idle" format="reference"/>
<attr name="swipe_left" format="reference"/> <attr name="swipe_left" format="reference"/>
<attr name="swipe_right" format="reference"/> <attr name="swipe_right" format="reference"/>
<attr name="tab_widget" format="reference"/>
<attr name="value_next" format="reference"/> <attr name="value_next" format="reference"/>
<attr name="value_prev" format="reference"/> <attr name="value_prev" format="reference"/>
<attr name="wind_on" format="reference"/> <attr name="wind_on" format="reference"/>
@@ -48,5 +48,10 @@
<dimen name="bigger_over_flow_width">64dp</dimen> <dimen name="bigger_over_flow_width">64dp</dimen>
<dimen name="bigger_over_flow_height">32dp</dimen> <dimen name="bigger_over_flow_height">32dp</dimen>
<dimen name="wind_hide_button_right_margin">76dp</dimen>
<dimen name="wind_hide_button_top_margin">20dp</dimen>
<item name="picker_scale" format="float" type="integer">1.55</item>
</resources> </resources>
@@ -81,6 +81,11 @@
<string name="app_folder" translatable="false">racecommittee</string> <string name="app_folder" translatable="false">racecommittee</string>
<bool name="preference_isSendingActive_default">false</bool> <bool name="preference_isSendingActive_default">false</bool>
<string name="preference_allow_dependent_races_key" translatable="false">dependentRaces</string>
<bool name="preference_allow_dependent_races_default">true</bool>
<string name="preference_dependent_races_offset_key" translatable="false">dependentRacesOffset</string>
<integer name="preference_dependent_races_offset_default">5</integer>
<string name="preference_allow_demo_key" translatable="false">allow_demo</string> <string name="preference_allow_demo_key" translatable="false">allow_demo</string>
<bool name="preference_allow_demo_default">false</bool> <bool name="preference_allow_demo_default">false</bool>
@@ -51,6 +51,7 @@
<string name="login_type_shore_control">Login as shore control.</string> <string name="login_type_shore_control">Login as shore control.</string>
<string name="login_type_viewer">Login as view-only (demo mode) user.</string> <string name="login_type_viewer">Login as view-only (demo mode) user.</string>
<string name="racelist_unscheduled">Not yet scheduled</string> <string name="racelist_unscheduled">Not yet scheduled</string>
<string name="racelist_prescheduled">Pre-scheduled for %s</string>
<string name="racelist_scheduled">Scheduled for %s</string> <string name="racelist_scheduled">Scheduled for %s</string>
<string name="racelist_startphase">Start at %s in progress</string> <string name="racelist_startphase">Start at %s in progress</string>
<string name="racelist_running">Running since %s</string> <string name="racelist_running">Running since %s</string>
@@ -246,8 +247,8 @@
<string name="race_start_in_4_minutes">4 Minutes</string> <string name="race_start_in_4_minutes">4 Minutes</string>
<string name="race_start_in_2_minutes">2 Minutes</string> <string name="race_start_in_2_minutes">2 Minutes</string>
<string name="race_start_in_1_minute">1 Minute</string> <string name="race_start_in_1_minute">1 Minute</string>
<string name="race_start_time_in">-#TIME#</string> <string name="race_start_time_in">-%s</string>
<string name="race_start_time_ago">#TIME#</string> <string name="race_start_time_ago">%s</string>
<string name="race_set_time">Set Time</string> <string name="race_set_time">Set Time</string>
<string name="race_reset_course">Reset course</string> <string name="race_reset_course">Reset course</string>
<string name="no_course_active">No course active</string> <string name="no_course_active">No course active</string>
@@ -322,13 +323,13 @@
<string name="wind_enter_position">Set Your Position</string> <string name="wind_enter_position">Set Your Position</string>
<string name="wind_kn">kn</string> <string name="wind_kn">kn</string>
<string name="wind_address_hint">Enter Address</string> <string name="wind_address_hint">Enter Address</string>
<string name="wind_sensor"><![CDATA[at #AT# / from #FROM#° / #SPEED# kn]]></string> <string name="wind_sensor"><![CDATA[at %1$s / from %2$.0f° / %3$.1f kn]]></string>
<string name="wind_panel"><![CDATA[from %1$.0f°\n%2$.1f kn]]></string> <string name="wind_panel"><![CDATA[from %1$.0f°\n%2$.1f kn]]></string>
<string name="wind_no_data">No Data</string> <string name="wind_no_data">No Data</string>
<string name="time_up">Up in #TIME#</string> <string name="time_up">Up in #TIME#</string>
<string name="time_down">Down in #TIME#</string> <string name="time_down">Down in #TIME#</string>
<string name="time_start">Start #TIME#</string> <string name="time_start">Start %s</string>
<string name="time_finish">Finish N/A</string> <string name="time_finish">Finish N/A</string>
<string name="time">#TIME#</string> <string name="time">#TIME#</string>
<string name="set_signal">Set Signal</string> <string name="set_signal">Set Signal</string>
@@ -352,7 +353,7 @@
<string name="race_reset_cancel">No Thanks</string> <string name="race_reset_cancel">No Thanks</string>
<string name="race_reset_message">Do you really want to reset this race including all settings and actions that have be made? This can not be undone.</string> <string name="race_reset_message">Do you really want to reset this race including all settings and actions that have be made? This can not be undone.</string>
<string name="race_begin_finish_header">Begin Finish</string> <string name="race_begin_finish_header">Begin Finish</string>
<string name="race_end_finish_header">End Finish</string> <string name="race_end_finish_header">End Finish (Begin Finish: %s)</string>
<string name="race_begin_finish_current">Use Current Time</string> <string name="race_begin_finish_current">Use Current Time</string>
<string name="race_begin_finish_custom">Use Custom Time</string> <string name="race_begin_finish_custom">Use Custom Time</string>
<string name="race_setup_confirm">Confirm Setup</string> <string name="race_setup_confirm">Confirm Setup</string>
@@ -393,7 +394,7 @@
<string name="delete_file_title">Delete file</string> <string name="delete_file_title">Delete file</string>
<string name="delete_file">This will delete the picture</string> <string name="delete_file">This will delete the picture</string>
<string name="start_time">Start Time</string> <string name="start_time">Start Time</string>
<string name="start_time_value">At #TIME# in #COUNTDOWN#</string> <string name="start_time_value">At %1$s in %2$s</string>
<!--Extracted locales --> <!--Extracted locales -->
<string name="selected_course_area_lost">The selected course area was lost.</string> <string name="selected_course_area_lost">The selected course area was lost.</string>
@@ -440,12 +441,26 @@
<string name="change_cancel">Cancel</string> <string name="change_cancel">Cancel</string>
<string name="change_message">According to the racing rules this data is not changeable in the current\nrace state. You may proceed nevertheless to correct wrong inputs.</string> <string name="change_message">According to the racing rules this data is not changeable in the current\nrace state. You may proceed nevertheless to correct wrong inputs.</string>
<string name="change_title">Warning</string> <string name="change_title">Warning</string>
<string name="send_mail">Send mail...</string> <string name="send_mail">Send mail…</string>
<string name="data_reload_title">Data has changed externally</string> <string name="data_reload_title">Data has changed externally</string>
<string name="data_reload_message">Data have to be reloaded. Possible data loss is possible.</string> <string name="data_reload_message">Data have 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="error_finished_time">The given finish time is earlier than the first finisher time. Please recheck the time.</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> <string name="error_finishing_time">The selected time is before the race start.</string>
<string name="error_time_in_future">The given time is in future. Please recheck the time.</string> <string name="error_time_in_future">The given time is in future. Please recheck the time.</string>
<string name="error_wrong_race_state">The RaceState isn\'t in the correct state (needed: %1$s - current: %2$s)</string> <string name="error_wrong_race_state">The RaceState isn\'t in the correct state (needed: %1$s - current: %2$s)</string>
<string name="wind_map_button_show">Wind Map</string>
<string name="wind_map_button_hide">Hide</string>
<string name="wind_latitude">Latitude</string>
<string name="wind_longitude">Longitude</string>
<string name="wind_accuracy">Accuracy</string>
<string name="dependent_races_absolute">Absolute Start Time</string>
<string name="dependent_races_relative">Relative Start Time</string>
<string name="dependent_races_prompt">Please select the race</string>
<string name="minutes_after">Minutes after</string>
<string name="minutes_after_long">%1$.0f Minutes after %2$s</string>
<string name="wind_accuracy_ago">ago</string>
</resources> </resources>
@@ -7,6 +7,7 @@
<style name="AppTheme.Dark.Base" parent="Theme.AppCompat.NoActionBar"> <style name="AppTheme.Dark.Base" parent="Theme.AppCompat.NoActionBar">
<item name="windowActionModeOverlay">true</item> <item name="windowActionModeOverlay">true</item>
<item name="android:actionOverflowButtonStyle">@style/OverFlow</item> <item name="android:actionOverflowButtonStyle">@style/OverFlow</item>
<item name="android:tabWidgetStyle">@style/AppTheme.Dark.TabWidget</item>
<item name="colorPrimary">@color/dark_colorPrimary</item> <item name="colorPrimary">@color/dark_colorPrimary</item>
<item name="colorPrimaryDark">@color/dark_colorPrimaryDark</item> <item name="colorPrimaryDark">@color/dark_colorPrimaryDark</item>
@@ -34,6 +35,7 @@
<item name="buttonSolidXSmall">@style/AppTheme.Dark.Button.XSmall</item> <item name="buttonSolidXSmall">@style/AppTheme.Dark.Button.XSmall</item>
<item name="buttonSolidSmall">@style/AppTheme.Dark.Button.Small</item> <item name="buttonSolidSmall">@style/AppTheme.Dark.Button.Small</item>
<item name="buttonSolidNormal">@style/AppTheme.Dark.Button.Normal</item> <item name="buttonSolidNormal">@style/AppTheme.Dark.Button.Normal</item>
<item name="text">@style/AppTheme.Dark.Text</item>
<item name="textXXSmall">@style/AppTheme.Dark.Text.XXSmall</item> <item name="textXXSmall">@style/AppTheme.Dark.Text.XXSmall</item>
<item name="textXSmall">@style/AppTheme.Dark.Text.XSmall</item> <item name="textXSmall">@style/AppTheme.Dark.Text.XSmall</item>
<item name="textSmall">@style/AppTheme.Dark.Text.Small</item> <item name="textSmall">@style/AppTheme.Dark.Text.Small</item>
@@ -67,6 +69,7 @@
<item name="course_updown_64dp">@drawable/course_updown_64dp_dark</item> <item name="course_updown_64dp">@drawable/course_updown_64dp_dark</item>
<item name="dns_48dp">@drawable/ic_dns_white_48dp</item> <item name="dns_48dp">@drawable/ic_dns_white_48dp</item>
<item name="hearing_48dp">@drawable/ic_hearing_white_48dp</item> <item name="hearing_48dp">@drawable/ic_hearing_white_48dp</item>
<item name="link_24dp">@drawable/ic_link_white_24dp</item>
<item name="lock_outline">@drawable/lock_outline_dark</item> <item name="lock_outline">@drawable/lock_outline_dark</item>
<item name="marker">@drawable/marker_dark</item> <item name="marker">@drawable/marker_dark</item>
<item name="marker_race">@drawable/marker_race_dark</item> <item name="marker_race">@drawable/marker_race_dark</item>
@@ -77,6 +80,7 @@
<item name="swipe_idle">@drawable/swipe_idle_dark</item> <item name="swipe_idle">@drawable/swipe_idle_dark</item>
<item name="swipe_left">@drawable/swipe_left_dark</item> <item name="swipe_left">@drawable/swipe_left_dark</item>
<item name="swipe_right">@drawable/swipe_right_dark</item> <item name="swipe_right">@drawable/swipe_right_dark</item>
<item name="tab_widget">@drawable/tabwidget_dark</item>
<item name="value_next">@drawable/value_next_dark</item> <item name="value_next">@drawable/value_next_dark</item>
<item name="value_prev">@drawable/value_prev_dark</item> <item name="value_prev">@drawable/value_prev_dark</item>
<item name="wind_off">@drawable/wind_off_dark</item> <item name="wind_off">@drawable/wind_off_dark</item>
@@ -171,4 +175,13 @@
<item name="android:gravity">center_horizontal</item> <item name="android:gravity">center_horizontal</item>
</style> </style>
<style name="AppTheme.Dark.TabWidget" parent="@android:style/Widget.TabWidget">
<item name="android:textAppearance">@style/AppTheme.Light.TabWidgetText</item>
</style>
<style name="AppTheme.Dark.TabWidgetText" parent="@android:style/TextAppearance.Widget.TabWidget">
<item name="android:textSize">@dimen/textSize_32</item>
<item name="android:textColor">?white</item>
</style>
</resources> </resources>
@@ -7,6 +7,7 @@
<style name="AppTheme.Light.Base" parent="Theme.AppCompat.NoActionBar"> <style name="AppTheme.Light.Base" parent="Theme.AppCompat.NoActionBar">
<item name="windowActionModeOverlay">true</item> <item name="windowActionModeOverlay">true</item>
<item name="android:actionOverflowButtonStyle">@style/OverFlow</item> <item name="android:actionOverflowButtonStyle">@style/OverFlow</item>
<item name="android:tabWidgetStyle">@style/AppTheme.Light.TabWidget</item>
<item name="colorPrimary">@color/light_colorPrimary</item> <item name="colorPrimary">@color/light_colorPrimary</item>
<item name="colorPrimaryDark">@color/light_colorPrimaryDark</item> <item name="colorPrimaryDark">@color/light_colorPrimaryDark</item>
@@ -37,6 +38,7 @@
<item name="buttonSolidXSmall">@style/AppTheme.Light.Button.XSmall</item> <item name="buttonSolidXSmall">@style/AppTheme.Light.Button.XSmall</item>
<item name="buttonSolidSmall">@style/AppTheme.Light.Button.Small</item> <item name="buttonSolidSmall">@style/AppTheme.Light.Button.Small</item>
<item name="buttonSolidNormal">@style/AppTheme.Light.Button.Normal</item> <item name="buttonSolidNormal">@style/AppTheme.Light.Button.Normal</item>
<item name="text">@style/AppTheme.Light.Text</item>
<item name="textXXSmall">@style/AppTheme.Light.Text.XXSmall</item> <item name="textXXSmall">@style/AppTheme.Light.Text.XXSmall</item>
<item name="textXSmall">@style/AppTheme.Light.Text.XSmall</item> <item name="textXSmall">@style/AppTheme.Light.Text.XSmall</item>
<item name="textSmall">@style/AppTheme.Light.Text.Small</item> <item name="textSmall">@style/AppTheme.Light.Text.Small</item>
@@ -70,6 +72,7 @@
<item name="course_updown_64dp">@drawable/course_updown_64dp_light</item> <item name="course_updown_64dp">@drawable/course_updown_64dp_light</item>
<item name="dns_48dp">@drawable/ic_dns_black_48dp</item> <item name="dns_48dp">@drawable/ic_dns_black_48dp</item>
<item name="hearing_48dp">@drawable/ic_hearing_black_48dp</item> <item name="hearing_48dp">@drawable/ic_hearing_black_48dp</item>
<item name="link_24dp">@drawable/ic_link_black_24dp</item>
<item name="lock_outline">@drawable/lock_outline_light</item> <item name="lock_outline">@drawable/lock_outline_light</item>
<item name="marker">@drawable/marker_light</item> <item name="marker">@drawable/marker_light</item>
<item name="marker_race">@drawable/marker_race_light</item> <item name="marker_race">@drawable/marker_race_light</item>
@@ -80,6 +83,7 @@
<item name="swipe_idle">@drawable/swipe_idle_light</item> <item name="swipe_idle">@drawable/swipe_idle_light</item>
<item name="swipe_left">@drawable/swipe_left_light</item> <item name="swipe_left">@drawable/swipe_left_light</item>
<item name="swipe_right">@drawable/swipe_right_light</item> <item name="swipe_right">@drawable/swipe_right_light</item>
<item name="tab_widget">@drawable/tabwidget_light</item>
<item name="value_next">@drawable/value_next_light</item> <item name="value_next">@drawable/value_next_light</item>
<item name="value_prev">@drawable/value_prev_light</item> <item name="value_prev">@drawable/value_prev_light</item>
<item name="wind_off">@drawable/wind_off_light</item> <item name="wind_off">@drawable/wind_off_light</item>
@@ -181,4 +185,13 @@
<item name="android:windowBackground">@null</item> <item name="android:windowBackground">@null</item>
</style> </style>
<style name="AppTheme.Light.TabWidget" parent="@android:style/Widget.TabWidget">
<item name="android:textAppearance">@style/AppTheme.Light.TabWidgetText</item>
</style>
<style name="AppTheme.Light.TabWidgetText" parent="@android:style/TextAppearance.Widget.TabWidget">
<item name="android:textSize">@dimen/textSize_32</item>
<item name="android:textColor">?white</item>
</style>
</resources> </resources>
@@ -10,7 +10,7 @@
android:defaultValue="@string/empty" android:defaultValue="@string/empty"
android:key="@string/preference_identifier_key" android:key="@string/preference_identifier_key"
android:title="@string/device_identifier"/> android:title="@string/device_identifier"/>
<EditTextPreference <com.sap.sailing.racecommittee.app.ui.views.UrlEditTextPreference
android:defaultValue="@string/preference_server_url_default" android:defaultValue="@string/preference_server_url_default"
android:key="@string/preference_server_url_key" android:key="@string/preference_server_url_key"
android:title="@string/settings_advanced_service_header"/> android:title="@string/settings_advanced_service_header"/>
@@ -1,118 +1,128 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/settings_category_general" > <PreferenceCategory android:title="@string/settings_category_general">
<ListPreference <ListPreference
android:key="@string/preference_racing_procedure_override_key"
android:defaultValue="@string/preference_racing_procedure_override_default" android:defaultValue="@string/preference_racing_procedure_override_default"
android:key="@string/preference_racing_procedure_override_key"
android:summary="@string/override_default_start_procedure_type_select_description" android:summary="@string/override_default_start_procedure_type_select_description"
android:title="@string/override_default_start_procedure_type_select_header" /> android:title="@string/override_default_start_procedure_type_select_header"/>
<ListPreference
android:key="@string/preference_course_designer_override_key"
android:defaultValue="@string/preference_course_designer_override_default"
android:summary="@string/empty"
android:title="@string/override_default_course_designer_type_select_header" />
</PreferenceCategory>
<PreferenceCategory android:title="RRS26" >
<ListPreference <ListPreference
android:defaultValue="@string/preference_course_designer_override_default"
android:key="@string/preference_course_designer_override_key"
android:title="@string/override_default_course_designer_type_select_header"/>
<CheckBoxPreference
android:defaultValue="@bool/preference_allow_dependent_races_default"
android:key="@string/preference_allow_dependent_races_key"
android:summary="@string/preference_allow_dependent_races_description"
android:title="@string/preference_allow_dependent_races_header"/>
<com.sap.sailing.racecommittee.app.ui.views.IntegerEditTextPreference
android:defaultValue="@integer/preference_dependent_races_offset_default"
android:key="@string/preference_dependent_races_offset_key"
android:numeric="integer"
android:title="@string/preference_dependent_races_offset_header"/>
</PreferenceCategory>
<PreferenceCategory android:title="RRS26">
<ListPreference
android:defaultValue="@string/preference_racing_procedure_classflag_default"
android:key="@string/preference_racing_procedure_rrs26_classflag_key" android:key="@string/preference_racing_procedure_rrs26_classflag_key"
android:defaultValue="@string/preference_racing_procedure_classflag_default" android:summary="@string/empty"
android:title="@string/preference_racing_procedure_classflag_header" android:title="@string/preference_racing_procedure_classflag_header"/>
android:summary="@string/empty" />
<CheckBoxPreference <CheckBoxPreference
android:key="@string/preference_racing_procedure_rrs26_hasxray_key"
android:defaultValue="@bool/preference_racing_procedure_rrs26_hasxray_default" android:defaultValue="@bool/preference_racing_procedure_rrs26_hasxray_default"
android:title="@string/preference_racing_procedure_hasxray_header" android:key="@string/preference_racing_procedure_rrs26_hasxray_key"
android:summary="@string/preference_racing_procedure_hasxray_description" /> android:summary="@string/preference_racing_procedure_hasxray_description"
android:title="@string/preference_racing_procedure_hasxray_header"/>
<com.sap.sailing.racecommittee.app.ui.views.FixedMultiSelectListPreference
android:key="@string/preference_racing_procedure_rrs26_startmode_flags_key" <com.sap.sailing.racecommittee.app.ui.views.FixedMultiSelectListPreference
android:defaultValue="@array/preference_racing_procedure_rrs26_startmode_flags_default" android:defaultValue="@array/preference_racing_procedure_rrs26_startmode_flags_default"
android:title="@string/preference_racing_procedure_rrs26_startmode_flags_header" android:key="@string/preference_racing_procedure_rrs26_startmode_flags_key"
android:summary="@string/empty" /> android:summary="@string/empty"
android:title="@string/preference_racing_procedure_rrs26_startmode_flags_header"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="Gate Start" > <PreferenceCategory android:title="Gate Start">
<ListPreference <ListPreference
android:defaultValue="@string/preference_racing_procedure_classflag_default"
android:key="@string/preference_racing_procedure_gatestart_classflag_key" android:key="@string/preference_racing_procedure_gatestart_classflag_key"
android:defaultValue="@string/preference_racing_procedure_classflag_default" android:summary="@string/empty"
android:title="@string/preference_racing_procedure_classflag_header" android:title="@string/preference_racing_procedure_classflag_header"/>
android:summary="@string/empty" />
<CheckBoxPreference <CheckBoxPreference
android:key="@string/preference_racing_procedure_gatestart_hasxray_key"
android:defaultValue="@bool/preference_racing_procedure_gatestart_hasxray_default" android:defaultValue="@bool/preference_racing_procedure_gatestart_hasxray_default"
android:title="@string/preference_racing_procedure_hasxray_header" android:key="@string/preference_racing_procedure_gatestart_hasxray_key"
android:summary="@string/preference_racing_procedure_hasxray_description" /> android:summary="@string/preference_racing_procedure_hasxray_description"
android:title="@string/preference_racing_procedure_hasxray_header"/>
<CheckBoxPreference <CheckBoxPreference
android:key="@string/preference_racing_procedure_gatestart_haspathfinder_key"
android:defaultValue="@bool/preference_racing_procedure_gatestart_haspathfinder_default" android:defaultValue="@bool/preference_racing_procedure_gatestart_haspathfinder_default"
android:title="@string/preference_racing_procedure_gatestart_haspathfinder_header" android:key="@string/preference_racing_procedure_gatestart_haspathfinder_key"
android:summary="@string/preference_racing_procedure_gatestart_haspathfinder_description" /> android:summary="@string/preference_racing_procedure_gatestart_haspathfinder_description"
android:title="@string/preference_racing_procedure_gatestart_haspathfinder_header"/>
<CheckBoxPreference <CheckBoxPreference
android:key="@string/preference_racing_procedure_gatestart_hasadditionalgolfdowntime_key"
android:defaultValue="@bool/preference_racing_procedure_gatestart_hasadditionalgolfdowntime_default" android:defaultValue="@bool/preference_racing_procedure_gatestart_hasadditionalgolfdowntime_default"
android:title="@string/preference_racing_procedure_gatestart_hasadditionalgolfdowntime_header" android:key="@string/preference_racing_procedure_gatestart_hasadditionalgolfdowntime_key"
android:summary="@string/preference_racing_procedure_gatestart_hasadditionalgolfdowntime_description" /> android:summary="@string/preference_racing_procedure_gatestart_hasadditionalgolfdowntime_description"
android:title="@string/preference_racing_procedure_gatestart_hasadditionalgolfdowntime_header"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="ESS Start" > <PreferenceCategory android:title="ESS Start">
<ListPreference <ListPreference
android:defaultValue="@string/preference_racing_procedure_classflag_default"
android:key="@string/preference_racing_procedure_ess_classflag_key" android:key="@string/preference_racing_procedure_ess_classflag_key"
android:defaultValue="@string/preference_racing_procedure_classflag_default" android:summary="@string/empty"
android:title="@string/preference_racing_procedure_classflag_header" android:title="@string/preference_racing_procedure_classflag_header"/>
android:summary="@string/empty" />
<CheckBoxPreference <CheckBoxPreference
android:key="@string/preference_racing_procedure_ess_hasxray_key"
android:defaultValue="@bool/preference_racing_procedure_ess_hasxray_default" android:defaultValue="@bool/preference_racing_procedure_ess_hasxray_default"
android:title="@string/preference_racing_procedure_hasxray_header" android:key="@string/preference_racing_procedure_ess_hasxray_key"
android:summary="@string/preference_racing_procedure_hasxray_description" /> android:summary="@string/preference_racing_procedure_hasxray_description"
android:title="@string/preference_racing_procedure_hasxray_header"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="Basic Start" > <PreferenceCategory android:title="Basic Start">
<ListPreference <ListPreference
android:defaultValue="@string/preference_racing_procedure_classflag_default"
android:key="@string/preference_racing_procedure_basic_classflag_key" android:key="@string/preference_racing_procedure_basic_classflag_key"
android:defaultValue="@string/preference_racing_procedure_classflag_default" android:summary="@string/empty"
android:title="@string/preference_racing_procedure_classflag_header" android:title="@string/preference_racing_procedure_classflag_header"/>
android:summary="@string/empty" />
<CheckBoxPreference <CheckBoxPreference
android:key="@string/preference_racing_procedure_basic_hasxray_key"
android:defaultValue="@bool/preference_racing_procedure_basic_hasxray_default" android:defaultValue="@bool/preference_racing_procedure_basic_hasxray_default"
android:title="@string/preference_racing_procedure_hasxray_header" android:key="@string/preference_racing_procedure_basic_hasxray_key"
android:summary="@string/preference_racing_procedure_hasxray_description" /> android:summary="@string/preference_racing_procedure_hasxray_description"
android:title="@string/preference_racing_procedure_hasxray_header"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="League Start" > <PreferenceCategory android:title="League Start">
<ListPreference <ListPreference
android:key="@string/preference_racing_procedure_league_classflag_key"
android:defaultValue="@string/preference_racing_procedure_classflag_default" android:defaultValue="@string/preference_racing_procedure_classflag_default"
android:title="@string/preference_racing_procedure_classflag_header" android:key="@string/preference_racing_procedure_league_classflag_key"
android:summary="@string/empty" /> android:summary="@string/empty"
android:title="@string/preference_racing_procedure_classflag_header"/>
<CheckBoxPreference <CheckBoxPreference
android:key="@string/preference_racing_procedure_league_hasxray_key"
android:defaultValue="@bool/preference_racing_procedure_league_hasxray_default" android:defaultValue="@bool/preference_racing_procedure_league_hasxray_default"
android:title="@string/preference_racing_procedure_hasxray_header" android:key="@string/preference_racing_procedure_league_hasxray_key"
android:summary="@string/preference_racing_procedure_hasxray_description" /> android:summary="@string/preference_racing_procedure_hasxray_description"
android:title="@string/preference_racing_procedure_hasxray_header"/>
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>
@@ -7,8 +7,6 @@ public class AppConstants {
//TODO replace it later with BuildConfig.APPLICATION_ID (Eclipse didn't know it) //TODO replace it later with BuildConfig.APPLICATION_ID (Eclipse didn't know it)
private final static String PACKAGE_NAME = "com.sap.sailing.racecommittee.app"; private final static String PACKAGE_NAME = "com.sap.sailing.racecommittee.app";
public final static String DEFAULT = "Default";
// Intent extra fields // Intent extra fields
public final static String COURSE_AREA_UUID_KEY = "courseUuid"; public final static String COURSE_AREA_UUID_KEY = "courseUuid";
public final static String RACE_ID_KEY = "raceUuid"; public final static String RACE_ID_KEY = "raceUuid";
@@ -72,4 +70,7 @@ public class AppConstants {
public final static String INTENT_ACTION_SHOW_SUMMARY_CONTENT = PACKAGE_NAME + ".action.show.summary"; public final static String INTENT_ACTION_SHOW_SUMMARY_CONTENT = PACKAGE_NAME + ".action.show.summary";
public final static String INTENT_ACTION_SHOW_PROTEST = PACKAGE_NAME + ".action.show.protest"; public final static String INTENT_ACTION_SHOW_PROTEST = PACKAGE_NAME + ".action.show.protest";
public final static String INTENT_ACTION_IS_TRACKING = PACKAGE_NAME + "action.is.tracking";
public final static String INTENT_ACTION_IS_TRACKING_EXTRA = PACKAGE_NAME + "action.is.tracking.extra";
} }
@@ -99,8 +99,7 @@ public class AppPreferences {
} }
public List<String> getByNameCourseDesignerCourseNames() { public List<String> getByNameCourseDesignerCourseNames() {
Set<String> values = preferences.getStringSet( Set<String> values = preferences.getStringSet(key(R.string.preference_course_designer_by_name_course_names_key), new HashSet<String>());
key(R.string.preference_course_designer_by_name_course_names_key), new HashSet<String>());
return new ArrayList<String>(values); return new ArrayList<String>(values);
} }
@@ -251,6 +250,7 @@ public class AppPreferences {
if (value.equals("")) { if (value.equals("")) {
return "http://localhost:8889"; return "http://localhost:8889";
} }
return value; return value;
} }
@@ -317,8 +317,7 @@ public class AppPreferences {
public void setGateStartHasAdditionalGolfDownTime(boolean hasAdditionalGolfDownTime) { public void setGateStartHasAdditionalGolfDownTime(boolean hasAdditionalGolfDownTime) {
preferences preferences
.edit() .edit()
.putBoolean(key(R.string.preference_racing_procedure_gatestart_hasadditionalgolfdowntime_key), .putBoolean(key(R.string.preference_racing_procedure_gatestart_hasadditionalgolfdowntime_key), hasAdditionalGolfDownTime).commit();
hasAdditionalGolfDownTime).commit();
} }
public void setGateStartHasPathfinder(boolean hasPathfinder) { public void setGateStartHasPathfinder(boolean hasPathfinder) {
@@ -435,6 +434,16 @@ public class AppPreferences {
context.getResources().getBoolean(R.bool.preference_offline_default)); context.getResources().getBoolean(R.bool.preference_offline_default));
} }
public boolean isDependentRacesAllowed() {
return preferences.getBoolean(context.getString(R.string.preference_allow_dependent_races_key),
context.getResources().getBoolean(R.bool.preference_allow_dependent_races_default));
}
public int getDependentRacesOffset() {
return preferences.getInt(context.getString(R.string.preference_dependent_races_offset_key),
context.getResources().getInteger(R.integer.preference_dependent_races_offset_default));
}
public String getTheme() { public String getTheme() {
return preferences.getString(context.getString(R.string.preference_theme_key), return preferences.getString(context.getString(R.string.preference_theme_key),
context.getResources().getString(R.string.preference_theme_default)); context.getResources().getString(R.string.preference_theme_default));
@@ -24,6 +24,15 @@ public class ManagedRacesDataHandler extends DataHandler<Collection<ManagedRace>
@Override @Override
public void onResult(Collection<ManagedRace> data) { public void onResult(Collection<ManagedRace> data) {
manager.addRaces(data); manager.addRaces(data);
calcRaceState(data);
} }
private void calcRaceState(Collection<ManagedRace> data) {
for (ManagedRace race : data) {
race.calculateRaceState();
}
for (ManagedRace race : data) {
race.getState().forceUpdate();
}
}
} }
@@ -10,8 +10,6 @@ import org.json.simple.JSONValue;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor; import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.state.RaceState;
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl;
import com.sap.sailing.domain.base.Fleet; import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.SeriesBase; import com.sap.sailing.domain.base.SeriesBase;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader; import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
@@ -20,7 +18,6 @@ import com.sap.sailing.domain.base.racegroup.RaceCell;
import com.sap.sailing.domain.base.racegroup.RaceGroup; import com.sap.sailing.domain.base.racegroup.RaceGroup;
import com.sap.sailing.domain.base.racegroup.RaceRow; import com.sap.sailing.domain.base.racegroup.RaceRow;
import com.sap.sailing.domain.base.racegroup.SeriesWithRows; import com.sap.sailing.domain.base.racegroup.SeriesWithRows;
import com.sap.sailing.racecommittee.app.data.AndroidRaceLogResolver;
import com.sap.sailing.racecommittee.app.domain.FleetIdentifier; import com.sap.sailing.racecommittee.app.domain.FleetIdentifier;
import com.sap.sailing.racecommittee.app.domain.ManagedRace; import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier; import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier;
@@ -28,6 +25,7 @@ import com.sap.sailing.racecommittee.app.domain.configuration.impl.MergingRegatt
import com.sap.sailing.racecommittee.app.domain.impl.FleetIdentifierImpl; import com.sap.sailing.racecommittee.app.domain.impl.FleetIdentifierImpl;
import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceIdentifierImpl; import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceIdentifierImpl;
import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceImpl; import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceImpl;
import com.sap.sailing.racecommittee.app.utils.ManagedRaceCalculator;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer; import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.Helpers; import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
@@ -55,7 +53,6 @@ public class ManagedRacesDataParser implements DataParser<Collection<ManagedRace
RaceGroup group = deserializer.deserialize(json); RaceGroup group = deserializer.deserialize(json);
addManagedRaces(managedRaces, group); addManagedRaces(managedRaces, group);
} }
return managedRaces; return managedRaces;
} }
@@ -80,8 +77,7 @@ public class ManagedRacesDataParser implements DataParser<Collection<ManagedRace
} }
FleetIdentifier fleetIdentifier = new FleetIdentifierImpl(fleet, series, raceGroup); FleetIdentifier fleetIdentifier = new FleetIdentifierImpl(fleet, series, raceGroup);
ManagedRaceIdentifier identifier = new ManagedRaceIdentifierImpl(name, fleetIdentifier); ManagedRaceIdentifier identifier = new ManagedRaceIdentifierImpl(name, fleetIdentifier);
RaceState state = RaceStateImpl.create(new AndroidRaceLogResolver(), raceLog, author, configurationLoader); return new ManagedRaceImpl(identifier, new ManagedRaceCalculator(raceLog, author, configurationLoader));
return new ManagedRaceImpl(identifier, state);
} }
} }
@@ -1,5 +1,8 @@
package com.sap.sailing.racecommittee.app.domain; package com.sap.sailing.racecommittee.app.domain;
import java.util.Collection;
import java.util.List;
import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.state.RaceState; import com.sap.sailing.domain.abstractlog.race.state.RaceState;
import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Competitor;
@@ -10,11 +13,8 @@ import com.sap.sse.common.Named;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.WithID; import com.sap.sse.common.WithID;
import java.util.Collection;
import java.util.List;
public interface ManagedRace extends ManagedRaceIdentifier, Named, WithID { public interface ManagedRace extends ManagedRaceIdentifier, Named, WithID {
/** /**
* @return the identifier of the race. * @return the identifier of the race.
*/ */
@@ -27,28 +27,28 @@ public interface ManagedRace extends ManagedRaceIdentifier, Named, WithID {
/** /**
* Shortcut to {@link RaceState#getRaceLog()} of {@link ManagedRace#getState()}. * Shortcut to {@link RaceState#getRaceLog()} of {@link ManagedRace#getState()}.
* *
* @return the log of the race. * @return the log of the race.
*/ */
RaceLog getRaceLog(); RaceLog getRaceLog();
/** /**
* Shortcut to {@link RaceState#getStatus()} of {@link ManagedRace#getState()}. * Shortcut to {@link RaceState#getStatus()} of {@link ManagedRace#getState()}.
* *
* @return the status of the race's state. * @return the status of the race's state.
*/ */
RaceLogRaceStatus getStatus(); RaceLogRaceStatus getStatus();
/** /**
* the current course of the race * the current course of the race
* *
* @return the course of the race * @return the course of the race
*/ */
CourseBase getCourseDesign(); CourseBase getCourseDesign();
/** /**
* returns the list of competitors for this race * returns the list of competitors for this race
* *
* @return list of competitors * @return list of competitors
*/ */
Collection<Competitor> getCompetitors(); Collection<Competitor> getCompetitors();
@@ -67,13 +67,12 @@ public interface ManagedRace extends ManagedRaceIdentifier, Named, WithID {
/** /**
* sets the list of competitors for a race. As the competitors are retrieved later from the backend, the list of * sets the list of competitors for a race. As the competitors are retrieved later from the backend, the list of
* competitors has to be settable. * competitors has to be settable.
* *
* @param competitors * @param competitors
* the retrieved list of competitors for this race * the retrieved list of competitors for this race
*/ */
void setCompetitors(Collection<Competitor> competitors); void setCompetitors(Collection<Competitor> competitors);
/** /**
* sets the list of mapItems ( buoys, other boats ) for a race. As the mapItems are retrieved later from the backend, the list of * sets the list of mapItems ( buoys, other boats ) for a race. As the mapItems are retrieved later from the backend, the list of
* mapItems has to be settable. * mapItems has to be settable.
@@ -83,6 +82,13 @@ public interface ManagedRace extends ManagedRaceIdentifier, Named, WithID {
*/ */
void setMapMarkers(List<MapMarker> markers); void setMapMarkers(List<MapMarker> markers);
/**
* Returns true if {@link RaceState} has been calculated and set
*
* @return true, if {@link RaceState} has been set
*/
boolean calculateRaceState();
/** /**
* sets the finished time, if the finished time is after the finishing time; check the {@link Result} for error message * sets the finished time, if the finished time is after the finishing time; check the {@link Result} for error message
* *
@@ -1,5 +1,9 @@
package com.sap.sailing.racecommittee.app.domain.impl; package com.sap.sailing.racecommittee.app.domain.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishingTimeFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishingTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
@@ -15,31 +19,33 @@ import com.sap.sailing.racecommittee.app.data.AndroidRaceLogResolver;
import com.sap.sailing.racecommittee.app.domain.ManagedRace; import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier; import com.sap.sailing.racecommittee.app.domain.ManagedRaceIdentifier;
import com.sap.sailing.racecommittee.app.domain.MapMarker; import com.sap.sailing.racecommittee.app.domain.MapMarker;
import com.sap.sailing.racecommittee.app.utils.ManagedRaceCalculator;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class ManagedRaceImpl implements ManagedRace { public class ManagedRaceImpl implements ManagedRace {
private static final long serialVersionUID = -4936566684992524001L; private static final long serialVersionUID = -4936566684992524001L;
// private static final String TAG = ManagedRace.class.getName();
private final RaceState state;
private final ManagedRaceIdentifier identifier; private final ManagedRaceIdentifier identifier;
private RaceState state;
private Collection<Competitor> competitors; private Collection<Competitor> competitors;
private List<MapMarker> mapMarkers; private List<MapMarker> mapMarkers;
private CourseBase courseOnServer; private CourseBase courseOnServer;
private ManagedRaceCalculator calculator;
public ManagedRaceImpl(ManagedRaceIdentifier identifier, RaceState state) { public ManagedRaceImpl(ManagedRaceIdentifier identifier, RaceState state) {
this.state = state; this.state = state;
this.identifier = identifier; this.identifier = identifier;
this.competitors = new ArrayList<Competitor>(); this.competitors = new ArrayList<>();
this.courseOnServer = null; this.courseOnServer = null;
} }
public ManagedRaceImpl(ManagedRaceIdentifier identifier, ManagedRaceCalculator calculator) {
this.identifier = identifier;
this.competitors = new ArrayList<>();
this.courseOnServer = null;
this.calculator = calculator;
}
@Override @Override
public RaceState getState() { public RaceState getState() {
return state; return state;
@@ -82,7 +88,7 @@ public class ManagedRaceImpl implements ManagedRace {
@Override @Override
public RaceLog getRaceLog() { public RaceLog getRaceLog() {
return state.getRaceLog(); return state == null ? null : state.getRaceLog();
} }
@Override @Override
@@ -101,10 +107,20 @@ public class ManagedRaceImpl implements ManagedRace {
} }
@Override @Override
public List<MapMarker> getMapMarkers(){ public void setCompetitors(Collection<Competitor> competitors) {
this.competitors = competitors;
}
@Override
public List<MapMarker> getMapMarkers() {
return mapMarkers; return mapMarkers;
} }
@Override
public void setMapMarkers(List<MapMarker> markers) {
this.mapMarkers = markers;
}
@Override @Override
public CourseBase getCourseOnServer() { public CourseBase getCourseOnServer() {
return courseOnServer; return courseOnServer;
@@ -116,13 +132,13 @@ public class ManagedRaceImpl implements ManagedRace {
} }
@Override @Override
public void setCompetitors(Collection<Competitor> competitors) { public boolean calculateRaceState() {
this.competitors = competitors; boolean calculated = false;
} if (state == null && calculator != null) {
state = calculator.calculateRaceState();
@Override calculated = true;
public void setMapMarkers(List<MapMarker> markers) { }
this.mapMarkers = markers; return calculated;
} }
@Override @Override
@@ -1,11 +1,10 @@
package com.sap.sailing.racecommittee.app.domain.impl; package com.sap.sailing.racecommittee.app.domain.impl;
import android.text.TextUtils; import android.text.TextUtils;
import com.sap.sailing.domain.base.Fleet; import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.SeriesBase; import com.sap.sailing.domain.base.SeriesBase;
import com.sap.sailing.domain.base.racegroup.RaceGroup; import com.sap.sailing.domain.base.racegroup.RaceGroup;
import com.sap.sailing.racecommittee.app.AppConstants; import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.racecommittee.app.domain.ManagedRace; import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sse.common.Util; import com.sap.sse.common.Util;
@@ -26,6 +25,10 @@ public class RaceGroupSeriesFleet {
fleetOrder = getFleetIndex(series.getFleets(), race.getFleet()); fleetOrder = getFleetIndex(series.getFleets(), race.getFleet());
} }
private static int getSeriesIndex(ManagedRace race, SeriesBase series) {
return Util.indexOf(race.getRaceGroup().getSeries(), series);
}
public RaceGroup getRaceGroup() { public RaceGroup getRaceGroup() {
return raceGroup; return raceGroup;
} }
@@ -59,10 +62,10 @@ public class RaceGroupSeriesFleet {
if (!useDisplayName || TextUtils.isEmpty(name)) { if (!useDisplayName || TextUtils.isEmpty(name)) {
name = raceGroup.getName(); name = raceGroup.getName();
} }
if (series != null && !series.getName().equals(AppConstants.DEFAULT)) { if (series != null && !series.getName().equals(LeaderboardNameConstants.DEFAULT_SERIES_NAME)) {
name += " - " + series.getName(); name += " - " + series.getName();
} }
if (fleet != null && !fleet.getName().equals(AppConstants.DEFAULT)) { if (fleet != null && !fleet.getName().equals(LeaderboardNameConstants.DEFAULT_FLEET_NAME)) {
name += " - " + fleet.getName(); name += " - " + fleet.getName();
} }
return name; return name;
@@ -130,8 +133,4 @@ public class RaceGroupSeriesFleet {
private int getFleetIndex(Iterable<? extends Fleet> fleets, Fleet fleet) { private int getFleetIndex(Iterable<? extends Fleet> fleets, Fleet fleet) {
return Util.indexOf(fleets, fleet); return Util.indexOf(fleets, fleet);
} }
private static int getSeriesIndex(ManagedRace race, SeriesBase series) {
return Util.indexOf(race.getRaceGroup().getSeries(), series);
}
} }
@@ -9,12 +9,12 @@ import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.internal.widget.TintImageView; import android.support.v7.internal.widget.TintImageView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.*; import android.view.*;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
@@ -46,6 +46,7 @@ import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.RaceFlagViewerFra
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.RaceInfoListener; import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.RaceInfoListener;
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.RaceSummaryFragment; import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.RaceSummaryFragment;
import com.sap.sailing.racecommittee.app.utils.BitmapHelper; import com.sap.sailing.racecommittee.app.utils.BitmapHelper;
import com.sap.sailing.racecommittee.app.utils.RaceHelper;
import com.sap.sailing.racecommittee.app.utils.ThemeHelper; import com.sap.sailing.racecommittee.app.utils.ThemeHelper;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint;
@@ -68,7 +69,6 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
private Wind mWind; private Wind mWind;
private RaceListFragment mRaceList; private RaceListFragment mRaceList;
private ManagedRace mSelectedRace; private ManagedRace mSelectedRace;
private CourseArea mCourseArea;
private TimePoint startTime; private TimePoint startTime;
private Serializable getCourseAreaIdFromIntent() { private Serializable getCourseAreaIdFromIntent() {
@@ -152,7 +152,7 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
throw new IllegalStateException("There was no course area id transmitted..."); throw new IllegalStateException("There was no course area id transmitted...");
} }
ExLog.i(this, this.getClass().toString(), "trying to load courseArea via id: " + courseAreaId); ExLog.i(this, this.getClass().toString(), "trying to load courseArea via id: " + courseAreaId);
mCourseArea = dataManager.getDataStore().getCourseArea(courseAreaId); CourseArea courseArea = dataManager.getDataStore().getCourseArea(courseAreaId);
Serializable eventId = getEventIdFromIntent(); Serializable eventId = getEventIdFromIntent();
if (eventId == null) { if (eventId == null) {
@@ -166,14 +166,14 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
startActivity(intent); startActivity(intent);
finish(); finish();
} else { } else {
if (mCourseArea != null) { if (courseArea != null) {
loadRaces(mCourseArea); loadRaces(courseArea);
ExLog.i(this, this.getClass().toString(), "did load courseArea!"); ExLog.i(this, this.getClass().toString(), "did load courseArea!");
} else { } else {
ExLog.i(this, this.getClass().toString(), "courseArea == null :("); ExLog.i(this, this.getClass().toString(), "courseArea == null :(");
Toast.makeText(this, getString(R.string.racing_course_area_missing), Toast.LENGTH_LONG).show(); Toast.makeText(this, getString(R.string.racing_course_area_missing), Toast.LENGTH_LONG).show();
} }
loadNavDrawer(mCourseArea); loadNavDrawer(courseArea);
loadWelcomeFragment(); loadWelcomeFragment();
} }
} }
@@ -253,7 +253,7 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
} }
@Override @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) { protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState); super.onRestoreInstanceState(savedInstanceState);
mWind = (Wind) savedInstanceState.getSerializable(WIND); mWind = (Wind) savedInstanceState.getSerializable(WIND);
@@ -359,20 +359,8 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
} }
private void setupActionBar(ManagedRace race) { private void setupActionBar(ManagedRace race) {
String title = race.getRaceGroup().getDisplayName();
if (TextUtils.isEmpty(title)) {
title = race.getRaceGroup().getName();
}
if (race.getSeries() != null && !race.getSeries().getName().equals(AppConstants.DEFAULT)) {
title += " / " + race.getSeries().getName();
}
if (race.getFleet() != null && !race.getFleet().getName().equals(AppConstants.DEFAULT)) {
title += " / " + race.getFleet().getName();
}
title += " / " + race.getRaceName();
if (getSupportActionBar() != null) { if (getSupportActionBar() != null) {
getSupportActionBar().setTitle(title); getSupportActionBar().setTitle(RaceHelper.getRaceName(race, " / "));
} }
} }
@@ -384,7 +372,7 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
builder.setPositiveButton(getString(R.string.race_reset_confirm), new DialogInterface.OnClickListener() { builder.setPositiveButton(getString(R.string.race_reset_confirm), new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
ExLog.i(RacingActivity.this, LogEvent.RACE_RESET_YES, mSelectedRace.getId().toString()); ExLog.i(RacingActivity.this, LogEvent.RACE_RESET_YES, mSelectedRace.getId());
ExLog.w(RacingActivity.this, TAG, String.format("Race %s is selected for reset.", mSelectedRace.getId())); ExLog.w(RacingActivity.this, TAG, String.format("Race %s is selected for reset.", mSelectedRace.getId()));
mSelectedRace.getState().setAdvancePass(MillisecondsTimePoint.now()); mSelectedRace.getState().setAdvancePass(MillisecondsTimePoint.now());
} }
@@ -393,7 +381,7 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (mSelectedRace != null) { if (mSelectedRace != null) {
ExLog.i(RacingActivity.this, LogEvent.RACE_RESET_NO, mSelectedRace.getId().toString()); ExLog.i(RacingActivity.this, LogEvent.RACE_RESET_NO, mSelectedRace.getId());
} }
dialog.cancel(); dialog.cancel();
} }
@@ -416,7 +404,7 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
@Override @Override
public void onGlobalLayout() { public void onGlobalLayout() {
// Find the overflow button // Find the overflow button
final ArrayList<View> outViews = new ArrayList<View>(); final ArrayList<View> outViews = new ArrayList<>();
decorView.findViewsWithText(outViews, overflowDescription, View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION); decorView.findViewsWithText(outViews, overflowDescription, View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty()) { if (outViews.isEmpty()) {
return; return;
@@ -493,7 +481,7 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
setProgressSpinnerVisibility(false); setProgressSpinnerVisibility(false);
AlertDialog.Builder builder = new AlertDialog.Builder(RacingActivity.this, R.style.AppTheme_AlertDialog); AlertDialog.Builder builder = new AlertDialog.Builder(RacingActivity.this, R.style.AppTheme_AlertDialog);
builder.setMessage(String.format(getString(R.string.generic_load_failure), ex.getMessage())).setTitle(getString(R.string.loading_failure)) builder.setMessage(String.format(getString(R.string.generic_load_failure), ex.getMessage())).setTitle(getString(R.string.loading_failure))
.setIcon(R.drawable.ic_warning_grey600_36dp).setCancelable(true) .setIcon(R.drawable.ic_warning_grey_600_36dp).setCancelable(true)
.setPositiveButton(getString(R.string.retry), new DialogInterface.OnClickListener() { .setPositiveButton(getString(R.string.retry), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
setProgressSpinnerVisibility(true); setProgressSpinnerVisibility(true);
@@ -0,0 +1,190 @@
package com.sap.sailing.racecommittee.app.ui.adapters;
import java.util.ArrayList;
import android.content.Context;
import android.database.DataSetObserver;
import android.support.annotation.LayoutRes;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import com.sap.sailing.android.shared.util.ViewHolder;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.utils.RaceHelper;
import com.sap.sailing.racecommittee.app.utils.ThemeHelper;
public class DependentRaceSpinnerAdapter implements SpinnerAdapter {
private static final int HEADER = 0;
private static final int DATA = 1;
private Context mContext;
private int mLayout;
private int mSelectedItem = -1;
private ArrayList<RaceData> mData;
public DependentRaceSpinnerAdapter(Context context, @LayoutRes int layout) {
mContext = context;
mLayout = layout;
mData = new ArrayList<>();
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View layout = convertView;
if (layout == null) {
layout = LayoutInflater.from(mContext).inflate(mLayout, parent, false);
}
TextView mainText = ViewHolder.get(layout, android.R.id.text1);
if (mainText != null) {
mainText.setText(mData.get(position).getMainText());
}
TextView subTextView = ViewHolder.get(layout, android.R.id.text2);
String subText = mData.get(position).getSubText();
if (subTextView != null) {
if (getItemViewType(position) == HEADER) {
layout.setBackgroundColor(ThemeHelper.getColor(mContext, R.attr.sap_gray_black_20));
if (subText != null) {
subTextView.setTextColor(ThemeHelper.getColor(mContext, R.attr.sap_light_gray));
subTextView.setText(subText);
subTextView.setVisibility(View.VISIBLE);
} else {
subTextView.setVisibility(View.GONE);
}
layout.setClickable(true);
if (mainText != null) {
mainText.setTextColor(ThemeHelper.getColor(mContext, R.attr.sap_light_gray));
}
} else {
if (mSelectedItem == position) {
layout.setBackgroundColor(ThemeHelper.getColor(mContext, R.attr.sap_light_gray));
} else {
layout.setBackgroundColor(ThemeHelper.getColor(mContext, R.attr.sap_gray_black_30));
}
subTextView.setVisibility(View.GONE);
layout.setClickable(false);
if (mainText != null) {
mainText.setTextColor(ThemeHelper.getColor(mContext, R.attr.white));
}
}
}
return layout;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View layout = convertView;
if (layout == null) {
layout = LayoutInflater.from(mContext).inflate(mLayout, parent, false);
}
TextView text = ViewHolder.get(layout, android.R.id.text1);
if (text != null && position < mData.size() && mData.get(position).getRace() != null) {
String raceName = mData.get(position).getRace().getName();
String additional = RaceHelper.getFleetSeries(mData.get(position).getRace());
if (!TextUtils.isEmpty(additional)) {
additional += " - ";
}
additional += RaceHelper.getRaceGroupName(mData.get(position).getRace());
if (!TextUtils.isEmpty(additional)) {
raceName += " (" + additional + ")";
}
text.setText(raceName);
}
return layout;
}
@Override
public int getItemViewType(int position) {
if (mData.get(position).getRace() == null) {
return HEADER;
}
return DATA;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public boolean isEmpty() {
return (mData.size() == 0);
}
public void add(RaceData data) {
mData.add(data);
}
public void setSelected(int position) {
mSelectedItem = position;
}
public ManagedRace getRaceAtPosition(int position) {
return mData.get(position).getRace();
}
public static class RaceData {
private String mText1;
private String mText2;
private ManagedRace mRace;
public RaceData(String mainText, String subText, ManagedRace race) {
mText1 = mainText;
mText2 = subText;
mRace = race;
}
public String getMainText() {
return mText1;
}
public String getSubText() {
return mText2;
}
public ManagedRace getRace() {
return mRace;
}
}
}
@@ -1,5 +1,8 @@
package com.sap.sailing.racecommittee.app.ui.adapters.racelist; package com.sap.sailing.racecommittee.app.ui.adapters.racelist;
import java.text.SimpleDateFormat;
import java.util.List;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
@@ -14,8 +17,12 @@ import android.widget.ArrayAdapter;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.ViewHolder; import com.sap.sailing.android.shared.util.ViewHolder;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult;
import com.sap.sailing.domain.abstractlog.race.state.RaceState; import com.sap.sailing.domain.abstractlog.race.state.RaceState;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.FlagPoleState; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.FlagPoleState;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure;
@@ -23,18 +30,19 @@ import com.sap.sailing.domain.common.racelog.FlagPole;
import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.racecommittee.app.AppConstants; import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.data.AndroidRaceLogResolver;
import com.sap.sailing.racecommittee.app.data.DataManager;
import com.sap.sailing.racecommittee.app.domain.ManagedRace; import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceFilter.FilterSubscriber; import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceFilter.FilterSubscriber;
import com.sap.sailing.racecommittee.app.ui.utils.FlagsResources; import com.sap.sailing.racecommittee.app.ui.utils.FlagsResources;
import com.sap.sailing.racecommittee.app.utils.BitmapHelper; import com.sap.sailing.racecommittee.app.utils.BitmapHelper;
import com.sap.sailing.racecommittee.app.utils.RaceHelper;
import com.sap.sailing.racecommittee.app.utils.ThemeHelper; import com.sap.sailing.racecommittee.app.utils.ThemeHelper;
import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sailing.racecommittee.app.utils.TimeUtils;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint;
import java.text.SimpleDateFormat;
import java.util.List;
public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> implements FilterSubscriber { public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> implements FilterSubscriber {
private final static String TAG = ManagedRaceListAdapter.class.getName(); private final static String TAG = ManagedRaceListAdapter.class.getName();
@@ -53,13 +61,14 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
private TextView race_finished; private TextView race_finished;
private LinearLayout race_scheduled; private LinearLayout race_scheduled;
private TextView race_unscheduled; private TextView race_unscheduled;
private TextView depends_on;
private ImageView current_flag; private ImageView current_flag;
private TextView race_name; private TextView race_name;
private TextView flag_timer; private TextView flag_timer;
private ImageView arrow_direction;
private TextView boat_class; private TextView boat_class;
private TextView fleet_series; private TextView fleet_series;
private ImageView protest_image; private ImageView protest_image;
private ImageView has_dependent_races;
private SimpleDateFormat dateFormat; private SimpleDateFormat dateFormat;
private RaceListDataType mSelectedRace; private RaceListDataType mSelectedRace;
@@ -70,7 +79,7 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
mShownViewItems = viewItems; mShownViewItems = viewItems;
mInflater = LayoutInflater.from(getContext()); mInflater = LayoutInflater.from(getContext());
mResources = getContext().getResources(); mResources = getContext().getResources();
dateFormat = new SimpleDateFormat("HH:mm", getContext().getResources().getConfiguration().locale); dateFormat = new SimpleDateFormat("kk:mm", getContext().getResources().getConfiguration().locale);
} }
@Override @Override
@@ -129,17 +138,7 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
regatta = header.getRaceGroup().getName(); regatta = header.getRaceGroup().getName();
} }
boat_class.setText(regatta); boat_class.setText(regatta);
String fleetSeries = ""; fleet_series.setText(RaceHelper.getFleetSeries(header.getFleet(), header.getSeries()));
if (header.getFleet() != null && !header.getFleet().getName().equals(AppConstants.DEFAULT)) {
fleetSeries += header.getFleet().getName();
}
if (header.getSeries() != null && !header.getSeries().getName().equals(AppConstants.DEFAULT)) {
if (!TextUtils.isEmpty(fleetSeries)) {
fleetSeries += " - ";
}
fleetSeries += header.getSeries().getName();
}
fleet_series.setText(fleetSeries);
protest_image.setImageDrawable(FlagsResources.getFlagDrawable(getContext(), Flags.BRAVO.name(), FLAG_SIZE)); protest_image.setImageDrawable(FlagsResources.getFlagDrawable(getContext(), Flags.BRAVO.name(), FLAG_SIZE));
protest_image.setOnClickListener(new View.OnClickListener() { protest_image.setOnClickListener(new View.OnClickListener() {
@Override @Override
@@ -156,8 +155,16 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
if (mSelectedRace != null && mSelectedRace.equals(race)) { if (mSelectedRace != null && mSelectedRace.equals(race)) {
setMarker(1 - getLevel()); setMarker(1 - getLevel());
convertView.setBackgroundColor(ThemeHelper.getColor(getContext(), R.attr.sap_gray_black_20)); convertView.setBackgroundColor(ThemeHelper.getColor(getContext(), R.attr.sap_gray_black_20));
if (race.isUpdateIndicatorVisible()) {
race.setUpdateIndicatorVisible(false);
}
} else { } else {
convertView.setBackgroundColor(ThemeHelper.getColor(getContext(), R.attr.sap_gray)); convertView.setBackgroundColor(ThemeHelper.getColor(getContext(), R.attr.sap_gray));
if (race.isUpdateIndicatorVisible()) {
update_badge.setVisibility(View.VISIBLE);
}
} }
} }
@@ -182,6 +189,11 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
} }
time.setTextSize(textSize); time.setTextSize(textSize);
} }
StartTimeFinder stf = new StartTimeFinder(new AndroidRaceLogResolver(), race.getRace().getRaceLog());
StartTimeFinderResult result = stf.analyze();
if (result != null && result.isDependentStartTime()) {
has_dependent_races.setVisibility(View.VISIBLE);
}
} }
if (state.getFinishedTime() != null) { if (state.getFinishedTime() != null) {
time.setVisibility(View.GONE); time.setVisibility(View.GONE);
@@ -189,8 +201,28 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
race_finished.setText(mResources.getString(R.string.race_finished, dateFormat.format(state.getFinishedTime().asDate()))); race_finished.setText(mResources.getString(R.string.race_finished, dateFormat.format(state.getFinishedTime().asDate())));
} }
if (state.getStartTime() == null && state.getFinishedTime() == null) { if (state.getStartTime() == null && state.getFinishedTime() == null) {
race_scheduled.setVisibility(View.GONE); switch (race.getRace().getStatus()) {
race_unscheduled.setVisibility(View.VISIBLE); case PRESCHEDULED:
race_scheduled.setVisibility(View.GONE);
race_unscheduled.setVisibility(View.GONE);
if (depends_on != null) {
StartTimeFinder stf = new StartTimeFinder(new AndroidRaceLogResolver(), race.getRace().getRaceLog());
StartTimeFinderResult result = stf.analyze();
if (result != null && result.isDependentStartTime()) {
SimpleRaceLogIdentifier identifier = Util.get(result.getRacesDependingOn(), 0);
ManagedRace tmp = DataManager.create(getContext()).getDataStore().getRace(identifier);
depends_on.setText(getContext()
.getString(R.string.minutes_after_long, result.getStartTimeDiff().asMinutes(), RaceHelper
.getRaceName(tmp, " / ")));
depends_on.setVisibility(View.VISIBLE);
}
}
break;
default:
race_scheduled.setVisibility(View.GONE);
race_unscheduled.setVisibility(View.VISIBLE);
}
} else { } else {
if (race_name != null) { if (race_name != null) {
race_name.setTextColor(ThemeHelper.getColor(getContext(), R.attr.white)); race_name.setTextColor(ThemeHelper.getColor(getContext(), R.attr.white));
@@ -198,10 +230,6 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
} }
} }
if (race.isUpdateIndicatorVisible()) {
update_badge.setVisibility(View.VISIBLE);
}
updateFlag(race.getRace(), now); updateFlag(race.getRace(), now);
} }
return convertView; return convertView;
@@ -229,26 +257,27 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
mSelectedRace = id; mSelectedRace = id;
} }
private void findViews(View convertView) { private void findViews(View layout) {
marker = ViewHolder.get(convertView, R.id.race_marker); marker = ViewHolder.get(layout, R.id.race_marker);
arrow_direction = ViewHolder.get(convertView, R.id.arrow_direction); current_flag = ViewHolder.get(layout, R.id.current_flag);
current_flag = ViewHolder.get(convertView, R.id.current_flag); update_badge = ViewHolder.get(layout, R.id.update_badge);
update_badge = ViewHolder.get(convertView, R.id.update_badge); race_flag = ViewHolder.get(layout, R.id.race_flag);
race_flag = ViewHolder.get(convertView, R.id.race_flag); time = ViewHolder.get(layout, R.id.time);
time = ViewHolder.get(convertView, R.id.time); race_name = ViewHolder.get(layout, R.id.race_name);
race_name = ViewHolder.get(convertView, R.id.race_name); race_finished = ViewHolder.get(layout, R.id.race_finshed);
race_finished = ViewHolder.get(convertView, R.id.race_finshed); race_started = ViewHolder.get(layout, R.id.race_started);
race_started = ViewHolder.get(convertView, R.id.race_started); race_scheduled = ViewHolder.get(layout, R.id.race_scheduled);
race_scheduled = ViewHolder.get(convertView, R.id.race_scheduled); race_unscheduled = ViewHolder.get(layout, R.id.race_unscheduled);
race_unscheduled = ViewHolder.get(convertView, R.id.race_unscheduled); flag_timer = ViewHolder.get(layout, R.id.flag_timer);
flag_timer = ViewHolder.get(convertView, R.id.flag_timer); protest_image = ViewHolder.get(layout, R.id.protest_image);
protest_image = ViewHolder.get(convertView, R.id.protest_image); boat_class = ViewHolder.get(layout, R.id.boat_class);
boat_class = ViewHolder.get(convertView, R.id.boat_class); fleet_series = ViewHolder.get(layout, R.id.fleet_series);
fleet_series = ViewHolder.get(convertView, R.id.fleet_series); has_dependent_races = ViewHolder.get(layout, R.id.has_dependent_races);
depends_on = ViewHolder.get(layout, R.id.depends_on);
} }
private void resetValues(View convertView) { private void resetValues(View layout) {
if (convertView != null) { if (layout != null) {
if (update_badge != null) { if (update_badge != null) {
update_badge.setVisibility(View.GONE); update_badge.setVisibility(View.GONE);
} }
@@ -273,6 +302,13 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
if (race_name != null) { if (race_name != null) {
race_name.setTextColor(ThemeHelper.getColor(getContext(), R.attr.sap_light_gray)); race_name.setTextColor(ThemeHelper.getColor(getContext(), R.attr.sap_light_gray));
} }
if (has_dependent_races != null) {
has_dependent_races.setVisibility(View.GONE);
}
if (depends_on != null) {
depends_on.setTextColor(ThemeHelper.getColor(getContext(), R.attr.sap_light_gray));
depends_on.setVisibility(View.GONE);
}
setMarker(0); setMarker(0);
} }
} }
@@ -314,20 +350,20 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
if (isNext != 0) { if (isNext != 0) {
flag = FlagsResources.getFlagDrawable(getContext(), currentFlag.name(), FLAG_SIZE); flag = FlagsResources.getFlagDrawable(getContext(), currentFlag.name(), FLAG_SIZE);
switch (isNext) { switch (isNext) {
case 1: case 1:
if (nextPole.isDisplayed()) { if (nextPole.isDisplayed()) {
arrow = BitmapHelper.getAttrDrawable(getContext(), R.attr.arrow_up);
} else {
arrow = BitmapHelper.getAttrDrawable(getContext(), R.attr.arrow_down);
}
break;
case 2:
arrow = BitmapHelper.getAttrDrawable(getContext(), R.attr.arrow_up); arrow = BitmapHelper.getAttrDrawable(getContext(), R.attr.arrow_up);
} else { break;
arrow = BitmapHelper.getAttrDrawable(getContext(), R.attr.arrow_down);
}
break;
case 2: default:
arrow = BitmapHelper.getAttrDrawable(getContext(), R.attr.arrow_up); ExLog.i(getContext(), TAG, "unknown flag");
break;
default:
ExLog.i(getContext(), TAG, "unknown flag");
} }
timer = TimeUtils.formatDuration(now, poleState.getNextStateValidFrom()); timer = TimeUtils.formatDuration(now, poleState.getNextStateValidFrom());
} }
@@ -354,8 +390,8 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
private void showFlag(LayerDrawable flag, Drawable arrow, String timer) { private void showFlag(LayerDrawable flag, Drawable arrow, String timer) {
if (flag != null && arrow != null && timer != null) { if (flag != null && arrow != null && timer != null) {
current_flag.setImageDrawable(flag); current_flag.setImageDrawable(flag);
arrow_direction.setImageDrawable(arrow);
flag_timer.setText(timer); flag_timer.setText(timer);
flag_timer.setCompoundDrawablesWithIntrinsicBounds(arrow, null, null, null);
race_flag.setVisibility(View.VISIBLE); race_flag.setVisibility(View.VISIBLE);
} }
} }
@@ -37,7 +37,7 @@ public class RaceFilter extends Filter {
protected static FilterResults createResults(Collection<RaceListDataType> result) { protected static FilterResults createResults(Collection<RaceListDataType> result) {
FilterResults results = new FilterResults(); FilterResults results = new FilterResults();
results.values = new ArrayList<RaceListDataType>(result); results.values = new ArrayList<>(result);
results.count = result.size(); results.count = result.size();
return results; return results;
} }
@@ -58,7 +58,7 @@ public class RaceFilter extends Filter {
RaceListDataTypeHeader headerItem = (RaceListDataTypeHeader) item; RaceListDataTypeHeader headerItem = (RaceListDataTypeHeader) item;
filteredItems.add(headerItem); filteredItems.add(headerItem);
// new run for both types! // new run for all types!
currentUnscheduledItem = null; currentUnscheduledItem = null;
currentFinishedItem = null; currentFinishedItem = null;
} else if (item instanceof RaceListDataTypeRace) { } else if (item instanceof RaceListDataTypeRace) {
@@ -76,7 +76,7 @@ public class RaceFilter extends Filter {
currentUnscheduledItem = null; currentUnscheduledItem = null;
} else if (RaceLogRaceStatus.isActive(status)) { } else if (RaceLogRaceStatus.isActive(status)) {
filteredItems.add(raceItem); filteredItems.add(raceItem);
// new run for both types! // new run for all types!
currentUnscheduledItem = null; currentUnscheduledItem = null;
currentFinishedItem = null; currentFinishedItem = null;
} }
@@ -14,6 +14,7 @@ import com.sap.sse.common.TimePoint;
public class RaceListDataTypeRace implements RaceListDataType { public class RaceListDataTypeRace implements RaceListDataType {
private static String unscheduledTemplate; private static String unscheduledTemplate;
private static String prescheduledTemplate;
private static String scheduldedTemplate; private static String scheduldedTemplate;
private static String startPhaseTemplate; private static String startPhaseTemplate;
private static String runningTemplate; private static String runningTemplate;
@@ -29,6 +30,7 @@ public class RaceListDataTypeRace implements RaceListDataType {
public static void initializeTemplates(Fragment fragment) { public static void initializeTemplates(Fragment fragment) {
unscheduledTemplate = fragment.getString(R.string.racelist_unscheduled); unscheduledTemplate = fragment.getString(R.string.racelist_unscheduled);
prescheduledTemplate = fragment.getString(R.string.racelist_prescheduled);
scheduldedTemplate = fragment.getString(R.string.racelist_scheduled); scheduldedTemplate = fragment.getString(R.string.racelist_scheduled);
startPhaseTemplate = fragment.getString(R.string.racelist_startphase); startPhaseTemplate = fragment.getString(R.string.racelist_startphase);
runningTemplate = fragment.getString(R.string.racelist_running); runningTemplate = fragment.getString(R.string.racelist_running);
@@ -77,6 +79,8 @@ public class RaceListDataTypeRace implements RaceListDataType {
switch (status) { switch (status) {
case UNSCHEDULED: case UNSCHEDULED:
return unscheduledTemplate; return unscheduledTemplate;
case PRESCHEDULED:
return String.format(prescheduledTemplate, formatStartTime());
case SCHEDULED: case SCHEDULED:
return String.format(scheduldedTemplate, formatStartTime()); return String.format(scheduldedTemplate, formatStartTime());
case STARTPHASE: case STARTPHASE:
@@ -123,7 +123,7 @@ public class RaceInfoFragment extends RaceFragment implements RaceInfoListener {
prepareResetRaceView(); prepareResetRaceView();
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_AlertDialog); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_AlertDialog);
builder.setView(resetRaceDialogView).setTitle(R.string.race_reset_confirmation_title) builder.setView(resetRaceDialogView).setTitle(R.string.race_reset_confirmation_title)
.setIcon(R.drawable.ic_warning_grey600_36dp).setCancelable(true) .setIcon(R.drawable.ic_warning_grey_600_36dp).setCancelable(true)
.setPositiveButton(getString(R.string.race_reset_reset_button), new DialogInterface.OnClickListener() { .setPositiveButton(getString(R.string.race_reset_reset_button), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
ExLog.i(getActivity(), LogEvent.RACE_RESET_YES, getRace().getId().toString()); ExLog.i(getActivity(), LogEvent.RACE_RESET_YES, getRace().getId().toString());
@@ -59,15 +59,14 @@ import com.sap.sailing.racecommittee.app.ui.comparators.RaceListDataTypeComparat
import com.sap.sailing.racecommittee.app.ui.comparators.RegattaSeriesFleetComparator; import com.sap.sailing.racecommittee.app.ui.comparators.RegattaSeriesFleetComparator;
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.ProtestTimeDialogFragment; import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.ProtestTimeDialogFragment;
import com.sap.sailing.racecommittee.app.utils.BitmapHelper; import com.sap.sailing.racecommittee.app.utils.BitmapHelper;
import com.sap.sailing.racecommittee.app.utils.RaceHelper;
import com.sap.sailing.racecommittee.app.utils.StringHelper; import com.sap.sailing.racecommittee.app.utils.StringHelper;
import com.sap.sailing.racecommittee.app.utils.ThemeHelper; import com.sap.sailing.racecommittee.app.utils.ThemeHelper;
import com.sap.sailing.racecommittee.app.utils.TickListener; import com.sap.sailing.racecommittee.app.utils.TickListener;
import com.sap.sailing.racecommittee.app.utils.TickSingleton; import com.sap.sailing.racecommittee.app.utils.TickSingleton;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
public class RaceListFragment public class RaceListFragment extends LoggableFragment implements OnItemClickListener, OnItemSelectedListener, TickListener, OnScrollListener {
extends LoggableFragment
implements OnItemClickListener, OnItemSelectedListener, TickListener, OnScrollListener {
private final static String TAG = RaceListFragment.class.getName(); private final static String TAG = RaceListFragment.class.getName();
private final static String LAYOUT = "layout"; private final static String LAYOUT = "layout";
@@ -123,12 +122,8 @@ public class RaceListFragment
public static void showProtest(Context context, ManagedRace race) { public static void showProtest(Context context, ManagedRace race) {
Intent intent = new Intent(AppConstants.INTENT_ACTION_SHOW_PROTEST); Intent intent = new Intent(AppConstants.INTENT_ACTION_SHOW_PROTEST);
String extra = race.getRaceGroup().getName(); String extra = race.getRaceGroup().getName();
if (!race.getSeries().getName().equals(AppConstants.DEFAULT)) { extra += RaceHelper.getSeriesName(race.getSeries());
extra += " - " + race.getSeries().getName(); extra += RaceHelper.getFleetName(race.getFleet());
}
if (!race.getFleet().getName().equals(AppConstants.DEFAULT)) {
extra += " - " + race.getFleet().getName();
}
intent.putExtra(AppConstants.INTENT_ACTION_EXTRA, extra); intent.putExtra(AppConstants.INTENT_ACTION_EXTRA, extra);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent); LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
} }
@@ -472,42 +467,6 @@ public class RaceListFragment
} }
} }
public enum FilterMode {
ACTIVE(R.string.race_list_filter_show_active), ALL(R.string.race_list_filter_show_all);
private String displayName;
FilterMode(int resId) {
this.displayName = RaceApplication.getStringContext().getString(resId);
}
@Override
public String toString() {
return displayName;
}
}
public interface RaceListCallbacks {
void onRaceListItemSelected(RaceListDataType selectedItem);
}
private class IntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (AppConstants.INTENT_ACTION_SHOW_PROTEST.equals(intent.getAction())) {
String raceGroupName = intent.getExtras().getString(AppConstants.INTENT_ACTION_EXTRA);
if (raceGroupName != null) {
showProtestTimeDialog(raceGroupName);
} else {
ExLog.e(getActivity(), TAG, "INTENT_ACTION_SHOW_PROTEST does not carry an INTENT_ACTION_EXTRA with the race group name!");
}
}
}
}
private void showProtestTimeDialog(String raceGroupName) { private void showProtestTimeDialog(String raceGroupName) {
// Find the race group for which the // Find the race group for which the
for (RaceGroupSeriesFleet raceGroupSeriesFleet : mRacesByGroup.keySet()) { for (RaceGroupSeriesFleet raceGroupSeriesFleet : mRacesByGroup.keySet()) {
@@ -535,5 +494,38 @@ public class RaceListFragment
return false; return false;
} }
public enum FilterMode {
ACTIVE(R.string.race_list_filter_show_active), ALL(R.string.race_list_filter_show_all);
private String displayName;
FilterMode(int resId) {
this.displayName = RaceApplication.getStringContext().getString(resId);
}
@Override
public String toString() {
return displayName;
}
}
public interface RaceListCallbacks {
void onRaceListItemSelected(RaceListDataType selectedItem);
}
private class IntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (AppConstants.INTENT_ACTION_SHOW_PROTEST.equals(intent.getAction())) {
String raceGroupName = intent.getExtras().getString(AppConstants.INTENT_ACTION_EXTRA);
if (raceGroupName != null) {
showProtestTimeDialog(raceGroupName);
} else {
ExLog.e(getActivity(), TAG, "INTENT_ACTION_SHOW_PROTEST does not carry an INTENT_ACTION_EXTRA with the race group name!");
}
}
}
}
} }
@@ -24,7 +24,8 @@ public abstract class RaceInfoFragmentChooser {
public RaceFragment choose(Context context, ManagedRace managedRace) { public RaceFragment choose(Context context, ManagedRace managedRace) {
switch (managedRace.getStatus()) { switch (managedRace.getStatus()) {
case UNSCHEDULED: case UNSCHEDULED:
return createInfoFragment(StartTimeFragment.newInstance(1), managedRace); return createInfoFragment(StartTimeFragment.newInstance(StartTimeFragment.MODE_1), managedRace);
case PRESCHEDULED:
case SCHEDULED: case SCHEDULED:
case STARTPHASE: case STARTPHASE:
return createInfoFragment(context, getStartphaseFragment(), managedRace); return createInfoFragment(context, getStartphaseFragment(), managedRace);
@@ -35,6 +35,6 @@ public class LoadFailedDialog extends FragmentAttachedDialogFragment {
getString(R.string.generic_load_failure), getString(R.string.generic_load_failure),
getArguments().getString(ARGS_ERROR_MSG))) getArguments().getString(ARGS_ERROR_MSG)))
.setTitle(getString(R.string.loading_failure)) .setTitle(getString(R.string.loading_failure))
.setIcon(R.drawable.ic_warning_grey600_36dp); .setIcon(R.drawable.ic_warning_grey_600_36dp);
} }
} }
@@ -1,11 +1,16 @@
package com.sap.sailing.racecommittee.app.ui.fragments.panels; package com.sap.sailing.racecommittee.app.ui.fragments.panels;
import android.content.*; import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.ViewHolder; import com.sap.sailing.android.shared.util.ViewHolder;
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
@@ -131,9 +136,22 @@ public class FlagPanelFragment extends BasePanelFragment {
changeVisibility(mRecallFlags, View.VISIBLE); changeVisibility(mRecallFlags, View.VISIBLE);
changeVisibility(mCourseFlags, View.GONE); changeVisibility(mCourseFlags, View.GONE);
changeVisibility(mMoreFlags, View.VISIBLE); changeVisibility(mMoreFlags, View.VISIBLE);
uncheckMarker(mCourseFlags); uncheckMarker(mCourseFlags);
break; break;
case PRESCHEDULED:
changeVisibility(mPostponeFlags, View.VISIBLE);
changeVisibility(mAbandonFlags, View.GONE);
changeVisibility(mRecallFlags, View.GONE);
changeVisibility(mCourseFlags, View.GONE);
changeVisibility(mMoreFlags, View.GONE);
uncheckMarker(mAbandonFlags);
uncheckMarker(mCourseFlags);
uncheckMarker(mMoreFlags);
break;
case SCHEDULED: case SCHEDULED:
case STARTPHASE: case STARTPHASE:
changeVisibility(mPostponeFlags, View.VISIBLE); changeVisibility(mPostponeFlags, View.VISIBLE);
@@ -141,6 +159,7 @@ public class FlagPanelFragment extends BasePanelFragment {
changeVisibility(mRecallFlags, View.GONE); changeVisibility(mRecallFlags, View.GONE);
changeVisibility(mCourseFlags, View.GONE); changeVisibility(mCourseFlags, View.GONE);
changeVisibility(mMoreFlags, View.GONE); changeVisibility(mMoreFlags, View.GONE);
uncheckMarker(mAbandonFlags); uncheckMarker(mAbandonFlags);
uncheckMarker(mRecallFlags); uncheckMarker(mRecallFlags);
uncheckMarker(mMoreFlags); uncheckMarker(mMoreFlags);
@@ -154,6 +173,7 @@ public class FlagPanelFragment extends BasePanelFragment {
changeVisibility(mRecallFlags, View.VISIBLE); changeVisibility(mRecallFlags, View.VISIBLE);
changeVisibility(mCourseFlags, View.GONE); changeVisibility(mCourseFlags, View.GONE);
changeVisibility(mMoreFlags, View.VISIBLE); changeVisibility(mMoreFlags, View.VISIBLE);
uncheckMarker(mCourseFlags); uncheckMarker(mCourseFlags);
break; break;
@@ -165,6 +185,7 @@ public class FlagPanelFragment extends BasePanelFragment {
changeVisibility(mRecallFlags, View.GONE); changeVisibility(mRecallFlags, View.GONE);
changeVisibility(mCourseFlags, View.GONE); changeVisibility(mCourseFlags, View.GONE);
changeVisibility(mMoreFlags, View.GONE); changeVisibility(mMoreFlags, View.GONE);
uncheckMarker(mRecallFlags); uncheckMarker(mRecallFlags);
uncheckMarker(mCourseFlags); uncheckMarker(mCourseFlags);
uncheckMarker(mMoreFlags); uncheckMarker(mMoreFlags);
@@ -178,6 +199,7 @@ public class FlagPanelFragment extends BasePanelFragment {
changeVisibility(mRecallFlags, View.VISIBLE); changeVisibility(mRecallFlags, View.VISIBLE);
changeVisibility(mCourseFlags, View.GONE); changeVisibility(mCourseFlags, View.GONE);
changeVisibility(mMoreFlags, View.VISIBLE); changeVisibility(mMoreFlags, View.VISIBLE);
uncheckMarker(mCourseFlags); uncheckMarker(mCourseFlags);
break; break;
@@ -187,6 +209,7 @@ public class FlagPanelFragment extends BasePanelFragment {
changeVisibility(mRecallFlags, View.GONE); changeVisibility(mRecallFlags, View.GONE);
changeVisibility(mCourseFlags, View.GONE); changeVisibility(mCourseFlags, View.GONE);
changeVisibility(mMoreFlags, View.GONE); changeVisibility(mMoreFlags, View.GONE);
uncheckMarker(mPostponeFlags); uncheckMarker(mPostponeFlags);
uncheckMarker(mAbandonFlags); uncheckMarker(mAbandonFlags);
uncheckMarker(mRecallFlags); uncheckMarker(mRecallFlags);
@@ -1,6 +1,10 @@
package com.sap.sailing.racecommittee.app.ui.fragments.panels; package com.sap.sailing.racecommittee.app.ui.fragments.panels;
import android.content.*; import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -8,6 +12,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.ViewHolder; import com.sap.sailing.android.shared.util.ViewHolder;
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
@@ -168,6 +173,13 @@ public class SetupPanelFragment extends BasePanelFragment {
changeVisibility(mWindLock, View.GONE); changeVisibility(mWindLock, View.GONE);
break; break;
case PRESCHEDULED:
changeVisibility(mStartProcedureLock, View.GONE);
changeVisibility(mStartModeLock, View.GONE);
changeVisibility(mCourseLock, View.GONE);
changeVisibility(mWindLock, View.GONE);
break;
case SCHEDULED: case SCHEDULED:
changeVisibility(mStartProcedureLock, View.GONE); changeVisibility(mStartProcedureLock, View.GONE);
changeVisibility(mStartModeLock, View.GONE); changeVisibility(mStartModeLock, View.GONE);
@@ -1,28 +1,41 @@
package com.sap.sailing.racecommittee.app.ui.fragments.panels; package com.sap.sailing.racecommittee.app.ui.fragments.panels;
import android.content.*; import java.text.SimpleDateFormat;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.ViewHolder; import com.sap.sailing.android.shared.util.ViewHolder;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult;
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
import com.sap.sailing.domain.abstractlog.race.state.impl.BaseRaceStateChangedListener; import com.sap.sailing.domain.abstractlog.race.state.impl.BaseRaceStateChangedListener;
import com.sap.sailing.racecommittee.app.AppConstants; import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.data.AndroidRaceLogResolver;
import com.sap.sailing.racecommittee.app.data.DataManager;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.StartTimeFragment; import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.StartTimeFragment;
import com.sap.sailing.racecommittee.app.utils.TickListener; import com.sap.sailing.racecommittee.app.utils.RaceHelper;
import com.sap.sailing.racecommittee.app.utils.TickSingleton; import com.sap.sailing.racecommittee.app.utils.TickSingleton;
import com.sap.sailing.racecommittee.app.utils.TimeUtils; import com.sap.sailing.racecommittee.app.utils.TimeUtils;
import com.sap.sse.common.TimePoint; import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint;
import java.text.SimpleDateFormat; public class TimePanelFragment extends BasePanelFragment {
public class TimePanelFragment extends BasePanelFragment implements TickListener {
public final static String TOGGLED = "toggled"; public final static String TOGGLED = "toggled";
@@ -36,6 +49,8 @@ public class TimePanelFragment extends BasePanelFragment implements TickListener
private TextView mHeaderTime; private TextView mHeaderTime;
private TextView mTimeStart; private TextView mTimeStart;
private TextView mTimeFinish; private TextView mTimeFinish;
private ImageView mLinkIcon;
private Boolean mLinkedRace = null;
public TimePanelFragment() { public TimePanelFragment() {
mReceiver = new IntentReceiver(); mReceiver = new IntentReceiver();
@@ -64,6 +79,8 @@ public class TimePanelFragment extends BasePanelFragment implements TickListener
mTimeFinish = ViewHolder.get(layout, R.id.time_finish); mTimeFinish = ViewHolder.get(layout, R.id.time_finish);
mHeaderTime = ViewHolder.get(layout, R.id.timer_text); mHeaderTime = ViewHolder.get(layout, R.id.timer_text);
mTimeStart = ViewHolder.get(layout, R.id.time_start); mTimeStart = ViewHolder.get(layout, R.id.time_start);
mLinkIcon = ViewHolder.get(layout, R.id.linked_race);
if (getArguments().getBoolean(TOGGLED, false)) { if (getArguments().getBoolean(TOGGLED, false)) {
toggleMarker(layout, R.id.time_marker); toggleMarker(layout, R.id.time_marker);
} }
@@ -75,7 +92,6 @@ public class TimePanelFragment extends BasePanelFragment implements TickListener
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
TickSingleton.INSTANCE.registerListener(this);
notifyTick(MillisecondsTimePoint.now()); notifyTick(MillisecondsTimePoint.now());
checkStatus(); checkStatus();
@@ -111,8 +127,12 @@ public class TimePanelFragment extends BasePanelFragment implements TickListener
if (getRace() != null && getRace().getState() != null) { if (getRace() != null && getRace().getState() != null) {
TimePoint startTime = getRace().getState().getStartTime(); TimePoint startTime = getRace().getState().getStartTime();
if (mTimeStart != null && startTime != null) { if (mTimeStart != null) {
mTimeStart.setText(getString(R.string.time_start).replace("#TIME#", dateFormat.format(startTime.asDate()))); if (startTime != null) {
mTimeStart.setText(getString(R.string.time_start, dateFormat.format(startTime.asDate())));
} else {
mTimeStart.setText(getString(R.string.time_start, "N/A"));
}
} }
if (mTimeFinish != null) { if (mTimeFinish != null) {
@@ -129,9 +149,26 @@ public class TimePanelFragment extends BasePanelFragment implements TickListener
resId = R.string.race_start_time_ago; resId = R.string.race_start_time_ago;
time = TimeUtils.formatDurationSince(now.minus(startTime.asMillis()).asMillis()); time = TimeUtils.formatDurationSince(now.minus(startTime.asMillis()).asMillis());
} }
mHeaderTime.setText(getString(resId).replace("#TIME#", time)); mHeaderTime.setText(getString(resId, time));
} }
} }
if (mLinkedRace == null) {
StartTimeFinder stf = new StartTimeFinder(new AndroidRaceLogResolver(), getRace().getRaceLog());
StartTimeFinderResult result = stf.analyze();
if (result != null) {
mLinkedRace = result.isDependentStartTime();
if (mLinkedRace && mHeaderTime != null) {
SimpleRaceLogIdentifier identifier = Util.get(result.getRacesDependingOn(), 0);
ManagedRace race = DataManager.create(getActivity()).getDataStore().getRace(identifier);
mHeaderTime.setText(getString(R.string.minutes_after_long, result.getStartTimeDiff().asMinutes(), RaceHelper.getRaceName(race, " / ")));
}
}
}
if (mLinkedRace != null && mLinkIcon != null) {
mLinkIcon.setVisibility(mLinkedRace ? View.VISIBLE : View.GONE);
}
} }
private void uncheckMarker(View view) { private void uncheckMarker(View view) {
@@ -145,33 +182,37 @@ public class TimePanelFragment extends BasePanelFragment implements TickListener
private void checkStatus() { private void checkStatus() {
switch (getRace().getStatus()) { switch (getRace().getStatus()) {
case UNSCHEDULED: case UNSCHEDULED:
changeVisibility(mTimeLock, View.GONE); changeVisibility(mTimeLock, View.GONE);
break; break;
case SCHEDULED: case PRESCHEDULED:
changeVisibility(mTimeLock, View.GONE); changeVisibility(mTimeLock, View.GONE);
break; break;
case STARTPHASE: case SCHEDULED:
changeVisibility(mTimeLock, View.GONE); changeVisibility(mTimeLock, View.GONE);
break; break;
case RUNNING: case STARTPHASE:
changeVisibility(mTimeLock, View.VISIBLE); changeVisibility(mTimeLock, View.GONE);
break; break;
case FINISHING: case RUNNING:
changeVisibility(mTimeLock, View.VISIBLE); changeVisibility(mTimeLock, View.VISIBLE);
break; break;
case FINISHED: case FINISHING:
changeVisibility(mTimeLock, View.VISIBLE); changeVisibility(mTimeLock, View.VISIBLE);
break; break;
default: case FINISHED:
changeVisibility(mTimeLock, View.VISIBLE); changeVisibility(mTimeLock, View.VISIBLE);
break; break;
default:
changeVisibility(mTimeLock, View.VISIBLE);
break;
} }
} }
@@ -199,17 +240,17 @@ public class TimePanelFragment extends BasePanelFragment implements TickListener
private void toggleFragment() { private void toggleFragment() {
sendIntent(AppConstants.INTENT_ACTION_TOGGLE, AppConstants.INTENT_ACTION_EXTRA, AppConstants.INTENT_ACTION_TOGGLE_TIME); sendIntent(AppConstants.INTENT_ACTION_TOGGLE, AppConstants.INTENT_ACTION_EXTRA, AppConstants.INTENT_ACTION_TOGGLE_TIME);
switch (toggleMarker(container, markerId)) { switch (toggleMarker(container, markerId)) {
case 0: case 0:
sendIntent(AppConstants.INTENT_ACTION_SHOW_MAIN_CONTENT); sendIntent(AppConstants.INTENT_ACTION_SHOW_MAIN_CONTENT);
break; break;
case 1: case 1:
replaceFragment(StartTimeFragment.newInstance(2)); replaceFragment(StartTimeFragment.newInstance(StartTimeFragment.MODE_TIME_PANEL));
break; break;
default: default:
ExLog.i(getActivity(), TAG, "Unknown return value"); ExLog.i(getActivity(), TAG, "Unknown return value");
break; break;
} }
disableToggle(container, markerId); disableToggle(container, markerId);
} }
@@ -252,5 +293,12 @@ public class TimePanelFragment extends BasePanelFragment implements TickListener
checkStatus(); checkStatus();
uncheckMarker(mView); uncheckMarker(mView);
} }
@Override
public void onStartTimeChanged(ReadonlyRaceState state) {
super.onStartTimeChanged(state);
mLinkedRace = null;
}
} }
} }
@@ -88,8 +88,6 @@ public class GeneralPreferenceFragment extends BasePreferenceFragment {
setupServerUrlBox(); setupServerUrlBox();
setupSyncQRCodeButton(); setupSyncQRCodeButton();
setupForceUpdateButton(); setupForceUpdateButton();
bindPreferenceSummaryToValue(findPreference(R.string.preference_server_url_key));
} }
private void setupIdentifierBox() { private void setupIdentifierBox() {
@@ -105,6 +105,7 @@ public class RegattaPreferenceFragment extends BasePreferenceFragment {
private void setupGeneral() { private void setupGeneral() {
setupRacingProcedureTypePreference(); setupRacingProcedureTypePreference();
setupCourseDesignerTypePreference(); setupCourseDesignerTypePreference();
setupDependentRacesPreference();
} }
private void setupRacingProcedureTypePreference() { private void setupRacingProcedureTypePreference() {
@@ -139,6 +140,10 @@ public class RegattaPreferenceFragment extends BasePreferenceFragment {
bindPreferenceSummaryToValue(preference); bindPreferenceSummaryToValue(preference);
} }
private void setupDependentRacesPreference() {
bindPreferenceSummaryToInteger(findPreference(R.string.preference_dependent_races_offset_key));
}
private void setupRRS26StartmodeFlagsList() { private void setupRRS26StartmodeFlagsList() {
MultiSelectListPreference preference = findPreference(R.string.preference_racing_procedure_rrs26_startmode_flags_key); MultiSelectListPreference preference = findPreference(R.string.preference_racing_procedure_rrs26_startmode_flags_key);
List<String> flags = new ArrayList<>(); List<String> flags = new ArrayList<>();
@@ -15,7 +15,6 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.EditText; import android.widget.EditText;
import android.widget.NumberPicker; import android.widget.NumberPicker;
import android.widget.TextView; import android.widget.TextView;
import com.sap.sailing.android.shared.util.ViewHolder; import com.sap.sailing.android.shared.util.ViewHolder;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.GateStartRacingProcedure; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.GateStartRacingProcedure;
import com.sap.sailing.racecommittee.app.AppConstants; import com.sap.sailing.racecommittee.app.AppConstants;
@@ -70,8 +69,7 @@ public class GateStartFragment {
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View layout = LayoutInflater.from(getActivity()).inflate( final View layout = LayoutInflater.from(getActivity()).inflate(R.layout.race_schedule_procedure_gate_start_pathfinder, container, false);
R.layout.race_schedule_procedure_gate_start_pathfinder, container, false);
mNat = ViewHolder.get(layout, R.id.pathfinder_nat); mNat = ViewHolder.get(layout, R.id.pathfinder_nat);
mNum = ViewHolder.get(layout, R.id.pathfinder_num); mNum = ViewHolder.get(layout, R.id.pathfinder_num);
@@ -201,8 +199,7 @@ public class GateStartFragment {
private void enableSetButton(View view, View button) { private void enableSetButton(View view, View button) {
if (view != null && view.getTag(R.id.pathfinder_nat) != null && view.getTag(R.id.pathfinder_num) != null) { if (view != null && view.getTag(R.id.pathfinder_nat) != null && view.getTag(R.id.pathfinder_num) != null) {
button.setEnabled( button.setEnabled((Boolean) view.getTag(R.id.pathfinder_nat) && (Boolean) view.getTag(R.id.pathfinder_num));
(Boolean) view.getTag(R.id.pathfinder_nat) && (Boolean) view.getTag(R.id.pathfinder_num));
} }
} }
} }
@@ -235,8 +232,7 @@ public class GateStartFragment {
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = LayoutInflater.from(getActivity()) View layout = LayoutInflater.from(getActivity()).inflate(R.layout.race_schedule_procedure_gate_start_timing, container, false);
.inflate(R.layout.race_schedule_procedure_gate_start_timing, container, false);
View caption = ViewHolder.get(layout, R.id.header_text); View caption = ViewHolder.get(layout, R.id.header_text);
if (caption != null) { if (caption != null) {
@@ -244,8 +240,7 @@ public class GateStartFragment {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
replaceFragment(Pathfinder replaceFragment(Pathfinder.newInstance(getArguments().getString(NAT, null), getArguments().getString(NUM, null)));
.newInstance(getArguments().getString(NAT, null), getArguments().getString(NUM, null)));
} }
}); });
} }
@@ -279,8 +274,10 @@ public class GateStartFragment {
mTimeLaunch = (NumberPicker) getActivity().findViewById(R.id.time_launch); mTimeLaunch = (NumberPicker) getActivity().findViewById(R.id.time_launch);
mTimeGolf = (NumberPicker) getActivity().findViewById(R.id.time_golf); mTimeGolf = (NumberPicker) getActivity().findViewById(R.id.time_golf);
mProcedure = getRaceState().getTypedRacingProcedure(); mProcedure = getRaceState().getTypedRacingProcedure();
ThemeHelper.setPickerTextColor(getActivity(), mTimeLaunch, ThemeHelper.getColor(getActivity(), R.attr.white)); ThemeHelper.setPickerColor(getActivity(), mTimeLaunch, ThemeHelper.getColor(getActivity(), R.attr.white), ThemeHelper
ThemeHelper.setPickerTextColor(getActivity(), mTimeGolf, ThemeHelper.getColor(getActivity(), R.attr.white)); .getColor(getActivity(), R.attr.sap_yellow_1));
ThemeHelper.setPickerColor(getActivity(), mTimeGolf, ThemeHelper.getColor(getActivity(), R.attr.white), ThemeHelper
.getColor(getActivity(), R.attr.sap_yellow_1));
setTimeLaunchWidget(); setTimeLaunchWidget();
setTimeGolfWidget(); setTimeGolfWidget();
@@ -1,5 +1,9 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo; package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
@@ -8,8 +12,11 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.ViewHolder; import com.sap.sailing.android.shared.util.ViewHolder;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl;
import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
import com.sap.sailing.domain.abstractlog.race.state.impl.BaseRaceStateChangedListener; import com.sap.sailing.domain.abstractlog.race.state.impl.BaseRaceStateChangedListener;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.rrs26.RRS26RacingProcedure; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.rrs26.RRS26RacingProcedure;
@@ -17,26 +24,33 @@ import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.racelog.Flags; import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RacingProcedureType; import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.data.DataManager;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.impl.FleetIdentifierImpl;
import com.sap.sailing.racecommittee.app.ui.activities.RacingActivity; import com.sap.sailing.racecommittee.app.ui.activities.RacingActivity;
import com.sap.sailing.racecommittee.app.ui.fragments.RaceFragment; import com.sap.sailing.racecommittee.app.ui.fragments.RaceFragment;
import com.sap.sailing.racecommittee.app.ui.utils.FlagsResources; import com.sap.sailing.racecommittee.app.ui.utils.FlagsResources;
import com.sap.sailing.racecommittee.app.utils.BitmapHelper; import com.sap.sailing.racecommittee.app.utils.BitmapHelper;
import com.sap.sailing.racecommittee.app.utils.RaceHelper;
import com.sap.sailing.racecommittee.app.utils.TimeUtils; 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.TimePoint;
import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
public class MainScheduleFragment extends BaseFragment implements View.OnClickListener { public class MainScheduleFragment extends BaseFragment implements View.OnClickListener {
public static final String START_TIME = "startTime"; public static final String START_TIME = "startTime";
public static final String DEPENDENT_RACE = "dependentRace";
public static final String START_TIME_DIFF = "startTimeDiff";
private static final String TAG = MainScheduleFragment.class.getName(); private static final String TAG = MainScheduleFragment.class.getName();
private TextView mStartTimeTextView; private TextView mStartTimeTextView;
private String mStartTimeString; private String mStartTimeString;
private String mRaceId;
private TimePoint mStartTime; private TimePoint mStartTime;
private Duration mStartTimeDiff;
private TextView mWindValue; private TextView mWindValue;
private RacingProcedureType mRacingProcedureType; private RacingProcedureType mRacingProcedureType;
@@ -162,8 +176,8 @@ public class MainScheduleFragment extends BaseFragment implements View.OnClickLi
} }
private void initStartTime() { private void initStartTime() {
TimePoint timePoint = (TimePoint) getArguments().getSerializable(START_TIME);
RacingActivity activity = (RacingActivity) getActivity(); RacingActivity activity = (RacingActivity) getActivity();
TimePoint timePoint = (TimePoint) getArguments().getSerializable(START_TIME);
if (timePoint == null && activity != null) { if (timePoint == null && activity != null) {
timePoint = activity.getStartTime(); timePoint = activity.getStartTime();
} }
@@ -174,6 +188,14 @@ public class MainScheduleFragment extends BaseFragment implements View.OnClickLi
mStartTime = timePoint; mStartTime = timePoint;
mStartTimeString = mDateFormat.format(timePoint.asDate()); mStartTimeString = mDateFormat.format(timePoint.asDate());
} }
mStartTimeDiff = (Duration) getArguments().getSerializable(START_TIME_DIFF);
mRaceId = (String) getArguments().getSerializable(DEPENDENT_RACE);
if (mRaceId != null && mStartTimeDiff != null) {
ManagedRace race = DataManager.create(getActivity()).getDataStore().getRace(mRaceId);
mStartTimeString = getString(R.string.minutes_after_long, mStartTimeDiff.asMinutes(), RaceHelper.getRaceName(race, " / "));
}
} }
@Override @Override
@@ -205,7 +227,7 @@ public class MainScheduleFragment extends BaseFragment implements View.OnClickLi
break; break;
case R.id.start_time: case R.id.start_time:
openFragment(StartTimeFragment.newInstance(getArguments().getSerializable(START_TIME))); openFragment(StartTimeFragment.newInstance(getArguments()));
break; break;
case R.id.wind: case R.id.wind:
@@ -226,7 +248,13 @@ public class MainScheduleFragment extends BaseFragment implements View.OnClickLi
} }
TimePoint now = MillisecondsTimePoint.now(); TimePoint now = MillisecondsTimePoint.now();
getRaceState().setRacingProcedure(now, mRacingProcedureType); getRaceState().setRacingProcedure(now, mRacingProcedureType);
getRaceState().forceNewStartTime(now, mStartTime); if (mStartTimeDiff == null && mRaceId == null) {
getRaceState().forceNewStartTime(now, mStartTime);
} else {
Util.Triple<String, String, String> triple = FleetIdentifierImpl.unescape(mRaceId);
SimpleRaceLogIdentifier identifier = new SimpleRaceLogIdentifierImpl(triple.getA(), triple.getB(), triple.getC());
getRaceState().forceNewDependentStartTime(now, mStartTimeDiff, identifier);
}
if (procedure != null) { if (procedure != null) {
procedure.setStartModeFlag(MillisecondsTimePoint.now(), flag); procedure.setStartModeFlag(MillisecondsTimePoint.now(), flag);
} }
@@ -237,17 +265,18 @@ public class MainScheduleFragment extends BaseFragment implements View.OnClickLi
super.notifyTick(now); super.notifyTick(now);
if (mStartTimeTextView != null && !TextUtils.isEmpty(mStartTimeString)) { if (mStartTimeTextView != null && !TextUtils.isEmpty(mStartTimeString)) {
String startTimeValue = getString(R.string.start_time_value).replace("#TIME#", mStartTimeString) if (mRaceId == null && mStartTimeDiff == null) {
.replace("#COUNTDOWN#", calcCountdown(now)); String startTimeValue = getString(R.string.start_time_value, mStartTimeString, calcCountdown(now));
mStartTimeTextView.setText(startTimeValue); mStartTimeTextView.setText(startTimeValue);
} else {
mStartTimeTextView.setText(mStartTimeString);
}
} }
if (mWindValue != null && getRace() != null && getRaceState() != null && getRaceState().getWindFix() != null) { if (mWindValue != null && getRace() != null && getRaceState() != null && getRaceState().getWindFix() != null) {
String sensorData = getString(R.string.wind_sensor);
Wind wind = getRaceState().getWindFix(); Wind wind = getRaceState().getWindFix();
sensorData = sensorData.replace("#AT#", mDateFormat.format(wind.getTimePoint().asDate())); String sensorData = getString(R.string.wind_sensor, mDateFormat.format(wind.getTimePoint().asDate()), wind.getFrom().getDegrees(), wind
sensorData = sensorData.replace("#FROM#", String.format("%.0f", wind.getFrom().getDegrees())); .getKnots());
sensorData = sensorData.replace("#SPEED#", String.format("%.1f", wind.getKnots()));
mWindValue.setText(sensorData); mWindValue.setText(sensorData);
} }
} }
@@ -269,9 +298,12 @@ public class MainScheduleFragment extends BaseFragment implements View.OnClickLi
} else { } else {
fragment.setArguments(getRecentArguments()); fragment.setArguments(getRecentArguments());
} }
if (mStartTime != null) {
fragment.getArguments().putSerializable(START_TIME, mStartTime); Bundle args = fragment.getArguments();
} args.putSerializable(START_TIME, mStartTime);
args.putSerializable(START_TIME_DIFF, mStartTimeDiff);
args.putSerializable(DEPENDENT_RACE, mRaceId);
getFragmentManager().beginTransaction().replace(R.id.racing_view_container, fragment).commitAllowingStateLoss(); getFragmentManager().beginTransaction().replace(R.id.racing_view_container, fragment).commitAllowingStateLoss();
} }
@@ -108,15 +108,11 @@ public class MoreFlagsFragment extends BaseFragment implements MoreFlagItemClick
mDateFormat = new SimpleDateFormat("HH:mm:ss", getResources().getConfiguration().locale); mDateFormat = new SimpleDateFormat("HH:mm:ss", getResources().getConfiguration().locale);
View header = ViewHolder.get(layout, R.id.header_text);
if (header != null) {
// header.setOnClickListener(this);
}
mTimePicker = ViewHolder.get(layout, R.id.time_picker); mTimePicker = ViewHolder.get(layout, R.id.time_picker);
if (mTimePicker != null) { if (mTimePicker != null) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
ThemeHelper.setPickerTextColor(getActivity(), mTimePicker, ThemeHelper.getColor(getActivity(), R.attr.white)); ThemeHelper.setPickerColor(getActivity(), mTimePicker, ThemeHelper.getColor(getActivity(), R.attr.white), ThemeHelper
.getColor(getActivity(), R.attr.sap_yellow_1));
mTimePicker.setIs24HourView(true); mTimePicker.setIs24HourView(true);
mTimePicker.setCurrentHour(calendar.get(Calendar.HOUR_OF_DAY)); mTimePicker.setCurrentHour(calendar.get(Calendar.HOUR_OF_DAY));
} }
@@ -133,26 +129,41 @@ public class MoreFlagsFragment extends BaseFragment implements MoreFlagItemClick
finishCustom.setOnClickListener(this); finishCustom.setOnClickListener(this);
} }
return layout;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
switch (getArguments().getInt(START_MODE, 0)) { switch (getArguments().getInt(START_MODE, 0)) {
case 1: // Race-State: Finishing -> End Finishing case 1: // Race-State: Finishing -> End Finishing
ImageView flag = ViewHolder.get(layout, R.id.header_flag); View header = ViewHolder.get(getView(), R.id.header_text);
if (header != null) {
header.setOnClickListener(this);
}
View back = ViewHolder.get(getView(), R.id.header_back);
if (back != null) {
back.setVisibility(View.VISIBLE);
}
ImageView flag = ViewHolder.get(getView(), R.id.header_flag);
if (flag != null) { if (flag != null) {
int resId = R.drawable.flag_blue_48dp; int resId = R.drawable.flag_blue_48dp;
Drawable drawable = BitmapHelper.getDrawable(getActivity(), resId); Drawable drawable = BitmapHelper.getDrawable(getActivity(), resId);
flag.setImageDrawable(drawable); flag.setImageDrawable(drawable);
} }
TextView headline = ViewHolder.get(layout, R.id.header_headline); TextView headline = ViewHolder.get(getView(), R.id.header_headline);
if (headline != null) { if (headline != null) {
headline.setText(getString(R.string.race_end_finish_header)); headline.setText(getString(R.string.race_end_finish_header, mDateFormat.format(getRaceState().getFinishingTime().asMillis())));
} }
break; break;
default: // Race-State: Running -> Start Finishing default: // Race-State: Running -> Start Finishing
break; break;
} }
return layout;
} }
@Override @Override
@@ -181,7 +192,7 @@ public class MoreFlagsFragment extends BaseFragment implements MoreFlagItemClick
break; break;
default: default:
// currently unused, because of no other button sendIntent(AppConstants.INTENT_ACTION_SHOW_MAIN_CONTENT);
break; break;
} }
} }
@@ -9,7 +9,6 @@ import android.os.Bundle;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -18,13 +17,13 @@ import android.widget.ImageView;
import android.widget.Toast; import android.widget.Toast;
import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.ViewHolder; import com.sap.sailing.android.shared.util.ViewHolder;
import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.AppPreferences; import com.sap.sailing.racecommittee.app.AppPreferences;
import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.ui.adapters.finishing.FinishListPhotoAdapter; import com.sap.sailing.racecommittee.app.ui.adapters.finishing.FinishListPhotoAdapter;
import com.sap.sailing.racecommittee.app.ui.views.DividerItemDecoration; import com.sap.sailing.racecommittee.app.ui.views.DividerItemDecoration;
import com.sap.sailing.racecommittee.app.utils.CameraHelper; import com.sap.sailing.racecommittee.app.utils.CameraHelper;
import com.sap.sailing.racecommittee.app.utils.MailHelper; import com.sap.sailing.racecommittee.app.utils.MailHelper;
import com.sap.sailing.racecommittee.app.utils.RaceHelper;
import com.sap.sailing.racecommittee.app.utils.StringHelper; import com.sap.sailing.racecommittee.app.utils.StringHelper;
import java.io.File; import java.io.File;
@@ -173,35 +172,16 @@ public class PhotoListFragment extends BaseFragment {
private String getSubject() { private String getSubject() {
String author = StringHelper.on(getActivity()).getAuthor(preferences.getAuthor().getName()); String author = StringHelper.on(getActivity()).getAuthor(preferences.getAuthor().getName());
return getString(R.string.results_mail_subject, author, getRaceName()); return getString(R.string.results_mail_subject, author, RaceHelper.getRaceName(getRace()));
} }
private String getBody() { private String getBody() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append(getString(R.string.results_mail_body, getRaceName())); builder.append(getString(R.string.results_mail_body, RaceHelper.getRaceName(getRace())));
builder.append(getString(R.string.results_mail_body_race_group, getRace().getRaceGroup().getName())); builder.append(getString(R.string.results_mail_body_race_group, getRace().getRaceGroup().getName()));
builder.append(getString(R.string.results_mail_body_boat_class, getRace().getRaceGroup().getBoatClass().getName())); builder.append(getString(R.string.results_mail_body_boat_class, getRace().getRaceGroup().getBoatClass().getName()));
builder.append(getString(R.string.results_mail_body_start, mDateFormat.format(getRaceState().getStartTime().asDate()))); builder.append(getString(R.string.results_mail_body_start, mDateFormat.format(getRaceState().getStartTime().asDate())));
builder.append(getString(R.string.results_mail_body_finish, mDateFormat.format(getRaceState().getFinishedTime().asDate()))); builder.append(getString(R.string.results_mail_body_finish, mDateFormat.format(getRaceState().getFinishedTime().asDate())));
return builder.toString(); return builder.toString();
} }
private String getRaceName() {
String name = getRace().getRaceGroup().getDisplayName();
if (TextUtils.isEmpty(name)) {
name = getRace().getRaceGroup().getName();
}
if (!getRace().getSeries().getName().equals(AppConstants.DEFAULT)) {
name += " - " + getRace().getSeries().getName();
}
if (!getRace().getFleet().getName().equals(AppConstants.DEFAULT)) {
name += " - " + getRace().getFleet().getName();
}
name += " - " + getRace().getName();
return name;
}
} }
@@ -131,7 +131,7 @@ public class RaceFlagViewerFragment extends BaseFragment {
} }
} }
} else { } else {
if (mLayout != null && mFlagCache.nextPole != null) { if (mFlagCache.nextPole != null) {
for (int i = 0; i < mLayout.getChildCount(); i++) { for (int i = 0; i < mLayout.getChildCount(); i++) {
ImageView flagImage = ViewHolder.get(mLayout.getChildAt(i), R.id.flag); ImageView flagImage = ViewHolder.get(mLayout.getChildAt(i), R.id.flag);
Flags flags = (Flags) flagImage.getTag(); Flags flags = (Flags) flagImage.getTag();
Loaded 100 of 112 files, more files were not shown because too many files have changed in this diff. Show more