getAllCompetitors(Fleet fleet);
/**
- * Provides the combined set of marks from all {@link #getTrackedRace(Fleet) tracked races attached to this
- * column} or, in case a fleet does not have a tracked race attached, the marks registered through the
+ * Provides the combined set of marks from the courses of all {@link #getTrackedRace(Fleet) tracked races attached
+ * to this column} or, in case a fleet does not have a tracked race attached, the marks registered through the
* {@link #getRegattaLog() regatta log} for the regatta-like object to which this column belongs (flexible
- * leaderboard or regatta).
+ * leaderboard or regatta) and used in a {@link RaceLogCourseDesignChangedEvent}.
+ *
+ *
+ * See also {@link #getAvailableMarks()}.
*/
- Iterable getAllMarks();
+ Iterable getCourseMarks();
/**
- * Same as {@link #getAllMarks()}, but restricted to the single race identified by the fleet parameter.
+ * Same as {@link #getCourseMarks()}, but restricted to the single race identified by the fleet parameter
+ * and in case of an existing {@link TrackedRace} restricted to the marks actually used by the
+ * {@link TrackedRace#getRace() race's} {@link RaceDefinition#getCourse() course}.
*/
- Iterable getMarks(Fleet fleet);
+ Iterable getCourseMarks(Fleet fleet);
+
+ /**
+ * Provides the set of marks available for use in course designs for races in this column. This includes, in
+ * particular, those marks defined on the {@link RegattaLog} using {@link RegattaLogDefineMarkEvent} objects.
+ * Additionally, all marks that any of the {@link TrackedRace}s attached to this column have "seen" (as
+ * returned by their {@link TrackedRace#getMarks()} method) will be added.
+ */
+ Iterable getAvailableMarks();
+
+ /**
+ * Like {@link #getAvailableMarks()}, but restricted to the race identified by the {@code fleet} parameter. While
+ * marks from the {@link RegattaLog} are available to all races of the regatta and therefore also to all races in
+ * this column, in case a {@link TrackedRace} exists for the {@code fleet}, only that race's
+ * {@link TrackedRace#getMarks() marks} will be added to the result.
+ */
+ Iterable getAvailableMarks(Fleet fleet);
/**
* Returns the competitor set registered in the race column's race log associated to the passed fleet. If competitor
@@ -345,4 +368,5 @@ public interface RaceColumn extends Named {
* {@link MetaLeaderboard}
*/
void deregisterCompetitors(Iterable currentlyRegisteredCompetitors, Fleet fleet) throws CompetitorRegistrationOnRaceLogDisabledException;
+
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java
index bc797de581b..698922f3a08 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/AbstractRaceColumn.java
@@ -321,30 +321,16 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem
}
@Override
- public Iterable getAllMarks() {
+ public Iterable getCourseMarks() {
final Set result = new HashSet<>();
- // if the marks from the regatta log are to be used because a slot has no TrackedRace attached,
- // those regatta log marks only need to be added to the result once
- boolean regattaLogMarksAlreadyAdded = false;
for (Fleet fleet : getFleets()) {
- TrackedRace trackedRace = getTrackedRace(fleet);
- if (trackedRace != null) {
- for (Waypoint waypoint : trackedRace.getRace().getCourse().getWaypoints()) {
- Util.addAll(waypoint.getMarks(), result);
- }
- } else if (!regattaLogMarksAlreadyAdded) {
- // if no tracked race is found, use marks from regatta log
- RegattaLog regattaLog = getRegattaLog();
- Collection viaRegattaLog = new RegattaLogDefinedMarkAnalyzer(regattaLog).analyze();
- result.addAll(viaRegattaLog);
- regattaLogMarksAlreadyAdded = true;
- }
+ Util.addAll(getCourseMarks(fleet), result);
}
return result;
}
@Override
- public Iterable getMarks(Fleet fleet) {
+ public Iterable getCourseMarks(Fleet fleet) {
final Set result = new HashSet<>();
final TrackedRace trackedRace = getTrackedRace(fleet);
if (trackedRace != null) {
@@ -353,19 +339,45 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem
}
} else {
// if no tracked race is found, use marks from race course if present in racelog
- // if not the marks defined in the regatta log
LastPublishedCourseDesignFinder courseDesginFinder = new LastPublishedCourseDesignFinder(getRaceLog(fleet));
final CourseBase courseBase = courseDesginFinder.analyze();
if (courseBase != null) {
- // TODO why do we collect the marks from the course definition here but not in getAllMarks()?
courseBase.getWaypoints().forEach((waypoint) -> Util.addAll(waypoint.getMarks(), result));
- } else {
- Util.addAll(new RegattaLogDefinedMarkAnalyzer(getRegattaLog()).analyze(), result);
}
}
return result;
}
+ @Override
+ public Iterable getAvailableMarks() {
+ final Set result = new HashSet<>();
+ // add the marks from the regatta log to the result
+ RegattaLog regattaLog = getRegattaLog();
+ Collection viaRegattaLog = new RegattaLogDefinedMarkAnalyzer(regattaLog).analyze();
+ result.addAll(viaRegattaLog);
+ for (Fleet fleet : getFleets()) {
+ TrackedRace trackedRace = getTrackedRace(fleet);
+ if (trackedRace != null) {
+ Util.addAll(trackedRace.getMarks(), result);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public Iterable getAvailableMarks(Fleet fleet) {
+ final Set result = new HashSet<>();
+ // add the marks from the regatta log to the result
+ RegattaLog regattaLog = getRegattaLog();
+ Collection viaRegattaLog = new RegattaLogDefinedMarkAnalyzer(regattaLog).analyze();
+ result.addAll(viaRegattaLog);
+ TrackedRace trackedRace = getTrackedRace(fleet);
+ if (trackedRace != null) {
+ Util.addAll(trackedRace.getMarks(), result);
+ }
+ return result;
+ }
+
@Override
public void enableCompetitorRegistrationOnRaceLog(Fleet fleet) {
TimePoint now = MillisecondsTimePoint.now();
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java
index 0583a1db0df..f9016dbef70 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java
@@ -229,12 +229,22 @@ public class MetaLeaderboardColumn extends SimpleAbstractRaceColumn implements R
}
@Override
- public Iterable getAllMarks() {
+ public Iterable getCourseMarks() {
return Collections.emptySet();
}
@Override
- public Iterable getMarks(Fleet fleet) {
+ public Iterable getCourseMarks(Fleet fleet) {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Iterable getAvailableMarks() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Iterable getAvailableMarks(Fleet fleet) {
return Collections.emptySet();
}
diff --git a/java/com.sap.sailing.gwt.ui/Leaderboard.css b/java/com.sap.sailing.gwt.ui/Leaderboard.css
index 2b70414a4b7..92b5cf8adae 100755
--- a/java/com.sap.sailing.gwt.ui/Leaderboard.css
+++ b/java/com.sap.sailing.gwt.ui/Leaderboard.css
@@ -54,7 +54,7 @@ table {
.leaderboardContent td, .leaderboardContent th {
vertical-align: bottom;
line-height: 1.3;
- padding-top: 2px;
+/* padding-top: 2px; */
}
.leaderboardContent-toolbar {
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AdminConsoleTable.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AdminConsoleTable.css
index 1ae3a5988c9..15de74761f6 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AdminConsoleTable.css
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AdminConsoleTable.css
@@ -1,162 +1,164 @@
-.cellTableWidget {
- border-left: 1px solid #c9caca;
- border-top: 1px solid #c9caca;
-}
-
-/** v-align images in the table header
- * grey background for table header
- */
-.cellTableHeader {
- position: relative;
- vertical-align: middle;
- background-color: #e5e5e5;
- border-right: 1px solid #ffffff !important;
- border-top: none !important;
- border-bottom: 1px solid #c9caca !important;
- padding: 3px 12px;
- text-align: center;
-}
-
-.cellTableFirstColumnHeader {
- position: relative;
- vertical-align: middle;
- background-color: #e5e5e5;
- border-left: none !important;
- border-right: 1px solid #ffffff !important;
- border-top: none !important;
- border-bottom: 1px solid #c9caca !important;
- padding: 3px 12px;
- text-align: center;
-}
-
-.cellTableLastColumnHeader {
- position: relative;
- vertical-align: middle;
- background-color: #e5e5e5;
- border-right: 1px solid #c9caca !important;
- border-top: none !important;
- border-bottom: 1px solid #c9caca !important;
- padding: 3px 12px;
- text-align: center;
-}
-
-.cellTableHeader > span > img:first-child {
- position: relative;
- vertical-align: middle;
-}
-
-.cellTableEvenRow {
- border-bottom: 1px solid #e5e5e5;
- background-color: rgba(255,255,255,0.5);
-}
-
-.cellTableEvenRowCell {
- border-right: 1px solid #c9caca !important;
- border-left: none;
- border-top: none !important;
- border-bottom: 1px solid #c9caca !important;
- padding: 5px 10px 5px !important;
- white-space: nowrap;
-}
-
-.cellTableOddRow {
- border-bottom: 1px solid #e5e5e5;
- background-color: rgba(242,242,242,0.5);
-}
-
-.cellTableOddRowCell {
- border-left: none !important;
- border-right: 1px solid #c9caca !important;
- border-top: none !important;
- border-bottom: 1px solid #c9caca !important;
- padding: 5px 10px 5px !important;
- white-space: nowrap;
-}
-
-.cellTableHoveredRow {
- background-color: rgba(229,242,249,0.5);
- border-bottom: 1px solid #e5e5e5;
-}
-
-.cellTableSelectedRow {
- color: #000000;
- background-color: rgba(229,242,249,0.5);
- border-right: 2px solid #21a0e4 !important;
- border-left: 2px solid #21a0e4 !important;
- border: 2px solid #21a0e4;
-}
-
-.cellTableSelectedRow > td:FIRST-CHILD {
- border-left: 2px solid rgba(33,160,228,0.5) !important;
-}
-
-.cellTableSelectedRow > td:LAST-CHILD {
- border-right: 2px solid rgba(33,160,228,0.5) !important;
-}
-
-.cellTableSelectedRowCell {
- border-left: none;
- border-right: 1px solid #e5e5e5;
- border-top: 2px solid #21a0e4 !important;
- border-bottom: 2px solid #21a0e4 !important;
-}
-
-.cellTableRaceColumnHeader {
- background-color: #e0e0e0;
- padding: 3px 12px;
-}
-
-.cellTableLegColumnHeader {
- background-color: #efefef;
- padding: 3px 12px;
-}
-
-.cellTableLegDetailColumnHeader {
- background-color: #f4f5f6;
- padding: 3px 12px;
-}
-
-.cellTableRaceColumn {
- background-color: #e0e0e0 !important;
-}
-
-.cellTableLegColumn {
- background-color: #efefef !important;
-}
-
-.cellTableLegDetailColumn {
- background-color: #ffffff !important;
-}
-
-.cellTableTotalColumn {
- background-color: #e0e0e0 !important;
-}
-
-.cellTableCheckboxColumnCell {
- padding: 1px 1px 1px !important;
- vertical-align: middle !important;
- text-align: center;
-}
-
-.cellTableCheckboxSelected {
- margin-left: 0px; /* account for the selection border that pushes a selected checkbox to the side */
- margin-top: 0px;
- margin-bottom: 0px;
- margin-right: 2px;
- height: 18px;
- width: 18px;
- border: solid 1px #acacac;
- background-color: #cacaca;
- vertical-align: middle;
-}
-
-.cellTableCheckboxDeselected {
- margin-left: 2px; /* account for the selection border that pushes a selected checkbox to the side */
- margin-top: 0px;
- margin-bottom: 0px;
- margin-right: 2px;
- border: solid 1px #acacac;
- height: 18px;
- width: 18px;
- vertical-align: middle;
-}
+.cellTableWidget {
+ border-left: 1px solid #c9caca;
+ border-top: 1px solid #c9caca;
+ border-collapse: collapse;
+}
+
+
+
+/** v-align images in the table header
+ * grey background for table header
+ */
+.cellTableHeader {
+ position: relative;
+ vertical-align: bottom;
+ background-color: #e5e5e5;
+ border-right: 0px solid #c9caca !important;
+ border-top: none !important;
+ border-bottom: 1px solid #c9caca !important;
+ padding: 3px 5px;
+ padding-bottom: 5px;
+ text-align: center;
+ text-shadow: none !important;
+}
+
+.cellTableFirstColumnHeader {
+ position: relative;
+ vertical-align: bottom;
+ background-color: #e5e5e5;
+ border-left: none !important;
+ border-right: 1px solid #c9caca !important;
+ border-top: none !important;
+ border-bottom: 1px solid #c9caca !important;
+ text-align: center;
+}
+
+.cellTableLastColumnHeader {
+ position: relative;
+ vertical-align: bottom;
+ background-color: #e5e5e5;
+ border-right: 1px solid #c9caca !important;
+ border-top: none !important;
+ border-bottom: 1px solid #c9caca !important;
+ text-align: center;
+}
+
+.cellTableHeader > span > img:first-child {
+ position: relative;
+ vertical-align: middle;
+}
+
+.cellTableEvenRow {
+ background-color: rgba(255,255,255,0.5);
+}
+
+.cellTableOddRow {
+ background-color: rgba(242,242,242,0.5);
+}
+
+.cellTableSelectedRow {
+ color: #000000;
+ background-color: rgba(229,242,249,0.6);
+}
+
+.cellTableSelectedRow > td:FIRST-CHILD {
+ border-left: 1px solid rgba(33,160,228,0.6) !important;
+}
+
+.cellTableSelectedRow > td:LAST-CHILD {
+ border-right: 1px solid rgba(33,160,228,0.6) !important;
+}
+.cellTableSelectedRow > td {
+}
+
+.cellTableCell {
+ overflow: inherit;
+ font-size: 12px !important;
+ line-height: 1.5em !important;
+}
+.cellTableSelectedRowCell {
+ border-top: 2px double #21a0e4 !important;
+ border-bottom: 2px double #21a0e4 !important;
+ padding: 7px 7px 6px 7px !important;
+}
+
+.cellTableEvenRowCell, .cellTableOddRowCell {
+ border: 1px solid #c9caca;
+ padding: 7px;
+ white-space: nowrap;
+}
+
+.cellTableCheckboxColumnCell {
+ padding: 1px 1px 1px !important;
+ vertical-align: middle !important;
+ text-align: center;
+}
+
+.cellTableCheckboxSelected {
+ margin: auto auto;
+ height: 13px;
+ width: 13px;
+ border: 1px solid #fcbb22;
+ background-color: #fcbb22;
+ vertical-align: middle;
+}
+
+.cellTableCheckboxDeselected {
+ margin: auto auto;
+ height: 13px;
+ width: 13px;
+ border: solid 1px #acacac;
+ vertical-align: middle;
+}
+
+.cellTableHoveredRow {
+ background-color: rgba(229,242,249,0.5);
+ border-bottom: 1px solid #e5e5e5;
+}
+
+
+.cellTableRaceColumnHeader {
+ background-color: #e5e5e5;
+}
+
+.cellTableRaceColumnHeader span:first-child{
+ display: block;
+}
+
+.cellTableRaceColumnHeader span input, .cellTableRaceColumnHeader span img{
+ margin: 0 auto;
+}
+
+.cellTableRaceColumnHeader span img {
+ float: left;
+}
+
+.cellTableLegColumnHeader {
+ background-color: #efefef;
+
+}
+
+.cellTableLegDetailColumnHeader {
+ background-color: #f4f5f6;
+}
+
+.cellTableRaceColumnHeader span > div, .cellTableLegColumnHeader span > div {
+ width: 19px !important;
+ height: 19px !important;
+}
+
+.cellTableRaceColumn {
+ background-color: #e0e0e0 !important;
+}
+
+.cellTableLegColumn {
+ background-color: #efefef !important;
+}
+
+.cellTableLegDetailColumn {
+ background-color: #ffffff !important;
+}
+
+.cellTableTotalColumn {
+ background-color: #e0e0e0 !important;
+}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DeviceConfigurationCreateSingleMatcherDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DeviceConfigurationCreateSingleMatcherDialog.java
index 1316ae6742f..e20bace0111 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DeviceConfigurationCreateSingleMatcherDialog.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DeviceConfigurationCreateSingleMatcherDialog.java
@@ -40,20 +40,22 @@ public class DeviceConfigurationCreateSingleMatcherDialog extends DataEntryDialo
}
- private TextBox identifierBox;
+ private final TextBox identifierBox;
+ private final StringMessages stringMessages;
public DeviceConfigurationCreateSingleMatcherDialog(StringMessages stringMessages,
Validator validator,
com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback callback) {
super(stringMessages.createDeviceConfiguration(), stringMessages.forWhichDeviceShouldConfigurationApply(),
stringMessages.create(), stringMessages.cancel(), validator, callback);
+ this.stringMessages = stringMessages;
this.identifierBox = createTextBox("");
}
@Override
protected Widget getAdditionalWidget() {
Grid grid = new Grid(1, 2);
- grid.setWidget(0, 0, createLabel("Identifier"));
+ grid.setWidget(0, 0, createLabel(stringMessages.raceManagerDeviceName()));
grid.setWidget(0, 1, identifierBox);
return grid;
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
index d690033ee0d..a1994551b29 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
@@ -176,6 +176,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String secondsUnit();
String secondsPerNauticalMileUnit();
String metersUnit();
+ String degreesUnit();
@Override
String close();
String compareCompetitors();
@@ -1261,9 +1262,9 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String valueDescending();
String sortBy();
- String dashboardWindBotLoadingText();
- String dashboardWindBotLoadingMessage();
- String dashboardWindBotNotAvailable();
+ String dashboardHeader();
+ String dashboardNoWindBotAvailableHeader();
+ String dashboardNoWindBotAvailableMessage();
String dashboardWindBot();
String dashboardTrueWindSpeed();
String dashboardTrueWindDirection();
@@ -1274,10 +1275,17 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String dashboardAverageWindMinutes(int minutes);
String dashboardWindChartHint();
+ String dashboardSelectCompetitor();
+ String dashboardStartAnalysesHeader();
String dashboardNewStartAnalysisAvailable();
-
- String dashboardStartlineAdvantagesByWind();
- String dashboardStartlineAdvantageByGeometry();
+ String dashboardNoStartAnalysesAvailableHeader();
+ String dashboardNoStartAnalysesAvailableMessage();
+ String dashboardNoStartlineAdvantagesByWindAvailableHeader();
+ String dashboardNoStartlineAdvantagesByWindAvailableMessage();
+ String dashboardNoStartlineAdvantagesByGeometryAvailableHeader();
+ String dashboardNoStartlineAdvantagesByGeometryAvailableMessage();
+ String dashboardStartlineAdvantagesByWindHeader();
+ String dashboardStartlineAdvantageByGeometryHeader();
String dashboardRankAtFirstMark();
String dashboardTeam();
String dashboardDistanceToLineInM();
@@ -1490,4 +1498,5 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String qrSync();
String thereIsNoIdentifierSet();
String couldNotObtainAccessTokenForUser(String message);
+ String raceManagerDeviceName();
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
index a8e7a0c6851..ae1417c1b07 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
@@ -179,6 +179,7 @@ in=in
secondsUnit=s
secondsPerNauticalMileUnit=s/NM
metersUnit=m
+degreesUnit=°
close=Close
compareCompetitors=Compare competitors
description=Description
@@ -1225,9 +1226,9 @@ groupName=Group Name
valueAscending=Value (Ascending)
valueDescending=Value (Descending)
sortBy=Sort by
-dashboardWindBotLoadingText=Waiting for wind bot data...
-dashboardWindBotLoadingMessage=Depending on your connection this operation might take some minutes to complete the first time. It can also take some time if there is no data available right now.
-dashboardWindBotNotAvailable=Wind bot not available.
+dashboardHeader=Dashboard
+dashboardNoWindBotAvailableHeader=Wind Bot is not available.
+dashboardNoWindBotAvailableMessage=To receive live wind data from wind measurement units, ensure that the wind bot is switched on and connected to the SAP Sailing Analytics.
dashboardWindBot=Wind Bot
dashboardTrueWindSpeed=TWS
dashboardTrueWindDirection=TWD
@@ -1237,9 +1238,17 @@ dashboardLiveWind=live
dashboardAverageWind=average
dashboardAverageWindMinutes=({0} minutes)
dashboardWindChartHint=Tap on chart to change interval
+dashboardSelectCompetitor=Select Competitor
+dashboardStartAnalysesHeader=Start Analyses
dashboardNewStartAnalysisAvailable=New start analysis available
-dashboardStartlineAdvantagesByWind=Startline advantage by wind
-dashboardStartlineAdvantageByGeometry=Startline advantage by geometry
+dashboardNoStartAnalysesAvailableHeader=No Start Analyses available.
+dashboardNoStartAnalysesAvailableMessage=There is a Start Analysis created from each race start. Please stand by till racing has been started.
+dashboardNoStartlineAdvantagesByWindAvailableHeader=No Startline Advantages available.
+dashboardNoStartlineAdvantagesByWindAvailableMessage=For calculating the startline advantage there needs to be a course set by the race commitee.
+dashboardNoStartlineAdvantagesByGeometryAvailableHeader=No Startline Advantage available.
+dashboardNoStartlineAdvantagesByGeometryAvailableMessage=For calculating the startline advantage there needs to be a course set by the race commitee.
+dashboardStartlineAdvantagesByWindHeader=Startline Advantages by Wind
+dashboardStartlineAdvantageByGeometryHeader=Startline Advantage by Geometry
dashboardRankAtFirstMark=Rank at first mark
dashboardTeam=Team
dashboardDistanceToLineInM=Distance to line in m
@@ -1435,7 +1444,6 @@ profile=Profile
showOnlyCompetitorsOfLog=Show only competitors registered in Log
confirmLosingCompetitorEditsWhenTogglingLogBasedView=This will reset your current, unsaved changes to the competitors.\nDo you really want to continue?
removalOfMarkDisabledMayBeUsedInRaces=Removal deavticated, marks are used in races {0}
-pleaseCreateAtLeastOneMappingBy=Plase create at list one mapping by first selecting a track on the left hand side and then selecting a mark or competitor on the right hand side
createDefaultLeaderboardGroup=Would you like to create a default LeaderboardGroup for your event?
pleaseCreateAtLeastOneMappingBy=Please create at least one mapping by first selecting a track on the left hand side and then selecting a mark or competitor on the right hand side
matcherType=Matcher type
@@ -1457,4 +1465,5 @@ defaultLocale=Default
defaultSailorsInfoLinkInfoText=The default link is used unless a language specific overwrite exists. If no default exists, there will be no link for languages that do not explicitly have one set.
qrSync=QR-Sync
thereIsNoIdentifierSet=There is no identifier set.
-couldNotObtainAccessTokenForUser=Could not obtain access token for user {0}
\ No newline at end of file
+couldNotObtainAccessTokenForUser=Could not obtain access token for user {0}
+raceManagerDeviceName=Device Name
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties
index a892380ba8d..e9bec87776f 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties
@@ -181,6 +181,7 @@ in=in
secondsUnit=s
secondsPerNauticalMileUnit=s/sm
metersUnit=m
+degreesUnit=°
close=Schließen
compareCompetitors=Teilnehmer vergleichen
description=Beschreibung
@@ -1212,9 +1213,9 @@ groupName=Gruppename
valueAscending=Wert (Aufsteigend)
valueDescending=Wert (Absteigend)
sortBy=Sortiert nach
-dashboardWindBotLoadingText=Lade Windmesser Daten ...
-dashboardWindBotLoadingMessage=Je nach Qualität Ihrer Verbindung kann dieser Vorgang ein paar Minuten dauern.
-dashboardWindBotNotAvailable=Keine Verbindung zu Windmesser.
+dashboardHeader=Dashboard
+dashboardNoWindBotAvailableHeader=Wind Bot nicht verfügbar.
+dashboardNoWindBotAvailableMessage=Um live Daten von Wind Messgeräten zu empfangen, muss der Wind Bot mit der SAP Sailing Analytics verknüpft sein.
dashboardWindBot=Windmesser
dashboardTrueWindSpeed=Wind Geschwindigkeit
dashboardTrueWindDirection=Wind Richtung
@@ -1224,9 +1225,17 @@ dashboardLiveWind=live
dashboardAverageWind=average
dashboardAverageWindMinutes=({0} minutes)
dashboardWindChartHint=Auf Chart drücken um Interval zu ändern
-dashboardNewStartAnalysisAvailable=Neue Startanalyse verfügbar
-dashboardStartlineAdvantagesByWind=Startlininien Vorteil nach Wind
-dashboardStartlineAdvantageByGeometry=Startlininien Vorteil nach Geometrie
+dashboardSelectCompetitor=Segler auswählen
+dashboardStartAnalysesHeader=Start Analysen
+dashboardNewStartAnalysisAvailable=Neue Start Analyse verfügbar.
+dashboardNoStartAnalysesAvailableHeader=Keine Start Analysen verfügbar.
+dashboardNoStartAnalysesAvailableMessage=Es wird eine Start Analyse für jeden Renn Start erstellt. Bitte warten bis die Rennen starten.
+dashboardNoStartlineAdvantagesByWindAvailableHeader=Kein Startlinien Vorteil verfügbar.
+dashboardNoStartlineAdvantagesByWindAvailableMessage=Um den Startlinien Vorteil zu berrechnen muss die Regattaleitung einen Kurs in im Race Manager gesetzt haben.
+dashboardNoStartlineAdvantagesByGeometryAvailableHeader=Keine Startlinien Vorteile verfügbar.
+dashboardNoStartlineAdvantagesByGeometryAvailableMessage=Um den Startlinien Vorteile zu berrechnen muss die Regattaleitung einen Kurs in im Race Manager gesetzt haben.
+dashboardStartlineAdvantagesByWindHeader=Startlinien Vorteile nach Wind
+dashboardStartlineAdvantageByGeometryHeader=Startlinien Vorteile nach Geometrie
dashboardRankAtFirstMark=Position an erster Bahnmarke
dashboardTeam=Team
dashboardDistanceToLineInM=Distanz zur Linie in m
@@ -1447,4 +1456,5 @@ defaultLocale=Standard
defaultSailorsInfoLinkInfoText=Der Standardwert wird verwendet, sofern kein Sprach-abhängiger Selglerinfo-Link hinterlegt wurde. Wenn kein Standardwert angegeben ist, so erscheint kein Selgerinfo-Link bei Sprachen, welche keinen Sprach-spezifischen Link definiert haben.
qrSync=QR-Sync
thereIsNoIdentifierSet=Es ist noch keine Kennung gesetzt.
-couldNotObtainAccessTokenForUser=Zugangscode für Benutzer {0} konnte nicht bezogen werden
\ No newline at end of file
+couldNotObtainAccessTokenForUser=Zugangscode für Benutzer {0} konnte nicht bezogen werden
+raceManagerDeviceName=Gerätename
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties
index 83bca313590..e43b12f8808 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties
@@ -177,6 +177,7 @@ in=в
secondsUnit=с
secondsPerNauticalMileUnit=с/NM
metersUnit=м
+degreesUnit=°
close=Закрыть
compareCompetitors=Сравнить участников
description=Описание
@@ -1155,9 +1156,9 @@ groupName=Group Name
valueAscending=Value (Ascending)
valueDescending=Value (Descending)
sortBy=Sort by
-dashboardWindBotLoadingText=Loading wind bot data ...
-dashboardWindBotLoadingMessage=Depending on your connection this operation might take some minutes to complete the first time.
-dashboardWindBotNotAvailable=Wind bot not available.
+dashboardHeader=Dashboard
+dashboardNoWindBotAvailableHeader=Wind Bot not available.
+dashboardNoWindBotAvailableMessage=To receive live wind data from wind measurement units, ensure that the wind bot is switched on and connected to the SAP Sailing Analytics.
dashboardWindBot=Wind Bot
dashboardTrueWindSpeed=TWS
dashboardTrueWindDirection=TWD
@@ -1167,9 +1168,17 @@ dashboardLiveWind=live
dashboardAverageWind=average
dashboardAverageWindMinutes=({0} minutes)
dashboardWindChartHint=Tap on chart to change interval
+dashboardStartAnalysesHeader=Start Analyses
+dashboardSelectCompetitor=Select Competitor
dashboardNewStartAnalysisAvailable=New start analysis available
-dashboardStartlineAdvantagesByWind=Startline advantage by wind
-dashboardStartlineAdvantageByGeometry=Startline advantage by geometry
+dashboardNoStartAnalysesAvailableHeader=No Start Analyses available.
+dashboardNoStartAnalysesAvailableMessage=There is a Start Analysis created from each race start. Please stand by till racing has been started.
+dashboardNoStartlineAdvantagesByWindAvailableHeader=No Startline Advantages available.
+dashboardNoStartlineAdvantagesByWindAvailableMessage=For calculating the startline advantage there needs to be a course set by the race commitee.
+dashboardNoStartlineAdvantagesByGeometryAvailableHeader=No Startline Advantage available.
+dashboardNoStartlineAdvantagesByGeometryAvailableMessage=For calculating the startline advantage there needs to be a course set by the race commitee.
+dashboardStartlineAdvantagesByWindHeader=Startline Advantages by Wind
+dashboardStartlineAdvantageByGeometryHeader=Startline Advantage by Geometry
dashboardRankAtFirstMark=Rank at first mark
dashboardTeam=Team
dashboardDistanceToLineInM=Distance to line in m
@@ -1357,7 +1366,6 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=High Point, winner gets 12 points (
scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Score in points. Winner scores 12 points, 2nd - 11 points, .... A tie is broken in favour of the competitor having won most races, if tie remains then tie is broken by the rank in the last race scored.
scoringSchemeHighPointEssOverall12=High Point System ESS Overall (12)
scoringSchemeHighPointEssOverall12Description=Score in points. Winner of an act scores 12 points, 2nd - 11 points, .... Any tie in the overall Extreme Sailing Series is broken in favour of the competitor with the most Act wins. If that does not break the tie, the result in the last Act will be used.
-pleaseCreateAtLeastOneMappingBy=Plase create at list one mapping by first selecting a track on the left hand side and then selecting a mark or competitor on the right hand side
createDefaultLeaderboardGroup=Would you like to create a default LeaderboardGroup for your event?
pleaseCreateAtLeastOneMappingBy=Please create at least one mapping by first selecting a track on the left hand side and then selecting a mark or competitor on the right hand side
matcherType=Matcher type
@@ -1379,4 +1387,5 @@ defaultLocale=Default
defaultSailorsInfoLinkInfoText=The default link is used unless a language specific overwrite exists. If no default exists, there will be no link for languages that do not explicitly have one set.
qrSync=QR-Sync
thereIsNoIdentifierSet=There is no identifier set.
-couldNotObtainAccessTokenForUser=Could not obtain access token for user {0}
\ No newline at end of file
+couldNotObtainAccessTokenForUser=Could not obtain access token for user {0}
+raceManagerDeviceName=Device Name
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties
index 7a953a3e9e3..1db85e36f16 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties
@@ -128,7 +128,9 @@ raceLogReloaded=Race log successfully reloaded from database
legend=Legend
courseDesignerMode=Course designer
configureLeaderboardUrlDescription=Configure a leaderboard and obtain the resulting URL from the link
+dashboardHeader=Dashboard
dashboardAverageWind=average
+dashboardSelectCompetitor=Select Competitor
welcomeToSailingAnalytics=Welcome to SAP Sailing Analytics
courseOverGroundTrueDegreesTooltip=实际航向角度
mediaSelectVideoCaption={0} Videos
@@ -160,7 +162,6 @@ explainReplicationServletPort=Servlet port number that is used to connect to reg
numberOfManeuvers=操作
successfullyAllowedCompetitorReset=Successfully allowed reload of competitor(s) {0}.
pleaseEnterAName=Please enter a name
-dashboardStartlineAdvantageByGeometry=Startline advantage by geometry
confidence=Confidence
from=从
start=起航
@@ -351,7 +352,10 @@ raceIsRunning=正在进行
starboardSide=右舷
polarSheetMinimumWindConfidence=Minimum wind confidence value
group=分组
+dashboardStartAnalysesHeader=Start Analyses
dashboardNewStartAnalysisAvailable=New start analysis available
+dashboardNoStartAnalysesAvailableHeader=No Start Analyses available.
+dashboardNoStartAnalysesAvailableMessage=There is a Start Analysis created from each race start. Please stand by till racing has been started.
actionAddWindData=Add wind data
competitorSearchFilter=Competitor Search Filter
dataCount=Data Size
@@ -861,6 +865,7 @@ selectAFilterCriteria=Select a filter criteria
errorWhileTryingToSetWindSourceForRace=Error while trying to set "wind starts upwind" flag
pleaseEnterASailNumber=Please enter a sail number
metersUnit=m
+degreesUnit=°
isPublic=Is public
speedOverGroundWhenPassingStartTooltip=参赛队越过起航线时的实际速度
successfullyUpdatedSailingServers=Successfully updated SailingServer instances
@@ -982,7 +987,6 @@ overallStandings=总排名
setClosingTimePoint=Set Timepoint that closes open time range
registeredCompetitors=Registered Competitors
timePointMustBeBeforeEndOfTracking=Time point must be before end of tracking.
-dashboardWindBotNotAvailable=Wind bot not available.
untracked=Untracked
scoringSchemeWinnerGetsEightAndInterpolation=High Point System, Winner 8 Points, Interpolated
export=Export
@@ -1095,7 +1099,8 @@ windwardDistanceToGoInMetersTooltip=迎/顺风航段时参赛队的位置离开
papaDisplayed=Start mode flag - four minutes till start
sheetNameTooltip=You can name your polar sheet using the text field.nA name will be generated using the boat classnif no name is provided.
competitorsFilter=参赛队过滤
-dashboardStartlineAdvantagesByWind=Startline advantage by wind
+dashboardStartlineAdvantagesByWindHeader=Startline Advantages by Wind
+dashboardStartlineAdvantageByGeometryHeader=Startline Advantage by Geometry
dashboardSecondsAbreviation=s
pleaseEnterNonEmptyDescription=Please enter a non-empty description
polarSheetChart=Polar Sheet
@@ -1252,8 +1257,12 @@ eventsCount[one]={0,number} event
competitorsCount={0,number} competitors
courseAreaName=Course area: {0}
competitorsCount[one]={0,number} competitor�
-dashboardWindBotLoadingText=Loading wind bot data ...
-dashboardWindBotLoadingMessage=Depending on your connection this operation might take some minutes to complete the first time.
+dashboardNoWindBotAvailableHeader=Wind Bot not available.
+dashboardNoWindBotAvailableMessage=To receive live wind data from wind measurement units, ensure that the wind bot is switched on and connected to the SAP Sailing Analytics.
+dashboardNoStartlineAdvantagesByWindAvailableHeader=No Startline Advantages available.
+dashboardNoStartlineAdvantagesByWindAvailableMessage=For calculating the startline advantage there needs to be a course set by the race commitee.
+dashboardNoStartlineAdvantagesByGeometryAvailableHeader=No Startline Advantage available.
+dashboardNoStartlineAdvantagesByGeometryAvailableMessage=For calculating the startline advantage there needs to be a course set by the race commitee.
currentOfTotalLegs=航段 {0,number}/{1,number}
clone=Clone
changed=Changed
@@ -1372,7 +1381,6 @@ scoringSchemeHighPointFirstGetsTwelveOrEight=High Point, winner gets 12 points (
scoringSchemeHighPointFirstGetsTwelveOrEightDescription=Score in points. Winner scores 12 points, 2nd - 11 points, .... A tie is broken in favour of the competitor having won most races, if tie remains then tie is broken by the rank in the last race scored.
scoringSchemeHighPointEssOverall12=High Point System ESS Overall (12)
scoringSchemeHighPointEssOverall12Description=Score in points. Winner of an act scores 12 points, 2nd - 11 points, .... Any tie in the overall Extreme Sailing Series is broken in favour of the competitor with the most Act wins. If that does not break the tie, the result in the last Act will be used.
-pleaseCreateAtLeastOneMappingBy=Plase create at list one mapping by first selecting a track on the left hand side and then selecting a mark or competitor on the right hand side
createDefaultLeaderboardGroup=Would you like to create a default LeaderboardGroup for your event?
pleaseCreateAtLeastOneMappingBy=Please create at least one mapping by first selecting a track on the left hand side and then selecting a mark or competitor on the right hand side
matcherType=Matcher type
@@ -1394,4 +1402,5 @@ defaultLocale=Default
defaultSailorsInfoLinkInfoText=The default link is used unless a language specific overwrite exists. If no default exists, there will be no link for languages that do not explicitly have one set.
qrSync=QR-Sync
thereIsNoIdentifierSet=There is no identifier set.
-couldNotObtainAccessTokenForUser=Could not obtain access token for user {0}
\ No newline at end of file
+couldNotObtainAccessTokenForUser=Could not obtain access token for user {0}
+raceManagerDeviceName=Device Name
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CombinedWindPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CombinedWindPanel.java
index 40d5bcbc314..aa92c3f2602 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CombinedWindPanel.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CombinedWindPanel.java
@@ -23,22 +23,23 @@ public class CombinedWindPanel extends FlowPanel {
private Canvas canvas;
- private CombinedWindPanelStyle combinedWindPanelStyle;
+ private RaceMapStyle raceMapStyle;
private final CoordinateSystem coordinateSystem;
- public CombinedWindPanel(RaceMapImageManager theRaceMapResources, CombinedWindPanelStyle combinedWindPanelStyle,
+ public CombinedWindPanel(RaceMapImageManager theRaceMapResources, RaceMapStyle raceMapStyle,
StringMessages stringMessages, CoordinateSystem coordinateSystem) {
+ raceMapStyle.ensureInjected();
this.stringMessages = stringMessages;
this.coordinateSystem = coordinateSystem;
this.raceMapResources = theRaceMapResources;
- this.combinedWindPanelStyle = combinedWindPanelStyle;
- addStyleName(combinedWindPanelStyle.combinedWindPanel());
+ this.raceMapStyle = raceMapStyle;
+ addStyleName(raceMapStyle.raceMapIndicatorPanel());
transformer = raceMapResources.getCombinedWindIconTransformer();
canvas = transformer.getCanvas();
- canvas.addStyleName(this.combinedWindPanelStyle.combinedWindPanelCanvas());
+ canvas.addStyleName(this.raceMapStyle.raceMapIndicatorPanelCanvas());
add(canvas);
textLabel = new Label("");
- textLabel.addStyleName(this.combinedWindPanelStyle.combinedWindPanelTextLabel());
+ textLabel.addStyleName(this.raceMapStyle.raceMapIndicatorPanelTextLabel());
add(textLabel);
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CombinedWindPanelStyle.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CombinedWindPanelStyle.java
deleted file mode 100644
index a1d84ffb09d..00000000000
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CombinedWindPanelStyle.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.sap.sailing.gwt.ui.client.shared.racemap;
-
-import com.google.gwt.resources.client.CssResource;
-import com.google.gwt.resources.client.CssResource.Shared;
-
-@Shared
-public interface CombinedWindPanelStyle extends CssResource {
- public String combinedWindPanel();
- public String combinedWindPanelTextLabel();
- public String combinedWindPanelCanvas();
-}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CombinedWindPanel.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.css
similarity index 73%
rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CombinedWindPanel.css
rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.css
index 2a333cf891c..9c8056bcd53 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/CombinedWindPanel.css
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.css
@@ -1,6 +1,6 @@
@CHARSET "UTF-8";
-.combinedWindPanel {
+.raceMapIndicatorPanel {
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
-o-border-radius: 4px;
@@ -10,7 +10,7 @@
border: 1px solid #C9CACA;
}
-.combinedWindPanelTextLabel {
+.raceMapIndicatorPanelTextLabel {
height: 12px;
width: 55px;
vertical-align: middle;
@@ -18,8 +18,12 @@
text-align: center;
}
-.combinedWindPanelCanvas{
+.raceMapIndicatorPanelCanvas {
width: 55px;
margin-left: 6px;
cursor: pointer;
-}
\ No newline at end of file
+}
+
+.combinedWindPanel {}
+
+.trueNorthIndicator {}
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java
index c0efaa1bd7b..d8a3d76289a 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java
@@ -409,7 +409,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
public RaceMap(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
ErrorReporter errorReporter, Timer timer, CompetitorSelectionProvider competitorSelection, StringMessages stringMessages,
boolean showMapControls, boolean showViewStreamlets, boolean showViewStreamletColors, boolean showViewSimulation,
- RegattaAndRaceIdentifier raceIdentifier, CombinedWindPanelStyle combinedWindPanelStyle, boolean showHeaderPanel) {
+ RegattaAndRaceIdentifier raceIdentifier, RaceMapResources raceMapResources, boolean showHeaderPanel) {
this.setSize("100%", "100%");
this.showMapControls = showMapControls;
this.stringMessages = stringMessages;
@@ -419,7 +419,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
this.errorReporter = errorReporter;
this.timer = timer;
timer.addTimeListener(this);
- raceMapImageManager = new RaceMapImageManager();
+ raceMapImageManager = new RaceMapImageManager(raceMapResources);
markDTOs = new HashMap();
courseSidelines = new HashMap<>();
courseMiddleLines = new HashMap<>();
@@ -446,9 +446,9 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
panelForLeftHeaderLabels = new AbsolutePanel();
panelForRightHeaderLabels = new AbsolutePanel();
initializeData(showMapControls, showHeaderPanel);
- combinedWindPanel = new CombinedWindPanel(raceMapImageManager, combinedWindPanelStyle, stringMessages, coordinateSystem);
+ combinedWindPanel = new CombinedWindPanel(raceMapImageManager, raceMapResources.raceMapStyle(), stringMessages, coordinateSystem);
combinedWindPanel.setVisible(false);
- trueNorthIndicatorPanel = new TrueNorthIndicatorPanel(this, raceMapImageManager, combinedWindPanelStyle, stringMessages, coordinateSystem);
+ trueNorthIndicatorPanel = new TrueNorthIndicatorPanel(this, raceMapImageManager, raceMapResources.raceMapStyle(), stringMessages, coordinateSystem);
trueNorthIndicatorPanel.setVisible(true);
orientationChangeInProgress = false;
mapFirstZoomDone = false;
@@ -632,8 +632,9 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
if (showHeaderPanel) {
createHeaderPanel(map);
}
- createSettingsButton(map);
-
+ if (showMapControls) {
+ createSettingsButton(map);
+ }
// Data has been initialized
RaceMap.this.isMapInitialized = true;
RaceMap.this.redraw();
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapImageManager.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapImageManager.java
index 4dffc1946d0..2ef5252955e 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapImageManager.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapImageManager.java
@@ -5,7 +5,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import com.google.gwt.core.client.GWT;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.base.Point;
import com.google.gwt.maps.client.base.Size;
@@ -39,9 +38,10 @@ public class RaceMapImageManager {
protected Map, Marker> maneuverIconsForTypeAndDirectionIndicatingColor;
- private static RaceMapResources resources = GWT.create(RaceMapResources.class);
-
- public RaceMapImageManager() {
+ private final RaceMapResources resources;
+
+ public RaceMapImageManager(RaceMapResources resources) {
+ this.resources = resources;
maneuverIconsForTypeAndDirectionIndicatingColor = new HashMap, Marker>();
trueNorthIndicatorIconTransformer = new ImageTransformer(resources.trueNorthIndicatorIcon());
combinedWindIconTransformer = new ImageTransformer(resources.combinedWindIcon());
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapResources.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapResources.java
index 689799cb81c..368ba925ee1 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapResources.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapResources.java
@@ -28,6 +28,6 @@ public interface RaceMapResources extends ClientBundle {
@Source("com/sap/sailing/gwt/ui/client/images/maneuver_green.png")
ImageResource maneuverMarkerGreen();
- @Source("CombinedWindPanel.css")
- CombinedWindPanelStyle combinedWindPanelStyle();
+ @Source("RaceMap.css")
+ RaceMapStyle raceMapStyle();
}
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapStyle.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapStyle.java
new file mode 100644
index 00000000000..4a2179a296b
--- /dev/null
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMapStyle.java
@@ -0,0 +1,21 @@
+package com.sap.sailing.gwt.ui.client.shared.racemap;
+
+import com.google.gwt.resources.client.CssResource;
+import com.google.gwt.resources.client.CssResource.Shared;
+
+/**
+ * Contains class names for styles that can get overwritten in the {@link RaceMap}.
+ * The {@link RaceMap} may require customized styles of elements when it is used in
+ * different contexts.
+ *
+ * @author Alexander Ries
+ *
+ */
+@Shared
+public interface RaceMapStyle extends CssResource {
+ public String raceMapIndicatorPanel();
+ public String raceMapIndicatorPanelTextLabel();
+ public String raceMapIndicatorPanelCanvas();
+ public String combinedWindPanel();
+ public String trueNorthIndicator();
+}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/TrueNorthIndicatorPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/TrueNorthIndicatorPanel.java
index 28da66d7f61..ef7cd8e80a3 100755
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/TrueNorthIndicatorPanel.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/TrueNorthIndicatorPanel.java
@@ -26,19 +26,20 @@ public class TrueNorthIndicatorPanel extends FlowPanel {
private Canvas canvas;
- private CombinedWindPanelStyle combinedWindPanelStyle;
+ private RaceMapStyle raceMapStyle;
private final CoordinateSystem coordinateSystem;
- public TrueNorthIndicatorPanel(final RaceMap map, RaceMapImageManager theRaceMapResources, CombinedWindPanelStyle combinedWindPanelStyle,
+ public TrueNorthIndicatorPanel(final RaceMap map, RaceMapImageManager theRaceMapResources, RaceMapStyle raceMapStyle,
final StringMessages stringMessages, CoordinateSystem coordinateSystem) {
this.stringMessages = stringMessages;
this.coordinateSystem = coordinateSystem;
this.raceMapResources = theRaceMapResources;
- this.combinedWindPanelStyle = combinedWindPanelStyle;
- addStyleName(combinedWindPanelStyle.combinedWindPanel());
+ this.raceMapStyle = raceMapStyle;
+ addStyleName(raceMapStyle.raceMapIndicatorPanel());
+ addStyleName(raceMapStyle.trueNorthIndicator());
transformer = raceMapResources.getTrueNorthIndicatorIconTransformer();
canvas = transformer.getCanvas();
- canvas.addStyleName(this.combinedWindPanelStyle.combinedWindPanelCanvas());
+ canvas.addStyleName(this.raceMapStyle.raceMapIndicatorPanelCanvas());
add(canvas);
canvas.addClickHandler(new ClickHandler() {
@Override
@@ -58,7 +59,7 @@ public class TrueNorthIndicatorPanel extends FlowPanel {
}
});
textLabel = new Label("");
- textLabel.addStyleName(this.combinedWindPanelStyle.combinedWindPanelTextLabel());
+ textLabel.addStyleName(this.raceMapStyle.raceMapIndicatorPanelTextLabel());
add(textLabel);
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardTable.css b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardTable.css
index cf2f58f985d..11d9c412cda 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardTable.css
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardTable.css
@@ -1,8 +1,11 @@
.cellTableWidget {
border-left: 1px solid #c9caca;
border-top: 1px solid #c9caca;
+ border-collapse: collapse;
}
+
+
/** v-align images in the table header
* grey background for table header
*/
@@ -10,7 +13,7 @@
position: relative;
vertical-align: bottom;
background-color: #e5e5e5;
- border-right: 1px solid #c9caca !important;
+ border-right: 0px solid #c9caca !important;
border-top: none !important;
border-bottom: 1px solid #c9caca !important;
padding: 3px 5px;
@@ -46,19 +49,43 @@
}
.cellTableEvenRow {
- border-bottom: 1px solid #e5e5e5;
- background-color: rgba(255,255,255,0.5);
+ background-color: rgba(255,255,255,0.5);
}
-.cellTableEvenRowCell {
- border-right: 1px solid #c9caca !important;
- border-left: none;
- border-top: none !important;
- border-bottom: 1px solid #c9caca !important;
- padding: 7px 7px 7px;
+.cellTableOddRow {
+ background-color: rgba(242,242,242,0.5);
+}
+
+.cellTableSelectedRow {
+ color: #000000;
+ background-color: rgba(229,242,249,0.6);
+}
+
+.cellTableSelectedRow > td:FIRST-CHILD {
+ border-left: 1px solid rgba(33,160,228,0.6) !important;
+}
+
+.cellTableSelectedRow > td:LAST-CHILD {
+ border-right: 1px solid rgba(33,160,228,0.6) !important;
+}
+.cellTableSelectedRow > td {
+}
+
+.cellTableCell {
+ overflow: inherit;
+ font-size: 12px !important;
+ line-height: 1.5em !important;
+}
+.cellTableSelectedRowCell {
+ border-top: 2px double #21a0e4 !important;
+ border-bottom: 2px double #21a0e4 !important;
+ padding: 7px 7px 6px 7px !important;
+}
+
+.cellTableEvenRowCell, .cellTableOddRowCell {
+ border: 1px solid #c9caca;
+ padding: 7px;
white-space: nowrap;
- font-size: 12px !important;
- line-height: 1.5 !important;
}
.cellTableCheckboxColumnCell {
@@ -68,71 +95,27 @@
}
.cellTableCheckboxSelected {
- margin-left: 0px; /* account for the selection border that pushes a selected checkbox to the side */
- margin-top: 0px;
- margin-bottom: 0px;
- margin-right: 2px;
- height: 18px;
- width: 18px;
- border: solid 1px #fcbb22;
+ margin: auto auto;
+ height: 13px;
+ width: 13px;
+ border: 1px solid #fcbb22;
background-color: #fcbb22;
vertical-align: middle;
}
.cellTableCheckboxDeselected {
- margin-left: 2px; /* account for the selection border that pushes a selected checkbox to the side */
- margin-top: 0px;
- margin-bottom: 0px;
- margin-right: 2px;
+ margin: auto auto;
+ height: 13px;
+ width: 13px;
border: solid 1px #acacac;
- height: 18px;
- width: 18px;
vertical-align: middle;
}
-.cellTableOddRow {
- border-bottom: 1px solid #e5e5e5;
- background-color: rgba(242,242,242,0.5);
-}
-
-.cellTableOddRowCell {
- border-left: none !important;
- border-right: 1px solid #c9caca !important;
- border-top: none !important;
- border-bottom: 1px solid #c9caca !important;
- padding: 7px 7px 7px;
- white-space: nowrap;
- font-size: 12px !important;
- line-height: 1.5 !important;
-}
-
.cellTableHoveredRow {
background-color: rgba(229,242,249,0.5);
border-bottom: 1px solid #e5e5e5;
}
-.cellTableSelectedRow {
- color: #000000;
- background-color: rgba(229,242,249,0.5);
- border-right: 2px solid #21a0e4 !important;
- border-left: 2px solid #21a0e4 !important;
- border: 2px solid #21a0e4;
-}
-
-.cellTableSelectedRow > td:FIRST-CHILD {
- border-left: 2px solid rgba(33,160,228,0.5) !important;
-}
-
-.cellTableSelectedRow > td:LAST-CHILD {
- border-right: 2px solid rgba(33,160,228,0.5) !important;
-}
-
-.cellTableSelectedRowCell {
- border-left: none;
- border-right: 1px solid #e5e5e5;
- border-top: 2px solid #21a0e4 !important;
- border-bottom: 2px solid #21a0e4 !important;
-}
.cellTableRaceColumnHeader {
background-color: #e5e5e5;
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/EmbeddedMapAndWindChartEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/EmbeddedMapAndWindChartEntryPoint.java
index 127cb23ee23..f1a0b2eb29c 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/EmbeddedMapAndWindChartEntryPoint.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/EmbeddedMapAndWindChartEntryPoint.java
@@ -155,7 +155,7 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
final TimePanelSettings timePanelSettings = timePanel.getSettings();
timePanelSettings.setRefreshInterval(refreshInterval);
timePanel.updateSettings(timePanelSettings);
- raceMapResources.combinedWindPanelStyle().ensureInjected();
+ raceMapResources.raceMapStyle().ensureInjected();
final CompetitorColorProvider colorProvider = new CompetitorColorProviderImpl(selectedRaceIdentifier, competitorBoats);
final CompetitorSelectionProvider competitorSelection;
if (showCompetitors) {
@@ -165,7 +165,7 @@ public class EmbeddedMapAndWindChartEntryPoint extends AbstractSailingEntryPoint
}
final RaceMap raceMap = new RaceMap(sailingService, asyncActionsExecutor, /* errorReporter */ EmbeddedMapAndWindChartEntryPoint.this, timer,
competitorSelection, getStringMessages(), showMapControls, showViewStreamlets, showViewStreamletColors,
- showViewSimulation, selectedRaceIdentifier, raceMapResources.combinedWindPanelStyle(), /* showHeaderPanel */ false) {
+ showViewSimulation, selectedRaceIdentifier, raceMapResources, /* showHeaderPanel */ false) {
@Override
protected void showAdditionalControls(MapWidget map) {
backToLivePlayButton.removeFromParent();
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java
index 05eea8e29be..567de85eb3e 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java
@@ -170,10 +170,10 @@ public class RaceBoardPanel extends SimplePanel implements LeaderboardUpdateList
final CompetitorColorProvider colorProvider = new CompetitorColorProviderImpl(selectedRaceIdentifier, competitorsAndTheirBoats);
competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */ true, colorProvider);
- raceMapResources.combinedWindPanelStyle().ensureInjected();
+ raceMapResources.raceMapStyle().ensureInjected();
raceMap = new RaceMap(sailingService, asyncActionsExecutor, errorReporter, timer,
competitorSelectionProvider, stringMessages, showMapControls, getConfiguration().isShowViewStreamlets(), getConfiguration().isShowViewStreamletColors(), getConfiguration().isShowViewSimulation(),
- selectedRaceIdentifier, raceMapResources.combinedWindPanelStyle(), /* showHeaderPanel */ true) {
+ selectedRaceIdentifier, raceMapResources, /* showHeaderPanel */ true) {
private static final String INDENT_SMALL_CONTROL_STYLE = "indentsmall";
private static final String INDENT_BIG_CONTROL_STYLE = "indentbig";
@Override
diff --git a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/home/solutions/RaceCommitteeAppNotes.html b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/home/solutions/RaceCommitteeAppNotes.html
index 7704a4b3255..7cd06cccd28 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/home/solutions/RaceCommitteeAppNotes.html
+++ b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/home/solutions/RaceCommitteeAppNotes.html
@@ -4,6 +4,19 @@
What's New - SAP Sailing Race Manager
+
March 2016
+
+
+ - Added sign in/sign out into the app. The user has to be create in the backend, with leaderboard
+ permission. Without the permission, the user can't send data to the server.
+ - We changed the QR Code, so it includes the user's access token. There is also a possibility to manual login into
+ the app, if no QR Code is available. The app doesn't store username and password.
+ - The behavior of the red share icon has also slightly changed. If it is red and tapped, it will call the server
+ to check, if the users access token is still valid. If not the server response with a 401 error code and the user
+ has to enter his credentials.
+ - You can force a user sign out within the overflow menu, if you need other user credentials.
+
+
February 2016
diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/MarksJsonExportServlet.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/MarksJsonExportServlet.java
index efcb71cc9f5..31bbdacf101 100644
--- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/MarksJsonExportServlet.java
+++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/impl/rc/MarksJsonExportServlet.java
@@ -1,7 +1,6 @@
package com.sap.sailing.server.gateway.impl.rc;
import java.io.IOException;
-import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -58,22 +57,12 @@ public class MarksJsonExportServlet extends AbstractJsonHttpServlet {
return;
}
JSONArray result = new JSONArray();
- final Iterable marks = raceColumn.getMarks(fleet);
+ final Iterable marks = raceColumn.getAvailableMarks(fleet);
MarkJsonSerializer serializer = new MarkJsonSerializer();
for (Mark mark : marks) {
- if (toUUID(mark.getId().toString()) != null) {
- result.add(serializer.serialize(mark));
- }
+ result.add(serializer.serialize(mark));
}
setJsonResponseHeader(response);
result.writeJSONString(response.getWriter());
}
-
- private UUID toUUID(String value) {
- try {
- return UUID.fromString(value);
- } catch (IllegalArgumentException iae) {
- return null;
- }
- }
}
diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java
index ff04315885c..a72a3ab2d0a 100644
--- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java
+++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/LeaderboardsResource.java
@@ -539,7 +539,7 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
.type(MediaType.TEXT_PLAIN).build();
} else {
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
- Util.addAll(raceColumn.getAllMarks(), marks);
+ Util.addAll(raceColumn.getCourseMarks(), marks);
}
}
} else {
@@ -558,13 +558,13 @@ public class LeaderboardsResource extends AbstractSailingServerResource {
StringEscapeUtils.escapeHtml(leaderboardName)
+ "'.").type(MediaType.TEXT_PLAIN).build();
} else {
- Util.addAll(raceColumn.getMarks(fleet), marks);
+ Util.addAll(raceColumn.getCourseMarks(fleet), marks);
}
} else {
// Return all marks for a certain race column
// if all races have a tracked race return all marks part of at least one tracked race
// if at least one race doesn't have a tracked race, return also the marks defined in the RegattaLog
- Util.addAll(raceColumn.getAllMarks(), marks);
+ Util.addAll(raceColumn.getCourseMarks(), marks);
}
}
JSONArray array = new JSONArray();
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch b/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch
index 70d5da234a1..64d68838215 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy OSX).launch
@@ -1,38 +1,38 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy).launch b/java/com.sap.sailing.server/SailingServer (No Proxy).launch
index fb49b67aa62..eb1a2722b78 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy).launch
@@ -1,38 +1,38 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch
index f423d629372..a08607085cc 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Cached MTB).launch
@@ -1,37 +1,37 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch
index a1b211da85d..3d3b3b72ea9 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889).launch
@@ -1,32 +1,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch
index 5fb70d15c55..95f214db6ad 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, Cached MTB).launch
@@ -1,32 +1,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch
index 7327c33673a..ce754832c84 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate dev).launch
@@ -1,32 +1,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch
index 3e59695678f..140ffe940f7 100644
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8889, auto-replicate).launch
@@ -1,32 +1,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch
index 4c27b93091f..ad8671fb860 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Jetty on 8890).launch
@@ -1,32 +1,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch
index 09a44db1439..4187f309ac1 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, Remote Debug SAP VM).launch
@@ -1,31 +1,31 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch
index a855c7db089..0b5043c7561 100755
--- a/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch
+++ b/java/com.sap.sailing.server/SailingServer (No Proxy, winddbTest).launch
@@ -1,37 +1,37 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy).launch b/java/com.sap.sailing.server/SailingServer (Proxy).launch
index c74298fb3be..21dfc841aea 100755
--- a/java/com.sap.sailing.server/SailingServer (Proxy).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy).launch
@@ -1,39 +1,39 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch b/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch
index b19398528bb..e30859d3dbe 100755
--- a/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy, Jetty on 8889).launch
@@ -1,32 +1,32 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch b/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch
index 57628771165..90b6f42c0f2 100755
--- a/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy, Remote Debug SAP VM).launch
@@ -1,31 +1,31 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch b/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch
index d9d2b3a236c..c8d7494d4d5 100755
--- a/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy, SwissTiming Live Simulation).launch
@@ -1,30 +1,30 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch b/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch
index 4e8e768c965..c577be0479c 100755
--- a/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch
+++ b/java/com.sap.sailing.server/SailingServer (Proxy, winddbTest).launch
@@ -1,33 +1,33 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/com.sap.sse.gwt/META-INF/MANIFEST.MF b/java/com.sap.sse.gwt/META-INF/MANIFEST.MF
index 59f798364a0..4dc211945df 100644
--- a/java/com.sap.sse.gwt/META-INF/MANIFEST.MF
+++ b/java/com.sap.sse.gwt/META-INF/MANIFEST.MF
@@ -9,9 +9,13 @@ Require-Bundle: com.google.gwt.osgi;bundle-version="2.7.0",
com.sap.sse.common,
com.sap.sse.filestorage
Bundle-ActivationPolicy: lazy
-Import-Package: javax.servlet;version="2.6.0",
- javax.servlet.http;version="2.6.0",
+Import-Package: com.google.gwt.core.ext,
+ com.google.gwt.core.ext.linker,
+ com.google.gwt.core.ext.linker.impl,
+ javax.servlet;version="2.6.0",
javax.servlet.descriptor;version="2.6.0",
+ javax.servlet.http;version="2.6.0",
+ org.apache.commons.io,
org.json.simple,
org.json.simple.parser,
org.osgi.framework,
@@ -31,6 +35,7 @@ Export-Package: com.google.gwt.user.client.rpc.core.java.util,
com.sap.sse.gwt.client.dialog,
com.sap.sse.gwt.client.event,
com.sap.sse.gwt.client.filestorage,
+ com.sap.sse.gwt.client.linker,
com.sap.sse.gwt.client.media,
com.sap.sse.gwt.client.mutationobserver,
com.sap.sse.gwt.client.mvp,
diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/linker/ManifestLinker.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/linker/ManifestLinker.java
new file mode 100644
index 00000000000..2e26ee6790c
--- /dev/null
+++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/linker/ManifestLinker.java
@@ -0,0 +1,135 @@
+package com.sap.sse.gwt.client.linker;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Date;
+
+import org.apache.commons.io.IOUtils;
+
+import com.google.gwt.core.ext.LinkerContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.AbstractLinker;
+import com.google.gwt.core.ext.linker.Artifact;
+import com.google.gwt.core.ext.linker.ArtifactSet;
+import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.LinkerOrder;
+import com.google.gwt.core.ext.linker.impl.SelectionInformation;
+
+/**
+ * This class creates an application manifest file for HTML 5 Offline Application Caching in the
+ * output folder of your client side gwt compilation results.
+ * Follow those steps to use HTML 5 Offline Application Caching in your bundle:
+ *
+ * - Add {@code manifest="YOURMODULENAME/appcache.manifest"} to the {@code } tag in your base html file.
+ * - Subclass {@link ManifestLinker} and override the method {@link #staticCachedFiles()}.
+ * - Define a mime type mapping for the
manifest extension in your web.xml file.
+ *
+ * {@code
+ * manifest
+ * text/cache-manifest
+ *
+ * }
+ *
+ * - Define the subclassed linker in your gwt.xml file and add the linker.
+ *
+ * {@code
+ *
+ * }
+ * - Make sure to import the those packages into your MANIFEST.MF file.
+ * com.google.gwt.core.ext
+ * com.google.gwt.core.ext.linker
+ * com.google.gwt.core.ext.linker.impl
+ *
+ *
+ * @author Alexander Ries
+ *
+ */
+@LinkerOrder(LinkerOrder.Order.POST)
+public class ManifestLinker extends AbstractLinker {
+
+ private static final String MANIFEST = "appcache.manifest";
+ private static final String MANIFESTTEMPLATE = "cache.manifest.template";
+
+ @Override
+ public String getDescription() {
+ return ManifestLinker.class.getName();
+ }
+
+ @Override
+ public ArtifactSet link(TreeLogger logger, LinkerContext context, ArtifactSet artifacts, boolean onePermutation) throws UnableToCompleteException {
+ ArtifactSet result = new ArtifactSet(artifacts);
+ if (onePermutation) {
+ return result;
+ }
+ if (result.find(SelectionInformation.class).isEmpty()) {
+ logger.log(TreeLogger.INFO, "Warning: Clobbering " + MANIFEST + " to allow debugging. " + "Recompile before deploying your app!");
+ artifacts = null;
+ } else {
+ result.add(emitLandingPageCacheManifest(context, logger, artifacts));
+ }
+ return result;
+ }
+
+ private Artifact> emitLandingPageCacheManifest(LinkerContext context, TreeLogger logger, ArtifactSet artifacts) throws UnableToCompleteException {
+ StringBuilder publicSourcesSb = new StringBuilder();
+ StringBuilder staticResoucesSb = new StringBuilder();
+ if (artifacts != null) {
+ for (@SuppressWarnings("rawtypes")
+ Artifact artifact : artifacts) {
+ if (artifact instanceof EmittedArtifact) {
+ EmittedArtifact ea = (EmittedArtifact) artifact;
+ String pathName = ea.getPartialPath();
+ if (pathName.endsWith("symbolMap") ||
+ pathName.endsWith(".xml.gz") ||
+ pathName.endsWith("rpc.log") ||
+ pathName.endsWith("gwt.rpc") ||
+ pathName.endsWith("manifest.txt") ||
+ pathName.startsWith("rpcPolicyManifest")) {
+ } else {
+ publicSourcesSb.append(pathName + "\n");
+ }
+ }
+ }
+ String[] cacheExtraFiles = getCacheExtraFiles();
+ for (int i = 0; i < cacheExtraFiles.length; i++) {
+ staticResoucesSb.append(cacheExtraFiles[i]);
+ staticResoucesSb.append("\n");
+ }
+ }
+ String cacheManifestString = createCache(logger, context, publicSourcesSb, staticResoucesSb);
+ return emitString(logger, cacheManifestString, MANIFEST);
+ }
+
+ protected String createCache(TreeLogger logger, LinkerContext context, StringBuilder publicSourcesSb, StringBuilder staticResoucesSb) throws UnableToCompleteException {
+ try {
+ String manifest = IOUtils.toString(getClass().getResourceAsStream(appCacheManifestTemplate()));
+ manifest = manifest.replace("$UNIQUEID$", (new Date()).getTime() + "." + Math.random()).toString();
+ manifest = manifest.replace("$STATICAPPFILES$", staticResoucesSb.toString());
+ manifest = manifest.replace("$GENAPPFILES$", publicSourcesSb.toString());
+ return manifest;
+ } catch (IOException e) {
+ //logger.log(TreeLogger.ERROR, "Could not read cache manifest template.", e);
+ throw new UnableToCompleteException();
+ }
+ }
+
+ private String[] getCacheExtraFiles() {
+ String[] cacheExtraFiles = staticCachedFiles();
+ return cacheExtraFiles == null ? new String[0] : Arrays.copyOf(cacheExtraFiles, cacheExtraFiles.length);
+ }
+
+ /**
+ * Override this method to provide static files for caching.
+ * Include at least your root HTML and CSS file.
+ * Also include all files referenced in your root HTML file.
+ * See {@link DashboardManifestLinker} as an example.
+ * */
+ protected String[] staticCachedFiles() {
+ return null;
+ }
+
+ protected String appCacheManifestTemplate() {
+ return MANIFESTTEMPLATE;
+ }
+}
diff --git a/mobile/com.sap.sailing.android.shared/build.gradle b/mobile/com.sap.sailing.android.shared/build.gradle
index 8688b6c0633..26ee1c69d88 100644
--- a/mobile/com.sap.sailing.android.shared/build.gradle
+++ b/mobile/com.sap.sailing.android.shared/build.gradle
@@ -51,7 +51,7 @@ dependencies {
/* Google Play Services */
compile "com.google.android.gms:play-services-location:${rootProject.ext.play_services}"
- /* licence dialog */
+ /* license dialog */
compile("de.psdev.licensesdialog:licensesdialog:${rootProject.ext.license_dialog}")
/* all local jar-libs */
diff --git a/mobile/com.sap.sailing.android.shared/res/layout/fragment_about.xml b/mobile/com.sap.sailing.android.shared/res/layout/fragment_about.xml
index eeed356f8e0..727c5695338 100644
--- a/mobile/com.sap.sailing.android.shared/res/layout/fragment_about.xml
+++ b/mobile/com.sap.sailing.android.shared/res/layout/fragment_about.xml
@@ -11,7 +11,7 @@
/>
diff --git a/mobile/com.sap.sailing.android.shared/res/values-de/strings.xml b/mobile/com.sap.sailing.android.shared/res/values-de/strings.xml
index 00171d91dd6..170eb3e5a64 100644
--- a/mobile/com.sap.sailing.android.shared/res/values-de/strings.xml
+++ b/mobile/com.sap.sailing.android.shared/res/values-de/strings.xml
@@ -41,6 +41,6 @@
Über diese App
Datenschutz
- Lizenzhinweise
+ Lizenzhinweise
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.android.shared/res/values/preferences.xml b/mobile/com.sap.sailing.android.shared/res/values/preferences.xml
index 0b9f6f463c5..924f5ccf26b 100644
--- a/mobile/com.sap.sailing.android.shared/res/values/preferences.xml
+++ b/mobile/com.sap.sailing.android.shared/res/values/preferences.xml
@@ -7,7 +7,7 @@
true
webserviceUrlPref
- http://dev.sapsailing.com/
+ https://dev.sapsailing.com
enableLifecycleLogging
false
diff --git a/mobile/com.sap.sailing.android.shared/res/values/strings.xml b/mobile/com.sap.sailing.android.shared/res/values/strings.xml
index 31727b149bd..93da04781d5 100644
--- a/mobile/com.sap.sailing.android.shared/res/values/strings.xml
+++ b/mobile/com.sap.sailing.android.shared/res/values/strings.xml
@@ -57,7 +57,7 @@
About this app
EULA
- Licence Information
+ License Information
(Request %1$d) %2$s\nHTTP response code: %3$d.\nHTTP response body: %4$s.
@@ -65,4 +65,8 @@
(Request %d) HTTP request aborted.
(Request %d) HTTP request failed.
+
+ Currently %1$d events waiting to be sent.\nLast successful sent was at %2$s
+ Currently no event waiting to be sent.
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/LoginData.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/LoginData.java
new file mode 100644
index 00000000000..8c57a824071
--- /dev/null
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/LoginData.java
@@ -0,0 +1,18 @@
+package com.sap.sailing.android.shared.data;
+
+import com.sap.sse.common.Base64Utils;
+
+public class LoginData {
+
+ private String username;
+ private String password;
+
+ public LoginData(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+
+ public String getCredentials() {
+ return Base64Utils.toBase64((username + ":" + password).getBytes());
+ }
+}
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/HttpJsonPostRequest.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/HttpJsonPostRequest.java
index 01381da8efa..28af17938f8 100644
--- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/HttpJsonPostRequest.java
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/HttpJsonPostRequest.java
@@ -14,14 +14,20 @@ public class HttpJsonPostRequest extends HttpRequest {
public final static String ContentType = "application/json;charset=UTF-8";
private String requestBody;
+ private String accessToken;
public HttpJsonPostRequest(URL requestUrl, Context context) {
- this(requestUrl, null, context);
+ this(requestUrl, null, context, null);
}
-
+
public HttpJsonPostRequest(URL requestUrl, String body, Context context) {
+ this(requestUrl, body, context, null);
+ }
+
+ public HttpJsonPostRequest(URL requestUrl, String body, Context context, String accessToken) {
super(requestUrl, context);
this.requestBody = body;
+ this.accessToken = accessToken;
}
@Override
@@ -32,6 +38,9 @@ public class HttpJsonPostRequest extends HttpRequest {
connection.setRequestProperty("Content-Type", ContentType);
connection.setRequestProperty("Accept", ContentType);
+ if (accessToken != null) {
+ connection.setRequestProperty("Authorization", "Bearer " + accessToken);
+ }
OutputStream outputStream = new BufferedOutputStream(connection.getOutputStream());
try {
sendBody(outputStream);
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/HttpRequest.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/HttpRequest.java
index 9829cce07e1..50f3ed82c48 100644
--- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/HttpRequest.java
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/HttpRequest.java
@@ -44,7 +44,7 @@ public abstract class HttpRequest {
private final URL url;
private final Context context;
private boolean isCancelled;
- private SharedPreferences pref;
+ protected SharedPreferences pref;
public HttpRequest(URL url, Context context) {
this(url, null, context);
@@ -95,7 +95,7 @@ public abstract class HttpRequest {
responseInputStream = doRequest(connection);
} catch (FileNotFoundException fnfe) {
if (HttpURLConnection.HTTP_UNAUTHORIZED == connection.getResponseCode()) {
- throw new UnauthorizedException();
+ throw new UnauthorizedException(connection.getHeaderField("WWW-Authenticate"));
}
// 404 errors...
throw new FileNotFoundException(context.getString(R.string.http_request_exception, this.hashCode(), fnfe.getMessage(), connection.getResponseCode(), connection.getResponseMessage()));
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/LoginGetRequest.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/LoginGetRequest.java
new file mode 100644
index 00000000000..51a745426e4
--- /dev/null
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/LoginGetRequest.java
@@ -0,0 +1,33 @@
+package com.sap.sailing.android.shared.data.http;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import android.content.Context;
+
+import com.sap.sailing.android.shared.data.LoginData;
+
+public class LoginGetRequest extends HttpRequest {
+
+ public final static String ContentType = "application/json;charset=UTF-8";
+ private final LoginData loginData;
+
+ public LoginGetRequest(URL url, Context context, LoginData login) {
+ super(url, context);
+ loginData = login;
+ }
+
+ @Override
+ protected BufferedInputStream doRequest(HttpURLConnection connection) throws IOException {
+ connection.setRequestMethod("GET");
+ connection.setChunkedStreamingMode(0);
+
+ connection.setRequestProperty("Content-Type", ContentType);
+ connection.setRequestProperty("Accept", ContentType);
+ connection.setRequestProperty("Authorization", "Basic " + loginData.getCredentials());
+
+ return new BufferedInputStream(connection.getInputStream());
+ }
+}
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/UnauthorizedException.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/UnauthorizedException.java
index 0208a7e40c8..9d396fd2d81 100644
--- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/UnauthorizedException.java
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/data/http/UnauthorizedException.java
@@ -7,4 +7,8 @@ import java.io.IOException;
*/
public class UnauthorizedException extends IOException {
private static final long serialVersionUID = 5913076970322227942L;
+
+ public UnauthorizedException(String detailMessage) {
+ super(detailMessage);
+ }
}
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessagePersistenceManager.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessagePersistenceManager.java
index eb37655aadf..8aa5c25e06c 100644
--- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessagePersistenceManager.java
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessagePersistenceManager.java
@@ -18,19 +18,19 @@ import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.FileHandlerUtils;
public class MessagePersistenceManager {
-
+
private final static String TAG = MessagePersistenceManager.class.getName();
private final static String delayedMessagesFileName = "delayedMessages.txt";
protected Context context;
protected List persistedMessages;
-
+
private final MessageRestorer messageRestorer;
public MessagePersistenceManager(Context context, MessageRestorer messageRestorer) {
this.context = context;
- persistedMessages = new ArrayList();
+ persistedMessages = new ArrayList<>();
this.messageRestorer = messageRestorer;
initializeFileAndPersistedMessages();
}
@@ -60,14 +60,13 @@ public class MessagePersistenceManager {
/**
* @param payload will be URL-encoded to ensure that the resulting string does not contain newlines
- * @throws UnsupportedEncodingException
+ * @throws UnsupportedEncodingException
*/
- private String getSerializedIntentForPersistence(String url, String callbackPayload,
- String payload, String callbackClass) throws UnsupportedEncodingException {
- String messageLine = String.format("%s;%s;%s;%s", callbackPayload, URLEncoder.encode(payload,
- MessageSendingService.charsetName),
+ private String getSerializedIntentForPersistence(String url, String callbackPayload,
+ String payload, String callbackClass) throws UnsupportedEncodingException {
+ return String.format("%s;%s;%s;%s", callbackPayload, URLEncoder.encode(payload,
+ MessageSendingService.charsetName),
url, callbackClass);
- return messageLine;
}
public void removeIntent(Intent intent) throws UnsupportedEncodingException {
@@ -86,7 +85,7 @@ public class MessagePersistenceManager {
removePersistedMessage(messageLine);
}
}
-
+
/**
* Removes all pending messages and clears the persistence file.
*/
@@ -106,12 +105,12 @@ public class MessagePersistenceManager {
public int getMessageCount() {
return persistedMessages.size();
}
-
+
public List getContent() {
return persistedMessages;
}
-
- public static interface MessageRestorer {
+
+ public interface MessageRestorer {
void restoreMessage(Context context, Intent messageIntent);
}
@@ -125,26 +124,26 @@ public class MessagePersistenceManager {
String callbackClassString = lineParts[3];
Class extends ServerReplyCallback> callbackClass = null;
- if (! "null".equals(callbackClassString)) {
+ if (!"null".equals(callbackClassString)) {
try {
@SuppressWarnings("unchecked")
Class extends ServerReplyCallback> tmp =
- (Class extends ServerReplyCallback>) Class.forName(callbackClassString);
+ (Class extends ServerReplyCallback>) Class.forName(callbackClassString);
callbackClass = tmp;
} catch (ClassNotFoundException e) {
ExLog.e(context, TAG, "Could not find class for callback name: " + callbackClassString);
}
}
-
+
// We are passing no message id, because we know it used to suppress message sending and
// we want this message to be sent.
Intent messageIntent = MessageSendingService.createMessageIntent(context, url, callbackPayload,
null, payload, callbackClass);
-
+
if (messageRestorer != null) {
messageRestorer.restoreMessage(context, messageIntent);
}
-
+
if (messageIntent != null) {
delayedIntents.add(messageIntent);
}
@@ -166,7 +165,7 @@ public class MessagePersistenceManager {
fileContent = FileHandlerUtils.convertStreamToString(inputStream, context);
inputStream.close();
} catch (IOException e) {
- ExLog.w(context, TAG, "In Method getFileContent(): " + e.getClass().getName()+" / "+e.getMessage() + " fileContent is empty");
+ ExLog.w(context, TAG, "In Method getFileContent(): " + e.getClass().getName() + " / " + e.getMessage() + " fileContent is empty");
}
return fileContent;
}
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSenderResult.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSenderResult.java
new file mode 100644
index 00000000000..a9ceabd9995
--- /dev/null
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSenderResult.java
@@ -0,0 +1,50 @@
+package com.sap.sailing.android.shared.services.sending;
+
+import java.io.InputStream;
+
+import android.content.Intent;
+
+public class MessageSenderResult {
+
+ private final Intent mIntent;
+ private final InputStream mInputStream;
+ private final Exception mException;
+
+ public MessageSenderResult() {
+ this(null, null, null);
+ }
+
+ public MessageSenderResult(Intent intent) {
+ this(intent, null, null);
+ }
+
+ public MessageSenderResult(Intent intent, InputStream inputStream) {
+ this(intent, inputStream, null);
+ }
+
+ public MessageSenderResult(Intent intent, Exception exception) {
+ this(intent, null, exception);
+ }
+
+ public MessageSenderResult(Intent intent, InputStream inputStream, Exception exception) {
+ mIntent = intent;
+ mInputStream = inputStream;
+ mException = exception;
+ }
+
+ public boolean isSuccessful() {
+ return mException == null;
+ }
+
+ public Intent getIntent() {
+ return mIntent;
+ }
+
+ public InputStream getInputStream() {
+ return mInputStream;
+ }
+
+ public Exception getException() {
+ return mException;
+ }
+}
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSenderTask.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSenderTask.java
index deea1ae4272..2b86375a0d1 100644
--- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSenderTask.java
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSenderTask.java
@@ -12,16 +12,10 @@ import android.os.Bundle;
import com.sap.sailing.android.shared.data.http.HttpJsonPostRequest;
import com.sap.sailing.android.shared.data.http.HttpRequest;
import com.sap.sailing.android.shared.logging.ExLog;
-import com.sap.sse.common.Util;
-public class MessageSenderTask extends AsyncTask> {
-
+public class MessageSenderTask extends AsyncTask {
+
private static String TAG = MessageSenderTask.class.getName();
-
- public interface MessageSendingListener {
- public void onMessageSent(Intent intent, boolean success, InputStream inputStream);
- }
-
private MessageSendingListener listener;
private Context context;
@@ -30,19 +24,18 @@ public class MessageSenderTask extends AsyncTask doInBackground(Intent... params) {
- Util.Triple result;
+ protected MessageSenderResult doInBackground(Intent... params) {
+ MessageSenderResult result;
Intent intent = params[0];
if (intent == null) {
- return new Util.Triple(intent, false, null);
+ return new MessageSenderResult();
}
Bundle extras = intent.getExtras();
String payload = extras.getString(MessageSendingService.PAYLOAD);
String url = extras.getString(MessageSendingService.URL);
if (payload == null || url == null) {
- return new Util.Triple(intent, false, null);
+ return new MessageSenderResult(intent);
}
InputStream responseStream = null;
try {
@@ -50,22 +43,28 @@ public class MessageSenderTask extends AsyncTask(intent, true, responseStream);
+ result = new MessageSenderResult(intent, responseStream);
} catch (IOException e) {
- if (responseStream != null) {
- try {
- responseStream.close();
- } catch (IOException ie) { }
- }
ExLog.e(context, TAG, String.format("Post not successful, exception occured: %s", e.toString()));
- result = new Util.Triple(intent, false, null);
+ result = new MessageSenderResult(intent, e);
+ } finally {
+ try {
+ if (responseStream != null) {
+ responseStream.close();
+ }
+ } catch (IOException e) {
+ }
}
return result;
}
@Override
- protected void onPostExecute(Util.Triple resultTriple) {
- super.onPostExecute(resultTriple);
- listener.onMessageSent(resultTriple.getA(), resultTriple.getB(), resultTriple.getC());
+ protected void onPostExecute(MessageSenderResult result) {
+ super.onPostExecute(result);
+ listener.onMessageSent(result);
+ }
+
+ public interface MessageSendingListener {
+ void onMessageSent(MessageSenderResult result);
}
}
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSendingService.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSendingService.java
index a564685b8ea..298ca7ed455 100644
--- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSendingService.java
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/services/sending/MessageSendingService.java
@@ -11,6 +11,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+
import com.sap.sailing.android.shared.R;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.services.sending.MessagePersistenceManager.MessageRestorer;
@@ -18,7 +19,6 @@ import com.sap.sailing.android.shared.services.sending.MessageSenderTask.Message
import com.sap.sailing.android.shared.util.PrefUtils;
import com.sap.sailing.domain.common.racelog.RaceLogServletConstants;
-import java.io.InputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
@@ -28,7 +28,7 @@ import java.util.*;
* Service that handles sending messages to a webservice. Deals with an offline setting
* by buffering the messages in a file, so that they can be sent when the connection is
* re-established.
- *
+ *
* Use in the following way: Add the service declaration to your {@code AndroidManifest.xml},
* and also specify your class implementing the {@link MessagePersistenceManager.MessageRestorer}
* as a meta-data tag with the key {@code com.sap.sailing.android.shared.services.sending.messageRestorer}.
@@ -42,9 +42,9 @@ import java.util.*;
* android:value="com.sap.sailing.racecommittee.app.services.sending.EventRestorer" />
*
* }
- *
- *
- * Message sending example:
+ *
+ *
+ * Message sending example:
* {@code
* context.startService(MessageSendingService.createMessageIntent(
* context, url, race.getId(), eventId, serializedEventAsJson, callbackClass));
@@ -56,7 +56,7 @@ public class MessageSendingService extends Service implements MessageSendingList
public final static String CALLBACK_CLASS = "callback";
public final static String CALLBACK_PAYLOAD = "callbackPayload"; // passed back to callback
public final static String MESSAGE_ID = "messageId";
-
+
public static final String charsetName = "UTF-8";
protected final static String TAG = MessageSendingService.class.getName();
@@ -66,7 +66,7 @@ public class MessageSendingService extends Service implements MessageSendingList
private final IBinder mBinder = new MessageSendingBinder();
private MessagePersistenceManager persistenceManager;
private boolean isHandlerSet;
-
+
private Set suppressedMessageIds = new HashSet();
private APIConnectivityListener apiConnectivityListener;
@@ -86,9 +86,9 @@ public class MessageSendingService extends Service implements MessageSendingList
};
public interface MessageSendingServiceLogger {
- public void onMessageSentSuccessful();
+ void onMessageSentSuccessful();
- public void onMessageSentFailed();
+ void onMessageSentFailed();
}
public void setMessageSendingServiceLogger(MessageSendingServiceLogger logger) {
@@ -107,7 +107,7 @@ public class MessageSendingService extends Service implements MessageSendingList
}
private Date lastSuccessfulSend;
-
+
public List getDelayedIntentsContent() {
return persistenceManager.getContent();
}
@@ -119,16 +119,16 @@ public class MessageSendingService extends Service implements MessageSendingList
public Date getLastSuccessfulSend() {
return lastSuccessfulSend;
}
-
+
public void clearDelayedIntents() {
persistenceManager.removeAllMessages();
// let's fake a successful send!
serviceLogger.onMessageSentSuccessful();
}
- public static Intent createMessageIntent(Context context, String url,
- Serializable callbackPayload, Serializable messageId, String payload,
- Class extends ServerReplyCallback> callbackClass) {
+ public static Intent createMessageIntent(Context context, String url,
+ Serializable callbackPayload, Serializable messageId, String payload,
+ Class extends ServerReplyCallback> callbackClass) {
Intent messageIntent = new Intent(context, MessageSendingService.class);
messageIntent.setAction(context.getString(R.string.intent_send_message));
messageIntent.putExtra(CALLBACK_PAYLOAD, callbackPayload);
@@ -138,7 +138,7 @@ public class MessageSendingService extends Service implements MessageSendingList
messageIntent.putExtra(CALLBACK_CLASS, callbackClass == null ? null : callbackClass.getName());
return messageIntent;
}
-
+
public static Intent createSendDelayedIntent(Context context) {
Intent intent = new Intent(context, MessageSendingService.class);
intent.setAction(context.getString(R.string.intent_send_saved_intents));
@@ -153,7 +153,7 @@ public class MessageSendingService extends Service implements MessageSendingList
ExLog.w(this, TAG, "Unable to extract message identifier from message intent.");
return null;
}
-
+
private MessagePersistenceManager getPersistenceManager() {
ComponentName thisService = new ComponentName(this, this.getClass());
MessageRestorer restorer = null;
@@ -172,7 +172,7 @@ public class MessageSendingService extends Service implements MessageSendingList
} else {
@SuppressWarnings("unchecked")
// checked above
- Class castedClass = (Class) clazz;
+ Class castedClass = (Class) clazz;
restorer = castedClass.getConstructor().newInstance();
}
}
@@ -223,9 +223,9 @@ public class MessageSendingService extends Service implements MessageSendingList
}
private void handleSendMessages(Intent intent) {
- ExLog.i(this, TAG, String.format("Trying to send a message..."));
+ ExLog.i(this, TAG, "Trying to send a message...");
if (!isConnected()) {
- ExLog.i(this, TAG, String.format("Send aborted because there is no connection."));
+ ExLog.i(this, TAG, "Send aborted because there is no connection.");
try {
persistenceManager.persistIntent(intent);
} catch (UnsupportedEncodingException e) {
@@ -240,10 +240,10 @@ public class MessageSendingService extends Service implements MessageSendingList
}
private void handleDelayedMessages() {
- ExLog.i(this, TAG, String.format("Trying to resend stored messages..."));
+ ExLog.i(this, TAG, "Trying to resend stored messages...");
isHandlerSet = false;
if (!isConnected()) {
- ExLog.i(this, TAG, String.format("Resend aborted because there is no connection."));
+ ExLog.i(this, TAG, "Resend aborted because there is no connection.");
ConnectivityChangedReceiver.enable(this);
serviceLogger.onMessageSentFailed();
} else {
@@ -281,16 +281,15 @@ public class MessageSendingService extends Service implements MessageSendingList
}
@Override
- public void onMessageSent(Intent intent, boolean success, InputStream inputStream) {
- ExLog.i(this, "MS", "on message sent");
- int resendMillis = PrefUtils.getInt(this, R.string.preference_messageResendIntervalMillis_key,
- R.integer.preference_messageResendIntervalMillis_default);
- if (!success) {
- ExLog.i(this, "MS", "!success");
+ public void onMessageSent(MessageSenderResult result) {
+ ExLog.i(this, TAG, "onMessageSent");
+ int resendMillis = PrefUtils.getInt(this, R.string.preference_messageResendIntervalMillis_key, R.integer.preference_messageResendIntervalMillis_default);
+ if (!result.isSuccessful()) {
+ ExLog.i(this, TAG, "!success");
reportApiConnectivity(APIConnectivity.transmissionError);
ExLog.w(this, TAG, "Error while posting intent to server. Will persist intent...");
try {
- persistenceManager.persistIntent(intent);
+ persistenceManager.persistIntent(result.getIntent());
} catch (UnsupportedEncodingException e) {
ExLog.e(this, TAG, "Could not store message (unsupported encoding)");
}
@@ -302,12 +301,12 @@ public class MessageSendingService extends Service implements MessageSendingList
reportUnsentGPSFixesCount();
serviceLogger.onMessageSentFailed();
} else {
- ExLog.i(this, "MS", "success");
+ ExLog.i(this, TAG, "success");
reportApiConnectivity(APIConnectivity.transmissionSuccess);
ExLog.i(this, TAG, "Message successfully sent.");
if (persistenceManager.areIntentsDelayed()) {
try {
- persistenceManager.removeIntent(intent);
+ persistenceManager.removeIntent(result.getIntent());
} catch (UnsupportedEncodingException e) {
ExLog.e(this, TAG, "Could not remove message (unsupported encoding)");
}
@@ -316,8 +315,8 @@ public class MessageSendingService extends Service implements MessageSendingList
if (serviceLogger != null) {
serviceLogger.onMessageSentSuccessful();
}
-
- String callbackClassString = intent.getStringExtra(CALLBACK_CLASS);
+
+ String callbackClassString = result.getIntent().getStringExtra(CALLBACK_CLASS);
ServerReplyCallback callback = null;
if (callbackClassString != null) {
try {
@@ -328,51 +327,47 @@ public class MessageSendingService extends Service implements MessageSendingList
}
}
if (callback != null) {
- String raceId = intent.getStringExtra(CALLBACK_PAYLOAD);
- callback.processResponse(this, inputStream, raceId);
+ String raceId = result.getIntent().getStringExtra(CALLBACK_PAYLOAD);
+ callback.processResponse(this, result.getInputStream(), raceId);
}
- ExLog.i(this, "MS", "report");
+ ExLog.i(this, TAG, "report");
reportUnsentGPSFixesCount();
}
}
/**
* checks if there is network connectivity
- *
+ *
* @return connectivity check value
*/
private boolean isConnected() {
NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
- if (activeNetwork == null) {
- return false;
- }
- return activeNetwork.isConnected();
+ return activeNetwork != null && activeNetwork.isConnected();
}
-
+
/**
* a UUID that identifies this client session; can be used, e.g., to let the server identify subsequent requests coming from the same client
*/
public final static UUID uuid = UUID.randomUUID();
-
+
public static String getRaceLogEventSendAndReceiveUrl(Context context, final String raceGroupName,
- final String raceName, final String fleetName) throws UnsupportedEncodingException {
- String url = String.format("%s/sailingserver/rc/racelog?"+
- RaceLogServletConstants.PARAMS_LEADERBOARD_NAME+"=%s&"+
- RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME+"=%s&"+
- RaceLogServletConstants.PARAMS_RACE_FLEET_NAME+"=%s&"+
- RaceLogServletConstants.PARAMS_CLIENT_UUID+"=%s",
+ final String raceName, final String fleetName) throws UnsupportedEncodingException {
+ String url = String.format("%s/sailingserver/rc/racelog?" +
+ RaceLogServletConstants.PARAMS_LEADERBOARD_NAME + "=%s&" +
+ RaceLogServletConstants.PARAMS_RACE_COLUMN_NAME + "=%s&" +
+ RaceLogServletConstants.PARAMS_RACE_FLEET_NAME + "=%s&" +
+ RaceLogServletConstants.PARAMS_CLIENT_UUID + "=%s",
PrefUtils.getString(context, R.string.preference_server_url_key, R.string.preference_server_url_default),
URLEncoder.encode(raceGroupName, charsetName),
- URLEncoder.encode(raceName, charsetName),
- URLEncoder.encode(fleetName, charsetName), uuid);
+ URLEncoder.encode(raceName, charsetName),
+ URLEncoder.encode(fleetName, charsetName), uuid);
return url;
}
/**
* Register listener for API-connectivity
*
- * @param listener
- * class that wants to be notified of api-connectivity changes
+ * @param listener class that wants to be notified of api-connectivity changes
*/
public void registerAPIConnectivityListener(APIConnectivityListener listener) {
apiConnectivityListener = listener;
@@ -424,8 +419,6 @@ public class MessageSendingService extends Service implements MessageSendingList
/**
* Report the number of currently unsent GPS-fixes
- *
- * @param unsentGPSFixesCount
*/
private void reportUnsentGPSFixesCount() {
if (apiConnectivityListener != null) {
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/activities/SendingServiceAwareActivity.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/activities/SendingServiceAwareActivity.java
index 21b552c66e5..bea1680d8ea 100644
--- a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/activities/SendingServiceAwareActivity.java
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/ui/activities/SendingServiceAwareActivity.java
@@ -20,7 +20,7 @@ import com.sap.sailing.android.shared.services.sending.MessageSendingService.Mes
import com.sap.sailing.android.shared.util.PrefUtils;
public abstract class SendingServiceAwareActivity extends ResilientActivity {
-
+
private class MessageSendingServiceConnection implements ServiceConnection, MessageSendingServiceLogger {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
@@ -55,9 +55,9 @@ public abstract class SendingServiceAwareActivity extends ResilientActivity {
protected boolean boundSendingService = false;
protected MessageSendingService sendingService;
private MessageSendingServiceConnection sendingServiceConnection;
-
+
private String sendingServiceStatus = "";
-
+
public SendingServiceAwareActivity() {
this.sendingServiceConnection = new MessageSendingServiceConnection();
}
@@ -65,15 +65,15 @@ public abstract class SendingServiceAwareActivity extends ResilientActivity {
@Override
public void onStart() {
super.onStart();
-
+
Intent intent = new Intent(this, MessageSendingService.class);
bindService(intent, sendingServiceConnection, Context.BIND_AUTO_CREATE);
}
-
+
@Override
public void onStop() {
super.onStop();
-
+
if (boundSendingService) {
unbindService(sendingServiceConnection);
boundSendingService = false;
@@ -83,28 +83,27 @@ public abstract class SendingServiceAwareActivity extends ResilientActivity {
protected void updateSendingServiceInformation() {
if (menuItemLive == null)
return;
-
+
if (!boundSendingService)
return;
-
- int errorCount = this.sendingService.getDelayedIntentsCount();
+
+ int errorCount = sendingService.getDelayedIntentsCount();
if (errorCount > 0) {
menuItemLive.setIcon(R.drawable.ic_menu_share_red);
Date lastSuccessfulSend = this.sendingService.getLastSuccessfulSend();
- sendingServiceStatus = String.format("Currently %d events waiting to be sent.\nLast successful sent was at %s",
- errorCount, lastSuccessfulSend == null ? "never" : lastSuccessfulSend);
+ sendingServiceStatus = getString(R.string.sending_waiting, errorCount, lastSuccessfulSend == null ? "never" : lastSuccessfulSend);
} else {
menuItemLive.setIcon(R.drawable.ic_menu_share);
- sendingServiceStatus = String.format("Currently no event waiting to be sent.", errorCount);
+ sendingServiceStatus = getString(R.string.sending_no_waiting);
}
}
-
+
/**
* @return the resource ID for the options menu, {@code 0} if none.
- * The menu item displaying the connection status is added automatically.
+ * The menu item displaying the connection status is added automatically.
*/
protected abstract int getOptionsMenuResId();
-
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
@@ -115,7 +114,7 @@ public abstract class SendingServiceAwareActivity extends ResilientActivity {
}
return true;
}
-
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (R.id.options_menu_live == item.getItemId()) {
@@ -126,7 +125,7 @@ public abstract class SendingServiceAwareActivity extends ResilientActivity {
return super.onOptionsItemSelected(item);
}
}
-
+
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
updateSendingServiceInformation();
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/AuthCheckTask.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/AuthCheckTask.java
new file mode 100644
index 00000000000..547ca6b78ff
--- /dev/null
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/AuthCheckTask.java
@@ -0,0 +1,78 @@
+package com.sap.sailing.android.shared.util;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+
+import android.content.Context;
+import android.os.AsyncTask;
+
+import com.sap.sailing.android.shared.data.http.HttpJsonGetRequest;
+import com.sap.sailing.android.shared.data.http.HttpRequest;
+import com.sap.sailing.android.shared.logging.ExLog;
+
+public class AuthCheckTask extends AsyncTask {
+
+ private static final String TAG = AuthCheckTask.class.getName();
+
+ private final static String HELLO_REQUEST = "/security/api/restsecurity/hello";
+
+ private Context context;
+ private URL url;
+ private AuthCheckTaskListener listener;
+ private Exception exception;
+
+ public AuthCheckTask(Context ctx, String baseUrl, AuthCheckTaskListener taskListener) {
+ try {
+ context = ctx;
+ url = new URL(baseUrl + HELLO_REQUEST);
+ listener = taskListener;
+ } catch (MalformedURLException e) {
+ ExLog.e(context, TAG, "Error: Failed to perform checking due to a MalformedURLException: " + e.getMessage());
+ }
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... params) {
+ Boolean authenticated = false;
+ if (url != null) {
+ try {
+ HttpRequest request = new HttpJsonGetRequest(url, context);
+ InputStream responseStream = request.execute();
+
+ JSONParser parser = new JSONParser();
+ JSONObject json = (JSONObject) parser.parse(new InputStreamReader(responseStream));
+ if (json.containsKey("authenticated")) {
+ authenticated = (Boolean) json.get("authenticated");
+ }
+ } catch (Exception e) {
+ exception = e;
+ }
+ } else {
+ exception = new IllegalArgumentException();
+ }
+ return authenticated;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean authenticated) {
+ super.onPostExecute(authenticated);
+ if (listener != null) {
+ if (exception != null) {
+ listener.onException(exception);
+ } else {
+ listener.onRequestReceived(authenticated);
+ }
+ }
+ }
+
+ public interface AuthCheckTaskListener {
+ void onRequestReceived(Boolean authenticated);
+
+ void onException(Exception exception);
+ }
+}
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/LoginTask.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/LoginTask.java
new file mode 100644
index 00000000000..b10cd51b2d9
--- /dev/null
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/LoginTask.java
@@ -0,0 +1,77 @@
+package com.sap.sailing.android.shared.util;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+
+import android.content.Context;
+import android.os.AsyncTask;
+
+import com.sap.sailing.android.shared.data.LoginData;
+import com.sap.sailing.android.shared.data.http.HttpRequest;
+import com.sap.sailing.android.shared.data.http.LoginGetRequest;
+import com.sap.sailing.android.shared.logging.ExLog;
+
+public class LoginTask extends AsyncTask {
+
+ private static final String TAG = LoginTask.class.getName();
+
+ private final static String TOKEN_REQUEST = "/security/api/restsecurity/access_token";
+
+ private URL url = null;
+ private Context context;
+ private LoginTaskListener listener;
+ private Exception exception;
+
+ public LoginTask(Context context, String baseUrl, LoginTaskListener listener) {
+ try {
+ this.context = context.getApplicationContext();
+ this.url = new URL(baseUrl + TOKEN_REQUEST);
+ this.listener = listener;
+ } catch (MalformedURLException e) {
+ ExLog.e(context, TAG, "Error: Failed to perform checking due to a MalformedURLException: " + e.getMessage());
+ }
+ }
+
+ @Override
+ protected String doInBackground(LoginData... params) {
+ String access_token = null;
+ if (url != null && params != null && params.length > 0) {
+ try {
+ HttpRequest request = new LoginGetRequest(url, context, params[0]);
+ InputStream responseStream = request.execute();
+
+ JSONParser parser = new JSONParser();
+ JSONObject result = (JSONObject) parser.parse(new InputStreamReader(responseStream));
+ access_token = (String) result.get("access_token");
+ } catch (Exception e) {
+ exception = e;
+ }
+ } else {
+ exception = new IllegalArgumentException();
+ }
+ return access_token;
+ }
+
+ @Override
+ protected void onPostExecute(String accessToken) {
+ super.onPostExecute(accessToken);
+ if (listener != null) {
+ if (exception != null) {
+ listener.onException(exception);
+ } else {
+ listener.onTokenReceived(accessToken);
+ }
+ }
+ }
+
+ public interface LoginTaskListener {
+ void onTokenReceived(String accessToken);
+
+ void onException(Exception exception);
+ }
+}
diff --git a/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/LogoutTask.java b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/LogoutTask.java
new file mode 100644
index 00000000000..16ee0a7cabe
--- /dev/null
+++ b/mobile/com.sap.sailing.android.shared/src/com/sap/sailing/android/shared/util/LogoutTask.java
@@ -0,0 +1,44 @@
+package com.sap.sailing.android.shared.util;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import android.content.Context;
+import android.os.AsyncTask;
+
+import com.sap.sailing.android.shared.data.http.HttpJsonGetRequest;
+import com.sap.sailing.android.shared.data.http.HttpRequest;
+import com.sap.sailing.android.shared.logging.ExLog;
+
+public class LogoutTask extends AsyncTask {
+
+ private static final String TAG = LogoutTask.class.getName();
+ private static final String LOGOUT_REQUEST = "/security/api/restsecurity/remove_access_token";
+
+ private Context context;
+ private URL url;
+
+ public LogoutTask(Context ctx, String baseUrl) {
+ context = ctx;
+ try {
+ url = new URL(baseUrl + LOGOUT_REQUEST);
+ } catch (MalformedURLException e) {
+ ExLog.e(context, TAG, "Error: Failed to perform checking due to a MalformedURLException: " + e.getMessage());
+
+ }
+ }
+
+ @Override
+ protected Void doInBackground(String... params) {
+ if (url != null && params != null && params.length > 0) {
+ HttpRequest request = new HttpJsonGetRequest(url, context);
+ try {
+ request.execute();
+ } catch (IOException e) {
+ ExLog.e(context, TAG, "Logout not possible: " + e.getMessage());
+ }
+ }
+ return null;
+ }
+}
diff --git a/mobile/com.sap.sailing.android.tracking.app/build.gradle b/mobile/com.sap.sailing.android.tracking.app/build.gradle
index 6ab855a8544..28f1e791c1f 100644
--- a/mobile/com.sap.sailing.android.tracking.app/build.gradle
+++ b/mobile/com.sap.sailing.android.tracking.app/build.gradle
@@ -75,7 +75,7 @@ dependencies {
compile "com.google.android.gms:play-services-gcm:${rootProject.ext.play_services}"
compile "com.google.android.gms:play-services-location:${rootProject.ext.play_services}"
- /* licence dialog */
+ /* license dialog */
compile("de.psdev.licensesdialog:licensesdialog:${rootProject.ext.license_dialog}")
/* local dependencies */
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/AboutFragment.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/AboutFragment.java
index 7d6f5906003..076458c080c 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/AboutFragment.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/AboutFragment.java
@@ -28,10 +28,10 @@ public class AboutFragment extends com.sap.sailing.android.ui.fragments.BaseFrag
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_about, container, false);
- view.findViewById(R.id.licence_button).setOnClickListener(new View.OnClickListener() {
+ view.findViewById(R.id.license_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- showLicenceDialog();
+ showLicenseDialog();
}
});
view.findViewById(R.id.eula_button).setOnClickListener(new View.OnClickListener() {
@@ -45,7 +45,7 @@ public class AboutFragment extends com.sap.sailing.android.ui.fragments.BaseFrag
return view;
}
- private void showLicenceDialog() {
+ private void showLicenseDialog() {
Notices notices = new Notices();
LicenseHelper licenseHelper = new LicenseHelper();
notices.addNotice(licenseHelper.getAndroidSupportNotice());
@@ -53,7 +53,7 @@ public class AboutFragment extends com.sap.sailing.android.ui.fragments.BaseFrag
notices.addNotice(licenseHelper.getJsonSimpleNotice());
notices.addNotice(licenseHelper.getDialogNotice());
LicensesDialog.Builder builder = new LicensesDialog.Builder(getActivity());
- builder.setTitle(getString(R.string.licence_information));
+ builder.setTitle(getString(R.string.license_information));
builder.setNotices(notices);
builder.build().show();
}
diff --git a/mobile/com.sap.sailing.buoy.positioning/build.gradle b/mobile/com.sap.sailing.buoy.positioning/build.gradle
index ea9b08f4f89..6eea899e38c 100644
--- a/mobile/com.sap.sailing.buoy.positioning/build.gradle
+++ b/mobile/com.sap.sailing.buoy.positioning/build.gradle
@@ -74,7 +74,7 @@ dependencies {
/* Google Play Services */
compile "com.google.android.gms:play-services-location:${rootProject.ext.play_services}"
- /* licence dialog */
+ /* license dialog */
compile("de.psdev.licensesdialog:licensesdialog:${rootProject.ext.license_dialog}")
/* local dependencies */
diff --git a/mobile/com.sap.sailing.buoy.positioning/src/com/sap/sailing/android/buoy/positioning/app/ui/fragments/AboutFragment.java b/mobile/com.sap.sailing.buoy.positioning/src/com/sap/sailing/android/buoy/positioning/app/ui/fragments/AboutFragment.java
index 0c9e56c2652..25cc30fc0f0 100644
--- a/mobile/com.sap.sailing.buoy.positioning/src/com/sap/sailing/android/buoy/positioning/app/ui/fragments/AboutFragment.java
+++ b/mobile/com.sap.sailing.buoy.positioning/src/com/sap/sailing/android/buoy/positioning/app/ui/fragments/AboutFragment.java
@@ -29,10 +29,10 @@ public class AboutFragment extends BaseFragment {
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_about, container, false);
- view.findViewById(R.id.licence_button).setOnClickListener(new View.OnClickListener() {
+ view.findViewById(R.id.license_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- showLicenceDialog();
+ showLicenseDialog();
}
});
view.findViewById(R.id.eula_button).setOnClickListener(new View.OnClickListener() {
@@ -46,7 +46,7 @@ public class AboutFragment extends BaseFragment {
return view;
}
- private void showLicenceDialog() {
+ private void showLicenseDialog() {
Notices notices = new Notices();
LicenseHelper licenseHelper = new LicenseHelper();
notices.addNotice(licenseHelper.getAndroidSupportNotice());
@@ -54,7 +54,7 @@ public class AboutFragment extends BaseFragment {
notices.addNotice(licenseHelper.getJsonSimpleNotice());
notices.addNotice(licenseHelper.getDialogNotice());
LicensesDialog.Builder builder = new LicensesDialog.Builder(getActivity());
- builder.setTitle(getString(R.string.licence_information));
+ builder.setTitle(getString(R.string.license_information));
builder.setNotices(notices);
builder.build().show();
}
diff --git a/mobile/com.sap.sailing.racecommittee.app/AndroidManifest.xml b/mobile/com.sap.sailing.racecommittee.app/AndroidManifest.xml
index ff63e9cb333..00b33d16cf3 100644
--- a/mobile/com.sap.sailing.racecommittee.app/AndroidManifest.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/AndroidManifest.xml
@@ -53,6 +53,7 @@
+
diff --git a/mobile/com.sap.sailing.racecommittee.app/build.gradle b/mobile/com.sap.sailing.racecommittee.app/build.gradle
index 63ec0abbc4d..ff444e72e88 100644
--- a/mobile/com.sap.sailing.racecommittee.app/build.gradle
+++ b/mobile/com.sap.sailing.racecommittee.app/build.gradle
@@ -82,7 +82,7 @@ dependencies {
/* Google Play Services */
compile "com.google.android.gms:play-services-location:${rootProject.ext.play_services}"
- /* licence dialog */
+ /* license dialog */
compile("de.psdev.licensesdialog:licensesdialog:${rootProject.ext.license_dialog}")
/* local dependencies */
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable-hdpi/ic_change_role_white_48dp.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable-hdpi/ic_change_role_white_48dp.png
new file mode 100644
index 00000000000..c29cb246f25
Binary files /dev/null and b/mobile/com.sap.sailing.racecommittee.app/res/drawable-hdpi/ic_change_role_white_48dp.png differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable-mdpi/ic_change_role_white_48dp.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable-mdpi/ic_change_role_white_48dp.png
new file mode 100644
index 00000000000..e966f5104b8
Binary files /dev/null and b/mobile/com.sap.sailing.racecommittee.app/res/drawable-mdpi/ic_change_role_white_48dp.png differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable-xhdpi/ic_change_role_white_48dp.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable-xhdpi/ic_change_role_white_48dp.png
new file mode 100644
index 00000000000..b811a20b301
Binary files /dev/null and b/mobile/com.sap.sailing.racecommittee.app/res/drawable-xhdpi/ic_change_role_white_48dp.png differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxhdpi/ic_change_role_white_48dp.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxhdpi/ic_change_role_white_48dp.png
new file mode 100644
index 00000000000..02076b894fb
Binary files /dev/null and b/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxhdpi/ic_change_role_white_48dp.png differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxxhdpi/ic_change_role_white_48dp.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxxhdpi/ic_change_role_white_48dp.png
new file mode 100644
index 00000000000..e4cf3914bd9
Binary files /dev/null and b/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxxhdpi/ic_change_role_white_48dp.png differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable/nav_drawer_header.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable/nav_drawer_header.png
index 01fab551c38..b4255dc43b6 100644
Binary files a/mobile/com.sap.sailing.racecommittee.app/res/drawable/nav_drawer_header.png and b/mobile/com.sap.sailing.racecommittee.app/res/drawable/nav_drawer_header.png differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable/round_button_no_fill.xml b/mobile/com.sap.sailing.racecommittee.app/res/drawable/round_button_no_fill.xml
new file mode 100644
index 00000000000..cdff28030c2
--- /dev/null
+++ b/mobile/com.sap.sailing.racecommittee.app/res/drawable/round_button_no_fill.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable/round_button_transparent.xml b/mobile/com.sap.sailing.racecommittee.app/res/drawable/round_button_transparent.xml
new file mode 100644
index 00000000000..18e08d92f52
--- /dev/null
+++ b/mobile/com.sap.sailing.racecommittee.app/res/drawable/round_button_transparent.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/accuracy.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/accuracy.xml
index 80cc48ade0c..bb56ef5802b 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/accuracy.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/accuracy.xml
@@ -29,7 +29,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_normal.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_normal.xml
index b068025f5b0..3f263645f15 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_normal.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_normal.xml
@@ -1,25 +1,54 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ android:src="@drawable/backdrop"/>
+ android:src="@drawable/sap_logo"/>
+
+
+
+
+
+
+
+
+
+
+ android:textSize="@dimen/textSize_40"/>
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:alpha="0"
+ android:background="@color/constant_black_transparent">
+ android:orientation="horizontal">
+ android:src="@drawable/ic_more_vert_white_48dp"/>
-
-
+ android:textSize="@dimen/textSize_40"/>
+ android:background="?attr/sap_yellow_1"/>
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_onboarding.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_onboarding.xml
new file mode 100644
index 00000000000..7316f279119
--- /dev/null
+++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_onboarding.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_xlarge.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_xlarge.xml
index eb1d9fc0564..8572902249a 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_xlarge.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_backdrop_xlarge.xml
@@ -1,15 +1,15 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ android:src="@drawable/backdrop"/>
+ android:src="@drawable/sap_logo"/>
+
+
+
+
+
+
+
+
+
+
+ android:textSize="@dimen/textSize_40"/>
+ android:alpha="0"
+ android:background="@color/constant_black_transparent">
+ android:orientation="horizontal">
+ android:src="@drawable/ic_settings_white_48dp"/>
+ android:src="@drawable/ic_info_outline_white_48dp"/>
+ android:src="@drawable/ic_refresh_white_48dp"/>
-
-
+ android:textSize="@dimen/textSize_40"/>
+ android:background="?attr/sap_yellow_1"/>
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding.xml
deleted file mode 100644
index c39e473a608..00000000000
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_edit.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_edit.xml
index 3ecb52b4392..c11c89a70c9 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_edit.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_edit.xml
@@ -1,39 +1,49 @@
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="@dimen/side_padding">
-
-
-
-
-
+ app:floatLabelPaddingLeft="@dimen/float_label_padding"
+ app:floatLabelTextAppearance="?attr/floatLabel">
-
+
+
+
+ android:layout_marginTop="@dimen/side_padding"
+ android:visibility="gone"
+ app:floatLabelPaddingLeft="@dimen/float_label_padding"
+ app:floatLabelTextAppearance="?attr/floatLabel"
+ tools:visibility="visible">
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_input_normal.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_input_normal.xml
deleted file mode 100644
index f7fc769e37c..00000000000
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_input_normal.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_input_xlarge.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_input_xlarge.xml
deleted file mode 100644
index 9a7e775e692..00000000000
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_input_xlarge.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_scan_normal.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_scan_normal.xml
deleted file mode 100644
index 3856e077065..00000000000
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_scan_normal.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_scan_xlarge.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_scan_xlarge.xml
deleted file mode 100644
index bc9017f6a44..00000000000
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_onboarding_scan_xlarge.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_view.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_view.xml
index 4040b5df015..582a58309c5 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/login_view.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/login_view.xml
@@ -19,13 +19,6 @@
android:layout_gravity="center_horizontal|bottom"
tools:layout="@layout/login_listviews"/>
-
-
+ android:layout_height="match_parent">
@@ -77,6 +77,7 @@
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
+ android:alpha=".5"
android:background="@color/lock_background"
android:padding="@dimen/panel_lock_padding"
android:visibility="gone"
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/password_activity.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/password_activity.xml
new file mode 100644
index 00000000000..961e63333f8
--- /dev/null
+++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/password_activity.xml
@@ -0,0 +1,7 @@
+
+
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/race_list_header_content.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/race_list_header_content.xml
index 3e192131644..88b2d17c939 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/race_list_header_content.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/race_list_header_content.xml
@@ -26,7 +26,7 @@
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_margin="@dimen/default_margin"
- android:src="@drawable/ic_logout_white_48dp"/>
+ android:src="@drawable/ic_change_role_white_48dp"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:text="@string/license_information"/>
+ android:text="@string/license_information"/>
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/menu/options_menu.xml b/mobile/com.sap.sailing.racecommittee.app/res/menu/options_menu.xml
index 704fab3ccd9..f3b3e6c599d 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/menu/options_menu.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/menu/options_menu.xml
@@ -12,4 +12,8 @@
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml b/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml
index 8506c5ad3be..11475c2c3df 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml
@@ -174,8 +174,10 @@
Nationalität
Nummer
Fotos schießen
- Möchten Sie sich abmelden?
- Wenn Sie sich abmelden, wird kein Rennen mehr verwaltet.
+ @string/logout
+ Wollen Sie sich abmelden und als neuer Nutzer anmelden. Ihre Rennen bleiben im Hintergrund erhalten.
+ Ummelden
+ Wenn Sie sich ummelden, wird kein Rennen mehr auf der aktuellen Bahn mehr verwaltet.
Abmelden
Lade Konfiguration…
Fehler beim Laden der Konfiguration.
@@ -254,7 +256,7 @@
Wenn aktiv kann man sich im Demo-Modus anmelden. Im Demo-Modus werden keine Rennänderungen an den Server geschickt.
Events geladen.
Verfügbare Rennen
- ÄNDERN
+ Ändern
Gestartet %s
Beendet %s
Wind
@@ -464,7 +466,20 @@
Group Race
Select Race
Getting Started
- http://www.sapsailing.com/gwt/Home.html?locale=de#SolutionsPlace:navigationTab=RaceCommitteeApp
+ https://www.sapsailing.com/gwt/Home.html?locale=de#SolutionsPlace:navigationTab=RaceCommitteeApp
Request fehlgeschlagen. User ist nicht autorisiert.
+ Server
+ Nutzername
+ Passwort
+ Nutzername oder Passwort ungültig
+ Ein unerwarteter Fehler ist aufgetreten
+ Warnung
+ Sie haben wahrscheinlich nicht die Befugnis Daten an den Server zu schicken. Möchten Sie sich als andere Nutzer anmelden?
+
+ Ein
+ Aus
+ Rechtweisend
+ Missweisend
+ Kursanzeige
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values-sw720dp/references.xml b/mobile/com.sap.sailing.racecommittee.app/res/values-sw720dp/references.xml
index 03249a3a0ac..c63fad1e780 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values-sw720dp/references.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values-sw720dp/references.xml
@@ -7,8 +7,6 @@
- @layout/flag_list_item_xlarge
- @layout/login_backdrop_xlarge
- @layout/login_listviews_button_xlarge
- - @layout/login_onboarding_scan_xlarge
- - @layout/login_onboarding_input_xlarge
- @layout/photo_list_button_xlarge
- @layout/photo_list_item_xlarge
- @layout/race_finishing_button_xlarge
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values-v21/dimen.xml b/mobile/com.sap.sailing.racecommittee.app/res/values-v21/dimen.xml
new file mode 100644
index 00000000000..74c0477fe23
--- /dev/null
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values-v21/dimen.xml
@@ -0,0 +1,6 @@
+
+
+
+ 3dp
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values/attrs.xml b/mobile/com.sap.sailing.racecommittee.app/res/values/attrs.xml
index d0f8fd23b31..cecc7ea40c9 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values/attrs.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values/attrs.xml
@@ -22,6 +22,7 @@
+
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values/dimens.xml b/mobile/com.sap.sailing.racecommittee.app/res/values/dimens.xml
index a7cb7755aa3..80a38c20a6d 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values/dimens.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values/dimens.xml
@@ -22,6 +22,8 @@
2dp
3dp
+ 9dp
+
12sp
14sp
16sp
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values/preferences.xml b/mobile/com.sap.sailing.racecommittee.app/res/values/preferences.xml
index 8cde9e5f53c..298da4716b6 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values/preferences.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values/preferences.xml
@@ -19,7 +19,7 @@
mailRecipientPreference
- lukas.niemeier@sap.com
+
pollingActivePreference
true
@@ -76,7 +76,9 @@
false
basicIndividualRecall
-
+ preferenceHeadingWithDeclinationSubtracted
+ true
+
racecommittee
false
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values/references.xml b/mobile/com.sap.sailing.racecommittee.app/res/values/references.xml
index f3bdfb957db..36ce2c7c331 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values/references.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values/references.xml
@@ -8,8 +8,6 @@
- @layout/flag_list_item_normal
- @layout/login_backdrop_normal
- @layout/login_listviews_button_normal
- - @layout/login_onboarding_scan_normal
- - @layout/login_onboarding_input_normal
- @layout/photo_list_button_normal
- @layout/photo_list_item_normal
- @layout/race_finished_normal
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml b/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml
index 6c2e499a2a0..c13f9cca623 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml
@@ -185,8 +185,10 @@
Set tracking list
Confirm tracking list
Snap
- Are you sure want to logout?
- Logging out stops automatic monitoring for all races.
+ Sign out
+ Do you want to sign out and sign in as a new user? All your races will still be monitored.
+ Change Regatta
+ Do you want to change a regatta and/or the area? Currently monitored races will be disconnected.
Logout
Loading configuration…
There was an error loading the configuration.
@@ -206,7 +208,7 @@
Pathfinder
Activate this option to enable choosing the additional Golf-Down time
Additional Golf-down time
- Device identifier
+ Device Name
Synchronize with server
When creating a configuration on the server, click here to synchronize your app and connection settings via QRCode.
Force update
@@ -286,7 +288,7 @@
ALL RACES
WELCOME
- CHANGE
+ Change
Procedure
More
@@ -491,7 +493,20 @@
Group Racing
Select Race
Getting Started
- http://www.sapsailing.com/gwt/Home.html?locale=en#SolutionsPlace:navigationTab=RaceCommitteeApp
+ https://www.sapsailing.com/gwt/Home.html?locale=en#SolutionsPlace:navigationTab=RaceCommitteeApp
Request failed. User is unauthorized.
+ Server
+ Username
+ Password
+ Username or password invalid
+ An unexpected error occurred
+ Warning
+ You probably don\'t have the permission to send data to the server. Do you want to change your login credentials?
+
+ On
+ Off
+ Magnetic
+ North-based
+ Heading
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values/themes_dark.xml b/mobile/com.sap.sailing.racecommittee.app/res/values/themes_dark.xml
index d06d92230ba..7ddb0891382 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values/themes_dark.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values/themes_dark.xml
@@ -37,6 +37,7 @@
- @style/AppTheme.Dark.Button.Small
- @style/AppTheme.Dark.Button.Normal
- @style/AppTheme.Dark.Round
+ - @style/AppTheme.Dark.RoundTransparent
- @style/AppTheme.Dark.Text
- @style/AppTheme.Dark.Text.XXSmall
- @style/AppTheme.Dark.Text.XSmall
@@ -123,6 +124,11 @@
- @dimen/logout_padding
+
+
+
+