mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-28 14:57:12 +00:00
Merge branch 'master' into bug3378
Conflicts: java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java Change-Id: I25bdf84204d891856ce0c71d5585885fc0216795
This commit is contained in:
commit
0dbd65f20e
147 files changed
+1635
-2355
No files matched your search
@@ -6,7 +6,7 @@ for i in $*; do
|
||||
gzip -cd $i
|
||||
else
|
||||
cat $i
|
||||
fi | iconv -f ISO-8859-1 -t UTF8 |
|
||||
fi | recode ISO-8859-1..UTF-8 |
|
||||
sed -e 's/^\([^T]*\)T\([^.]*\)[^ ]* [^ ]* \([^:]*\):[^ ]* [^ ]* [^ ]* [^ ]* [^ ]* [^ ]* \([^ ]*\) \([^ ]*\) [^ ]* \(\"[^"]*\"\) \(\"[^"]*\"\).*$/'$PREFIX' \3 - - [\1:\2 +0000] \6 \4 \5 "http:\/\/'$PREFIX'" \7/' |
|
||||
sed -e 's/\[\([0-9]*\)-01-\([0-9]*\):/\[\2\/Jan\/\1:/' |
|
||||
sed -e 's/\[\([0-9]*\)-02-\([0-9]*\):/\[\2\/Feb\/\1:/' |
|
||||
|
||||
@@ -28,7 +28,7 @@ for i in $*; do
|
||||
gzip -cd $i
|
||||
else
|
||||
cat $i
|
||||
fi | iconv -f ISO-8859-1 -t UTF8 | sed -e 's/^\([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \[\([^:]*\):\([^]]*\)\] \"[^"]*\" [^ ]* [^ ]* \"[^"]*\" \"\([^"]*\)\"/\1 \2 \5 \7/' | while read referrer hit; do
|
||||
fi | recode ISO-8859-1..UTF-8 | sed -e 's/^\([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \[\([^:]*\):\([^]]*\)\] \"[^"]*\" [^ ]* [^ ]* \"[^"]*\" \"\([^"]*\)\"/\1 \2 \5 \7/' | while read referrer hit; do
|
||||
echo "$hit" >>${STATS}/${referrer}.ips
|
||||
done
|
||||
echo "$i" >>$VISITED_FILES
|
||||
@@ -49,7 +49,7 @@ for month in `cat $MONTHS`; do
|
||||
echo -n "`basename $i .ips` "
|
||||
cat $i | grep "^[^ ]* [0-9]*/$month .*" | sort -u | wc | awk '{ print $1; }'
|
||||
# TODO consider producing an AWStats configuration file for each virtual host name and splitting all new logs into virtual host name-specific log files
|
||||
done | tee $STATS/unique-ips-days-useragents-per-event-$month
|
||||
echo "Wrote per-month results to $STATS/unique-ips-days-useragents-per-event-$month"
|
||||
done | tee $STATS/unique-ips-days-useragents-per-event-`echo $month | tr / -`
|
||||
echo "Wrote per-month results to $STATS/unique-ips-days-useragents-per-event-`echo $month | tr / -`"
|
||||
done
|
||||
echo "Done at `date`."
|
||||
@@ -11,6 +11,6 @@ for month in `cat $MONTHS`; do
|
||||
cat $i | grep "^[^ ]* [0-9]*/$month .*" | sort -u | wc | awk '{ print $1; }'
|
||||
# TODO consider producing an AWStats configuration file for each virtual host name and splitting all new logs into virtual host name-specific log files
|
||||
done | tee $STATS/unique-ips-days-useragents-per-event-`echo $month | tr / -`
|
||||
echo "Wrote per-month results to $STATS/unique-ips-days-useragents-per-event-$month"
|
||||
echo "Wrote per-month results to $STATS/unique-ips-days-useragents-per-event-`echo $month | tr / -`"
|
||||
done
|
||||
echo "Done."
|
||||
@@ -94,8 +94,8 @@ public class TracTrac {
|
||||
new MillisecondsTimePoint(record.getTrackingStartTime().asMillis()),
|
||||
new MillisecondsTimePoint(record.getTrackingEndTime().asMillis()),
|
||||
raceLogStore, regattaLogStore,
|
||||
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, /* simulateWithStartTimeNow */
|
||||
false, /*useTracTracMarkPassings*/ false,
|
||||
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, /* offsetToStartTimeOfSimulatedRace */
|
||||
null, /*useTracTracMarkPassings*/ false,
|
||||
/* tracTracUsername */"", /* tracTracPassword */"", record.getRaceStatus(),
|
||||
record.getRaceVisibility());
|
||||
} else {
|
||||
|
||||
+7
-4
@@ -167,12 +167,13 @@ public abstract class AbstractLeaderboardDTO implements Serializable {
|
||||
* must not be null
|
||||
*/
|
||||
public RaceColumnDTO addRace(String raceColumnName, Double explicitFactor, double effectiveFactor,
|
||||
String regattaName, String seriesName, FleetDTO fleetDTO, boolean medalRace, RegattaAndRaceIdentifier trackedRaceIdentifier, RaceDTO race) {
|
||||
String regattaName, String seriesName, FleetDTO fleetDTO, boolean medalRace,
|
||||
RegattaAndRaceIdentifier trackedRaceIdentifier, RaceDTO race, boolean isMetaLeaderboardColumn) {
|
||||
assert fleetDTO != null;
|
||||
RaceColumnDTO raceColumnDTO = getRaceColumnByName(raceColumnName);
|
||||
if (raceColumnDTO == null) {
|
||||
raceColumnDTO = RaceColumnDTOFactory.INSTANCE.createRaceColumnDTO(raceColumnName, medalRace,
|
||||
explicitFactor, regattaName, seriesName);
|
||||
explicitFactor, regattaName, seriesName, isMetaLeaderboardColumn);
|
||||
races.add(raceColumnDTO);
|
||||
}
|
||||
raceColumnDTO.setEffectiveFactor(effectiveFactor);
|
||||
@@ -191,9 +192,10 @@ public abstract class AbstractLeaderboardDTO implements Serializable {
|
||||
return raceColumnDTO;
|
||||
}
|
||||
|
||||
public RaceColumnDTO createEmptyRaceColumn(String raceColumnName, boolean medalRace, String regattaName, String seriesName) {
|
||||
public RaceColumnDTO createEmptyRaceColumn(String raceColumnName, boolean medalRace, String regattaName,
|
||||
String seriesName, boolean isMetaLeaderboardColumn) {
|
||||
final RaceColumnDTO raceColumn = RaceColumnDTOFactory.INSTANCE.createRaceColumnDTO(raceColumnName,
|
||||
medalRace, /* explicit factor */ null, regattaName, seriesName);
|
||||
medalRace, /* explicit factor */ null, regattaName, seriesName, isMetaLeaderboardColumn);
|
||||
races.add(raceColumn);
|
||||
return raceColumn;
|
||||
}
|
||||
@@ -345,6 +347,7 @@ public abstract class AbstractLeaderboardDTO implements Serializable {
|
||||
result = prime * result + ((competitorDisplayNames == null) ? 0 : competitorDisplayNames.hashCode());
|
||||
result = prime * result + Arrays.hashCode(discardThresholds);
|
||||
result = prime * result + (hasCarriedPoints ? 1231 : 1237);
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((scoringScheme == null) ? 0 : scoringScheme.hashCode());
|
||||
if (races == null) {
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
package com.sap.sailing.domain.common.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.TimingConstants;
|
||||
|
||||
/**
|
||||
* Master data about a single race that is to be transferred to the client. Holds only timing and a bit
|
||||
* of information about the tracked race, if any. See also {@link RaceDTO} for a more comprehensive set
|
||||
* of data about a race to be serialized to a client.<p>
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class BasicRaceDTO extends NamedDTO {
|
||||
private static final long serialVersionUID = -7884808503795229609L;
|
||||
|
||||
public Date startOfRace;
|
||||
public Date endOfRace;
|
||||
public TrackedRaceDTO trackedRace;
|
||||
|
||||
public BasicRaceDTO() {} // for GWT serialization only
|
||||
|
||||
public BasicRaceDTO(RegattaAndRaceIdentifier raceIdentifier, TrackedRaceDTO trackedRace) {
|
||||
super(raceIdentifier.getRaceName());
|
||||
this.trackedRace = trackedRace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link TrackedRace#isLive} for further explanation.
|
||||
* @param serverTimePointAsMillis
|
||||
* the time point (in server clock time) at which to determine whether the race is/was live
|
||||
* @return <code>true</code> if <code>serverTimePointAsMillis</code> is between (inclusively) the start and end time
|
||||
* point of the "live" interval as defined above.
|
||||
*/
|
||||
public boolean isLive(long serverTimePointAsMillis) {
|
||||
final Date startOfLivePeriod;
|
||||
final Date endOfLivePeriod;
|
||||
if (trackedRace == null || !trackedRace.hasGPSData || !trackedRace.hasWindData) {
|
||||
startOfLivePeriod = null;
|
||||
endOfLivePeriod = null;
|
||||
} else {
|
||||
if (startOfRace == null) {
|
||||
startOfLivePeriod = trackedRace.startOfTracking;
|
||||
} else {
|
||||
startOfLivePeriod = new Date(startOfRace.getTime() - TimingConstants.PRE_START_PHASE_DURATION_IN_MILLIS);
|
||||
}
|
||||
if (endOfRace == null) {
|
||||
if (trackedRace.timePointOfNewestEvent != null) {
|
||||
endOfLivePeriod = new Date(trackedRace.timePointOfNewestEvent.getTime()
|
||||
+ TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS);
|
||||
} else {
|
||||
endOfLivePeriod = null;
|
||||
}
|
||||
} else {
|
||||
endOfLivePeriod = new Date(endOfRace.getTime() + TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS);
|
||||
}
|
||||
}
|
||||
|
||||
// if an empty timepoint is given then take the start of the race
|
||||
if (serverTimePointAsMillis == 0) {
|
||||
serverTimePointAsMillis = startOfLivePeriod.getTime()+1;
|
||||
}
|
||||
|
||||
// whenLastTrackedRaceWasLive is null if there is no tracked race for fleet, or the tracked race hasn't started yet at the server time
|
||||
// when this DTO was assembled, or there were no GPS or wind data
|
||||
final boolean result =
|
||||
startOfLivePeriod != null &&
|
||||
endOfLivePeriod != null &&
|
||||
startOfLivePeriod.getTime() <= serverTimePointAsMillis &&
|
||||
serverTimePointAsMillis <= endOfLivePeriod.getTime();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((endOfRace == null) ? 0 : endOfRace.hashCode());
|
||||
result = prime * result + ((startOfRace == null) ? 0 : startOfRace.hashCode());
|
||||
result = prime * result + ((trackedRace == null) ? 0 : trackedRace.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BasicRaceDTO other = (BasicRaceDTO) obj;
|
||||
if (endOfRace == null) {
|
||||
if (other.endOfRace != null)
|
||||
return false;
|
||||
} else if (!endOfRace.equals(other.endOfRace))
|
||||
return false;
|
||||
if (startOfRace == null) {
|
||||
if (other.startOfRace != null)
|
||||
return false;
|
||||
} else if (!startOfRace.equals(other.startOfRace))
|
||||
return false;
|
||||
if (trackedRace == null) {
|
||||
if (other.trackedRace != null)
|
||||
return false;
|
||||
} else if (!trackedRace.equals(other.trackedRace))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -62,7 +62,6 @@ public class LeaderboardDTO extends AbstractLeaderboardDTO implements Serializab
|
||||
/**
|
||||
* @param uuidGenerator used to provide the {@link #id ID} for this object (see also {@link #getId()}) and for any clones produced
|
||||
* from it by the {@link #clone()} operation.
|
||||
* @param hasOverallDetails TODO
|
||||
*/
|
||||
public LeaderboardDTO(Date timePointOfLastCorrectionsValidity, String comment, ScoringSchemeType scoringScheme, boolean higherScoreIsBetter, UUIDGenerator uuidGenerator, boolean hasOverallDetails) {
|
||||
initCollections();
|
||||
@@ -79,7 +78,7 @@ public class LeaderboardDTO extends AbstractLeaderboardDTO implements Serializab
|
||||
this.suppressedCompetitors = new ArrayList<CompetitorDTO>();
|
||||
}
|
||||
|
||||
public LeaderboardDTO(String id) {
|
||||
protected LeaderboardDTO(String id) {
|
||||
initCollections();
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.sap.sailing.domain.common.dto;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MetaLeaderboardRaceColumnDTO extends RaceColumnDTO {
|
||||
|
||||
private static final long serialVersionUID = 6152752963316150432L;
|
||||
|
||||
private ArrayList<BasicRaceDTO> raceList = new ArrayList<BasicRaceDTO>();
|
||||
|
||||
public boolean isLive(FleetDTO fleet, long serverTimePointAsMillis) {
|
||||
for (BasicRaceDTO race : raceList) {
|
||||
if (race.isLive(serverTimePointAsMillis)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addRace(BasicRaceDTO race) {
|
||||
raceList.add(race);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((raceList == null) ? 0 : raceList.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MetaLeaderboardRaceColumnDTO other = (MetaLeaderboardRaceColumnDTO) obj;
|
||||
if (raceList == null) {
|
||||
if (other.raceList != null)
|
||||
return false;
|
||||
} else if (!raceList.equals(other.raceList))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+6
-4
@@ -7,15 +7,17 @@ public class RaceColumnDTOFactory {
|
||||
* @param regattaName
|
||||
* must not be <code>null</code> if <code>seriesName</code> is not <code>null</code>
|
||||
* @param seriesName
|
||||
* when <code>null</code>, a regular {@link RaceColumnDTO} will be produced and initialized from the
|
||||
* properties passed; otherwise, a {@link RaceColumnInSeriesDTO} will be created.
|
||||
* when <code>null</code>, a regular {@link RaceColumnDTO} or {@link MetaLeaderboardRaceColumnDTO} will
|
||||
* be produced (depending on <code>isMetaLeaderboardColumn</code>) and initialized from the properties
|
||||
* passed; otherwise, a {@link RaceColumnInSeriesDTO} will be created.
|
||||
*/
|
||||
public RaceColumnDTO createRaceColumnDTO(String columnName, boolean isMedal, Double explicitFactor, String regattaName, String seriesName) {
|
||||
public RaceColumnDTO createRaceColumnDTO(String columnName, boolean isMedal, Double explicitFactor,
|
||||
String regattaName, String seriesName, boolean isMetaLeaderboardColumn) {
|
||||
final RaceColumnDTO raceColumnDTO;
|
||||
if (seriesName != null) {
|
||||
raceColumnDTO = new RaceColumnInSeriesDTO(seriesName, regattaName);
|
||||
} else {
|
||||
raceColumnDTO = new RaceColumnDTO();
|
||||
raceColumnDTO = isMetaLeaderboardColumn ? new MetaLeaderboardRaceColumnDTO() : new RaceColumnDTO();
|
||||
}
|
||||
fillRaceColumnDTO(raceColumnDTO, columnName, isMedal, explicitFactor);
|
||||
return raceColumnDTO;
|
||||
|
||||
+2
-73
@@ -1,10 +1,7 @@
|
||||
package com.sap.sailing.domain.common.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
|
||||
import com.sap.sailing.domain.common.TimingConstants;
|
||||
|
||||
/**
|
||||
* Master data about a single race that is to be transferred to the client.<p>
|
||||
@@ -12,7 +9,7 @@ import com.sap.sailing.domain.common.TimingConstants;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class RaceDTO extends NamedDTO {
|
||||
public class RaceDTO extends BasicRaceDTO {
|
||||
private static final long serialVersionUID = 2613189982608149975L;
|
||||
|
||||
public enum RaceLiveState { NOT_TRACKED, TRACKED, TRACKED_AND_LIVE, TRACKED_BUT_NOT_SCHEDULED };
|
||||
@@ -24,13 +21,10 @@ public class RaceDTO extends NamedDTO {
|
||||
*/
|
||||
public boolean isTracked;
|
||||
|
||||
public Date startOfRace;
|
||||
public Date endOfRace;
|
||||
public RaceStatusDTO status;
|
||||
|
||||
public PlacemarkOrderDTO places;
|
||||
|
||||
public TrackedRaceDTO trackedRace;
|
||||
public TrackedRaceStatisticsDTO trackedRaceStatistics;
|
||||
|
||||
private String regattaName;
|
||||
@@ -43,9 +37,8 @@ public class RaceDTO extends NamedDTO {
|
||||
}
|
||||
|
||||
public RaceDTO(RegattaAndRaceIdentifier raceIdentifier, TrackedRaceDTO trackedRace, boolean isCurrentlyTracked) {
|
||||
super(raceIdentifier.getRaceName());
|
||||
super(raceIdentifier, trackedRace);
|
||||
this.regattaName = raceIdentifier.getRegattaName();
|
||||
this.trackedRace = trackedRace;
|
||||
this.isTracked = isCurrentlyTracked;
|
||||
}
|
||||
|
||||
@@ -71,64 +64,15 @@ public class RaceDTO extends NamedDTO {
|
||||
return regattaName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link TrackedRace#isLive} for further explanation.
|
||||
* @param serverTimePointAsMillis
|
||||
* the time point (in server clock time) at which to determine whether the race is/was live
|
||||
* @return <code>true</code> if <code>serverTimePointAsMillis</code> is between (inclusively) the start and end time
|
||||
* point of the "live" interval as defined above.
|
||||
*/
|
||||
public boolean isLive(long serverTimePointAsMillis) {
|
||||
final Date startOfLivePeriod;
|
||||
final Date endOfLivePeriod;
|
||||
if (trackedRace == null || !trackedRace.hasGPSData || !trackedRace.hasWindData) {
|
||||
startOfLivePeriod = null;
|
||||
endOfLivePeriod = null;
|
||||
} else {
|
||||
if (startOfRace == null) {
|
||||
startOfLivePeriod = trackedRace.startOfTracking;
|
||||
} else {
|
||||
startOfLivePeriod = new Date(startOfRace.getTime() - TimingConstants.PRE_START_PHASE_DURATION_IN_MILLIS);
|
||||
}
|
||||
if (endOfRace == null) {
|
||||
if (trackedRace.timePointOfNewestEvent != null) {
|
||||
endOfLivePeriod = new Date(trackedRace.timePointOfNewestEvent.getTime()
|
||||
+ TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS);
|
||||
} else {
|
||||
endOfLivePeriod = null;
|
||||
}
|
||||
} else {
|
||||
endOfLivePeriod = new Date(endOfRace.getTime() + TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS);
|
||||
}
|
||||
}
|
||||
|
||||
// if an empty timepoint is given then take the start of the race
|
||||
if (serverTimePointAsMillis == 0) {
|
||||
serverTimePointAsMillis = startOfLivePeriod.getTime()+1;
|
||||
}
|
||||
|
||||
// whenLastTrackedRaceWasLive is null if there is no tracked race for fleet, or the tracked race hasn't started yet at the server time
|
||||
// when this DTO was assembled, or there were no GPS or wind data
|
||||
final boolean result =
|
||||
startOfLivePeriod != null &&
|
||||
endOfLivePeriod != null &&
|
||||
startOfLivePeriod.getTime() <= serverTimePointAsMillis &&
|
||||
serverTimePointAsMillis <= endOfLivePeriod.getTime();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((boatClass == null) ? 0 : boatClass.hashCode());
|
||||
result = prime * result + ((endOfRace == null) ? 0 : endOfRace.hashCode());
|
||||
result = prime * result + (isTracked ? 1231 : 1237);
|
||||
result = prime * result + ((places == null) ? 0 : places.hashCode());
|
||||
result = prime * result + ((regattaName == null) ? 0 : regattaName.hashCode());
|
||||
result = prime * result + ((startOfRace == null) ? 0 : startOfRace.hashCode());
|
||||
result = prime * result + ((status == null) ? 0 : status.hashCode());
|
||||
result = prime * result + ((trackedRace == null) ? 0 : trackedRace.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -146,11 +90,6 @@ public class RaceDTO extends NamedDTO {
|
||||
return false;
|
||||
} else if (!boatClass.equals(other.boatClass))
|
||||
return false;
|
||||
if (endOfRace == null) {
|
||||
if (other.endOfRace != null)
|
||||
return false;
|
||||
} else if (!endOfRace.equals(other.endOfRace))
|
||||
return false;
|
||||
if (isTracked != other.isTracked)
|
||||
return false;
|
||||
if (places == null) {
|
||||
@@ -163,21 +102,11 @@ public class RaceDTO extends NamedDTO {
|
||||
return false;
|
||||
} else if (!regattaName.equals(other.regattaName))
|
||||
return false;
|
||||
if (startOfRace == null) {
|
||||
if (other.startOfRace != null)
|
||||
return false;
|
||||
} else if (!startOfRace.equals(other.startOfRace))
|
||||
return false;
|
||||
if (status == null) {
|
||||
if (other.status != null)
|
||||
return false;
|
||||
} else if (!status.equals(other.status))
|
||||
return false;
|
||||
if (trackedRace == null) {
|
||||
if (other.trackedRace != null)
|
||||
return false;
|
||||
} else if (!trackedRace.equals(other.trackedRace))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -49,7 +49,8 @@ public class RaceLogFixedMarkPassingEventImpl extends RaceLogEventImpl implement
|
||||
|
||||
@Override
|
||||
public String getShortInfo() {
|
||||
return getInvolvedBoats().get(0).getName() + " at mark " + getZeroBasedIndexOfPassedWaypoint() + " at "
|
||||
return (getInvolvedBoats() == null || getInvolvedBoats().get(0) == null ? "Unknown" :
|
||||
getInvolvedBoats().get(0).getName()) + " at mark " + getZeroBasedIndexOfPassedWaypoint() + " at "
|
||||
+ getTimePointOfFixedPassing();
|
||||
}
|
||||
}
|
||||
+5
@@ -35,4 +35,9 @@ public class RaceLogDefineMarkEventImpl extends RaceLogEventImpl implements Race
|
||||
return mark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortInfo() {
|
||||
return mark.toString();
|
||||
}
|
||||
|
||||
}
|
||||
-3
@@ -75,7 +75,4 @@ public class MarkImpl extends NamedImpl implements Mark {
|
||||
public String toString() {
|
||||
return getId() + " " + (getColor() == null ? "" : (getColor() + " ")) + super.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Binary file not shown.
+4
-4
@@ -60,7 +60,7 @@ public class MultipleClassesInRegattaTest {
|
||||
httpAndHost
|
||||
+ "/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=cce678c8-97e6-11e0-9aed-406186cbf87c"),
|
||||
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings*/
|
||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
||||
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
||||
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
|
||||
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
||||
@@ -71,7 +71,7 @@ public class MultipleClassesInRegattaTest {
|
||||
httpAndHost
|
||||
+ "/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=11290bd6-97e7-11e0-9aed-406186cbf87c"),
|
||||
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings*/
|
||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
||||
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
||||
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
|
||||
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
||||
@@ -82,7 +82,7 @@ public class MultipleClassesInRegattaTest {
|
||||
httpAndHost
|
||||
+ "/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=39635b24-97e7-11e0-9aed-406186cbf87c"),
|
||||
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings*/
|
||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
||||
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
||||
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
|
||||
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
||||
@@ -93,7 +93,7 @@ public class MultipleClassesInRegattaTest {
|
||||
httpAndHost
|
||||
+ "/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=04498426-7dfd-11e0-8236-406186cbf87c"),
|
||||
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings*/
|
||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
||||
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
||||
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
|
||||
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ public class UnicodeCharactersInCompetitorNamesTest {
|
||||
+ TracTracConnectionConstants.PORT_STORED), new URI(
|
||||
"http://tracms.traclive.dk/update_course"),
|
||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l,
|
||||
/* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings*/
|
||||
/* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
||||
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
|
||||
EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, "tracTest", "tracTest", "", "",
|
||||
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
||||
|
||||
+15
-9
@@ -44,6 +44,7 @@ import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||
import com.sap.sailing.domain.tractracadapter.impl.DomainFactoryImpl;
|
||||
import com.sap.sailing.domain.tractracadapter.impl.RaceCourseReceiver;
|
||||
import com.sap.sailing.domain.tractracadapter.impl.Simulator;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.tractrac.model.lib.api.data.IPosition;
|
||||
@@ -95,7 +96,6 @@ public interface DomainFactory {
|
||||
* Fetch a race definition previously created by a call to {@link #getOrCreateRaceDefinitionAndTrackedRace}. If no such
|
||||
* race definition was created so far, the call blocks until such a definition is provided by a call to
|
||||
* {@link #getOrCreateRaceDefinitionAndTrackedRace}.
|
||||
* @param raceId TODO
|
||||
*/
|
||||
RaceDefinition getAndWaitForRaceDefinition(UUID raceId);
|
||||
|
||||
@@ -105,7 +105,6 @@ public interface DomainFactory {
|
||||
* A new {@link com.sap.sailing.domain.base.Regatta} is created if no event by
|
||||
* an equal name with a boat class with an equal name as the <code>event</code>'s
|
||||
* boat class exists yet.
|
||||
* @param trackedRegattaRegistry TODO
|
||||
*/
|
||||
com.sap.sailing.domain.base.Regatta getOrCreateDefaultRegatta(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
IRace race, TrackedRegattaRegistry trackedRegattaRegistry);
|
||||
@@ -134,27 +133,30 @@ public interface DomainFactory {
|
||||
* if <code>null</code>, all stored data until the "end of time" will be loaded that the event has
|
||||
* to provide, particularly for the mark positions which are stored per event, not per race; otherwise,
|
||||
* particularly the mark position loading will be constrained to this end time.
|
||||
* @param offsetToStartTimeOfSimulatedRace
|
||||
* if non-<code>null</code>, the {@link Simulator} will be used with this duration as start offset
|
||||
* @param windStore
|
||||
* Provides the capability to obtain the {@link WindTrack}s for the different wind sources. A trivial
|
||||
* implementation is {@link EmptyWindStore} which simply provides new, empty tracks. This is always
|
||||
* available but loses track of the wind, e.g., during server restarts.
|
||||
* @param raceLogResolver TODO
|
||||
*/
|
||||
TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
|
||||
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
|
||||
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
||||
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException, SubscriberInitializationException;
|
||||
|
||||
/**
|
||||
* Same as {@link #createRaceTracker(URL, URI, URI, URI, TimePoint, TimePoint, WindStore, TrackedRegattaRegistry)}, only that
|
||||
* a predefined {@link Regatta} is used to hold the resulting races.
|
||||
* @param raceLogResolver TODO
|
||||
* Same as {@link #createRaceTracker(URL, URI, URI, URI, TimePoint, TimePoint, WindStore, TrackedRegattaRegistry)},
|
||||
* only that a predefined {@link Regatta} is used to hold the resulting races.
|
||||
*
|
||||
* @param offsetToStartTimeOfSimulatedRace
|
||||
* if non-<code>null</code>, the {@link Simulator} will be used with this duration as start offset
|
||||
*/
|
||||
RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
|
||||
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
|
||||
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
||||
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
|
||||
@@ -262,9 +264,13 @@ public interface DomainFactory {
|
||||
|
||||
Util.Pair<Iterable<com.sap.sailing.domain.base.Competitor>, BoatClass> getCompetitorsAndDominantBoatClass(IRace race);
|
||||
|
||||
/**
|
||||
* @param offsetToStartTimeOfSimulatedRace
|
||||
* if non-<code>null</code>, the {@link Simulator} will be used with this duration as start offset
|
||||
*/
|
||||
RaceTrackingConnectivityParameters createTrackingConnectivityParameters(URL paramURL, URI liveURI, URI storedURI,
|
||||
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility);
|
||||
/**
|
||||
* Removes all knowledge about <code>tractracRace</code> which includes removing it from the race cache, from the
|
||||
|
||||
+5
-2
@@ -17,6 +17,8 @@ import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||
import com.sap.sailing.domain.tracking.RaceHandle;
|
||||
import com.sap.sailing.domain.tracking.TrackerManager;
|
||||
import com.sap.sailing.domain.tracking.WindStore;
|
||||
import com.sap.sailing.domain.tractracadapter.impl.Simulator;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
@@ -65,12 +67,13 @@ public interface TracTracAdapter {
|
||||
* created, with a single default series and a single default fleet. If a valid {@link RegattaIdentifier}
|
||||
* is specified, a regatta lookup is performed with that identifier; if the regatta is found, it is used
|
||||
* to add the races to. Otherwise, a default regatta as described above will be created and used.
|
||||
* @param raceStatus
|
||||
* @param offsetToStartTimeOfSimulatedRace
|
||||
* if non-<code>null</code>, the {@link Simulator} will be used with this duration as start offset
|
||||
*/
|
||||
RaceHandle addTracTracRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, URL paramURL,
|
||||
URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint trackingStartTime,
|
||||
TimePoint trackingEndTime, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
long timeoutForReceivingRaceDefinitionInMilliseconds, boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm,
|
||||
long timeoutForReceivingRaceDefinitionInMilliseconds, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm,
|
||||
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility)
|
||||
throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
|
||||
|
||||
|
||||
+7
-6
@@ -74,6 +74,7 @@ import com.sap.sailing.domain.tractracadapter.ReceiverType;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracConfiguration;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracControlPoint;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
@@ -652,27 +653,27 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
@Override
|
||||
public TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
|
||||
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
|
||||
String tracTracPassword, String raceStatus, String raceVisibility,
|
||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws MalformedURLException, FileNotFoundException,
|
||||
URISyntaxException, CreateModelException, SubscriberInitializationException {
|
||||
return new TracTracRaceTrackerImpl(this, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
|
||||
endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
|
||||
endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
|
||||
gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI,
|
||||
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
|
||||
String tracTracPassword, String raceStatus, String raceVisibility,
|
||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
||||
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
|
||||
SubscriberInitializationException {
|
||||
return new TracTracRaceTrackerImpl(regatta, this, paramURL, liveURI, storedURI, courseDesignUpdateURI,
|
||||
startOfTracking, endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore,
|
||||
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
|
||||
regattaLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus,
|
||||
raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||
}
|
||||
@@ -690,11 +691,11 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
@Override
|
||||
public RaceTrackingConnectivityParameters createTrackingConnectivityParameters(URL paramURL, URI liveURI,
|
||||
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
|
||||
long delayToLiveInMillis, boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||
RegattaLogStore regattaLogStore, String tracTracUsername, String tracTracPassword, String raceStatus,
|
||||
String raceVisibility) {
|
||||
return new RaceTrackingConnectivityParametersImpl(paramURL, liveURI, storedURI, courseDesignUpdateURI,
|
||||
startOfTracking, endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore,
|
||||
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
|
||||
regattaLogStore, this, tracTracUsername, tracTracPassword, raceStatus, raceVisibility);
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -16,6 +16,7 @@ import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||
import com.sap.sailing.domain.tracking.WindStore;
|
||||
import com.sap.sailing.domain.tractracadapter.DomainFactory;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.tractrac.model.lib.api.event.CreateModelException;
|
||||
import com.tractrac.subscription.lib.api.SubscriberInitializationException;
|
||||
@@ -31,7 +32,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
|
||||
private final RegattaLogStore regattaLogStore;
|
||||
private final DomainFactory domainFactory;
|
||||
private final long delayToLiveInMillis;
|
||||
private final boolean simulateWithStartTimeNow;
|
||||
private final Duration offsetToStartTimeOfSimulatedRace;
|
||||
private final String tracTracUsername;
|
||||
private final String tracTracPassword;
|
||||
private final String raceStatus;
|
||||
@@ -40,7 +41,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
|
||||
|
||||
public RaceTrackingConnectivityParametersImpl(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
|
||||
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
DomainFactory domainFactory, String tracTracUsername, String tracTracPassword, String raceStatus,
|
||||
String raceVisibility) {
|
||||
super();
|
||||
@@ -52,7 +53,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
|
||||
this.endOfTracking = endOfTracking;
|
||||
this.delayToLiveInMillis = delayToLiveInMillis;
|
||||
this.domainFactory = domainFactory;
|
||||
this.simulateWithStartTimeNow = simulateWithStartTimeNow;
|
||||
this.offsetToStartTimeOfSimulatedRace = offsetToStartTimeOfSimulatedRace;
|
||||
this.raceLogStore = raceLogStore;
|
||||
this.regattaLogStore = regattaLogStore;
|
||||
this.tracTracUsername = tracTracUsername;
|
||||
@@ -67,7 +68,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
|
||||
GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) throws MalformedURLException, FileNotFoundException, URISyntaxException,
|
||||
CreateModelException, SubscriberInitializationException {
|
||||
RaceTracker tracker = domainFactory.createRaceTracker(paramURL, liveURI, storedURI, courseDesignUpdateURI,
|
||||
startOfTracking, endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore,
|
||||
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
|
||||
regattaLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus,
|
||||
raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||
return tracker;
|
||||
@@ -77,7 +78,7 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
|
||||
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
|
||||
WindStore windStore, GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) throws Exception {
|
||||
RaceTracker tracker = domainFactory.createRaceTracker(regatta, paramURL, liveURI, storedURI,
|
||||
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm,
|
||||
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm,
|
||||
raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus,
|
||||
raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||
return tracker;
|
||||
|
||||
+5
-6
@@ -4,7 +4,6 @@ import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||
import com.sap.sailing.domain.tractracadapter.DomainFactory;
|
||||
@@ -57,13 +56,13 @@ public class RawPositionReceiver extends AbstractReceiverWithQueue<IRaceCompetit
|
||||
IRace race = event.getA().getRace();
|
||||
DynamicTrackedRace trackedRace = getTrackedRace(race);
|
||||
if (trackedRace != null) {
|
||||
GPSFixMoving fix = getDomainFactory().createGPSFixMoving(event.getB());
|
||||
if (getSimulator() != null) {
|
||||
fix = new GPSFixMovingImpl(fix.getPosition(), getSimulator().delay(
|
||||
fix.getTimePoint()), fix.getSpeed());
|
||||
}
|
||||
final GPSFixMoving fix = getDomainFactory().createGPSFixMoving(event.getB());
|
||||
Competitor competitor = getDomainFactory().getOrCreateCompetitor(event.getA().getCompetitor());
|
||||
if (getSimulator() != null) {
|
||||
getSimulator().scheduleCompetitorPosition(competitor, fix);
|
||||
} else {
|
||||
trackedRace.recordFix(competitor, fix);
|
||||
}
|
||||
} else {
|
||||
logger.warning("Couldn't find tracked race for race " + race.getName()
|
||||
+ ". Dropping raw position event " + event);
|
||||
|
||||
+40
-12
@@ -24,7 +24,9 @@ import com.sap.sailing.domain.tracking.WindStore;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class Simulator {
|
||||
@@ -33,13 +35,15 @@ public class Simulator {
|
||||
private DynamicTrackedRace trackedRace;
|
||||
private final WindStore windStore;
|
||||
private boolean stopped;
|
||||
private long advanceInMillis = -1;
|
||||
private Duration advanceInMillis = Duration.NULL.minus(1);
|
||||
private Timer timer = new Timer("Timer for TracTrac Simulator");
|
||||
private final Duration offsetToStart;
|
||||
|
||||
public Simulator(WindStore windStore) {
|
||||
public Simulator(WindStore windStore, Duration offsetToStart) {
|
||||
super();
|
||||
assert windStore != null;
|
||||
this.windStore = windStore;
|
||||
this.offsetToStart = offsetToStart;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +73,7 @@ public class Simulator {
|
||||
/**
|
||||
* This is what everybody is waiting for :-). Notifies all waiters.
|
||||
*/
|
||||
public synchronized void setAdvanceInMillis(long advanceInMillis) {
|
||||
public synchronized void setAdvanceInMillis(Duration advanceInMillis) {
|
||||
this.advanceInMillis = advanceInMillis;
|
||||
notifyAll();
|
||||
}
|
||||
@@ -114,7 +118,7 @@ public class Simulator {
|
||||
* Waits until {@link #advanceInMillis} is set to something not equal to -1 which is its initial value. Unblocked by
|
||||
* {@link #setAdvanceInMillis(long)}.
|
||||
*/
|
||||
private synchronized long getAdvanceInMillis() {
|
||||
private synchronized Duration getAdvance() {
|
||||
while (!isAdvanceInMillisSet()) {
|
||||
try {
|
||||
wait(2000); // wait for two seconds, then re-evaluate whether there is a start time
|
||||
@@ -126,6 +130,16 @@ public class Simulator {
|
||||
return advanceInMillis;
|
||||
}
|
||||
|
||||
private Duration getOffsetToStart() {
|
||||
final Duration result;
|
||||
if (offsetToStart != null) {
|
||||
result = offsetToStart;
|
||||
} else {
|
||||
result = Duration.NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms <code>timed</code>'s time point according to this simulator's delay and waits roughly until this time
|
||||
* has passed. Then, returns the adjusted time point which therefore should roughly equal "now."
|
||||
@@ -157,12 +171,12 @@ public class Simulator {
|
||||
* Like {@link #delay}, only that it doesn't wait until <code>timePoint</code> is reached in wall time.
|
||||
*/
|
||||
public TimePoint advance(TimePoint timePoint) {
|
||||
return new MillisecondsTimePoint(timePoint.asMillis()+getAdvanceInMillis());
|
||||
return timePoint.plus(getAdvance());
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@link #advanceInMillis} is already set to a non-negative value, it is left alone, and
|
||||
* {@link #delay(TimePoint)} is called. Otherwise, <code>time</code> is taken to be the original start time of the
|
||||
* {@link #advance(TimePoint)} is called. Otherwise, <code>time</code> is taken to be the original start time of the
|
||||
* race which is then used to compute {@link #advanceInMillis} such that
|
||||
* <code>time.asMillis() + advanceInMillis == System.currentTimeMillis()</code>.
|
||||
*/
|
||||
@@ -183,13 +197,13 @@ public class Simulator {
|
||||
if (isAdvanceInMillisSet()) {
|
||||
return advance(time);
|
||||
} else {
|
||||
setAdvanceInMillis(System.currentTimeMillis() - time.asMillis());
|
||||
setAdvanceInMillis(new MillisecondsDurationImpl(MillisecondsTimePoint.now().minus(time.asMillis()).plus(getOffsetToStart()).asMillis()));
|
||||
return advance(time);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAdvanceInMillisSet() {
|
||||
return advanceInMillis != -1;
|
||||
return !advanceInMillis.equals(Duration.NULL.minus(1));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,21 +252,35 @@ public class Simulator {
|
||||
// deliver an empty list now
|
||||
trackedRace.updateMarkPassings(competitor, markPassings);
|
||||
}
|
||||
}
|
||||
|
||||
public void scheduleCompetitorPosition(final Competitor competitor, GPSFixMoving competitorFix) {
|
||||
final RecordGPSFix<Competitor> recorder = (c, f)->trackedRace.recordFix(c, f);
|
||||
scheduleFixRecording(competitor, competitorFix, recorder);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private static interface RecordGPSFix<T> {
|
||||
void recordFix(T objectForFix, GPSFixMoving fix);
|
||||
}
|
||||
|
||||
public void scheduleMarkPosition(final Mark mark, GPSFixMoving markFix) {
|
||||
final TimePoint transformedTimepoint = advance(markFix.getTimePoint());
|
||||
final GPSFixMoving transformedMarkFix = new GPSFixMovingImpl(markFix.getPosition(), transformedTimepoint, markFix.getSpeed());
|
||||
final RecordGPSFix<Mark> recorder = (m, f)->trackedRace.recordFix(mark, f);
|
||||
scheduleFixRecording(mark, markFix, recorder);
|
||||
}
|
||||
|
||||
private <T> void scheduleFixRecording(final T object, GPSFixMoving fix, final RecordGPSFix<T> recorder) {
|
||||
final TimePoint transformedTimepoint = advance(fix.getTimePoint());
|
||||
final GPSFixMoving transformedMarkFix = new GPSFixMovingImpl(fix.getPosition(), transformedTimepoint, fix.getSpeed());
|
||||
long waitTime = getWaitTimeInMillisUntil(transformedMarkFix.getTimePoint());
|
||||
if (waitTime <= 0) {
|
||||
trackedRace.recordFix(mark, transformedMarkFix);
|
||||
recorder.recordFix(object, transformedMarkFix);
|
||||
} else {
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
trackedRace.recordFix(mark, transformedMarkFix);
|
||||
recorder.recordFix(object, transformedMarkFix);
|
||||
} catch (Exception e) {
|
||||
logger.throwing(Simulator.class.getName(), "scheduleMarkPosition", e);
|
||||
}
|
||||
|
||||
+4
-3
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.tractracadapter.JSONService;
|
||||
import com.sap.sailing.domain.tractracadapter.RaceRecord;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracAdapter;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracConfiguration;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
@@ -56,7 +57,7 @@ public class TracTracAdapterImpl implements TracTracAdapter {
|
||||
getTracTracDomainFactory().createTrackingConnectivityParameters(paramURL, liveURI, storedURI,
|
||||
courseDesignUpdateURI,
|
||||
/* startOfTracking */null,
|
||||
/* endOfTracking */null, delayToLiveInMillis, /* simulateWithStartTimeNow */false, /* ignoreTracTracMarkPassings */ false,
|
||||
/* endOfTracking */null, delayToLiveInMillis, /* offsetToStartTimeOfSimulatedRace */null, /* ignoreTracTracMarkPassings */ false,
|
||||
raceLogStore, regattaLogStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility),
|
||||
timeoutInMilliseconds);
|
||||
}
|
||||
@@ -65,13 +66,13 @@ public class TracTracAdapterImpl implements TracTracAdapter {
|
||||
public RaceHandle addTracTracRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, URL paramURL,
|
||||
URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
|
||||
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, long timeoutInMilliseconds,
|
||||
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword, String raceStatus,
|
||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword, String raceStatus,
|
||||
String raceVisibility) throws Exception {
|
||||
return trackerManager.addRace(
|
||||
regattaToAddTo,
|
||||
getTracTracDomainFactory().createTrackingConnectivityParameters(paramURL, liveURI, storedURI,
|
||||
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
|
||||
simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, tracTracUsername, tracTracPassword,
|
||||
offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, tracTracUsername, tracTracPassword,
|
||||
raceStatus, raceVisibility), timeoutInMilliseconds);
|
||||
}
|
||||
|
||||
|
||||
+13
-12
@@ -49,6 +49,7 @@ import com.sap.sailing.domain.tractracadapter.DomainFactory;
|
||||
import com.sap.sailing.domain.tractracadapter.Receiver;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracConnectionConstants;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.tractrac.model.lib.api.ModelLocator;
|
||||
@@ -253,26 +254,26 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
||||
*/
|
||||
protected TracTracRaceTrackerImpl(DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI,
|
||||
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
|
||||
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
||||
throws URISyntaxException, MalformedURLException, FileNotFoundException, CreateModelException,
|
||||
SubscriberInitializationException {
|
||||
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), domainFactory, paramURL, liveURI,
|
||||
storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
|
||||
simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername,
|
||||
offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername,
|
||||
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||
}
|
||||
|
||||
private TracTracRaceTrackerImpl(IRace tractracRace, DomainFactory domainFactory, URL paramURL, URI liveURI,
|
||||
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
|
||||
long delayToLiveInMillis, boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
|
||||
String tracTracPassword, String raceStatus, String raceVisibility,
|
||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException, MalformedURLException,
|
||||
FileNotFoundException, SubscriberInitializationException {
|
||||
this(tractracRace, null, domainFactory, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
|
||||
endOfTracking, delayToLiveInMillis, simulateWithStartTimeNow, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
|
||||
endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
|
||||
gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||
}
|
||||
|
||||
@@ -284,14 +285,14 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
||||
*/
|
||||
protected TracTracRaceTrackerImpl(Regatta regatta, DomainFactory domainFactory, URL paramURL, URI liveURI,
|
||||
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
|
||||
long delayToLiveInMillis, boolean simulateWithStartTimeNow, boolean ignoreTracTracMarkPassings, RaceLogStore raceLogStore,
|
||||
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean ignoreTracTracMarkPassings, RaceLogStore raceLogStore,
|
||||
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
|
||||
String tracTracPassword, String raceStatus, String raceVisibility,
|
||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException,
|
||||
MalformedURLException, FileNotFoundException, CreateModelException, SubscriberInitializationException {
|
||||
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), regatta, domainFactory, paramURL,
|
||||
liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
|
||||
simulateWithStartTimeNow, ignoreTracTracMarkPassings, raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername,
|
||||
offsetToStartTimeOfSimulatedRace, ignoreTracTracMarkPassings, raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername,
|
||||
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||
}
|
||||
|
||||
@@ -300,15 +301,15 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
||||
* @param regatta
|
||||
* if <code>null</code>, then <code>domainFactory.getOrCreateRegatta(tractracEvent)</code> will be used
|
||||
* to obtain a default regatta
|
||||
* @param simulateWithStartTimeNow
|
||||
* if <code>true</code>, the connector will adjust the time stamps of all events received such that the
|
||||
* @param offsetToStartTimeOfSimulatedRace
|
||||
* if not <code>null</code>, the connector will adjust the time stamps of all events received such that the
|
||||
* first mark passing for the first waypoint will be set to "now." It will delay the forwarding of all
|
||||
* events received such that they seem to be sent in "real-time." So, more or less the time points
|
||||
* events received such that they seem to be sent in "real-time" + <code>offsetToStartTimeOfSimulatedRace</code> So, more or less the time points
|
||||
* attached to the events sent to the receivers will again approximate the wall time.
|
||||
*/
|
||||
private TracTracRaceTrackerImpl(IRace tractracRace, final Regatta regatta, DomainFactory domainFactory,
|
||||
URL paramURL, URI liveURI, URI storedURI, URI tracTracUpdateURI, TimePoint startOfTracking,
|
||||
TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm,
|
||||
TimePoint endOfTracking, long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm,
|
||||
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore,
|
||||
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility,
|
||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException, MalformedURLException,
|
||||
@@ -323,8 +324,8 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
||||
this.gpsFixStore = gpsFixStore;
|
||||
this.domainFactory = domainFactory;
|
||||
this.lastProgressPerID = new HashMap<>();
|
||||
if (simulateWithStartTimeNow) {
|
||||
simulator = new Simulator(windStore);
|
||||
if (offsetToStartTimeOfSimulatedRace != null) {
|
||||
simulator = new Simulator(windStore, offsetToStartTimeOfSimulatedRace);
|
||||
// don't write the transformed wind fixes into the DB again... see also bug 1974
|
||||
this.windStore = EmptyWindStore.INSTANCE;
|
||||
} else {
|
||||
|
||||
@@ -43,4 +43,6 @@ public interface Course extends CourseBase {
|
||||
void update(Iterable<Util.Pair<ControlPoint, PassingInstruction>> newControlPoints, DomainFactory baseDomainFactory) throws PatchFailedException;
|
||||
|
||||
int getNumberOfWaypoints();
|
||||
|
||||
Leg getLeg(int zeroBasedIndexOfWaypoint);
|
||||
}
|
||||
@@ -246,6 +246,11 @@ public class CourseImpl extends NamedImpl implements Course {
|
||||
return waypoints.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Leg getLeg(int zeroBasedIndexOfWaypoint) {
|
||||
return legs.get(zeroBasedIndexOfWaypoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
lockForRead();
|
||||
|
||||
+33
-3
@@ -42,6 +42,7 @@ import com.sap.sailing.domain.base.RaceColumnInSeries;
|
||||
import com.sap.sailing.domain.base.RaceColumnListener;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
@@ -51,12 +52,15 @@ import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.dto.BasicRaceDTO;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.domain.common.dto.FleetDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardEntryDTO;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
|
||||
import com.sap.sailing.domain.common.dto.LegEntryDTO;
|
||||
import com.sap.sailing.domain.common.dto.MetaLeaderboardRaceColumnDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceDTO;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
@@ -68,6 +72,7 @@ import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCache;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuseCache;
|
||||
import com.sap.sailing.domain.leaderboard.caching.LiveLeaderboardUpdater;
|
||||
import com.sap.sailing.domain.leaderboard.meta.MetaLeaderboardColumn;
|
||||
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.CompetitorRankingInfo;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
@@ -1215,6 +1220,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
this.getScoreCorrection() == null ? null : this.getScoreCorrection().getComment(),
|
||||
this.getScoringScheme() == null ? null : this.getScoringScheme().getType(), this
|
||||
.getScoringScheme().isHigherBetter(), new UUIDGenerator(), addOverallDetails);
|
||||
result.type = getLeaderboardType();
|
||||
result.competitors = new ArrayList<CompetitorDTO>();
|
||||
result.name = this.getName();
|
||||
result.competitorDisplayNames = new HashMap<CompetitorDTO, String>();
|
||||
@@ -1225,9 +1231,15 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
// futures to finish:
|
||||
Map<RaceColumn, FutureTask<List<CompetitorDTO>>> competitorsFromBestToWorstTasks = new HashMap<>();
|
||||
for (final RaceColumn raceColumn : this.getRaceColumns()) {
|
||||
result.createEmptyRaceColumn(raceColumn.getName(), raceColumn.isMedalRace(),
|
||||
boolean isMetaLeaderboardColumn = raceColumn instanceof MetaLeaderboardColumn;
|
||||
RaceColumnDTO raceColumnDTO = result.createEmptyRaceColumn(raceColumn.getName(), raceColumn.isMedalRace(),
|
||||
raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getRegatta().getName() : null,
|
||||
raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getSeries().getName() : null);
|
||||
raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getSeries().getName() : null,
|
||||
isMetaLeaderboardColumn);
|
||||
if (isMetaLeaderboardColumn && raceColumnDTO instanceof MetaLeaderboardRaceColumnDTO) {
|
||||
calculateRacesMetadata((MetaLeaderboardColumn) raceColumn, (MetaLeaderboardRaceColumnDTO) raceColumnDTO,
|
||||
trackedRegattaRegistry, baseDomainFactory);
|
||||
}
|
||||
for (Fleet fleet : raceColumn.getFleets()) {
|
||||
RegattaAndRaceIdentifier raceIdentifier = null;
|
||||
RaceDTO race = null;
|
||||
@@ -1243,7 +1255,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
result.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), raceColumn.getFactor(),
|
||||
raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getRegatta().getName() : null,
|
||||
raceColumn instanceof RaceColumnInSeries ? ((RaceColumnInSeries) raceColumn).getSeries().getName() : null,
|
||||
fleetDTO, raceColumn.isMedalRace(), raceIdentifier, race);
|
||||
fleetDTO, raceColumn.isMedalRace(), raceIdentifier, race, isMetaLeaderboardColumn);
|
||||
}
|
||||
FutureTask<List<CompetitorDTO>> task = new FutureTask<List<CompetitorDTO>>(
|
||||
() -> baseDomainFactory.getCompetitorDTOList(AbstractSimpleLeaderboardImpl.this.getCompetitorsFromBestToWorst(raceColumn, timePoint)));
|
||||
@@ -1357,6 +1369,21 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
return result;
|
||||
}
|
||||
|
||||
private void calculateRacesMetadata(MetaLeaderboardColumn metaLeaderboardColumn, MetaLeaderboardRaceColumnDTO columnDTO,
|
||||
TrackedRegattaRegistry trackedRegattaRegistry, final DomainFactory baseDomainFactory) {
|
||||
for (final RaceColumn raceColumn : metaLeaderboardColumn.getLeaderboard().getRaceColumns()) {
|
||||
for (Fleet fleet : raceColumn.getFleets()) {
|
||||
TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
|
||||
if (trackedRace != null) {
|
||||
String regattaName = trackedRace.getTrackedRegatta().getRegatta().getName();
|
||||
String raceName = trackedRace.getRace().getName();
|
||||
RegattaAndRaceIdentifier raceIdentifier = new RegattaNameAndRaceName(regattaName, raceName);
|
||||
columnDTO.addRace(new BasicRaceDTO(raceIdentifier, baseDomainFactory.createTrackedRaceDTO(trackedRace)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addOverallDetailsToRow(final TimePoint timePoint,
|
||||
final Competitor competitor, LeaderboardRowDTO row) throws NoWindException {
|
||||
final com.sap.sse.common.Util.Pair<GPSFixMoving, Speed> maximumSpeedOverGround = this.getMaximumSpeedOverGround(competitor, timePoint);
|
||||
@@ -1904,4 +1931,7 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
public NumberOfCompetitorsInLeaderboardFetcher getNumberOfCompetitorsInLeaderboardFetcher() {
|
||||
return new NumberOfCompetitorsFetcherImpl();
|
||||
}
|
||||
|
||||
protected abstract LeaderboardType getLeaderboardType();
|
||||
|
||||
}
|
||||
+6
@@ -19,6 +19,7 @@ import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnListener;
|
||||
import com.sap.sailing.domain.base.impl.AbstractRaceExecutionOrderProvider;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleRaceColumn;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
@@ -333,4 +334,9 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LeaderboardType getLeaderboardType() {
|
||||
return LeaderboardType.FlexibleLeaderboard;
|
||||
}
|
||||
}
|
||||
+6
@@ -14,6 +14,7 @@ import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.impl.RaceColumnInSeriesImpl;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.ResultDiscardingRule;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
@@ -114,4 +115,9 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R
|
||||
public IsRegattaLike getRegattaLike() {
|
||||
return regatta;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LeaderboardType getLeaderboardType() {
|
||||
return LeaderboardType.RegattaLeaderboard;
|
||||
}
|
||||
}
|
||||
+6
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
|
||||
@@ -61,4 +62,9 @@ public class FlexibleMetaLeaderboard extends AbstractMetaLeaderboard {
|
||||
public CourseArea getDefaultCourseArea() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LeaderboardType getLeaderboardType() {
|
||||
return LeaderboardType.FlexibleMetaLeaderboard;
|
||||
}
|
||||
}
|
||||
+6
@@ -6,6 +6,7 @@ import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceColumnListener;
|
||||
import com.sap.sailing.domain.base.impl.TrackedRaces;
|
||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroupListener;
|
||||
@@ -89,4 +90,9 @@ public class LeaderboardGroupMetaLeaderboard extends AbstractMetaLeaderboard imp
|
||||
public CourseArea getDefaultCourseArea() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LeaderboardType getLeaderboardType() {
|
||||
return LeaderboardType.RegattaMetaLeaderboard;
|
||||
}
|
||||
}
|
||||
Executable → Regular
+26
-23
@@ -13,7 +13,6 @@ import java.util.ConcurrentModificationException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
@@ -154,6 +153,7 @@ import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.concurrent.LockUtil;
|
||||
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||
import com.sap.sse.util.IdentityWrapper;
|
||||
import com.sap.sse.util.SmartFutureCache;
|
||||
import com.sap.sse.util.SmartFutureCache.AbstractCacheUpdater;
|
||||
import com.sap.sse.util.SmartFutureCache.EmptyUpdateInterval;
|
||||
@@ -183,7 +183,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
* By default, all wind sources are used, none are excluded. However, e.g., for performance reasons, particular wind
|
||||
* sources such as the track-based estimation wind source, may be excluded by adding them to this set.
|
||||
*/
|
||||
private final Set<WindSource> windSourcesToExclude;
|
||||
private final ConcurrentHashMap<WindSource, TrackedRaceImpl> windSourcesToExclude;
|
||||
|
||||
/**
|
||||
* Keeps the oldest timestamp that is fed into this tracked race, either from a boat fix, a mark fix, a race
|
||||
@@ -269,7 +269,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
*/
|
||||
private transient SmartFutureCache<Competitor, com.sap.sse.common.Util.Triple<TimePoint, TimePoint, List<Maneuver>>, EmptyUpdateInterval> maneuverCache;
|
||||
|
||||
private transient Map<TimePoint, Future<Wind>> directionFromStartToNextMarkCache;
|
||||
private transient ConcurrentHashMap<TimePoint, Future<Wind>> directionFromStartToNextMarkCache;
|
||||
|
||||
protected final MarkPassingCalculator markPassingCalculator;
|
||||
|
||||
@@ -354,7 +354,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
*/
|
||||
private final NamedReentrantReadWriteLock loadingFromGPSFixStoreLock;
|
||||
|
||||
private final Map<Iterable<MarkPassing>, NamedReentrantReadWriteLock> locksForMarkPassings;
|
||||
private final ConcurrentHashMap<IdentityWrapper<Iterable<MarkPassing>>, NamedReentrantReadWriteLock> locksForMarkPassings;
|
||||
|
||||
/**
|
||||
* Caches wind requests for a few seconds to accelerate access in live mode
|
||||
@@ -412,7 +412,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
rankingMetric = rankingMetricConstructor.apply(this);
|
||||
raceStates = new WeakHashMap<>();
|
||||
shortTimeWindCache = new ShortTimeWindCache(this, millisecondsOverWhichToAverageWind / 2);
|
||||
locksForMarkPassings = new IdentityHashMap<>();
|
||||
locksForMarkPassings = new ConcurrentHashMap<IdentityWrapper<Iterable<MarkPassing>>, NamedReentrantReadWriteLock>();
|
||||
attachedRaceLogs = new ConcurrentHashMap<>();
|
||||
attachedRegattaLogs = new ConcurrentHashMap<>();
|
||||
attachedRaceExecutionOrderProviders = new ConcurrentHashMap<>();
|
||||
@@ -424,8 +424,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
+ race.getName(), /* fair */ false);
|
||||
this.cacheInvalidationTimerLock = new Object();
|
||||
this.updateCount = 0;
|
||||
this.windSourcesToExclude = new HashSet<WindSource>();
|
||||
this.directionFromStartToNextMarkCache = new HashMap<TimePoint, Future<Wind>>();
|
||||
this.windSourcesToExclude = new ConcurrentHashMap<>();
|
||||
this.directionFromStartToNextMarkCache = new ConcurrentHashMap<TimePoint, Future<Wind>>();
|
||||
this.millisecondsOverWhichToAverageSpeed = millisecondsOverWhichToAverageSpeed;
|
||||
this.delayToLiveInMillis = delayToLiveInMillis;
|
||||
this.startToNextMarkCacheInvalidationListeners = new ConcurrentHashMap<Mark, TrackedRaceImpl.StartToNextMarkCacheInvalidationListener>();
|
||||
@@ -624,7 +624,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
gpsFixStore = EmptyGPSFixStore.INSTANCE;
|
||||
competitorRankings = createCompetitorRankingsCache();
|
||||
competitorRankingsLocks = createCompetitorRankingsLockMap();
|
||||
directionFromStartToNextMarkCache = new HashMap<TimePoint, Future<Wind>>();
|
||||
directionFromStartToNextMarkCache = new ConcurrentHashMap<>();
|
||||
crossTrackErrorCache = new CrossTrackErrorCache(this);
|
||||
crossTrackErrorCache.invalidate();
|
||||
maneuverCache = createManeuverCache();
|
||||
@@ -1146,11 +1146,11 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
int indexOfWaypoint = getRace().getCourse().getIndexOfWaypoint(startOfLeg);
|
||||
if (indexOfWaypoint == -1) {
|
||||
throw new IllegalArgumentException("Waypoint " + startOfLeg + " not found in " + getRace().getCourse());
|
||||
} else if (indexOfWaypoint == Util.size(getRace().getCourse().getWaypoints()) - 1) {
|
||||
} else if (indexOfWaypoint == getRace().getCourse().getNumberOfWaypoints() - 1) {
|
||||
throw new IllegalArgumentException("Waypoint " + startOfLeg + " isn't start of any leg in "
|
||||
+ getRace().getCourse());
|
||||
}
|
||||
return trackedLegs.get(race.getCourse().getLegs().get(indexOfWaypoint));
|
||||
return trackedLegs.get(race.getCourse().getLeg(indexOfWaypoint));
|
||||
} finally {
|
||||
getRace().getCourse().unlockAfterRead();
|
||||
}
|
||||
@@ -1679,25 +1679,21 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
|
||||
@Override
|
||||
public Set<WindSource> getWindSourcesToExclude() {
|
||||
synchronized (windSourcesToExclude) {
|
||||
return Collections.unmodifiableSet(windSourcesToExclude);
|
||||
}
|
||||
return Collections.unmodifiableSet(windSourcesToExclude.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWindSourcesToExclude(Iterable<? extends WindSource> windSourcesToExclude) {
|
||||
Set<WindSource> old = new HashSet<>(this.windSourcesToExclude);
|
||||
synchronized (this.windSourcesToExclude) {
|
||||
Set<WindSource> old = new HashSet<>(getWindSourcesToExclude());
|
||||
LockUtil.lockForRead(getSerializationLock());
|
||||
try {
|
||||
this.windSourcesToExclude.clear();
|
||||
for (WindSource windSourceToExclude : windSourcesToExclude) {
|
||||
this.windSourcesToExclude.add(windSourceToExclude);
|
||||
this.windSourcesToExclude.put(windSourceToExclude, this);
|
||||
}
|
||||
} finally {
|
||||
LockUtil.unlockAfterRead(getSerializationLock());
|
||||
}
|
||||
}
|
||||
if (!old.equals(this.windSourcesToExclude)) {
|
||||
clearAllCachesExceptManeuvers();
|
||||
triggerManeuverCacheRecalculationForAllCompetitors();
|
||||
@@ -1742,6 +1738,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
public Wind getDirectionFromStartToNextMark(final TimePoint at) {
|
||||
Future<Wind> future;
|
||||
FutureTask<Wind> newFuture = null;
|
||||
future = directionFromStartToNextMarkCache.get(at);
|
||||
if (future == null) {
|
||||
synchronized (directionFromStartToNextMarkCache) {
|
||||
future = directionFromStartToNextMarkCache.get(at);
|
||||
if (future == null) {
|
||||
@@ -1768,6 +1766,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
directionFromStartToNextMarkCache.put(at, newFuture);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newFuture != null) {
|
||||
newFuture.run();
|
||||
future = newFuture;
|
||||
@@ -2062,16 +2061,20 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
}
|
||||
|
||||
protected NamedReentrantReadWriteLock getMarkPassingsLock(Iterable<MarkPassing> markPassings) {
|
||||
synchronized (locksForMarkPassings) {
|
||||
NamedReentrantReadWriteLock lock = locksForMarkPassings.get(markPassings);
|
||||
final IdentityWrapper<Iterable<MarkPassing>> markPassingsIdentity = new IdentityWrapper<>(markPassings);
|
||||
NamedReentrantReadWriteLock lock = locksForMarkPassings.get(markPassingsIdentity);
|
||||
if (lock == null) {
|
||||
lock = new NamedReentrantReadWriteLock("mark passings lock for tracked race " + getRace().getName(), /* fair */
|
||||
false);
|
||||
locksForMarkPassings.put(markPassings, lock);
|
||||
synchronized (locksForMarkPassings) {
|
||||
lock = locksForMarkPassings.get(markPassingsIdentity);
|
||||
if (lock == null) {
|
||||
lock = new NamedReentrantReadWriteLock(
|
||||
"mark passings lock for tracked race " + getRace().getName(), /* fair */false);
|
||||
locksForMarkPassings.put(markPassingsIdentity, lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
return lock;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStartToNextMarkCacheInvalidationCacheListenersAfterWaypointRemoved(int zeroBasedIndex,
|
||||
Waypoint waypointThatGotRemoved) {
|
||||
|
||||
@@ -55,8 +55,6 @@
|
||||
<plugin id="com.sap.sailing.sailwave.resultimport" autoStart="true" startLevel="3" />
|
||||
<plugin id="com.sap.sailing.server" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.server.gateway" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.server.gateway.ess40" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.server.replication" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.velum.resultimport" autoStart="true" startLevel="3" />
|
||||
<plugin id="com.sap.sailing.www" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.www.events" autoStart="true" startLevel="4" />
|
||||
|
||||
@@ -87,13 +87,6 @@ Computes leaderboard information for sailing races and offers RESTful APIs to al
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.sap.sailing.server.gateway.ess40"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.tractrac.clientmodule"
|
||||
download-size="0"
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ public class GwtTestCaseColumnToggling extends GWTTestCase {
|
||||
+ TracTracConnectionConstants.PORT_TUNNEL_STORED : "tcp://" + TracTracConnectionConstants.HOST_NAME
|
||||
+ ":" + TracTracConnectionConstants.PORT_STORED,
|
||||
COURSE_DESIGN_UPDATE_URI,
|
||||
false, false, /* simulateWithStartTimeNow */ false, /* ignoreTracTracMarkPassings */ false, TRACTRAC_USERNAME, TRACTRAC_PASSWORD, new AsyncCallback<Void>() {
|
||||
false, false, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings */ false, TRACTRAC_USERNAME, TRACTRAC_PASSWORD, new AsyncCallback<Void>() {
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ public class LeaderboardPanelMock extends LeaderboardPanel {
|
||||
String leaderboardName, ErrorReporter errorReporter,
|
||||
StringMessages stringMessages) {
|
||||
super(sailingService, new AsyncActionsExecutor(), LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
/* racesToShow */null, /* namesOfRacesToShow */ null, null, /* autoExpandFirstRace */ false, /* showRegattaRank */ true), new CompetitorSelectionModel(
|
||||
/* racesToShow */null, /* namesOfRacesToShow */ null, null, /* autoExpandFirstRace */ false, /* showRegattaRank */ true, /* showCompetitorSailIdColumn */ true, /* showCompetitorFullNameColumn */ true), new CompetitorSelectionModel(
|
||||
/* hasMultiSelection */true), leaderboardName, errorReporter, stringMessages, new UserAgentDetails("gecko1_8"), /* showRaceDetails */ true);
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -61,9 +61,9 @@ public class TestColumnSwapping {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
}, /* hasOverallDetails */ false);
|
||||
leaderboardOriginalDTO.addRace("Race1", /* explicitFactor */ null, 2., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, true, null, null);
|
||||
leaderboardOriginalDTO.addRace("Race3", /* explicitFactor */ null, 2., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, true, null, null);
|
||||
leaderboardOriginalDTO.addRace("Race2", /* explicitFactor */ null, 2., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, true, null, null);
|
||||
leaderboardOriginalDTO.addRace("Race1", /* explicitFactor */ null, 2., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, true, null, null, false);
|
||||
leaderboardOriginalDTO.addRace("Race3", /* explicitFactor */ null, 2., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, true, null, null, false);
|
||||
leaderboardOriginalDTO.addRace("Race2", /* explicitFactor */ null, 2., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, true, null, null, false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -126,9 +126,9 @@ public class TestColumnSwapping {
|
||||
}
|
||||
}, /* hasOverallDetails */ false);
|
||||
assertNotNull("Leaderboard != NULL", lb);
|
||||
lb.addRace("1", /* explicitFactor */ null, 1., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, false, null, null);
|
||||
lb.addRace("2", /* explicitFactor */ null, 1., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, false, null, null);
|
||||
lb.addRace("3", /* explicitFactor */ null, 1., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, true, null, null);
|
||||
lb.addRace("1", /* explicitFactor */ null, 1., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, false, null, null, false);
|
||||
lb.addRace("2", /* explicitFactor */ null, 1., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, false, null, null, false);
|
||||
lb.addRace("3", /* explicitFactor */ null, 1., /* regattaName */ null, /* seriesName */ null, DEFAULT_FLEET, true, null, null, false);
|
||||
lb.moveRaceDown("1");
|
||||
String[] s = new String[] { "2", "1", "3" };
|
||||
for (int i = 0; i < lb.getRaceList().size(); i++) {
|
||||
|
||||
@@ -3,7 +3,11 @@ encoding//src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.prop
|
||||
encoding//src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_de.properties=UTF-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_ru.properties=UTF-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_zh.properties=UTF-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/server/HomeServiceUtil.java=utf-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/ui/adminconsole/IgtimiAccountsPanel.java=utf-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties=UTF-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties=UTF-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties=UTF-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties=UTF-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/AbstractResultsPresenter.java=utf-8
|
||||
encoding//src/main/java/com/sap/sailing/gwt/ui/leaderboard/CompetitorFilterPanel.java=utf-8
|
||||
@@ -104,7 +104,7 @@ body, table td, select, button {
|
||||
.LeaderboardHeader {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 400px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 18px;
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
|
||||
RegattaRaceInformation-Header
|
||||
RaceName-Label
|
||||
RaceSeriesAndFleet-Label
|
||||
|
||||
RegattaAndRaceTime-Header???
|
||||
RegattaName-Anchor
|
||||
*/
|
||||
|
||||
|
||||
@@ -87,6 +94,14 @@ table {
|
||||
padding-top: 10px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.CombinedWindPanelParentDiv.indentsmall,
|
||||
.TrueNorthIndicatorPanelParentDiv.indentsmall {
|
||||
padding-left: 30px;
|
||||
}
|
||||
.CombinedWindPanelParentDiv.indentbig,
|
||||
.TrueNorthIndicatorPanelParentDiv.indentbig {
|
||||
padding-left: 45px;
|
||||
}
|
||||
|
||||
.MapSimulationLegendParentDiv {
|
||||
padding-bottom: 10px;
|
||||
@@ -573,7 +588,8 @@ img.openColumn {
|
||||
url(images/viewicons/@1x/img/SAP_RV_Leaderboard_GHOSTED.png),
|
||||
url(images/arrows_top_black_small.png);
|
||||
background-repeat: no-repeat, no-repeat;
|
||||
background-position: 4% 50%, 96% 50%
|
||||
background-position: 4% 50%, 96% 50%;
|
||||
background-position: 5px center, calc(100% - 6px) center;
|
||||
}
|
||||
|
||||
.gwt-SplitLayoutPanel-EastToggleButton-Closed-leaderboard {
|
||||
@@ -582,7 +598,8 @@ img.openColumn {
|
||||
url(images/viewicons/@1x/img/SAP_RV_Leaderboard_INACTIVE.png),
|
||||
url(images/arrows_bottom_black_small.png);
|
||||
background-repeat: no-repeat, no-repeat;
|
||||
background-position: 4% 50%, 96% 50%
|
||||
background-position: 4% 50%, 96% 50%;
|
||||
background-position: 5px center, calc(100% - 6px) center;
|
||||
}
|
||||
|
||||
.gwt-SplitLayoutPanel-NorthSouthToggleButton-Closed-media,
|
||||
@@ -664,6 +681,32 @@ img.openColumn {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.compactHeader .RegattaRaceInformation-Header {
|
||||
left: 110px;
|
||||
}
|
||||
.compactHeader .RegattaRaceInformation-Header .RaceName-Label {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
padding: 2px 0;
|
||||
}
|
||||
.compactHeader .RegattaRaceInformation-Header .RaceSeriesAndFleet-Label {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.compactHeader .RegattaAndRaceTime-Header {
|
||||
top: 11px;
|
||||
}
|
||||
.compactHeader .RegattaAndRaceTime-Header .RegattaName-Anchor {
|
||||
width: 115px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
padding: 2px 0 2px 20px;
|
||||
background-position: 4px -1px;
|
||||
}
|
||||
|
||||
.VideoPopup-Close-Button {
|
||||
border: none;
|
||||
}
|
||||
|
||||
+3
-3
@@ -107,7 +107,7 @@ public class AutoPlayController implements RaceTimesInfoProviderListener {
|
||||
asyncActionsExecutor = new AsyncActionsExecutor();
|
||||
showWindChart = false;
|
||||
leaderboard = null;
|
||||
leaderboardSettings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, /* autoExpandFirstRace */ false, /* showRegattaRank */ true);
|
||||
leaderboardSettings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, /* autoExpandFirstRace */ false, /* showRegattaRank */ true, /* showCompetitorSailIdColumn */ true, /* showCompetitorFullNameColumn */ true);
|
||||
|
||||
leaderboardTimer = new Timer(PlayModes.Live, /* delayBetweenAutoAdvancesInMilliseconds */1000l);
|
||||
leaderboardTimer.setLivePlayDelayInMillis(delayToLiveInMillis);
|
||||
@@ -170,10 +170,10 @@ public class AutoPlayController implements RaceTimesInfoProviderListener {
|
||||
RaceSelectionModel raceSelectionModel = new RaceSelectionModel();
|
||||
List<RegattaAndRaceIdentifier> singletonList = Collections.singletonList(raceToShow);
|
||||
raceSelectionModel.setSelection(singletonList);
|
||||
|
||||
RaceBoardPanel raceBoardPanel = new RaceBoardPanel(sailingService, mediaService, userService, asyncActionsExecutor,
|
||||
competitorsAndTheirBoats, raceboardTimer, raceSelectionModel, leaderboardName, null, /* event */ null, raceboardViewConfig,
|
||||
errorReporter, StringMessages.INSTANCE, userAgent, raceTimesInfoProvider, /* showMapControls */false);
|
||||
errorReporter, StringMessages.INSTANCE, userAgent, raceTimesInfoProvider, /* showMapControls */ false,
|
||||
/* isScreenLargeEnoughToOfferChartSupport */ true);
|
||||
return raceBoardPanel;
|
||||
}
|
||||
|
||||
|
||||
+17
-1
@@ -18,6 +18,8 @@ public class AutomaticBatchingDispatch<CTX extends DispatchContext> implements D
|
||||
|
||||
private DispatchCallStack<CTX> currentCallstack;
|
||||
|
||||
private boolean processResultsScheduled;
|
||||
|
||||
/**
|
||||
* Creates a batching dispatch service using the given dispatch implementation.
|
||||
*
|
||||
@@ -28,7 +30,21 @@ public class AutomaticBatchingDispatch<CTX extends DispatchContext> implements D
|
||||
*
|
||||
*/
|
||||
public AutomaticBatchingDispatch(DispatchAsync<CTX> service) {
|
||||
this(service, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a batching dispatch service using the given dispatch implementation.
|
||||
*
|
||||
* The underlying dispatch service is responsible for the context propagation.
|
||||
*
|
||||
* @param service
|
||||
* the underlying service implementation to use
|
||||
*
|
||||
*/
|
||||
public AutomaticBatchingDispatch(DispatchAsync<CTX> service, boolean processResultsScheduled) {
|
||||
this.executionContext = service;
|
||||
this.processResultsScheduled = processResultsScheduled;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,7 +89,7 @@ public class AutomaticBatchingDispatch<CTX extends DispatchContext> implements D
|
||||
|
||||
@Override
|
||||
public void onSuccess(BatchResult result) {
|
||||
callStackInExecution.processResult(result);
|
||||
callStackInExecution.processResult(result, processResultsScheduled);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+29
-6
@@ -2,6 +2,7 @@ package com.sap.sailing.gwt.dispatch.client.batching;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.gwt.dispatch.client.Action;
|
||||
import com.sap.sailing.gwt.dispatch.client.DispatchContext;
|
||||
@@ -70,22 +71,44 @@ public final class DispatchCallStack<CTX extends DispatchContext> {
|
||||
*
|
||||
* @param batchResult
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void processResult(BatchResult batchResult) {
|
||||
public void processResult(BatchResult batchResult, boolean processResultsScheduled) {
|
||||
assert (batchResult != null);
|
||||
|
||||
int loop = 0;
|
||||
for (@SuppressWarnings("rawtypes")
|
||||
DispatchCall call : this.actionQueue) {
|
||||
Result result = batchResult.getResult(loop);
|
||||
|
||||
if (result == null) {
|
||||
Throwable exception = batchResult.getException(loop);
|
||||
call.getCallback().onFailure(exception);
|
||||
|
||||
CallbackCommand callbackCommand = new CallbackCommand(call, result, exception);
|
||||
if(processResultsScheduled) {
|
||||
SplitScheduler.get().schedule(callbackCommand);
|
||||
} else {
|
||||
call.getCallback().onSuccess(result);
|
||||
callbackCommand.execute();
|
||||
}
|
||||
loop++;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private class CallbackCommand implements ScheduledCommand {
|
||||
private final DispatchCall call;
|
||||
private final Result result;
|
||||
private final Throwable exception;
|
||||
public CallbackCommand(DispatchCall call, Result result, Throwable exception) {
|
||||
this.call = call;
|
||||
this.result = result;
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
if (result == null) {
|
||||
call.getCallback().onFailure(exception);
|
||||
} else {
|
||||
call.getCallback().onSuccess(result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.sap.sailing.gwt.dispatch.client.batching;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
|
||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
||||
|
||||
public class SplitScheduler {
|
||||
|
||||
private static final SplitScheduler INSTANCE = new SplitScheduler();
|
||||
|
||||
private List<ScheduledCommand> pendingCommands = new ArrayList<ScheduledCommand>();
|
||||
|
||||
private boolean scheduled = false;
|
||||
|
||||
private final RepeatingCommand repeatingCommand = new RepeatingCommand() {
|
||||
@Override
|
||||
public boolean execute() {
|
||||
ScheduledCommand commandToExecute = pendingCommands.remove(0);
|
||||
|
||||
try {
|
||||
commandToExecute.execute();
|
||||
} catch (Exception e) {
|
||||
if(GWT.getUncaughtExceptionHandler() != null) {
|
||||
GWT.getUncaughtExceptionHandler().onUncaughtException(e);
|
||||
}
|
||||
}
|
||||
scheduled = !pendingCommands.isEmpty();
|
||||
return scheduled;
|
||||
}
|
||||
};
|
||||
|
||||
private SplitScheduler() {
|
||||
}
|
||||
|
||||
public static SplitScheduler get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void schedule(ScheduledCommand command) {
|
||||
pendingCommands.add(command);
|
||||
|
||||
if(!scheduled) {
|
||||
Scheduler.get().scheduleIncremental(repeatingCommand);
|
||||
scheduled = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+10
-2
@@ -16,8 +16,16 @@ import com.sap.sailing.gwt.dispatch.client.rpcimpl.SimpleDispatch;
|
||||
public class DispatchSystemImpl<CTX extends DispatchContext> implements DispatchSystem<CTX> {
|
||||
|
||||
private final SimpleDispatch<CTX> simpleDispatch = new SimpleDispatch<CTX>(null);
|
||||
private final DispatchAsync<CTX> dispatch = new CachingDispatch<CTX>(new AutomaticBatchingDispatch<CTX>(
|
||||
simpleDispatch));
|
||||
private final DispatchAsync<CTX> dispatch;
|
||||
|
||||
public DispatchSystemImpl() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public DispatchSystemImpl(boolean processResultsScheduled) {
|
||||
dispatch = new CachingDispatch<CTX>(new AutomaticBatchingDispatch<CTX>(
|
||||
simpleDispatch, processResultsScheduled));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends Result, A extends Action<R, CTX>> void execute(final A action, final AsyncCallback<R> callback) {
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class GetRegattasAndLiveRacesForEventAction implements SailingAction<Resu
|
||||
EventState eventState = HomeServiceUtil.calculateEventState(event);
|
||||
|
||||
final Duration ttl;
|
||||
if(eventState == EventState.RUNNING) {
|
||||
if(eventState == EventState.RUNNING || eventState == EventState.UPCOMING) {
|
||||
EventActionUtil.forRacesOfEvent(context, eventId, new RaceCallback() {
|
||||
@Override
|
||||
public void doForRace(RaceContext context) {
|
||||
|
||||
+17
@@ -1,5 +1,6 @@
|
||||
package com.sap.sailing.gwt.home.desktop.partials.old;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
@@ -8,6 +9,9 @@ import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.home.shared.partials.fullscreen.FullscreenContainer;
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicatorResources;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator;
|
||||
|
||||
public abstract class AbstractLeaderboardFullscreenViewer<T extends Widget> extends FullscreenContainer<T> implements
|
||||
LeaderboardDelegate<T> {
|
||||
@@ -15,14 +19,18 @@ public abstract class AbstractLeaderboardFullscreenViewer<T extends Widget> exte
|
||||
private final Image autoRefreshControl = new Image("images/home/reload.svg");
|
||||
private final Image settingsControl = new Image("images/home/settings.svg");
|
||||
|
||||
private final static BusyIndicatorResources RESOURCES = GWT.create(BusyIndicatorResources.class);
|
||||
|
||||
private final Label lastScoringUpdateTime = new Label();
|
||||
private final Label lastScoringUpdateText = new Label();
|
||||
protected final Label lastScoringComment = new Label();
|
||||
protected final Label scoringScheme = new Label();
|
||||
protected final BusyIndicator busyIndicator = new SimpleBusyIndicator(false, 0.9f, RESOURCES.busyIndicatorCircleInverted());
|
||||
|
||||
public AbstractLeaderboardFullscreenViewer() {
|
||||
showLogo();
|
||||
showBorder();
|
||||
addToolbarBusyIndicator(busyIndicator);
|
||||
addToolbarInfo(createPanel(lastScoringUpdateText, lastScoringUpdateTime));
|
||||
addToolbarAction(autoRefreshControl);
|
||||
addToolbarAction(settingsControl);
|
||||
@@ -88,4 +96,13 @@ public abstract class AbstractLeaderboardFullscreenViewer<T extends Widget> exte
|
||||
return scoringScheme.getElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Element getBusyIndicatorElement() {
|
||||
return busyIndicator.getElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBusyState(boolean isBusy) {
|
||||
busyIndicator.setBusy(isBusy);
|
||||
}
|
||||
}
|
||||
+5
@@ -106,6 +106,11 @@
|
||||
background-color: #f0ab00;
|
||||
}
|
||||
|
||||
.regattaleaderboard_meta_busyindicator {
|
||||
display: inline-block;
|
||||
margin: 0 0.666666666666667em;
|
||||
}
|
||||
|
||||
.regattaleaderboard_meta_liverace {
|
||||
color: red;
|
||||
font-weight: 600;
|
||||
|
||||
+1
@@ -30,6 +30,7 @@ public interface EventRegattaLeaderboardResources extends ClientBundle {
|
||||
String regattaleaderboard_meta_update_type();
|
||||
String regattaleaderboard_meta_scoring_timestamp();
|
||||
String regattaleaderboard_meta_update_timestamp();
|
||||
String regattaleaderboard_meta_busyindicator();
|
||||
String regattaleaderboard_meta_scoring_text();
|
||||
String regattaleaderboard_meta_update_text();
|
||||
String regattaleaderboard_meta_reload();
|
||||
|
||||
+3
@@ -10,6 +10,8 @@ public interface LeaderboardDelegate<T extends Widget> {
|
||||
|
||||
void setLeaderboardPanel(T leaderboardPanel);
|
||||
|
||||
void setBusyState(boolean isBusy);
|
||||
|
||||
Widget getAutoRefreshControl();
|
||||
|
||||
Widget getSettingsControl();
|
||||
@@ -24,4 +26,5 @@ public interface LeaderboardDelegate<T extends Widget> {
|
||||
|
||||
Element getScoringSchemeElement();
|
||||
|
||||
Element getBusyIndicatorElement();
|
||||
}
|
||||
+14
-1
@@ -31,12 +31,14 @@ import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.ScoringSchemeTypeFormatter;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.BusyStateChangeListener;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayStates;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
|
||||
|
||||
public class OldLeaderboard extends Composite {
|
||||
public class OldLeaderboard extends Composite implements BusyStateChangeListener {
|
||||
private static OldLeaderboardUiBinder uiBinder = GWT.create(OldLeaderboardUiBinder.class);
|
||||
|
||||
interface OldLeaderboardUiBinder extends UiBinder<Widget, OldLeaderboard> {
|
||||
@@ -52,6 +54,7 @@ public class OldLeaderboard extends Composite {
|
||||
@UiField DivElement lastScoringCommentDiv;
|
||||
@UiField DivElement scoringSchemeDiv;
|
||||
@UiField DivElement hasLiveRaceDiv;
|
||||
@UiField BusyIndicator busyIndicator;
|
||||
@UiField EventRegattaLeaderboardResources local_res;
|
||||
|
||||
private LeaderboardPanel leaderboardPanel;
|
||||
@@ -166,6 +169,7 @@ public class OldLeaderboard extends Composite {
|
||||
this.autoRefreshTimer = timer;
|
||||
this.leaderboardPanel = leaderboardPanel;
|
||||
oldLeaderboardPanel.add(leaderboardPanel);
|
||||
leaderboardPanel.addBusyStateChangeListener(this);
|
||||
}
|
||||
|
||||
public void updatedLeaderboard(LeaderboardDTO leaderboard) {
|
||||
@@ -218,7 +222,16 @@ public class OldLeaderboard extends Composite {
|
||||
lastScoringUpdateTimeDiv.getStyle().setVisibility(Visibility.HIDDEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBusyStateChange(boolean busyState) {
|
||||
busyIndicator.setBusy(busyState);
|
||||
if(delegate != null) {
|
||||
delegate.setBusyState(busyState);
|
||||
}
|
||||
}
|
||||
|
||||
public interface OldLeaderboardDelegate extends LeaderboardDelegate<LeaderboardPanel> {
|
||||
Element getHasLiveRaceElement();
|
||||
}
|
||||
|
||||
}
|
||||
+5
-3
@@ -1,16 +1,18 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
|
||||
xmlns:c="urn:import:com.sap.sse.gwt.client.controls.busyindicator">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.common.client.i18n.TextMessages"/>
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.desktop.partials.old.EventRegattaLeaderboardResources" />
|
||||
<g:HTMLPanel styleName=" {local_res.css.marginFix}">
|
||||
<div class="{res.mediaCss.grid}">
|
||||
<div class="{res.mediaCss.small7} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
|
||||
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
|
||||
<div ui:field="lastScoringCommentDiv" class="{local_res.css.regattaleaderboard_meta_scoring_comment}"></div>
|
||||
<div ui:field="hasLiveRaceDiv" class="{local_res.css.regattaleaderboard_meta_liverace}"></div>
|
||||
<div ui:field="scoringSchemeDiv" class="{local_res.css.regattaleaderboard_meta_scoring_type}"></div>
|
||||
</div>
|
||||
<div class="{res.mediaCss.small5} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_settings}">
|
||||
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_settings}">
|
||||
<c:SimpleBusyIndicator addStyleNames="{local_res.css.regattaleaderboard_meta_busyindicator}" ui:field="busyIndicator" />
|
||||
<div class="{local_res.css.regattaleaderboard_meta_update}">
|
||||
<div ui:field="lastScoringUpdateTextDiv" class="{local_res.css.regattaleaderboard_meta_update_text}"></div>
|
||||
<div ui:field="lastScoringUpdateTimeDiv" class="{local_res.css.regattaleaderboard_meta_update_timestamp}"></div>
|
||||
|
||||
+31
-6
@@ -3,7 +3,7 @@ package com.sap.sailing.gwt.home.desktop.partials.old.multileaderboard;
|
||||
import java.util.Date;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.ParagraphElement;
|
||||
import com.google.gwt.dom.client.DivElement;
|
||||
import com.google.gwt.dom.client.Style.Overflow;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.dom.client.Style.Visibility;
|
||||
@@ -27,15 +27,19 @@ import com.sap.sailing.gwt.home.desktop.partials.old.LeaderboardDelegate;
|
||||
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.MultiLeaderboardPanel;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.ScoringSchemeTypeFormatter;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.SelectedLeaderboardChangeListener;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.BusyStateChangeListener;
|
||||
import com.sap.sse.gwt.client.player.Timer;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayModes;
|
||||
import com.sap.sse.gwt.client.player.Timer.PlayStates;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialog;
|
||||
|
||||
public class OldMultiLeaderboard extends Composite {
|
||||
public class OldMultiLeaderboard extends Composite implements SelectedLeaderboardChangeListener, BusyStateChangeListener {
|
||||
private static OldMultiLeaderboardUiBinder uiBinder = GWT.create(OldMultiLeaderboardUiBinder.class);
|
||||
|
||||
interface OldMultiLeaderboardUiBinder extends UiBinder<Widget, OldMultiLeaderboard> {
|
||||
@@ -46,15 +50,17 @@ public class OldMultiLeaderboard extends Composite {
|
||||
@UiField Anchor settingsAnchor;
|
||||
@UiField Anchor autoRefreshAnchor;
|
||||
@UiField Anchor fullscreenAnchor;
|
||||
@UiField ParagraphElement lastScoringUpdateTimeDiv;
|
||||
@UiField ParagraphElement lastScoringUpdateTextDiv;
|
||||
@UiField ParagraphElement lastScoringCommentDiv;
|
||||
@UiField ParagraphElement scoringSchemeDiv;
|
||||
@UiField DivElement lastScoringUpdateTimeDiv;
|
||||
@UiField DivElement lastScoringUpdateTextDiv;
|
||||
@UiField DivElement lastScoringCommentDiv;
|
||||
@UiField DivElement scoringSchemeDiv;
|
||||
@UiField BusyIndicator busyIndicator;
|
||||
@UiField EventRegattaLeaderboardResources local_res;
|
||||
|
||||
private MultiLeaderboardPanel multiLeaderboardPanel;
|
||||
private Timer autoRefreshTimer;
|
||||
private final OldMultiLeaderboardDelegate delegate;
|
||||
private LeaderboardPanel lastSelectedLeaderboardPanel;
|
||||
|
||||
public OldMultiLeaderboard() {
|
||||
this(null);
|
||||
@@ -69,6 +75,7 @@ public class OldMultiLeaderboard extends Composite {
|
||||
fullscreenAnchor.setTitle(StringMessages.INSTANCE.openFullscreenView());
|
||||
this.delegate = delegate;
|
||||
this.setupFullscreenDelegate();
|
||||
lastSelectedLeaderboardPanel = null;
|
||||
}
|
||||
|
||||
private void setupFullscreenDelegate() {
|
||||
@@ -163,6 +170,7 @@ public class OldMultiLeaderboard extends Composite {
|
||||
public void setMultiLeaderboard(MultiLeaderboardPanel multiLeaderboardPanel, final Timer timer) {
|
||||
this.autoRefreshTimer = timer;
|
||||
this.multiLeaderboardPanel = multiLeaderboardPanel;
|
||||
this.multiLeaderboardPanel.addSelectedLeaderboardChangeListener(this);
|
||||
|
||||
oldMultiLeaderboardPanel.add(multiLeaderboardPanel);
|
||||
}
|
||||
@@ -199,6 +207,23 @@ public class OldMultiLeaderboard extends Composite {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBusyStateChange(boolean busyState) {
|
||||
busyIndicator.setBusy(busyState);
|
||||
if(delegate != null) {
|
||||
delegate.setBusyState(busyState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelectedLeaderboardChanged(LeaderboardPanel selectedLeaderboard) {
|
||||
if(lastSelectedLeaderboardPanel != null) {
|
||||
lastSelectedLeaderboardPanel.removeBusyStateChangeListener(this);
|
||||
}
|
||||
selectedLeaderboard.addBusyStateChangeListener(this);
|
||||
lastSelectedLeaderboardPanel = selectedLeaderboard;
|
||||
}
|
||||
|
||||
public interface OldMultiLeaderboardDelegate extends LeaderboardDelegate<MultiLeaderboardPanel>{
|
||||
}
|
||||
}
|
||||
+7
-5
@@ -1,18 +1,20 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
|
||||
xmlns:c="urn:import:com.sap.sse.gwt.client.controls.busyindicator">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.common.client.i18n.TextMessages"/>
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.desktop.partials.old.EventRegattaLeaderboardResources" />
|
||||
<g:HTMLPanel styleName=" {local_res.css.marginFix}">
|
||||
<div class="{res.mediaCss.grid}">
|
||||
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
|
||||
<p ui:field="lastScoringCommentDiv" class="{local_res.css.regattaleaderboard_meta_scoring_comment}"></p>
|
||||
<p ui:field="scoringSchemeDiv" class="{local_res.css.regattaleaderboard_meta_scoring_type}"></p>
|
||||
<div ui:field="lastScoringCommentDiv" class="{local_res.css.regattaleaderboard_meta_scoring_comment}"></div>
|
||||
<div ui:field="scoringSchemeDiv" class="{local_res.css.regattaleaderboard_meta_scoring_type}"></div>
|
||||
</div>
|
||||
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_settings}">
|
||||
<c:SimpleBusyIndicator addStyleNames="{local_res.css.regattaleaderboard_meta_busyindicator}" ui:field="busyIndicator"/>
|
||||
<div class="{local_res.css.regattaleaderboard_meta_update}">
|
||||
<p ui:field="lastScoringUpdateTextDiv" class="{local_res.css.regattaleaderboard_meta_update_text}"></p>
|
||||
<p ui:field="lastScoringUpdateTimeDiv" class="{local_res.css.regattaleaderboard_meta_update_timestamp}"></p>
|
||||
<div ui:field="lastScoringUpdateTextDiv" class="{local_res.css.regattaleaderboard_meta_update_text}"></div>
|
||||
<div ui:field="lastScoringUpdateTimeDiv" class="{local_res.css.regattaleaderboard_meta_update_timestamp}"></div>
|
||||
</div>
|
||||
<g:Anchor ui:field="autoRefreshAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_reload}"></g:Anchor>
|
||||
<g:Anchor ui:field="settingsAnchor" href="javascript:;" styleName="{res.mainCss.button} {local_res.css.regattaleaderboard_meta_settings_button}"></g:Anchor>
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ public class EventParamUtils {
|
||||
.createNewDefaultSettings(null, null,
|
||||
/* overallDetails */overallDetails, null,
|
||||
/* autoExpandFirstRace */false, refreshIntervalMillis, numberOfLastRacesToShow,
|
||||
raceColumnSelectionStrategy);
|
||||
raceColumnSelectionStrategy, /* showCompetitorSailIdColumns */ true, /*showCompetitorFullNameColumn*/ true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
-2
@@ -44,7 +44,6 @@ import com.sap.sailing.gwt.home.shared.places.fakeseries.SeriesDefaultPlace;
|
||||
import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.refresh.ErrorAndBusyClientFactory;
|
||||
import com.sap.sailing.gwt.ui.raceboard.RaceBoardViewConfiguration;
|
||||
import com.sap.sailing.gwt.ui.shared.util.NullSafeComparableComparator;
|
||||
|
||||
public abstract class AbstractEventActivity<PLACE extends AbstractEventPlace> extends AbstractActivity implements Presenter {
|
||||
@@ -248,7 +247,6 @@ public abstract class AbstractEventActivity<PLACE extends AbstractEventPlace> ex
|
||||
}
|
||||
linkParams.put("raceName", trackedRaceName);
|
||||
linkParams.put("regattaName", regattaName);
|
||||
linkParams.put(RaceBoardViewConfiguration.PARAM_VIEW_MODE, "simple");
|
||||
// TODO this must only be forwarded if there is a logged-on user
|
||||
// linkParams.put(RaceBoardViewConfiguration.PARAM_CAN_REPLAY_DURING_LIVE_RACES, "true");
|
||||
return linkParams;
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ public class ExperimentalFeatures {
|
||||
/**
|
||||
* Enables/disables the link to the race board on mobile races view (competition format), in case of a tracked race
|
||||
*/
|
||||
public static final boolean ENABLE_RACE_VIEWER_LINK_ON_MOBILE = false;
|
||||
public static final boolean ENABLE_RACE_VIEWER_LINK_ON_MOBILE = true;
|
||||
/**
|
||||
* Provide selection to filter regattas by boat category on mobile multiregatta event overview
|
||||
*/
|
||||
|
||||
+3
-2
@@ -8,7 +8,8 @@ public class BusyViewImpl extends Composite implements BusyView {
|
||||
|
||||
public BusyViewImpl() {
|
||||
BusyViewResources.INSTANCE.css().ensureInjected();
|
||||
initWidget(new SimpleBusyIndicator(true, 1.0f, "", BusyViewResources.INSTANCE.css().busy()));
|
||||
SimpleBusyIndicator busyIndicator = new SimpleBusyIndicator(true, 1.0f);
|
||||
busyIndicator.setImageStyleClass(BusyViewResources.INSTANCE.css().busy());
|
||||
initWidget(busyIndicator);
|
||||
}
|
||||
|
||||
}
|
||||
+6
@@ -37,6 +37,7 @@ public class FullscreenContainer<T extends Widget> {
|
||||
String popup();
|
||||
String toolbarInfo();
|
||||
String toolbarAction();
|
||||
String toolbarBusyIndicator();
|
||||
String content();
|
||||
String contentBorder();
|
||||
}
|
||||
@@ -89,6 +90,11 @@ public class FullscreenContainer<T extends Widget> {
|
||||
toolbarUi.add(widget);
|
||||
}
|
||||
|
||||
public void addToolbarBusyIndicator(Widget widget) {
|
||||
widget.addStyleName(style.toolbarBusyIndicator());
|
||||
toolbarUi.add(widget);
|
||||
}
|
||||
|
||||
public void addToolbarInfo(Widget widget) {
|
||||
widget.addStyleName(style.toolbarInfo());
|
||||
toolbarUi.add(widget);
|
||||
|
||||
+7
@@ -50,6 +50,13 @@
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
}
|
||||
.toolbarBusyIndicator {
|
||||
display: inline-block;
|
||||
height: 50px;
|
||||
width: auto;
|
||||
padding: 10px;
|
||||
vertical-align: top;
|
||||
}
|
||||
.toolbarAction:hover {
|
||||
background-color: #d79900;
|
||||
}
|
||||
|
||||
+1
-1
@@ -237,7 +237,7 @@ public class RegattaOverviewPanel extends SimplePanel {
|
||||
if (leaderboardsTabPanel != null) {
|
||||
if (showLeaderboard) {
|
||||
final CompetitorSelectionModel competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */ true);
|
||||
final LeaderboardSettings leaderboardSettings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, /* autoExpandFirstRace */ false, /* showRegattaRank */ true);
|
||||
final LeaderboardSettings leaderboardSettings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, /* autoExpandFirstRace */ false, /* showRegattaRank */ true, /* showCompetitorSailIdColumn */ true, /* showCompetitorFullNameColumn */ true);
|
||||
sailingService.getLeaderboardsByEvent(eventDTO, new MarkedAsyncCallback<List<StrippedLeaderboardDTO>>(
|
||||
new AsyncCallback<List<StrippedLeaderboardDTO>>() {
|
||||
@Override
|
||||
|
||||
+17
-13
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.common.RankingMetrics;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.gwt.ui.client.DataEntryDialogWithBootstrap;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.RankingMetricTypeFormatter;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.ScoringSchemeTypeFormatter;
|
||||
import com.sap.sailing.gwt.ui.shared.BetterDateTimeBox;
|
||||
@@ -134,20 +135,23 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
|
||||
if (additionalWidget != null) {
|
||||
panel.add(additionalWidget);
|
||||
}
|
||||
Grid formGrid = new Grid(6, 2);
|
||||
Grid formGrid = new Grid(7, 2);
|
||||
panel.add(formGrid);
|
||||
formGrid.setWidget(0, 0, new Label(stringMessages.startDate() + ":"));
|
||||
formGrid.setWidget(0, 1, startDateBox);
|
||||
formGrid.setWidget(1, 0, new Label(stringMessages.endDate() + ":"));
|
||||
formGrid.setWidget(1, 1, endDateBox);
|
||||
formGrid.setWidget(2, 0, new Label(stringMessages.scoringSystem() + ":"));
|
||||
formGrid.setWidget(2, 1, scoringSchemeListBox);
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.event() + ":"));
|
||||
formGrid.setWidget(3, 1, sailingEventsListBox);
|
||||
formGrid.setWidget(4, 0, new Label(stringMessages.courseArea() + ":"));
|
||||
formGrid.setWidget(4, 1, courseAreaListBox);
|
||||
formGrid.setWidget(5, 0, new Label(stringMessages.useStartTimeInference() + ":"));
|
||||
formGrid.setWidget(5, 1, useStartTimeInferenceCheckBox);
|
||||
|
||||
formGrid.setWidget(0, 0, new Label(stringMessages.timeZone() + ":"));
|
||||
formGrid.setWidget(0, 1, new Label(DateAndTimeFormatterUtil.getClientTimeZoneAsGMTString()));
|
||||
formGrid.setWidget(1, 0, new Label(stringMessages.startDate() + ":"));
|
||||
formGrid.setWidget(1, 1, startDateBox);
|
||||
formGrid.setWidget(2, 0, new Label(stringMessages.endDate() + ":"));
|
||||
formGrid.setWidget(2, 1, endDateBox);
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.scoringSystem() + ":"));
|
||||
formGrid.setWidget(3, 1, scoringSchemeListBox);
|
||||
formGrid.setWidget(4, 0, new Label(stringMessages.event() + ":"));
|
||||
formGrid.setWidget(4, 1, sailingEventsListBox);
|
||||
formGrid.setWidget(5, 0, new Label(stringMessages.courseArea() + ":"));
|
||||
formGrid.setWidget(5, 1, courseAreaListBox);
|
||||
formGrid.setWidget(6, 0, new Label(stringMessages.useStartTimeInference() + ":"));
|
||||
formGrid.setWidget(6, 1, useStartTimeInferenceCheckBox);
|
||||
setupAdditionalWidgetsOnPanel(panel, formGrid);
|
||||
return panel;
|
||||
}
|
||||
|
||||
+4
-4
@@ -40,18 +40,18 @@ public class AddWindFixDialog extends DataEntryDialog<WindDTO> {
|
||||
if(windDTO.trueWindSpeedInKnots == null) {
|
||||
errorMessage = stringMessages.pleaseEnterAValue();
|
||||
} else if(windDTO.trueWindSpeedInKnots != null && (windDTO.trueWindSpeedInKnots < 0.0 || windDTO.trueWindSpeedInKnots > 100.0)) {
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.speedInKnots(), "0", "100");
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.speedInKnots(), 0, 100);
|
||||
} else if(windDTO.trueWindFromDeg == null){
|
||||
errorMessage = stringMessages.pleaseEnterAValue();
|
||||
} else if(windDTO.trueWindFromDeg != null && (windDTO.trueWindFromDeg < 0.0 || windDTO.trueWindFromDeg > 360.0)){
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.fromDeg(), "0", "360");
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.fromDeg(), 0, 360);
|
||||
} else if(windDTO.measureTimepoint == null) {
|
||||
errorMessage = stringMessages.pleaseEnterAValue();
|
||||
} else if(windDTO.position != null) {
|
||||
if(windDTO.position.getLatDeg() < -90.0 || windDTO.position.getLatDeg() > 90.0){
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.latitude(), "-90", "90");
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.latitude(), -90, 90);
|
||||
} else if(windDTO.position.getLngDeg() < -180.0 || windDTO.position.getLngDeg() > 180.0){
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.longitude(), "-180", "180");
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.longitude(), -180, 180);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-12
@@ -24,6 +24,7 @@ import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.ui.client.DataEntryDialogWithBootstrap;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
|
||||
import com.sap.sailing.gwt.ui.shared.BetterDateTimeBox;
|
||||
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
@@ -195,24 +196,25 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
if (additionalWidget != null) {
|
||||
panel.add(additionalWidget);
|
||||
}
|
||||
|
||||
Grid formGrid = new Grid(8, 2);
|
||||
Grid formGrid = new Grid(9, 2);
|
||||
formGrid.setWidget(0, 0, new Label(stringMessages.name() + ":"));
|
||||
formGrid.setWidget(0, 1, nameEntryField);
|
||||
formGrid.setWidget(1, 0, new Label(stringMessages.description() + ":"));
|
||||
formGrid.setWidget(1, 1, descriptionEntryField);
|
||||
formGrid.setWidget(2, 0, new Label(stringMessages.venue() + ":"));
|
||||
formGrid.setWidget(2, 1, venueEntryField);
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.startDate() + ":"));
|
||||
formGrid.setWidget(3, 1, startDateBox);
|
||||
formGrid.setWidget(4, 0, new Label(stringMessages.endDate() + ":"));
|
||||
formGrid.setWidget(4, 1, endDateBox);
|
||||
formGrid.setWidget(5, 0, new Label(stringMessages.isPublic() + ":"));
|
||||
formGrid.setWidget(5, 1, isPublicCheckBox);
|
||||
formGrid.setWidget(6, 0, new Label(stringMessages.eventOfficialWebsiteURL() + ":"));
|
||||
formGrid.setWidget(6, 1, officialWebsiteURLEntryField);
|
||||
formGrid.setWidget(7, 0, new Label(stringMessages.eventSailorsInfoWebsiteURL() + ":"));
|
||||
formGrid.setWidget(7, 1, sailorsInfoWebsiteURLEntryField);
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.timeZone() + ":"));
|
||||
formGrid.setWidget(3, 1, new Label(DateAndTimeFormatterUtil.getClientTimeZoneAsGMTString()));
|
||||
formGrid.setWidget(4, 0, new Label(stringMessages.startDate() + ":"));
|
||||
formGrid.setWidget(4, 1, startDateBox);
|
||||
formGrid.setWidget(5, 0, new Label(stringMessages.endDate() + ":"));
|
||||
formGrid.setWidget(5, 1, endDateBox);
|
||||
formGrid.setWidget(6, 0, new Label(stringMessages.isPublic() + ":"));
|
||||
formGrid.setWidget(6, 1, isPublicCheckBox);
|
||||
formGrid.setWidget(7, 0, new Label(stringMessages.eventOfficialWebsiteURL() + ":"));
|
||||
formGrid.setWidget(7, 1, officialWebsiteURLEntryField);
|
||||
formGrid.setWidget(8, 0, new Label(stringMessages.eventSailorsInfoWebsiteURL() + ":"));
|
||||
formGrid.setWidget(8, 1, sailorsInfoWebsiteURLEntryField);
|
||||
|
||||
TabLayoutPanel tabPanel = new TabLayoutPanel(30, Unit.PX);
|
||||
tabPanel.setHeight("500px");
|
||||
|
||||
+15
-1
@@ -126,7 +126,6 @@ public class RaceLogCourseManagementWidget extends CourseManagementWidget {
|
||||
@Override
|
||||
public void onSuccess(RaceCourseDTO result) {
|
||||
updateWaypointsAndControlPoints(result);
|
||||
marks.refresh(result.getMarks());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,5 +133,20 @@ public class RaceLogCourseManagementWidget extends CourseManagementWidget {
|
||||
errorReporter.reportError("Could not load course: " + caught.getMessage());
|
||||
}
|
||||
});
|
||||
|
||||
sailingService.getMarksInRaceLog(leaderboardName, raceColumnName, fleetName,
|
||||
new AsyncCallback<Iterable<MarkDTO>>() {
|
||||
@Override
|
||||
public void onSuccess(Iterable<MarkDTO> result) {
|
||||
marks.refresh(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
errorReporter.reportError(
|
||||
stringMessages.errorTryingToObtainTheMarksOfTheRace(
|
||||
caught.getMessage()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -273,7 +273,8 @@ public class ReplicationPanel extends FlowPanel {
|
||||
errorReporter.reportPersistentInformation(stringMessages.warningServerIsReplica());
|
||||
registeredMasters.insertRow(i);
|
||||
registeredMasters.setWidget(i, 0, new Label(stringMessages.replicatingFromMaster(replicatingFromMaster.getHostname(),
|
||||
replicatingFromMaster.getMessagingPort(), replicatingFromMaster.getServletPort())));
|
||||
replicatingFromMaster.getMessagingPort(), replicatingFromMaster.getServletPort(),
|
||||
replicatingFromMaster.getMessagingHostname(), replicatingFromMaster.getExchangeName())));
|
||||
i++;
|
||||
addButton.setEnabled(false);
|
||||
stopReplicationButton.setEnabled(true);
|
||||
|
||||
+1
-1
@@ -225,7 +225,7 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
|
||||
declinationCheckbox.setValue(true);
|
||||
trackableRacesPanel.add(declinationCheckbox);
|
||||
|
||||
final CheckBox simulateWithStartTimeNow = new CheckBox(stringMessages.simulateWithStartTimeNow());
|
||||
final CheckBox simulateWithStartTimeNow = new CheckBox(stringMessages.simulateAsLiveRace());
|
||||
simulateWithStartTimeNow.setWordWrap(false);
|
||||
simulateWithStartTimeNow.setValue(false);
|
||||
trackableRacesPanel.add(simulateWithStartTimeNow);
|
||||
|
||||
+49
-20
@@ -24,6 +24,7 @@ import com.google.gwt.user.client.ui.CaptionPanel;
|
||||
import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.FlexTable;
|
||||
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.HTMLTable.ColumnFormatter;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
@@ -44,6 +45,7 @@ import com.sap.sailing.gwt.ui.client.shared.controls.SelectionCheckboxColumn;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.TracTracConfigurationDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.TracTracRaceRecordDTO;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.util.NaturalComparator;
|
||||
import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.async.MarkedAsyncCallback;
|
||||
@@ -83,6 +85,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
|
||||
private LabeledAbstractFilterablePanel<TracTracRaceRecordDTO> racesFilterablePanel;
|
||||
private CellTable<TracTracRaceRecordDTO> racesTable;
|
||||
private static final String ZERO_AS_STRING = "0";
|
||||
|
||||
public TracTracEventManagementPanel(final SailingServiceAsync sailingService, ErrorReporter errorReporter,
|
||||
RegattaRefresher regattaRefresher, StringMessages stringMessages) {
|
||||
@@ -229,17 +232,12 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
|
||||
protected HorizontalPanel createRacesPanel() {
|
||||
HorizontalPanel racesPanel = new HorizontalPanel();
|
||||
|
||||
CaptionPanel trackableRacesPanel = createTrackableRacesPanel();
|
||||
|
||||
racesPanel.add(trackableRacesPanel);
|
||||
racesPanel.setCellWidth(trackableRacesPanel, "50%");
|
||||
|
||||
CaptionPanel trackedRacesPanel = createTrackedRacesPanel();
|
||||
|
||||
racesPanel.add(trackedRacesPanel);
|
||||
racesPanel.setCellWidth(trackedRacesPanel, "50%");
|
||||
|
||||
return racesPanel;
|
||||
}
|
||||
|
||||
@@ -276,10 +274,32 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
correctWindCheckBox.setWordWrap(false);
|
||||
correctWindCheckBox.setValue(Boolean.TRUE);
|
||||
|
||||
final CheckBox simulateWithStartTimeNowCheckBox = new CheckBox(stringMessages.simulateWithStartTimeNow());
|
||||
final TextBox offsetToStartTimeOfSimulatedRaceTextBox = new TextBox();
|
||||
offsetToStartTimeOfSimulatedRaceTextBox.setWidth("40px");
|
||||
offsetToStartTimeOfSimulatedRaceTextBox.setEnabled(false);
|
||||
offsetToStartTimeOfSimulatedRaceTextBox.setValue(ZERO_AS_STRING);
|
||||
|
||||
final CheckBox simulateWithStartTimeNowCheckBox = new CheckBox(stringMessages.simulateAsLiveRace());
|
||||
simulateWithStartTimeNowCheckBox.ensureDebugId("SimulateWithStartTimeNowCheckBox");
|
||||
simulateWithStartTimeNowCheckBox.setWordWrap(false);
|
||||
simulateWithStartTimeNowCheckBox.setValue(Boolean.FALSE);
|
||||
simulateWithStartTimeNowCheckBox.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
offsetToStartTimeOfSimulatedRaceTextBox.setEnabled(simulateWithStartTimeNowCheckBox.getValue());
|
||||
offsetToStartTimeOfSimulatedRaceTextBox.setFocus(simulateWithStartTimeNowCheckBox.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
final FlowPanel simulateAsLiveRacePanel = new FlowPanel();
|
||||
simulateAsLiveRacePanel.add(simulateWithStartTimeNowCheckBox);
|
||||
|
||||
final Label offsetToStartLabel = new Label(stringMessages.simulateWithOffset());
|
||||
|
||||
final HorizontalPanel simulateWithOffsetPanel = new HorizontalPanel();
|
||||
simulateWithOffsetPanel.add(offsetToStartLabel);
|
||||
simulateWithOffsetPanel.add(offsetToStartTimeOfSimulatedRaceTextBox);
|
||||
|
||||
final CheckBox ignoreTracTracMarkPassingsCheckbox = new CheckBox(stringMessages.useInternalAlgorithm());
|
||||
ignoreTracTracMarkPassingsCheckbox.setWordWrap(false);
|
||||
ignoreTracTracMarkPassingsCheckbox.setValue(Boolean.FALSE);
|
||||
@@ -287,8 +307,9 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
layoutTable.setWidget(1, 0, trackSettingsLabel);
|
||||
layoutTable.setWidget(1, 1, trackWindCheckBox);
|
||||
layoutTable.setWidget(2, 1, correctWindCheckBox);
|
||||
layoutTable.setWidget(3, 1, simulateWithStartTimeNowCheckBox);
|
||||
layoutTable.setWidget(4, 1, ignoreTracTracMarkPassingsCheckbox);
|
||||
layoutTable.setWidget(3, 1, simulateAsLiveRacePanel);
|
||||
layoutTable.setWidget(4, 1, simulateWithOffsetPanel);
|
||||
layoutTable.setWidget(5, 1, ignoreTracTracMarkPassingsCheckbox);
|
||||
|
||||
// Filter
|
||||
Label racesFilterLabel = new Label(stringMessages.filterRacesByName() + ":");
|
||||
@@ -310,8 +331,8 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
}
|
||||
};
|
||||
racesFilterablePanel.getTextBox().ensureDebugId("TrackableRacesFilterTextBox");
|
||||
layoutTable.setWidget(5, 0, racesFilterLabel);
|
||||
layoutTable.setWidget(5, 1, racesFilterablePanel);
|
||||
layoutTable.setWidget(6, 0, racesFilterLabel);
|
||||
layoutTable.setWidget(6, 1, racesFilterablePanel);
|
||||
|
||||
// Races
|
||||
TextColumn<TracTracRaceRecordDTO> regattaNameColumn = new TextColumn<TracTracRaceRecordDTO>() {
|
||||
@@ -357,7 +378,6 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
}
|
||||
};
|
||||
raceVisibilityColumn.setSortable(true);
|
||||
|
||||
SelectionCheckboxColumn<TracTracRaceRecordDTO> selectionCheckboxColumn = new SelectionCheckboxColumn<TracTracRaceRecordDTO>(tableResources.cellTableStyle().cellTableCheckboxSelected(),
|
||||
tableResources.cellTableStyle().cellTableCheckboxDeselected(), tableResources.cellTableStyle().cellTableCheckboxColumnCell()) {
|
||||
@Override
|
||||
@@ -381,26 +401,24 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
raceNameColumn, boatClassColumn, raceStartTrackingColumn, raceStatusColumn));
|
||||
racesTable.setSelectionModel(selectionCheckboxColumn.getSelectionModel(), selectionCheckboxColumn.getSelectionManager());
|
||||
racesTable.setWidth("100%");
|
||||
|
||||
raceList.addDataDisplay(racesTable);
|
||||
|
||||
layoutTable.setWidget(6, 0, racesTable);
|
||||
cellFormatter.setColSpan(6, 0, 2);
|
||||
|
||||
Button startTrackingButton = new Button(stringMessages.startTracking());
|
||||
startTrackingButton.ensureDebugId("StartTrackingButton");
|
||||
startTrackingButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
Duration offsetToStartTimeOfSimulatedRace = null;
|
||||
if(simulateWithStartTimeNowCheckBox.getValue().booleanValue()) {
|
||||
offsetToStartTimeOfSimulatedRace = getMillisecondsDurationFromMinutesAsString(offsetToStartTimeOfSimulatedRaceTextBox.getValue());
|
||||
}
|
||||
trackSelectedRaces(trackWindCheckBox.getValue(), correctWindCheckBox.getValue(),
|
||||
simulateWithStartTimeNowCheckBox.getValue(), ignoreTracTracMarkPassingsCheckbox.getValue());
|
||||
offsetToStartTimeOfSimulatedRace, ignoreTracTracMarkPassingsCheckbox.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
layoutTable.setWidget(7, 1, startTrackingButton);
|
||||
|
||||
trackableRacesPanel.setContentWidget(layoutTable);
|
||||
|
||||
return trackableRacesPanel;
|
||||
}
|
||||
|
||||
@@ -463,6 +481,17 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
return boatClassNames.substring(0, boatClassNames.length() - 2);
|
||||
}
|
||||
|
||||
private Duration getMillisecondsDurationFromMinutesAsString(String minutesAsString) {
|
||||
Duration result = null;
|
||||
if (minutesAsString != null) {
|
||||
Double minutesAsDouble = Double.parseDouble(minutesAsString);
|
||||
if (minutesAsDouble != null) {
|
||||
result = Duration.ONE_MINUTE.times(minutesAsDouble.longValue());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void fillConfigurations() {
|
||||
this.sailingService.getPreviousTracTracConfigurations(new MarkedAsyncCallback<List<TracTracConfigurationDTO>>(
|
||||
new AsyncCallback<List<TracTracConfigurationDTO>>() {
|
||||
@@ -551,7 +580,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
}));
|
||||
}
|
||||
|
||||
private void trackSelectedRaces(boolean trackWind, boolean correctWind, final boolean simulateWithStartTimeNow, boolean ignoreTracTracMarkPassings) {
|
||||
private void trackSelectedRaces(boolean trackWind, boolean correctWind, final Duration offsetToStartTimeOfSimulatedRace, boolean ignoreTracTracMarkPassings) {
|
||||
String liveURI = liveURITextBox.getValue();
|
||||
String storedURI = storedURITextBox.getValue();
|
||||
String courseDesignUpdateURI = tracTracUpdateURITextBox.getValue();
|
||||
@@ -577,7 +606,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
}
|
||||
if (checkBoatClassOK(selectedRegatta, selectedRaces)) {
|
||||
sailingService.trackWithTracTrac(regattaIdentifier, selectedRaces, liveURI, storedURI,
|
||||
courseDesignUpdateURI, trackWind, correctWind, simulateWithStartTimeNow, ignoreTracTracMarkPassings, tractracUsername,
|
||||
courseDesignUpdateURI, trackWind, correctWind, offsetToStartTimeOfSimulatedRace, ignoreTracTracMarkPassings, tractracUsername,
|
||||
tractracPassword, new MarkedAsyncCallback<Void>(new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
|
||||
+2
-2
@@ -30,8 +30,8 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
|
||||
private boolean redrawAllMarkersPendingForMinMaxBeingInitialized;
|
||||
|
||||
public RaceTimePanel(Timer timer, TimeRangeWithZoomProvider timeRangeProvider, StringMessages stringMessages,
|
||||
RaceTimesInfoProvider raceTimesInfoProvider, boolean canReplayWhileLiveIsPossible) {
|
||||
super(timer, timeRangeProvider, stringMessages, canReplayWhileLiveIsPossible);
|
||||
RaceTimesInfoProvider raceTimesInfoProvider, boolean canReplayWhileLiveIsPossible, boolean isScreenLargeEnoughToOfferChartSupport) {
|
||||
super(timer, timeRangeProvider, stringMessages, canReplayWhileLiveIsPossible, isScreenLargeEnoughToOfferChartSupport);
|
||||
this.raceTimesInfoProvider = raceTimesInfoProvider;
|
||||
selectedRace = null;
|
||||
autoAdjustPlayMode = true;
|
||||
|
||||
+2
-1
@@ -86,6 +86,7 @@ import com.sap.sailing.gwt.ui.shared.TrackFileImportDeviceIdentifierDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.VenueDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
@@ -116,7 +117,7 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
|
||||
|
||||
void trackWithTracTrac(RegattaIdentifier regattaToAddTo, Iterable<TracTracRaceRecordDTO> rrs, String liveURI,
|
||||
String storedURI, String courseDesignUpdateURI, boolean trackWind, boolean correctWindByDeclination,
|
||||
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword) throws Exception;
|
||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, String tracTracUsername, String tracTracPassword) throws Exception;
|
||||
|
||||
void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, Iterable<SwissTimingRaceRecordDTO> rrs, String hostname, int port,
|
||||
boolean trackWind, boolean correctWindByDeclination, boolean useInternalMarkPassingAlgorithm) throws Exception;
|
||||
|
||||
+5
-4
@@ -78,6 +78,7 @@ import com.sap.sailing.gwt.ui.shared.TrackFileImportDeviceIdentifierDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.VenueDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
@@ -114,10 +115,10 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan
|
||||
* @param liveURI
|
||||
* may be <code>null</code> or the empty string in which case the server will use the
|
||||
* {@link TracTracRaceRecordDTO#liveURI} from the <code>rr</code> race record.
|
||||
* @param simulateWithStartTimeNow
|
||||
* if <code>true</code>, the connector will adjust the time stamps of all events received such that the
|
||||
* @param offsetToStartTimeOfSimulatedRace
|
||||
* if not <code>null</code>, the connector will adjust the time stamps of all events received such that the
|
||||
* first mark passing for the first waypoint will be set to "now." It will delay the forwarding of all
|
||||
* events received such that they seem to be sent in "real-time." So, more or less the time points
|
||||
* events received such that they seem to be sent in "real-time" plus the <code>offsetToStartTimeOfSimulatedRace</code>. So, more or less the time points
|
||||
* attached to the events sent to the receivers will again approximate the wall time.
|
||||
* @param useInternalMarkPassingAlgorithm
|
||||
* whether or not to ignore the TracTrac-provided mark passings; if <code>true</code>, a separate mark
|
||||
@@ -128,7 +129,7 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan
|
||||
*/
|
||||
void trackWithTracTrac(RegattaIdentifier regattaToAddTo, Iterable<TracTracRaceRecordDTO> rrs, String liveURI,
|
||||
String storedURI, String courseDesignUpdateURI, boolean trackWind, boolean correctWindByDeclination,
|
||||
boolean simulateWithStartTimeNow, boolean useInternalMarkPassingAlgorithm, String tracTracUsername,
|
||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, String tracTracUsername,
|
||||
String tracTracPassword, AsyncCallback<Void> callback);
|
||||
|
||||
void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, Iterable<SwissTimingRaceRecordDTO> rrs,
|
||||
|
||||
+10
-3
@@ -325,7 +325,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String messagingPortNumber();
|
||||
String servletPortNumber();
|
||||
String registeredAt(String string);
|
||||
String replicatingFromMaster(String hostname, int jmsPort, int servletPort);
|
||||
String replicatingFromMaster(String hostname, int jmsPort, int servletPort, String messagingHostname, String exchangeName);
|
||||
String showWindSpeedSeries();
|
||||
String showWindDirectionSeries();
|
||||
String fleet();
|
||||
@@ -361,7 +361,8 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String successfullyUpdatedScores();
|
||||
String errorUpdatingScoresForLeaderboard(String leaderboardName, String message);
|
||||
String maneuverTypesToShowWhenCompetitorIsClicked();
|
||||
String simulateWithStartTimeNow();
|
||||
String simulateAsLiveRace();
|
||||
String simulateWithOffset();
|
||||
String boatClassDoesNotMatchSelectedRegatta(String boatClass);
|
||||
String regattaExistForSelectedBoatClass();
|
||||
String reload();
|
||||
@@ -436,7 +437,8 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String overallDetailsToShow();
|
||||
String hhmmssUnit();
|
||||
String actionAddWindData();
|
||||
String valueMustBeBetweenMinMax(String name, String minValue, String maxValue);
|
||||
String valueMustBeBetweenMinMax(String name, int minValue, int maxValue);
|
||||
String valueMustBeGreaterThan(String name, String minValue);
|
||||
String optional();
|
||||
String pleaseEnterAValue();
|
||||
String latitude();
|
||||
@@ -503,6 +505,8 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String sideToWhichMarkAtLegStartWasRounded();
|
||||
String raceIsLive(String raceName);
|
||||
String racesAreLive(String raceNames);
|
||||
String regattaIsLive(String regattaName);
|
||||
String regattasAreLive(String regattaNames);
|
||||
String scoringSchemeHighPointFirstGetsOne();
|
||||
String scoringSchemeHighPointFirstGetsTen();
|
||||
String knotsUnit();
|
||||
@@ -1107,6 +1111,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String invalidSelection();
|
||||
String advancePassId();
|
||||
String pleaseSelectAScoringResult();
|
||||
String timeZone();
|
||||
String eventOfficialWebsiteURL();
|
||||
String eventSailorsInfoWebsiteURL();
|
||||
String eventOverviewURL();
|
||||
@@ -1444,4 +1449,6 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
|
||||
String requiresValidRegatta();
|
||||
String couldNotObtainRace(String regattaLikeName, String raceColumnName, String fleetName, String technicalErrorMessage);
|
||||
String errorTryingToCreateEmbeddedMap(String message);
|
||||
String transparentBufferLineOnHover();
|
||||
String bufferLineStrokeWeight();
|
||||
}
|
||||
+9
-2
@@ -336,7 +336,7 @@ courseMiddleLine=Course middle line
|
||||
messagingPortNumber=Messaging port number (0 for default)
|
||||
servletPortNumber=Servlet port number
|
||||
registeredAt=Registered at {0}
|
||||
replicatingFromMaster=Replicating from master {0}, messaging port {1}, servlet port {2}
|
||||
replicatingFromMaster=Replicating from master {0}:{2}, messaging port {3}:{1}, exchange {4}
|
||||
showWindSpeedSeries=Show wind speed data
|
||||
showWindDirectionSeries=Show wind directions data
|
||||
fleet=Fleet
|
||||
@@ -371,7 +371,8 @@ apply=Apply
|
||||
successfullyUpdatedScores=Successfully updated scores
|
||||
errorUpdatingScoresForLeaderboard=Error updating scores for leaderboard {0}: {1}
|
||||
maneuverTypesToShowWhenCompetitorIsClicked=Maneuver types to show when competitor is clicked
|
||||
simulateWithStartTimeNow=Simulate with "now" as start time
|
||||
simulateAsLiveRace=Simulate as live race
|
||||
simulateWithOffset=Offset before start in minutes:
|
||||
boatClassDoesNotMatchSelectedRegatta=The selected races contain boat classes which are not the same as the boat class ''{0}'' of the selected regatta. No races will be loaded.
|
||||
regattaExistForSelectedBoatClass=There is at least one regatta for the selected boat classes. Really create default regatta(s) for those race(s)?
|
||||
reload=Reload
|
||||
@@ -456,6 +457,7 @@ totalAverageSpeedOverGroundTooltip=Average speed over ground across the regatta.
|
||||
hhmmssUnit=hh:mm:ss
|
||||
actionAddWindData=Add wind data
|
||||
valueMustBeBetweenMinMax=The value of ''{0}'' must be between {1} and {2}.
|
||||
valueMustBeGreaterThan=The value of ''{0}'' must be greater than {1}.
|
||||
optional=optional
|
||||
pleaseEnterAValue=Please enter a value.
|
||||
latitude=Latitude
|
||||
@@ -527,6 +529,8 @@ sideToWhichMarkAtLegStartWasRounded=Mark rounded to
|
||||
sideToWhichMarkAtLegStartWasRoundedTooltip=Side to which the mark at leg start was rounded.
|
||||
raceIsLive=Race {0} is live
|
||||
racesAreLive=Races {0} are live
|
||||
regattaIsLive=Regatta {0} is live
|
||||
regattasAreLive=Regattas {0} are live
|
||||
knotsUnit=kts
|
||||
knotsValue={0,number,#0.0} kts
|
||||
knotsRange={0,number,#0.0} - {1,number,#0.0} kts
|
||||
@@ -1078,6 +1082,7 @@ sponsorImageURLs=Sponsor Image URLs
|
||||
invalidSelection=The current selection isn''t valid.
|
||||
advancePassId=Advance Pass ID
|
||||
pleaseSelectAScoringResult=Please select a scoring result...
|
||||
timeZone=Time zone
|
||||
eventOfficialWebsiteURL=Official Website URL
|
||||
eventSailorsInfoWebsiteURL=Sailors Info Website URL
|
||||
eventOverviewURL=Event Overview URL
|
||||
@@ -1411,3 +1416,5 @@ pleaseSelect=Please select
|
||||
requiresValidRegatta=This page requires a valid regatta, race column and fleet name to identify the race to show.
|
||||
couldNotObtainRace=Could not obtain a race with name {1} for fleet {2} for a regatta with name {0}: {3}
|
||||
errorTryingToCreateEmbeddedMap=Error trying to create the embedded map: {0}
|
||||
transparentBufferLineOnHover=Transparent buffer lines on hover of helplines
|
||||
bufferLineStrokeWeight=Buffer line stroke weight
|
||||
+10
-3
@@ -337,7 +337,7 @@ courseMiddleLine=Kursmittellinie
|
||||
messagingPortNumber=Messaging-Portnummer (0 für Default)
|
||||
servletPortNumber=Servlet Portnummer
|
||||
registeredAt=Registriert {0}
|
||||
replicatingFromMaster=Repliziert von master {0}, Messaging Port {1}, Servlet Port {2}
|
||||
replicatingFromMaster=Repliziert von master {0}:{2}, Messaging Port {3}:{1}, Exchange {4}
|
||||
showWindSpeedSeries=Daten für Windgeschwindigkeit zeigen
|
||||
showWindDirectionSeries=Daten für Windrichtung zeigen
|
||||
fleet=Flotte
|
||||
@@ -372,7 +372,8 @@ apply=Übernehmen
|
||||
successfullyUpdatedScores=Ergebnisse erfolgreich aktualisiert
|
||||
errorUpdatingScoresForLeaderboard=Fehler beim Aktualisieren der Ergebnisse für {0}: {1}
|
||||
maneuverTypesToShowWhenCompetitorIsClicked=Anzuzeigende Manövertypen für angeklickte Teilnehmer
|
||||
simulateWithStartTimeNow=Simulieren mit "jetzt" als Startzeit
|
||||
simulateAsLiveRace=Simuliere als Live Rennen
|
||||
simulateWithOffset=Zeit bis zum Start in Minuten:
|
||||
boatClassDoesNotMatchSelectedRegatta=Die ausgewählten Rennen enthalten eine Bootsklasse, die nicht der Bootsklasse der ausgewählten Regatta ''{0}'' entspricht. Es werden keine Rennen geladen.
|
||||
regattaExistForSelectedBoatClass=Es gibt mindestens eine Regatta zu den ausgewählten Bootsklassen. Dennoch Default-Regatta für diese(s) Rennen anlegen?
|
||||
reload=Neu laden
|
||||
@@ -456,7 +457,8 @@ totalAverageSpeedOverGround=\u2205 FüG
|
||||
totalAverageSpeedOverGroundTooltip=Durchschnittliche Fahrt über Grund über die gesamte Regatta.
|
||||
hhmmssUnit=hh:mm:ss
|
||||
actionAddWindData=Winddaten hinzufügen
|
||||
valueMustBeBetweenMinMax=Der Wert von ''{0}'' muß zwischen {1} und {2} sein.
|
||||
valueMustBeBetweenMinMax=Der Wert von ''{0}'' muss zwischen {1} und {2} sein.
|
||||
valueMustBeGreaterThan=Der Wert von ''{0}'' muss größer als {1} sein.
|
||||
optional=optional
|
||||
pleaseEnterAValue=Bitte geben Sie einen Wert ein.
|
||||
latitude=Breite
|
||||
@@ -528,6 +530,8 @@ sideToWhichMarkAtLegStartWasRounded=Tonne gerundet an
|
||||
sideToWhichMarkAtLegStartWasRoundedTooltip=Seite, an der die Bahnmarke am Schenkelstart gerundet wurde
|
||||
raceIsLive=Rennen {0} ist live
|
||||
racesAreLive=Rennen {0} sind live
|
||||
regattaIsLive=Regatta {0} ist live
|
||||
regattasAreLive=Regatten {0} sind live
|
||||
scoringSchemeHighPointFirstGetsOne=High Point System, Gewinner erhält 1 Punkt
|
||||
scoringSchemeHighPointFirstGetsTen=High Point System, Gewinner erhält 10 Punkte
|
||||
knotsUnit=kn
|
||||
@@ -1073,6 +1077,7 @@ sponsorImageURLs=Sponsorenlogo-URLs
|
||||
invalidSelection=Die aktuelle Selektion ist nicht gültig.
|
||||
advancePassId=Pass ID erhöhen
|
||||
pleaseSelectAScoringResult=Bitte ein Ergebnis auswählen...
|
||||
timeZone=Zeitzone
|
||||
eventOfficialWebsiteURL=URL der offiziellen Veranstaltungswebseite
|
||||
eventSailorsInfoWebsiteURL=URL zur Webseite mit Seglerinfos
|
||||
eventOverviewURL=URL der Veranstaltungsübersicht
|
||||
@@ -1402,3 +1407,5 @@ pleaseSelect=Bitte auswählen
|
||||
requiresValidRegatta=Diese Seite benötigt eine gültige Regatta, Rennspalte und einen gültigen Gruppennamen um die anzuzeigende Wettfahrt zu identifizieren.
|
||||
couldNotObtainRace=Wettfahrt namens {1} für Gruppe {2} in einer Regatta names {0} konnte nicht gefunden werden: {3}
|
||||
errorTryingToCreateEmbeddedMap=Fehler beim Erstellen der eingebetteten Karte: {0}
|
||||
transparentBufferLineOnHover=Transparente Pufferlinien bei Maus über Hilfslinien
|
||||
bufferLineStrokeWeight=Linienbreite der Pufferlinien
|
||||
+9
-2
@@ -329,7 +329,7 @@ courseMiddleLine=Средняя линия курса
|
||||
messagingPortNumber=Номер порта обмена сообщениями ( по умолчанию 0)
|
||||
servletPortNumber=Номер порта сервлета
|
||||
registeredAt=Зарегистрирован в {0}
|
||||
replicatingFromMaster=Дублирование с основного {0}, порт передачи обмена сообщениями {1}, порт сервлета {2}
|
||||
replicatingFromMaster=Replicating from master {0}:{2}, messaging port {3}:{1}, exchange {4}
|
||||
showWindSpeedSeries=Показать данные о силе ветра
|
||||
showWindDirectionSeries=Показать данные о направлении ветра
|
||||
fleet=Флот
|
||||
@@ -364,7 +364,8 @@ apply=Применить
|
||||
successfullyUpdatedScores=Очки обновлены успешно
|
||||
errorUpdatingScoresForLeaderboard=Ошибка обновления очков для таблицы лидеров {0}: {1}
|
||||
maneuverTypesToShowWhenCompetitorIsClicked=Типы маневров для отображения при нажатии на участника
|
||||
simulateWithStartTimeNow=Моделирования с "сейчас" в качестве времени начала
|
||||
simulateAsLiveRace=Simulate as live race
|
||||
simulateWithOffset=Offset before start in minutes:
|
||||
boatClassDoesNotMatchSelectedRegatta=Выбранные гонки содержат классы судов не соответствующие классу судов ''{0}'' выбранной регаты.
|
||||
regattaExistForSelectedBoatClass=Есть только одна регата для выбранных классов судов.
|
||||
reload=Перезагрузить
|
||||
@@ -440,6 +441,7 @@ totalAverageSpeedOverGroundTooltip=Средняя скорость относи
|
||||
hhmmssUnit=чч:мм:сс
|
||||
actionAddWindData=Добавить данные о ветре
|
||||
valueMustBeBetweenMinMax=Значение ''{0}''должно быть в пределах от {1} до {2}.
|
||||
valueMustBeGreaterThan=The value of ''{0}'' must be greater than {1}.
|
||||
optional=Дополнительно
|
||||
pleaseEnterAValue=Введите, пожалуйста, значение.
|
||||
latitude=Широта
|
||||
@@ -511,6 +513,8 @@ sideToWhichMarkAtLegStartWasRounded=Отметка округленная до
|
||||
sideToWhichMarkAtLegStartWasRoundedTooltip=Сторона в которую округляется отметка на старте этапа.
|
||||
raceIsLive=Гонка {0} в прямом эфире
|
||||
racesAreLive=Гонки {0} в прямом эфире
|
||||
regattaIsLive=Регата {0} в прямом эфире
|
||||
regattasAreLive=Регаты {0} в прямом эфире
|
||||
knotsUnit=Узлы
|
||||
knotsValue={0,number,#0.0} Узлы
|
||||
knotsRange={0,number,#0.0} - {1,number,#0.0} Узлы
|
||||
@@ -1026,6 +1030,7 @@ imageURLs=Image URLs
|
||||
videoURLs=Video URLs
|
||||
sponsorImageURLs=Sponsor Image URLs
|
||||
pleaseSelectAScoringResult=Please select a scoring result...
|
||||
timeZone=Time zone
|
||||
eventOfficialWebsiteURL=Official Website URL
|
||||
eventSailorsInfoWebsiteURL=Sailors Info Website URL
|
||||
eventOverviewURL=Event Overview URL
|
||||
@@ -1341,3 +1346,5 @@ pleaseSelect=Please select
|
||||
requiresValidRegatta=This page requires a valid regatta, race column and fleet name to identify the race to show.
|
||||
couldNotObtainRace=Could not obtain a race with name {1} for fleet {2} for a regatta with name {0}: {3}
|
||||
errorTryingToCreateEmbeddedMap=Error trying to create the embedded map: {0}
|
||||
transparentBufferLineOnHover=Transparent buffer lines on hover of helplines
|
||||
bufferLineStrokeWeight=Buffer line stroke weight
|
||||
+10
-3
@@ -328,7 +328,7 @@ setFixedPassing=Set time as mark passing
|
||||
maximumSpeedOverGroundInKnotsTooltip=比赛中参赛队的最大实际速度
|
||||
twoMarkControlPoint=2-mark-controlpoint
|
||||
earlyStarters=Early starters
|
||||
replicatingFromMaster=Replicating from master {0}, messaging port {1}, servlet port {2}
|
||||
replicatingFromMaster=Replicating from master {0}:{2}, messaging port {3}:{1}, exchange {4}
|
||||
latitude=Latitude
|
||||
filterByLeaderboard=Filter by Leaderboard
|
||||
fromDeg=从 (角度)
|
||||
@@ -538,6 +538,7 @@ connectors=Connectors
|
||||
dampeningInterval=Dampening Interval
|
||||
trackBasedEstimationWindSourceTypeTooltip=Calculated data from the competitor tracks
|
||||
valueMustBeBetweenMinMax=The value of ''{0}'' must be between {1} and {2}.
|
||||
valueMustBeGreaterThan=The value of ''{0}'' must be greater than {1}.
|
||||
orMultipleEmails=or multiple E-Mails separated by comma
|
||||
searchEvents=Search for events
|
||||
explainNoConnectionsFromReplicas=No connections from a replica found. You can connect replicas by using their AdminConsole.
|
||||
@@ -839,12 +840,16 @@ refreshIntervalMustBeGreaterThanXSeconds=刷新间隔必须大于0秒 {0}
|
||||
authorName=Author name
|
||||
raceIsInStartphase=开始阶段
|
||||
pleaseSelectAScoringResult=Please select a scoring result...
|
||||
timeZone=Time zone
|
||||
portSide=左舷
|
||||
explainReplicationHostname=Hostname where the replication master is running on.
|
||||
igtimiAccounts=Igtimi Accounts
|
||||
windChart=Wind Chart
|
||||
events=活动
|
||||
raceIsLive=Race {0} is live
|
||||
racesAreLive=Races {0} are live
|
||||
regattaIsLive=Regatta {0} is live
|
||||
regattasAreLive=Regattas {0} are live
|
||||
operatorNotContains=Not Contains
|
||||
windwardDistanceToCompetitorFarthestAheadInMetersTooltip=迎/顺风航段时离开上风/下风第一名的平行距离或横风时的实际距离name 名字
|
||||
errorAddingResultImportUrl=Error adding result import URL: {0}
|
||||
@@ -1066,13 +1071,13 @@ polarSheetMinimumConfidenceMeasure=Minimum confidence measure
|
||||
operator=operator
|
||||
tractracUsername=TracTrac username
|
||||
webWindSourceTypeName=Manual
|
||||
raceIsLive=Race {0} is live
|
||||
sapSailingAnalytics=航行分析
|
||||
trackWind=Track Wind
|
||||
rawFixes=All fixes (including outliers)
|
||||
showCompetitorFullNameColumn=Show Competitor Full Name
|
||||
disableRaceFilter=Disable filter
|
||||
simulateWithStartTimeNow=Simulate with "now" as start time
|
||||
simulateAsLiveRace=Simulate as live race
|
||||
simulateWithOffset=Offset before start in minutes:
|
||||
polarSheetOutlierDetectionRadiusTooltip=The radius used in the distance based outlierndetection algorithm.
|
||||
noWindFixesAvailable=No Wind-Fixes available.
|
||||
correctScoreFor=Correct score for competitor {0} in race {1}
|
||||
@@ -1356,3 +1361,5 @@ pleaseSelect=Please select
|
||||
requiresValidRegatta=This page requires a valid regatta, race column and fleet name to identify the race to show.
|
||||
couldNotObtainRace=Could not obtain a race with name {1} for fleet {2} for a regatta with name {0}: {3}
|
||||
errorTryingToCreateEmbeddedMap=Error trying to create the embedded map: {0}
|
||||
transparentBufferLineOnHover=Transparent buffer lines on hover of helplines
|
||||
bufferLineStrokeWeight=Buffer line stroke weight
|
||||
+9
-1
@@ -89,7 +89,13 @@ public class TimePanel<T extends TimePanelSettings> extends SimplePanel implemen
|
||||
private static ClientResources resources = GWT.create(ClientResources.class);
|
||||
protected static TimePanelCss timePanelCss = TimePanelCssResources.INSTANCE.css();
|
||||
|
||||
public TimePanel(Timer timer, TimeRangeWithZoomProvider timeRangeProvider, StringMessages stringMessages, boolean canReplayWhileLiveIsPossible) {
|
||||
/**
|
||||
* @param isScreenLargeEnoughToOfferChartSupport
|
||||
* if <code>true</code>, the right padding will be set such that the time panel lines up with charts such
|
||||
* as the competitor chart or the wind chart shown above it
|
||||
*/
|
||||
public TimePanel(Timer timer, TimeRangeWithZoomProvider timeRangeProvider, StringMessages stringMessages,
|
||||
boolean canReplayWhileLiveIsPossible, boolean isScreenLargeEnoughToOfferChartSupport) {
|
||||
this.timer = timer;
|
||||
this.timeRangeProvider = timeRangeProvider;
|
||||
this.stringMessages = stringMessages;
|
||||
@@ -105,7 +111,9 @@ public class TimePanel<T extends TimePanelSettings> extends SimplePanel implemen
|
||||
timePanelSliderFlowWrapper = new FlowPanel();
|
||||
timePanelSlider.setStyleName("timePanelSlider");
|
||||
timePanelSlider.getElement().getStyle().setPaddingLeft(66, Unit.PX);
|
||||
if (isScreenLargeEnoughToOfferChartSupport) {
|
||||
timePanelSlider.getElement().getStyle().setPaddingRight(66, Unit.PX);
|
||||
}
|
||||
timePanelSliderFlowWrapper.add(timePanelSlider);
|
||||
|
||||
playSpeedImg = resources.timesliderPlaySpeedIcon();
|
||||
|
||||
+3
-1
@@ -83,7 +83,9 @@ public abstract class AbstractRaceChart extends AbsolutePanel implements RaceSel
|
||||
timeRangeWithZoomProvider.addTimeZoomChangeListener(this);
|
||||
timeRangeWithZoomProvider.addTimeRangeChangeListener(this);
|
||||
chartsCss.ensureInjected();
|
||||
busyIndicator = new SimpleBusyIndicator(/* busy */ true, 2.0f, chartsCss.busyIndicatorStyle(), chartsCss.busyIndicatorImageStyle());
|
||||
busyIndicator = new SimpleBusyIndicator(/* busy */ true, 2.0f);
|
||||
busyIndicator.setPanelStyleClass(chartsCss.busyIndicatorStyle());
|
||||
busyIndicator.setImageStyleClass(chartsCss.busyIndicatorImageStyle());
|
||||
settingsButton = createSettingsButton();
|
||||
settingsButton.setStyleName(chartsCss.settingsButtonStyle());
|
||||
settingsButton.addStyleName(chartsCss.settingsButtonBackgroundImage());
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.racemap;
|
||||
|
||||
import com.google.gwt.maps.client.base.LatLng;
|
||||
import com.google.gwt.maps.client.mvc.MVCArray;
|
||||
import com.google.gwt.maps.client.overlays.Polyline;
|
||||
import com.google.gwt.user.client.Timer;
|
||||
|
||||
/**
|
||||
* Moves a {@link Polyline} from its current position to a target position in a given duration with a fixed
|
||||
* {@link #ANIMATION_PERIOD_MILLIS animation interval}. Since the timer may be triggered at non-exact intervals, the
|
||||
* offset per animation tick is calculated based on the current time for each iteration.
|
||||
* <p>
|
||||
*
|
||||
* If an animation is still going on, it is permissible for clients to invoke
|
||||
* {@link #setNextPositionAndTransitionMillis(MVCArray, long)} which will have the effect that from its current position
|
||||
* reached so far the {@link Polyline} will then be animated to the next target position in the specified time interval.
|
||||
*
|
||||
* @author Jonas Dann
|
||||
*
|
||||
*/
|
||||
public class AdvantageLineAnimator extends Timer {
|
||||
/**
|
||||
* Time between two animation steps
|
||||
*/
|
||||
private static final int ANIMATION_PERIOD_MILLIS = 100;
|
||||
|
||||
/**
|
||||
* The polyline to animate by updating its {@link Polyline#getPath() path}
|
||||
*/
|
||||
private final Polyline advantageLine;
|
||||
|
||||
/**
|
||||
* The last time the coordinates in the {@link #advantageLine}'s path were updated
|
||||
*/
|
||||
private long lastTime;
|
||||
|
||||
/**
|
||||
* The remaining time for the animation to move the {@link #advantageLine} to its {@link #nextPosition target
|
||||
* position}. If <code>-1</code>, the {@link #advantageLine} will be moved to its {@link #nextPosition next target
|
||||
* position} in one step.
|
||||
*/
|
||||
private long durationMillis = -1;
|
||||
|
||||
/**
|
||||
* The "to-be" / target position to which to move the {@link #advantageLine}'s path gradually during the remaining
|
||||
* {@link #durationMillis}.
|
||||
*/
|
||||
private MVCArray<LatLng> nextPosition;
|
||||
|
||||
public AdvantageLineAnimator(Polyline advantageLine) {
|
||||
if (advantageLine == null) {
|
||||
throw new NullPointerException("Advantage line must not be null");
|
||||
}
|
||||
this.advantageLine = advantageLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param timeForPositionTransitionMillis if <code>-1</code> then no animation is requested and the {@link #advantageLine} will
|
||||
* be moved to its {@link #nextPosition next target position} in one step.
|
||||
*
|
||||
* @param nextPosition the next target position for the {@link #advantageLine}; if <code>null</code>, no animation will happen at all
|
||||
*/
|
||||
public void setNextPositionAndTransitionMillis(MVCArray<LatLng> nextPosition, long timeForPositionTransitionMillis) {
|
||||
if (nextPosition.getLength() != advantageLine.getPath().getLength()) {
|
||||
throw new IllegalArgumentException("The next animation position for a polyline with "+advantageLine.getPath().getLength()+
|
||||
" elements must have the same number of positions but did have "+nextPosition.getLength());
|
||||
}
|
||||
this.nextPosition = nextPosition;
|
||||
this.lastTime = System.currentTimeMillis();
|
||||
this.durationMillis = timeForPositionTransitionMillis;
|
||||
this.scheduleRepeating(ANIMATION_PERIOD_MILLIS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final long time = System.currentTimeMillis();
|
||||
final double moveFactor; // how much of the delta to the nextPosition shall this tick move the advantage line?
|
||||
if (durationMillis > 0) {
|
||||
long deltaTime = time - lastTime;
|
||||
moveFactor = Math.min(1.0, (double) deltaTime / (double) durationMillis); // don't overshoot
|
||||
durationMillis -= deltaTime;
|
||||
} else {
|
||||
moveFactor = 1;
|
||||
}
|
||||
if (nextPosition != null) {
|
||||
final MVCArray<LatLng> currentPosition = this.advantageLine.getPath();
|
||||
for (int i = 0; i < nextPosition.getLength(); i++) {
|
||||
final LatLng currentLatLng = currentPosition.get(i);
|
||||
final LatLng nextLatLng = nextPosition.get(i);
|
||||
currentPosition.setAt(i, LatLng.newInstance(currentLatLng.getLatitude() + (nextLatLng.getLatitude() - currentLatLng.getLatitude()) * moveFactor,
|
||||
currentLatLng.getLongitude() + (nextLatLng.getLongitude() - currentLatLng.getLongitude()) * moveFactor));
|
||||
}
|
||||
}
|
||||
if (durationMillis <= 0) {
|
||||
cancel();
|
||||
}
|
||||
lastTime = time;
|
||||
}
|
||||
|
||||
public void removeAnimation() {
|
||||
this.durationMillis = -1;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.racemap;
|
||||
|
||||
import com.google.gwt.event.shared.HandlerRegistration;
|
||||
import com.google.gwt.maps.client.events.click.ClickMapHandler;
|
||||
import com.google.gwt.maps.client.events.mouseout.MouseOutMapEvent;
|
||||
import com.google.gwt.maps.client.events.mouseout.MouseOutMapHandler;
|
||||
import com.google.gwt.maps.client.events.mouseover.MouseOverMapEvent;
|
||||
import com.google.gwt.maps.client.events.mouseover.MouseOverMapHandler;
|
||||
import com.google.gwt.maps.client.overlays.Polyline;
|
||||
import com.google.gwt.maps.client.overlays.PolylineOptions;
|
||||
|
||||
public class Hoverline {
|
||||
private static final double TRANSPARENT = 0;
|
||||
private static final double VISIBLE = 0.2d;
|
||||
|
||||
private final Polyline hoverline;
|
||||
private final PolylineOptions options;
|
||||
|
||||
public Hoverline(final Polyline polyline, PolylineOptions polylineOptions, final RaceMap map) {
|
||||
this.options = PolylineOptions.newInstance();
|
||||
this.options.setClickable(polylineOptions.getClickable());
|
||||
this.options.setGeodesic(polylineOptions.getGeodesic());
|
||||
this.options.setMap(polyline.getMap());
|
||||
this.options.setPath(polyline.getPath());
|
||||
this.options.setStrokeColor(polylineOptions.getStrokeColor());
|
||||
this.options.setZindex(polylineOptions.getZindex());
|
||||
this.hoverline = Polyline.newInstance(this.options);
|
||||
this.hoverline.setVisible(false);
|
||||
polyline.addMouseOverHandler(new MouseOverMapHandler() {
|
||||
@Override
|
||||
public void onEvent(MouseOverMapEvent event) {
|
||||
options.setStrokeOpacity(map.getSettings().getTransparentHoverlines() ? TRANSPARENT : VISIBLE);
|
||||
options.setStrokeWeight(map.getSettings().getHoverlineStrokeWeight());
|
||||
options.setVisible(true);
|
||||
hoverline.setOptions(options);
|
||||
}
|
||||
});
|
||||
hoverline.addMouseOutMoveHandler(new MouseOutMapHandler() {
|
||||
@Override
|
||||
public void onEvent(MouseOutMapEvent event) {
|
||||
hoverline.setVisible(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public HandlerRegistration addClickHandler(ClickMapHandler handler) {
|
||||
return this.hoverline.addClickHandler(handler);
|
||||
}
|
||||
|
||||
public HandlerRegistration addMouseOutMoveHandler(MouseOutMapHandler handler) {
|
||||
return this.hoverline.addMouseOutMoveHandler(handler);
|
||||
}
|
||||
|
||||
public HandlerRegistration addMouseOverHandler(MouseOverMapHandler handler) {
|
||||
return this.hoverline.addMouseOverHandler(handler);
|
||||
}
|
||||
}
|
||||
+69
-25
@@ -142,6 +142,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
public static final String GET_RACE_MAP_DATA_CATEGORY = "getRaceMapData";
|
||||
public static final String GET_WIND_DATA_CATEGORY = "getWindData";
|
||||
|
||||
private static final String COMPACT_HEADER_STYLE = "compactHeader";
|
||||
|
||||
private MapWidget map;
|
||||
|
||||
/**
|
||||
@@ -176,6 +178,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
*/
|
||||
private Polyline advantageLine;
|
||||
|
||||
private AdvantageLineAnimator advantageTimer;
|
||||
|
||||
/**
|
||||
* The windward of two Polylines representing a triangle between startline and first mark.
|
||||
*/
|
||||
@@ -534,9 +538,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
RaceMap.this.add(sapLogo);
|
||||
}
|
||||
map.setControls(ControlPosition.LEFT_TOP, combinedWindPanel);
|
||||
combinedWindPanel.getParent().addStyleName("CombinedWindPanelParentDiv");
|
||||
map.setControls(ControlPosition.LEFT_TOP, trueNorthIndicatorPanel);
|
||||
trueNorthIndicatorPanel.getParent().addStyleName("TrueNorthIndicatorPanelParentDiv");
|
||||
adjustLeftControlsIndent();
|
||||
|
||||
RaceMap.this.raceMapImageManager.loadMapIcons(map);
|
||||
map.setSize("100%", "100%");
|
||||
@@ -710,6 +713,10 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
for (CompetitorInfoOverlay infoOverlay : competitorInfoOverlays.values()) {
|
||||
infoOverlay.removeCanvasPositionAndRotationTransition();
|
||||
}
|
||||
// remove the advantage line animation
|
||||
if (advantageTimer != null) {
|
||||
advantageTimer.removeAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
public void redraw() {
|
||||
@@ -766,6 +773,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
final Iterable<CompetitorDTO> competitorsToShow = getCompetitorsToShow();
|
||||
|
||||
if (race != null) {
|
||||
final long transitionTimeInMillis = calculateTimeForPositionTransitionInMillis(newTime, oldTime);
|
||||
final com.sap.sse.common.Util.Triple<Map<CompetitorDTO, Date>, Map<CompetitorDTO, Date>, Map<CompetitorDTO, Boolean>> fromAndToAndOverlap =
|
||||
fixesAndTails.computeFromAndTo(newTime, competitorsToShow, settings.getEffectiveTailLengthInMilliseconds());
|
||||
int requestID = ++boatPositionRequestIDCounter;
|
||||
@@ -777,7 +785,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
final boolean updateMarksAndLinesExceptAdvantageLineInCallback;
|
||||
if (getRaceMapDataForAllOverlappingAndTipsOfNonOverlapping != null) {
|
||||
asyncActionsExecutor.execute(getRaceMapDataForAllOverlappingAndTipsOfNonOverlapping, GET_RACE_MAP_DATA_CATEGORY,
|
||||
getRaceMapDataCallback(oldTime, newTime, fromAndToAndOverlap.getC(), competitorsToShow, requestID,
|
||||
getRaceMapDataCallback(newTime, transitionTimeInMillis, fromAndToAndOverlap.getC(), competitorsToShow, requestID,
|
||||
/* updateMarksAndLinesExceptAdvantageLineInCallback */ true));
|
||||
updateMarksAndLinesExceptAdvantageLineInCallback = false; // don't do this again in the second call that mainly fetches
|
||||
requestID = ++boatPositionRequestIDCounter;
|
||||
@@ -789,7 +797,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
GetRaceMapDataAction getRaceMapDataAction = new GetRaceMapDataAction(sailingService, competitorSelection.getAllCompetitors(), race,
|
||||
useNullAsTimePoint() ? null : newTime, fromAndToAndOverlap.getA(), fromAndToAndOverlap.getB(), /* extrapolate */ true, (settings.isShowSimulationOverlay() ? simulationOverlay.getLegIdentifier() : null));
|
||||
asyncActionsExecutor.execute(getRaceMapDataAction, GET_RACE_MAP_DATA_CATEGORY,
|
||||
getRaceMapDataCallback(oldTime, newTime, fromAndToAndOverlap.getC(), competitorsToShow, requestID,
|
||||
getRaceMapDataCallback(newTime, transitionTimeInMillis, fromAndToAndOverlap.getC(), competitorsToShow, requestID,
|
||||
updateMarksAndLinesExceptAdvantageLineInCallback));
|
||||
|
||||
// draw the wind into the map, get the combined wind
|
||||
@@ -809,7 +817,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
List<com.sap.sse.common.Util.Pair<WindSource, WindTrackInfoDTO>> windSourcesToShow = new ArrayList<com.sap.sse.common.Util.Pair<WindSource, WindTrackInfoDTO>>();
|
||||
if (windInfo != null) {
|
||||
lastCombinedWindTrackInfoDTO = windInfo;
|
||||
showAdvantageLine(competitorsToShow, newTime);
|
||||
showAdvantageLine(competitorsToShow, newTime, transitionTimeInMillis);
|
||||
for (WindSource windSource : windInfo.windTrackInfoByWindSource.keySet()) {
|
||||
WindTrackInfoDTO windTrackInfoDTO = windInfo.windTrackInfoByWindSource.get(windSource);
|
||||
switch (windSource.getType()) {
|
||||
@@ -882,8 +890,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
* the advantage line will be updated.
|
||||
*/
|
||||
private AsyncCallback<RaceMapDataDTO> getRaceMapDataCallback(
|
||||
final Date oldTime,
|
||||
final Date newTime,
|
||||
final long transitionTimeInMillis,
|
||||
final Map<CompetitorDTO, Boolean> hasTailOverlapForCompetitor,
|
||||
final Iterable<CompetitorDTO> competitorsToShow, final int requestID,
|
||||
final boolean updateMarksAndLinesExceptAdvantageLineInCallback) {
|
||||
@@ -908,7 +916,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
startedProcessingRequestID = requestID;
|
||||
// Do boat specific actions
|
||||
Map<CompetitorDTO, List<GPSFixDTO>> boatData = raceMapDataDTO.boatPositions;
|
||||
long timeForPositionTransitionMillis = calculateTimeForPositionTransition(newTime, oldTime);
|
||||
fixesAndTails.updateFixes(boatData, hasTailOverlapForCompetitor, RaceMap.this, transitionTimeInMillis);
|
||||
Iterable<CompetitorDTO> competitorsForWhichNewFixesWereReveiced =
|
||||
fixesAndTails.updateFixes(boatData, hasTailOverlapForCompetitor, RaceMap.this, timeForPositionTransitionMillis);
|
||||
if (!Util.isEmpty(competitorsForWhichNewFixesWereReveiced)) {
|
||||
@@ -916,7 +924,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
showCompetitorInfoOnMap(newTime, timeForPositionTransitionMillis, competitorSelection.getSelectedFilteredCompetitors());
|
||||
// even though the wind data is retrieved by a separate call, re-draw the advantage line because it needs to
|
||||
// adjust to new boat positions
|
||||
showAdvantageLine(competitorsToShow, newTime);
|
||||
showAdvantageLine(competitorsToShow, newTime, transitionTimeInMillis);
|
||||
}
|
||||
if (douglasMarkers != null) {
|
||||
removeAllMarkDouglasPeuckerpoints();
|
||||
@@ -1153,7 +1161,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
}
|
||||
|
||||
private long calculateTimeForPositionTransition(final Date newTime, final Date oldTime) {
|
||||
private long calculateTimeForPositionTransitionInMillis(final Date newTime, final Date oldTime) {
|
||||
final long timeForPositionTransitionMillis;
|
||||
boolean hasTimeJumped = oldTime != null && Math.abs(oldTime.getTime() - newTime.getTime()) > 3*timer.getRefreshInterval();
|
||||
if (timer.getPlayState() == PlayStates.Playing && !hasTimeJumped) {
|
||||
@@ -1177,7 +1185,6 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
Polyline tail = fixesAndTails.getTail(competitorDTO);
|
||||
if (tail == null) {
|
||||
tail = fixesAndTails.createTailAndUpdateIndices(competitorDTO, tailsFromTime, tailsToTime, this);
|
||||
tail.setMap(map);
|
||||
} else {
|
||||
fixesAndTails.updateTail(tail, competitorDTO, tailsFromTime, tailsToTime,
|
||||
(int) (timeForPositionTransitionMillis==-1?-1:timeForPositionTransitionMillis/2));
|
||||
@@ -1241,7 +1248,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
return null;
|
||||
}
|
||||
|
||||
private void showAdvantageLine(Iterable<CompetitorDTO> competitorsToShow, Date date) {
|
||||
private void showAdvantageLine(Iterable<CompetitorDTO> competitorsToShow, Date date, long timeForPositionTransitionMillis) {
|
||||
if (map != null && lastRaceTimesInfo != null && quickRanks != null && lastCombinedWindTrackInfoDTO != null) {
|
||||
boolean drawAdvantageLine = false;
|
||||
if (settings.getHelpLinesSettings().isVisible(HelpLineTypes.ADVANTAGELINE)) {
|
||||
@@ -1307,6 +1314,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
break;
|
||||
}
|
||||
MVCArray<LatLng> nextPath = MVCArray.newInstance();
|
||||
LatLng advantageLinePos1 = calculatePositionAlongRhumbline(posAheadOfFirstBoat,
|
||||
coordinateSystem.mapDegreeBearing(rotatedBearingDeg1), advantageLineLengthInKm / 2.0);
|
||||
LatLng advantageLinePos2 = calculatePositionAlongRhumbline(posAheadOfFirstBoat,
|
||||
@@ -1320,26 +1328,27 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
options.setStrokeOpacity(0.5);
|
||||
|
||||
advantageLine = Polyline.newInstance(options);
|
||||
advantageTimer = new AdvantageLineAnimator(advantageLine);
|
||||
MVCArray<LatLng> pointsAsArray = MVCArray.newInstance();
|
||||
pointsAsArray.insertAt(0, advantageLinePos1);
|
||||
pointsAsArray.insertAt(1, advantageLinePos2);
|
||||
advantageLine.setPath(pointsAsArray);
|
||||
advantageLine.setMap(map);
|
||||
Hoverline advantageHoverline = new Hoverline(advantageLine, options, this);
|
||||
|
||||
advantageLineMouseOverHandler = new AdvantageLineMouseOverMapHandler(
|
||||
bearingOfCombinedWindInDeg, new Date(windFix.measureTimepoint));
|
||||
advantageLine.addMouseOverHandler(advantageLineMouseOverHandler);
|
||||
advantageLine.addMouseOutMoveHandler(new MouseOutMapHandler() {
|
||||
advantageHoverline.addMouseOutMoveHandler(new MouseOutMapHandler() {
|
||||
@Override
|
||||
public void onEvent(MouseOutMapEvent event) {
|
||||
map.setTitle("");
|
||||
}
|
||||
});
|
||||
advantageLine.setMap(map);
|
||||
} else {
|
||||
advantageLine.getPath().removeAt(1);
|
||||
advantageLine.getPath().removeAt(0);
|
||||
advantageLine.getPath().insertAt(0, advantageLinePos1);
|
||||
advantageLine.getPath().insertAt(1, advantageLinePos2);
|
||||
nextPath.push(advantageLinePos1);
|
||||
nextPath.push(advantageLinePos2);
|
||||
advantageTimer.setNextPositionAndTransitionMillis(nextPath, timeForPositionTransitionMillis);
|
||||
advantageLineMouseOverHandler.setTrueWindBearing(bearingOfCombinedWindInDeg);
|
||||
advantageLineMouseOverHandler.setDate(new Date(windFix.measureTimepoint));
|
||||
}
|
||||
@@ -1350,6 +1359,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
if (advantageLine != null) {
|
||||
advantageLine.setMap(null);
|
||||
advantageLine = null;
|
||||
advantageTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1580,20 +1590,20 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
pointsAsArray = MVCArray.newInstance();
|
||||
lineToShowOrRemoveOrUpdate = Polyline.newInstance(options);
|
||||
lineToShowOrRemoveOrUpdate.setPath(pointsAsArray);
|
||||
lineToShowOrRemoveOrUpdate.setMap(map);
|
||||
Hoverline lineToShowOrRemoveOrUpdateHoverline = new Hoverline(lineToShowOrRemoveOrUpdate, options, this);
|
||||
lineToShowOrRemoveOrUpdate.addMouseOverHandler(new MouseOverMapHandler() {
|
||||
@Override
|
||||
public void onEvent(MouseOverMapEvent event) {
|
||||
map.setTitle(lineInfoProvider.getLineInfo());
|
||||
}
|
||||
});
|
||||
lineToShowOrRemoveOrUpdate.addMouseOutMoveHandler(new MouseOutMapHandler() {
|
||||
lineToShowOrRemoveOrUpdateHoverline.addMouseOutMoveHandler(new MouseOutMapHandler() {
|
||||
@Override
|
||||
public void onEvent(MouseOutMapEvent event) {
|
||||
map.setTitle("");
|
||||
}
|
||||
});
|
||||
lineToShowOrRemoveOrUpdate.setMap(map);
|
||||
|
||||
} else {
|
||||
pointsAsArray = lineToShowOrRemoveOrUpdate.getPath();
|
||||
pointsAsArray.removeAt(1);
|
||||
@@ -2347,6 +2357,12 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
updateCoordinateSystemFromSettings();
|
||||
requiredRedraw = true;
|
||||
}
|
||||
if (newSettings.getTransparentHoverlines() != settings.getTransparentHoverlines()) {
|
||||
settings.setTransparentHoverlines(newSettings.getTransparentHoverlines());
|
||||
}
|
||||
if (newSettings.getHoverlineStrokeWeight() != settings.getHoverlineStrokeWeight()) {
|
||||
settings.setHoverlineStrokeWeight(newSettings.getHoverlineStrokeWeight());
|
||||
}
|
||||
if (requiredRedraw) {
|
||||
redraw();
|
||||
}
|
||||
@@ -2469,6 +2485,25 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
map.triggerResize();
|
||||
zoomMapToNewBounds(settings.getZoomSettings().getNewBounds(RaceMap.this));
|
||||
}
|
||||
// Adjust RaceMap headers to avoid overlapping based on the RaceMap width
|
||||
boolean isCompactHeader = this.getOffsetWidth() <= 600;
|
||||
getLeftHeaderPanel().setStyleName(COMPACT_HEADER_STYLE, isCompactHeader);
|
||||
getRightHeaderPanel().setStyleName(COMPACT_HEADER_STYLE, isCompactHeader);
|
||||
|
||||
// Adjust combined wind and true north indicator panel indent, based on the RaceMap height
|
||||
if (combinedWindPanel.getParent() != null && trueNorthIndicatorPanel.getParent() != null) {
|
||||
this.adjustLeftControlsIndent();
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustLeftControlsIndent() {
|
||||
combinedWindPanel.getParent().setStyleName("CombinedWindPanelParentDiv");
|
||||
trueNorthIndicatorPanel.getParent().setStyleName("TrueNorthIndicatorPanelParentDiv");
|
||||
String leftControlsIndentStyle = getLeftControlsIndentStyle();
|
||||
if (leftControlsIndentStyle != null) {
|
||||
combinedWindPanel.getParent().addStyleName(leftControlsIndentStyle);
|
||||
trueNorthIndicatorPanel.getParent().addStyleName(leftControlsIndentStyle);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2512,23 +2547,25 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
public Polyline createTail(final CompetitorDTO competitor, List<LatLng> points) {
|
||||
PolylineOptions options = createTailStyle(competitor, displayHighlighted(competitor));
|
||||
Polyline result = Polyline.newInstance(options);
|
||||
|
||||
MVCArray<LatLng> pointsAsArray = MVCArray.newInstance(points.toArray(new LatLng[0]));
|
||||
result.setPath(pointsAsArray);
|
||||
|
||||
result.addClickHandler(new ClickMapHandler() {
|
||||
result.setMap(map);
|
||||
Hoverline resultHoverline = new Hoverline(result, options, this);
|
||||
final ClickMapHandler clickHandler = new ClickMapHandler() {
|
||||
@Override
|
||||
public void onEvent(ClickMapEvent event) {
|
||||
showCompetitorInfoWindow(competitor, event.getMouseEvent().getLatLng());
|
||||
}
|
||||
});
|
||||
};
|
||||
result.addClickHandler(clickHandler);
|
||||
resultHoverline.addClickHandler(clickHandler);
|
||||
result.addMouseOverHandler(new MouseOverMapHandler() {
|
||||
@Override
|
||||
public void onEvent(MouseOverMapEvent event) {
|
||||
map.setTitle(competitor.getSailID() + ", " + competitor.getName());
|
||||
}
|
||||
});
|
||||
result.addMouseOutMoveHandler(new MouseOutMapHandler() {
|
||||
resultHoverline.addMouseOutMoveHandler(new MouseOutMapHandler() {
|
||||
@Override
|
||||
public void onEvent(MouseOutMapEvent event) {
|
||||
map.setTitle("");
|
||||
@@ -2617,4 +2654,11 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
return mapOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CSS style name to adjust the indent of left controls (combined wind and true north indicator).
|
||||
*/
|
||||
protected String getLeftControlsIndentStyle() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+22
@@ -20,6 +20,10 @@ public class RaceMapSettings extends AbstractSettings {
|
||||
|
||||
private RaceMapHelpLinesSettings helpLinesSettings;
|
||||
|
||||
private boolean transparentHoverlines = false; // as discussed with Stefan on 2015-12-08
|
||||
|
||||
private int hoverlineStrokeWeight = 15; // as discussed with Stefan on 2015-12-08
|
||||
|
||||
private long tailLengthInMilliseconds = 100000l;
|
||||
|
||||
private double buoyZoneRadiusInMeters = 0.0;
|
||||
@@ -55,6 +59,8 @@ public class RaceMapSettings extends AbstractSettings {
|
||||
public RaceMapSettings(RaceMapSettings settings) {
|
||||
this.buoyZoneRadiusInMeters = settings.buoyZoneRadiusInMeters;
|
||||
this.helpLinesSettings = new RaceMapHelpLinesSettings(settings.getHelpLinesSettings().getVisibleHelpLineTypes());
|
||||
this.transparentHoverlines = settings.transparentHoverlines;
|
||||
this.hoverlineStrokeWeight = settings.hoverlineStrokeWeight;
|
||||
this.maneuverTypesToShow = settings.maneuverTypesToShow;
|
||||
this.showDouglasPeuckerPoints = settings.showDouglasPeuckerPoints;
|
||||
this.showOnlySelectedCompetitors = settings.showOnlySelectedCompetitors;
|
||||
@@ -154,6 +160,22 @@ public class RaceMapSettings extends AbstractSettings {
|
||||
this.helpLinesSettings = helpLinesSettings;
|
||||
}
|
||||
|
||||
public boolean getTransparentHoverlines() {
|
||||
return this.transparentHoverlines;
|
||||
}
|
||||
|
||||
public void setTransparentHoverlines(boolean transparentHoverlines) {
|
||||
this.transparentHoverlines = transparentHoverlines;
|
||||
}
|
||||
|
||||
public int getHoverlineStrokeWeight() {
|
||||
return this.hoverlineStrokeWeight;
|
||||
}
|
||||
|
||||
public void setHoverlineStrokeWeight(int hoverlineStrokeWeight) {
|
||||
this.hoverlineStrokeWeight = hoverlineStrokeWeight;
|
||||
}
|
||||
|
||||
public boolean isShowSelectedCompetitorsInfo() {
|
||||
return showSelectedCompetitorsInfo;
|
||||
}
|
||||
|
||||
+22
-2
@@ -24,11 +24,14 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
|
||||
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings.ZoomTypes;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.gwt.client.controls.IntegerBox;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog.Validator;
|
||||
import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent;
|
||||
|
||||
public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<RaceMapSettings> {
|
||||
private static final int MAX_BUOY_ZONE_RADIUS_IN_METERS = 100;
|
||||
private static final int MAX_STROKE_WEIGHT = 33;
|
||||
//Initializing the lists to prevent a null pointer exception in the first validation call
|
||||
private List<Util.Pair<CheckBox, ManeuverType>> checkboxAndManeuverType = new ArrayList<Util.Pair<CheckBox, ManeuverType>>();
|
||||
private List<Util.Pair<CheckBox, ZoomTypes>> checkboxAndZoomType = new ArrayList<Util.Pair<CheckBox,ZoomTypes>>();
|
||||
@@ -43,6 +46,8 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
private CheckBox showSelectedCompetitorsInfoCheckBox;
|
||||
private LongBox tailLengthBox;
|
||||
private DoubleBox buoyZoneRadiusBox;
|
||||
private CheckBox transparentHoverlines;
|
||||
private IntegerBox hoverlineStrokeWeight;
|
||||
private boolean showViewSimulation;
|
||||
|
||||
private final StringMessages stringMessages;
|
||||
@@ -211,6 +216,17 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
vp.add(createHelpLineCheckBox(dialog, HelpLineTypes.STARTLINETOFIRSTMARKTRIANGLE));
|
||||
vp.add(createHelpLineCheckBox(dialog, HelpLineTypes.COURSEGEOMETRY));
|
||||
|
||||
transparentHoverlines = dialog.createCheckbox(stringMessages.transparentBufferLineOnHover());
|
||||
transparentHoverlines.setValue(initialSettings.getTransparentHoverlines());
|
||||
vp.add(transparentHoverlines);
|
||||
|
||||
HorizontalPanel hoverlineStrokeWeightPanel = new HorizontalPanel();
|
||||
Label hoverlineStrokeWeightLabel = new Label(stringMessages.bufferLineStrokeWeight() + ":");
|
||||
hoverlineStrokeWeightPanel.add(hoverlineStrokeWeightLabel);
|
||||
hoverlineStrokeWeight = dialog.createIntegerBox(initialSettings.getHoverlineStrokeWeight(), 3);
|
||||
hoverlineStrokeWeightPanel.add(hoverlineStrokeWeight);
|
||||
vp.add(hoverlineStrokeWeightPanel);
|
||||
|
||||
return vp;
|
||||
}
|
||||
|
||||
@@ -267,6 +283,8 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
result.setBuoyZoneRadiusInMeters(value);
|
||||
}
|
||||
}
|
||||
result.setTransparentHoverlines(transparentHoverlines.getValue());
|
||||
result.setHoverlineStrokeWeight(hoverlineStrokeWeight.getValue());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -304,8 +322,10 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
if (valueToValidate.getHelpLinesSettings().isVisible(HelpLineTypes.BOATTAILS) && valueToValidate.getTailLengthInMilliseconds() <= 0) {
|
||||
errorMessage = stringMessages.tailLengthMustBePositive();
|
||||
} else if (valueToValidate.getHelpLinesSettings().isVisible(HelpLineTypes.BUOYZONE)
|
||||
&& (valueToValidate.getBuoyZoneRadiusInMeters() < 0.0 || valueToValidate.getBuoyZoneRadiusInMeters() > 100.0)) {
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.buoyZone(), "0", "100");
|
||||
&& (valueToValidate.getBuoyZoneRadiusInMeters() < 0 || valueToValidate.getBuoyZoneRadiusInMeters() > MAX_BUOY_ZONE_RADIUS_IN_METERS)) {
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.buoyZone(), 0, 100);
|
||||
} else if (valueToValidate.getHoverlineStrokeWeight() < 0 || valueToValidate.getHoverlineStrokeWeight() > MAX_STROKE_WEIGHT) {
|
||||
errorMessage = stringMessages.valueMustBeBetweenMinMax(stringMessages.bufferLineStrokeWeight(), 0, MAX_STROKE_WEIGHT);
|
||||
}
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
+8
@@ -60,4 +60,12 @@ public class DateAndTimeFormatterUtil {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String getClientTimeZoneAsGMTString() {
|
||||
Date now = new Date();
|
||||
@SuppressWarnings("deprecation")
|
||||
int localeTimezoneOffset = now.getTimezoneOffset();
|
||||
TimeZone localeTimeZone = TimeZone.createTimeZone(localeTimezoneOffset);
|
||||
return localeTimeZone.getGMTString(now);
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
.competitorFilterContainer {
|
||||
width: 400px;
|
||||
max-width: 400px;
|
||||
width: 100%;
|
||||
height: 2.14em;
|
||||
background-color: #FFFFFF;
|
||||
margin-left: 0px;
|
||||
@@ -22,7 +23,7 @@
|
||||
.searchInput {
|
||||
font-size: .933333333333333em;
|
||||
height: 2.142857142857143em;
|
||||
width: 280px;
|
||||
width: 70%;
|
||||
border: none;
|
||||
background-color: #eaeaea;
|
||||
padding: 0;
|
||||
|
||||
+4
-4
@@ -149,15 +149,15 @@ public abstract class ExpandableSortableColumn<C> extends LeaderboardSortableCol
|
||||
*/
|
||||
public void toggleExpansion() {
|
||||
if (isExpansionEnabled()) {
|
||||
final boolean oldBusyState = getLeaderboardPanel().getBusyIndicator().isBusy();
|
||||
getLeaderboardPanel().getBusyIndicator().setBusy(true);
|
||||
final boolean oldBusyState = getLeaderboardPanel().isBusy();
|
||||
getLeaderboardPanel().setBusyState(true);
|
||||
setTogglingInProcess(true);
|
||||
final CellTable<LeaderboardRowDTO> table = getLeaderboardPanel().getLeaderboardTable();
|
||||
if (isExpanded()) {
|
||||
for (AbstractSortableColumnWithMinMax<LeaderboardRowDTO, ?> column : getAllVisibleChildren()) {
|
||||
getLeaderboardPanel().removeColumn(column); // removes only the children currently displayed
|
||||
}
|
||||
getLeaderboardPanel().getBusyIndicator().setBusy(false);
|
||||
getLeaderboardPanel().setBusyState(false);
|
||||
setTogglingInProcess(false);
|
||||
// important: toggle expanded state after asking for all visible children
|
||||
setExpanded(!isExpanded());
|
||||
@@ -177,7 +177,7 @@ public abstract class ExpandableSortableColumn<C> extends LeaderboardSortableCol
|
||||
}
|
||||
getLeaderboardPanel().getLeaderboardTable().redraw();
|
||||
}
|
||||
getLeaderboardPanel().getBusyIndicator().setBusy(oldBusyState);
|
||||
getLeaderboardPanel().setBusyState(oldBusyState);
|
||||
setTogglingInProcess(false);
|
||||
}
|
||||
});
|
||||
|
||||
+1
-1
@@ -258,7 +258,7 @@ public class LeaderboardEntryPoint extends AbstractSailingEntryPoint {
|
||||
result = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null,
|
||||
/* overallDetails */ overallDetails, null,
|
||||
/* autoExpandFirstRace */false, refreshIntervalMillis, numberOfLastRacesToShow,
|
||||
raceColumnSelectionStrategy);
|
||||
raceColumnSelectionStrategy, /* showCompetitorSailIdColumns */ true, /*showCompetitorFullNameColumn*/ true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+58
-46
@@ -102,6 +102,8 @@ import com.sap.sse.gwt.client.ErrorReporter;
|
||||
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
|
||||
import com.sap.sse.gwt.client.async.MarkedAsyncCallback;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.BusyStateChangeListener;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.BusyStateProvider;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator;
|
||||
import com.sap.sse.gwt.client.player.PlayStateListener;
|
||||
import com.sap.sse.gwt.client.player.TimeListener;
|
||||
@@ -122,7 +124,8 @@ import com.sap.sse.gwt.client.useragent.UserAgentDetails;
|
||||
*
|
||||
*/
|
||||
public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayStateListener, DisplayedLeaderboardRowsProvider,
|
||||
Component<LeaderboardSettings>, IsEmbeddableComponent, CompetitorSelectionChangeListener, LeaderboardFetcher {
|
||||
Component<LeaderboardSettings>, IsEmbeddableComponent, CompetitorSelectionChangeListener, LeaderboardFetcher,
|
||||
BusyStateProvider {
|
||||
public static final String LOAD_LEADERBOARD_DATA_CATEGORY = "loadLeaderboardData";
|
||||
|
||||
protected static final NumberFormat scoreFormat = NumberFormat.getFormat("0.##");
|
||||
@@ -296,6 +299,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
private ImageResource playIcon;
|
||||
|
||||
private final BusyIndicator busyIndicator;
|
||||
private final Set<BusyStateChangeListener> busyStateChangeListeners;
|
||||
|
||||
/**
|
||||
* Tells whether the leaderboard settings were explicitly changed by an external call to
|
||||
@@ -344,7 +348,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
private Element elementToBlur;
|
||||
private boolean showSelectionCheckbox;
|
||||
|
||||
private List<LeaderboardUpdateListener> leaderboardUpdateListener;
|
||||
private final List<LeaderboardUpdateListener> leaderboardUpdateListener;
|
||||
|
||||
private boolean initialCompetitorFilterHasBeenApplied = false;
|
||||
private final boolean showCompetitorFilterStatus;
|
||||
@@ -477,8 +481,8 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
break;
|
||||
}
|
||||
|
||||
final boolean oldBusyState = getBusyIndicator().isBusy();
|
||||
getBusyIndicator().setBusy(true);
|
||||
final boolean oldBusyState = isBusy();
|
||||
setBusyState(true);
|
||||
Runnable doWhenNecessaryDetailHasBeenLoaded = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -501,7 +505,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
getLeaderboardTable().sortColumn(raceColumnByRaceName, /* ascending */true);
|
||||
}
|
||||
}
|
||||
getBusyIndicator().setBusy(oldBusyState);
|
||||
setBusyState(oldBusyState);
|
||||
}
|
||||
};
|
||||
if (oldShallAddOverallDetails == shallAddOverallDetails() || oldShallAddOverallDetails || getLeaderboard().hasOverallDetails()) {
|
||||
@@ -669,6 +673,13 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
final String twoLetterIsoCountryCode = competitor.getTwoLetterIsoCountryCode();
|
||||
final String flagImageURL = competitor.getFlagImageURL();
|
||||
|
||||
boolean showBoatColor = !isShowCompetitorFullName() && LeaderboardPanel.this.isEmbedded && preSelectedRace != null;
|
||||
if (showBoatColor) {
|
||||
String competitorColor = LeaderboardPanel.this.competitorSelectionProvider.getColor(
|
||||
competitorFetcher.getCompetitor(object), LeaderboardPanel.this.preSelectedRace).getAsHtml();
|
||||
sb.appendHtmlConstant("<div style=\"border-bottom: 2px solid " + competitorColor + ";\">");
|
||||
}
|
||||
|
||||
if (flagImageURL != null && !flagImageURL.isEmpty()) {
|
||||
sb.appendHtmlConstant("<img src=\"" + flagImageURL + "\" width=\"18px\" height=\"12px\" title=\"" + competitor.getName() + "\"/>");
|
||||
sb.appendHtmlConstant(" ");
|
||||
@@ -685,6 +696,9 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
}
|
||||
}
|
||||
sb.appendEscaped(competitor.getSailID());
|
||||
if (showBoatColor) {
|
||||
sb.appendHtmlConstant("</div>");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1824,7 +1838,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
contentPanel.setStyleName(STYLE_LEADERBOARD_CONTENT);
|
||||
busyIndicator = new SimpleBusyIndicator(false, 0.8f);
|
||||
busyIndicator.ensureDebugId("BusyIndicator");
|
||||
|
||||
busyStateChangeListeners = new HashSet<>();
|
||||
|
||||
// the information panel
|
||||
if (!isEmbedded) {
|
||||
@@ -1920,7 +1934,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
filterClearButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
getBusyIndicator().setBusy(true);
|
||||
setBusyState(true);
|
||||
competitorFilterPanel.clearAllActiveFilters();
|
||||
timeChanged(new Date(), null);
|
||||
}
|
||||
@@ -2237,19 +2251,19 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
@Override
|
||||
public void onSuccess(LeaderboardDTO result) {
|
||||
updateLeaderboard(result);
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
getErrorReporter()
|
||||
.reportError("Error trying to obtain leaderboard contents: " + caught.getMessage(),
|
||||
true /* silentMode */);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2399,32 +2413,13 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
scoreCorrectionLastUpdateTimeLabel.setText("");
|
||||
}
|
||||
|
||||
List<com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO>> liveRaces = leaderboard.getLiveRaces(timer.getLiveTimePointInMillis());
|
||||
boolean hasLiveRace = !liveRaces.isEmpty();
|
||||
boolean hasLiveRace = !leaderboard.getLiveRaces(timer.getLiveTimePointInMillis()).isEmpty();
|
||||
liveRaceLabel.setText(hasLiveRace ? getLiveRacesText() : "");
|
||||
if (hasLiveRace) {
|
||||
String liveRaceText = "";
|
||||
if(liveRaces.size() == 1) {
|
||||
com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO> liveRace = liveRaces.get(0);
|
||||
liveRaceText = stringMessages.raceIsLive("'" + liveRace.getA().getRaceColumnName() + "'");
|
||||
} else {
|
||||
String raceNames = "";
|
||||
for (com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO> liveRace : liveRaces) {
|
||||
raceNames += "'" + liveRace.getA().getRaceColumnName() + "', ";
|
||||
}
|
||||
// remove last ", "
|
||||
raceNames = raceNames.substring(0, raceNames.length() - 2);
|
||||
liveRaceText = stringMessages.racesAreLive(raceNames);
|
||||
}
|
||||
liveRaceLabel.setText(liveRaceText);
|
||||
} else {
|
||||
liveRaceLabel.setText("");
|
||||
}
|
||||
scoreCorrectionLastUpdateTimeLabel.setVisible(!hasLiveRace);
|
||||
liveRaceLabel.setVisible(hasLiveRace);
|
||||
}
|
||||
informLeaderboardUpdateListenersAboutLeaderboardUpdated(leaderboard);
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3147,16 +3142,6 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BusyIndicator getBusyIndicator() {
|
||||
return busyIndicator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBusyIndicator() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Iterable<LeaderboardRowDTO> getSelectedRows() {
|
||||
return leaderboardSelectionModel.getSelectedSet();
|
||||
}
|
||||
@@ -3256,18 +3241,20 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
public String getLiveRacesText() {
|
||||
String result = "";
|
||||
List<com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO>> liveRaces = leaderboard.getLiveRaces(timer.getLiveTimePointInMillis());
|
||||
boolean isMeta = leaderboard.type.isMetaLeaderboard();
|
||||
if (!liveRaces.isEmpty()) {
|
||||
if (liveRaces.size() == 1) {
|
||||
com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO> liveRace = liveRaces.get(0);
|
||||
result = stringMessages.raceIsLive("'" + liveRace.getA().getRaceColumnName() + "'");
|
||||
String text = "'" + liveRace.getA().getRaceColumnName() + "'";
|
||||
result = isMeta ? stringMessages.regattaIsLive(text) : stringMessages.raceIsLive(text);
|
||||
} else {
|
||||
String raceNames = "";
|
||||
String names = "";
|
||||
for (com.sap.sse.common.Util.Pair<RaceColumnDTO, FleetDTO> liveRace : liveRaces) {
|
||||
raceNames += "'" + liveRace.getA().getRaceColumnName() + "', ";
|
||||
names += "'" + liveRace.getA().getRaceColumnName() + "', ";
|
||||
}
|
||||
// remove last ", "
|
||||
raceNames = raceNames.substring(0, raceNames.length() - 2);
|
||||
result = stringMessages.racesAreLive(raceNames);
|
||||
names = names.substring(0, names.length() - 2);
|
||||
result = isMeta ? stringMessages.regattasAreLive(names) : stringMessages.racesAreLive(names);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -3277,4 +3264,29 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS
|
||||
public String getDependentCssClassName() {
|
||||
return "leaderboard";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBusyStateChangeListener(BusyStateChangeListener listener) {
|
||||
busyStateChangeListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeBusyStateChangeListener(BusyStateChangeListener listener) {
|
||||
busyStateChangeListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBusy() {
|
||||
return busyIndicator.isBusy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBusyState(boolean isBusy) {
|
||||
if (busyIndicator.isBusy() != isBusy) {
|
||||
busyIndicator.setBusy(isBusy);
|
||||
for (BusyStateChangeListener listener : busyStateChangeListeners) {
|
||||
listener.onBusyStateChange(isBusy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
-10
@@ -78,11 +78,11 @@ public class LeaderboardSettingsFactory {
|
||||
/* refresh interval */ null, /* name of race to sort */ nameOfRaceToSort,
|
||||
/* ascending */ true, /* updateUponPlayStateChange */ true, raceColumnSelection.getType(),
|
||||
/*showAddedScores*/ false, /*showOverallRacesCompleted*/ false,
|
||||
/*showCompetitorSailIdColumns*/showCompetitorSailIdColumn, /*showCompetitorFullNameColumn*/showCompetitorNameColumn);
|
||||
showCompetitorSailIdColumn, showCompetitorNameColumn);
|
||||
break;
|
||||
case Replay:
|
||||
settings = createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, nameOfRaceToSort, /* autoExpandFirstRace */
|
||||
nameOfRaceColumnToShow != null, showRegattaRank);
|
||||
nameOfRaceColumnToShow != null, showRegattaRank, showCompetitorSailIdColumn, showCompetitorNameColumn);
|
||||
break;
|
||||
}
|
||||
return settings;
|
||||
@@ -127,28 +127,32 @@ public class LeaderboardSettingsFactory {
|
||||
* such a meta leaderboard exists; if multiple such meta leaderboards exist, they are all shown
|
||||
*/
|
||||
public LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
|
||||
List<String> namesOfRacesToShow, String nameOfRaceToSort, boolean autoExpandPreSelectedRace, Boolean showRegattaRank) {
|
||||
List<String> namesOfRacesToShow, String nameOfRaceToSort, boolean autoExpandPreSelectedRace, Boolean showRegattaRank,
|
||||
boolean showCompetitorSailIdColumn, boolean showCompetitorFullNameColumn) {
|
||||
final List<DetailType> overallDetails = createOverallDetailsForShowRegattaRank(showRegattaRank);
|
||||
return createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, overallDetails,
|
||||
nameOfRaceToSort, autoExpandPreSelectedRace, /* refreshIntervalMillis */ null);
|
||||
nameOfRaceToSort, autoExpandPreSelectedRace, /* refreshIntervalMillis */ null,
|
||||
showCompetitorSailIdColumn, showCompetitorFullNameColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #createNewDefaultSettings(List, List, String, boolean, boolean)}, only that an additional refresh interval for auto-refresh
|
||||
* Like {@link #createNewDefaultSettings(List, List, String, boolean, boolean, boolean, boolean)}, only that an additional refresh interval for auto-refresh
|
||||
* may be specified; if <code>null</code>, no auto-refresh shall be performed
|
||||
*/
|
||||
public LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
|
||||
private LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
|
||||
List<String> namesOfRacesToShow, List<DetailType> overallDetailsToShow, String nameOfRaceToSort,
|
||||
boolean autoExpandPreSelectedRace, Long refreshIntervalMillis) {
|
||||
boolean autoExpandPreSelectedRace, Long refreshIntervalMillis, boolean showCompetitorSailIdColumns, boolean showCompetitorFullNameColumn) {
|
||||
return createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, overallDetailsToShow,
|
||||
nameOfRaceToSort, autoExpandPreSelectedRace, refreshIntervalMillis,
|
||||
/* numberOfLastRacesToShow */null, /* raceColumnSelectionStrategy */ RaceColumnSelectionStrategies.EXPLICIT);
|
||||
/* numberOfLastRacesToShow */null, /* raceColumnSelectionStrategy */ RaceColumnSelectionStrategies.EXPLICIT,
|
||||
showCompetitorSailIdColumns, showCompetitorFullNameColumn);
|
||||
}
|
||||
|
||||
public LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
|
||||
List<String> namesOfRacesToShow, List<DetailType> overallDetailsToShow, String nameOfRaceToSort,
|
||||
boolean autoExpandPreSelectedRace, Long refreshIntervalMillis, Integer numberOfLastRacesToShow,
|
||||
RaceColumnSelectionStrategies raceColumnSelectionStrategy) {
|
||||
RaceColumnSelectionStrategies raceColumnSelectionStrategy, boolean showCompetitorSailIdColumns,
|
||||
boolean showCompetitorFullNameColumn) {
|
||||
if (namesOfRaceColumnsToShow != null && namesOfRacesToShow != null) {
|
||||
throw new IllegalArgumentException("Can specify race columns either by column or by race name, not both");
|
||||
}
|
||||
@@ -168,7 +172,7 @@ public class LeaderboardSettingsFactory {
|
||||
autoExpandPreSelectedRace, refreshIntervalMillis, /* sort by column */ nameOfRaceToSort,
|
||||
/* ascending */ true, /* updateUponPlayStateChange */ true, raceColumnSelectionStrategy,
|
||||
/*showAddedScores*/ false, /*showOverallRacesCompleted*/ false,
|
||||
/*showCompetitorSailIdColumns*/true, /*showCompetitorFullNameColumn*/true);
|
||||
showCompetitorSailIdColumns, showCompetitorFullNameColumn);
|
||||
}
|
||||
|
||||
public LeaderboardSettings mergeLeaderboardSettings(LeaderboardSettings settingsWithRaceSelection, LeaderboardSettings settingsWithDetails) {
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ public class LeaderboardUrlConfigurationDialog extends SettingsDialog<Leaderboar
|
||||
}
|
||||
LeaderboardSettings settings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
namesOfRaceColumnsToShow, /* namesOfRacesToShow */null, /* nameOfRaceToSort */null, /* autoExpandPreSelectedRace */
|
||||
false, /* showRegattaRank */ true);
|
||||
false, /* showRegattaRank */ true, /* showCompetitorSailIdColumn */ true, /* showCompetitorFullNameColumn */ true);
|
||||
leaderboardSettingsDialogComponent = new LeaderboardSettingsDialogComponent(settings.getManeuverDetailsToShow(),
|
||||
settings.getLegDetailsToShow(), settings.getRaceDetailsToShow(), settings.getOverallDetailsToShow(), raceList,
|
||||
/* select all races by default */ raceList, new ExplicitRaceColumnSelection(),
|
||||
|
||||
+37
-10
@@ -3,8 +3,10 @@ package com.sap.sailing.gwt.ui.leaderboard;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.gwt.core.shared.GWT;
|
||||
import com.google.gwt.dom.client.Style.FontWeight;
|
||||
@@ -35,7 +37,7 @@ import com.sap.sse.gwt.client.useragent.UserAgentDetails;
|
||||
* A panel managing multiple {@link LeaderboardPanel}s (e.g. from a meta leaderboard) so that the user can switch between them.
|
||||
* @author Frank
|
||||
*/
|
||||
public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSettings> implements TimeListener {
|
||||
public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSettings> implements TimeListener, SelectedLeaderboardChangeProvider {
|
||||
|
||||
private LeaderboardPanel selectedLeaderboardPanel;
|
||||
private FlowPanel selectedLeaderboardFlowPanel;
|
||||
@@ -60,7 +62,8 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
|
||||
private final String metaLeaderboardName;
|
||||
private final boolean isEmbedded;
|
||||
|
||||
private List<LeaderboardUpdateListener> leaderboardUpdateListener;
|
||||
private final Set<LeaderboardUpdateListener> leaderboardUpdateListeners;
|
||||
private final Set<SelectedLeaderboardChangeListener> selectedLeaderboardChangeListeners;
|
||||
|
||||
public MultiLeaderboardPanel(SailingServiceAsync sailingService, String metaLeaderboardName, AsyncActionsExecutor asyncActionsExecutor,
|
||||
Timer timer, boolean isEmbedded, String preselectedLeaderboardName, RaceIdentifier preselectedRace,
|
||||
@@ -81,13 +84,14 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
|
||||
selectedLeaderboardPanel = null;
|
||||
leaderboardNamesAndDisplayNames = new ArrayList<Util.Pair<String, String>>();
|
||||
leaderboardNamesAndSettings = new HashMap<String, LeaderboardSettings>();
|
||||
leaderboardUpdateListener = new ArrayList<LeaderboardUpdateListener>();
|
||||
leaderboardUpdateListeners = new HashSet<LeaderboardUpdateListener>();
|
||||
selectedLeaderboardChangeListeners = new HashSet<SelectedLeaderboardChangeListener>();
|
||||
}
|
||||
|
||||
private LeaderboardSettings getOrCreateLeaderboardSettings(String leaderboardName, LeaderboardSettings currentLeaderboardSettings) {
|
||||
LeaderboardSettings newLeaderboardSettings = leaderboardNamesAndSettings.get(leaderboardName);
|
||||
if(newLeaderboardSettings == null) {
|
||||
newLeaderboardSettings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, false, /* showRegattaRank */ true);
|
||||
newLeaderboardSettings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, false, /* showRegattaRank */ true, /* showCompetitorSailIdColumn */ true, /* showCompetitorFullNameColumn */ true);
|
||||
}
|
||||
if(currentLeaderboardSettings != null) {
|
||||
newLeaderboardSettings = LeaderboardSettingsFactory.getInstance().mergeLeaderboardSettings(newLeaderboardSettings, currentLeaderboardSettings);
|
||||
@@ -152,7 +156,7 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
|
||||
}
|
||||
|
||||
public void addLeaderboardUpdateListener(LeaderboardUpdateListener listener) {
|
||||
this.leaderboardUpdateListener.add(listener);
|
||||
this.leaderboardUpdateListeners.add(listener);
|
||||
}
|
||||
|
||||
public void setLeaderboardNames(List<Util.Pair<String, String>> newLeaderboardNamesAndDisplayNames) {
|
||||
@@ -177,6 +181,10 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
|
||||
});
|
||||
}
|
||||
|
||||
// public LeaderboardPanel getSelectedLeaderboardPanel() {
|
||||
// return selectedLeaderboardPanel;
|
||||
// }
|
||||
//
|
||||
private void updateLeaderboardSelection() {
|
||||
if(leaderboardsTabPanel != null) {
|
||||
leaderboardsTabPanel.clear();
|
||||
@@ -215,16 +223,16 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
|
||||
|
||||
selectedLeaderboardFlowPanel = (FlowPanel) leaderboardsTabPanel.getWidget(newTabIndex);
|
||||
LeaderboardSettings newLeaderboardSettings = getOrCreateLeaderboardSettings(newSelectedLeaderboardName, leaderboardNamesAndSettings.get(selectedLeaderboardName));
|
||||
selectedLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor, newLeaderboardSettings, isEmbedded,
|
||||
LeaderboardPanel newSelectedLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor, newLeaderboardSettings, isEmbedded,
|
||||
/* preselectedRace*/ null, new CompetitorSelectionModel(true), timer,
|
||||
null, newSelectedLeaderboardName, errorReporter, stringMessages, userAgent,
|
||||
showRaceDetails, /* competitorSearchTextBox */ null, /* showSelectionCheckbox */ true, /* raceTimesInfoProvider */null,
|
||||
false, /* adjustTimerDelay */ true, /*autoApplyTopNFilter*/ false, false);
|
||||
selectedLeaderboardFlowPanel.add(selectedLeaderboardPanel);
|
||||
for(LeaderboardUpdateListener listener: leaderboardUpdateListener) {
|
||||
selectedLeaderboardPanel.addLeaderboardUpdateListener(listener);
|
||||
selectedLeaderboardFlowPanel.add(newSelectedLeaderboardPanel);
|
||||
for(LeaderboardUpdateListener listener: leaderboardUpdateListeners) {
|
||||
newSelectedLeaderboardPanel.addLeaderboardUpdateListener(listener);
|
||||
}
|
||||
|
||||
setSelectedLeaderboard(newSelectedLeaderboardPanel);
|
||||
} else {
|
||||
if(selectedLeaderboardPanel != null && selectedLeaderboardFlowPanel != null) {
|
||||
selectedLeaderboardPanel.removeAllListeners();
|
||||
@@ -254,4 +262,23 @@ public class MultiLeaderboardPanel extends AbstractLazyComponent<LeaderboardSett
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSelectedLeaderboardChangeListener(SelectedLeaderboardChangeListener listener) {
|
||||
selectedLeaderboardChangeListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSelectedLeaderboardChangeListener(SelectedLeaderboardChangeListener listener) {
|
||||
selectedLeaderboardChangeListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectedLeaderboard(LeaderboardPanel selectedLeaderboard) {
|
||||
if(this.selectedLeaderboardPanel != selectedLeaderboard) {
|
||||
this.selectedLeaderboardPanel = selectedLeaderboard;
|
||||
for (SelectedLeaderboardChangeListener listener : selectedLeaderboardChangeListeners) {
|
||||
listener.onSelectedLeaderboardChanged(selectedLeaderboardPanel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.sap.sailing.gwt.ui.leaderboard;
|
||||
|
||||
|
||||
/**
|
||||
* Allows UI components to observe a change of the selected leaderboard in a Multi-Leaderboard scenario.
|
||||
*/
|
||||
public interface SelectedLeaderboardChangeListener {
|
||||
|
||||
/**
|
||||
* @param selectedLeaderboard the selected non-<code>null</code> LeaderboardPanel
|
||||
*/
|
||||
void onSelectedLeaderboardChanged(LeaderboardPanel selectedLeaderboard);
|
||||
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.sap.sailing.gwt.ui.leaderboard;
|
||||
|
||||
|
||||
public interface SelectedLeaderboardChangeProvider {
|
||||
|
||||
void addSelectedLeaderboardChangeListener(SelectedLeaderboardChangeListener listener);
|
||||
|
||||
void removeSelectedLeaderboardChangeListener(SelectedLeaderboardChangeListener listener);
|
||||
|
||||
void setSelectedLeaderboard(LeaderboardPanel selectedLeaderboard);
|
||||
}
|
||||
+11
-11
@@ -319,13 +319,13 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
final RowUpdateWhiteboard<LeaderboardRowDTO> whiteboard = new RowUpdateWhiteboard<LeaderboardRowDTO>(
|
||||
EditableLeaderboardPanel.this.getData());
|
||||
getWhiteboardOwner().whiteboardProduced(whiteboard);
|
||||
getBusyIndicator().setBusy(true);
|
||||
setBusyState(true);
|
||||
getSailingService().updateLeaderboardMaxPointsReason(getLeaderboardName(), row.competitor.getIdAsString(),
|
||||
raceColumnName, value == null || value.trim().length() == 0 ? null : MaxPointsReason.valueOf(value.trim()),
|
||||
getLeaderboardDisplayDate(), new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
getErrorReporter().reportError(
|
||||
"Error trying to update max points reason for competitor "
|
||||
+ row.competitor.getName() + " in leaderboard " + getLeaderboardName()
|
||||
@@ -334,7 +334,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Util.Triple<Double, Double, Boolean> newNetAndTotalPointsAndIsCorrected) {
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
row.fieldsByRaceColumnName.get(raceColumnName).reasonForMaxPoints = value == null
|
||||
|| value.length() == 0 ? null : MaxPointsReason.valueOf(value.trim());
|
||||
row.fieldsByRaceColumnName.get(raceColumnName).netPoints = newNetAndTotalPointsAndIsCorrected.getA();
|
||||
@@ -444,14 +444,14 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
final RowUpdateWhiteboard<LeaderboardRowDTO> whiteboard = new RowUpdateWhiteboard<LeaderboardRowDTO>(
|
||||
EditableLeaderboardPanel.this.getData());
|
||||
getWhiteboardOwner().whiteboardProduced(whiteboard);
|
||||
getBusyIndicator().setBusy(true);
|
||||
setBusyState(true);
|
||||
getSailingService().updateLeaderboardScoreCorrection(getLeaderboardName(), row.competitor.getIdAsString(), raceColumnName,
|
||||
value == null || value.trim().length() == 0 ? null : value.trim().equals("n/a") ? null
|
||||
: Double.valueOf(value.trim()), getLeaderboardDisplayDate(),
|
||||
new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
getErrorReporter().reportError("Error trying to update score correction for competitor "+
|
||||
row.competitor.getName()+" in leaderboard "+getLeaderboardName()+
|
||||
" for race "+raceColumnName+": "+t.getMessage()+
|
||||
@@ -460,7 +460,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Util.Triple<Double, Double, Boolean> newNetAndTotalPointsAndIsCorrected) {
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
final LeaderboardEntryDTO leaderboardEntryDTO = row.fieldsByRaceColumnName.get(raceColumnName);
|
||||
leaderboardEntryDTO.netPoints = value == null || value.length() == 0 ? newNetAndTotalPointsAndIsCorrected
|
||||
.getA() : Double.valueOf(value.trim());
|
||||
@@ -523,13 +523,13 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
row.fieldsByRaceColumnName.get(raceColumnName).netPoints, new DialogCallback<Util.Pair<MaxPointsReason, Double>>() {
|
||||
@Override
|
||||
public void ok(final Util.Pair<MaxPointsReason, Double> editedObject) {
|
||||
getBusyIndicator().setBusy(true);
|
||||
setBusyState(true);
|
||||
getSailingService().updateLeaderboardScoreCorrection(getLeaderboardName(), row.competitor.getIdAsString(), raceColumnName,
|
||||
editedObject.getB(), getLeaderboardDisplayDate(),
|
||||
new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
getErrorReporter().reportError("Error trying to update score correction for competitor "+
|
||||
row.competitor.getName()+" in leaderboard "+getLeaderboardName()+
|
||||
" for race "+raceColumnName+": "+t.getMessage()+
|
||||
@@ -543,7 +543,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
new AsyncCallback<Util.Triple<Double, Double, Boolean>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
getErrorReporter().reportError("Error trying to update score correction for competitor "+
|
||||
row.competitor.getName()+" in leaderboard "+getLeaderboardName()+
|
||||
" for race "+raceColumnName+": "+t.getMessage()+
|
||||
@@ -552,7 +552,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
|
||||
@Override
|
||||
public void onSuccess(Util.Triple<Double, Double, Boolean> newNetAndTotalPointsAndIsCorrected) {
|
||||
getBusyIndicator().setBusy(false);
|
||||
setBusyState(false);
|
||||
final LeaderboardEntryDTO leaderboardEntryDTO = row.fieldsByRaceColumnName.get(raceColumnName);
|
||||
leaderboardEntryDTO.reasonForMaxPoints = editedObject.getA();
|
||||
leaderboardEntryDTO.netPoints = newNetAndTotalPointsAndIsCorrected.getA();
|
||||
@@ -584,7 +584,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
String leaderboardName, String leaderboardGroupName, final ErrorReporter errorReporter,
|
||||
final StringMessages stringMessages, UserAgentDetails userAgent) {
|
||||
super(sailingService, asyncActionsExecutor, LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
/* racesToShow */ null, /* namesOfRacesToShow */ null, null, /* autoExpandFirstRace */ false, /* showRegattaRank */ true),
|
||||
/* racesToShow */ null, /* namesOfRacesToShow */ null, null, /* autoExpandFirstRace */ false, /* showRegattaRank */ true, /* showCompetitorSailIdColumn */ true, /* showCompetitorFullNameColumn */ true),
|
||||
new CompetitorSelectionModel(/* hasMultiSelection */true),
|
||||
leaderboardName, errorReporter, stringMessages, userAgent, /* showRaceDetails */ true);
|
||||
suppressedCompetitorsShown = new ListDataProvider<CompetitorDTO>(new ArrayList<CompetitorDTO>());
|
||||
|
||||
+2
-2
@@ -409,11 +409,11 @@ public class MatchAndApplyScoreCorrectionsDialog extends DataEntryDialog<BulkSco
|
||||
|
||||
@Override
|
||||
public void ok(final BulkScoreCorrectionDTO result) {
|
||||
leaderboardPanel.getBusyIndicator().setBusy(true);
|
||||
leaderboardPanel.setBusyState(true);
|
||||
sailingService.updateLeaderboardScoreCorrectionsAndMaxPointsReasons(result, new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
leaderboardPanel.getBusyIndicator().setBusy(false);
|
||||
leaderboardPanel.setBusyState(false);
|
||||
errorReporter.reportError(stringMessages.errorUpdatingScoresForLeaderboard(result.getLeaderboardName(),
|
||||
caught.getMessage()));
|
||||
}
|
||||
|
||||
+3
-3
@@ -214,19 +214,19 @@ public class ResultSelectionAndApplyDialog extends DataEntryDialog<Util.Triple<S
|
||||
final String eventName = providerNameAndEventNameBoatClassNameCapturedWhen.getB();
|
||||
final String boatClassName = providerNameAndEventNameBoatClassNameCapturedWhen.getC().getA();
|
||||
final Date timePointWhenResultPublished = providerNameAndEventNameBoatClassNameCapturedWhen.getC().getB();
|
||||
leaderboardPanel.getBusyIndicator().setBusy(true);
|
||||
leaderboardPanel.setBusyState(true);
|
||||
sailingService.getScoreCorrections(scoreCorrectionProviderName, eventName, boatClassName, timePointWhenResultPublished,
|
||||
new AsyncCallback<RegattaScoreCorrectionDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
leaderboardPanel.getBusyIndicator().setBusy(false);
|
||||
leaderboardPanel.setBusyState(false);
|
||||
errorReporter.reportError(stringMessages.errorObtainingScoreCorrections(scoreCorrectionProviderName,
|
||||
eventName, boatClassName, timePointWhenResultPublished.toString(), caught.getMessage()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(RegattaScoreCorrectionDTO result) {
|
||||
leaderboardPanel.getBusyIndicator().setBusy(false);
|
||||
leaderboardPanel.setBusyState(false);
|
||||
new MatchAndApplyScoreCorrectionsDialog(leaderboardPanel, stringMessages, sailingService,
|
||||
errorReporter, result).show();
|
||||
}
|
||||
|
||||
+2
-1
@@ -151,7 +151,8 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
|
||||
// Use a TimePanel to manage wind chart zoom, although the TimePanel itself is not being displayed;
|
||||
// let the time panel always return to "live" mode.
|
||||
final TimePanel<TimePanelSettings> timePanel = new TimePanel<TimePanelSettings>(
|
||||
timer, timeRangeWithZoomProvider, getStringMessages(), /* canReplayWhileLive */ false) {
|
||||
timer, timeRangeWithZoomProvider, getStringMessages(), /* canReplayWhileLive */ false,
|
||||
/* isScreenLargeEnoughToOfferChartSupport set to true iff wind chart will be displayed */ showWindChart) {
|
||||
protected boolean isLiveModeToBeMadePossible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
+14
-6
@@ -6,6 +6,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.Document;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
@@ -97,7 +98,12 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
sailingService.getRaceboardData(regattaName, raceName, leaderboardName, leaderboardGroupName, eventId, new AsyncCallback<RaceboardDataDTO>() {
|
||||
@Override
|
||||
public void onSuccess(RaceboardDataDTO result) {
|
||||
checkUrlParameters(result, canReplayWhileLiveIsPossible, showMapControls);
|
||||
// Determine if the screen is large enough to display charts such as the competitor chart or the wind chart.
|
||||
// This decision is made once based on the initial screen height. Resizing the window afterwards will have
|
||||
// no impact on the chart support, i.e. they are available/unavailable based on the initial decision.
|
||||
boolean isScreenLargeEnoughToOfferChartSupport = Document.get().getClientHeight() >= 600;
|
||||
checkUrlParameters(result, canReplayWhileLiveIsPossible, showMapControls,
|
||||
isScreenLargeEnoughToOfferChartSupport);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,7 +122,8 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
vp.add(new Label(message));
|
||||
}
|
||||
|
||||
private void checkUrlParameters(RaceboardDataDTO raceboardData, boolean canReplayWhileLiveIsPossible, boolean showMapControls) {
|
||||
private void checkUrlParameters(RaceboardDataDTO raceboardData, boolean canReplayWhileLiveIsPossible, boolean showMapControls,
|
||||
boolean isScreenLargeEnoughToOfferChartSupport) {
|
||||
if (!raceboardData.isValidLeaderboard()) {
|
||||
createErrorPage(getStringMessages().noSuchLeaderboard());
|
||||
return;
|
||||
@@ -148,21 +155,22 @@ public class RaceBoardEntryPoint extends AbstractSailingEntryPoint {
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(sailingService, asyncActionsExecutor, this, singletonList, 5000l /* requestInterval*/);
|
||||
RaceBoardPanel raceBoardPanel = new RaceBoardPanel(sailingService, mediaService, getUserService(), asyncActionsExecutor,
|
||||
raceboardData.getCompetitorAndTheirBoats(), timer, raceSelectionModel, leaderboardName, leaderboardGroupName, eventId,
|
||||
raceboardViewConfig, RaceBoardEntryPoint.this, getStringMessages(), userAgent, raceTimesInfoProvider, showMapControls);
|
||||
raceboardViewConfig, RaceBoardEntryPoint.this, getStringMessages(), userAgent, raceTimesInfoProvider, showMapControls,
|
||||
isScreenLargeEnoughToOfferChartSupport);
|
||||
|
||||
createRaceBoardInOneScreenMode(raceBoardPanel, raceboardViewConfig);
|
||||
}
|
||||
|
||||
private FlowPanel createTimePanel(RaceBoardPanel raceBoardPanel) {
|
||||
FlowPanel timeLineInnerBgPanel = new FlowPanel();
|
||||
FlowPanel timeLineInnerBgPanel = new ResizableFlowPanel();
|
||||
timeLineInnerBgPanel.addStyleName("timeLineInnerBgPanel");
|
||||
timeLineInnerBgPanel.add(raceBoardPanel.getTimePanel());
|
||||
|
||||
FlowPanel timeLineInnerPanel = new FlowPanel();
|
||||
FlowPanel timeLineInnerPanel = new ResizableFlowPanel();
|
||||
timeLineInnerPanel.add(timeLineInnerBgPanel);
|
||||
timeLineInnerPanel.addStyleName("timeLineInnerPanel");
|
||||
|
||||
FlowPanel timelinePanel = new FlowPanel();
|
||||
FlowPanel timelinePanel = new ResizableFlowPanel();
|
||||
timelinePanel.add(timeLineInnerPanel);
|
||||
timelinePanel.addStyleName("timeLinePanel");
|
||||
|
||||
|
||||
+75
-29
@@ -7,6 +7,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
|
||||
import com.google.gwt.core.shared.GWT;
|
||||
import com.google.gwt.dom.client.Document;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
@@ -17,8 +19,10 @@ import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.MenuBar;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.UIObject;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
@@ -79,7 +83,8 @@ import com.sap.sse.security.ui.client.UserService;
|
||||
* @author Frank Mittag, Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeListener, LeaderboardUpdateListener, PopupPositionProvider {
|
||||
public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeListener,
|
||||
LeaderboardUpdateListener, PopupPositionProvider, RequiresResize {
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final MediaServiceAsync mediaService;
|
||||
private final UUID eventId;
|
||||
@@ -123,13 +128,17 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
* @param eventId
|
||||
* an optional event that can be used for "back"-navigation in case the race board shows a race in the
|
||||
* context of an event; may be <code>null</code>.
|
||||
* @param isScreenLargeEnoughToOfferChartSupport
|
||||
* if the screen is large enough to display charts such as the competitor chart or the wind chart, a
|
||||
* padding is provided for the RaceTimePanel that aligns its right border with that of the charts, and
|
||||
* the charts are created. This decision is made once on startup in the {@link RaceBoardEntryPoint} class.
|
||||
*/
|
||||
public RaceBoardPanel(SailingServiceAsync sailingService, MediaServiceAsync mediaService,
|
||||
UserService userService, AsyncActionsExecutor asyncActionsExecutor, Map<CompetitorDTO, BoatDTO> competitorsAndTheirBoats,
|
||||
Timer timer, RaceSelectionProvider theRaceSelectionProvider, String leaderboardName,
|
||||
String leaderboardGroupName, UUID eventId, RaceBoardViewConfiguration raceboardViewConfiguration,
|
||||
ErrorReporter errorReporter, final StringMessages stringMessages,
|
||||
UserAgentDetails userAgent, RaceTimesInfoProvider raceTimesInfoProvider, boolean showMapControls) {
|
||||
UserAgentDetails userAgent, RaceTimesInfoProvider raceTimesInfoProvider, boolean showMapControls, boolean isScreenLargeEnoughToOfferChartSupport) {
|
||||
this.sailingService = sailingService;
|
||||
this.mediaService = mediaService;
|
||||
this.stringMessages = stringMessages;
|
||||
@@ -146,7 +155,7 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
selectedRaceIdentifier = raceSelectionProvider.getSelectedRaces().iterator().next();
|
||||
this.setRaceBoardName(selectedRaceIdentifier.getRaceName());
|
||||
this.asyncActionsExecutor = asyncActionsExecutor;
|
||||
FlowPanel mainPanel = new FlowPanel();
|
||||
FlowPanel mainPanel = new ResizableFlowPanel();
|
||||
mainPanel.setSize("100%", "100%");
|
||||
setWidget(mainPanel);
|
||||
raceInformationHeader = new FlowPanel();
|
||||
@@ -161,7 +170,33 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
raceMapResources.combinedWindPanelStyle().ensureInjected();
|
||||
raceMap = new RaceMap(sailingService, asyncActionsExecutor, errorReporter, timer,
|
||||
competitorSelectionProvider, stringMessages, showMapControls, getConfiguration().isShowViewStreamlets(), getConfiguration().isShowViewStreamletColors(), getConfiguration().isShowViewSimulation(),
|
||||
selectedRaceIdentifier, raceMapResources.combinedWindPanelStyle(), /* showHeaderPanel */ true);
|
||||
selectedRaceIdentifier, raceMapResources.combinedWindPanelStyle(), /* showHeaderPanel */ true) {
|
||||
private static final String INDENT_SMALL_CONTROL_STYLE = "indentsmall";
|
||||
private static final String INDENT_BIG_CONTROL_STYLE = "indentbig";
|
||||
@Override
|
||||
public void onResize() {
|
||||
super.onResize();
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
// Show/hide the leaderboard panels toggle button text based on the race map height
|
||||
leaderboardAndMapViewer.setLeftComponentToggleButtonTextVisibilityAndDraggerPosition(raceMap.getOffsetHeight() > 400);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLeftControlsIndentStyle() {
|
||||
// Calculate style name for left control indent based on race map height an leaderboard panel visibility
|
||||
if (raceMap.getOffsetHeight() <= 300) {
|
||||
return INDENT_BIG_CONTROL_STYLE;
|
||||
}
|
||||
if (leaderboardPanel.isVisible() && raceMap.getOffsetHeight() <= 500) {
|
||||
return INDENT_SMALL_CONTROL_STYLE;
|
||||
}
|
||||
return super.getLeftControlsIndentStyle();
|
||||
}
|
||||
};
|
||||
CompetitorFilterPanel competitorSearchTextBox = new CompetitorFilterPanel(competitorSelectionProvider, stringMessages, raceMap,
|
||||
new LeaderboardFetcher() {
|
||||
@Override
|
||||
@@ -172,11 +207,14 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
raceMap.getLeftHeaderPanel().add(raceInformationHeader);
|
||||
raceMap.getRightHeaderPanel().add(regattaAndRaceTimeInformationHeader);
|
||||
|
||||
leaderboardPanel = createLeaderboardPanel(leaderboardName, leaderboardGroupName, competitorSearchTextBox);
|
||||
// Determine if the screen is large enough to initially display the leaderboard panel on the left side of the
|
||||
// map based on the initial screen width. Afterwards, the leaderboard panel visibility can be toggled as usual.
|
||||
boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard = Document.get().getClientWidth() >= 1024;
|
||||
leaderboardPanel = createLeaderboardPanel(leaderboardName, leaderboardGroupName, competitorSearchTextBox, isScreenLargeEnoughToInitiallyDisplayLeaderboard);
|
||||
leaderboardPanel.setTitle(stringMessages.leaderboard());
|
||||
leaderboardPanel.getElement().getStyle().setMarginLeft(6, Unit.PX);
|
||||
leaderboardPanel.getElement().getStyle().setMarginTop(10, Unit.PX);
|
||||
createOneScreenView(leaderboardName, leaderboardGroupName, eventId, mainPanel, showMapControls, raceMap, userService); // initializes the raceMap field
|
||||
createOneScreenView(leaderboardName, leaderboardGroupName, eventId, mainPanel, showMapControls, isScreenLargeEnoughToOfferChartSupport, isScreenLargeEnoughToInitiallyDisplayLeaderboard, raceMap, userService); // initializes the raceMap field
|
||||
leaderboardPanel.addLeaderboardUpdateListener(this);
|
||||
// in case the URL configuration contains the name of a competitors filter set we try to activate it
|
||||
// FIXME the competitorsFilterSets has now moved to CompetitorSearchTextBox (which should probably be renamed); pass on the parameters to the LeaderboardPanel and see what it does with it
|
||||
@@ -190,7 +228,7 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
}
|
||||
}
|
||||
timePanel = new RaceTimePanel(timer, timeRangeWithZoomModel, stringMessages, raceTimesInfoProvider,
|
||||
raceboardViewConfiguration.isCanReplayDuringLiveRaces());
|
||||
raceboardViewConfiguration.isCanReplayDuringLiveRaces(), isScreenLargeEnoughToOfferChartSupport);
|
||||
timeRangeWithZoomModel.addTimeZoomChangeListener(timePanel);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(timePanel);
|
||||
raceSelectionProvider.addRaceSelectionChangeListener(timePanel);
|
||||
@@ -198,15 +236,22 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
}
|
||||
|
||||
/**
|
||||
* @param event an optional event; may be <code>null</code> or else can be used to show some context information in
|
||||
* @param event
|
||||
* an optional event; may be <code>null</code> or else can be used to show some context information in
|
||||
* the {@link GlobalNavigationPanel}.
|
||||
* @param isScreenLargeEnoughToOfferChartSupport
|
||||
* if the screen is large enough to display charts such as the competitor chart or the wind chart, a
|
||||
* padding is provided for the RaceTimePanel that aligns its right border with that of the charts, and
|
||||
* the charts are created.
|
||||
* @param isScreenLargeEnoughToInitiallyDisplayLeaderboard TODO
|
||||
*/
|
||||
private void createOneScreenView(String leaderboardName, String leaderboardGroupName, UUID event, FlowPanel mainPanel,
|
||||
boolean showMapControls, RaceMap raceMap, UserService userService) {
|
||||
boolean showMapControls, boolean isScreenLargeEnoughToOfferChartSupport, boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard, RaceMap raceMap, UserService userService) {
|
||||
// create the default leaderboard and select the right race
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap);
|
||||
raceMap.onRaceSelectionChange(Collections.singletonList(selectedRaceIdentifier));
|
||||
List<Component<?>> components = new ArrayList<Component<?>>();
|
||||
if (isScreenLargeEnoughToOfferChartSupport) {
|
||||
competitorChart = new MultiCompetitorRaceChart(sailingService, asyncActionsExecutor, competitorSelectionProvider, raceSelectionProvider,
|
||||
timer, timeRangeWithZoomModel, stringMessages, errorReporter, true, true, leaderboardGroupName, leaderboardName);
|
||||
competitorChart.onRaceSelectionChange(raceSelectionProvider.getSelectedRaces());
|
||||
@@ -224,6 +269,7 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
editMarkPassingPanel.setLeaderboard(leaderboardPanel.getLeaderboard());
|
||||
editMarkPassingPanel.getEntryWidget().setTitle(stringMessages.editMarkPassings());
|
||||
components.add(editMarkPassingPanel);
|
||||
}
|
||||
boolean autoSelectMedia = getConfiguration().isAutoSelectMedia();
|
||||
MediaPlayerManagerComponent mediaPlayerManagerComponent = new MediaPlayerManagerComponent(
|
||||
selectedRaceIdentifier, raceTimesInfoProvider, timer, mediaService, userService, stringMessages,
|
||||
@@ -233,13 +279,12 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
for (ComponentViewer componentViewer : componentViewers) {
|
||||
mainPanel.add(componentViewer.getViewerWidget());
|
||||
}
|
||||
boolean showLeaderboard = getConfiguration().isShowLeaderboard();
|
||||
if (Document.get().getClientWidth() <= 1024) {
|
||||
showLeaderboard = false;
|
||||
}
|
||||
boolean showLeaderboard = getConfiguration().isShowLeaderboard() && isScreenLargeEnoughToInitiallyDisplayLeaderboard;
|
||||
setLeaderboardVisible(showLeaderboard);
|
||||
if (isScreenLargeEnoughToOfferChartSupport) {
|
||||
setWindChartVisible(getConfiguration().isShowWindChart());
|
||||
setCompetitorChartVisible(getConfiguration().isShowCompetitorsChart());
|
||||
}
|
||||
// make sure to load leaderboard data for filtering to work
|
||||
if (!showLeaderboard) {
|
||||
leaderboardPanel.setVisible(true);
|
||||
@@ -258,13 +303,16 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
}
|
||||
}
|
||||
|
||||
private LeaderboardPanel createLeaderboardPanel(String leaderboardName, String leaderboardGroupName, CompetitorFilterPanel competitorSearchTextBox) {
|
||||
private LeaderboardPanel createLeaderboardPanel(String leaderboardName, String leaderboardGroupName,
|
||||
CompetitorFilterPanel competitorSearchTextBox, boolean isScreenLargeEnoughToInitiallyDisplayLeaderboard) {
|
||||
LeaderboardSettings leaderBoardSettings = LeaderboardSettingsFactory.getInstance()
|
||||
.createNewSettingsForPlayMode(timer.getPlayMode(),
|
||||
/* nameOfRaceToSort */ selectedRaceIdentifier.getRaceName(),
|
||||
/* nameOfRaceColumnToShow */ null, /* nameOfRaceToShow */ selectedRaceIdentifier.getRaceName(),
|
||||
new ExplicitRaceColumnSelectionWithPreselectedRace(selectedRaceIdentifier), /* showRegattaRank */ false,
|
||||
/*showCompetitorSailIdColumn*/true, /*showCompetitorFullNameColumn*/true);
|
||||
/*showCompetitorSailIdColumn*/true,
|
||||
/* don't showCompetitorFullNameColumn in case screen is so small that we don't
|
||||
* even display the leaderboard initially */ isScreenLargeEnoughToInitiallyDisplayLeaderboard);
|
||||
return new LeaderboardPanel(sailingService, asyncActionsExecutor, leaderBoardSettings, selectedRaceIdentifier != null, selectedRaceIdentifier,
|
||||
competitorSelectionProvider, timer, leaderboardGroupName, leaderboardName, errorReporter, stringMessages,
|
||||
userAgent, /* showRaceDetails */ true, competitorSearchTextBox,
|
||||
@@ -345,8 +393,10 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
@Override
|
||||
public void updatedLeaderboard(LeaderboardDTO leaderboard) {
|
||||
leaderboardAndMapViewer.setLeftComponentWidth(leaderboardPanel.getContentPanel().getOffsetWidth());
|
||||
if (editMarkPassingPanel != null) {
|
||||
editMarkPassingPanel.setLeaderboard(leaderboard);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) {
|
||||
@@ -360,7 +410,7 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
if (fleetForRaceName.equals(LeaderboardNameConstants.DEFAULT_FLEET_NAME)) {
|
||||
fleetForRaceName = "";
|
||||
} else {
|
||||
fleetForRaceName = " - "+fleetForRaceName;
|
||||
fleetForRaceName = (seriesName.isEmpty() ? "" : " - ") + fleetForRaceName;
|
||||
}
|
||||
final Label raceNameLabel = new Label(stringMessages.race() + " " + raceColumn.getRaceColumnName());
|
||||
raceNameLabel.setStyleName("RaceName-Label");
|
||||
@@ -370,6 +420,7 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
raceInformationHeader.add(raceNameLabel);
|
||||
raceInformationHeader.add(raceAdditionalInformationLabel);
|
||||
final Anchor regattaNameAnchor = new Anchor(raceIdentifier.getRegattaName());
|
||||
regattaNameAnchor.setTitle(raceIdentifier.getRegattaName());
|
||||
if (eventId != null) {
|
||||
// we don't use the EntryPointLinkFactory here, because of lacking support for Places
|
||||
String debugParam = Window.Location.getParameter("gwt.codesvr");
|
||||
@@ -394,19 +445,6 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
}
|
||||
}
|
||||
regattaNameAnchor.setStyleName("RegattaName-Anchor");
|
||||
|
||||
// TODO: Strange behavior... check
|
||||
// Window.addResizeHandler(new ResizeHandler() {
|
||||
// @Override
|
||||
// public void onResize(ResizeEvent event) {
|
||||
// int headerPanelWidth = raceMap.getRightHeaderPanel().getOffsetWidth() - 150; // 150px is the width of the sapLogo
|
||||
// int raceNameAndFleetLabelWidth = raceInformationHeader.getOffsetWidth();
|
||||
// int regattaAnchorWidth = regattaNameAnchor.getOffsetWidth();
|
||||
// boolean overlap = raceNameAndFleetLabelWidth + regattaAnchorWidth > headerPanelWidth;
|
||||
// raceInformationHeader.setVisible(!overlap);
|
||||
// }
|
||||
// });
|
||||
|
||||
Label raceTimeLabel = computeRaceInformation(raceColumn, fleet);
|
||||
raceTimeLabel.setStyleName("RaceTime-Label");
|
||||
regattaAndRaceTimeInformationHeader.clear();
|
||||
@@ -433,5 +471,13 @@ public class RaceBoardPanel extends SimplePanel implements RaceSelectionChangeLi
|
||||
raceInformationLabel.setText(formatter.format(raceColumn.getStartDate(fleet)));
|
||||
return raceInformationLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResize() {
|
||||
Widget child = getWidget();
|
||||
if (child != null && child instanceof RequiresResize) {
|
||||
((RequiresResize) child).onResize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.sap.sailing.gwt.ui.raceboard;
|
||||
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.google.gwt.user.client.ui.WidgetCollection;
|
||||
|
||||
/**
|
||||
* Utility class extending {@link FlowPanel} and implementing {@link RequiresResize} interface. All
|
||||
* {@link #getChildren() children} also implementing {@link RequiresResize} are informed by calling their
|
||||
* {@link RequiresResize#onResize()} method.
|
||||
*/
|
||||
class ResizableFlowPanel extends FlowPanel implements RequiresResize {
|
||||
@Override
|
||||
public void onResize() {
|
||||
WidgetCollection children = getChildren();
|
||||
for (Widget widget : children) {
|
||||
if (widget instanceof RequiresResize) {
|
||||
((RequiresResize) widget).onResize();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 147 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user