mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-07 19:42:17 +00:00
Merge remote-tracking branch 'origin/master' into simulator
Conflicts: doc/DEVELOPMENT java/com.sap.sailing.gwt.ui.test/META-INF/MANIFEST.MF java/com.sap.sailing.gwt.ui/META-INF/MANIFEST.MF java/com.sap.sailing.gwt.ui/RaceBoard.css java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TrackedRacesListComposite.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/RaceTimePanel.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardResources.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardSettingsFactory.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardEntryPoint.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/MarkPassingTimesDTO.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/RaceTimesInfoDTO.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/RaceMap.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/RaceMapImageManager.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/RaceMapResources.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/RaceMapSettings.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/racemap/ZoomTypeFormatter.java java/com.sap.sailing.server/META-INF/MANIFEST.MF java/com.sap.sailing.server/SailingServer (No Proxy).launch java/com.sap.sailing.server/SailingServer (Proxy).launch java/com.sap.sailing.server/src/com/sap/sailing/server/RacingEventService.java java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java java/com.sap.sailing.targetplatform.base/features/target-base/feature.xml java/com.sap.sailing.targetplatform.base/site.xml java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-ide-local-frank.target java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-ide-p2admin.target java/com.sap.sailing.targetplatform/definitions/race-analysis-p2-maven-local-extern.target java/com.sap.sailing.www/main.css java/pom.xml java/target/configuration/jetty/etc/realm.properties
This commit is contained in:
commit
58f2201db5
277 files changed
+5077
-1181
No files matched your search
@@ -17,7 +17,8 @@ Require-Bundle: com.sap.sailing.domain,
|
||||
com.google.gwt.osgi;bundle-version="2.4.0",
|
||||
com.sap.sailing.domain.common,
|
||||
org.moxieapps.gwt.highcharts;bundle-version="1.1.4",
|
||||
com.sap.sailing.geocoding
|
||||
com.sap.sailing.geocoding,
|
||||
com.sap.sailing.server.replication
|
||||
Bundle-Activator: com.sap.sailing.gwt.ui.server.Activator
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.sap.sailing.gwt.ui.client;x-friends:="com.sap.sailing.gwt.ui.test",
|
||||
@@ -26,9 +27,9 @@ Export-Package: com.sap.sailing.gwt.ui.client;x-friends:="com.sap.sailing.gwt.ui
|
||||
com.sap.sailing.gwt.ui.leaderboardedit;x-friends:="com.sap.sailing.gwt.ui.test",
|
||||
com.sap.sailing.gwt.ui.server;x-friends:="com.sap.sailing.gwt.ui.test",
|
||||
com.sap.sailing.gwt.ui.shared;x-friends:="com.sap.sailing.gwt.ui.test"
|
||||
Import-Package: com.sap.sailing.gwt.ui.shared,
|
||||
com.sap.sailing.simulator,
|
||||
Import-Package: com.sap.sailing.simulator,
|
||||
com.sap.sailing.simulator.impl,
|
||||
javax.jms;version="1.1.0",
|
||||
javax.servlet;version="2.5.0",
|
||||
javax.servlet.http;version="2.5.0",
|
||||
org.json.simple,
|
||||
|
||||
@@ -91,9 +91,9 @@ table {
|
||||
line-height: 1.0;
|
||||
}
|
||||
|
||||
input.magnifier {
|
||||
input.opencoloumn {
|
||||
display: block;
|
||||
margin: 3px auto 0 auto !important;
|
||||
margin: 3px auto 3px auto !important;
|
||||
}
|
||||
|
||||
.breadcrumbPanel {
|
||||
|
||||
+2
-2
@@ -8,13 +8,13 @@ import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
|
||||
public abstract class AbstractEventManagementPanel extends AbstractEventPanel {
|
||||
protected final TrackedEventsComposite trackedEventsComposite;
|
||||
protected final TrackedRacesListComposite trackedRacesListComposite;
|
||||
|
||||
public AbstractEventManagementPanel(SailingServiceAsync sailingService, EventRefresher eventRefresher,
|
||||
ErrorReporter errorReporter, RaceSelectionProvider raceSelectionProvider, StringMessages stringConstants) {
|
||||
super(sailingService, eventRefresher, errorReporter, stringConstants);
|
||||
// TrackedEventsComposite should exist in every *ManagementPanel.
|
||||
trackedEventsComposite = new TrackedEventsComposite(sailingService, errorReporter, eventRefresher,
|
||||
trackedRacesListComposite = new TrackedRacesListComposite(sailingService, errorReporter, eventRefresher,
|
||||
raceSelectionProvider, stringConstants, /* multiselection */ true);
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -48,13 +48,17 @@ public class AdminConsoleEntryPoint extends AbstractEntryPoint implements EventR
|
||||
CreateSwissTimingRacePanel createSwissTimingRacePanel = new CreateSwissTimingRacePanel(sailingService,this,stringMessages);
|
||||
createSwissTimingRacePanel.setSize("90%", "90%");
|
||||
tabPanel.add(createSwissTimingRacePanel,"Create SwissTiming race",false);
|
||||
TrackedRacesManagementPanel trackedRacesManagementPanel = new TrackedRacesManagementPanel(sailingService, this, this, stringMessages);
|
||||
eventDisplayers.add(trackedRacesManagementPanel);
|
||||
trackedRacesManagementPanel.setSize("90%", "90%");
|
||||
tabPanel.add(trackedRacesManagementPanel, stringMessages.trackedRaces(),false);
|
||||
final AsyncActionsExecutor asyncActionsExecutor = new AsyncActionsExecutor();
|
||||
WindPanel windPanel = new WindPanel(sailingService, asyncActionsExecutor, this, this, stringMessages);
|
||||
eventDisplayers.add(windPanel);
|
||||
windPanel.setSize("90%", "90%");
|
||||
tabPanel.add(windPanel, stringMessages.wind(), /* asHTML */ false);
|
||||
LeaderboardSettings defaultLeaderboardSettings = LeaderboardSettingsFactory.getInstance()
|
||||
.createNewDefaultSettings(/* racesToShow */ null, /* namesOfRacesToShow */ null, /* autoExpandFirstRace */false);
|
||||
.createNewDefaultSettings(/* racesToShow */ null, /* namesOfRacesToShow */ null, null, /* autoExpandFirstRace */false);
|
||||
final LeaderboardPanel defaultLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor,
|
||||
defaultLeaderboardSettings,
|
||||
/* preSelectedRace */null, new CompetitorSelectionModel(/* hasMultiSelection */true),
|
||||
@@ -70,6 +74,7 @@ public class AdminConsoleEntryPoint extends AbstractEntryPoint implements EventR
|
||||
leaderboardConfigPanel.setSize("90%", "90%");
|
||||
tabPanel.add(leaderboardConfigPanel, stringMessages.leaderboardConfiguration(), /* asHTML */ false);
|
||||
eventDisplayers.add(leaderboardConfigPanel);
|
||||
tabPanel.add(new ReplicationPanel(sailingService, this, stringMessages), stringMessages.replication(), /* asHTML */ false);
|
||||
|
||||
tabPanel.selectTab(0);
|
||||
tabPanel.addSelectionHandler(new SelectionHandler<Integer>() {
|
||||
|
||||
+14
-14
@@ -41,8 +41,8 @@ import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.view.client.ListDataProvider;
|
||||
import com.google.gwt.view.client.SelectionChangeEvent;
|
||||
import com.google.gwt.view.client.SingleSelectionModel;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventNameAndRaceName;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.EventDisplayer;
|
||||
@@ -59,7 +59,7 @@ import com.sap.sailing.gwt.ui.shared.RaceInLeaderboardDTO;
|
||||
public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer, RaceSelectionChangeListener,
|
||||
TrackedRaceChangedListener {
|
||||
|
||||
private final TrackedEventsComposite trackedEventsComposite;
|
||||
private final TrackedRacesListComposite trackedRacesListComposite;
|
||||
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
@@ -279,10 +279,10 @@ public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer,
|
||||
trackedRacesCaptionPanel.setStyleName("bold");
|
||||
|
||||
raceSelectionProvider = new RaceSelectionModel();
|
||||
trackedEventsComposite = new TrackedEventsComposite(sailingService, errorReporter, adminConsole,
|
||||
trackedRacesListComposite = new TrackedRacesListComposite(sailingService, errorReporter, adminConsole,
|
||||
raceSelectionProvider, stringMessages, /* multiselection */false);
|
||||
trackedRacesPanel.add(trackedEventsComposite);
|
||||
trackedEventsComposite.addTrackedRaceChangeListener(this);
|
||||
trackedRacesPanel.add(trackedRacesListComposite);
|
||||
trackedRacesListComposite.addTrackedRaceChangeListener(this);
|
||||
raceSelectionProvider.addRaceSelectionChangeListener(this);
|
||||
|
||||
HorizontalPanel hPanel = new HorizontalPanel();
|
||||
@@ -465,7 +465,7 @@ public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer,
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void arg0) {
|
||||
trackedEventsComposite.clearSelection();
|
||||
trackedRacesListComposite.clearSelection();
|
||||
getSelectedRaceInLeaderboard().setRaceIdentifier(null);
|
||||
raceColumnList.refresh();
|
||||
}
|
||||
@@ -567,7 +567,7 @@ public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer,
|
||||
} else {
|
||||
columnMoveUpButton.setEnabled(false);
|
||||
columnMoveDownButton.setEnabled(false);
|
||||
trackedEventsComposite.clearSelection();
|
||||
trackedRacesListComposite.clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,7 +588,7 @@ public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer,
|
||||
if (eventAndRaceName != null) {
|
||||
selectRaceInList(eventAndRaceName.getA(), eventAndRaceName.getB());
|
||||
} else {
|
||||
trackedEventsComposite.clearSelection();
|
||||
trackedRacesListComposite.clearSelection();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -596,7 +596,7 @@ public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer,
|
||||
|
||||
private void selectRaceInList(String eventName, String raceName) {
|
||||
EventNameAndRaceName raceIdentifier = new EventNameAndRaceName(eventName, raceName);
|
||||
trackedEventsComposite.selectRaceByIdentifier(raceIdentifier);
|
||||
trackedRacesListComposite.selectRaceByIdentifier(raceIdentifier);
|
||||
}
|
||||
|
||||
private RaceInLeaderboardDTO getSelectedRaceInLeaderboard() {
|
||||
@@ -726,7 +726,7 @@ public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer,
|
||||
private void leaderboardSelectionChanged() {
|
||||
// make sure that clearing the selection doesn't cause an unlinking of the selected tracked race
|
||||
raceSelectionProvider.removeRaceSelectionChangeListener(this);
|
||||
trackedEventsComposite.clearSelection();
|
||||
trackedRacesListComposite.clearSelection();
|
||||
// add listener again using a scheduled command which is executed when the browser's event loop re-gains
|
||||
// control; we assume that at that point in time the selection updates have already been performed
|
||||
Scheduler.get().scheduleFinally(new ScheduledCommand() {
|
||||
@@ -753,7 +753,7 @@ public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer,
|
||||
|
||||
@Override
|
||||
public void fillEvents(List<EventDTO> result) {
|
||||
trackedEventsComposite.fillEvents(result);
|
||||
trackedRacesListComposite.fillEvents(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -846,7 +846,7 @@ public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
// if no leaderboard column is selected, ignore the race selection change
|
||||
RaceInLeaderboardDTO selectedRaceInLeaderboard = getSelectedRaceInLeaderboard();
|
||||
if (selectedRaceInLeaderboard != null) {
|
||||
@@ -859,7 +859,7 @@ public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer,
|
||||
}
|
||||
|
||||
private void linkTrackedRaceToSelectedRaceColumn(final RaceInLeaderboardDTO selectedRaceInLeaderboard,
|
||||
final RaceIdentifier selectedRace) {
|
||||
final EventAndRaceIdentifier selectedRace) {
|
||||
sailingService.connectTrackedRaceToLeaderboardColumn(getSelectedLeaderboardName(), selectedRaceInLeaderboard
|
||||
.getRaceColumnName(), selectedRace,
|
||||
new AsyncCallback<Boolean>() {
|
||||
@@ -868,7 +868,7 @@ public class LeaderboardConfigPanel extends FormPanel implements EventDisplayer,
|
||||
errorReporter.reportError("Error trying to link tracked race " + selectedRace + " to race column named "
|
||||
+ selectedRaceInLeaderboard.getRaceColumnName() + " of leaderboard "
|
||||
+ getSelectedLeaderboardName() + ": " + t.getMessage());
|
||||
trackedEventsComposite.clearSelection();
|
||||
trackedRacesListComposite.clearSelection();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-3
@@ -15,6 +15,7 @@ import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.client.EventDisplayer;
|
||||
import com.sap.sailing.gwt.ui.client.EventRefresher;
|
||||
@@ -93,8 +94,8 @@ public class RacesListBoxPanel extends FormPanel implements EventDisplayer, Race
|
||||
raceSelectionProvider.setSelection(getSelectedRaceIdentifiers(), this);
|
||||
}
|
||||
|
||||
private List<RaceIdentifier> getSelectedRaceIdentifiers() {
|
||||
List<RaceIdentifier> result = new ArrayList<RaceIdentifier>();
|
||||
private List<EventAndRaceIdentifier> getSelectedRaceIdentifiers() {
|
||||
List<EventAndRaceIdentifier> result = new ArrayList<EventAndRaceIdentifier>();
|
||||
for (RaceDTO selectedRace : getSelectedRaces()) {
|
||||
result.add(selectedRace.getRaceIdentifier());
|
||||
}
|
||||
@@ -118,7 +119,7 @@ public class RacesListBoxPanel extends FormPanel implements EventDisplayer, Race
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
if (selectedRaces != null && !selectedRaces.isEmpty()) {
|
||||
RaceDTO newSelection = getRace(selectedRaces.iterator().next());
|
||||
int index = raceList.indexOf(newSelection);
|
||||
|
||||
Executable
+96
@@ -0,0 +1,96 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.TextfieldEntryDialog;
|
||||
|
||||
/**
|
||||
* Allows administrators to manage all aspects of server instance replication such as showing whether the instance
|
||||
* is a master or a replica and for a master showing the replicas to which the master is currently replicating.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public class ReplicationPanel extends FlowPanel {
|
||||
private final ListBox registeredReplicas;
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final ErrorReporter errorReporter;
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
public ReplicationPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter, StringMessages stringMessages) {
|
||||
this.sailingService = sailingService;
|
||||
this.stringMessages = stringMessages;
|
||||
this.errorReporter = errorReporter;
|
||||
registeredReplicas = new ListBox();
|
||||
add(registeredReplicas);
|
||||
Button refreshButton = new Button(stringMessages.refresh());
|
||||
refreshButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
updateReplicaList();
|
||||
}
|
||||
});
|
||||
add(refreshButton);
|
||||
Button addButton = new Button(stringMessages.add());
|
||||
addButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
addReplication();
|
||||
}
|
||||
});
|
||||
add(addButton);
|
||||
}
|
||||
|
||||
private void addReplication() {
|
||||
TextfieldEntryDialog dialog = new TextfieldEntryDialog(stringMessages.add(), stringMessages.enterMaster(),
|
||||
stringMessages.ok(), stringMessages.cancel(), "", null, new AsyncCallback<String>() {
|
||||
@Override
|
||||
public void onSuccess(final String masterName) {
|
||||
sailingService.startReplicatingFromMaster(masterName, /* TODO servlet port */ 8888,
|
||||
/* TODO JMS port */ 61616, new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
errorReporter.reportError(stringMessages.errorStartingReplication(masterName, e.getMessage()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Void arg0) {
|
||||
updateReplicaList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable arg0) {
|
||||
// simply don't add replication
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void updateReplicaList() {
|
||||
sailingService.getHostnamesOfReplica(new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
public void onSuccess(List<String> hostnames) {
|
||||
registeredReplicas.clear();
|
||||
for (String hostname : hostnames) {
|
||||
registeredReplicas.addItem(hostname);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
errorReporter.reportError(stringMessages.errorFetchingReplicaData(e.getMessage()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -230,7 +230,7 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
|
||||
declinationCheckbox.setWordWrap(false);
|
||||
declinationCheckbox.setValue(true);
|
||||
trackPanel.add(declinationCheckbox);
|
||||
trackedRacesPanel.add(trackedEventsComposite);
|
||||
trackedRacesPanel.add(trackedRacesListComposite);
|
||||
|
||||
HorizontalPanel racesButtonPanel = new HorizontalPanel();
|
||||
racesPanel.add(racesButtonPanel);
|
||||
@@ -373,7 +373,7 @@ public class SwissTimingEventManagementPanel extends AbstractEventManagementPane
|
||||
|
||||
@Override
|
||||
public void fillEvents(List<EventDTO> result) {
|
||||
trackedEventsComposite.fillEvents(result);
|
||||
trackedRacesListComposite.fillEvents(result);
|
||||
}
|
||||
|
||||
private void fillRaceListFromAvailableRacesApplyingFilter(String text) {
|
||||
|
||||
+2
-2
@@ -327,7 +327,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
declinationCheckbox.setValue(true);
|
||||
trackPanel.add(declinationCheckbox);
|
||||
|
||||
trackedRacesPanel.add(trackedEventsComposite);
|
||||
trackedRacesPanel.add(trackedRacesListComposite);
|
||||
|
||||
HorizontalPanel racesButtonPanel = new HorizontalPanel();
|
||||
racesPanel.add(racesButtonPanel);
|
||||
@@ -487,7 +487,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
|
||||
|
||||
@Override
|
||||
public void fillEvents(List<EventDTO> result) {
|
||||
trackedEventsComposite.fillEvents(result);
|
||||
trackedRacesListComposite.fillEvents(result);
|
||||
}
|
||||
|
||||
private void fillRaceListFromAvailableRacesApplyingFilter(String text) {
|
||||
|
||||
+12
-8
@@ -42,6 +42,7 @@ import com.google.gwt.view.client.SelectionChangeEvent;
|
||||
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
|
||||
import com.google.gwt.view.client.SelectionModel;
|
||||
import com.google.gwt.view.client.SingleSelectionModel;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventNameAndRaceName;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
@@ -60,7 +61,7 @@ import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
* Shows the currently tracked events/races in a table. Updated if subscribed as an {@link EventDisplayer}, e.g., with
|
||||
* the {@link AdminConsoleEntryPoint}.
|
||||
*/
|
||||
public class TrackedEventsComposite extends FormPanel implements EventDisplayer, RaceSelectionChangeListener {
|
||||
public class TrackedRacesListComposite extends FormPanel implements EventDisplayer, RaceSelectionChangeListener {
|
||||
private final Set<TrackedRaceChangedListener> raceIsTrackedRaceChangeListener;
|
||||
|
||||
private final boolean multiSelection;
|
||||
@@ -110,7 +111,7 @@ public class TrackedEventsComposite extends FormPanel implements EventDisplayer,
|
||||
|
||||
private static AnchorTemplates ANCHORTEMPLATE = GWT.create(AnchorTemplates.class);
|
||||
|
||||
public TrackedEventsComposite(final SailingServiceAsync sailingService, final ErrorReporter errorReporter,
|
||||
public TrackedRacesListComposite(final SailingServiceAsync sailingService, final ErrorReporter errorReporter,
|
||||
final EventRefresher eventRefresher, RaceSelectionProvider raceSelectionProvider,
|
||||
StringMessages stringConstants, boolean hasMultiSelection) {
|
||||
if (eventRefresher == null) {
|
||||
@@ -313,11 +314,11 @@ public class TrackedEventsComposite extends FormPanel implements EventDisplayer,
|
||||
if (dontFireNextSelectionChangeEvent) {
|
||||
dontFireNextSelectionChangeEvent = false;
|
||||
} else {
|
||||
List<RaceIdentifier> selectedRaceIdentifiers = new ArrayList<RaceIdentifier>();
|
||||
List<EventAndRaceIdentifier> selectedRaceIdentifiers = new ArrayList<EventAndRaceIdentifier>();
|
||||
for (RaceDTO selectedRace : selectedRaces) {
|
||||
selectedRaceIdentifiers.add(selectedRace.getRaceIdentifier());
|
||||
}
|
||||
TrackedEventsComposite.this.raceSelectionProvider.setSelection(selectedRaceIdentifiers, TrackedEventsComposite.this);
|
||||
TrackedRacesListComposite.this.raceSelectionProvider.setSelection(selectedRaceIdentifiers, TrackedRacesListComposite.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -385,7 +386,7 @@ public class TrackedEventsComposite extends FormPanel implements EventDisplayer,
|
||||
}
|
||||
|
||||
public void clearSelection() {
|
||||
List<RaceIdentifier> emptySelection = Collections.emptyList();
|
||||
List<EventAndRaceIdentifier> emptySelection = Collections.emptyList();
|
||||
raceSelectionProvider.setSelection(emptySelection, /* listenersNotToNotify */ this);
|
||||
if (raceList != null) {
|
||||
for (RaceDTO race : raceList.getList()) {
|
||||
@@ -410,7 +411,7 @@ public class TrackedEventsComposite extends FormPanel implements EventDisplayer,
|
||||
noTrackedRacesLabel.setVisible(false);
|
||||
}
|
||||
List<RaceDTO> newAllRaces = new ArrayList<RaceDTO>();
|
||||
List<RaceIdentifier> newAllRaceIdentifiers = new ArrayList<RaceIdentifier>();
|
||||
List<EventAndRaceIdentifier> newAllRaceIdentifiers = new ArrayList<EventAndRaceIdentifier>();
|
||||
for (EventDTO event : events) {
|
||||
for (RegattaDTO regatta : event.regattas) {
|
||||
for (RaceDTO race : regatta.races) {
|
||||
@@ -426,6 +427,10 @@ public class TrackedEventsComposite extends FormPanel implements EventDisplayer,
|
||||
raceSelectionProvider.setAllRaces(newAllRaceIdentifiers); // have this object be notified; triggers onRaceSelectionChange
|
||||
}
|
||||
|
||||
public void addRaceSelectionChangeListener(RaceSelectionChangeListener listener) {
|
||||
this.raceSelectionProvider.addRaceSelectionChangeListener(listener);
|
||||
}
|
||||
|
||||
public void addTrackedRaceChangeListener(TrackedRaceChangedListener listener) {
|
||||
this.raceIsTrackedRaceChangeListener.add(listener);
|
||||
}
|
||||
@@ -500,11 +505,10 @@ public class TrackedEventsComposite extends FormPanel implements EventDisplayer,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
for (RaceDTO raceFromAllRaces : raceList.getList()) {
|
||||
selectionModel.setSelected(raceFromAllRaces, selectedRaces.contains(raceFromAllRaces.getRaceIdentifier()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Iterable<RaceDTO> getAllRaces() {
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.i18n.client.DateTimeFormat;
|
||||
import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
|
||||
import com.google.gwt.i18n.client.TimeZone;
|
||||
import com.google.gwt.text.client.DateTimeFormatRenderer;
|
||||
import com.google.gwt.user.client.ui.CaptionPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.EventRefresher;
|
||||
import com.sap.sailing.gwt.ui.client.RaceSelectionChangeListener;
|
||||
import com.sap.sailing.gwt.ui.client.RaceSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
|
||||
public class TrackedRacesManagementPanel extends AbstractEventManagementPanel implements RaceSelectionChangeListener {
|
||||
private EventAndRaceIdentifier singleSelectedRace;
|
||||
|
||||
private RaceDTO selectedRaceDTO;
|
||||
|
||||
private final CaptionPanel selectedRacePanel;
|
||||
|
||||
private final DateTimeFormatRenderer dateFormatter = new DateTimeFormatRenderer(
|
||||
DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT));
|
||||
private final DateTimeFormatRenderer timeFormatter = new DateTimeFormatRenderer(
|
||||
DateTimeFormat.getFormat(PredefinedFormat.TIME_LONG));
|
||||
private final DateTimeFormatRenderer durationFormatter = new DateTimeFormatRenderer(
|
||||
DateTimeFormat.getFormat(PredefinedFormat.TIME_MEDIUM), TimeZone.createTimeZone(0));
|
||||
|
||||
private List<EventDTO> savedEvents;
|
||||
|
||||
private final Grid raceDataGrid;
|
||||
|
||||
public TrackedRacesManagementPanel(final SailingServiceAsync sailingService, ErrorReporter errorReporter,
|
||||
EventRefresher eventRefresher, StringMessages stringConstants) {
|
||||
super(sailingService, eventRefresher, errorReporter, new RaceSelectionModel(), stringConstants);
|
||||
|
||||
VerticalPanel mainPanel = new VerticalPanel();
|
||||
this.setWidget(mainPanel);
|
||||
mainPanel.setWidth("100%");
|
||||
|
||||
mainPanel.add(trackedRacesListComposite);
|
||||
|
||||
trackedRacesListComposite.addRaceSelectionChangeListener(this);
|
||||
|
||||
singleSelectedRace = null;
|
||||
|
||||
selectedRacePanel = new CaptionPanel("???");
|
||||
selectedRacePanel.setWidth("100%");
|
||||
mainPanel.add(selectedRacePanel);
|
||||
|
||||
VerticalPanel vPanel = new VerticalPanel();
|
||||
vPanel.setWidth("100%");
|
||||
selectedRacePanel.setContentWidget(vPanel);
|
||||
selectedRacePanel.setVisible(false);
|
||||
|
||||
raceDataGrid = new Grid(3,2);
|
||||
vPanel.add(raceDataGrid);
|
||||
|
||||
raceDataGrid.setText(0, 0, "StartTime:");
|
||||
raceDataGrid.setText(1, 0, "EndTime:");
|
||||
raceDataGrid.setText(2, 0, "Duration:");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillEvents(List<EventDTO> result) {
|
||||
trackedRacesListComposite.fillEvents(result);
|
||||
|
||||
savedEvents = result;
|
||||
}
|
||||
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
if(selectedRaces.size() == 1) {
|
||||
singleSelectedRace = selectedRaces.get(0);
|
||||
selectedRacePanel.setCaptionText(singleSelectedRace.getRaceName());
|
||||
selectedRacePanel.setVisible(true);
|
||||
|
||||
for (EventDTO event : savedEvents) {
|
||||
for (RegattaDTO regatta : event.regattas) {
|
||||
for (RaceDTO race : regatta.races) {
|
||||
if (race != null && race.getRaceIdentifier().equals(singleSelectedRace)) {
|
||||
this.selectedRaceDTO = race;
|
||||
refreshRaceData();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
selectedRacePanel.setCaptionText("");
|
||||
singleSelectedRace = null;
|
||||
selectedRacePanel.setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshRaceData() {
|
||||
|
||||
if(singleSelectedRace != null && selectedRaceDTO != null) {
|
||||
if (selectedRaceDTO.startOfRace != null) {
|
||||
raceDataGrid.setText(0, 1, dateFormatter.render(selectedRaceDTO.startOfRace) + " "
|
||||
+ timeFormatter.render(selectedRaceDTO.startOfRace));
|
||||
} else {
|
||||
raceDataGrid.setText(0, 1, "");
|
||||
}
|
||||
if (selectedRaceDTO.endOfRace != null) {
|
||||
raceDataGrid.setText(1, 1, dateFormatter.render(selectedRaceDTO.endOfRace) + " "
|
||||
+ timeFormatter.render(selectedRaceDTO.endOfRace));
|
||||
} else {
|
||||
raceDataGrid.setText(1, 1, "");
|
||||
}
|
||||
if(selectedRaceDTO.startOfRace != null && selectedRaceDTO.endOfRace != null) {
|
||||
Date duration = new Date(selectedRaceDTO.endOfRace.getTime() - selectedRaceDTO.startOfRace.getTime());
|
||||
raceDataGrid.setText(2, 1, durationFormatter.render(duration));
|
||||
} else {
|
||||
raceDataGrid.setText(2, 1, "");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -35,6 +35,7 @@ import com.google.gwt.i18n.client.NumberFormat;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
@@ -493,7 +494,7 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
if (selectedRaces != null && !selectedRaces.isEmpty()) {
|
||||
// show wind of first selected race
|
||||
selectedRaceIdentifier = selectedRaces.iterator().next();
|
||||
|
||||
+13
-13
@@ -36,7 +36,7 @@ import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.view.client.ListDataProvider;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
@@ -77,7 +77,7 @@ public class WindPanel extends FormPanel implements EventDisplayer, WindShower,
|
||||
private final TextColumn<WindDTO> windDirectionInDegColumn;
|
||||
private final TextColumn<WindDTO> dampenedSpeedInKnotsColumn;
|
||||
private final TextColumn<WindDTO> dampenedWindDirectionInDegColumn;
|
||||
private final TrackedEventsComposite trackedEventsComposite;
|
||||
private final TrackedRacesListComposite trackedRacesListComposite;
|
||||
private final RaceSelectionProvider raceSelectionProvider;
|
||||
private final WindSourcesToExcludeSelector windSourcesToExcludeSelector;
|
||||
private final Map<WindSource, ListDataProvider<WindDTO>> windLists;
|
||||
@@ -96,8 +96,8 @@ public class WindPanel extends FormPanel implements EventDisplayer, WindShower,
|
||||
removeColumn = new IdentityColumn<WindDTO>(new ActionCell<WindDTO>(stringMessages.remove(), new Delegate<WindDTO>() {
|
||||
@Override
|
||||
public void execute(final WindDTO wind) {
|
||||
List<RaceIdentifier> selectedRaces = raceSelectionProvider.getSelectedRaces();
|
||||
final RaceIdentifier raceIdentifier = selectedRaces.get(selectedRaces.size()-1);
|
||||
List<EventAndRaceIdentifier> selectedRaces = raceSelectionProvider.getSelectedRaces();
|
||||
final EventAndRaceIdentifier raceIdentifier = selectedRaces.get(selectedRaces.size()-1);
|
||||
sailingService.removeWind(raceIdentifier, wind, new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
@@ -148,10 +148,10 @@ public class WindPanel extends FormPanel implements EventDisplayer, WindShower,
|
||||
}
|
||||
};
|
||||
grid = new Grid(4, 2); // first row: event/race selection; second row: wind source selection; third row: wind display
|
||||
trackedEventsComposite = new TrackedEventsComposite(sailingService, errorReporter, eventRefresher,
|
||||
trackedRacesListComposite = new TrackedRacesListComposite(sailingService, errorReporter, eventRefresher,
|
||||
raceSelectionProvider, stringMessages, false);
|
||||
raceSelectionProvider.addRaceSelectionChangeListener(this);
|
||||
grid.setWidget(0, 0, trackedEventsComposite);
|
||||
grid.setWidget(0, 0, trackedRacesListComposite);
|
||||
windSettingPanel = new WindSettingPanel(sailingService, errorReporter, raceSelectionProvider, this);
|
||||
grid.setWidget(0, 1, windSettingPanel);
|
||||
HorizontalPanel windSourceSelectionPanel = new HorizontalPanel();
|
||||
@@ -188,7 +188,7 @@ public class WindPanel extends FormPanel implements EventDisplayer, WindShower,
|
||||
this.setWidget(grid);
|
||||
}
|
||||
|
||||
private void clearOrShowWindBasedOnRaceSelection(List<RaceIdentifier> selectedRaces) {
|
||||
private void clearOrShowWindBasedOnRaceSelection(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
if (selectedRaces.isEmpty()) {
|
||||
clearWindDisplay(); // no wind known for untracked race
|
||||
} else {
|
||||
@@ -198,11 +198,11 @@ public class WindPanel extends FormPanel implements EventDisplayer, WindShower,
|
||||
|
||||
@Override
|
||||
public void fillEvents(List<EventDTO> result) {
|
||||
trackedEventsComposite.fillEvents(result);
|
||||
trackedRacesListComposite.fillEvents(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showWind(final RaceIdentifier raceIdentifier) {
|
||||
public void showWind(final EventAndRaceIdentifier raceIdentifier) {
|
||||
sailingService.getWindInfo(raceIdentifier,
|
||||
// TODO Time interval should be determined by a selection in the chart but be at most 60s. See bug #121. Consider incremental updates for new data only.
|
||||
null, null, // use race start and time of newest event as default time period
|
||||
@@ -228,7 +228,7 @@ public class WindPanel extends FormPanel implements EventDisplayer, WindShower,
|
||||
});
|
||||
}
|
||||
|
||||
private void updateWindSourcesToExclude(WindInfoForRaceDTO result, RaceIdentifier raceIdentifier) {
|
||||
private void updateWindSourcesToExclude(WindInfoForRaceDTO result, EventAndRaceIdentifier raceIdentifier) {
|
||||
windSourcesToExcludeSelector.update(raceIdentifier, result.windTrackInfoByWindSource.keySet(), result.windSourcesToExclude);
|
||||
}
|
||||
|
||||
@@ -338,9 +338,9 @@ public class WindPanel extends FormPanel implements EventDisplayer, WindShower,
|
||||
}
|
||||
|
||||
private void setRaceIsKnownToStartUpwind(final Runnable runOnSuccess) {
|
||||
List<RaceIdentifier> selection = raceSelectionProvider.getSelectedRaces();
|
||||
List<EventAndRaceIdentifier> selection = raceSelectionProvider.getSelectedRaces();
|
||||
if (selection != null && !selection.isEmpty()) {
|
||||
final RaceIdentifier selectedRace = selection.get(0);
|
||||
final EventAndRaceIdentifier selectedRace = selection.get(0);
|
||||
sailingService.setRaceIsKnownToStartUpwind(selectedRace,
|
||||
raceIsKnownToStartUpwindBox.getValue(), new AsyncCallback<Void>() {
|
||||
@Override
|
||||
@@ -359,7 +359,7 @@ public class WindPanel extends FormPanel implements EventDisplayer, WindShower,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
clearOrShowWindBasedOnRaceSelection(selectedRaces);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -10,7 +10,7 @@ import com.google.gwt.user.client.ui.DoubleBox;
|
||||
import com.google.gwt.user.client.ui.FormPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.RaceSelectionProvider;
|
||||
@@ -51,9 +51,9 @@ public class WindSettingPanel extends FormPanel {
|
||||
if (latDegBox.getValue() != null && lngDegBox.getValue() != null) {
|
||||
wind.position = new PositionDTO(latDegBox.getValue(), lngDegBox.getValue());
|
||||
}
|
||||
List<RaceIdentifier> selectedRaces = raceSelectionProvider.getSelectedRaces();
|
||||
List<EventAndRaceIdentifier> selectedRaces = raceSelectionProvider.getSelectedRaces();
|
||||
// Here we assume that single selection is enabled because the WindPanel creates a TrackedComposite with disabled multi selection.
|
||||
final RaceIdentifier raceIdentifier = selectedRaces.get(selectedRaces.size()-1);
|
||||
final EventAndRaceIdentifier raceIdentifier = selectedRaces.get(selectedRaces.size()-1);
|
||||
sailingService.setWind(raceIdentifier, wind, new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(Void result) {
|
||||
|
||||
+2
-4
@@ -1,9 +1,7 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
|
||||
public interface WindShower {
|
||||
|
||||
void showWind(RaceIdentifier race);
|
||||
|
||||
void showWind(EventAndRaceIdentifier race);
|
||||
}
|
||||
+4
-4
@@ -11,7 +11,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
@@ -31,7 +31,7 @@ public class WindSourcesToExcludeSelector extends VerticalPanel {
|
||||
private final StringMessages stringMessages;
|
||||
private final SailingServiceAsync service;
|
||||
private final ErrorReporter errorReporter;
|
||||
private RaceIdentifier raceIdentifier;
|
||||
private EventAndRaceIdentifier raceIdentifier;
|
||||
|
||||
public WindSourcesToExcludeSelector(SailingServiceAsync service,
|
||||
StringMessages stringMessages, ErrorReporter errorReporter) {
|
||||
@@ -42,7 +42,7 @@ public class WindSourcesToExcludeSelector extends VerticalPanel {
|
||||
add(new Label(stringMessages.windSourcesUsed()));
|
||||
}
|
||||
|
||||
public void update(RaceIdentifier raceIdentifier, Iterable<WindSource> allWindSources, Iterable<WindSource> windSourcesToExclude) {
|
||||
public void update(EventAndRaceIdentifier raceIdentifier, Iterable<WindSource> allWindSources, Iterable<WindSource> windSourcesToExclude) {
|
||||
this.raceIdentifier = raceIdentifier;
|
||||
Set<WindSource> windSourcesToRemove = new HashSet<WindSource>(checkboxesByWindSource.keySet());
|
||||
for (WindSource windSource : allWindSources) {
|
||||
@@ -73,7 +73,7 @@ public class WindSourcesToExcludeSelector extends VerticalPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private void onWindSourcesToExcludeChanged(final RaceIdentifier raceIdentifier) {
|
||||
private void onWindSourcesToExcludeChanged(final EventAndRaceIdentifier raceIdentifier) {
|
||||
service.setWindSourcesToExclude(raceIdentifier, getWindSourcesToExclude(), new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
|
||||
+9
@@ -1,5 +1,7 @@
|
||||
package com.sap.sailing.gwt.ui.client;
|
||||
|
||||
import com.google.gwt.dom.client.Style.FontWeight;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.dom.client.ChangeEvent;
|
||||
import com.google.gwt.event.dom.client.ChangeHandler;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
@@ -230,6 +232,13 @@ public abstract class DataEntryDialog<T> {
|
||||
return longBox;
|
||||
}
|
||||
|
||||
public Label createHeadlineLabel(String headlineText) {
|
||||
Label headlineLabel = new Label(headlineText);
|
||||
headlineLabel.getElement().getStyle().setFontWeight(FontWeight.BOLD);
|
||||
headlineLabel.getElement().getStyle().setPaddingTop(1, Unit.EM);
|
||||
return headlineLabel;
|
||||
}
|
||||
|
||||
public CheckBox createCheckbox(String checkboxLabel) {
|
||||
CheckBox result = new CheckBox(checkboxLabel);
|
||||
result.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||
|
||||
+4
@@ -33,6 +33,8 @@ public class DetailTypeFormatter {
|
||||
return stringMessages.gapToLeaderInSeconds();
|
||||
case RACE_DISTANCE_TO_LEADER_IN_METERS:
|
||||
return stringMessages.windwardDistanceToLeaderInMeters();
|
||||
case RACE_AVERAGE_CROSS_TRACK_ERROR_IN_METERS:
|
||||
return stringMessages.averageCrossTrackErrorInMeters();
|
||||
case WINDWARD_DISTANCE_TO_OVERALL_LEADER:
|
||||
return stringMessages.windwardDistanceToOverallLeader();
|
||||
case HEAD_UP:
|
||||
@@ -53,6 +55,8 @@ public class DetailTypeFormatter {
|
||||
return stringMessages.currentLeg();
|
||||
case TIME_TRAVELED:
|
||||
return stringMessages.time();
|
||||
case AVERAGE_CROSS_TRACK_ERROR_IN_METERS:
|
||||
return stringMessages.averageCrossTrackErrorInMeters();
|
||||
}
|
||||
return null;
|
||||
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ package com.sap.sailing.gwt.ui.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
|
||||
|
||||
/**
|
||||
@@ -18,6 +18,6 @@ public interface RaceSelectionChangeListener {
|
||||
*
|
||||
* @param selectedRaces a non-<code>null</code> list which is empty if nothing is selected
|
||||
*/
|
||||
void onRaceSelectionChange(List<RaceIdentifier> selectedRaces);
|
||||
void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces);
|
||||
|
||||
}
|
||||
+12
-11
@@ -8,23 +8,24 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
|
||||
public class RaceSelectionModel implements RaceSelectionProvider {
|
||||
private final List<RaceIdentifier> selection;
|
||||
private final List<EventAndRaceIdentifier> selection;
|
||||
|
||||
private final List<RaceIdentifier> allRaces;
|
||||
private final List<EventAndRaceIdentifier> allRaces;
|
||||
|
||||
private final Set<RaceSelectionChangeListener> listeners;
|
||||
|
||||
public RaceSelectionModel() {
|
||||
this.selection = new ArrayList<RaceIdentifier>();
|
||||
this.allRaces = new ArrayList<RaceIdentifier>();
|
||||
this.selection = new ArrayList<EventAndRaceIdentifier>();
|
||||
this.allRaces = new ArrayList<EventAndRaceIdentifier>();
|
||||
listeners = new HashSet<RaceSelectionChangeListener>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RaceIdentifier> getSelectedRaces() {
|
||||
public List<EventAndRaceIdentifier> getSelectedRaces() {
|
||||
return Collections.unmodifiableList(selection);
|
||||
}
|
||||
|
||||
@@ -39,7 +40,7 @@ public class RaceSelectionModel implements RaceSelectionProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelection(List<RaceIdentifier> newSelection, RaceSelectionChangeListener... listenersNotToNotify) {
|
||||
public void setSelection(List<EventAndRaceIdentifier> newSelection, RaceSelectionChangeListener... listenersNotToNotify) {
|
||||
boolean notify = !selection.equals(newSelection);
|
||||
selection.clear();
|
||||
selection.addAll(newSelection);
|
||||
@@ -49,7 +50,7 @@ public class RaceSelectionModel implements RaceSelectionProvider {
|
||||
}
|
||||
|
||||
private void notifyListeners(RaceSelectionChangeListener[] listenersNotToNotify) {
|
||||
List<RaceIdentifier> selectedRaces = getSelectedRaces();
|
||||
List<EventAndRaceIdentifier> selectedRaces = getSelectedRaces();
|
||||
for (RaceSelectionChangeListener listener : listeners) {
|
||||
if (listenersNotToNotify == null || !Arrays.asList(listenersNotToNotify).contains(listener)) {
|
||||
listener.onRaceSelectionChange(selectedRaces);
|
||||
@@ -63,13 +64,13 @@ public class RaceSelectionModel implements RaceSelectionProvider {
|
||||
* <code>newAllRaces</code> are removed from the selection. If this happens, the selection listeners are notified.
|
||||
*/
|
||||
@Override
|
||||
public void setAllRaces(List<RaceIdentifier> newAllRaces, RaceSelectionChangeListener... listenersNotToNotify) {
|
||||
public void setAllRaces(List<EventAndRaceIdentifier> newAllRaces, RaceSelectionChangeListener... listenersNotToNotify) {
|
||||
allRaces.clear();
|
||||
for (RaceIdentifier r : newAllRaces) {
|
||||
for (EventAndRaceIdentifier r : newAllRaces) {
|
||||
allRaces.add(r);
|
||||
}
|
||||
boolean notify = false;
|
||||
for (Iterator<RaceIdentifier> i=selection.iterator(); i.hasNext(); ) {
|
||||
for (Iterator<EventAndRaceIdentifier> i=selection.iterator(); i.hasNext(); ) {
|
||||
RaceIdentifier selectedRace = i.next();
|
||||
if (!allRaces.contains(selectedRace)) {
|
||||
notify = true;
|
||||
@@ -82,7 +83,7 @@ public class RaceSelectionModel implements RaceSelectionProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RaceIdentifier> getAllRaces() {
|
||||
public List<EventAndRaceIdentifier> getAllRaces() {
|
||||
return Collections.unmodifiableList(allRaces);
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -2,24 +2,24 @@ package com.sap.sailing.gwt.ui.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
|
||||
public interface RaceSelectionProvider {
|
||||
/**
|
||||
* @return a non-<code>null</code> list which may be empty
|
||||
*/
|
||||
List<RaceIdentifier> getSelectedRaces();
|
||||
List<EventAndRaceIdentifier> getSelectedRaces();
|
||||
|
||||
void addRaceSelectionChangeListener(RaceSelectionChangeListener listener);
|
||||
|
||||
void removeRaceSelectionChangeListener(RaceSelectionChangeListener listener);
|
||||
|
||||
void setSelection(List<RaceIdentifier> newSelection, RaceSelectionChangeListener... listenersNotToNotify);
|
||||
void setSelection(List<EventAndRaceIdentifier> newSelection, RaceSelectionChangeListener... listenersNotToNotify);
|
||||
|
||||
/**
|
||||
* @return a non-<code>null</code> list which may be empty
|
||||
*/
|
||||
List<RaceIdentifier> getAllRaces();
|
||||
List<EventAndRaceIdentifier> getAllRaces();
|
||||
|
||||
void setAllRaces(List<RaceIdentifier> newAllRaces, RaceSelectionChangeListener... listenersNotToNotify);
|
||||
void setAllRaces(List<EventAndRaceIdentifier> newAllRaces, RaceSelectionChangeListener... listenersNotToNotify);
|
||||
}
|
||||
+23
-22
@@ -4,10 +4,11 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayStates;
|
||||
import com.sap.sailing.gwt.ui.shared.LegTimesInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.MarkPassingTimesDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent;
|
||||
|
||||
@@ -49,7 +50,7 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
|
||||
// in case the race is not tracked anymore we reset the timer
|
||||
reset();
|
||||
} else {
|
||||
if ((raceTimesInfo.startOfTracking != null || raceTimesInfo.startOfRace != null) && raceTimesInfo.timePointOfNewestEvent != null) {
|
||||
if ((raceTimesInfo.startOfTracking != null || raceTimesInfo.startOfRace != null) && raceTimesInfo.newestTrackingEvent != null) {
|
||||
// we set here the min and max of the time slider, the start and end of the race as well as the known
|
||||
// leg markers
|
||||
boolean liveModeToBeMadePossible = isLiveModeToBeMadePossible();
|
||||
@@ -79,14 +80,14 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
|
||||
long liveTimePointInMillis = System.currentTimeMillis() - livePlayDelayInMillis;
|
||||
RaceTimesInfoDTO lastRaceTimesInfo = raceTimesInfoProvider != null ? raceTimesInfoProvider.getRaceTimesInfo(selectedRace) : null;
|
||||
return lastRaceTimesInfo != null &&
|
||||
lastRaceTimesInfo.timePointOfNewestEvent != null &&
|
||||
liveTimePointInMillis < lastRaceTimesInfo.timePointOfNewestEvent.getTime() + eventTimeoutTolerance &&
|
||||
lastRaceTimesInfo.newestTrackingEvent != null &&
|
||||
liveTimePointInMillis < lastRaceTimesInfo.newestTrackingEvent.getTime() + eventTimeoutTolerance &&
|
||||
lastRaceTimesInfo.startOfTracking != null &&
|
||||
liveTimePointInMillis > lastRaceTimesInfo.startOfTracking.getTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
if (selectedRaces != null && !selectedRaces.isEmpty()) {
|
||||
selectedRace = selectedRaces.iterator().next();
|
||||
if (!raceTimesInfoProvider.containsRaceIdentifier(selectedRace)) {
|
||||
@@ -121,15 +122,15 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
|
||||
switch (timer.getPlayMode()) {
|
||||
case Live:
|
||||
if (newRaceTimesInfo.startOfRace != null) {
|
||||
long extensionTime = calculateRaceExtensionTime(newRaceTimesInfo.startOfRace, newRaceTimesInfo.timePointOfNewestEvent);
|
||||
long extensionTime = calculateRaceExtensionTime(newRaceTimesInfo.startOfRace, newRaceTimesInfo.newestTrackingEvent);
|
||||
|
||||
min = new Date(newRaceTimesInfo.startOfRace.getTime() - extensionTime);
|
||||
} else if (newRaceTimesInfo.startOfTracking != null) {
|
||||
min = newRaceTimesInfo.startOfTracking;
|
||||
}
|
||||
|
||||
if (newRaceTimesInfo.timePointOfNewestEvent != null) {
|
||||
max = newRaceTimesInfo.timePointOfNewestEvent;
|
||||
if (newRaceTimesInfo.newestTrackingEvent != null) {
|
||||
max = newRaceTimesInfo.newestTrackingEvent;
|
||||
}
|
||||
break;
|
||||
case Replay:
|
||||
@@ -143,8 +144,8 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
|
||||
|
||||
if (newRaceTimesInfo.endOfRace != null) {
|
||||
max = new Date(newRaceTimesInfo.endOfRace.getTime() + extensionTime);
|
||||
} else if (newRaceTimesInfo.timePointOfNewestEvent != null) {
|
||||
max = newRaceTimesInfo.timePointOfNewestEvent;
|
||||
} else if (newRaceTimesInfo.newestTrackingEvent != null) {
|
||||
max = newRaceTimesInfo.newestTrackingEvent;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -184,15 +185,15 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
|
||||
// initialize timer position
|
||||
switch (timer.getPlayMode()) {
|
||||
case Live:
|
||||
if (newRaceTimesInfo.timePointOfNewestEvent != null) {
|
||||
timer.setTime(newRaceTimesInfo.timePointOfNewestEvent.getTime());
|
||||
if (newRaceTimesInfo.newestTrackingEvent != null) {
|
||||
timer.setTime(newRaceTimesInfo.newestTrackingEvent.getTime());
|
||||
}
|
||||
timer.play();
|
||||
break;
|
||||
case Replay:
|
||||
// set time to end of race
|
||||
if (newRaceTimesInfo.getLastLegTimes() != null) {
|
||||
timer.setTime(newRaceTimesInfo.getLastLegTimes().firstPassingDate.getTime());
|
||||
if (newRaceTimesInfo.getLastMarkPassingTimes() != null) {
|
||||
timer.setTime(newRaceTimesInfo.getLastMarkPassingTimes().firstPassingDate.getTime());
|
||||
} else if (newRaceTimesInfo.endOfRace != null) {
|
||||
timer.setTime(newRaceTimesInfo.endOfRace.getTime());
|
||||
} else if (newRaceTimesInfo.startOfRace != null) {
|
||||
@@ -204,14 +205,15 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
|
||||
}
|
||||
|
||||
private void updateLegMarkers(RaceTimesInfoDTO newRaceTimesInfo) {
|
||||
List<LegTimesInfoDTO> legTimepoints = newRaceTimesInfo.getLegTimes();
|
||||
List<MarkPassingTimesDTO> markPassingTimes = newRaceTimesInfo.getMarkPassingTimes();
|
||||
boolean requiresMarkerUpdate = true;
|
||||
|
||||
// updating the sliderbar markers requires a lot of time, therefore we need to do this only if required
|
||||
if(lastRaceTimesInfo != null && lastRaceTimesInfo.legTimes.size() == newRaceTimesInfo.legTimes.size()) {
|
||||
if(lastRaceTimesInfo != null && lastRaceTimesInfo.markPassingTimes.size() == newRaceTimesInfo.markPassingTimes.size()) {
|
||||
requiresMarkerUpdate = false;
|
||||
for(int i = 0; i < newRaceTimesInfo.legTimes.size(); i++) {
|
||||
if(newRaceTimesInfo.legTimes.get(i).firstPassingDate.getTime() != lastRaceTimesInfo.legTimes.get(i).firstPassingDate.getTime()) {
|
||||
int numberOfLegs = newRaceTimesInfo.markPassingTimes.size();
|
||||
for(int i = 0; i < numberOfLegs; i++) {
|
||||
if(newRaceTimesInfo.markPassingTimes.get(i).firstPassingDate.getTime() != lastRaceTimesInfo.markPassingTimes.get(i).firstPassingDate.getTime()) {
|
||||
requiresMarkerUpdate = true;
|
||||
break;
|
||||
}
|
||||
@@ -219,8 +221,8 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
|
||||
}
|
||||
if (requiresMarkerUpdate && sliderBar.isMinMaxInitialized()) {
|
||||
sliderBar.clearMarkers();
|
||||
for (LegTimesInfoDTO legTimepointDTO : legTimepoints) {
|
||||
sliderBar.addMarker(legTimepointDTO.name, new Double(legTimepointDTO.firstPassingDate.getTime()));
|
||||
for (MarkPassingTimesDTO markPassingTimesDTO: markPassingTimes) {
|
||||
sliderBar.addMarker(markPassingTimesDTO.name, new Double(markPassingTimesDTO.firstPassingDate.getTime()));
|
||||
}
|
||||
sliderBar.redraw();
|
||||
}
|
||||
@@ -229,7 +231,6 @@ public class RaceTimePanel extends TimePanel<RaceTimePanelSettings> implements R
|
||||
|
||||
@Override
|
||||
public void raceTimesInfosReceived(Map<RaceIdentifier, RaceTimesInfoDTO> raceTimesInfos) {
|
||||
// raceTimesInfo can be null if the race is not tracked anymore
|
||||
updateTimeInfo(raceTimesInfos.get(selectedRace));
|
||||
updateTimeInfo(raceTimesInfos.get(selectedRace));
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -11,6 +11,7 @@ import java.util.Set;
|
||||
import com.google.gwt.core.client.Scheduler;
|
||||
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
|
||||
|
||||
@@ -29,7 +30,7 @@ public class RaceTimesInfoProvider {
|
||||
/**
|
||||
* The <code>raceIdentifiers</code> has to be <code>not-null</code>, but can be empty.
|
||||
*/
|
||||
public RaceTimesInfoProvider(SailingServiceAsync sailingService, ErrorReporter errorReporter, Collection<RaceIdentifier> raceIdentifiers, long requestInterval) {
|
||||
public RaceTimesInfoProvider(SailingServiceAsync sailingService, ErrorReporter errorReporter, Collection<EventAndRaceIdentifier> raceIdentifiers, long requestInterval) {
|
||||
this.sailingService = sailingService;
|
||||
this.errorReporter = errorReporter;
|
||||
this.raceIdentifiers = new HashSet<RaceIdentifier>(raceIdentifiers);
|
||||
|
||||
+7
-3
@@ -130,7 +130,7 @@ public interface SailingService extends RemoteService {
|
||||
String raceColumnName, MaxPointsReason maxPointsReason, Date date) throws NoWindException;
|
||||
|
||||
Pair<Integer, Integer> updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString,
|
||||
String raceName, Integer correctedScore, Date date) throws NoWindException;
|
||||
String columnName, Integer correctedScore, Date date) throws NoWindException;
|
||||
|
||||
void updateCompetitorDisplayNameInLeaderboard(String leaderboardName, String competitorIdAsString, String displayName);
|
||||
|
||||
@@ -175,7 +175,11 @@ public interface SailingService extends RemoteService {
|
||||
Date toDate, long stepSize, DetailType detailType)
|
||||
throws NoWindException;
|
||||
|
||||
void setRaceIsKnownToStartUpwind(RaceIdentifier raceIdentifier, boolean raceIsKnownToStartUpwind);
|
||||
void setRaceIsKnownToStartUpwind(EventAndRaceIdentifier raceIdentifier, boolean raceIsKnownToStartUpwind);
|
||||
|
||||
void setWindSourcesToExclude(RaceIdentifier raceIdentifier, Iterable<WindSource> windSourcesToExclude);
|
||||
void setWindSourcesToExclude(EventAndRaceIdentifier raceIdentifier, Iterable<WindSource> windSourcesToExclude);
|
||||
|
||||
List<String> getHostnamesOfReplica();
|
||||
|
||||
void startReplicatingFromMaster(String masterName, int servletPort, int jmsPort) throws Exception;
|
||||
}
|
||||
+6
-2
@@ -305,13 +305,17 @@ public interface SailingServiceAsync {
|
||||
void getCompetitorsRaceData(RaceIdentifier race, List<Pair<Date,CompetitorDTO>> competitorsToLoad, Date toDate, long stepSize,
|
||||
DetailType detailType, AsyncCallback<MultiCompetitorRaceDataDTO> callback);
|
||||
|
||||
void setRaceIsKnownToStartUpwind(RaceIdentifier raceIdentifier, boolean raceIsKnownToStartUpwind,
|
||||
void setRaceIsKnownToStartUpwind(EventAndRaceIdentifier raceIdentifier, boolean raceIsKnownToStartUpwind,
|
||||
AsyncCallback<Void> callback);
|
||||
|
||||
void setWindSourcesToExclude(RaceIdentifier raceIdentifier, Iterable<WindSource> windSourcesToExclude,
|
||||
void setWindSourcesToExclude(EventAndRaceIdentifier raceIdentifier, Iterable<WindSource> windSourcesToExclude,
|
||||
AsyncCallback<Void> callback);
|
||||
|
||||
void getRaceMapData(RaceIdentifier raceIdentifier, Date date, Map<CompetitorDTO, Date> from,
|
||||
Map<CompetitorDTO, Date> to, boolean extrapolate, AsyncCallback<RaceMapDataDTO> callback);
|
||||
|
||||
void getHostnamesOfReplica(AsyncCallback<List<String>> callback);
|
||||
|
||||
void startReplicatingFromMaster(String masterName, int servletPort, int jmsPort, AsyncCallback<Void> callback);
|
||||
|
||||
}
|
||||
+2
-1
@@ -10,6 +10,7 @@ import com.google.gwt.user.client.ui.FormPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
@@ -147,7 +148,7 @@ public class SmallWindHistoryPanel extends FormPanel implements TimeListener, Ra
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
if (!selectedRaces.isEmpty()) {
|
||||
race = selectedRaces.get(selectedRaces.size() - 1);
|
||||
updateWindDisplay();
|
||||
|
||||
+10
@@ -284,4 +284,14 @@ public interface StringMessages extends Messages {
|
||||
String degreesBoatToTheWind();
|
||||
String racesInLeaderboard();
|
||||
String leaderboardsInGroup();
|
||||
String replication();
|
||||
String errorFetchingReplicaData(String message);
|
||||
String averageCrossTrackErrorInMeters();
|
||||
String enterMaster();
|
||||
String errorStartingReplication(String hostname, String message);
|
||||
String helpLines();
|
||||
String startLine();
|
||||
String finishLine();
|
||||
String advantageLine();
|
||||
String courseMiddleLine();
|
||||
}
|
||||
+11
-1
@@ -278,4 +278,14 @@ speedPlaySpeedUp=Speed play speed up
|
||||
showHideComponent=Show/Hide {0}
|
||||
degreesBoatToTheWind=Angle to wind
|
||||
racesInLeaderboard=Races in leaderboard
|
||||
leaderboardsInGroup=Leaderboards in group
|
||||
leaderboardsInGroup=Leaderboards in group
|
||||
replication=Replication
|
||||
errorFetchingReplicaData=Error fetching replica data: {0}
|
||||
averageCrossTrackErrorInMeters=\u2205 XTE
|
||||
enterMaster=Hostname of Master Instance
|
||||
errorStartingReplication=Error starting replication from host {0}: {1}
|
||||
helpLines=Help lines
|
||||
startLine=Start line
|
||||
finishLine=Finish line
|
||||
advantageLine=Advantage line
|
||||
courseMiddleLine=Course middle line
|
||||
+11
-1
@@ -279,4 +279,14 @@ speedPlaySpeedUp=Abspielgeschwindigkeit erhöhen
|
||||
showHideComponent={0} anzeigen/verstecken
|
||||
degreesBoatToTheWind=Winkel zum Wind
|
||||
racesInLeaderboard=Rennen im Leaderboard
|
||||
leaderboardsInGroup=Leaderboards in der Gruppe
|
||||
leaderboardsInGroup=Leaderboards in der Gruppe
|
||||
replication=Replikation
|
||||
errorFetchingReplicaData=Fehler beim Beschaffen der Replikationsdaten: {0}
|
||||
averageCrossTrackErrorInMeters=\u2205 XTE
|
||||
enterMaster=Hostname der Master-Instanz
|
||||
errorStartingReplication=Fehler beim Starten der Replikation von Host {0}: {1}
|
||||
helpLines=Hilfslinien
|
||||
startLine=Startlinie
|
||||
finishLine=Ziellinie
|
||||
advantageLine=Führungslinie
|
||||
courseMiddleLine=Kursmittellinie
|
||||
+4
-3
@@ -35,6 +35,7 @@ import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
@@ -136,7 +137,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
}
|
||||
});
|
||||
|
||||
List<RaceIdentifier> selectedRaces = raceSelectionProvider.getSelectedRaces();
|
||||
List<EventAndRaceIdentifier> selectedRaces = raceSelectionProvider.getSelectedRaces();
|
||||
if(!selectedRaces.isEmpty()) {
|
||||
loadData(true);
|
||||
}
|
||||
@@ -307,7 +308,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
|
||||
private RaceIdentifier getSelectedRace() {
|
||||
RaceIdentifier result = null;
|
||||
List<RaceIdentifier> selectedRaces = raceSelectionProvider.getSelectedRaces();
|
||||
List<EventAndRaceIdentifier> selectedRaces = raceSelectionProvider.getSelectedRaces();
|
||||
if (selectedRaces != null && !selectedRaces.isEmpty()) {
|
||||
result = selectedRaces.iterator().next();
|
||||
}
|
||||
@@ -565,7 +566,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
setChartData(null);
|
||||
clearChart();
|
||||
timeLineNeedsUpdate = true;
|
||||
|
||||
+4
-4
@@ -20,7 +20,7 @@ import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Panel;
|
||||
import com.google.gwt.user.client.ui.RadioButton;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
@@ -48,7 +48,7 @@ public class CompareCompetitorsChartDialog extends DialogBox {
|
||||
private final CollapsablePanel collapsablePanel;
|
||||
|
||||
public CompareCompetitorsChartDialog(SailingServiceAsync sailingService,
|
||||
List<RaceIdentifier> races, final CompetitorSelectionProvider competitorSelectionProvider, Timer timer,
|
||||
List<EventAndRaceIdentifier> races, final CompetitorSelectionProvider competitorSelectionProvider, Timer timer,
|
||||
StringMessages stringConstants, ErrorReporter errorReporter) {
|
||||
super(false);
|
||||
raceSelectionProvider = new RaceSelectionModel();
|
||||
@@ -118,7 +118,7 @@ public class CompareCompetitorsChartDialog extends DialogBox {
|
||||
HorizontalPanel raceChooserPanel = new HorizontalPanel();
|
||||
raceChooserPanel.setSpacing(5);
|
||||
boolean first = true;
|
||||
for (final RaceIdentifier selectedRace : raceSelectionProvider.getAllRaces()) {
|
||||
for (final EventAndRaceIdentifier selectedRace : raceSelectionProvider.getAllRaces()) {
|
||||
RadioButton raceSelectionRadioButton = new RadioButton("chooseRace");
|
||||
raceSelectionRadioButton.setText(selectedRace.toString());
|
||||
raceChooserPanel.add(raceSelectionRadioButton);
|
||||
@@ -138,7 +138,7 @@ public class CompareCompetitorsChartDialog extends DialogBox {
|
||||
|
||||
}
|
||||
|
||||
private void selectRace(final RaceIdentifier selectedRace) {
|
||||
private void selectRace(final EventAndRaceIdentifier selectedRace) {
|
||||
if(selectedRace != null)
|
||||
collapsablePanel.getHeaderTextAccessor().setText(selectedRace.getRaceName());
|
||||
else
|
||||
|
||||
+3
-3
@@ -32,10 +32,10 @@ public class ExpandCollapseButtonCell extends AbstractCell<SafeHtml> {
|
||||
this.column = column;
|
||||
this.delegate = delegate;
|
||||
|
||||
String src = column.isExpanded() ? RESOURCES.magnifierSlashedIcon().getSafeUri().asString() : RESOURCES
|
||||
.magnifierIcon().getSafeUri().asString();
|
||||
String src = column.isExpanded() ? RESOURCES.minusIcon().getSafeUri().asString() : RESOURCES
|
||||
.plusIcon().getSafeUri().asString();
|
||||
this.html = new SafeHtmlBuilder().appendHtmlConstant(
|
||||
"<input class=\"valignMiddle magnifier\" type=\"image\" src=\"" + src + "\" />").toSafeHtml();
|
||||
"<input class=\"valignMiddle opencoloumn\" type=\"image\" src=\"" + src + "\" />").toSafeHtml();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
|
||||
contentScrollPanel.setWidget(tvViewPanel);
|
||||
} else {
|
||||
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService, new AsyncActionsExecutor(),
|
||||
LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, /* autoExpandFirstRace */ false),
|
||||
LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, /* autoExpandFirstRace */ false),
|
||||
/* preSelectedRace */ null, new CompetitorSelectionModel(/* hasMultiSelection */ true),
|
||||
new Timer(PlayModes.Replay, /* delayBetweenAutoAdvancesInMilliseconds */3000l),
|
||||
leaderboardName, leaderboardGroupName,
|
||||
|
||||
+68
-18
@@ -45,6 +45,7 @@ import com.google.gwt.view.client.SelectionChangeEvent;
|
||||
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
|
||||
import com.google.gwt.view.client.SelectionModel;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
import com.sap.sailing.gwt.ui.actions.GetLeaderboardByNameAction;
|
||||
@@ -61,6 +62,7 @@ import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayStates;
|
||||
import com.sap.sailing.gwt.ui.client.UserAgentChecker.UserAgentTypes;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LegDetailColumn.LegDetailField;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.NetPointsComparator.SortOrderCalculator;
|
||||
import com.sap.sailing.gwt.ui.shared.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardEntryDTO;
|
||||
@@ -198,6 +200,13 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
private PlayModes oldPlayMode;
|
||||
|
||||
private final AsyncActionsExecutor asyncActionsExecutor;
|
||||
|
||||
/**
|
||||
* See also {@link #getDefaultSortColumn()}. If no other column is explicitly selected for sorting and this attribute
|
||||
* holds a non-<code>null</code> string identifying a valid race by name that is represented in this leaderboard panel
|
||||
* then sort by it. Otherwise, default sorting will default to the overall rank column.
|
||||
*/
|
||||
private String raceNameForDefaultSorting;
|
||||
|
||||
private class SettingsClickHandler implements ClickHandler {
|
||||
private final StringMessages stringMessages;
|
||||
@@ -445,11 +454,11 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
if (entry.reasonForMaxPoints.equals("NONE")) {
|
||||
if (!entry.discarded) {
|
||||
html.appendHtmlConstant("<span style=\"font-weight: bold;\">");
|
||||
html.append(entry.totalPoints);
|
||||
html.appendHtmlConstant(entry.totalPoints == 0 ? "" : ""+entry.totalPoints);
|
||||
html.appendHtmlConstant("</span>");
|
||||
} else {
|
||||
html.appendHtmlConstant(" <span style=\"opacity: 0.5;\"><del>");
|
||||
html.append(entry.netPoints);
|
||||
html.appendHtmlConstant(entry.netPoints == 0 ? "" : ""+entry.netPoints);
|
||||
html.appendHtmlConstant("</del></span>");
|
||||
}
|
||||
} else {
|
||||
@@ -471,8 +480,13 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
if (race.isMedalRace()) {
|
||||
return getLeaderboard().getMedalRaceComparator(race.getRaceColumnName());
|
||||
} else {
|
||||
return new NetPointsComparator(isSortedAscendingForThisColumn(getLeaderboardPanel().getLeaderboardTable()),
|
||||
race.getRaceColumnName());
|
||||
SortOrderCalculator sortOrderCalculator = new SortOrderCalculator() {
|
||||
@Override
|
||||
public boolean isAscending() {
|
||||
return isSortedAscendingForThisColumn(getLeaderboardPanel().getLeaderboardTable());
|
||||
}
|
||||
};
|
||||
return new NetPointsComparator(sortOrderCalculator, race.getRaceColumnName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,7 +508,8 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
public static DetailType[] getAvailableRaceDetailColumnTypes() {
|
||||
return new DetailType[] { DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS,
|
||||
DetailType.RACE_DISTANCE_TRAVELED, DetailType.RACE_GAP_TO_LEADER_IN_SECONDS, DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS,
|
||||
DetailType.NUMBER_OF_MANEUVERS, DetailType.DISPLAY_LEGS, DetailType.CURRENT_LEG };
|
||||
DetailType.NUMBER_OF_MANEUVERS, DetailType.DISPLAY_LEGS, DetailType.CURRENT_LEG,
|
||||
DetailType.RACE_AVERAGE_CROSS_TRACK_ERROR_IN_METERS };
|
||||
}
|
||||
|
||||
private class TextRaceColumn extends RaceColumn<String> implements RaceNameProvider {
|
||||
@@ -512,7 +527,8 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
|
||||
@Override
|
||||
public String getValue(LeaderboardRowDTO object) {
|
||||
return "" + object.fieldsByRaceName.get(getRaceColumnName()).totalPoints;
|
||||
final int totalPoints = object.fieldsByRaceName.get(getRaceColumnName()).totalPoints;
|
||||
return "" + (totalPoints == 0 ? "" : totalPoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -562,10 +578,16 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
new FormattedDoubleLegDetailColumn(stringMessages.windwardDistanceToOverallLeader(), "["+stringMessages
|
||||
.distanceInMetersUnit()+"]", new RaceDistanceToLeaderInMeters(), 0, getLeaderboardPanel()
|
||||
.getLeaderboardTable(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
|
||||
result.put(
|
||||
DetailType.RACE_AVERAGE_CROSS_TRACK_ERROR_IN_METERS,
|
||||
new FormattedDoubleLegDetailColumn(stringMessages.averageCrossTrackErrorInMeters(), "["+stringMessages
|
||||
.metersUnit()+"]", new RaceAverageCrossTrackErrorInMeters(), 0, getLeaderboardPanel()
|
||||
.getLeaderboardTable(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
|
||||
result.put(DetailType.NUMBER_OF_MANEUVERS, getManeuverCountRaceColumn());
|
||||
result.put(DetailType.CURRENT_LEG, new FormattedDoubleLegDetailColumn(stringMessages.currentLeg(), "",
|
||||
new CurrentLeg(), 0, getLeaderboardPanel().getLeaderboardTable(), LEG_COLUMN_HEADER_STYLE,
|
||||
LEG_COLUMN_STYLE));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -646,6 +668,23 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the average cross-track error for the race
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*/
|
||||
private class RaceAverageCrossTrackErrorInMeters implements LegDetailField<Double> {
|
||||
@Override
|
||||
public Double get(LeaderboardRowDTO row) {
|
||||
Double result = null;
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceColumnName());
|
||||
if (fieldsForRace != null) {
|
||||
result = fieldsForRace.averageCrossTrackErrorInMeters;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates the distance traveled over all legs of a race
|
||||
*
|
||||
@@ -759,7 +798,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
@Override
|
||||
public String getValue(LeaderboardRowDTO object) {
|
||||
int totalPoints = getLeaderboard().getTotalPoints(object);
|
||||
return "" + totalPoints;
|
||||
return "" + (totalPoints==0 ? "" : totalPoints);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -827,7 +866,8 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
|
||||
@Override
|
||||
public String getValue(LeaderboardRowDTO object) {
|
||||
return "" + getLeaderboard().getRank(object.competitor);
|
||||
final int rank = getLeaderboard().getRank(object.competitor);
|
||||
return "" + (rank == 0 ? "" : rank);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -835,7 +875,9 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
return new Comparator<LeaderboardRowDTO>() {
|
||||
@Override
|
||||
public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) {
|
||||
return getLeaderboard().getRank(o1.competitor) - getLeaderboard().getRank(o2.competitor);
|
||||
final int rank1 = getLeaderboard().getRank(o1.competitor);
|
||||
final int rank2 = getLeaderboard().getRank(o2.competitor);
|
||||
return rank1 == 0 ? rank2 == 0 ? 0 : 1 : rank2 == 0 ? -1 : rank1 - rank2;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -987,10 +1029,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
}
|
||||
contentPanel.add(getLeaderboardTable());
|
||||
setWidget(contentPanel);
|
||||
if (settings.getNameOfRaceToSort() != null) {
|
||||
RaceColumn<?> column = getRaceColumnByRaceName(settings.getNameOfRaceToSort());
|
||||
sort(column, settings.isSortAscending());
|
||||
}
|
||||
raceNameForDefaultSorting = settings.getNameOfRaceToSort();
|
||||
}
|
||||
|
||||
private RaceInLeaderboardDTO getRaceByName(String raceName) {
|
||||
@@ -1192,7 +1231,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
if (comparator != null) {
|
||||
Collections.sort(getData().getList(), comparator);
|
||||
} else {
|
||||
RankColumn columnToSortFor = getRankColumn();
|
||||
SortableColumn<LeaderboardRowDTO, ?> columnToSortFor = getDefaultSortColumn();
|
||||
// if no sorting was selected, sort by ascending rank and mark
|
||||
// table header so
|
||||
sort(columnToSortFor, true);
|
||||
@@ -1208,6 +1247,17 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
}
|
||||
}
|
||||
|
||||
private SortableColumn<LeaderboardRowDTO, ?> getDefaultSortColumn() {
|
||||
SortableColumn<LeaderboardRowDTO, ?> defaultSortColumn = null;
|
||||
if (raceNameForDefaultSorting != null) {
|
||||
defaultSortColumn = getRaceColumnByRaceName(raceNameForDefaultSorting);
|
||||
}
|
||||
if (defaultSortColumn == null) {
|
||||
defaultSortColumn = getRankColumn();
|
||||
}
|
||||
return defaultSortColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the leaderboard contents in ascending order according to <code>columnToSortFor</code>'s comparator and
|
||||
* marks the table's column sort list so.
|
||||
@@ -1514,7 +1564,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
|
||||
private void ensureRankColumn() {
|
||||
if (getLeaderboardTable().getColumnCount() == RANK_COLUMN_INDEX) {
|
||||
addColumn(getRankColumn());
|
||||
addColumn(getDefaultSortColumn());
|
||||
} else {
|
||||
if (!(getLeaderboardTable().getColumn(RANK_COLUMN_INDEX) instanceof RankColumn)) {
|
||||
throw new RuntimeException("The first column must always be the rank column but it was of type "
|
||||
@@ -1634,14 +1684,14 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
}
|
||||
|
||||
private void compareCompetitors() {
|
||||
List<RaceIdentifier> races = getTrackedRacesIdentifiers();
|
||||
List<EventAndRaceIdentifier> races = getTrackedRacesIdentifiers();
|
||||
CompareCompetitorsChartDialog chartDialog = new CompareCompetitorsChartDialog(sailingService, races,
|
||||
competitorSelectionProvider, timer, stringMessages, errorReporter);
|
||||
chartDialog.show();
|
||||
}
|
||||
|
||||
private List<RaceIdentifier> getTrackedRacesIdentifiers() {
|
||||
List<RaceIdentifier> result = new ArrayList<RaceIdentifier>();
|
||||
private List<EventAndRaceIdentifier> getTrackedRacesIdentifiers() {
|
||||
List<EventAndRaceIdentifier> result = new ArrayList<EventAndRaceIdentifier>();
|
||||
for (RaceInLeaderboardDTO raceColumn : getLeaderboard().getRaceList()) {
|
||||
if (raceColumn.getRaceIdentifier() != null) {
|
||||
result.add(raceColumn.getRaceIdentifier());
|
||||
|
||||
+6
@@ -20,6 +20,12 @@ interface LeaderboardResources extends ClientBundle {
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/magnifier.png")
|
||||
ImageResource magnifierIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/plusicon.png")
|
||||
ImageResource plusIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/minusicon.png")
|
||||
ImageResource minusIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/magnifier_slashed.png")
|
||||
ImageResource magnifierSlashedIcon();
|
||||
|
||||
|
||||
+6
-4
@@ -61,8 +61,9 @@ public class LeaderboardSettingsFactory {
|
||||
/* delay to live */ null, /* name of race to sort */ nameOfRaceToSort, /* ascending */ true);
|
||||
break;
|
||||
case Replay:
|
||||
settings = createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, /* autoExpandFirstRace */ nameOfRaceColumnToShow != null);
|
||||
break;
|
||||
settings = createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, nameOfRaceToSort, /* autoExpandFirstRace */
|
||||
nameOfRaceColumnToShow != null);
|
||||
break;
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
@@ -76,9 +77,10 @@ public class LeaderboardSettingsFactory {
|
||||
* @param namesOfRacesToShow
|
||||
* alternatively, races to show can also be specified by their race names; if not <code>null</code>,
|
||||
* <code>namesOfRaceColumnsToShow</code> must be <code>null
|
||||
* @param nameOfRaceToSort TODO
|
||||
*/
|
||||
public LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
|
||||
List<String> namesOfRacesToShow, boolean autoExpandFirstRace) {
|
||||
List<String> namesOfRacesToShow, String nameOfRaceToSort, boolean autoExpandFirstRace) {
|
||||
if (namesOfRaceColumnsToShow != null && namesOfRacesToShow != null) {
|
||||
throw new IllegalArgumentException("Can specify race columns either by column or by race name, not both");
|
||||
}
|
||||
@@ -95,6 +97,6 @@ public class LeaderboardSettingsFactory {
|
||||
return new LeaderboardSettings(maneuverDetails, legDetails, raceDetails, namesOfRaceColumnsToShow,
|
||||
namesOfRacesToShow,
|
||||
autoExpandFirstRace, /* refresh interval */ null,
|
||||
/* delay to live */ null, /* sort by column */ null, /* ascending */ true);
|
||||
/* delay to live */ null, /* sort by column */ nameOfRaceToSort, /* ascending */ true);
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -64,6 +64,13 @@ public class LegColumn extends ExpandableSortableColumn<String> {
|
||||
}
|
||||
}
|
||||
|
||||
private class AverageCrossTrackErrorInMeters extends AbstractLegDetailField<Double> {
|
||||
@Override
|
||||
protected Double getFromNonNullEntry(LegEntryDTO entry) {
|
||||
return entry.averageCrossTrackErrorInMeters;
|
||||
}
|
||||
}
|
||||
|
||||
private class CurrentSpeedOverGroundInKnots extends AbstractLegDetailField<Double> {
|
||||
@Override
|
||||
protected Double getFromNonNullEntry(LegEntryDTO entry) {
|
||||
@@ -216,7 +223,7 @@ public class LegColumn extends ExpandableSortableColumn<String> {
|
||||
DetailType.VELOCITY_MADE_GOOD_IN_KNOTS, DetailType.GAP_TO_LEADER_IN_SECONDS,
|
||||
DetailType.WINDWARD_DISTANCE_TO_GO_IN_METERS,
|
||||
DetailType.NUMBER_OF_MANEUVERS,
|
||||
DetailType.TIME_TRAVELED};
|
||||
DetailType.TIME_TRAVELED, DetailType.AVERAGE_CROSS_TRACK_ERROR_IN_METERS };
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -257,6 +264,9 @@ public class LegColumn extends ExpandableSortableColumn<String> {
|
||||
result.put(DetailType.TIME_TRAVELED, new FormattedDoubleLegDetailColumn(stringConstants.time(),
|
||||
"[" + stringConstants.secondsUnit() + "]", new TimeTraveledInSeconds(), 0,
|
||||
getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle));
|
||||
result.put(DetailType.AVERAGE_CROSS_TRACK_ERROR_IN_METERS, new FormattedDoubleLegDetailColumn(stringConstants.averageCrossTrackErrorInMeters(),
|
||||
"[" + stringConstants.metersUnit() + "]", new AverageCrossTrackErrorInMeters(), 0,
|
||||
getLeaderboardPanel().getLeaderboardTable(), detailHeaderStyle, detailColumnStyle));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+12
-3
@@ -6,17 +6,26 @@ import com.sap.sailing.gwt.ui.shared.LeaderboardEntryDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardRowDTO;
|
||||
|
||||
public class NetPointsComparator implements Comparator<LeaderboardRowDTO> {
|
||||
private final boolean ascending;
|
||||
private final SortOrderCalculator sortOrderCalculator;
|
||||
private final String raceName;
|
||||
|
||||
public NetPointsComparator(boolean ascending, String raceName) {
|
||||
public interface SortOrderCalculator {
|
||||
boolean isAscending();
|
||||
}
|
||||
|
||||
public NetPointsComparator(SortOrderCalculator sortOrderCalculator, String raceName) {
|
||||
super();
|
||||
this.ascending = ascending;
|
||||
this.sortOrderCalculator = sortOrderCalculator;
|
||||
this.raceName = raceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* sorts a meaningless <code>0</code> value to the bottom always, regardless whether ascending/descending sorting is
|
||||
* requested
|
||||
*/
|
||||
@Override
|
||||
public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) {
|
||||
boolean ascending = sortOrderCalculator.isAscending();
|
||||
LeaderboardEntryDTO o1Entry = o1.fieldsByRaceName.get(raceName);
|
||||
LeaderboardEntryDTO o2Entry = o2.fieldsByRaceName.get(raceName);
|
||||
return (o1Entry == null || o1Entry.netPoints == 0) ? (o2Entry == null || o2Entry.netPoints == 0) ? 0
|
||||
|
||||
+10
-9
@@ -11,6 +11,7 @@ import com.google.gwt.user.client.ui.DockLayoutPanel;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
@@ -51,7 +52,7 @@ public class TVViewPanel extends SimplePanel implements RaceTimesInfoProviderLis
|
||||
private Label raceBoardHeader;
|
||||
private RaceBoardPanel raceBoardPanel;
|
||||
private FlowPanel timePanel;
|
||||
private RaceIdentifier currentRace;
|
||||
private EventAndRaceIdentifier currentRace;
|
||||
private boolean raceBoardIsWidget;
|
||||
|
||||
public TVViewPanel(SailingServiceAsync sailingService, StringMessages stringMessages, ErrorReporter errorReporter,
|
||||
@@ -72,7 +73,7 @@ public class TVViewPanel extends SimplePanel implements RaceTimesInfoProviderLis
|
||||
timePanel = null;
|
||||
|
||||
timer.play();
|
||||
raceTimesInfoProvider = new RaceTimesInfoProvider(sailingService, errorReporter, new ArrayList<RaceIdentifier>(), 1000l);
|
||||
raceTimesInfoProvider = new RaceTimesInfoProvider(sailingService, errorReporter, new ArrayList<EventAndRaceIdentifier>(), 1000l);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(this);
|
||||
|
||||
leaderboardPanel = createLeaderboardPanel(leaderboardName);
|
||||
@@ -81,7 +82,7 @@ public class TVViewPanel extends SimplePanel implements RaceTimesInfoProviderLis
|
||||
}
|
||||
|
||||
private LeaderboardPanel createLeaderboardPanel(String leaderboardName) {
|
||||
LeaderboardSettings settings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, /* autoExpandFirstRace */ false);
|
||||
LeaderboardSettings settings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, /* autoExpandFirstRace */ false);
|
||||
CompetitorSelectionModel selectionModel = new CompetitorSelectionModel(/* hasMultiSelection */ true);
|
||||
Timer timer = new Timer(PlayModes.Live, /* delayBetweenAutoAdvancesInMilliseconds */3000l);
|
||||
timer.play();
|
||||
@@ -112,9 +113,9 @@ public class TVViewPanel extends SimplePanel implements RaceTimesInfoProviderLis
|
||||
}
|
||||
}
|
||||
|
||||
private RaceBoardPanel createRaceBoardPanel(String leaderboardName, RaceIdentifier raceToShow) {
|
||||
private RaceBoardPanel createRaceBoardPanel(String leaderboardName, EventAndRaceIdentifier raceToShow) {
|
||||
RaceSelectionModel raceSelectionModel = new RaceSelectionModel();
|
||||
List<RaceIdentifier> singletonList = Collections.singletonList(raceToShow);
|
||||
List<EventAndRaceIdentifier> singletonList = Collections.singletonList(raceToShow);
|
||||
raceSelectionModel.setSelection(singletonList);
|
||||
RaceBoardPanel raceBoardPanel = new RaceBoardPanel(sailingService, userDTO, timer, raceSelectionModel, leaderboardName, null,
|
||||
errorReporter, stringMessages, userAgentType, RaceBoardViewModes.ONESCREEN, raceTimesInfoProvider);
|
||||
@@ -130,7 +131,7 @@ public class TVViewPanel extends SimplePanel implements RaceTimesInfoProviderLis
|
||||
namesOfRaceColumnsToShow.add(race.getRaceColumnName());
|
||||
}
|
||||
LeaderboardSettings settings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
namesOfRaceColumnsToShow, null, false);
|
||||
namesOfRaceColumnsToShow, null, null, false);
|
||||
leaderboardPanel.updateSettings(settings);
|
||||
}
|
||||
|
||||
@@ -216,11 +217,11 @@ public class TVViewPanel extends SimplePanel implements RaceTimesInfoProviderLis
|
||||
}
|
||||
}
|
||||
|
||||
private RaceIdentifier getFirstStartedAndUnfinishedRace() {
|
||||
RaceIdentifier firstStartedAndUnfinishedRace = null;
|
||||
private EventAndRaceIdentifier getFirstStartedAndUnfinishedRace() {
|
||||
EventAndRaceIdentifier firstStartedAndUnfinishedRace = null;
|
||||
Map<RaceIdentifier, RaceTimesInfoDTO> raceTimesInfos = raceTimesInfoProvider.getRaceTimesInfos();
|
||||
for (RaceInLeaderboardDTO race : leaderboard.getRaceList()) {
|
||||
RaceIdentifier raceIdentifier = race.getRaceIdentifier();
|
||||
EventAndRaceIdentifier raceIdentifier = race.getRaceIdentifier();
|
||||
RaceTimesInfoDTO raceTimes = raceTimesInfos.get(raceIdentifier);
|
||||
if (raceIdentifier != null && raceTimes != null && raceTimes.startOfTracking != null
|
||||
&& raceTimes.endOfRace == null) {
|
||||
|
||||
+1
-1
@@ -259,7 +259,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
public EditableLeaderboardPanel(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, String leaderboardName, String leaderboardGroupName,
|
||||
ErrorReporter errorReporter, StringMessages stringConstants, UserAgentTypes userAgentType) {
|
||||
super(sailingService, asyncActionsExecutor, LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
/* racesToShow */ null, /* namesOfRacesToShow */ null, /* autoExpandFirstRace */false),
|
||||
/* racesToShow */ null, /* namesOfRacesToShow */ null, null, /* autoExpandFirstRace */false),
|
||||
new CompetitorSelectionModel(/* hasMultiSelection */true),
|
||||
leaderboardName, leaderboardGroupName, errorReporter, stringConstants, userAgentType);
|
||||
}
|
||||
|
||||
+10
-11
@@ -13,7 +13,7 @@ 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.domain.common.DefaultLeaderboardName;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.client.LogoAndTitlePanel;
|
||||
@@ -49,9 +49,8 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
String leaderboardGroupNameParamValue = Window.Location.getParameter("leaderboardGroupName");
|
||||
String viewModeParamValue = Window.Location.getParameter("viewMode");
|
||||
// set the view mode for the race board
|
||||
if(viewModeParamValue != null && !viewModeParamValue.isEmpty()) {
|
||||
if (viewModeParamValue != null && !viewModeParamValue.isEmpty()) {
|
||||
try {
|
||||
|
||||
viewMode = RaceBoardViewModes.valueOf(viewModeParamValue);
|
||||
} catch (IllegalArgumentException e) {
|
||||
viewMode = RaceBoardViewModes.ONESCREEN;
|
||||
@@ -59,12 +58,12 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
} else {
|
||||
viewMode = RaceBoardViewModes.ONESCREEN;
|
||||
}
|
||||
if(leaderboardNameParamValue == null || leaderboardNameParamValue.isEmpty()) {
|
||||
if (leaderboardNameParamValue == null || leaderboardNameParamValue.isEmpty()) {
|
||||
leaderboardName = DefaultLeaderboardName.DEFAULT_LEADERBOARD_NAME;
|
||||
} else {
|
||||
leaderboardName = leaderboardNameParamValue;
|
||||
}
|
||||
if(leaderboardGroupNameParamValue != null && !leaderboardGroupNameParamValue.isEmpty()) {
|
||||
if (leaderboardGroupNameParamValue != null && !leaderboardGroupNameParamValue.isEmpty()) {
|
||||
leaderboardGroupName = leaderboardGroupNameParamValue;
|
||||
}
|
||||
if (eventName == null || eventName.isEmpty() || raceName == null || raceName.isEmpty()) {
|
||||
@@ -101,7 +100,7 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
}
|
||||
sailingService.listEvents(listEventsCallback);
|
||||
sailingService.getLeaderboardNames(getLeaderboardNamesCallback);
|
||||
if(leaderboardGroupName != null) {
|
||||
if (leaderboardGroupName != null) {
|
||||
sailingService.getLeaderboardGroupByName(leaderboardGroupNameParamValue, getLeaderboardGroupByNameCallback);
|
||||
}
|
||||
userManagementService.getUser(getUserCallback);
|
||||
@@ -126,13 +125,13 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
}
|
||||
}
|
||||
selectedRace = findRace(eventName, raceName, events);
|
||||
if(selectedRace == null) {
|
||||
if (selectedRace == null) {
|
||||
createErrorPage("Could not obtain a race with name " + raceName + " for an event with name " + eventName);
|
||||
return;
|
||||
}
|
||||
|
||||
RaceSelectionModel raceSelectionModel = new RaceSelectionModel();
|
||||
List<RaceIdentifier> singletonList = Collections.singletonList(selectedRace.getRaceIdentifier());
|
||||
List<EventAndRaceIdentifier> singletonList = Collections.singletonList(selectedRace.getRaceIdentifier());
|
||||
raceSelectionModel.setSelection(singletonList);
|
||||
Timer timer = new Timer(PlayModes.Replay, 1000l);
|
||||
RaceBoardPanel raceBoardPanel = new RaceBoardPanel(sailingService, user, timer, raceSelectionModel, leaderboardName, leaderboardGroupName,
|
||||
@@ -151,10 +150,10 @@ public class RaceBoardEntryPoint extends AbstractEntryPoint {
|
||||
|
||||
private RaceDTO findRace(String eventName, String raceName, List<EventDTO> events) {
|
||||
for (EventDTO eventDTO : events) {
|
||||
if(eventDTO.name.equals(eventName)) {
|
||||
if (eventDTO.name.equals(eventName)) {
|
||||
for (RegattaDTO regattaDTO : eventDTO.regattas) {
|
||||
for(RaceDTO raceDTO: regattaDTO.races) {
|
||||
if(raceDTO.name.equals(raceName)) {
|
||||
for (RaceDTO raceDTO: regattaDTO.races) {
|
||||
if (raceDTO.name.equals(raceName)) {
|
||||
return raceDTO;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -20,6 +20,7 @@ import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.MenuBar;
|
||||
import com.google.gwt.user.client.ui.ToggleButton;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
@@ -87,7 +88,7 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
private final RaceSelectionProvider raceSelectionProvider;
|
||||
private final UserAgentTypes userAgentType;
|
||||
private final CompetitorSelectionModel competitorSelectionModel;
|
||||
private final RaceIdentifier selectedRaceIdentifier;
|
||||
private final EventAndRaceIdentifier selectedRaceIdentifier;
|
||||
|
||||
private LeaderboardPanel leaderboardPanel;
|
||||
private WindChart windChart;
|
||||
@@ -114,6 +115,8 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
private CollapsableComponentViewer<MultiChartSettings> competitorChartViewer = null;
|
||||
|
||||
private final AsyncActionsExecutor asyncActionsExecutor;
|
||||
|
||||
private final RaceTimesInfoProvider raceTimesInfoProvider;
|
||||
|
||||
public RaceBoardPanel(SailingServiceAsync sailingService, UserDTO theUser, Timer timer,
|
||||
RaceSelectionProvider theRaceSelectionProvider, String leaderboardName, String leaderboardGroupName,
|
||||
@@ -122,6 +125,7 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
this.sailingService = sailingService;
|
||||
this.stringMessages = stringMessages;
|
||||
this.raceSelectionProvider = theRaceSelectionProvider;
|
||||
this.raceTimesInfoProvider = raceTimesInfoProvider;
|
||||
this.scrollOffset = 0;
|
||||
raceSelectionProvider.addRaceSelectionChangeListener(this);
|
||||
racesByIdentifier = new HashMap<RaceIdentifier, RaceDTO>();
|
||||
@@ -167,6 +171,7 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
// create the default leaderboard and select the right race
|
||||
leaderboardPanel = createLeaderboardPanel(leaderboardName, leaderboardGroupName);
|
||||
RaceMap raceMap = new RaceMap(sailingService, asyncActionsExecutor, errorReporter, timer, competitorSelectionModel, stringMessages);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap);
|
||||
raceMap.onRaceSelectionChange(Collections.singletonList(selectedRaceIdentifier));
|
||||
|
||||
List<Component<?>> components = new ArrayList<Component<?>>();
|
||||
@@ -271,6 +276,7 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
CollapsableComponentViewer<RaceMapSettings> raceMapViewer = new CollapsableComponentViewer<RaceMapSettings>(
|
||||
raceMap, "auto", "500px", stringMessages);
|
||||
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap);
|
||||
raceMap.onRaceSelectionChange(Collections.singletonList(selectedRaceIdentifier));
|
||||
componentViewers.add(raceMapViewer);
|
||||
}
|
||||
@@ -482,7 +488,7 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
}
|
||||
}
|
||||
|
||||
+150
-187
@@ -28,6 +28,7 @@ import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.RunnableFuture;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.jms.JMSException;
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
@@ -81,8 +82,8 @@ import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard.Entry;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.RaceInLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.impl.ResultDiscardingRuleImpl;
|
||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.MongoWindStoreFactory;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingConfiguration;
|
||||
@@ -95,6 +96,7 @@ import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.RacesHandle;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
@@ -117,9 +119,10 @@ import com.sap.sailing.gwt.ui.shared.LeaderboardEntryDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardRowDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LegEntryDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LegTimesInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LegInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.ManeuverDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.MarkDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.MarkPassingTimesDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.MultiCompetitorRaceDataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.PlacemarkDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.PlacemarkOrderDTO;
|
||||
@@ -140,6 +143,33 @@ import com.sap.sailing.gwt.ui.shared.WindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindTrackInfoDTO;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.operationaltransformation.AddColumnToLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.ConnectTrackedRaceToLeaderboardColumn;
|
||||
import com.sap.sailing.server.operationaltransformation.CreateLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.CreateLeaderboardGroup;
|
||||
import com.sap.sailing.server.operationaltransformation.DisconnectLeaderboardColumnFromTrackedRace;
|
||||
import com.sap.sailing.server.operationaltransformation.MoveLeaderboardColumnDown;
|
||||
import com.sap.sailing.server.operationaltransformation.MoveLeaderboardColumnUp;
|
||||
import com.sap.sailing.server.operationaltransformation.RemoveAndUntrackRace;
|
||||
import com.sap.sailing.server.operationaltransformation.RemoveLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.RemoveLeaderboardColumn;
|
||||
import com.sap.sailing.server.operationaltransformation.RemoveLeaderboardGroup;
|
||||
import com.sap.sailing.server.operationaltransformation.RenameLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.RenameLeaderboardColumn;
|
||||
import com.sap.sailing.server.operationaltransformation.RenameLeaderboardGroup;
|
||||
import com.sap.sailing.server.operationaltransformation.SetRaceIsKnownToStartUpwind;
|
||||
import com.sap.sailing.server.operationaltransformation.SetWindSourcesToExclude;
|
||||
import com.sap.sailing.server.operationaltransformation.StopTrackingEvent;
|
||||
import com.sap.sailing.server.operationaltransformation.StopTrackingRace;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateCompetitorDisplayNameInLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateIsMedalRace;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboard;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardCarryValue;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardGroup;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardMaxPointsReason;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardScoreCorrection;
|
||||
import com.sap.sailing.server.replication.ReplicationFactory;
|
||||
import com.sap.sailing.server.replication.ReplicationService;
|
||||
|
||||
/**
|
||||
* The server side implementation of the RPC service.
|
||||
@@ -149,10 +179,17 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
|
||||
private static final long serialVersionUID = 9031688830194537489L;
|
||||
|
||||
private static final long TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS = 60000;
|
||||
/**
|
||||
* Wait five minutes for race data; sometimes, a tracking provider's server may be under heavy load and
|
||||
* may serve races one after another. If many races are requested concurrently, this can lead to a queue
|
||||
* of several minutes length.
|
||||
*/
|
||||
private static final long TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS = 300000;
|
||||
|
||||
private final ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker;
|
||||
|
||||
private final ServiceTracker<ReplicationService, ReplicationService> replicationServiceTracker;
|
||||
|
||||
private final MongoObjectFactory mongoObjectFactory;
|
||||
|
||||
private final SwissTimingAdapterPersistence swissTimingAdapterPersistence;
|
||||
@@ -172,8 +209,9 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
public SailingServiceImpl() {
|
||||
BundleContext context = Activator.getDefault();
|
||||
racingEventServiceTracker = createAndOpenRacingEventServiceTracker(context);
|
||||
mongoObjectFactory = MongoObjectFactory.INSTANCE;
|
||||
domainObjectFactory = DomainObjectFactory.INSTANCE;
|
||||
replicationServiceTracker = createAndOpenReplicationServiceTracker(context);
|
||||
mongoObjectFactory = MongoFactory.INSTANCE.getDefaultMongoObjectFactory();
|
||||
domainObjectFactory = MongoFactory.INSTANCE.getDefaultDomainObjectFactory();
|
||||
swissTimingAdapterPersistence = SwissTimingAdapterPersistence.INSTANCE;
|
||||
tractracDomainObjectFactory = com.sap.sailing.domain.tractracadapter.persistence.DomainObjectFactory.INSTANCE;
|
||||
tractracMongoObjectFactory = com.sap.sailing.domain.tractracadapter.persistence.MongoObjectFactory.INSTANCE;
|
||||
@@ -190,6 +228,14 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
return result;
|
||||
}
|
||||
|
||||
protected ServiceTracker<ReplicationService, ReplicationService> createAndOpenReplicationServiceTracker(
|
||||
BundleContext context) {
|
||||
ServiceTracker<ReplicationService, ReplicationService> result = new ServiceTracker<ReplicationService, ReplicationService>(
|
||||
context, ReplicationService.class.getName(), null);
|
||||
result.open();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderboardDTO getLeaderboardByName(String leaderboardName, Date date,
|
||||
final Collection<String> namesOfRacesForWhichToLoadLegDetails)
|
||||
@@ -204,7 +250,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
result.name = leaderboard.getName();
|
||||
result.competitorDisplayNames = new HashMap<CompetitorDTO, String>();
|
||||
for (RaceInLeaderboard raceColumn : leaderboard.getRaceColumns()) {
|
||||
RaceIdentifier raceIdentifier = null;
|
||||
EventAndRaceIdentifier raceIdentifier = null;
|
||||
if (raceColumn.getTrackedRace() != null) {
|
||||
TrackedRace trackedRace = raceColumn.getTrackedRace();
|
||||
raceIdentifier = new EventNameAndRaceName(trackedRace.getTrackedEvent().getEvent().getName(), trackedRace.getRace().getName());
|
||||
@@ -300,6 +346,8 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
}
|
||||
final Distance windwardDistanceToOverallLeader = trackedRace == null ? null : trackedRace.getWindwardDistanceToOverallLeader(competitor, timePoint);
|
||||
entryDTO.windwardDistanceToOverallLeaderInMeters = windwardDistanceToOverallLeader == null ? null : windwardDistanceToOverallLeader.getMeters();
|
||||
final Distance averageCrossTrackError = trackedRace == null ? null : trackedRace.getAverageCrossTrackError(competitor, timePoint);
|
||||
entryDTO.averageCrossTrackErrorInMeters = averageCrossTrackError == null ? null : averageCrossTrackError.getMeters();
|
||||
return entryDTO;
|
||||
}
|
||||
|
||||
@@ -310,8 +358,9 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
} else {
|
||||
result = new LegEntryDTO();
|
||||
final Speed averageSpeedOverGround = trackedLeg.getAverageSpeedOverGround(timePoint);
|
||||
result.averageSpeedOverGroundInKnots = averageSpeedOverGround == null ? null : averageSpeedOverGround
|
||||
.getKnots();
|
||||
result.averageSpeedOverGroundInKnots = averageSpeedOverGround == null ? null : averageSpeedOverGround.getKnots();
|
||||
final Distance averageCrossTrackError = trackedLeg.getAverageCrossTrackError(timePoint);
|
||||
result.averageCrossTrackErrorInMeters = averageCrossTrackError == null ? null : averageCrossTrackError.getMeters();
|
||||
Double speedOverGroundInKnots;
|
||||
if (trackedLeg.hasFinishedLeg(timePoint)) {
|
||||
speedOverGroundInKnots = averageSpeedOverGround == null ? null : averageSpeedOverGround.getKnots();
|
||||
@@ -494,10 +543,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
|
||||
@Override
|
||||
public void stopTrackingEvent(EventIdentifier eventIdentifier) throws Exception {
|
||||
Event event = getEvent(eventIdentifier);
|
||||
if (event != null) {
|
||||
getService().stopTracking(event);
|
||||
}
|
||||
getService().apply(new StopTrackingEvent(eventIdentifier));
|
||||
}
|
||||
|
||||
private RaceDefinition getRaceByName(Event event, String raceName) {
|
||||
@@ -510,24 +556,12 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
|
||||
@Override
|
||||
public void stopTrackingRace(EventAndRaceIdentifier eventAndRaceIdentifier) throws Exception {
|
||||
Event event = getEvent(eventAndRaceIdentifier);
|
||||
if (event != null) {
|
||||
RaceDefinition r = getRace(eventAndRaceIdentifier);
|
||||
if (r != null) {
|
||||
getService().stopTracking(event, r);
|
||||
}
|
||||
}
|
||||
getService().apply(new StopTrackingRace(eventAndRaceIdentifier));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAndUntrackRace(EventAndRaceIdentifier eventAndRaceidentifier) throws Exception{
|
||||
Event event = getEvent(eventAndRaceidentifier);
|
||||
if (event!= null) {
|
||||
RaceDefinition race = getRace(eventAndRaceidentifier);
|
||||
if (race != null) {
|
||||
getService().removeRace(event, race);
|
||||
}
|
||||
}
|
||||
public void removeAndUntrackRace(EventAndRaceIdentifier eventAndRaceidentifier) {
|
||||
getService().apply(new RemoveAndUntrackRace(eventAndRaceidentifier));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -730,7 +764,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
windTrackInfoDTO.dampeningIntervalInMilliseconds = windTrack
|
||||
.getMillisecondsOverWhichToAverageWind();
|
||||
TimePoint timePoint = from;
|
||||
for (int i = 0; i < numberOfFixes && timePoint.compareTo(newestEvent) < 0; i++) {
|
||||
for (int i = 0; i < numberOfFixes && newestEvent != null && timePoint.compareTo(newestEvent) < 0; i++) {
|
||||
Wind wind = windTrack.getAveragedWind(null, timePoint);
|
||||
if (wind != null) {
|
||||
WindDTO windDTO = createWindDTOFromAlreadyAveraged(wind, windTrack);
|
||||
@@ -912,24 +946,54 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
public RaceTimesInfoDTO getRaceTimesInfo(RaceIdentifier raceIdentifier) {
|
||||
RaceTimesInfoDTO raceTimesInfo = null;
|
||||
TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier);
|
||||
|
||||
if (trackedRace != null) {
|
||||
raceTimesInfo = new RaceTimesInfoDTO(raceIdentifier);
|
||||
List<LegInfoDTO> legInfos = new ArrayList<LegInfoDTO>();
|
||||
raceTimesInfo.setLegInfos(legInfos);
|
||||
List<MarkPassingTimesDTO> markPassingTimesDTOs = new ArrayList<MarkPassingTimesDTO>();
|
||||
raceTimesInfo.setMarkPassingTimes(markPassingTimesDTOs);
|
||||
|
||||
raceTimesInfo.setStartOfRace(trackedRace.getStart() == null ? null : trackedRace.getStart().asDate());
|
||||
raceTimesInfo.startOfTracking = trackedRace.getStartOfTracking() == null ? null : trackedRace.getStartOfTracking().asDate();
|
||||
raceTimesInfo.timePointOfLastEvent = trackedRace.getTimePointOfLastEvent() == null ? null : trackedRace.getTimePointOfLastEvent().asDate();
|
||||
raceTimesInfo.timePointOfNewestEvent = trackedRace.getTimePointOfNewestEvent() == null ? null : trackedRace.getTimePointOfNewestEvent().asDate();
|
||||
raceTimesInfo.newestTrackingEvent = trackedRace.getTimePointOfNewestEvent() == null ? null : trackedRace.getTimePointOfNewestEvent().asDate();
|
||||
raceTimesInfo.endOfTracking = trackedRace.getEndOfTracking() == null ? null : trackedRace.getEndOfTracking().asDate();
|
||||
raceTimesInfo.endOfRace = trackedRace.getAssumedEnd() == null ? null : trackedRace.getAssumedEnd().asDate();
|
||||
List<LegTimesInfoDTO> legTimes = new ArrayList<LegTimesInfoDTO>();
|
||||
raceTimesInfo.setLegTimes(legTimes);
|
||||
Iterable<TimePoint> startTimesOfTrackedLegs = trackedRace.getStartTimesOfTrackedLegs();
|
||||
synchronized(startTimesOfTrackedLegs) {
|
||||
|
||||
Iterable<Pair<Waypoint, Pair<TimePoint, TimePoint>>> markPassingsTimes = trackedRace.getMarkPassingsTimes();
|
||||
synchronized(markPassingsTimes) {
|
||||
int numberOfWaypoints = Util.size(markPassingsTimes);
|
||||
int wayPointNumber = 1;
|
||||
for(Pair<Waypoint, Pair<TimePoint, TimePoint>> markPassingTimes: markPassingsTimes) {
|
||||
MarkPassingTimesDTO markPassingTimesDTO = new MarkPassingTimesDTO();
|
||||
markPassingTimesDTO.name = wayPointNumber == numberOfWaypoints ? "F" : "L" + wayPointNumber;
|
||||
Pair<TimePoint, TimePoint> timesPair = markPassingTimes.getB();
|
||||
TimePoint firstPassingTime = timesPair.getA();
|
||||
TimePoint lastPassingTime = timesPair.getB();
|
||||
markPassingTimesDTO.firstPassingDate = firstPassingTime == null ? null : firstPassingTime.asDate();
|
||||
markPassingTimesDTO.lastPassingDate = lastPassingTime == null ? null : lastPassingTime.asDate();
|
||||
markPassingTimesDTOs.add(markPassingTimesDTO);
|
||||
wayPointNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
Iterable<TrackedLeg> trackedLegs = trackedRace.getTrackedLegs();
|
||||
synchronized(trackedLegs) {
|
||||
int legNumber = 1;
|
||||
for(TimePoint legStartTime: startTimesOfTrackedLegs) {
|
||||
LegTimesInfoDTO legTimepointDTO = new LegTimesInfoDTO(legNumber);
|
||||
legTimepointDTO.name = (legNumber == 1) ? "S" : "L" + legNumber;
|
||||
legTimepointDTO.firstPassingDate = legStartTime.asDate();
|
||||
legTimes.add(legTimepointDTO);
|
||||
for(TrackedLeg trackedLeg: trackedLegs) {
|
||||
LegInfoDTO legInfoDTO = new LegInfoDTO(legNumber);
|
||||
legInfoDTO.name = "L" + legNumber;
|
||||
try {
|
||||
MarkPassingTimesDTO markPassingTimesDTO = markPassingTimesDTOs.get(legNumber-1);
|
||||
if(markPassingTimesDTO.firstPassingDate != null) {
|
||||
TimePoint p = new MillisecondsTimePoint(markPassingTimesDTO.firstPassingDate);
|
||||
legInfoDTO.legType = trackedLeg.getLegType(p);
|
||||
legInfoDTO.legBearingInDegrees = trackedLeg.getLegBearing(p).getDegrees();
|
||||
}
|
||||
} catch (NoWindException e) {
|
||||
// do nothing
|
||||
}
|
||||
legInfos.add(legInfoDTO);
|
||||
legNumber++;
|
||||
}
|
||||
}
|
||||
@@ -1026,7 +1090,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
int rank = trackedRace.getRank(competitor, dateAsTimePoint);
|
||||
TrackedLegOfCompetitor trackedLeg = trackedRace.getTrackedLeg(competitor, dateAsTimePoint);
|
||||
if (trackedLeg != null) {
|
||||
int legNumber = race.getCourse().getLegs().indexOf(trackedLeg.getLeg());
|
||||
int legNumber = race.getCourse().getLegs().indexOf(trackedLeg.getLeg()) + 1;
|
||||
QuickRankDTO quickRankDTO = new QuickRankDTO(getCompetitorDTO(competitor), rank, legNumber);
|
||||
result.add(quickRankDTO);
|
||||
}
|
||||
@@ -1043,24 +1107,18 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRaceIsKnownToStartUpwind(RaceIdentifier raceIdentifier, boolean raceIsKnownToStartUpwind) {
|
||||
DynamicTrackedRace trackedRace = (DynamicTrackedRace) getExistingTrackedRace(raceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
trackedRace.setRaceIsKnownToStartUpwind(raceIsKnownToStartUpwind);
|
||||
}
|
||||
public void setRaceIsKnownToStartUpwind(EventAndRaceIdentifier raceIdentifier, boolean raceIsKnownToStartUpwind) {
|
||||
getService().apply(new SetRaceIsKnownToStartUpwind(raceIdentifier, raceIsKnownToStartUpwind));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWindSourcesToExclude(RaceIdentifier raceIdentifier, Iterable<WindSource> windSourcesToExclude) {
|
||||
DynamicTrackedRace trackedRace = (DynamicTrackedRace) getExistingTrackedRace(raceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
trackedRace.setWindSourcesToExclude(windSourcesToExclude);
|
||||
}
|
||||
public void setWindSourcesToExclude(EventAndRaceIdentifier raceIdentifier, Iterable<WindSource> windSourcesToExclude) {
|
||||
getService().apply(new SetWindSourcesToExclude(raceIdentifier, windSourcesToExclude));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWind(RaceIdentifier raceIdentifier, WindDTO windDTO) {
|
||||
TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier);
|
||||
DynamicTrackedRace trackedRace = (DynamicTrackedRace) getExistingTrackedRace(raceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
Position p = null;
|
||||
if (windDTO.position != null) {
|
||||
@@ -1099,6 +1157,10 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
return racingEventServiceTracker.getService(); // grab the service
|
||||
}
|
||||
|
||||
private ReplicationService getReplicationService() {
|
||||
return replicationServiceTracker.getService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLeaderboardNames() throws Exception {
|
||||
return new ArrayList<String>(getService().getLeaderboards().keySet());
|
||||
@@ -1106,7 +1168,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
|
||||
@Override
|
||||
public LeaderboardDTO createLeaderboard(String leaderboardName, int[] discardThresholds) {
|
||||
return createStrippedLeaderboardDTO(getService().addLeaderboard(leaderboardName, discardThresholds), false);
|
||||
return createStrippedLeaderboardDTO(getService().apply(new CreateLeaderboard(leaderboardName, discardThresholds)), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1117,14 +1179,12 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
LeaderboardDTO dao = createStrippedLeaderboardDTO(leaderboard, false);
|
||||
results.add(dao);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LeaderboardDTO> getLeaderboardsByEvent(EventDTO event) {
|
||||
List<LeaderboardDTO> results = new ArrayList<LeaderboardDTO>();
|
||||
|
||||
for (RegattaDTO regatta : event.regattas) {
|
||||
for (RaceDTO race : regatta.races) {
|
||||
List<LeaderboardDTO> leaderboard = getLeaderboardsByRace(race);
|
||||
@@ -1133,7 +1193,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
}
|
||||
}
|
||||
}
|
||||
//Removing duplicates
|
||||
// Removing duplicates
|
||||
HashSet<LeaderboardDTO> set = new HashSet<LeaderboardDTO>(results);
|
||||
results.clear();
|
||||
results.addAll(set);
|
||||
@@ -1171,7 +1231,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
dto.name = leaderboard.getName();
|
||||
dto.competitorDisplayNames = new HashMap<CompetitorDTO, String>();
|
||||
for (RaceInLeaderboard raceColumn : leaderboard.getRaceColumns()) {
|
||||
RaceIdentifier raceIdentifier = null;
|
||||
EventAndRaceIdentifier raceIdentifier = null;
|
||||
StrippedRaceDTO race = null;
|
||||
if(raceColumn.getTrackedRace() != null) {
|
||||
TrackedRace trackedRace = raceColumn.getTrackedRace();
|
||||
@@ -1270,58 +1330,37 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
|
||||
@Override
|
||||
public void updateLeaderboard(String leaderboardName, String newLeaderboardName, int[] newDiscardingThresholds) {
|
||||
if (!leaderboardName.equals(newLeaderboardName)) {
|
||||
getService().renameLeaderboard(leaderboardName, newLeaderboardName);
|
||||
}
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(newLeaderboardName);
|
||||
if (!Arrays.equals(leaderboard.getResultDiscardingRule().getDiscardIndexResultsStartingWithHowManyRaces(), newDiscardingThresholds)) {
|
||||
leaderboard.setResultDiscardingRule(new ResultDiscardingRuleImpl(newDiscardingThresholds));
|
||||
}
|
||||
getService().updateStoredLeaderboard(leaderboard);
|
||||
getService().apply(new UpdateLeaderboard(leaderboardName, newLeaderboardName, newDiscardingThresholds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLeaderboard(String leaderboardName) {
|
||||
getService().removeLeaderboard(leaderboardName);
|
||||
getService().apply(new RemoveLeaderboard(leaderboardName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renameLeaderboard(String leaderboardName, String newLeaderboardName) {
|
||||
getService().renameLeaderboard(leaderboardName, newLeaderboardName);
|
||||
getService().apply(new RenameLeaderboard(leaderboardName, newLeaderboardName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addColumnToLeaderboard(String columnName, String leaderboardName, boolean medalRace) {
|
||||
getService().addColumnToLeaderboard(columnName, leaderboardName, medalRace);
|
||||
getService().apply(new AddColumnToLeaderboard(columnName, leaderboardName, medalRace));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLeaderboardColumn(String leaderboardName, String columnName) {
|
||||
getService().removeLeaderboardColumn(leaderboardName, columnName);
|
||||
getService().apply(new RemoveLeaderboardColumn(columnName, leaderboardName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renameLeaderboardColumn(String leaderboardName, String oldColumnName, String newColumnName) {
|
||||
getService().renameLeaderboardColumn(leaderboardName, oldColumnName, newColumnName);
|
||||
getService().apply(new RenameLeaderboardColumn(leaderboardName, oldColumnName, newColumnName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connectTrackedRaceToLeaderboardColumn(String leaderboardName, String raceColumnName, RaceIdentifier raceIdentifier) {
|
||||
boolean success = false;
|
||||
TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier);
|
||||
if (trackedRace != null) {
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
if (leaderboard != null) {
|
||||
RaceInLeaderboard raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
|
||||
if (raceColumn != null) {
|
||||
raceColumn.setTrackedRace(trackedRace);
|
||||
raceColumn.setRaceIdentifier(trackedRace.getRaceIdentifier());
|
||||
success = true;
|
||||
getService().updateStoredLeaderboard(leaderboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
return getService().apply(new ConnectTrackedRaceToLeaderboardColumn(leaderboardName, raceColumnName, raceIdentifier));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1344,126 +1383,44 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
|
||||
@Override
|
||||
public void disconnectLeaderboardColumnFromTrackedRace(String leaderboardName, String raceColumnName) {
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
if (leaderboard != null) {
|
||||
RaceInLeaderboard raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
|
||||
if (raceColumn != null) {
|
||||
raceColumn.setTrackedRace(null);
|
||||
raceColumn.setRaceIdentifier(null);
|
||||
getService().updateStoredLeaderboard(leaderboard);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Didn't find race "+raceColumnName+" in leaderboard "+leaderboardName);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Didn't find leaderboard "+leaderboardName);
|
||||
}
|
||||
getService().apply(new DisconnectLeaderboardColumnFromTrackedRace(leaderboardName, raceColumnName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLeaderboardCarryValue(String leaderboardName, String competitorIdAsString, Integer carriedPoints) {
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
if (leaderboard != null) {
|
||||
Competitor competitor = leaderboard.getCompetitorByIdAsString(competitorIdAsString);
|
||||
if (competitor != null) {
|
||||
if (carriedPoints == null) {
|
||||
leaderboard.unsetCarriedPoints(competitor);
|
||||
} else {
|
||||
leaderboard.setCarriedPoints(competitor, carriedPoints);
|
||||
}
|
||||
getService().updateStoredLeaderboard(leaderboard);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Didn't find competitor ID "+competitorIdAsString+" in leaderboard "+leaderboardName);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Didn't find leaderboard "+leaderboardName);
|
||||
}
|
||||
getService().apply(new UpdateLeaderboardCarryValue(leaderboardName, competitorIdAsString, carriedPoints));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Integer, Integer> updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString, String raceColumnName,
|
||||
MaxPointsReason maxPointsReason, Date date) throws NoWindException {
|
||||
TimePoint timePoint = new MillisecondsTimePoint(date);
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
if (leaderboard != null) {
|
||||
Competitor competitor = leaderboard.getCompetitorByIdAsString(competitorIdAsString);
|
||||
if (competitor != null) {
|
||||
RaceInLeaderboard raceColumn = leaderboard.getRaceColumnByName(raceColumnName);
|
||||
if (raceColumn == null) {
|
||||
throw new IllegalArgumentException("Didn't find race "+raceColumnName+" in leaderboard "+leaderboardName);
|
||||
}
|
||||
leaderboard.getScoreCorrection().setMaxPointsReason(competitor, raceColumn, maxPointsReason);
|
||||
getService().updateStoredLeaderboard(leaderboard);
|
||||
Entry updatedEntry = leaderboard.getEntry(competitor, raceColumn, timePoint);
|
||||
return new Pair<Integer, Integer>(updatedEntry.getNetPoints(), updatedEntry.getTotalPoints());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Didn't find competitor with ID "+competitorIdAsString+" in leaderboard "+leaderboardName);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Didn't find leaderboard "+leaderboardName);
|
||||
}
|
||||
return getService().apply(new UpdateLeaderboardMaxPointsReason(leaderboardName, raceColumnName, competitorIdAsString, maxPointsReason, date));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Integer, Integer> updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString, String raceName,
|
||||
public Pair<Integer, Integer> updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString, String columnName,
|
||||
Integer correctedScore, Date date) throws NoWindException {
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
int newNetPoints;
|
||||
int newTotalPoints;
|
||||
if (leaderboard != null) {
|
||||
Competitor competitor = leaderboard.getCompetitorByIdAsString(competitorIdAsString);
|
||||
if (competitor != null) {
|
||||
MillisecondsTimePoint timePoint = new MillisecondsTimePoint(date);
|
||||
RaceInLeaderboard raceColumn = leaderboard.getRaceColumnByName(raceName);
|
||||
if (raceColumn == null) {
|
||||
throw new IllegalArgumentException("Didn't find race "+raceName+" in leaderboard "+leaderboardName);
|
||||
}
|
||||
if (correctedScore == null) {
|
||||
leaderboard.getScoreCorrection().uncorrectScore(competitor, raceColumn);
|
||||
newNetPoints = leaderboard.getNetPoints(competitor, raceColumn, timePoint);
|
||||
} else {
|
||||
leaderboard.getScoreCorrection().correctScore(competitor, raceColumn, correctedScore);
|
||||
newNetPoints = correctedScore;
|
||||
}
|
||||
newTotalPoints = leaderboard.getEntry(competitor, raceColumn, timePoint).getTotalPoints();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Didn't find competitor with ID "+competitorIdAsString+" in leaderboard "+leaderboardName);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Didn't find leaderboard "+leaderboardName);
|
||||
}
|
||||
getService().updateStoredLeaderboard(leaderboard);
|
||||
return new Pair<Integer, Integer>(newNetPoints, newTotalPoints);
|
||||
return getService().apply(new UpdateLeaderboardScoreCorrection(leaderboardName, columnName, competitorIdAsString, correctedScore, date));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCompetitorDisplayNameInLeaderboard(String leaderboardName, String competitorIdAsString, String displayName) {
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
Competitor competitor = leaderboard.getCompetitorByIdAsString(competitorIdAsString);
|
||||
if (competitor != null) {
|
||||
leaderboard.setDisplayName(competitor, displayName);
|
||||
getService().updateStoredLeaderboard(leaderboard);
|
||||
}
|
||||
getService().apply(new UpdateCompetitorDisplayNameInLeaderboard(leaderboardName, competitorIdAsString, displayName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveLeaderboardColumnUp(String leaderboardName, String columnName) {
|
||||
getService().moveLeaderboardColumnUp(leaderboardName, columnName);
|
||||
getService().apply(new MoveLeaderboardColumnUp(leaderboardName, columnName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveLeaderboardColumnDown(String leaderboardName, String columnName) {
|
||||
getService().moveLeaderboardColumnDown(leaderboardName, columnName);
|
||||
getService().apply(new MoveLeaderboardColumnDown(leaderboardName, columnName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateIsMedalRace(String leaderboardName, String columnName, boolean isMedalRace) {
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
if (leaderboard != null) {
|
||||
leaderboard.updateIsMedalRace(columnName, isMedalRace);
|
||||
getService().updateStoredLeaderboard(leaderboard);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Leaderboard named " + leaderboardName + " not found");
|
||||
}
|
||||
getService().apply(new UpdateIsMedalRace(leaderboardName, columnName, isMedalRace));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1723,14 +1680,14 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceDefinition getRace(EventAndRaceIdentifier eventNameAndRaceName) {
|
||||
Event event = getService().getEventByName(eventNameAndRaceName.getEventName());
|
||||
RaceDefinition race = getRaceByName(event, eventNameAndRaceName.getRaceName());
|
||||
public RaceDefinition getRace(EventAndRaceIdentifier raceIdentifier) {
|
||||
Event event = getService().getEventByName(raceIdentifier.getEventName());
|
||||
RaceDefinition race = getRaceByName(event, raceIdentifier.getRaceName());
|
||||
return race;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedRace getTrackedRace(RaceIdentifier eventNameAndRaceName) {
|
||||
public TrackedRace getTrackedRace(EventAndRaceIdentifier eventNameAndRaceName) {
|
||||
Event event = getService().getEventByName(eventNameAndRaceName.getEventName());
|
||||
RaceDefinition race = getRaceByName(event, eventNameAndRaceName.getRaceName());
|
||||
TrackedRace trackedRace = getService().getOrCreateTrackedEvent(event).getTrackedRace(race);
|
||||
@@ -1747,10 +1704,6 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
return getService().getEventByName(eventIdentifier.getEventName());
|
||||
}
|
||||
|
||||
private Event getEvent(EventIdentifier eventIdentifier) {
|
||||
return (Event) eventIdentifier.getEvent(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a servlet context that, when asked for a resource, first tries the original servlet context's implementation. If that
|
||||
* fails, it prepends "war/" to the request because the war/ folder contains all the resources exposed externally
|
||||
@@ -1805,22 +1758,32 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
|
||||
@Override
|
||||
public void renameLeaderboardGroup(String oldName, String newName) {
|
||||
getService().renameLeaderboardGroup(oldName, newName);
|
||||
getService().apply(new RenameLeaderboardGroup(oldName, newName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeLeaderboardGroup(String groupName) {
|
||||
getService().removeLeaderboardGroup(groupName);
|
||||
getService().apply(new RemoveLeaderboardGroup(groupName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderboardGroupDTO createLeaderboardGroup(String groupName, String description) {
|
||||
return convertToLeaderboardGroupDTO(getService().addLeaderboardGroup(groupName, description, new ArrayList<String>()));
|
||||
return convertToLeaderboardGroupDTO(getService().apply(new CreateLeaderboardGroup(groupName, description, new ArrayList<String>())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLeaderboardGroup(String oldName, String newName, String description, List<String> leaderboardNames) {
|
||||
getService().updateLeaderboardGroup(oldName, newName, description, leaderboardNames);
|
||||
getService().apply(new UpdateLeaderboardGroup(oldName, newName, description, leaderboardNames));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getHostnamesOfReplica() {
|
||||
ReplicationService service = getReplicationService();
|
||||
return service.getHostnamesOfReplica();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startReplicatingFromMaster(String masterName, int servletPort, int jmsPort) throws IOException, ClassNotFoundException, JMSException {
|
||||
getReplicationService().startToReplicateFrom(ReplicationFactory.INSTANCE.createReplicationMasterDescriptor(masterName, servletPort, jmsPort));
|
||||
}
|
||||
}
|
||||
+9
-6
@@ -9,7 +9,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
|
||||
/**
|
||||
* Captures the serializable properties of a leaderboard which in particular has the competitors, any optional display
|
||||
@@ -101,10 +101,12 @@ public class LeaderboardDTO implements IsSerializable {
|
||||
} else if (o2 == null) {
|
||||
result = 1;
|
||||
} else {
|
||||
final int totalPoints1 = getTotalPoints(o1);
|
||||
final int totalPoints2 = getTotalPoints(o2);
|
||||
if (scoredInMedalRace(o1.competitor)) {
|
||||
if (scoredInMedalRace(o2.competitor)) {
|
||||
// both scored in medal race
|
||||
result = getTotalPoints(o1) - getTotalPoints(o2);
|
||||
result = totalPoints1 - totalPoints2;
|
||||
// in case of tie, medal race points decide:
|
||||
if (result == 0) {
|
||||
result = getMedalRaceScore(o1.competitor) - getMedalRaceScore(o2.competitor);
|
||||
@@ -118,10 +120,11 @@ public class LeaderboardDTO implements IsSerializable {
|
||||
// only o2 scored in medal race, so o2 scores better, o1 scores worse = "greater"
|
||||
result = 1;
|
||||
} else {
|
||||
// neither one scored in any medal race
|
||||
result = getTotalPoints(o1) - getTotalPoints(o2);
|
||||
// neither one scored in any medal race; 0 total points means "did not participate" and ranks worse
|
||||
result = totalPoints1 == 0 ? totalPoints2 == 0 ? 0 : 1 : totalPoints2 == 0 ? -1 : totalPoints1 - totalPoints2;
|
||||
// Now if both have equal points, count races won.
|
||||
if (result == 0) {
|
||||
// TODO bug 469: not the number of races won but the better rankings count
|
||||
result = getNumberOfRacesWon(o2.competitor) - getNumberOfRacesWon(o1.competitor);
|
||||
}
|
||||
// If number of races won is still equal, use rank in last race where at least one of the two
|
||||
@@ -292,7 +295,7 @@ public class LeaderboardDTO implements IsSerializable {
|
||||
return getRaceInLeaderboardByName(raceColumnName).isMedalRace();
|
||||
}
|
||||
|
||||
public void addRace(String raceColumnName, boolean medalRace, RaceIdentifier trackedRaceIdentifier, StrippedRaceDTO race) {
|
||||
public void addRace(String raceColumnName, boolean medalRace, EventAndRaceIdentifier trackedRaceIdentifier, StrippedRaceDTO race) {
|
||||
RaceInLeaderboardDTO raceInLeaderboardDTO = new RaceInLeaderboardDTO();
|
||||
raceInLeaderboardDTO.setRaceColumnName(raceColumnName);
|
||||
raceInLeaderboardDTO.setMedalRace(medalRace);
|
||||
@@ -301,7 +304,7 @@ public class LeaderboardDTO implements IsSerializable {
|
||||
races.add(raceInLeaderboardDTO);
|
||||
}
|
||||
|
||||
public void addRaceAt(String raceColumnName, boolean medalRace, RaceIdentifier trackedRaceIdentifier, int index) {
|
||||
public void addRaceAt(String raceColumnName, boolean medalRace, EventAndRaceIdentifier trackedRaceIdentifier, int index) {
|
||||
RaceInLeaderboardDTO raceInLeaderboardDTO = new RaceInLeaderboardDTO();
|
||||
raceInLeaderboardDTO.setRaceColumnName(raceColumnName);
|
||||
raceInLeaderboardDTO.setMedalRace(medalRace);
|
||||
|
||||
+8
@@ -26,6 +26,8 @@ public class LeaderboardEntryDTO implements IsSerializable {
|
||||
|
||||
public Double windwardDistanceToOverallLeaderInMeters;
|
||||
|
||||
public Double averageCrossTrackErrorInMeters;
|
||||
|
||||
/**
|
||||
* If <code>null</code>, no leg details are known yet, the race is not being tracked or the details
|
||||
* haven't been requested from the server yet. Otherwise, the list holds one entry per {@link Leg} of the
|
||||
@@ -40,6 +42,7 @@ public class LeaderboardEntryDTO implements IsSerializable {
|
||||
result = prime * result + (discarded ? 1231 : 1237);
|
||||
result = prime * result + ((legDetails == null) ? 0 : legDetails.hashCode());
|
||||
result = prime * result + netPoints;
|
||||
result = prime * result + ((averageCrossTrackErrorInMeters == null) ? 0 : averageCrossTrackErrorInMeters.hashCode());
|
||||
result = prime * result + ((reasonForMaxPoints == null) ? 0 : reasonForMaxPoints.hashCode());
|
||||
result = prime * result + ((windwardDistanceToOverallLeaderInMeters == null) ? 0 : windwardDistanceToOverallLeaderInMeters.hashCode());
|
||||
result = prime * result + totalPoints;
|
||||
@@ -74,6 +77,11 @@ public class LeaderboardEntryDTO implements IsSerializable {
|
||||
return false;
|
||||
} else if (!windwardDistanceToOverallLeaderInMeters.equals(other.windwardDistanceToOverallLeaderInMeters))
|
||||
return false;
|
||||
if (averageCrossTrackErrorInMeters == null) {
|
||||
if (other.averageCrossTrackErrorInMeters != null)
|
||||
return false;
|
||||
} else if (!averageCrossTrackErrorInMeters.equals(other.averageCrossTrackErrorInMeters))
|
||||
return false;
|
||||
if (totalPoints != other.totalPoints)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
+1
@@ -38,6 +38,7 @@ public class LegEntryDTO implements IsSerializable {
|
||||
public Integer numberOfJibes;
|
||||
public Integer numberOfTacks;
|
||||
public Integer numberOfPenaltyCircles;
|
||||
public Double averageCrossTrackErrorInMeters;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.sap.sailing.gwt.ui.shared;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
|
||||
public class LegInfoDTO extends NamedDTO implements IsSerializable {
|
||||
public int legNumber;
|
||||
|
||||
public LegType legType;
|
||||
|
||||
public double legBearingInDegrees;
|
||||
|
||||
public LegInfoDTO() {}
|
||||
|
||||
public LegInfoDTO(int legNumber) {
|
||||
this.legNumber = legNumber;
|
||||
}
|
||||
}
|
||||
+5
-7
@@ -4,7 +4,7 @@ import java.util.Date;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
|
||||
public class LegTimesInfoDTO extends NamedDTO implements IsSerializable {
|
||||
public class MarkPassingTimesDTO extends NamedDTO implements IsSerializable {
|
||||
/**
|
||||
* The time point when the leg was first entered by a competitor; for the first leg the semantics
|
||||
* are slightly different: if the official race start time is known it is used instead of the first
|
||||
@@ -12,13 +12,11 @@ public class LegTimesInfoDTO extends NamedDTO implements IsSerializable {
|
||||
*/
|
||||
public Date firstPassingDate;
|
||||
|
||||
// public Date lastPassingDate;
|
||||
public Date lastPassingDate;
|
||||
|
||||
public int legNumber;
|
||||
|
||||
public LegTimesInfoDTO() {}
|
||||
public MarkPassingTimesDTO() {}
|
||||
|
||||
public LegTimesInfoDTO(int legNumber) {
|
||||
this.legNumber = legNumber;
|
||||
public MarkPassingTimesDTO(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -3,8 +3,8 @@ package com.sap.sailing.gwt.ui.shared;
|
||||
import java.util.Date;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventNameAndRaceName;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
|
||||
public class RaceDTO extends NamedDTO implements IsSerializable {
|
||||
public Iterable<CompetitorDTO> competitors;
|
||||
@@ -40,7 +40,7 @@ public class RaceDTO extends NamedDTO implements IsSerializable {
|
||||
this.regatta = regatta;
|
||||
}
|
||||
|
||||
public RaceIdentifier getRaceIdentifier() {
|
||||
public EventAndRaceIdentifier getRaceIdentifier() {
|
||||
return new EventNameAndRaceName(regatta.getEvent().name, name);
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -3,12 +3,12 @@ package com.sap.sailing.gwt.ui.shared;
|
||||
import java.util.Date;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
|
||||
public class RaceInLeaderboardDTO implements IsSerializable {
|
||||
private String raceColumnName;
|
||||
private boolean medalRace;
|
||||
private RaceIdentifier trackedRaceIdentifier;
|
||||
private EventAndRaceIdentifier trackedRaceIdentifier;
|
||||
private StrippedRaceDTO race;
|
||||
|
||||
public String getRaceColumnName() {
|
||||
@@ -31,7 +31,7 @@ public class RaceInLeaderboardDTO implements IsSerializable {
|
||||
return trackedRaceIdentifier != null;
|
||||
}
|
||||
|
||||
public void setRaceIdentifier(RaceIdentifier raceIdentifier) {
|
||||
public void setRaceIdentifier(EventAndRaceIdentifier raceIdentifier) {
|
||||
this.trackedRaceIdentifier = raceIdentifier;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class RaceInLeaderboardDTO implements IsSerializable {
|
||||
* data can be obtained from the server in great detail, as opposed to non-tracked races for which only
|
||||
* result points may have been entered manually.
|
||||
*/
|
||||
public RaceIdentifier getRaceIdentifier() {
|
||||
public EventAndRaceIdentifier getRaceIdentifier() {
|
||||
return trackedRaceIdentifier;
|
||||
}
|
||||
|
||||
|
||||
+51
-24
@@ -10,15 +10,17 @@ import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
public class RaceTimesInfoDTO implements IsSerializable {
|
||||
private RaceIdentifier raceIdentifier;
|
||||
|
||||
public List<LegTimesInfoDTO> legTimes;
|
||||
public List<LegInfoDTO> legInfos;
|
||||
|
||||
public List<MarkPassingTimesDTO> markPassingTimes;
|
||||
|
||||
public Date startOfRace;
|
||||
public Date startOfTracking;
|
||||
public Date endOfTracking;
|
||||
public Date endOfRace;
|
||||
|
||||
public Date timePointOfLastEvent;
|
||||
public Date timePointOfNewestEvent;
|
||||
public Date assumedEndOfRace;
|
||||
public Date newestTrackingEvent;
|
||||
|
||||
public RaceTimesInfoDTO(RaceIdentifier raceIdentifier) {
|
||||
this.raceIdentifier = raceIdentifier;
|
||||
@@ -34,25 +36,18 @@ public class RaceTimesInfoDTO implements IsSerializable {
|
||||
this.raceIdentifier = raceIdentifier;
|
||||
}
|
||||
|
||||
public LegTimesInfoDTO getLastLegTimes() {
|
||||
if (legTimes == null || legTimes.isEmpty()) {
|
||||
public MarkPassingTimesDTO getLastMarkPassingTimes() {
|
||||
if (markPassingTimes == null || markPassingTimes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
LegTimesInfoDTO lastLegTime = null;
|
||||
Iterator<LegTimesInfoDTO> iterator = legTimes.iterator();
|
||||
MarkPassingTimesDTO lastTimes = null;
|
||||
Iterator<MarkPassingTimesDTO> iterator = markPassingTimes.iterator();
|
||||
while(iterator.hasNext()) {
|
||||
lastLegTime = iterator.next();
|
||||
lastTimes = iterator.next();
|
||||
}
|
||||
return lastLegTime;
|
||||
return lastTimes;
|
||||
}
|
||||
|
||||
public List<LegTimesInfoDTO> getLegTimes() {
|
||||
return legTimes;
|
||||
}
|
||||
|
||||
public void setLegTimes(List<LegTimesInfoDTO> legTimes) {
|
||||
this.legTimes = legTimes;
|
||||
}
|
||||
|
||||
public Date getStartOfRace() {
|
||||
return startOfRace;
|
||||
@@ -70,19 +65,51 @@ public class RaceTimesInfoDTO implements IsSerializable {
|
||||
this.startOfTracking = startOfTracking;
|
||||
}
|
||||
|
||||
public Date getTimePointOfLastEvent() {
|
||||
return timePointOfLastEvent;
|
||||
public Date getEndOfTracking() {
|
||||
return endOfTracking;
|
||||
}
|
||||
|
||||
public void setTimePointOfLastEvent(Date timePointOfLastEvent) {
|
||||
this.timePointOfLastEvent = timePointOfLastEvent;
|
||||
public void setEndOfTracking(Date endOfTracking) {
|
||||
this.endOfTracking = endOfTracking;
|
||||
}
|
||||
|
||||
public Date getTimePointOfNewestEvent() {
|
||||
return timePointOfNewestEvent;
|
||||
public Date getEndOfRace() {
|
||||
return endOfRace;
|
||||
}
|
||||
|
||||
public void setTimePointOfNewestEvent(Date timePointOfNewestEvent) {
|
||||
this.timePointOfNewestEvent = timePointOfNewestEvent;
|
||||
public void setEndOfRace(Date endOfRace) {
|
||||
this.endOfRace = endOfRace;
|
||||
}
|
||||
|
||||
public Date getAssumedEndOfRace() {
|
||||
return assumedEndOfRace;
|
||||
}
|
||||
|
||||
public void setAssumedEndOfRace(Date assumedEndOfRace) {
|
||||
this.assumedEndOfRace = assumedEndOfRace;
|
||||
}
|
||||
|
||||
public Date getNewestTrackingEvent() {
|
||||
return newestTrackingEvent;
|
||||
}
|
||||
|
||||
public void setNewestTrackingEvent(Date newestTrackingEvent) {
|
||||
this.newestTrackingEvent = newestTrackingEvent;
|
||||
}
|
||||
|
||||
public List<LegInfoDTO> getLegInfos() {
|
||||
return legInfos;
|
||||
}
|
||||
|
||||
public void setLegInfos(List<LegInfoDTO> legInfos) {
|
||||
this.legInfos = legInfos;
|
||||
}
|
||||
|
||||
public List<MarkPassingTimesDTO> getMarkPassingTimes() {
|
||||
return markPassingTimes;
|
||||
}
|
||||
|
||||
public void setMarkPassingTimes(List<MarkPassingTimesDTO> markPassingTimes) {
|
||||
this.markPassingTimes = markPassingTimes;
|
||||
}
|
||||
}
|
||||
+123
-32
@@ -45,6 +45,7 @@ import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.EventAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
@@ -61,6 +62,7 @@ import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.RaceSelectionChangeListener;
|
||||
import com.sap.sailing.gwt.ui.client.RaceTimesInfoProviderListener;
|
||||
import com.sap.sailing.gwt.ui.client.RequiresDataInitialization;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
@@ -72,21 +74,24 @@ import com.sap.sailing.gwt.ui.client.WindSourceTypeFormatter;
|
||||
import com.sap.sailing.gwt.ui.shared.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.CourseDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.GPSFixDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LegInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.ManeuverDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.MarkDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.PositionDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceMapDataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SpeedWithBearingDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindTrackInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.components.Component;
|
||||
import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.RaceMapZoomSettings.ZoomTypes;
|
||||
|
||||
public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSelectionChangeListener, RaceSelectionChangeListener,
|
||||
Component<RaceMapSettings>, RequiresDataInitialization, RequiresResize {
|
||||
RaceTimesInfoProviderListener, Component<RaceMapSettings>, RequiresDataInitialization, RequiresResize {
|
||||
private MapWidget map;
|
||||
|
||||
private final SailingServiceAsync sailingService;
|
||||
@@ -112,6 +117,11 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
*/
|
||||
private Polyline advantageLine;
|
||||
|
||||
/**
|
||||
* Polyline for the course middle line.
|
||||
*/
|
||||
private Polyline courseMiddleLine;
|
||||
|
||||
private WindTrackInfoDTO lastCombinedWindTrackInfoDTO;
|
||||
|
||||
/**
|
||||
@@ -165,7 +175,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
|
||||
private CompetitorSelectionProvider competitorSelection;
|
||||
|
||||
private List<RaceIdentifier> selectedRaces;
|
||||
private List<EventAndRaceIdentifier> selectedRaces;
|
||||
|
||||
/**
|
||||
* Used to check if the first initial zoom to the buoy markers was already done.
|
||||
@@ -177,6 +187,8 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
|
||||
private final Timer timer;
|
||||
|
||||
private RaceTimesInfoDTO lastRaceTimesInfo;
|
||||
|
||||
/**
|
||||
* RPC calls may receive responses out of order if there are multiple calls in-flight at the same time. If the time
|
||||
* slider is moved quickly it generates many requests for boat positions quickly after each other. Sometimes,
|
||||
@@ -308,21 +320,27 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
public void onRaceSelectionChange(List<EventAndRaceIdentifier> selectedRaces) {
|
||||
mapFirstZoomDone = false;
|
||||
// TODO bug 494: reset zoom settings to user preferences
|
||||
this.selectedRaces = selectedRaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void raceTimesInfosReceived(Map<RaceIdentifier, RaceTimesInfoDTO> raceTimesInfos) {
|
||||
this.lastRaceTimesInfo = raceTimesInfos.get(selectedRaces.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timeChanged(final Date date) {
|
||||
if (date != null) {
|
||||
if (selectedRaces != null && !selectedRaces.isEmpty()) {
|
||||
RaceIdentifier race = selectedRaces.get(selectedRaces.size() - 1);
|
||||
final Iterable<CompetitorDTO> competitorsToShow = getCompetitorsToShow();
|
||||
|
||||
if (race != null) {
|
||||
final Triple<Map<CompetitorDTO, Date>, Map<CompetitorDTO, Date>, Map<CompetitorDTO, Boolean>> fromAndToAndOverlap =
|
||||
computeFromAndTo(date, getCompetitorsToShow());
|
||||
computeFromAndTo(date, competitorsToShow);
|
||||
final int requestID = ++boatPositionRequestIDCounter;
|
||||
|
||||
GetRaceMapDataAction getRaceMapDataAction = new GetRaceMapDataAction(sailingService, race, date,
|
||||
@@ -354,10 +372,11 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
// Do mark specific actions
|
||||
showMarksOnMap(raceMapDataDTO.coursePositions);
|
||||
showStartAndFinishLines(raceMapDataDTO.coursePositions);
|
||||
showAdvantageLine();
|
||||
showAdvantageLine(competitorsToShow);
|
||||
|
||||
// Rezoom the map
|
||||
// TODO make this a loop across the LatLngBoundsCalculators, pulling them from a collection updated in updateSettings
|
||||
if (!getSettings().getZoomSettings().contains(ZoomTypes.NONE)) { // Auto zoom if setting is not manual
|
||||
if (!getSettings().getZoomSettings().containsZoomType(ZoomTypes.NONE)) { // Auto zoom if setting is not manual
|
||||
LatLngBounds bounds = getSettings().getZoomSettings().getNewBounds(RaceMap.this);
|
||||
zoomMapToNewBounds(bounds);
|
||||
mapFirstZoomDone = true;
|
||||
@@ -619,26 +638,58 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
return LatLng.newInstance(lat2 / Math.PI * 180., lon2 / Math.PI * 180.);
|
||||
}
|
||||
|
||||
private void showAdvantageLine() {
|
||||
if(map != null && quickRanks != null && lastCombinedWindTrackInfoDTO != null && lastCombinedWindTrackInfoDTO.windFixes.size() > 0) {
|
||||
final CompetitorDTO leadingCompetitorDTO = quickRanks.get(0).competitor;
|
||||
if (leadingCompetitorDTO != null && lastShownFix.containsKey(leadingCompetitorDTO) && lastShownFix.get(leadingCompetitorDTO) != -1) {
|
||||
private void showAdvantageLine(Iterable<CompetitorDTO> competitorsToShow) {
|
||||
if(map != null && lastRaceTimesInfo != null && quickRanks != null && lastCombinedWindTrackInfoDTO != null && lastCombinedWindTrackInfoDTO.windFixes.size() > 0) {
|
||||
// find competitor with highest rank
|
||||
CompetitorDTO leadingCompetitorDTO = null;
|
||||
int legOfLeaderCompetitor = -1;
|
||||
// this only works because the quickRanks are sorted
|
||||
for (QuickRankDTO quickRank : quickRanks) {
|
||||
if(Util.contains(competitorsToShow, quickRank.competitor)) {
|
||||
leadingCompetitorDTO = quickRank.competitor;
|
||||
legOfLeaderCompetitor = quickRank.legNumber;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (leadingCompetitorDTO != null && getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.ADVANTAGELINE) &&
|
||||
lastShownFix.containsKey(leadingCompetitorDTO) && lastShownFix.get(leadingCompetitorDTO) != -1
|
||||
&& legOfLeaderCompetitor > 0 && legOfLeaderCompetitor <= lastRaceTimesInfo.getLegInfos().size()) {
|
||||
LegInfoDTO legInfoDTO = lastRaceTimesInfo.getLegInfos().get(legOfLeaderCompetitor-1);
|
||||
GPSFixDTO lastBoatFix = getBoatFix(leadingCompetitorDTO);
|
||||
|
||||
double advantageLineLengthInKm = 1.0;
|
||||
double distanceFromBoatPosition = 0.005; // 5m
|
||||
// implement and use Position.translateRhumb()
|
||||
double bearingOfBoatInDeg = lastBoatFix.speedWithBearing.bearingInDegrees;
|
||||
LatLng boatPosition = LatLng.newInstance(lastBoatFix.position.latDeg, lastBoatFix.position.lngDeg);
|
||||
LatLng posAheadOfFirstBoat = calculatePositionAlongRhumbline(boatPosition, bearingOfBoatInDeg, 0.05);
|
||||
double bearingOfCombinedWindInDeg = lastCombinedWindTrackInfoDTO.windFixes.get(0).trueWindBearingDeg;
|
||||
double rotatedBearingDeg = bearingOfCombinedWindInDeg + 90.0;
|
||||
if(rotatedBearingDeg >= 360.0)
|
||||
rotatedBearingDeg -= 360.0;
|
||||
LatLng advantageLinePos1 = calculatePositionAlongRhumbline(posAheadOfFirstBoat, rotatedBearingDeg, advantageLineLengthInKm / 2.0);
|
||||
rotatedBearingDeg = bearingOfCombinedWindInDeg - 90.0;
|
||||
if(rotatedBearingDeg < 0.0)
|
||||
rotatedBearingDeg += 360.0;
|
||||
LatLng advantageLinePos2 = calculatePositionAlongRhumbline(posAheadOfFirstBoat, rotatedBearingDeg, advantageLineLengthInKm / 2.0);
|
||||
LatLng posAheadOfFirstBoat = calculatePositionAlongRhumbline(boatPosition, bearingOfBoatInDeg, distanceFromBoatPosition);
|
||||
double bearingOfCombinedWindInDeg = lastCombinedWindTrackInfoDTO.windFixes.get(0).trueWindBearingDeg;
|
||||
double rotatedBearingDeg1 = 0.0;
|
||||
double rotatedBearingDeg2 = 0.0;
|
||||
switch(legInfoDTO.legType) {
|
||||
case UPWIND:
|
||||
case DOWNWIND: {
|
||||
rotatedBearingDeg1 = bearingOfCombinedWindInDeg + 90.0;
|
||||
if(rotatedBearingDeg1 >= 360.0)
|
||||
rotatedBearingDeg1 -= 360.0;
|
||||
rotatedBearingDeg2 = bearingOfCombinedWindInDeg - 90.0;
|
||||
if(rotatedBearingDeg2 < 0.0)
|
||||
rotatedBearingDeg2 += 360.0;
|
||||
}
|
||||
break;
|
||||
case REACHING: {
|
||||
rotatedBearingDeg1 = legInfoDTO.legBearingInDegrees + 90.0;
|
||||
if(rotatedBearingDeg1 >= 360.0)
|
||||
rotatedBearingDeg1 -= 360.0;
|
||||
rotatedBearingDeg2 = legInfoDTO.legBearingInDegrees - 90.0;
|
||||
if(rotatedBearingDeg2 < 0.0)
|
||||
rotatedBearingDeg2 += 360.0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
LatLng advantageLinePos1 = calculatePositionAlongRhumbline(posAheadOfFirstBoat, rotatedBearingDeg1, advantageLineLengthInKm / 2.0);
|
||||
LatLng advantageLinePos2 = calculatePositionAlongRhumbline(posAheadOfFirstBoat, rotatedBearingDeg2, advantageLineLengthInKm / 2.0);
|
||||
|
||||
LatLng[] advantageLinePoints = new LatLng[2];
|
||||
advantageLinePoints[0] = LatLng.newInstance(advantageLinePos1.getLatitude(), advantageLinePos1.getLongitude());
|
||||
@@ -662,16 +713,20 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void showStartAndFinishLines(final CourseDTO courseDTO) {
|
||||
if(map != null && courseDTO != null) {
|
||||
if(courseDTO.startGate != null) {
|
||||
if(map != null && courseDTO != null && quickRanks != null && !quickRanks.isEmpty() && lastRaceTimesInfo != null) {
|
||||
int legOfLeadingCompetitor = quickRanks.get(0).legNumber;
|
||||
int numberOfLegs = lastRaceTimesInfo.legInfos.size();
|
||||
// draw the start line
|
||||
if(courseDTO.startGate != null && legOfLeadingCompetitor == 1 &&
|
||||
getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.STARTLINE)) {
|
||||
LatLng[] startGatePoints = new LatLng[2];
|
||||
startGatePoints[0] = LatLng.newInstance(courseDTO.startGate.getA().position.latDeg, courseDTO.startGate.getA().position.lngDeg);
|
||||
startGatePoints[1] = LatLng.newInstance(courseDTO.startGate.getB().position.latDeg, courseDTO.startGate.getB().position.lngDeg);
|
||||
if(startLine == null) {
|
||||
PolylineOptions options = PolylineOptions.newInstance(/* clickable */false, /* geodesic */true);
|
||||
startLine = new Polyline(startGatePoints, /* color */ "#1e60bc", /* width */ 1, /* opacity */1.0, options);
|
||||
startLine = new Polyline(startGatePoints, /* color */ "#FFFFFF", /* width */ 1, /* opacity */1.0, options);
|
||||
map.addOverlay(startLine);
|
||||
} else {
|
||||
startLine.deleteVertex(1);
|
||||
@@ -686,13 +741,15 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
startLine.deleteVertex(0);
|
||||
}
|
||||
}
|
||||
if(courseDTO.finishGate != null) {
|
||||
// draw the finish line
|
||||
if(courseDTO.finishGate != null && legOfLeadingCompetitor == numberOfLegs &&
|
||||
getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.FINISHLINE)) {
|
||||
LatLng[] finishGatePoints = new LatLng[2];
|
||||
finishGatePoints[0] = LatLng.newInstance(courseDTO.finishGate.getA().position.latDeg, courseDTO.finishGate.getA().position.lngDeg);
|
||||
finishGatePoints[1] = LatLng.newInstance(courseDTO.finishGate.getB().position.latDeg, courseDTO.finishGate.getB().position.lngDeg);
|
||||
if(finishLine == null) {
|
||||
PolylineOptions options = PolylineOptions.newInstance(/* clickable */false, /* geodesic */true);
|
||||
finishLine = new Polyline(finishGatePoints, /* color */ "#1e60bc", /* width */ 1, /* opacity */1.0, options);
|
||||
finishLine = new Polyline(finishGatePoints, /* color */ "#000000", /* width */ 1, /* opacity */1.0, options);
|
||||
map.addOverlay(finishLine);
|
||||
} else {
|
||||
finishLine.deleteVertex(1);
|
||||
@@ -707,6 +764,32 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
finishLine.deleteVertex(0);
|
||||
}
|
||||
}
|
||||
// draw the course middle line
|
||||
if(courseDTO.startGate != null && legOfLeadingCompetitor == 1 && courseDTO.buoys.size() >= 1 &&
|
||||
getSettings().getHelpLinesSettings().containsHelpLine(HelpLineTypes.COURSEMIDDLELINE)) {
|
||||
LatLng[] courseMiddleLinePoints = new LatLng[2];
|
||||
double p1Lat = (courseDTO.startGate.getA().position.latDeg + courseDTO.startGate.getB().position.latDeg) / 2.0;
|
||||
double p1Lng = (courseDTO.startGate.getA().position.lngDeg + courseDTO.startGate.getB().position.lngDeg) / 2.0;
|
||||
courseMiddleLinePoints[0] = LatLng.newInstance(p1Lat, p1Lng);
|
||||
courseMiddleLinePoints[1] = LatLng.newInstance(courseDTO.buoys.get(0).position.latDeg, courseDTO.buoys.get(0).position.lngDeg);
|
||||
if(courseMiddleLine == null) {
|
||||
PolylineOptions options = PolylineOptions.newInstance(/* clickable */false, /* geodesic */true);
|
||||
courseMiddleLine = new Polyline(courseMiddleLinePoints, /* color */ "#FF0000", /* width */ 1, /* opacity */1.0, options);
|
||||
map.addOverlay(courseMiddleLine);
|
||||
} else {
|
||||
courseMiddleLine.deleteVertex(1);
|
||||
courseMiddleLine.deleteVertex(0);
|
||||
courseMiddleLine.insertVertex(0, courseMiddleLinePoints[0]);
|
||||
courseMiddleLine.insertVertex(1, courseMiddleLinePoints[1]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(courseMiddleLine != null) {
|
||||
courseMiddleLine.deleteVertex(1);
|
||||
courseMiddleLine.deleteVertex(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1233,7 +1316,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
//Trigger auto-zoom if needed
|
||||
RaceMapZoomSettings zoomSettings = getSettings().getZoomSettings();
|
||||
if (!zoomSettings.contains(ZoomTypes.NONE) && zoomSettings.isZoomToSelectedCompetitors()) {
|
||||
if (!zoomSettings.containsZoomType(ZoomTypes.NONE) && zoomSettings.isZoomToSelectedCompetitors()) {
|
||||
zoomMapToNewBounds(zoomSettings.getNewBounds(this));
|
||||
}
|
||||
}
|
||||
@@ -1275,7 +1358,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
//Trigger auto-zoom if needed
|
||||
RaceMapZoomSettings zoomSettings = getSettings().getZoomSettings();
|
||||
if (!zoomSettings.contains(ZoomTypes.NONE) && zoomSettings.isZoomToSelectedCompetitors()) {
|
||||
if (!zoomSettings.containsZoomType(ZoomTypes.NONE) && zoomSettings.isZoomToSelectedCompetitors()) {
|
||||
zoomMapToNewBounds(zoomSettings.getNewBounds(this));
|
||||
}
|
||||
}
|
||||
@@ -1303,6 +1386,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
@Override
|
||||
public void updateSettings(RaceMapSettings newSettings) {
|
||||
boolean maneuverTypeSelectionChanged = false;
|
||||
boolean requiredRedraw = false;
|
||||
for (ManeuverType maneuverType : ManeuverType.values()) {
|
||||
if (newSettings.isShowManeuverType(maneuverType) != getSettings().isShowManeuverType(maneuverType)) {
|
||||
maneuverTypeSelectionChanged = true;
|
||||
@@ -1327,18 +1411,25 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
}
|
||||
if (newSettings.getTailLengthInMilliseconds() != getSettings().getTailLengthInMilliseconds()) {
|
||||
getSettings().setTailLengthInMilliseconds(newSettings.getTailLengthInMilliseconds());
|
||||
redraw();
|
||||
requiredRedraw = true;
|
||||
}
|
||||
if (newSettings.isShowOnlySelectedCompetitors() != getSettings().isShowOnlySelectedCompetitors()) {
|
||||
getSettings().setShowOnlySelectedCompetitors(newSettings.isShowOnlySelectedCompetitors());
|
||||
redraw();
|
||||
requiredRedraw = true;
|
||||
}
|
||||
if (!newSettings.getZoomSettings().equals(getSettings().getZoomSettings())) {
|
||||
getSettings().setZoomSettings(newSettings.getZoomSettings());
|
||||
if (!getSettings().getZoomSettings().contains(ZoomTypes.NONE)) {
|
||||
if (!getSettings().getZoomSettings().containsZoomType(ZoomTypes.NONE)) {
|
||||
zoomMapToNewBounds(getSettings().getZoomSettings().getNewBounds(this));
|
||||
}
|
||||
}
|
||||
if (!newSettings.getHelpLinesSettings().equals(getSettings().getHelpLinesSettings())) {
|
||||
getSettings().setHelpLinesSettings(newSettings.getHelpLinesSettings());
|
||||
requiredRedraw = true;
|
||||
}
|
||||
if(requiredRedraw) {
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public static class BoatsBoundsCalculator extends LatLngBoundsCalculatorForSelected {
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.sap.sailing.gwt.ui.shared.racemap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RaceMapHelpLinesSettings {
|
||||
|
||||
/**
|
||||
* Types of help lines on the map
|
||||
*/
|
||||
public enum HelpLineTypes {
|
||||
STARTLINE, FINISHLINE, ADVANTAGELINE, COURSEMIDDLELINE
|
||||
}
|
||||
|
||||
private ArrayList<HelpLineTypes> visibleHelpLines;
|
||||
|
||||
/**
|
||||
* Creates new RaceMapHelpLinesSettings with the {@link HelpLineTypes} <code>STARTLINE</code>, <code>FINISHLINE</code> and <code>ADVANTAGELINE</code>.<br />
|
||||
*/
|
||||
public RaceMapHelpLinesSettings() {
|
||||
visibleHelpLines = new ArrayList<HelpLineTypes>();
|
||||
visibleHelpLines.add(HelpLineTypes.STARTLINE);
|
||||
visibleHelpLines.add(HelpLineTypes.FINISHLINE);
|
||||
visibleHelpLines.add(HelpLineTypes.ADVANTAGELINE);
|
||||
visibleHelpLines.add(HelpLineTypes.COURSEMIDDLELINE);
|
||||
}
|
||||
|
||||
public RaceMapHelpLinesSettings(ArrayList<HelpLineTypes> visibleHelpLines) {
|
||||
this.visibleHelpLines = visibleHelpLines;
|
||||
}
|
||||
|
||||
public List<HelpLineTypes> getVisibleHelpLines() {
|
||||
return visibleHelpLines;
|
||||
}
|
||||
|
||||
public void setVisibleHelpLines(List<HelpLineTypes> visibleHelpLines) {
|
||||
this.visibleHelpLines = new ArrayList<HelpLineTypes>(visibleHelpLines);
|
||||
}
|
||||
|
||||
public boolean containsHelpLine(HelpLineTypes helpLineType) {
|
||||
return visibleHelpLines.contains(helpLineType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((visibleHelpLines == null) ? 0 : visibleHelpLines.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
RaceMapHelpLinesSettings other = (RaceMapHelpLinesSettings) obj;
|
||||
if (visibleHelpLines == null) {
|
||||
if (other.visibleHelpLines != null)
|
||||
return false;
|
||||
} else if (!visibleHelpLines.equals(other.visibleHelpLines))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -6,6 +6,7 @@ import java.util.Map;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.maps.client.MapWidget;
|
||||
import com.google.gwt.maps.client.geom.Point;
|
||||
import com.google.gwt.maps.client.geom.Size;
|
||||
import com.google.gwt.maps.client.overlay.Icon;
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
@@ -92,7 +93,8 @@ public class RaceMapImageManager {
|
||||
public void loadMapIcons(MapWidget map) {
|
||||
if(map != null) {
|
||||
buoyIcon = Icon.newInstance(resources.buoyIcon().getSafeUri().asString());
|
||||
buoyIcon.setIconAnchor(Point.newInstance(4, 4));
|
||||
buoyIcon.setIconSize(Size.newInstance(12, 17));
|
||||
buoyIcon.setIconAnchor(Point.newInstance(6, 15));
|
||||
|
||||
Icon tackToStarboardIcon = Icon
|
||||
.newInstance("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=T|00FF00|000000");
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import com.google.gwt.resources.client.ImageResource;
|
||||
|
||||
interface RaceMapResources extends ClientBundle {
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/coursemark.png")
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/buoy.png")
|
||||
ImageResource buoyIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/wind_combined.png")
|
||||
|
||||
+12
-1
@@ -14,7 +14,9 @@ public class RaceMapSettings {
|
||||
private boolean showOnlySelectedCompetitors = false;
|
||||
|
||||
private RaceMapZoomSettings zoomSettings;
|
||||
|
||||
|
||||
private RaceMapHelpLinesSettings helpLinesSettings;
|
||||
|
||||
private long tailLengthInMilliseconds = 100000l;
|
||||
|
||||
public RaceMapSettings() {
|
||||
@@ -25,6 +27,7 @@ public class RaceMapSettings {
|
||||
maneuverTypesToShow.add(ManeuverType.MARK_PASSING);
|
||||
|
||||
this.zoomSettings = new RaceMapZoomSettings();
|
||||
this.helpLinesSettings = new RaceMapHelpLinesSettings();
|
||||
}
|
||||
|
||||
public long getTailLengthInMilliseconds() {
|
||||
@@ -71,4 +74,12 @@ public class RaceMapSettings {
|
||||
this.zoomSettings = zoomSettings;
|
||||
}
|
||||
|
||||
public RaceMapHelpLinesSettings getHelpLinesSettings() {
|
||||
return helpLinesSettings;
|
||||
}
|
||||
|
||||
public void setHelpLinesSettings(RaceMapHelpLinesSettings helpLinesSettings) {
|
||||
this.helpLinesSettings = helpLinesSettings;
|
||||
}
|
||||
|
||||
}
|
||||
+35
-10
@@ -3,12 +3,11 @@ package com.sap.sailing.gwt.ui.shared.racemap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.dom.client.Style.FontWeight;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.FocusWidget;
|
||||
import com.google.gwt.user.client.ui.HasVerticalAlignment;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.LongBox;
|
||||
@@ -21,12 +20,14 @@ import com.sap.sailing.gwt.ui.client.DataEntryDialog.Validator;
|
||||
import com.sap.sailing.gwt.ui.client.ManeuverTypeFormatter;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.RaceMapZoomSettings.ZoomTypes;
|
||||
|
||||
public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<RaceMapSettings> {
|
||||
//Initializing the lists to prevent a null pointer exception in the first validation call
|
||||
private List<Pair<CheckBox, ManeuverType>> checkboxAndManeuverType = new ArrayList<Pair<CheckBox, ManeuverType>>();
|
||||
private List<Pair<CheckBox, ZoomTypes>> checkboxAndZoomType = new ArrayList<Pair<CheckBox,ZoomTypes>>();
|
||||
private List<Pair<CheckBox, HelpLineTypes>> checkboxAndHelpLineType = new ArrayList<Pair<CheckBox,HelpLineTypes>>();
|
||||
private CheckBox zoomOnlyToSelectedCompetitors = new CheckBox();
|
||||
private CheckBox checkBoxDouglasPeuckerPoints = new CheckBox();
|
||||
private CheckBox showOnlySelectedCompetitors = new CheckBox();
|
||||
@@ -46,17 +47,19 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
public Widget getAdditionalWidget(DataEntryDialog<?> dialog) {
|
||||
VerticalPanel vp = new VerticalPanel();
|
||||
HorizontalPanel labelAndTailLengthBoxPanel = new HorizontalPanel();
|
||||
labelAndTailLengthBoxPanel.add(new Label(stringMessages.tailLength()));
|
||||
labelAndTailLengthBoxPanel.setSpacing(5);
|
||||
Label tailLengthLabel = new Label(stringMessages.tailLength() + ":");
|
||||
labelAndTailLengthBoxPanel.add(tailLengthLabel);
|
||||
labelAndTailLengthBoxPanel.setCellVerticalAlignment(tailLengthLabel, HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
tailLengthBox = dialog.createLongBox((int) (initialSettings.getTailLengthInMilliseconds() / 1000), 4);
|
||||
labelAndTailLengthBoxPanel.add(tailLengthBox);
|
||||
labelAndTailLengthBoxPanel.setCellVerticalAlignment(tailLengthBox, HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
vp.add(labelAndTailLengthBoxPanel);
|
||||
showOnlySelectedCompetitors = dialog.createCheckbox(stringMessages.showOnlySelected());
|
||||
showOnlySelectedCompetitors.setValue(initialSettings.isShowOnlySelectedCompetitors());
|
||||
vp.add(showOnlySelectedCompetitors);
|
||||
|
||||
Label zoomLabel = new Label(stringMessages.zoom());
|
||||
zoomLabel.getElement().getStyle().setFontWeight(FontWeight.BOLD);
|
||||
zoomLabel.getElement().getStyle().setPaddingTop(1, Unit.EM);
|
||||
Label zoomLabel = dialog.createHeadlineLabel(stringMessages.zoom());
|
||||
vp.add(zoomLabel);
|
||||
|
||||
HorizontalPanel labelAndZoomSettingsPanel = new HorizontalPanel();
|
||||
@@ -66,7 +69,7 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
disableOnlySelectedWhenAreFalse = new ArrayList<CheckBox>();
|
||||
for (ZoomTypes zoomType : ZoomTypes.values()) {
|
||||
if (zoomType != ZoomTypes.NONE) {
|
||||
CheckBox cb = dialog.createCheckbox(ZoomTypeFormatter.format(zoomType, stringMessages));
|
||||
CheckBox cb = dialog.createCheckbox(RaceMapSettingsTypeFormatter.formatZoomType(zoomType, stringMessages));
|
||||
cb.setValue(initialSettings.getZoomSettings().getTypesToConsiderOnZoom().contains(zoomType), true);
|
||||
checkboxAndZoomType.add(new Pair<CheckBox, ZoomTypes>(cb, zoomType));
|
||||
zoomSettingsBoxesPanel.add(cb);
|
||||
@@ -92,9 +95,7 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
//Run zoomSettingsChanged to set the checkboxes to their correct state
|
||||
zoomSettingsChanged();
|
||||
|
||||
Label maneuversLabel = new Label(stringMessages.maneuverTypes());
|
||||
maneuversLabel.getElement().getStyle().setFontWeight(FontWeight.BOLD);
|
||||
maneuversLabel.getElement().getStyle().setPaddingTop(1, Unit.EM);
|
||||
Label maneuversLabel = dialog.createHeadlineLabel(stringMessages.maneuverTypes());
|
||||
vp.add(maneuversLabel);
|
||||
for (ManeuverType maneuverType : ManeuverType.values()) {
|
||||
CheckBox checkbox = dialog.createCheckbox(ManeuverTypeFormatter.format(maneuverType, stringMessages));
|
||||
@@ -105,6 +106,19 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
checkBoxDouglasPeuckerPoints = dialog.createCheckbox(stringMessages.douglasPeuckerPoints());
|
||||
checkBoxDouglasPeuckerPoints.setValue(initialSettings.isShowDouglasPeuckerPoints());
|
||||
vp.add(checkBoxDouglasPeuckerPoints);
|
||||
|
||||
Label helpLinesLabel = dialog.createHeadlineLabel(stringMessages.helpLines());
|
||||
vp.add(helpLinesLabel);
|
||||
|
||||
VerticalPanel helpLineSettingsBoxesPanel = new VerticalPanel();
|
||||
for (HelpLineTypes helpLineType : HelpLineTypes.values()) {
|
||||
CheckBox cb = dialog.createCheckbox(RaceMapSettingsTypeFormatter.formatHelpLineType(helpLineType, stringMessages));
|
||||
cb.setValue(initialSettings.getHelpLinesSettings().containsHelpLine(helpLineType), true);
|
||||
checkboxAndHelpLineType.add(new Pair<CheckBox, HelpLineTypes>(cb, helpLineType));
|
||||
helpLineSettingsBoxesPanel.add(cb);
|
||||
}
|
||||
vp.add(helpLineSettingsBoxesPanel);
|
||||
|
||||
return vp;
|
||||
}
|
||||
|
||||
@@ -132,6 +146,7 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
result.showManeuverType(p.getB(), p.getA().getValue());
|
||||
}
|
||||
result.setZoomSettings(getZoomSettings());
|
||||
result.setHelpLinesSettings(getHelpLinesSettings());
|
||||
result.setShowDouglasPeuckerPoints(checkBoxDouglasPeuckerPoints.getValue());
|
||||
result.setShowOnlySelectedCompetitors(showOnlySelectedCompetitors.getValue());
|
||||
result.setTailLengthInMilliseconds(tailLengthBox.getValue() == null ? -1 : tailLengthBox.getValue()*1000l);
|
||||
@@ -153,6 +168,16 @@ public class RaceMapSettingsDialogComponent implements SettingsDialogComponent<R
|
||||
return new RaceMapZoomSettings(zoomTypes, zoomOnlyToSelectedCompetitors.getValue());
|
||||
}
|
||||
|
||||
private RaceMapHelpLinesSettings getHelpLinesSettings() {
|
||||
ArrayList<HelpLineTypes> helpLineTypes = new ArrayList<HelpLineTypes>();
|
||||
for (Pair<CheckBox, HelpLineTypes> pair : checkboxAndHelpLineType) {
|
||||
if (pair.getA().getValue()) {
|
||||
helpLineTypes.add(pair.getB());
|
||||
}
|
||||
}
|
||||
return new RaceMapHelpLinesSettings(helpLineTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Validator<RaceMapSettings> getValidator() {
|
||||
return new Validator<RaceMapSettings>() {
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.sap.sailing.gwt.ui.shared.racemap;
|
||||
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.RaceMapHelpLinesSettings.HelpLineTypes;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.RaceMapZoomSettings.ZoomTypes;
|
||||
|
||||
public class RaceMapSettingsTypeFormatter {
|
||||
public static String formatZoomType(ZoomTypes zoomType, StringMessages stringConstants) {
|
||||
switch (zoomType) {
|
||||
case NONE:
|
||||
return stringConstants.autoZoomOff();
|
||||
case BOATS:
|
||||
return stringConstants.autoZoomToBoats();
|
||||
case TAILS:
|
||||
return stringConstants.autoZoomToTails();
|
||||
case BUOYS:
|
||||
return stringConstants.autoZoomToBuoys();
|
||||
case WINDSENSORS:
|
||||
return stringConstants.autoZoomToWindSensors();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String formatHelpLineType(HelpLineTypes helpLineType, StringMessages stringConstants) {
|
||||
switch (helpLineType) {
|
||||
case STARTLINE:
|
||||
return stringConstants.startLine();
|
||||
case FINISHLINE:
|
||||
return stringConstants.finishLine();
|
||||
case ADVANTAGELINE:
|
||||
return stringConstants.advantageLine();
|
||||
case COURSEMIDDLELINE:
|
||||
return stringConstants.courseMiddleLine();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -5,13 +5,14 @@ import java.util.List;
|
||||
|
||||
import com.google.gwt.maps.client.geom.LatLngBounds;
|
||||
|
||||
/**
|
||||
* @author Lennart Hensler (D054527)
|
||||
*/
|
||||
public class RaceMapZoomSettings {
|
||||
|
||||
/**
|
||||
* The auto-zoom types for a {@link RaceMap}.<br />
|
||||
* Each zoom type has a {@link LatLngBoundsCalculator}, which calculates the new bounds for a map.
|
||||
* @author Lennart Hensler (D054527)
|
||||
*
|
||||
*/
|
||||
public enum ZoomTypes {
|
||||
NONE(null), WINDSENSORS(new RaceMap.WindSensorsBoundsCalculator()), BOATS(new RaceMap.BoatsBoundsCalculator()),
|
||||
@@ -27,13 +28,13 @@ public class RaceMapZoomSettings {
|
||||
return calculater.calculateNewBounds(forMap);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private ArrayList<ZoomTypes> typesToConsiderOnZoom;
|
||||
private boolean zoomToSelectedCompetitors;
|
||||
|
||||
/**
|
||||
* Creates new RaceMapZoomSettings with the {@link ZoomTypes} <code>BOATS</code> and <code>TAILS</code>.<br />
|
||||
* The attritbute <code>zoomToSelectedCompetitors</code> will be <code>false</code>.
|
||||
* The attribute <code>zoomToSelectedCompetitors</code> will be <code>false</code>.
|
||||
*/
|
||||
public RaceMapZoomSettings() {
|
||||
typesToConsiderOnZoom = new ArrayList<ZoomTypes>();
|
||||
@@ -85,7 +86,7 @@ public class RaceMapZoomSettings {
|
||||
return zoomToSelectedCompetitors;
|
||||
}
|
||||
|
||||
public boolean contains(ZoomTypes zoomType) {
|
||||
public boolean containsZoomType(ZoomTypes zoomType) {
|
||||
return typesToConsiderOnZoom.contains(zoomType);
|
||||
}
|
||||
|
||||
@@ -116,5 +117,4 @@ public class RaceMapZoomSettings {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package com.sap.sailing.gwt.ui.shared.racemap;
|
||||
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.RaceMapZoomSettings.ZoomTypes;
|
||||
|
||||
public class ZoomTypeFormatter {
|
||||
public static String format(ZoomTypes zoomType, StringMessages stringConstants) {
|
||||
switch (zoomType) {
|
||||
case NONE:
|
||||
return stringConstants.autoZoomOff();
|
||||
case BOATS:
|
||||
return stringConstants.autoZoomToBoats();
|
||||
case TAILS:
|
||||
return stringConstants.autoZoomToTails();
|
||||
case BUOYS:
|
||||
return stringConstants.autoZoomToBuoys();
|
||||
case WINDSENSORS:
|
||||
return stringConstants.autoZoomToWindSensors();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Executable → Regular
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 3.4 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 151 B |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 175 B |
Reference in new issue
Block a user