Merge branch 'design2015' of ssh://sapsailing.com/home/trac/git into design2015

# By Christopher Ronnewinkel (D036654) (42) and others
# Via Christopher Ronnewinkel (D036654) (20) and others
* 'design2015' of ssh://sapsailing.com/home/trac/git: (101 commits)
  fixing bug 2789 (device configuration caption panel e-mail uneditable)
  adjusted message texts for "uploaded file" instead of "uploaded image" only
  fixed re-opened bug 1963 comment #23 by showing the flag image, not the competitor image, in the nationality/sail number column in leaderboard if present
  fixed rendering of competitor image and flag image in admin console competitor table wrapper; see bug 1963 comment #23
  fixing bug 2780 by adding flag URI change handling to listener interface and CompetitorImpl setter implementation; leaderboard cache handling updated
  Fixed Leaderboard positioning for lower resolutions
  Fixed aligment of event overview year title
  Added design2015 messages to StringMessages_cn.properties
  added missing dashboard StringMessageProperties to cn file and removed not used ones
  handle sparse-simulation-data-exception; further improvement for finish-phase of opportunist-360;
  consolidated imports
  replaced remove icon by text to make button porpose clearer
  bug1963: also offer image upload for flag image; fixed swapping problem of competitor image and flag image
  Fixed bug2762
  New polars maneuver api uses ManeuverType rather than LegType
  check for zero-speed due to missing wind or polar data; extend get-even-timed-path for the case of two cornerpoints per step; scale turning step of finish-phase 1-turner to layline; fix plausibility check;
  fix finish-phase of opportunist-360 to avoid steep-angle-steps;
  Added chinese translation
  support start-line initialization in tree-grow-360; fix orientation in initial steps of opportunist-360;
  Fixed errors after merge
  ...
This commit is contained in:
Papick Garcia Taboada committed 2015-04-30 13:19:01 +02:00
commit 5f201a5ef7
222 files changed
+6977 -1801

No files matched your search

@@ -77,4 +77,62 @@
height: 22.5pt;
z-index: 1;
}
.wrongOrientationNotification {
position: absolute !important;
top: 50%;
right: 50%;
background-color: white;
z-index: 2;
}
.wrongOrientationNotification_shown {
width: 200px;
height: 200px;
margin-right: -100px;
margin-top: -100px;
border-radius: 100px;
-webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1);
/* older webkit */
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
opacity: 1.0;
}
.wrongOrientationNotification_hidden {
width: 0px;
height: 0px;
marin-right: 0px;
margin-top: 0px;
border-radius: 0px;
overflow: hidden;
-webkit-transition: all 300ms;
/* older webkit */
-webkit-transition: all 300ms;
-moz-transition: all 300ms;
-o-transition: all 300ms;
transition: all 300ms;
opacity: 0.0;
}
.wrongOrientationNotification_logo {
max-width: 40%;
max-height: 40%;
margin: 30%;
margin-top: 23%
}
.wrongOrientationNotification_text {
position: absolute;
width: 100%;
height: 14px;
top: 76%;
line-height: 10px;
text-align: center;
font-weight: bold;
font-size: 13px;
color: grey;
font-family: "Arial";
}
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="false"/>
<stringAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT" value="9998"/>
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sailing.dashboards.gwt.RibDashboard"/>
</listAttribute>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/dashboards/RibDashboard.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.sap.sailing.dashboards.gwt"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.dashboards.gwt/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.dashboards.gwt/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.dashboards.gwt&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-servlet.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt.adminconsole/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war &quot;${project_loc:com.sap.sailing.dashboards.gwt}&quot; -startupUrl /dashboards/RibDashboard.html -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto com.sap.sailing.dashboards.gwt.RibDashboard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XstartOnFirstThread -Xmx2048m"/>
</launchConfiguration>
@@ -4,6 +4,20 @@
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.eclipse.jetty.servlet.DefaultServlet
</servlet-class>
<init-param>
<param-name>dirAllowed</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>useFileMappedBuffer</param-name>
<param-value>false</param-value>
</init-param>
</servlet>
<servlet>
<display-name>Rib Dashboard Service</display-name>
<servlet-name>RibDashboardService</servlet-name>
@@ -8,9 +8,11 @@ import com.googlecode.mgwt.ui.client.MGWTSettings;
import com.googlecode.mgwt.ui.client.MGWTSettings.StatusBarStyle;
import com.googlecode.mgwt.ui.client.MGWTSettings.ViewPort;
import com.googlecode.mgwt.ui.client.MGWTStyle;
import com.sap.sailing.dashboards.gwt.client.i18n.StringMessages;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetriever;
import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetriever;
import com.sap.sailing.gwt.ui.client.SailingService;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.gwt.client.AbstractEntryPoint;
import com.sap.sse.gwt.client.EntryPointHelper;
import com.sap.sse.gwt.client.player.Timer;
@@ -41,4 +41,7 @@ public interface RibDashboardImageResources extends ClientBundle {
@Source("images/settings.png")
ImageResource settings();
@Source("images/rotatedevice.png")
ImageResource rotatedevice();
}
@@ -17,6 +17,12 @@ import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.Widget;
import com.googlecode.mgwt.ui.client.widget.carousel.Carousel;
import com.sap.sailing.dashboards.gwt.client.dataretriever.NumberOfWindBotsChangeListener;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetriever;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetrieverProvider;
import com.sap.sailing.dashboards.gwt.client.eventlogo.EventLogo;
import com.sap.sailing.dashboards.gwt.client.notifications.WrongDeviceOrientationNotification;
import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAnalysisComponent;
import com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartLineAdvantageComponent;
import com.sap.sailing.dashboards.gwt.client.windchart.WindBotComponent;
@@ -89,9 +95,10 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
initWidget(uiBinder.createAndBindUi(this));
initLogos();
windcharthint.getElement().setInnerText(stringConstants.dashboardWindChartHint());
windloadinghintleft.setInnerText(stringConstants.dashboardWindBotLoading());
windloadinghintright.setInnerText(stringConstants.dashboardWindBotLoading());
loadAndDisplayEventLogo(sailingServiceAsync);
windloadinghintleft.setInnerHTML(stringConstants.dashboardWindBotLoadingText()+"<br>"+stringConstants.dashboardWindBotLoadingMessage());
windloadinghintright.setInnerHTML(stringConstants.dashboardWindBotLoadingText()+"<br>"+stringConstants.dashboardWindBotLoadingMessage());
loadAndAddEventLogo(sailingServiceAsync);
initAndAddWrongOrientationNotification();
}
private void initLogos() {
@@ -101,7 +108,7 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
Document.get().getBody().appendChild(logo.getElement());
}
private void loadAndDisplayEventLogo(SailingServiceAsync sailingServiceAsync){
private void loadAndAddEventLogo(SailingServiceAsync sailingServiceAsync){
String eventId = Window.Location.getParameter(EVENT_ID_PARAMETER);
if (eventId != null) {
EventLogo eventLogo = EventLogo.getEventLogoFromEventId(sailingServiceAsync, eventId);
@@ -110,6 +117,11 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
}
}
}
private void initAndAddWrongOrientationNotification(){
WrongDeviceOrientationNotification wrongDeviceOrientationNotification = new WrongDeviceOrientationNotification();
Document.get().getBody().appendChild(wrongDeviceOrientationNotification.getElement());
}
private void initWindBotComponents(List<String> windBotIDs,
WindBotDataRetrieverProvider windBotDataRetrieverProvider) {
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client;
package com.sap.sailing.dashboards.gwt.client.dataretriever;
import java.util.List;
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client;
package com.sap.sailing.dashboards.gwt.client.dataretriever;
import java.util.ArrayList;
import java.util.Collections;
@@ -7,6 +7,7 @@ import java.util.List;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
import com.sap.sailing.dashboards.gwt.client.actions.GetRibDashboardRaceInfoAction;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
@@ -1,7 +1,7 @@
/**
*
*/
package com.sap.sailing.dashboards.gwt.client;
package com.sap.sailing.dashboards.gwt.client.dataretriever;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
@@ -1,8 +1,10 @@
package com.sap.sailing.dashboards.gwt.client;
package com.sap.sailing.dashboards.gwt.client.dataretriever;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
@@ -24,9 +26,13 @@ public class WindBotDataRetriever implements TimeListener, RaceSelectionChangeLi
private List<WindBotDataRetrieverListener> windBotDataRetrieverListeners;
private List<String> windBotIDsInLiveRace;
private static final int WIND_CHART_RESOLUTION_IN_MILLISECONDS = 5000;
public static final String LODA_WIND_CHART_DATA_CATEGORY = "loadWindChartData";
private final Set<String> windSourceTypeNames;
private final int WIND_CHART_RESOLUTION_IN_MILLISECONDS = 5000;
private final int ONE_HOUR_IN_MILLISECONDS = 1000*60*60;
private final String LODA_WIND_CHART_DATA_CATEGORY = "loadWindChartData";
private boolean didInitialLoading;
public WindBotDataRetriever(SailingServiceAsync sailingService) {
this.sailingService = sailingService;
@@ -36,15 +42,17 @@ public class WindBotDataRetriever implements TimeListener, RaceSelectionChangeLi
numberOfWindBotsChangeListeners = new ArrayList<NumberOfWindBotsChangeListener>();
windBotDataRetrieverListeners = new ArrayList<WindBotDataRetrieverListener>();
windBotIDsInLiveRace = new ArrayList<String>();
windSourceTypeNames = new HashSet<>();
windSourceTypeNames.add(WindSourceType.EXPEDITION.name());
}
private void loadWindBotData(Date from, Date to, RegattaAndRaceIdentifier selectedRaceIdentifier) {
if(!didInitialLoading){
didInitialLoading = true;
from = new Date(from.getTime()-1000*60*15);
from = new Date(from.getTime()-ONE_HOUR_IN_MILLISECONDS);
}
GetWindInfoAction getWindInfoAction = new GetWindInfoAction(sailingService, selectedRaceIdentifier, from, to,
WIND_CHART_RESOLUTION_IN_MILLISECONDS, null, /*
WIND_CHART_RESOLUTION_IN_MILLISECONDS, windSourceTypeNames, /*
* onlyUpToNewestEvent==true because we don't want to
* overshoot the evidence so far
*/true);
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client;
package com.sap.sailing.dashboards.gwt.client.dataretriever;
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client;
package com.sap.sailing.dashboards.gwt.client.dataretriever;
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
@@ -3,6 +3,8 @@ package com.sap.sailing.dashboards.gwt.client.device;
import java.util.ArrayList;
import java.util.List;
import com.sap.sse.common.Util.Pair;
/**
*
* @author Alexander Ries (D062114)
@@ -62,8 +64,38 @@ public class Orientation {
}
public void notifiyListenerAboutHeadingChange(double orientationHeading) {
Pair<OrientationType, Double> orienationPair = new Pair<OrientationType, Double>(getOrientationTypeForHeadingInSafari(orientationHeading), new Double(orientationHeading));
for (OrientationListener orientationListener : orientationListeners) {
orientationListener.orientationChanged(orientationHeading);
orientationListener.orientationChanged(orienationPair);
}
}
private OrientationType getOrientationTypeForHeadingInSafari(double heading){
OrientationType orientationType = null;
if (heading > -45 && heading <= 0 || heading > 0 && heading < 45){
orientationType = OrientationType.PORTRAIT_UP;
}else if (heading > 45 && heading < 135){
orientationType = OrientationType.LANDSCAPE_RIGHT;
}else if (heading > 135 && heading <= 180 || heading >=-180 && heading < -135){
orientationType = OrientationType.PORTRAIT_DOWN;
}else if (heading > -135 && heading < -45){
orientationType = OrientationType.LANDSCAPE_LEFT;
}
return orientationType;
}
private OrientationType getOrientationTypeForHeadingInChrome(double heading){
OrientationType orientationType = null;
if (heading > -45 && heading <= 0 || heading > 0 && heading < 45){
orientationType = OrientationType.LANDSCAPE_RIGHT;
}else if (heading > 45 && heading < 135){
orientationType = OrientationType.PORTRAIT_DOWN;
}else if (heading > 135 && heading <= 180 || heading >=-180 && heading < -135){
orientationType = OrientationType.LANDSCAPE_LEFT;
}else if (heading > -135 && heading < -45){
orientationType = OrientationType.PORTRAIT_UP;
}
return orientationType;
}
}
@@ -1,6 +1,11 @@
package com.sap.sailing.dashboards.gwt.client.device;
import com.sap.sse.common.Util.Pair;
public interface OrientationListener {
public void orientationChanged(double orientationHeading);
/**
* Returns a Pair containing the {@link OrientationType} and the exact angle.
* */
public void orientationChanged(Pair <OrientationType, Double> orientation);
}
@@ -0,0 +1,6 @@
package com.sap.sailing.dashboards.gwt.client.device;
public enum OrientationType {
PORTRAIT_UP, PORTRAIT_DOWN, LANDSCAPE_RIGHT, LANDSCAPE_LEFT;
}
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client;
package com.sap.sailing.dashboards.gwt.client.eventlogo;
import java.util.UUID;
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.bottomnotification;
package com.sap.sailing.dashboards.gwt.client.notifications;
import java.util.ArrayList;
import java.util.List;
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.bottomnotification;
package com.sap.sailing.dashboards.gwt.client.notifications;
public interface BottomNotificationClickListener {
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.bottomnotification;
package com.sap.sailing.dashboards.gwt.client.notifications;
import com.sap.sailing.gwt.ui.client.StringMessages;
@@ -0,0 +1,67 @@
package com.sap.sailing.dashboards.gwt.client.notifications;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.sap.sailing.dashboards.gwt.client.RibDashboardImageResources;
import com.sap.sailing.dashboards.gwt.client.device.Orientation;
import com.sap.sailing.dashboards.gwt.client.device.OrientationListener;
import com.sap.sailing.dashboards.gwt.client.device.OrientationType;
import com.sap.sailing.dashboards.gwt.client.visualeffects.BlurEffect;
import com.sap.sse.common.Util.Pair;
public class WrongDeviceOrientationNotification extends AbsolutePanel implements OrientationListener {
private Label rotateDeviceLabel;
public WrongDeviceOrientationNotification() {
super();
this.addStyleName("wrongOrientationNotification");
this.addStyleName("wrongOrientationNotification_hidden");
Image rotateDeviceIcon = new Image();
rotateDeviceIcon.setResource(RibDashboardImageResources.INSTANCE.rotatedevice());
rotateDeviceIcon.getElement().addClassName("wrongOrientationNotification_logo");
add(rotateDeviceIcon);
rotateDeviceLabel = new Label();
rotateDeviceLabel.getElement().addClassName("wrongOrientationNotification_text");
rotateDeviceLabel.setText("Rotate Device");
add(rotateDeviceLabel);
Orientation.getInstance().addListener(this);
Orientation.getInstance().triggerDeviceOrientationRead();
}
public void show() {
this.removeStyleName("wrongOrientationNotification_hidden");
this.addStyleName("wrongOrientationNotification_shown");
BlurEffect.getInstance().addToView(RootLayoutPanel.get());
}
public void hide() {
this.removeStyleName("wrongOrientationNotification_shown");
this.addStyleName("wrongOrientationNotification_hidden");
BlurEffect.getInstance().removeFromView(RootLayoutPanel.get());
}
@Override
public void orientationChanged(Pair<OrientationType, Double> orientation) {
OrientationType orientationType = orientation.getA();
switch (orientationType) {
case PORTRAIT_UP:
show();
break;
case PORTRAIT_DOWN:
show();
break;
case LANDSCAPE_RIGHT:
hide();
break;
case LANDSCAPE_LEFT:
hide();
break;
}
}
}
@@ -75,13 +75,3 @@
transition: margin-top ease-in-out 500ms;
margin-top: -600pt;
}
.blurred {
-webkit-filter: blur(10pt) brightness(0.92);
filter: blur(10pt) brightness(0.92);
}
.not_blurred {
-webkit-filter: blur(0pt) brightness(1);
filter: blur(0pt) brightness(1);
}
@@ -17,6 +17,7 @@ import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.visualeffects.BlurEffect;
import com.sap.sailing.domain.common.dto.CompetitorDTO;
public class CompetitorSelectionPopup extends Composite implements HasWidgets, CompetitorTableRowSelectionListener {
@@ -27,10 +28,6 @@ public class CompetitorSelectionPopup extends Composite implements HasWidgets, C
String popuphide();
String buttonshow();
String blurred();
String not_blurred();
}
@UiField
@@ -68,16 +65,14 @@ public class CompetitorSelectionPopup extends Composite implements HasWidgets, C
this.button.setText("OK");
this.getElement().addClassName(style.popupshow());
this.getElement().removeClassName(style.popuphide());
RootLayoutPanel.get().addStyleName(style.blurred());
RootLayoutPanel.get().removeStyleName(style.not_blurred());
BlurEffect.getInstance().addToView(RootLayoutPanel.get());
isVisible = true;
}
public void hide() {
this.getElement().addClassName(style.popuphide());
this.getElement().removeClassName(style.popupshow());
RootLayoutPanel.get().addStyleName(style.not_blurred());
RootLayoutPanel.get().removeStyleName(style.blurred());
BlurEffect.getInstance().removeFromView(RootLayoutPanel.get());
RootPanel.get().remove(this);
isVisible = false;
}
@@ -10,11 +10,8 @@
}
.settings_button_image {
position: absolute;
height: 23.5pt;
width: 23.5pt;
right: 10pt;
top: 17.5pt;
}
.settings_indication_label {
@@ -5,8 +5,9 @@
type='com.sap.sailing.dashboards.gwt.client.popups.competitorselection.SettingsButtonWithSelectionIndicationLabel.SettingsButtonWithSelectionIndicationLabelStyle'
src='SettingsButtonWithSelectionIndicationLabel.css'></ui:style>
<g:HTMLPanel>
<g:FocusPanel ui:field="settingsButton" styleName="{style.settings_button}"></g:FocusPanel>
<g:Image ui:field="settingsButtonImage" styleName="{style.settings_button_image}"></g:Image>
<g:FocusPanel ui:field="settingsButton" styleName="{style.settings_button}">
<g:Image ui:field="settingsButtonImage" styleName="{style.settings_button_image}"></g:Image>
</g:FocusPanel>
<g:Label ui:field="settingsIndicationLabel" styleName="{style.settings_indication_label}"></g:Label>
</g:HTMLPanel>
</ui:UiBinder>
@@ -136,10 +136,10 @@ public class StartlineAnalysisCard extends Composite implements HasWidgets, Star
com.sap.sse.gwt.client.player.Timer timer = new com.sap.sse.gwt.client.player.Timer(PlayModes.Live, 1000l);
timer.pause();
ArrayList<ZoomTypes> zoomTypes = new ArrayList<ZoomTypes>();
if(startAnalysisDTO.racingProcedureType.equals(RacingProcedureType.GateStart)){
timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds+startAnalysisDTO.tailLenghtInMilliseconds);
if (startAnalysisDTO.racingProcedureType.equals(RacingProcedureType.GateStart)) {
timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds + startAnalysisDTO.tailLenghtInMilliseconds);
zoomTypes.add(ZoomTypes.BUOYS);
}else{
} else {
timer.setTime(startAnalysisDTO.timeOfStartInMilliSeconds);
zoomTypes.add(ZoomTypes.TAILS);
}
@@ -24,9 +24,9 @@ import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.RibDashboardImageResources;
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
import com.sap.sailing.dashboards.gwt.client.bottomnotification.BottomNotification;
import com.sap.sailing.dashboards.gwt.client.bottomnotification.BottomNotificationClickListener;
import com.sap.sailing.dashboards.gwt.client.bottomnotification.BottomNotificationType;
import com.sap.sailing.dashboards.gwt.client.notifications.BottomNotification;
import com.sap.sailing.dashboards.gwt.client.notifications.BottomNotificationClickListener;
import com.sap.sailing.dashboards.gwt.client.notifications.BottomNotificationType;
import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.CompetitorSelectionListener;
import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.CompetitorSelectionPopup;
import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.SettingsButtonWithSelectionIndicationLabel;
@@ -1,8 +1,8 @@
package com.sap.sailing.dashboards.gwt.client.startlineadvantage;
import com.google.gwt.i18n.client.NumberFormat;
import com.sap.sailing.dashboards.gwt.client.RibDashboardDataRetriever;
import com.sap.sailing.dashboards.gwt.client.RibDashboardDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetriever;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAdvantageType;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
@@ -0,0 +1,11 @@
@CHARSET "UTF-8";
.blurred {
-webkit-filter: blur(10pt) brightness(0.92);
filter: blur(10pt) brightness(0.92);
}
.not_blurred {
-webkit-filter: blur(0pt) brightness(1);
filter: blur(0pt) brightness(1);
}
@@ -0,0 +1,34 @@
package com.sap.sailing.dashboards.gwt.client.visualeffects;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.user.client.ui.Widget;
public class BlurEffect {
private static BlurEffect INSTANCE = null;
private VisualEffectsResources visualEffectsResources = GWT.create(VisualEffectsResources.class);
private BlurEffect() {
visualEffectsResources.blurEffectStyle().ensureInjected();
}
public static BlurEffect getInstance() {
synchronized (BlurEffect.class) {
if (INSTANCE == null) {
INSTANCE = new BlurEffect();
}
}
return INSTANCE;
}
public void addToView(Widget widget){
widget.removeStyleName(visualEffectsResources.blurEffectStyle().not_blurred());
widget.addStyleName(visualEffectsResources.blurEffectStyle().blurred());
}
public void removeFromView(Widget widget){
widget.removeStyleName(visualEffectsResources.blurEffectStyle().blurred());
widget.addStyleName(visualEffectsResources.blurEffectStyle().not_blurred());
}
}
@@ -0,0 +1,13 @@
package com.sap.sailing.dashboards.gwt.client.visualeffects;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.CssResource.Shared;
@Shared
public interface BlurEffectStyle extends CssResource{
public String blurred();
public String not_blurred();
}
@@ -0,0 +1,9 @@
package com.sap.sailing.dashboards.gwt.client.visualeffects;
import com.google.gwt.resources.client.ClientBundle;
public interface VisualEffectsResources extends ClientBundle{
@Source("BlurEffect.css")
BlurEffectStyle blurEffectStyle();
}
@@ -26,6 +26,8 @@ import org.moxieapps.gwt.highcharts.client.plotOptions.BarPlotOptions;
import org.moxieapps.gwt.highcharts.client.plotOptions.Marker;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
@@ -90,8 +92,8 @@ public class VerticalWindChart extends Composite implements HasWidgets {
initWidget(uiBinder.createAndBindUi(this));
}
public @UiConstructor VerticalWindChart(String positiveFillColor, String negativeFillColor) {
initVerticalWindChartWithColors(positiveFillColor, negativeFillColor);
public @UiConstructor VerticalWindChart(String positiveFillColorAsHex, String negativeFillColorAsHex) {
initVerticalWindChartWithColors(positiveFillColorAsHex, negativeFillColorAsHex);
initWidget(uiBinder.createAndBindUi(this));
}
@@ -175,18 +177,24 @@ public class VerticalWindChart extends Composite implements HasWidgets {
* {@link #setXAxisExtremesForSeriesPointRangeIsSmallerThanChartDisplayIntervall()} and
* {@link #setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall()}.
* */
public void addPointsToSeriesWithAverage(Point[] points, double average) {
if (verticalWindChartSeries == null) {
initVerticalWindChartSeries();
verticalWindChartSeries.setPoints(points, true);
} else {
for (Point point : points) {
verticalWindChartSeries.addPoint(point, true, false, false);
public void addPointsToSeriesWithAverage(final Point[] points, final double average) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
if (verticalWindChartSeries == null) {
initVerticalWindChartSeries();
verticalWindChartSeries.setPoints(points, true);
} else {
for (Point point : points) {
verticalWindChartSeries.addPoint(point, true, false, false);
}
}
verticalWindChartSeries.updateThreshold("" + average);
adaptVerticalWindChartExtemes();
verticalWindChart.setSizeToMatchContainer();
}
}
verticalWindChartSeries.updateThreshold("" + average);
adaptVerticalWindChartExtemes();
verticalWindChart.setSizeToMatchContainer();
});
}
/**
@@ -194,23 +202,7 @@ public class VerticalWindChart extends Composite implements HasWidgets {
* interval or not. So there are two cases where the extreme points of the x-axis get calculated differently.
* */
private void adaptVerticalWindChartExtemes() {
if (getVerticalWindChartSeriesPointsTimeRangeInMilliseconds() < chartIntervallinMinutes * 60 * 1000) {
setXAxisExtremesForSeriesPointRangeIsSmallerThanChartDisplayIntervall();
} else {
setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall();
}
}
/**
* When the time range of the series points is smaller than the current selected display interval represented by
* either LARGE_DISPLAY_INTERVALL_IN_MINUTES or SMALL_DISPLAY_INTERVALL_IN_MINUTES the x-axis extremes min value is
* the the first points time and the maximum value the min value plus the selected display interval. The chart gets
* other extremes, because the values fit easily into the selected display interval.
* */
private void setXAxisExtremesForSeriesPointRangeIsSmallerThanChartDisplayIntervall() {
long minimumExtremeValueInMillis = getFirstPointOfVerticalWindChartSeries().getX().longValue();
long maximumExtremeValueInMillis = minimumExtremeValueInMillis + chartIntervallinMinutes * 60 * 1000;
verticalWindChart.getXAxis().setExtremes(minimumExtremeValueInMillis, maximumExtremeValueInMillis, true, true);
}
/**
@@ -220,29 +212,11 @@ public class VerticalWindChart extends Composite implements HasWidgets {
* gets other extremes, because the values do not fit anymore into the selected display interval.
* */
private void setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall() {
long maximumExtremeValueInMillis = getLastPointOfVerticalWindChartSeries().getX().longValue();
long minimumExtremeValueInMillis = maximumExtremeValueInMillis - chartIntervallinMinutes * 60 * 1000;
verticalWindChart.getXAxis().setExtremes(minimumExtremeValueInMillis, maximumExtremeValueInMillis, true, true);
long maximumExtremeValueInMillis = getLastPointOfVerticalWindChartSeries().getX().longValue();
long minimumExtremeValueInMillis = maximumExtremeValueInMillis - chartIntervallinMinutes * 60 * 1000;
verticalWindChart.getXAxis().setExtremes(minimumExtremeValueInMillis, maximumExtremeValueInMillis, true, true);
}
private long getVerticalWindChartSeriesPointsTimeRangeInMilliseconds() {
Point[] seriesPoints = verticalWindChartSeries.getPoints();
long pointRangeInMilliseconds;
int seriesPointsLenght = seriesPoints.length;
if (seriesPointsLenght > 0 && seriesPoints[0].getX() != null) {
long earliesPointAsTimestamp = seriesPoints[0].getX().longValue();
long latestPointAsTimestamp;
if (seriesPointsLenght > 1) {
latestPointAsTimestamp = seriesPoints[seriesPointsLenght - 1].getX().longValue();
} else {
latestPointAsTimestamp = earliesPointAsTimestamp;
}
pointRangeInMilliseconds = latestPointAsTimestamp - earliesPointAsTimestamp;
} else {
pointRangeInMilliseconds = 0;
}
return pointRangeInMilliseconds;
}
private Point getLastPointOfVerticalWindChartSeries() {
Point lastPointOfVerticalWindChartSeries = null;
@@ -256,16 +230,6 @@ public class VerticalWindChart extends Composite implements HasWidgets {
return lastPointOfVerticalWindChartSeries;
}
private Point getFirstPointOfVerticalWindChartSeries() {
Point firstPointOfVerticalWindChartSeries = null;
Point[] seriesPoints = verticalWindChartSeries.getPoints();
int seriesPointsLenght = seriesPoints.length;
if (seriesPointsLenght > 0) {
firstPointOfVerticalWindChartSeries = seriesPoints[0];
}
return firstPointOfVerticalWindChartSeries;
}
public void addVerticalWindChartClickListener(VerticalWindChartClickListener verticalWindChartClickListener) {
verticalWindChartClickListeners.add(verticalWindChartClickListener);
}
@@ -291,8 +255,13 @@ public class VerticalWindChart extends Composite implements HasWidgets {
} else {
chartIntervallinMinutes = SMALL_DISPLAY_INTERVALL_IN_MINUTES;
}
adaptVerticalWindChartExtemes();
notifyVerticalWindChartClickListeners(chartIntervallinMinutes);
Scheduler.get().scheduleFinally(new ScheduledCommand() {
@Override
public void execute() {
adaptVerticalWindChartExtemes();
notifyVerticalWindChartClickListeners(chartIntervallinMinutes);
}});
}
@Override
@@ -15,8 +15,8 @@ import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.RibDashboardDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.client.WindBotDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.client.startlineadvantage.LiveAverageComponent;
import com.sap.sailing.dashboards.gwt.client.windchart.compass.LocationPointerCompass;
import com.sap.sailing.dashboards.gwt.shared.MovingAverage;
@@ -85,14 +85,14 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa
* One of two {@link VerticalWindChart}s that shows the wind fixes speed measured by the wind bot in a chart
* vertically.
* */
@UiField
@UiField(provided = true)
public VerticalWindChart trueWindSpeedVerticalWindChart;
/**
* One of two {@link VerticalWindChart}s that shows the wind fixes direction measured by the wind bot in a chart
* vertically.
* */
@UiField
@UiField(provided = true)
public VerticalWindChart trueWindDirectionVerticalWindChart;
/**
@@ -104,6 +104,7 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa
private String windBotId;
private StringMessages stringConstants;
private final static String UNIT_WIND_DIRECTION = "°";
public WindBotComponent(String windBotId) {
this.windBotId = windBotId;
@@ -119,7 +120,9 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa
movingAverageSpeed = new MovingAverage(500);
movingAverageDirection = new MovingAverage(500);
trueWindSpeedLiveAverageComponent = new LiveAverageComponent(stringConstants.dashboardTrueWindSpeed(), stringConstants.dashboardTrueWindSpeedUnit());
trueWindDirectionLiveAverageComponent = new LiveAverageComponent(stringConstants.dashboardTrueWindDirection(), stringConstants.dashboardTrueWindDirectionUnit());
trueWindDirectionLiveAverageComponent = new LiveAverageComponent(stringConstants.dashboardTrueWindDirection(), UNIT_WIND_DIRECTION);
trueWindSpeedVerticalWindChart = new VerticalWindChart("#008FFF", "#6ADBFF");
trueWindDirectionVerticalWindChart = new VerticalWindChart("#008FFF", "#6ADBFF");
initWidget(uiBinder.createAndBindUi(this));
windBotNamePanel.getElement().setInnerText(stringConstants.dashboardWindBot()+" "+ windBotId);
trueWindSpeedVerticalWindChart.addVerticalWindChartClickListener(trueWindSpeedLiveAverageComponent);
@@ -197,16 +200,16 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa
Point[] points = new Point[windFixes.size()];
int counter = 0;
if (windtype.equals(WindType.DIRECTION)) {
Point previouspoint = new Point(windFixes.get(0).requestTimepoint, windFixes.get(0).trueWindBearingDeg);
Point previouspoint = new Point(windFixes.get(0).requestTimepoint, windFixes.get(0).trueWindFromDeg);
for (WindDTO windDTO : windFixes) {
double nextSinusValue = 0;
if (inSimulationMode == true) {
nextSinusValue = directionSinWave.getNexNumber();
}
points[counter] = new Point(windDTO.requestTimepoint, windDTO.trueWindBearingDeg + nextSinusValue);
points[counter] = new Point(windDTO.requestTimepoint, windDTO.trueWindFromDeg + nextSinusValue);
points[counter] = adaptWindDirectionPointToStayCloseToLastPoint(previouspoint, points[counter]);
previouspoint = points[counter];
movingAverageDirection.add(windDTO.trueWindBearingDeg + nextSinusValue);
movingAverageDirection.add(windDTO.trueWindFromDeg + nextSinusValue);
counter++;
}
} else if (windtype.equals(WindType.SPEED)) {
@@ -23,14 +23,12 @@
<g:HTMLPanel
styleName="{style.wind_bot_component_windchart_container} {style.wind_bot_component_left}">
<windchart:VerticalWindChart ui:field="trueWindSpeedVerticalWindChart"
styleName="{style.wind_bot_component_windchart}" positiveFillColor="#008FFF"
negativeFillColor="#6ADBFF"></windchart:VerticalWindChart>
styleName="{style.wind_bot_component_windchart}"></windchart:VerticalWindChart>
</g:HTMLPanel>
<g:HTMLPanel
styleName="{style.wind_bot_component_windchart_container} {style.wind_bot_component_right}">
<windchart:VerticalWindChart ui:field="trueWindDirectionVerticalWindChart"
styleName="{style.wind_bot_component_windchart}" positiveFillColor="#008FFF"
negativeFillColor="#6ADBFF"></windchart:VerticalWindChart>
styleName="{style.wind_bot_component_windchart}"></windchart:VerticalWindChart>
</g:HTMLPanel>
<g:HTMLPanel styleName="{style.wind_bot_component_compass_container}">
<compass:LocationPointerCompass
@@ -9,8 +9,10 @@ import com.sap.sailing.dashboards.gwt.client.device.Location;
import com.sap.sailing.dashboards.gwt.client.device.LocationListener;
import com.sap.sailing.dashboards.gwt.client.device.Orientation;
import com.sap.sailing.dashboards.gwt.client.device.OrientationListener;
import com.sap.sailing.dashboards.gwt.client.device.OrientationType;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sse.common.Util.Pair;
/**
* The classes task is to notify its listeners about changes in distance and angle from the actual device to a pointed
@@ -137,7 +139,7 @@ public class LocationPointerCompassAngleDistance implements LocationListener, Co
}
@Override
public void orientationChanged(double orintationHeading) {
setAngleOffsetAtListeners(orintationHeading);
public void orientationChanged(Pair<OrientationType, Double> orientation) {
setAngleOffsetAtListeners(orientation.getB().doubleValue());
}
}
@@ -6,24 +6,49 @@ import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.TimePoint;
public abstract class AbstractStartAnalysisCreationValidator {
private static int MINIMUM_NUMBER_COMPETITORS_FOR_STARTANALYSIS = 3;
private static int MINIMUM_MARKPASSIINGS_AT_FIRST_MARK = 3;
private static long MINIMUM_RACE_PROGRESSION_IN_MILLISECONDS = 6*60*1000;
protected boolean threeCompetitorsPassedSecondWayPoint(TrackedRace trackedRace){
Waypoint secondWaypoint = trackedRace.getRace().getCourse().getFirstLeg().getTo();
Iterator<MarkPassing> markPassingsInOrder = trackedRace.getMarkPassingsInOrder(secondWaypoint).iterator();
int counter = 0;
while (markPassingsInOrder.hasNext()) {
int markPassingsCounter = 0;
while (markPassingsInOrder.hasNext() && markPassingsCounter < MINIMUM_MARKPASSIINGS_AT_FIRST_MARK) {
markPassingsInOrder.next();
counter ++;
markPassingsCounter ++;
}
return counter >= MINIMUM_NUMBER_COMPETITORS_FOR_STARTANALYSIS ? true : false;
return markPassingsCounter >= MINIMUM_MARKPASSIINGS_AT_FIRST_MARK ? true : false;
}
protected boolean competitorPassedSecondWayPoint(Competitor competitor, TrackedRace trackedRace){
private boolean competitorPassedSecondWayPoint(Competitor competitor, TrackedRace trackedRace){
Waypoint secondWaypoint = trackedRace.getRace().getCourse().getFirstLeg().getTo();
return trackedRace.getMarkPassing(competitor, secondWaypoint) == null ? false : true;
}
private boolean gateStartGolfFlagIsDown(TrackedRace trackedRace){
if(trackedRace.getGateStartGolfDownTime() != 0){
return true;
}else{
TimePoint timeStartOfRace = trackedRace.getStartOfRace();
TimePoint timeNewestEvent = trackedRace.getTimePointOfNewestEvent();
if(timeStartOfRace != null && timeNewestEvent != null){
if(timeStartOfRace.asMillis()+MINIMUM_RACE_PROGRESSION_IN_MILLISECONDS > timeNewestEvent.asMillis()){
return true;
}
}
}
return false;
}
protected boolean raceProgressedFarEnough(Competitor competitor, TrackedRace trackedRace){
if(trackedRace.isGateStart()){
return gateStartGolfFlagIsDown(trackedRace);
}else{
return competitorPassedSecondWayPoint(competitor, trackedRace);
}
}
}
@@ -21,7 +21,7 @@ public class StartAnalysisCreationController extends AbstractStartAnalysisCreati
public StartAnalysisDTO checkStartAnalysisForCompetitorInTrackedRace(Competitor competitor, TrackedRace trackedRace) {
StartAnalysisDTO startAnalysisDTO;
if (threeCompetitorsPassedSecondWayPoint(trackedRace) &&
competitorPassedSecondWayPoint(competitor, trackedRace))
raceProgressedFarEnough(competitor, trackedRace))
{
logger.log(Level.INFO, "Trigger StartAnalysisDTO creation");
startAnalysisDTO = startAnalysisDTOFactory.createStartAnalysisForCompetitorAndTrackedRace(competitor, trackedRace);
@@ -34,6 +34,7 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida
private static int MINIMUM_NUMBER_COMPETITORS_FOR_STARTANALYSIS = 3;
private static int DEFAULT_GATE_START_INTERVALL_IN_MILLISECONDS = 5*60*1000;
private static int ONE_MINUTE_INTERVALL_IN_MILLISECONDS = 60*1000;
private static final Logger logger = Logger.getLogger(StartAnalysisDTOFactory.class.getName());
@@ -72,7 +73,6 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida
if (trackedRace.isGateStart()) {
logger.log(Level.INFO, "IS GATESTART");
startAnalysisDTO.racingProcedureType = RacingProcedureType.GateStart;
// Waypoint startLineWaypoint = trackedRace.getStartLine(trackedRace.getStartOfRace()).getWaypoint();
long timePointOfGolfDownTime = trackedRace.getGateStartGolfDownTime();
startAnalysisDTO.timeOfStartInMilliSeconds = trackedRace.getStartOfRace().asMillis();
if(timePointOfGolfDownTime < trackedRace.getStartOfRace().asMillis() || timePointOfGolfDownTime == 0){
@@ -83,6 +83,7 @@ public class StartAnalysisDTOFactory extends AbstractStartAnalysisCreationValida
} else {
startAnalysisDTO.racingProcedureType = RacingProcedureType.ESS;
startAnalysisDTO.timeOfStartInMilliSeconds = trackedRace.getStartOfRace().asMillis();
startAnalysisDTO.tailLenghtInMilliseconds = ONE_MINUTE_INTERVALL_IN_MILLISECONDS;
}
startAnalysisDTO.regattaAndRaceIdentifier = trackedRace.getRaceIdentifier();
logger.log(Level.INFO, "Created StartAnalysis For Competitor " + competitor.getName() + " and "+ trackedRace.getRace().getName());
@@ -1,7 +1,7 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.polars.PolarDataService;
import com.sap.sailing.domain.polars.PolarDataService;
public interface HasLeaderboardContext {
@@ -1,7 +1,7 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.polars.PolarDataService;
import com.sap.sailing.domain.polars.PolarDataService;
public interface HasLeaderboardGroupContext {
@@ -5,7 +5,7 @@ import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import com.sap.sailing.datamining.impl.data.LeaderboardGroupWithContext;
import com.sap.sailing.polars.PolarDataService;
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
@@ -2,7 +2,7 @@ package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasLeaderboardGroupContext;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.polars.PolarDataService;
import com.sap.sailing.domain.polars.PolarDataService;
public class LeaderboardGroupWithContext implements HasLeaderboardGroupContext {
@@ -2,7 +2,7 @@ package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasLeaderboardContext;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.polars.PolarDataService;
import com.sap.sailing.domain.polars.PolarDataService;
public class LeaderboardWithContext implements HasLeaderboardContext {
@@ -20,11 +20,11 @@ import com.sap.sailing.domain.common.Tack;
import com.sap.sailing.domain.common.scalablevalue.impl.ScalableSpeed;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.domain.tracking.GPSFixTrack;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.polars.PolarDataService;
import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util;
@@ -0,0 +1,7 @@
package com.sap.sailing.domain.common;
public interface LegIdentifier extends RegattaAndRaceIdentifier {
RaceIdentifier getRaceIdentifier();
String getLegName();
int getLegNumber();
}
@@ -0,0 +1,62 @@
package com.sap.sailing.domain.common;
public class LegIdentifierImpl extends RegattaNameAndRaceName implements LegIdentifier {
private static final long serialVersionUID = 3599904513673776450L;
private RaceIdentifier raceIdentifier = null;
private String legName;
LegIdentifierImpl() {}
public LegIdentifierImpl(RegattaAndRaceIdentifier raceIdentifier, String legName) {
super(raceIdentifier.getRegattaName(), raceIdentifier.getRaceName());
this.raceIdentifier = raceIdentifier;
this.legName = legName;
}
@Override
public RaceIdentifier getRaceIdentifier() {
return this.raceIdentifier;
}
@Override
public String getLegName() {
return legName;
}
@Override
public int getLegNumber() {
return Integer.parseInt(legName)-1;
}
@Override
public String toString() {
return getRegattaName() + "/" + getRaceName() + "/" + getLegName();
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((legName == null) ? 0 : legName.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;
LegIdentifierImpl other = (LegIdentifierImpl) obj;
if (legName == null) {
if (other.legName != null)
return false;
} else if (!legName.equals(other.legName))
return false;
return true;
}
}
@@ -13,7 +13,8 @@ public enum RacingProcedureType {
RRS26("Fix Line Start (RRS26)"),
GateStart("Gate Start"),
ESS("\"Extreme Sailing Series\"-Start"),
BASIC("Basic Countdown Start");
BASIC("Basic Countdown Start"),
LEAGUE("League Start");
private String displayName;
@@ -11,6 +11,7 @@ import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ReadonlyRac
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.basic.impl.BasicRacingProcedureImpl;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ess.impl.ESSRacingProcedureImpl;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.impl.GateStartRacingProcedureImpl;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl.LeagueRacingProcedureImpl;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.rrs26.impl.RRS26RacingProcedureImpl;
import com.sap.sailing.domain.base.configuration.ConfigurationLoader;
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
@@ -48,6 +49,8 @@ public class ReadonlyRacingProcedureFactory implements RacingProcedureFactory {
return new RRS26RacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getRRS26Configuration());
case BASIC:
return new BasicRacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getBasicConfiguration());
case LEAGUE:
return new LeagueRacingProcedureImpl(raceLog, author, factory, loadedConfiguration.getLeagueConfiguration());
default:
throw new UnsupportedOperationException("Unknown racing procedure " + type.toString());
}
@@ -0,0 +1,7 @@
package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure;
public interface LeagueRacingProcedure extends RacingProcedure {
}
@@ -0,0 +1,6 @@
package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedureChangedListener;
public interface LeagueRacingProcedureChangedListener extends RacingProcedureChangedListener {
}
@@ -0,0 +1,22 @@
package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.BaseRacingProcedurePrerequisite;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.LeagueRacingProcedure;
import com.sap.sse.common.TimePoint;
/**
* Easy access to the {@link LeagueRacingProcedure}.
*/
public abstract class LeaguePrerequisite extends BaseRacingProcedurePrerequisite implements RacingProcedurePrerequisite {
public LeaguePrerequisite(FulfillmentFunction function, LeagueRacingProcedure procedure, TimePoint originalNow,
TimePoint originalStartTime) {
super(function, procedure, originalNow, originalStartTime);
}
protected LeagueRacingProcedure getProcedure() {
return (LeagueRacingProcedure) procedure;
}
}
@@ -0,0 +1,8 @@
package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.RacingProcedureChangedListeners;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.LeagueRacingProcedureChangedListener;
public class LeagueRacingProcedureChangedListeners extends RacingProcedureChangedListeners<LeagueRacingProcedureChangedListener> implements
LeagueRacingProcedureChangedListener {
}
@@ -0,0 +1,141 @@
package com.sap.sailing.domain.abstractlog.race.state.racingprocedure.league.impl;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEventFactory;
import com.sap.sailing.domain.abstractlog.race.state.RaceStateEvent;
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateEventImpl;
import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateEvents;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.FlagPoleState;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedureChangedListener;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedurePrerequisite.FulfillmentFunction;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.BaseRacingProcedure;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.NoMorePrerequisite;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.impl.RacingProcedureChangedListeners;
import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration;
import com.sap.sailing.domain.common.racelog.FlagPole;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sse.common.TimePoint;
// TODO consider subclassing RRS26RacingProcedureImpl instead of this copy&paste orgy...
public class LeagueRacingProcedureImpl extends BaseRacingProcedure {
private final static long startPhaseClassUpInterval = 3 * 60 * 1000; // minutes * seconds * milliseconds
private final static long startPhaseStartModeUpInterval = 2 * 60 * 1000; // minutes * seconds * milliseconds
private final static long startPhaseStartModeDownInterval = 1 * 60 * 1000; // minutes * seconds * milliseconds
private final static Flags startmodeFlag = Flags.PAPA;
public LeagueRacingProcedureImpl(RaceLog raceLog, AbstractLogEventAuthor author,
RaceLogEventFactory factory, LeagueConfiguration configuration) {
super(raceLog, author, factory, configuration);
update();
}
@Override
public RacingProcedureType getType() {
return RacingProcedureType.LEAGUE;
}
@Override
public boolean hasIndividualRecall() {
boolean hasRecall = super.hasIndividualRecall();
if (!hasRecall) {
return false;
} else {
return hasRecall;
}
}
@Override
protected boolean hasIndividualRecallByDefault() {
return true;
}
@Override
public RacingProcedurePrerequisite checkPrerequisitesForStart(TimePoint now, TimePoint startTime,
FulfillmentFunction function) {
return new NoMorePrerequisite(function);
}
@Override
public boolean isStartphaseActive(TimePoint startTime, TimePoint now) {
if (now.before(startTime)) {
long timeTillStart = startTime.minus(now.asMillis()).asMillis();
return timeTillStart < startPhaseClassUpInterval;
}
return false;
}
@Override
protected Collection<RaceStateEvent> createStartStateEvents(TimePoint startTime) {
// Remark: We are reusing here CLASS_UP, STARTMODE_UP and STARTMODE_DOWN from the RRS26 procedure
// The question is why there are no generic CLASS_UP, STARTMODE_UP and STARTMODE_DOWN events
return Arrays.<RaceStateEvent> asList(
new RaceStateEventImpl(startTime.minus(startPhaseClassUpInterval), RaceStateEvents.RRS26_CLASS_UP),
new RaceStateEventImpl(startTime.minus(startPhaseStartModeUpInterval), RaceStateEvents.RRS26_STARTMODE_UP),
new RaceStateEventImpl(startTime.minus(startPhaseStartModeDownInterval), RaceStateEvents.RRS26_STARTMODE_DOWN),
new RaceStateEventImpl(startTime, RaceStateEvents.START));
}
@Override
public FlagPoleState getActiveFlags(TimePoint startTime, TimePoint now) {
Flags classFlag = getConfiguration().getClassFlag() != null ?
getConfiguration().getClassFlag() : Flags.CLASS;
if (now.before(startTime.minus(startPhaseClassUpInterval))) {
return new FlagPoleState(
Arrays.asList(new FlagPole(classFlag, false), new FlagPole(startmodeFlag, false)),
null,
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)),
startTime.minus(startPhaseClassUpInterval));
} else if (now.before(startTime.minus(startPhaseStartModeUpInterval))) {
return new FlagPoleState(
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)),
startTime.minus(startPhaseClassUpInterval),
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, true)),
startTime.minus(startPhaseStartModeUpInterval));
} else if (now.before(startTime.minus(startPhaseStartModeDownInterval))) {
return new FlagPoleState(
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, true)),
startTime.minus(startPhaseStartModeUpInterval),
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)),
startTime.minus(startPhaseStartModeDownInterval));
} else if (now.before(startTime)) {
return new FlagPoleState(
Arrays.asList(new FlagPole(classFlag, true), new FlagPole(startmodeFlag, false)),
startTime.minus(startPhaseStartModeDownInterval),
Arrays.asList(new FlagPole(classFlag, false), new FlagPole(startmodeFlag, false)),
startTime);
} else {
if (isIndividualRecallDisplayed(now)) {
return new FlagPoleState(
Arrays.asList(new FlagPole(Flags.XRAY, true)),
getIndividualRecallDisplayedTime(),
Arrays.asList(new FlagPole(Flags.XRAY, false)),
getIndividualRecallRemovalTime());
} else if (isFinished(now)) {
return new FlagPoleState(
Arrays.asList(new FlagPole(Flags.BLUE, false)), getFinishedTime());
} else if (isInFinishingPhase(now)) {
return new FlagPoleState(
Arrays.asList(new FlagPole(Flags.BLUE, true)),
getFinishingTime(),
Arrays.asList(new FlagPole(Flags.BLUE, false)),
null);
} else {
TimePoint recallRemoved = getIndividualRecallRemovalTime();
return new FlagPoleState(Collections.<FlagPole>emptyList(), recallRemoved == null ? startTime : recallRemoved);
}
}
}
@Override
protected RacingProcedureChangedListeners<? extends RacingProcedureChangedListener> createChangedListenerContainer() {
return new LeagueRacingProcedureChangedListeners();
}
}
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.base;
import java.net.URI;
import com.sap.sse.common.Color;
public interface CompetitorChangeListener extends BoatChangeListener, NationalityChangeListener {
@@ -8,4 +10,6 @@ public interface CompetitorChangeListener extends BoatChangeListener, Nationalit
void nameChanged(String oldName, String newName);
void emailChanged(String oldEmail, String newEmail);
void flagImageChanged(URI oldFlagImageURI, URI newFlagImageURI);
}
@@ -5,6 +5,7 @@ import java.io.Serializable;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure;
import com.sap.sailing.domain.base.configuration.procedures.ESSConfiguration;
import com.sap.sailing.domain.base.configuration.procedures.GateStartConfiguration;
import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration;
import com.sap.sailing.domain.base.configuration.procedures.RRS26Configuration;
import com.sap.sailing.domain.common.CourseDesignerMode;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
@@ -42,7 +43,13 @@ public interface RegattaConfiguration extends Serializable, Cloneable {
* @return <code>null</code> if there is no configuration.
*/
ESSConfiguration getESSConfiguration();
/**
* Gets the configuration for league races.
* @return <code>null</code> if there is no configuration.
*/
LeagueConfiguration getLeagueConfiguration();
/**
* Gets the configuration for Basic races.
* @return <code>null</code> if there is no configuration.
@@ -21,6 +21,7 @@ public class EmptyRegattaConfiguration extends RegattaConfigurationImpl implemen
setGateStartConfiguration(new GateStartConfigurationImpl());
setESSConfiguration(new ESSConfigurationImpl());
setBasicConfiguration(new RacingProcedureConfigurationImpl());
setLeagueConfiguration(new LeagueConfigurationImpl());
return clone();
}
@@ -0,0 +1,20 @@
package com.sap.sailing.domain.base.configuration.impl;
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration;
public class LeagueConfigurationImpl extends RacingProcedureConfigurationImpl implements LeagueConfiguration {
private static final long serialVersionUID = 3625803505541394766L;
protected LeagueConfigurationImpl copy() {
LeagueConfigurationImpl copy = (LeagueConfigurationImpl) super.copy(new LeagueConfigurationImpl());
return copy;
}
@Override
public RacingProcedureConfiguration merge(RacingProcedureConfiguration update) {
LeagueConfigurationImpl target = (LeagueConfigurationImpl) super.merge(update);
return target;
}
}
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
import com.sap.sailing.domain.base.configuration.procedures.ESSConfiguration;
import com.sap.sailing.domain.base.configuration.procedures.GateStartConfiguration;
import com.sap.sailing.domain.base.configuration.procedures.LeagueConfiguration;
import com.sap.sailing.domain.base.configuration.procedures.RRS26Configuration;
import com.sap.sailing.domain.common.CourseDesignerMode;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
@@ -18,6 +19,7 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
private RRS26Configuration rrs26Configuration;
private GateStartConfiguration gateStartConfiguration;
private ESSConfiguration essConfiguration;
private LeagueConfiguration leagueConfiguration;
private RacingProcedureConfiguration basicConfiguration;
@Override
@@ -65,6 +67,15 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
this.essConfiguration = essConfiguration;
}
@Override
public LeagueConfiguration getLeagueConfiguration() {
return leagueConfiguration;
}
public void setLeagueConfiguration(LeagueConfiguration leagueConfiguration) {
this.leagueConfiguration = leagueConfiguration;
}
@Override
public RacingProcedureConfiguration getBasicConfiguration() {
return basicConfiguration;
@@ -83,6 +94,7 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
copy.setGateStartConfiguration(gateStartConfiguration);
copy.setESSConfiguration(essConfiguration);
copy.setBasicConfiguration(basicConfiguration);
copy.setLeagueConfiguration(leagueConfiguration);
return copy;
}
@@ -112,6 +124,10 @@ public class RegattaConfigurationImpl implements RegattaConfiguration {
target.setBasicConfiguration(
(RacingProcedureConfiguration) target.getBasicConfiguration().merge(update.getBasicConfiguration()));
}
if (update.getLeagueConfiguration() != null) {
target.setLeagueConfiguration(
(LeagueConfiguration) target.getLeagueConfiguration().merge(update.getLeagueConfiguration()));
}
return target;
}
@@ -0,0 +1,7 @@
package com.sap.sailing.domain.base.configuration.procedures;
import com.sap.sailing.domain.base.configuration.RacingProcedureConfiguration;
public interface LeagueConfiguration extends RacingProcedureConfiguration {
}
@@ -145,6 +145,12 @@ public class CompetitorImpl implements DynamicCompetitor {
@Override
public void setFlagImage(URI flagImage) {
final URI oldFlagImage = this.flagImage;
this.flagImage = flagImage;
if (!Util.equalsWithNull(oldFlagImage, flagImage)) {
for (CompetitorChangeListener listener : getListeners()) {
listener.flagImageChanged(oldFlagImage, flagImage);
}
}
}
}
@@ -7,6 +7,8 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.junit.Before;
import org.junit.Test;
@@ -45,6 +47,12 @@ public class CompetitorListenerTest extends AbstractSerializationTest {
private Color newColor;
private DynamicCompetitor competitor;
private DomainFactoryImpl baseDomainFactory;
private boolean emailChanged;
private String oldEmail;
private String newEmail;
private boolean flagImageChanged;
private URI oldFlagImageURL;
private URI newFlagImageURL;
@Before
public void setUp() {
@@ -63,6 +71,12 @@ public class CompetitorListenerTest extends AbstractSerializationTest {
colorChanged = false;
oldColor = null;
newColor = null;
emailChanged = false;
oldEmail = null;
newEmail = null;
flagImageChanged = false;
oldFlagImageURL = null;
newFlagImageURL = null;
listener = new CompetitorChangeListener() {
private static final long serialVersionUID = 4581029778988240209L;
@@ -97,7 +111,16 @@ public class CompetitorListenerTest extends AbstractSerializationTest {
@Override
public void emailChanged(String oldEmail, String newEmail) {
//TODO
emailChanged = true;
CompetitorListenerTest.this.oldEmail = oldEmail;
CompetitorListenerTest.this.newEmail = newEmail;
}
@Override
public void flagImageChanged(URI oldFlagImageURL, URI newFlagImageURL) {
flagImageChanged = true;
CompetitorListenerTest.this.oldFlagImageURL = oldFlagImageURL;
CompetitorListenerTest.this.newFlagImageURL = newFlagImageURL;
}
};
competitor.addCompetitorChangeListener(listener);
@@ -126,6 +149,22 @@ public class CompetitorListenerTest extends AbstractSerializationTest {
assertFalse(nationalityChanged);
}
@Test
public void testFlagChange() throws URISyntaxException {
competitor.setFlagImage(new URI("http://www.something.de/pic.png"));
assertTrue(flagImageChanged);
assertNull(oldFlagImageURL);
assertEquals(new URI("http://www.something.de/pic.png"), newFlagImageURL);
}
@Test
public void testEmailChange() throws URISyntaxException {
competitor.setEmail("hasso.plattner@sap.com");
assertTrue(emailChanged);
assertNull(oldEmail);
assertEquals("hasso.plattner@sap.com", newEmail);
}
@Test
public void testSimpleCompetitorListenerPatternForSailId() {
final String myOldSailId = competitor.getBoat().getSailID();
@@ -149,7 +149,9 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
Wind combinedWindDirection = combinedTrack.getAveragedWind(/* position */ null, now);
// The course layout makes a wind estimation around 7deg. The confidence of the cluster based wind estimation is a lot
// higher that that of the course layout wind (currently at approximately 10E-13), we will end up quite near 180 deg.
assertEquals(180.0, combinedWindDirection.getBearing().getDegrees(), 0.2);
// Update 04/24/15: Since polar data service is not available here, the confidence will not be as good as it once was.
// So we have quite a big delta in the assert
assertEquals(180.0, combinedWindDirection.getBearing().getDegrees(), 0.9);
}
/**
@@ -40,6 +40,7 @@ import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.leaderboard.ScoringScheme;
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
import com.sap.sailing.domain.regattalike.RegattaLikeListener;
@@ -904,4 +905,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
// TODO Auto-generated method stub
return 0;
}
@Override
public void setPolarDataService(PolarDataService polarDataService) {
}
}
@@ -29,6 +29,7 @@ import com.sap.sailing.domain.common.Tack;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
@@ -591,12 +592,12 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
public GPSFixTrack<Mark, GPSFix> getTrack(Mark mark) {
return null;
}
@Override
public long getGateStartGolfDownTime() {
return 0;
}
@Override
public boolean isUsingMarkPassingCalculator() {
// TODO Auto-generated method stub
@@ -608,5 +609,9 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
// TODO Auto-generated method stub
return 0;
}
@Override
public void setPolarDataService(PolarDataService polarDataService) {
}
}
@@ -17,6 +17,7 @@ Export-Package: com.sap.sailing.domain.base,
com.sap.sailing.domain.markpassingcalculation.impl,
com.sap.sailing.domain.markpassingcalculation.splining,
com.sap.sailing.domain.masterdataimport,
com.sap.sailing.domain.polars,
com.sap.sailing.domain.racelog,
com.sap.sailing.domain.racelog.impl,
com.sap.sailing.domain.racelog.tracking,
@@ -38,4 +39,5 @@ Require-Bundle: com.googlecode.java-diff-utils;bundle-version="1.3.0",
com.sap.sse.datamining.shared,
com.sap.sse.common,
com.sap.sse,
com.sap.sse.shared.android
com.sap.sse.shared.android,
org.apache.commons.math
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.leaderboard;
import java.net.URI;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
@@ -121,7 +122,11 @@ public class LeaderboardCacheManager {
public void emailChanged(String oldEmail, String newEmail) {
//ignore (email not shown in leaderboard)
}
@Override
public void flagImageChanged(URI oldFlagImageURL, URI newFlagImageURL) {
removeFromCache(leaderboard);
}
}
private class CacheInvalidationUponScoreCorrectionListener implements ScoreCorrectionListener {
@@ -1,4 +1,4 @@
package com.sap.sailing.polars;
package com.sap.sailing.domain.polars;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.common.Bearing;
@@ -1,4 +1,4 @@
package com.sap.sailing.polars.regression;
package com.sap.sailing.domain.polars;
public class NotEnoughDataHasBeenAddedException extends Exception {
@@ -1,4 +1,4 @@
package com.sap.sailing.polars;
package com.sap.sailing.domain.polars;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -17,10 +17,9 @@ import com.sap.sailing.domain.common.PolarSheetGenerationSettings;
import com.sap.sailing.domain.common.PolarSheetsData;
import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.common.Tack;
import com.sap.sailing.domain.common.confidence.BearingWithConfidence;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.polars.mining.MovingAverageProcessor;
import com.sap.sailing.polars.regression.NotEnoughDataHasBeenAddedException;
import com.sap.sse.common.Util.Pair;
/**
@@ -206,7 +205,28 @@ public interface PolarDataService {
*/
PolynomialFunction getSpeedRegressionFunction(BoatClass boatClass, double trueWindAngle) throws NotEnoughDataHasBeenAddedException;
/**
* For Upwind and Downwind returns the typical angle needed for a maneuver.
*
* @param boatClass
* @param maneuverType
* needs to be Tack or Jibe
* @param windSpeed
* Since the maneuver angle is windSpeed depended, supply it here
* @return angle with confidence as supplied by polars. Angle is always >= 0
* @throws NotEnoughDataHasBeenAddedException
*/
BearingWithConfidence<Void> getManeuverAngle(BoatClass boatClass, ManeuverType maneuverType, Speed windSpeed)
throws NotEnoughDataHasBeenAddedException;
void raceFinishedLoading(TrackedRace race);
/**
* See {@link #getAverageSpeedWithBearing(BoatClass, Speed, LegType, Tack, boolean)}
* Always use regression
*/
SpeedWithBearingWithConfidence<Void> getAverageSpeedWithBearing(BoatClass boatClass, Speed windSpeed,
LegType legType, Tack tack) throws NotEnoughDataHasBeenAddedException;
}
@@ -35,6 +35,7 @@ import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.dto.TrackedRaceDTO;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
@@ -770,4 +771,6 @@ public interface TrackedRace extends Serializable {
boolean isUsingMarkPassingCalculator();
void setPolarDataService(PolarDataService polarDataService);
}
@@ -101,6 +101,8 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.confidence.ConfidenceBasedWindAverager;
import com.sap.sailing.domain.confidence.ConfidenceFactory;
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
@@ -317,6 +319,8 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
*/
private transient ShortTimeWindCache shortTimeWindCache;
private transient PolarDataService polarDataService;
public TrackedRaceImpl(final TrackedRegatta trackedRegatta, RaceDefinition race,
final Iterable<Sideline> sidelines, final WindStore windStore, final GPSFixStore gpsFixStore,
long delayToLiveInMillis, final long millisecondsOverWhichToAverageWind,
@@ -407,7 +411,6 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
windTracks.putAll(loadedWindTracks);
updateEventTimePoints(loadedWindTracks.values());
logger.info("Finished loading wind tracks for " + getRace().getName() + ". Found " + windTracks.size() + " wind tracks for this race.");
} finally {
synchronized (TrackedRaceImpl.this) {
loadingFromWindStoreState = LoadingFromStoresState.FINISHED;
@@ -1861,40 +1864,66 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
BearingWithConfidence<TimePoint> resultBearing = null;
ScalablePosition scaledPosition = null;
int numberOfFixesConsideredForScaledPosition = 0;
Set<WindSource> estimationExcluded = new HashSet<>();
estimationExcluded.addAll(getWindSources(WindSourceType.TRACK_BASED_ESTIMATION));
estimationExcluded.addAll(getWindSources(WindSourceType.COURSE_BASED));
if (bearings != null) {
BearingWithConfidenceCluster<TimePoint>[] bearingClustersUpwind = bearings.get(LegType.UPWIND).getA().splitInTwo(
getMinimumAngleBetweenDifferentTacksUpwind(), timePoint);
if (!bearingClustersUpwind[0].isEmpty() && !bearingClustersUpwind[1].isEmpty()) {
BearingWithConfidence<TimePoint> average0 = bearingClustersUpwind[0].getAverage(timePoint);
BearingWithConfidence<TimePoint> average1 = bearingClustersUpwind[1].getAverage(timePoint);
upwindNumberOfRelevantBoats = Math
.min(bearingClustersUpwind[0].size(), bearingClustersUpwind[1].size());
confidence = Math.min(average0.getConfidence(), average1.getConfidence())
* getRace().getBoatClass().getUpwindWindEstimationConfidence(upwindNumberOfRelevantBoats);
reversedUpwindAverage = new BearingWithConfidenceImpl<TimePoint>(average0.getObject()
.middle(average1.getObject()).reverse(), confidence, timePoint);
scaledPosition = bearings.get(LegType.UPWIND).getB();
numberOfFixesConsideredForScaledPosition += bearings.get(LegType.UPWIND).getA().size();
int numberOfFixesUpwind = bearings.get(LegType.UPWIND).getA().size();
if (numberOfFixesUpwind > 0) {
ScalablePosition upwindPosition = bearings.get(LegType.UPWIND).getB();
Pair<Double, Double> minimumAngleBetweenDifferentTacksUpwindWithConfidence = getMinimumAngleBetweenDifferentTacksUpwind(getWind(
upwindPosition.divide(numberOfFixesUpwind), timePoint, estimationExcluded));
BearingWithConfidenceCluster<TimePoint>[] bearingClustersUpwind = bearings
.get(LegType.UPWIND)
.getA()
.splitInTwo(
minimumAngleBetweenDifferentTacksUpwindWithConfidence.getA(),
timePoint);
if (!bearingClustersUpwind[0].isEmpty() && !bearingClustersUpwind[1].isEmpty()) {
BearingWithConfidence<TimePoint> average0 = bearingClustersUpwind[0].getAverage(timePoint);
BearingWithConfidence<TimePoint> average1 = bearingClustersUpwind[1].getAverage(timePoint);
upwindNumberOfRelevantBoats = Math.min(bearingClustersUpwind[0].size(),
bearingClustersUpwind[1].size());
confidence = Math.min(average0.getConfidence(), average1.getConfidence())
* getRace().getBoatClass().getUpwindWindEstimationConfidence(upwindNumberOfRelevantBoats)
* minimumAngleBetweenDifferentTacksUpwindWithConfidence.getB();
reversedUpwindAverage = new BearingWithConfidenceImpl<TimePoint>(average0.getObject()
.middle(average1.getObject()).reverse(), confidence, timePoint);
scaledPosition = upwindPosition;
numberOfFixesConsideredForScaledPosition += bearings.get(LegType.UPWIND).getA().size();
}
}
BearingWithConfidenceImpl<TimePoint> downwindAverage = null;
int downwindNumberOfRelevantBoats = 0;
BearingWithConfidenceCluster<TimePoint>[] bearingClustersDownwind = bearings.get(LegType.DOWNWIND).getA()
.splitInTwo(getMinimumAngleBetweenDifferentTacksDownwind(), timePoint);
if (!bearingClustersDownwind[0].isEmpty() && !bearingClustersDownwind[1].isEmpty()) {
BearingWithConfidence<TimePoint> average0 = bearingClustersDownwind[0].getAverage(timePoint);
BearingWithConfidence<TimePoint> average1 = bearingClustersDownwind[1].getAverage(timePoint);
downwindNumberOfRelevantBoats = Math.min(bearingClustersDownwind[0].size(),
bearingClustersDownwind[1].size());
confidence = Math.min(average0.getConfidence(), average1.getConfidence())
* getRace().getBoatClass().getDownwindWindEstimationConfidence(downwindNumberOfRelevantBoats);
downwindAverage = new BearingWithConfidenceImpl<TimePoint>(average0.getObject().middle(
average1.getObject()), confidence, timePoint);
if (scaledPosition == null) {
scaledPosition = bearings.get(LegType.DOWNWIND).getB();
} else {
scaledPosition.add(bearings.get(LegType.DOWNWIND).getB());
int numberOfFixesDownwind = bearings.get(LegType.DOWNWIND).getA().size();
if (numberOfFixesDownwind > 0) {
ScalablePosition downwindPosition = bearings.get(LegType.DOWNWIND).getB();
Pair<Double, Double> minimumAngleBetweenDifferentTacksDownwindWithConfidence = getMinimumAngleBetweenDifferentTacksDownwind(getWind(
downwindPosition.divide(numberOfFixesDownwind), timePoint, estimationExcluded));
BearingWithConfidenceCluster<TimePoint>[] bearingClustersDownwind = bearings
.get(LegType.DOWNWIND)
.getA()
.splitInTwo(
minimumAngleBetweenDifferentTacksDownwindWithConfidence.getA(),
timePoint);
if (!bearingClustersDownwind[0].isEmpty() && !bearingClustersDownwind[1].isEmpty()) {
BearingWithConfidence<TimePoint> average0 = bearingClustersDownwind[0].getAverage(timePoint);
BearingWithConfidence<TimePoint> average1 = bearingClustersDownwind[1].getAverage(timePoint);
downwindNumberOfRelevantBoats = Math.min(bearingClustersDownwind[0].size(),
bearingClustersDownwind[1].size());
confidence = Math.min(average0.getConfidence(), average1.getConfidence())
* getRace().getBoatClass().getDownwindWindEstimationConfidence(
downwindNumberOfRelevantBoats)
* minimumAngleBetweenDifferentTacksDownwindWithConfidence.getB();
downwindAverage = new BearingWithConfidenceImpl<TimePoint>(average0.getObject().middle(
average1.getObject()), confidence, timePoint);
if (scaledPosition == null) {
scaledPosition = downwindPosition;
} else {
scaledPosition.add(downwindPosition);
}
numberOfFixesConsideredForScaledPosition += bearings.get(LegType.DOWNWIND).getA().size();
}
numberOfFixesConsideredForScaledPosition += bearings.get(LegType.DOWNWIND).getA().size();
}
BearingWithConfidenceCluster<TimePoint> resultCluster = new BearingWithConfidenceCluster<TimePoint>(weigher);
assert upwindNumberOfRelevantBoats == 0 || reversedUpwindAverage != null;
@@ -2716,12 +2745,41 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
return getRace().getBoatClass().getManeuverDegreeAngleThreshold();
}
private double getMinimumAngleBetweenDifferentTacksDownwind() {
return getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksDownwind();
private Pair<Double, Double> getMinimumAngleBetweenDifferentTacksDownwind(Wind wind) {
Pair<Double, Double> result;
double defaultAngle = getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksDownwind();
double threshold = 20;
result = usePolarsIfPossible(wind, defaultAngle, LegType.DOWNWIND, threshold);
return result;
}
private Pair<Double, Double> getMinimumAngleBetweenDifferentTacksUpwind(Wind wind) {
Pair<Double, Double> result;
double defaultAngle = getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksUpwind();
double threshold = 10;
result = usePolarsIfPossible(wind, defaultAngle, LegType.UPWIND, threshold);
return result;
}
private double getMinimumAngleBetweenDifferentTacksUpwind() {
return getRace().getBoatClass().getMinimumAngleBetweenDifferentTacksUpwind();
private Pair<Double, Double> usePolarsIfPossible(Wind wind, double defaultAngle, LegType legType, double threshold) {
Pair<Double, Double> result;
if (polarDataService != null) {
try {
BearingWithConfidence<Void> average = polarDataService.getManeuverAngle(getRace().getBoatClass(),
legType == LegType.DOWNWIND ? ManeuverType.JIBE : ManeuverType.TACK, wind);
double averageAngleInDegMinusThreshold = average.getObject().getDegrees() - threshold;
if (averageAngleInDegMinusThreshold < defaultAngle) {
result = new Pair<Double, Double>(defaultAngle, 0.1);
} else {
result = new Pair<Double, Double>(averageAngleInDegMinusThreshold, average.getConfidence());
}
} catch (NotEnoughDataHasBeenAddedException e) {
result = new Pair<Double, Double>(defaultAngle, 0.1);
}
} else {
result = new Pair<Double, Double>(defaultAngle, 0.1);
}
return result;
}
private long getApproximateManeuverDurationInMilliseconds() {
@@ -2880,7 +2938,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
(DynamicGPSFixTrack<Competitor, GPSFixMoving>) tracks.get(competitor), log,
competitor);
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
logger.log(Level.WARNING, "Could not load track for " + competitor);
logger.log(Level.WARNING, "Could not load track for " + competitor, e);
}
}
logger.info("Finished loading competitor tracks for " + getRace().getName());
@@ -2890,7 +2948,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
gpsFixStore.loadMarkTrack((DynamicGPSFixTrack<Mark, GPSFix>) markTracks.get(mark), log,
mark);
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
logger.log(Level.WARNING, "Could not load track for " + mark);
logger.log(Level.WARNING, "Could not load track for " + mark, e);
}
}
logger.info("Finished loading mark tracks for " + getRace().getName());
@@ -3423,13 +3481,12 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
@Override
public long getGateStartGolfDownTime() {
long result = 0;
if (isGateStart()) {
Boolean isGateStart = isGateStart();
if (isGateStart != null && isGateStart.booleanValue() == true) {
for (RaceLog raceLog : attachedRaceLogs.values()) {
raceLog.lockForRead();
for(RaceLogEvent raceLogEvent: raceLog.getRawFixes()) {
logger.log(Level.INFO, ""+raceLogEvent.getClass().getName());
if(raceLogEvent.getClass().equals(RaceLogGateLineOpeningTimeEventImpl.class)){
logger.log(Level.INFO, "GOT RIGHT EVENT"+raceLogEvent.getClass().getName());
RaceLogGateLineOpeningTimeEvent raceLogGateLineOpeningTimeEvent = (RaceLogGateLineOpeningTimeEvent) raceLogEvent;
result = raceLogGateLineOpeningTimeEvent.getGateLineOpeningTimes().getGolfDownTime();
}
@@ -3456,5 +3513,10 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
}
return result;
}
@Override
public void setPolarDataService(PolarDataService polarDataService) {
this.polarDataService = polarDataService;
}
}
+7
View File
@@ -444,4 +444,11 @@ Computes leaderboard information for sailing races and offers RESTful APIs to al
version="0.0.0"
unpack="false"/>
<plugin
id="com.sap.sailing.polars"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>
@@ -38,6 +38,7 @@ import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.leaderboard.ScoringScheme;
import com.sap.sailing.domain.polars.PolarDataService;
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
import com.sap.sailing.domain.regattalike.RegattaLikeIdentifier;
import com.sap.sailing.domain.regattalike.RegattaLikeListener;
@@ -902,4 +903,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
// TODO Auto-generated method stub
return 0;
}
@Override
public void setPolarDataService(PolarDataService polarDataService) {
}
}
@@ -2,5 +2,7 @@ eclipse.preferences.version=1
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.properties=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_cn.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
@@ -50,10 +50,7 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sse.gwt.theme
Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator
Bundle-ActivationPolicy: lazy
Import-Package: com.sap.sailing.polars,
com.sap.sailing.polars.factory,
com.sap.sailing.polars.regression,
javax.jms;version="1.1.0",
Import-Package: javax.jms;version="1.1.0",
javax.servlet;version="3.1.0",
javax.servlet.descriptor;version="3.1.0",
javax.servlet.http;version="3.1.0",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 KiB

After

Width:  |  Height:  |  Size: 286 KiB

@@ -44,6 +44,7 @@ public interface TextMessages extends Messages {
String overview();
String sapSailing();
String search();
String startSimulator();
String countdownDays();
String countdownHours();
@@ -33,6 +33,7 @@ whatsNew=What''s new
overview=Overview
sapSailing=SAP Sailing
search=Search
startSimulator=Start Simulator
countdownDays=Days
countdownHours=Hrs
@@ -33,6 +33,7 @@ whatsNew=Neuigkeiten
overview=Übersicht
sapSailing=SAP Sailing
search=Suche
startSimulator=Simulator starten
countdownDays=Tage
countdownHours=Std.
@@ -1,5 +1,8 @@
package com.sap.sailing.gwt.home.client.app;
import java.util.HashMap;
import java.util.Map;
import com.google.gwt.place.shared.PlaceController;
import com.sap.sailing.gwt.home.client.place.aboutus.AboutUsPlace;
import com.sap.sailing.gwt.home.client.place.contact.ContactPlace;
@@ -19,6 +22,7 @@ import com.sap.sailing.gwt.home.client.place.sponsoring.SponsoringPlace;
import com.sap.sailing.gwt.home.client.place.start.StartPlace;
import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace;
import com.sap.sailing.gwt.home.client.place.whatsnew.WhatsNewPlace.WhatsNewNavigationTabs;
import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory;
public class HomePlacesNavigator extends AbstractPlaceNavigator {
@@ -42,6 +46,11 @@ public class HomePlacesNavigator extends AbstractPlaceNavigator {
return createLocalPlaceNavigation(new WhatsNewPlace(navigationTab));
}
public String getSimulatorURL() {
Map<String, String> parameters = new HashMap<String, String>();
return EntryPointLinkFactory.createSimulatorLink(parameters);
}
public PlaceNavigation<SponsoringPlace> getSponsoringNavigation() {
return createGlobalPlaceNavigation(new SponsoringPlace());
}
@@ -6,11 +6,6 @@
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.oldleaderboard.OldLeaderboardResources" />
<ui:style>
.marginFix {
margin:2rem 5rem;
}
</ui:style>
<g:HTMLPanel >
<div class="{res.mediaCss.grid}" >
<div class="{res.mediaCss.small7} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
@@ -27,7 +22,7 @@
</div>
</div>
<div class="{res.mediaCss.grid} {style.marginFix}" >
<div class="{res.mediaCss.grid} {local_res.css.marginFix}" >
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<table class="{local_res.css.regattaleaderboard_table}">
<tr>
@@ -6,12 +6,6 @@
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
<ui:with field="local_res" type="com.sap.sailing.gwt.home.client.place.event.regattaleaderboard.EventRegattaLeaderboardResources" />
<ui:with field="local_res2" type="com.sap.sailing.gwt.home.client.place.event.oldmultileaderboard.OldMultiLeaderboardResources" />
<ui:style>
.marginFix {
margin:2rem 5rem;
}
</ui:style>
<g:HTMLPanel>
<div class="{res.mediaCss.grid}" >
<div class="{res.mediaCss.small6} {res.mediaCss.column} {local_res.css.regattaleaderboard_meta_scoring}">
@@ -28,7 +22,7 @@
</div>
</div>
<div class="{res.mediaCss.grid} {style.marginFix}" >
<div class="{res.mediaCss.grid} {local_res.css.marginFix}" >
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<table class="{local_res.css.regattaleaderboard_table}">
<tr>
@@ -41,7 +41,7 @@
margin-left: 5rem;
margin-right: 5rem;
font-size: 15px;
font-size: 1rem;
/* @alternate */ font-size: 1rem;
width: 100%;
}
.regattaleaderboard_meta {
@@ -208,3 +208,13 @@
width: 100%;
table-layout: fixed;
}
.marginFix {
margin:2rem auto;
width: 100%;
}
@media (min-width: 84em) {
.marginFix {
margin:2rem 5rem;
width: auto;
}
}
@@ -7,7 +7,7 @@ import com.google.gwt.resources.client.CssResource;
public interface EventRegattaLeaderboardResources extends ClientBundle {
public static final EventRegattaLeaderboardResources INSTANCE = GWT.create(EventRegattaLeaderboardResources.class);
@Source("com/sap/sailing/gwt/home/client/place/event/regattaleaderboard/EventRegattaLeaderboard.css")
@Source("EventRegattaLeaderboard.gss")
LocalCss css();
public interface LocalCss extends CssResource {
@@ -58,5 +58,6 @@ public interface EventRegattaLeaderboardResources extends ClientBundle {
String leaderboardcompetitor_item_table();
String leaderboardcompetitor_itemcenter_table();
String leaderboardcompetitorshort();
String marginFix();
}
}
@@ -54,6 +54,7 @@
}
.eventsoverviewrecent_year_header_title {
margin-bottom: 0;
line-height: 1.944444444444444em;
}
.eventsoverviewrecent_year_header_info {
float: right;
@@ -28,15 +28,15 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV
private static final HyperlinkImpl HYPERLINK_IMPL = GWT.create(HyperlinkImpl.class);
@UiField HTML sailingAnalyticsNotes;
// @UiField HTML sailingSimulatorNotes;
@UiField HTML sailingSimulatorNotes;
@UiField HTML raceCommitteeAppNotes;
@UiField Anchor sailingAnalyticsNotesAnchor;
// @UiField Anchor sailingSimulatorNotesAnchor;
@UiField Anchor sailingSimulatorNotesAnchor;
@UiField Anchor raceCommitteeAppNotesAnchor;
private final PlaceNavigation<WhatsNewPlace> sailingAnalyticNotesNavigation;
// private final PlaceNavigation<WhatsNewPlace> sailingSimulatorNoteNavigation;
private final PlaceNavigation<WhatsNewPlace> sailingSimulatorNoteNavigation;
private final PlaceNavigation<WhatsNewPlace> raceCommitteeAppNotesNavigation;
private final List<Anchor> links;
@@ -49,19 +49,19 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV
initWidget(uiBinder.createAndBindUi(this));
sailingAnalyticsNotes.setHTML(WhatsNewResources.INSTANCE.getSailingAnalyticsNotesHtml().getText());
// sailingSimulatorNotes.setHTML(WhatsNewResources.INSTANCE.getSailingSimulatorNotesHtml().getText());
sailingSimulatorNotes.setHTML(WhatsNewResources.INSTANCE.getSailingSimulatorNotesHtml().getText());
raceCommitteeAppNotes.setHTML(WhatsNewResources.INSTANCE.getRaceCommitteeAppNotesHtml().getText());
sailingAnalyticNotesNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingAnalytics);
// sailingSimulatorNoteNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingSimulator);
sailingSimulatorNoteNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingSimulator);
raceCommitteeAppNotesNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.RaceCommiteeApp);
sailingAnalyticsNotesAnchor.setHref(sailingAnalyticNotesNavigation.getTargetUrl());
// sailingSimulatorNotesAnchor.setHref(sailingSimulatorNoteNavigation.getTargetUrl());
sailingSimulatorNotesAnchor.setHref(sailingSimulatorNoteNavigation.getTargetUrl());
raceCommitteeAppNotesAnchor.setHref(raceCommitteeAppNotesNavigation.getTargetUrl());
links = Arrays.asList(new Anchor[] { sailingAnalyticsNotesAnchor, /*sailingSimulatorNotesAnchor,*/ raceCommitteeAppNotesAnchor });
contentWidgets = Arrays.asList(new HTML[] { sailingAnalyticsNotes, /*sailingSimulatorNotes,*/ raceCommitteeAppNotes });
links = Arrays.asList(new Anchor[] { sailingAnalyticsNotesAnchor, sailingSimulatorNotesAnchor, raceCommitteeAppNotesAnchor });
contentWidgets = Arrays.asList(new HTML[] { sailingAnalyticsNotes, sailingSimulatorNotes, raceCommitteeAppNotes });
switch(navigationTab) {
case PostRaceAnalytics:
@@ -73,7 +73,7 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV
setActiveContent(sailingAnalyticsNotes, sailingAnalyticsNotesAnchor);
break;
case SailingSimulator:
// setActiveContent(sailingSimulatorNotes, sailingSimulatorNotesAnchor);
setActiveContent(sailingSimulatorNotes, sailingSimulatorNotesAnchor);
break;
case TrainingDiary:
break;
@@ -85,13 +85,13 @@ public class TabletAndDesktopWhatsNewView extends Composite implements WhatsNewV
setActiveContent(sailingAnalyticsNotes, sailingAnalyticsNotesAnchor);
handleClickEventWithLocalNavigation(event, sailingAnalyticNotesNavigation);
}
/*
@UiHandler("sailingSimulatorNotesAnchor")
void featuresClicked(ClickEvent event) {
setActiveContent(sailingSimulatorNotes, sailingSimulatorNotesAnchor);
handleClickEventWithLocalNavigation(event, sailingSimulatorNoteNavigation);
}
*/
@UiHandler("raceCommitteeAppNotesAnchor")
void releaseNotesClicked(ClickEvent event) {
setActiveContent(raceCommitteeAppNotes, raceCommitteeAppNotesAnchor);
@@ -10,9 +10,7 @@
<div class="{res.mediaCss.grid}">
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<g:Anchor ui:field="sailingAnalyticsNotesAnchor" href="javascript:;" styleName="{local_res.css.whatsnew_nav_link}"><ui:text from='{i18n.solutionsSAPHeadline}'/></g:Anchor>
<!--
<g:Anchor ui:field="sailingSimulatorNotesAnchor" href="javascript:;" styleName="{local_res.css.whatsnew_nav_link}"><ui:text from='{i18n.solutionsSimulatorHeadline}'/></g:Anchor>
-->
<g:Anchor ui:field="sailingSimulatorNotesAnchor" href="javascript:;" styleName="{local_res.css.whatsnew_nav_link}"><ui:text from='{i18n.solutionsSimulatorHeadline}'/></g:Anchor>
<g:Anchor ui:field="raceCommitteeAppNotesAnchor" href="javascript:;" styleName="{local_res.css.whatsnew_nav_link}"><ui:text from='{i18n.solutionsRaceHeadline}'/></g:Anchor>
</div>
</div>
@@ -20,9 +18,7 @@
<div class="{res.mediaCss.grid}">
<div class="{res.mediaCss.small12} {res.mediaCss.columns}">
<g:HTML ui:field="sailingAnalyticsNotes" />
<!--
<g:HTML ui:field="sailingSimulatorNotes" />
-->
<g:HTML ui:field="raceCommitteeAppNotes" />
</div>
</div>
@@ -44,6 +44,8 @@ public class Solutions extends Composite {
@UiField Anchor sailingAnalyticsDetailsAnchor;
@UiField Anchor raceCommitteeAppDetailsAnchor;
@UiField Anchor simulatorStartAnchor;
@UiField Anchor simulatorAppDetailsAnchor;
private final PlaceNavigation<SolutionsPlace> sailingAnalyticsNavigation;
private final PlaceNavigation<SolutionsPlace> raceCommitteeAppNavigation;
@@ -55,6 +57,7 @@ public class Solutions extends Composite {
private final PlaceNavigation<WhatsNewPlace> sailingAnalyticsDetailsNavigation;
private final PlaceNavigation<WhatsNewPlace> raceCommitteeAppDetailsNavigation;
private final PlaceNavigation<WhatsNewPlace> simulatorAppDetailsNavigation;
private final HomePlacesNavigator placesNavigator;
public Solutions(SolutionsNavigationTabs navigationTab, HomePlacesNavigator placesNavigator) {
@@ -67,9 +70,12 @@ public class Solutions extends Composite {
sailingAnalyticsDetailsNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingAnalytics);
raceCommitteeAppDetailsNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.RaceCommiteeApp);
simulatorAppDetailsNavigation = placesNavigator.getWhatsNewNavigation(WhatsNewNavigationTabs.SailingSimulator);
sailingAnalyticsDetailsAnchor.setHref(sailingAnalyticsDetailsNavigation.getTargetUrl());
raceCommitteeAppDetailsAnchor.setHref(raceCommitteeAppDetailsNavigation.getTargetUrl());
simulatorAppDetailsAnchor.setHref(simulatorAppDetailsNavigation.getTargetUrl());
simulatorStartAnchor.setHref(placesNavigator.getSimulatorURL());
sailingAnalyticsNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.SailingAnalytics);
raceCommitteeAppNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.RaceCommiteeApp);
@@ -127,7 +133,12 @@ public class Solutions extends Composite {
public void sailingAnalyticsDetailsClicked(ClickEvent e) {
handleClickEventWithPlaceController(e, sailingAnalyticsDetailsNavigation);
}
@UiHandler("simulatorAppDetailsAnchor")
public void simulatorAppDetailsAnchorClicked(ClickEvent e) {
handleClickEventWithPlaceController(e, simulatorAppDetailsNavigation);
}
private void scrollToView(SolutionsNavigationTabs navigationTab) {
switch (navigationTab) {
case SailingAnalytics:
@@ -67,7 +67,9 @@
<div class="{res.mediaCss.small5} {res.mediaCss.smalloffset7} {res.mediaCss.columns}">
<h2><ui:text from='{i18n.solutionsSimulatorHeadline}'/></h2>
<p><ui:text from='{i18n.solutionsSimulatorText}'/></p>
<!-- <a href="#" class="{res.mainCss.button}">Learn More</a> -->
<g:Anchor ui:field="simulatorAppDetailsAnchor" styleName="{res.mainCss.button}"><ui:text from='{i18n.whatsNew}'/></g:Anchor>
<span>&nbsp;&nbsp;</span>
<g:Anchor ui:field="simulatorStartAnchor" target="_blank" styleName="{res.mainCss.button}"><ui:text from='{i18n.startSimulator}'/></g:Anchor>
</div>
</div>
</div>
@@ -5,6 +5,7 @@ import java.util.HashMap;
import java.util.Map;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.domain.common.LegIdentifier;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.dto.CompetitorDTO;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
@@ -20,10 +21,11 @@ public class GetRaceMapDataAction implements AsyncAction<RaceMapDataDTO> {
private final Map<CompetitorDTO, Date> to;
private final boolean extrapolate;
private final Date date;
private final LegIdentifier simulationLegIdentifier;
public GetRaceMapDataAction(SailingServiceAsync sailingService, Iterable<CompetitorDTO> allCompetitors,
RegattaAndRaceIdentifier raceIdentifier, Date date, Map<CompetitorDTO, Date> from,
Map<CompetitorDTO, Date> to, boolean extrapolate) {
Map<CompetitorDTO, Date> to, boolean extrapolate, LegIdentifier simulationLegIdentifier) {
this.allCompetitors = allCompetitors;
this.sailingService = sailingService;
this.raceIdentifier = raceIdentifier;
@@ -31,6 +33,7 @@ public class GetRaceMapDataAction implements AsyncAction<RaceMapDataDTO> {
this.from = from;
this.to = to;
this.extrapolate = extrapolate;
this.simulationLegIdentifier = simulationLegIdentifier;
}
@Override
@@ -46,7 +49,7 @@ public class GetRaceMapDataAction implements AsyncAction<RaceMapDataDTO> {
}
sailingService.getRaceMapData(raceIdentifier, date, fromByCompetitorIdAsString, toByCompetitorIdAsString,
extrapolate, new AsyncCallback<CompactRaceMapDataDTO>() {
extrapolate, simulationLegIdentifier, new AsyncCallback<CompactRaceMapDataDTO>() {
@Override
public void onFailure(Throwable caught) {
callback.onFailure(caught);
@@ -1,12 +1,11 @@
package com.sap.sailing.gwt.ui.actions;
import java.util.Date;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.LegIdentifier;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMap;
import com.sap.sailing.gwt.ui.shared.SimulatorResultsDTO;
import com.sap.sailing.gwt.ui.shared.racemap.RaceSimulationOverlay;
import com.sap.sse.gwt.client.async.AsyncAction;
/**
@@ -18,19 +17,15 @@ import com.sap.sse.gwt.client.async.AsyncAction;
*/
public class GetSimulationAction implements AsyncAction<SimulatorResultsDTO> {
private final SailingServiceAsync sailingService;
private final RegattaAndRaceIdentifier raceIdentifier;
private final Date from;
private final Date prevStartTime;
private final LegIdentifier legIdentifier;
public GetSimulationAction(SailingServiceAsync sailingService, RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime) {
public GetSimulationAction(SailingServiceAsync sailingService, LegIdentifier legIdentifier) {
this.sailingService = sailingService;
this.raceIdentifier = raceIdentifier;
this.from = from;
this.prevStartTime = prevStartTime;
this.legIdentifier = legIdentifier;
}
@Override
public void execute(AsyncCallback<SimulatorResultsDTO> callback) {
sailingService.getSimulatorResults(raceIdentifier, from, prevStartTime, callback);
sailingService.getSimulatorResults(legIdentifier, callback);
}
}
@@ -41,7 +41,7 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
private final TextBox sailId;
private final TextBox email;
private final StringMessages stringMessages;
private final TextBox flagImageURL;
private final URLFieldWithFileUpload flagImageURL;
private final URLFieldWithFileUpload imageUrlAndUploadComposite;
public CompetitorEditDialog(final StringMessages stringMessages, CompetitorDTO competitorToEdit,
@@ -123,12 +123,12 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
}
}
this.sailId = createTextBox(competitorToEdit.getSailID());
this.flagImageURL = createTextBox(competitorToEdit.getFlagImageURL(), 100);
imageUrlAndUploadComposite = new URLFieldWithFileUpload(stringMessages);
imageUrlAndUploadComposite.setURL(competitorToEdit.getImageURL());
this.flagImageURL = new URLFieldWithFileUpload(stringMessages);
this.flagImageURL.setURL(competitorToEdit.getFlagImageURL());
this.imageUrlAndUploadComposite = new URLFieldWithFileUpload(stringMessages);
this.imageUrlAndUploadComposite.setURL(competitorToEdit.getImageURL());
}
@Override
public void show() {
super.show();
@@ -182,7 +182,7 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
/* twoLetterIsoCountryCode */ null,
threeLetterIocCountryCode.getValue(threeLetterIocCountryCode.getSelectedIndex()),
/* countryName */ null, sailId.getText(), competitorToEdit.getIdAsString(),
imageUrlAndUploadComposite.getURL(), flagImageURL.getText(), boatClass);
imageUrlAndUploadComposite.getURL(), flagImageURL.getURL(), boatClass);
return result;
}
@@ -70,11 +70,9 @@ public class CompetitorTableWrapper<S extends SelectionModel<CompetitorDTO>> ext
SafeHtmlBuilder sb = new SafeHtmlBuilder();
ImageResourceRenderer renderer = new ImageResourceRenderer();
final String twoLetterIsoCountryCode = competitor.getTwoLetterIsoCountryCode();
final String imageURL = competitor.getImageURL();
if (imageURL != null && !imageURL.isEmpty()) {
sb.appendHtmlConstant("<img src=\"" + imageURL + "\" width=\"18px\" height=\"12px\" title=\"" + competitor.getName() + "\"/>");
final String flagImageURL = competitor.getFlagImageURL();
if (flagImageURL != null && !flagImageURL.isEmpty()) {
sb.appendHtmlConstant("<img src=\"" + flagImageURL + "\" width=\"18px\" height=\"12px\" title=\"" + competitor.getName() + "\"/>");
sb.appendHtmlConstant("&nbsp;");
} else {
final ImageResource flagImageResource;
@@ -113,8 +111,8 @@ public class CompetitorTableWrapper<S extends SelectionModel<CompetitorDTO>> ext
public SafeHtml getValue(CompetitorDTO competitor) {
SafeHtmlBuilder sb = new SafeHtmlBuilder();
if (competitor.getImageURL() != null && !competitor.getImageURL().isEmpty()) {
sb.appendHtmlConstant("<img src=\"/sailingserver/api/v1/file?uri=" + competitor.getImageURL()
+ "\" height=\"40px\" title=\"" + competitor.getImageURL() + "\"/>");
sb.appendHtmlConstant("<img src=\"" + competitor.getImageURL() + "\" height=\"40px\" title=\""
+ competitor.getImageURL() + "\"/>");
}
return sb.toSafeHtml();
}
@@ -246,10 +246,14 @@ public class DeviceConfigurationDetailComposite extends Composite {
}
private void markAsDirty(boolean dirty) {
if (dirty && !(captionPanel.getTitle() == stringMessages.configuration())) {
captionPanel.setCaptionText(stringMessages.configuration() + "* (CHANGED)");
if (dirty) {
if (captionPanel.getCaptionText().equals(stringMessages.configuration())) {
captionPanel.setCaptionText(stringMessages.configuration() + "* (CHANGED)");
}
} else {
captionPanel.setCaptionText(stringMessages.configuration());
if (!captionPanel.getCaptionText().equals(stringMessages.configuration())) {
captionPanel.setCaptionText(stringMessages.configuration());
}
}
}
@@ -60,6 +60,11 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
private ListBox basicClassFlagListBox;
private CheckBox basicRecallBox;
private DisclosurePanel leagueDisclosurePanel;
private CheckBox leagueEnabledBox;
private ListBox leagueClassFlagListBox;
private CheckBox leagueRecallBox;
public RegattaConfigurationDialog(DeviceConfigurationDTO.RegattaConfigurationDTO regattaConfiguration,
StringMessages messages, DataEntryDialog.DialogCallback<RegattaConfigurationDTO> callback) {
super(messages.racingProcedureConfiguration(), "", messages.save(), messages.cancel(), /* validator */ null, callback);
@@ -75,6 +80,7 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
setupGateStart();
setupESS();
setupBasic();
setupLeague();
if (rrs26EnabledBox.getValue()) {
rrs26DisclosurePanel.setOpen(true);
@@ -88,6 +94,9 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
if (basicEnabledBox.getValue()) {
basicDisclosurePanel.setOpen(true);
}
if (leagueEnabledBox.getValue()) {
leagueDisclosurePanel.setOpen(true);
}
return contentPanel;
}
@@ -109,7 +118,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
racingProcedureListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
markAsDrity(true);
}
});
grid.setWidget(gridRow, 0, new Label(stringMessages.racingProcedure()));
@@ -126,7 +134,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
designerModeEntryListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
markAsDrity(true);
}
});
grid.setWidget(gridRow, 0, new Label(stringMessages.courseDesignerMode()));
@@ -143,7 +150,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
box.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
markAsDrity(true);
}
});
return box;
@@ -155,7 +161,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
markAsDrity(true);
}
});
return box;
@@ -170,7 +175,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
rrs26EnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
markAsDrity(true);
boolean isActive = event.getValue();
rrs26ClassFlagListBox.setEnabled(isActive);
rrs26RecallBox.setEnabled(isActive);
@@ -215,7 +219,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
rrs26StartModeFlagsBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
markAsDrity(true);
}
});
}
@@ -229,7 +232,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
gateStartEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
markAsDrity(true);
gateStartClassFlagListBox.setEnabled(event.getValue());
gateStartRecallBox.setEnabled(event.getValue());
gateStartPathfinderBox.setEnabled(event.getValue());
@@ -244,14 +246,12 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
gateStartPathfinderBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
markAsDrity(true);
}
});
gateStartGolfDownBox = createCheckbox(stringMessages.hasAdditionalGolfDownTime());
gateStartGolfDownBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
markAsDrity(true);
}
});
@@ -284,7 +284,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
essEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
markAsDrity(true);
essClassFlagListBox.setEnabled(event.getValue());
essRecallBox.setEnabled(event.getValue());
}
@@ -318,7 +317,6 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
basicEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
markAsDrity(true);
basicClassFlagListBox.setEnabled(event.getValue());
basicRecallBox.setEnabled(event.getValue());
}
@@ -343,8 +341,37 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
contentPanel.add(basicDisclosurePanel);
}
private void markAsDrity(boolean b) {
// hmnn do we need to this?
private void setupLeague() {
leagueDisclosurePanel = new DisclosurePanel(stringMessages.leagueStart());
VerticalPanel panel = new VerticalPanel();
Grid grid = new Grid(2, 3);
leagueEnabledBox = new CheckBox(stringMessages.setConfiguration());
leagueEnabledBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
leagueClassFlagListBox.setEnabled(event.getValue());
leagueRecallBox.setEnabled(event.getValue());
}
});
leagueClassFlagListBox = setupClassFlagListBox(originalConfiguration == null ? null
: originalConfiguration.leagueConfiguration);
leagueClassFlagListBox.setWidth("100%");
leagueRecallBox = setupRecallBox();
grid.setWidget(0, 0, new Label(stringMessages.classFlag() + ":"));
grid.setWidget(0, 1, leagueClassFlagListBox);
grid.setWidget(0, 2, createHelpImage(stringMessages.classFlagHelpText("league start")));
grid.setWidget(1, 0, leagueRecallBox);
grid.setWidget(1, 2, createHelpImage(stringMessages.individualRecallHelpText()));
leagueEnabledBox.setValue(originalConfiguration != null && originalConfiguration.leagueConfiguration != null);
ValueChangeEvent.fire(leagueEnabledBox, leagueEnabledBox.getValue());
panel.add(leagueEnabledBox);
panel.add(grid);
leagueDisclosurePanel.add(panel);
contentPanel.add(leagueDisclosurePanel);
}
private Widget createHelpImage(String tooltip) {
@@ -399,6 +426,10 @@ public class RegattaConfigurationDialog extends DataEntryDialog<DeviceConfigurat
result.basicConfiguration = new DeviceConfigurationDTO.RegattaConfigurationDTO.RacingProcedureConfigurationDTO();
getRacingProcedureConfigurationResults(result.basicConfiguration, basicClassFlagListBox, basicRecallBox);
}
if (leagueEnabledBox.getValue()) {
result.leagueConfiguration = new DeviceConfigurationDTO.RegattaConfigurationDTO.LeagueConfigurationDTO();
getRacingProcedureConfigurationResults(result.leagueConfiguration, leagueClassFlagListBox, leagueRecallBox);
}
return result;
}
@@ -9,6 +9,10 @@ public class EntryPointLinkFactory extends AbstractEntryPointLinkFactory {
return createEntryPointLink("/gwt/RaceBoard.html", parameters);
}
public static String createSimulatorLink(Map<String, String> parameters) {
return createEntryPointLink("/gwt/Simulator.html", parameters);
}
public static String createLeaderboardLink(Map<String, String> parameters) {
return createEntryPointLink("/gwt/Leaderboard.html", parameters);
}
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.base.RemoteSailingServerReference;
import com.sap.sailing.domain.common.DataImportProgress;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.LeaderboardType;
import com.sap.sailing.domain.common.LegIdentifier;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.PassingInstruction;
@@ -144,10 +145,10 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
boolean getPolarResults(RegattaAndRaceIdentifier raceIdentifier);
SimulatorResultsDTO getSimulatorResults(RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime);
SimulatorResultsDTO getSimulatorResults(LegIdentifier legIdentifier);
CompactRaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date, Map<String, Date> fromPerCompetitorIdAsString,
Map<String, Date> toPerCompetitorIdAsString, boolean extrapolate) throws NoWindException;
Map<String, Date> toPerCompetitorIdAsString, boolean extrapolate, LegIdentifier simulationLegIdentifier) throws NoWindException;
RaceTimesInfoDTO getRaceTimesInfo(RegattaAndRaceIdentifier raceIdentifier);
@@ -13,6 +13,7 @@ import com.sap.sailing.domain.base.RemoteSailingServerReference;
import com.sap.sailing.domain.common.DataImportProgress;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.LeaderboardType;
import com.sap.sailing.domain.common.LegIdentifier;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.PassingInstruction;
import com.sap.sailing.domain.common.PolarSheetGenerationResponse;
@@ -191,7 +192,7 @@ public interface SailingServiceAsync extends BuildVersionRetriever, FileStorageM
void getPolarResults(RegattaAndRaceIdentifier raceIdentifier, AsyncCallback<Boolean> callback);
void getSimulatorResults(RegattaAndRaceIdentifier raceIdentifier, Date from, Date prevStartTime, AsyncCallback<SimulatorResultsDTO> callback);
void getSimulatorResults(LegIdentifier legIdentifier, AsyncCallback<SimulatorResultsDTO> callback);
void setWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO wind, AsyncCallback<Void> callback);
@@ -336,7 +337,7 @@ public interface SailingServiceAsync extends BuildVersionRetriever, FileStorageM
* identified by <code>raceIdentifier</code> will be used, considering that race's delay.
*/
void getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date, Map<String, Date> fromPerCompetitorIdAsString,
Map<String, Date> toPerCompetitorIdAsString, boolean extrapolate, AsyncCallback<CompactRaceMapDataDTO> callback);
Map<String, Date> toPerCompetitorIdAsString, boolean extrapolate, LegIdentifier simulationLegIdentifier, AsyncCallback<CompactRaceMapDataDTO> callback);
void getReplicaInfo(AsyncCallback<ReplicationStateDTO> callback);
@@ -19,6 +19,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String wind();
String windPanelLabel();
String refresh();
@Override
String remove();
String windSource();
String dampeningInterval();
@@ -53,6 +54,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String linkToColumn();
String unlink();
String leaderboardName();
@Override
String cancel();
String pleaseEnterAName();
String pleaseEnterABoatClass();
@@ -65,6 +67,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String renameLeaderboard();
String addColumnToLeaderboard();
String pleaseEnterNameForNewRaceColumn();
@Override
String ok();
String medalRace();
String renameRace();
@@ -81,6 +84,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String leaderboard();
String leaderboards();
String leaderboardSettings();
@Override
String settings();
String linkedRaces();
String selectAtLeastOneLegDetail();
@@ -154,6 +158,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String penaltyCircles();
String medalRaceIsNull();
String maneuverTypes();
@Override
String configuration();
String chooseChart();
String distanceTraveled();
@@ -166,12 +171,14 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String in();
String secondsUnit();
String metersUnit();
@Override
String close();
String compareCompetitors();
String description();
String sailNumber();
String country();
String no3LetterCodes();
@Override
String add();
String delete();
String showCharts();
@@ -944,6 +951,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String pathfinderHelpText();
String essStart();
String basicStart();
String leagueStart();
String configured();
String overwriteRacingProceduresConfiguration();
String overwriteRacingProceduresConfigurationHelpText();
@@ -1141,9 +1149,13 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String enterRaceName();
String enterCourseName();
String scoringSchemeHighPointFirstGetsTenOrEightDescription();
@Override
String serverError();
@Override
String remoteProcedureCall();
@Override
String serverReplies();
@Override
String errorCommunicatingWithServer();
String userManagement();
String structureImportUrls();
@@ -1191,10 +1203,15 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String sendingMailsSuccessful();
String selectEventForInvitation();
String imageURL();
@Override
String upload();
String removeResult(JSONValue status, JSONValue message);
@Override
String uploadSuccessful();
String fileUploadResult(JSONValue status, JSONValue message);
@Override
String fileUploadResult(String status, String message);
@Override
String removeUploadedFile();
String showCompetitorSailIdColumn();
String showCompetitorFullNameColumn();
String loadingDimensionValues();
@@ -1212,7 +1229,8 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String valueDescending();
String sortBy();
String dashboardWindBotLoading();
String dashboardWindBotLoadingText();
String dashboardWindBotLoadingMessage();
String dashboardWindBotNotAvailable();
String dashboardWindBot();
String dashboardTrueWindSpeed();
Loaded 100 of 222 files, more files were not shown because too many files have changed in this diff. Show more