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 d80170db093..186fc289800 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
@@ -267,6 +267,7 @@
Kurs
Zieleinlauf
Verschieben
+ von abhängigen Rennen
%2$s / %1$s kn
http://maps.googleapis.com/maps/api/geocode/json?address=
\?sensor=true
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 82318e4453e..447c41cf5a7 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml
@@ -308,6 +308,7 @@
Course
Finish
Postpone
+ of dependent races
Select a Race
Pathfinder
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/RacingActivity.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/RacingActivity.java
index b8f2a462cea..4a2c023f8a5 100755
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/RacingActivity.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/RacingActivity.java
@@ -21,6 +21,7 @@ import android.os.Build;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AlertDialog;
@@ -40,6 +41,8 @@ import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.AppUtils;
import com.sap.sailing.android.shared.util.CollectionUtils;
import com.sap.sailing.android.shared.util.ViewHelper;
+import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
+import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.common.Wind;
@@ -47,6 +50,7 @@ import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.data.DataManager;
+import com.sap.sailing.racecommittee.app.data.DataStore;
import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager;
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
@@ -69,6 +73,7 @@ import com.sap.sailing.racecommittee.app.ui.views.PanelButton;
import com.sap.sailing.racecommittee.app.utils.BitmapHelper;
import com.sap.sailing.racecommittee.app.utils.RaceHelper;
import com.sap.sse.common.TimePoint;
+import com.sap.sse.common.Util;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class RacingActivity extends SessionActivity implements RaceListCallbacks {
@@ -86,6 +91,7 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
private RaceListFragment mRaceList;
private ManagedRace mSelectedRace;
private TimePoint startTime;
+ private Collection lastSeenRaces = null;
private Serializable getCourseAreaIdFromIntent() {
if (getIntent() == null || getIntent().getExtras() == null) {
@@ -453,6 +459,31 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
return null;
}
+ public List getChildRaces(ManagedRace currentRace, @Nullable RaceLogRaceStatus[] state) {
+ StartTimeFinderResult result;
+ SimpleRaceLogIdentifier identifier;
+ ArrayList list = new ArrayList<>();
+ DataStore dataStore = dataManager.getDataStore();
+ for (ManagedRace race : lastSeenRaces) {
+ result = race.getState().getStartTimeFinderResult();
+ if (result.isDependentStartTime()) {
+ identifier = Util.get(result.getRacesDependingOn(), 0);
+ if (dataStore.getRace(identifier).equals(currentRace)) {
+ if (state == null) {
+ list.add(race);
+ } else {
+ for (RaceLogRaceStatus status : state) {
+ if (status.equals(race.getStatus())) {
+ list.add(race);
+ }
+ }
+ }
+ }
+ }
+ }
+ return list;
+ }
+
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void setOverflowIcon() {
// Required to set overflow icon
@@ -472,7 +503,9 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
TintImageView overflow = (TintImageView) outViews.get(0);
overflow.setMinimumWidth(getResources().getDimensionPixelSize(R.dimen.bigger_over_flow_width));
overflow.setMinimumHeight(getResources().getDimensionPixelSize(R.dimen.bigger_over_flow_height));
- Bitmap bitmap = BitmapHelper.decodeSampledBitmapFromResource(getResources(), R.drawable.ic_more_vert_white_48dp, overflow.getMinimumWidth(), overflow.getMinimumHeight());
+ Bitmap bitmap = BitmapHelper
+ .decodeSampledBitmapFromResource(getResources(), R.drawable.ic_more_vert_white_48dp, overflow.getMinimumWidth(), overflow
+ .getMinimumHeight());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
overflow.setScaleType(ImageView.ScaleType.FIT_END);
}
@@ -559,7 +592,6 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
private class RaceLoadClient implements LoadClient> {
private CourseArea courseArea;
- private Collection lastSeenRaces = null;
public RaceLoadClient(CourseArea courseArea) {
this.courseArea = courseArea;
@@ -570,16 +602,15 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
setProgressSpinnerVisibility(false);
AlertDialog.Builder builder = new AlertDialog.Builder(RacingActivity.this, R.style.AppTheme_AlertDialog);
builder.setMessage(String.format(getString(R.string.generic_load_failure), ex.getMessage())).setTitle(getString(R.string.loading_failure))
- .setIcon(R.drawable.ic_warning_grey_600_36dp).setCancelable(true)
- .setPositiveButton(getString(R.string.retry), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- setProgressSpinnerVisibility(true);
+ .setCancelable(true).setPositiveButton(getString(R.string.retry), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ setProgressSpinnerVisibility(true);
- ExLog.i(RacingActivity.this, TAG, "Issuing a reload of managed races");
- getLoaderManager().restartLoader(RacesLoaderId, null, dataManager.createRacesLoader(courseArea.getId(), RaceLoadClient.this));
- dialog.cancel();
- }
- }).setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
+ ExLog.i(RacingActivity.this, TAG, "Issuing a reload of managed races");
+ getLoaderManager().restartLoader(RacesLoaderId, null, dataManager.createRacesLoader(courseArea.getId(), RaceLoadClient.this));
+ dialog.cancel();
+ }
+ }).setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/AbortFlagsFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/AbortFlagsFragment.java
index 5aa08c6ddec..50c834c2de9 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/AbortFlagsFragment.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/AbortFlagsFragment.java
@@ -1,6 +1,11 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.content.DialogInterface;
import android.os.Bundle;
+import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -10,14 +15,19 @@ import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.ViewHelper;
import com.sap.sailing.domain.abstractlog.race.state.RaceState;
import com.sap.sailing.domain.common.racelog.Flags;
+import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.racecommittee.app.AppConstants;
import com.sap.sailing.racecommittee.app.R;
+import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.logging.LogEvent;
+import com.sap.sailing.racecommittee.app.ui.activities.RacingActivity;
import com.sap.sailing.racecommittee.app.ui.adapters.AbortFlagsAdapter;
import com.sap.sailing.racecommittee.app.ui.adapters.AbortFlagsAdapter.AbortFlagItemClick;
import com.sap.sailing.racecommittee.app.ui.fragments.RaceFragment;
import com.sap.sailing.racecommittee.app.ui.fragments.RaceListFragment;
import com.sap.sailing.racecommittee.app.ui.layouts.HeaderLayout;
+import com.sap.sailing.racecommittee.app.utils.RaceHelper;
+import com.sap.sse.common.Duration;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
@@ -69,42 +79,40 @@ public class AbortFlagsFragment extends RaceFragment implements AbortFlagItemCli
RaceState state = getRaceState();
Flags mainFlag = Flags.valueOf(getArguments().getString(AppConstants.FLAG_KEY));
switch (mainFlag) {
- case AP:
- logFlag(flag);
- state.setAborted(now, /* postponed */ true, flag);
- if (flag != Flags.NONE) {
- setProtestTime();
- }
- break;
+ case AP:
+ logFlag(flag);
+ state.setAborted(now, /* postponed */ true, flag);
+ if (flag != Flags.NONE) {
+ setProtestTime();
+ }
+ state.setAdvancePass(now);
+ break;
- case NOVEMBER:
- logFlag(flag);
- state.setAborted(now, /* postponed */ false, flag);
- if (flag != Flags.NONE) {
- setProtestTime();
- }
- break;
+ case NOVEMBER:
+ logFlag(flag);
+ abortChildRaces(now, state, flag);
+ break;
- default:
- logFlag(flag);
- break;
+ default:
+ logFlag(flag);
+ state.setAdvancePass(now);
+ break;
}
- state.setAdvancePass(now);
}
private void logFlag(Flags flag) {
switch (flag) {
- case ALPHA:
- ExLog.i(getActivity(), LogEvent.RACE_CHOOSE_ABORT_ALPHA, getRace().getId());
- break;
+ case ALPHA:
+ ExLog.i(getActivity(), LogEvent.RACE_CHOOSE_ABORT_ALPHA, getRace().getId());
+ break;
- case HOTEL:
- ExLog.i(getActivity(), LogEvent.RACE_CHOOSE_ABORT_HOTEL, getRace().getId());
- break;
+ case HOTEL:
+ ExLog.i(getActivity(), LogEvent.RACE_CHOOSE_ABORT_HOTEL, getRace().getId());
+ break;
- default:
- ExLog.i(getActivity(), LogEvent.RACE_CHOOSE_ABORT_NONE, getRace().getId());
- break;
+ default:
+ ExLog.i(getActivity(), LogEvent.RACE_CHOOSE_ABORT_NONE, getRace().getId());
+ break;
}
}
@@ -125,4 +133,80 @@ public class AbortFlagsFragment extends RaceFragment implements AbortFlagItemCli
sendIntent(AppConstants.INTENT_ACTION_TIME_SHOW);
}
+
+ private void abortChildRaces(final TimePoint now, final RaceState state, final Flags flag) {
+ RacingActivity activity = (RacingActivity) getActivity();
+ final List races = activity
+ .getChildRaces(getRace(), new RaceLogRaceStatus[] { RaceLogRaceStatus.STARTPHASE, RaceLogRaceStatus.RUNNING });
+
+ if (races.size() > 0) {
+ final ArrayList raceList = new ArrayList<>();
+ for (ManagedRace race : races) {
+ raceList.add(RaceHelper.getShortReverseRaceName(race, " / ", getRace()));
+ }
+ final ArrayList raceChecked = new ArrayList<>();
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_AlertDialog);
+ builder.setTitle(getArguments().getString(HEADER_TEXT, getString(R.string.not_available)) + " " + getString(R.string.flags_dependent_races));
+ builder.setMultiChoiceItems(raceList.toArray(new String[raceList.size()]), null, new DialogInterface.OnMultiChoiceClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+ ManagedRace race = races.get(which);
+ if (raceChecked.contains(race)) {
+ raceChecked.remove(race);
+ }
+ if (isChecked) {
+ raceChecked.add(race);
+ }
+ }
+ });
+ builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ for (ManagedRace race : races) {
+ RaceState raceState = race.getState();
+ if (raceChecked.contains(race)) {
+ Duration startTimeDiff = raceState.getStartTimeFinderResult().getStartTimeDiff();
+ raceState.setAborted(now, /* postponed */ false, flag);
+ raceState.setAdvancePass(now);
+ raceState.forceNewDependentStartTime(now, startTimeDiff, RaceHelper.getSimpleRaceLogIdentifier(getRace()));
+ } else {
+ raceState.forceNewStartTime(now, raceState.getStartTimeFinderResult().getStartTime());
+ }
+ }
+ abortRace(now, state, flag);
+ }
+ });
+ builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ abortRace(now, state, flag);
+ }
+ });
+ builder.setCancelable(false);
+ builder.show();
+ } else {
+ abortRace(now, state, flag);
+ }
+ }
+
+ private void abortRace(TimePoint now, RaceState state, Flags flag) {
+ fixStartTime(now);
+ state.setAborted(now, /* postponed */ false, flag);
+ if (flag != Flags.NONE) {
+ setProtestTime();
+ }
+ state.setAdvancePass(now);
+ }
+
+ private void fixStartTime(TimePoint now) {
+ RacingActivity activity = (RacingActivity) getActivity();
+ List races = activity
+ .getChildRaces(getRace(), new RaceLogRaceStatus[] { RaceLogRaceStatus.PRESCHEDULED, RaceLogRaceStatus.SCHEDULED,
+ RaceLogRaceStatus.FINISHING, RaceLogRaceStatus.FINISHED });
+
+ for (ManagedRace race : races) {
+ race.getState().forceNewStartTime(now, race.getState().getStartTimeFinderResult().getStartTime());
+ }
+ }
}
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/RaceHelper.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/RaceHelper.java
index ea868134d18..a2a789b764b 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/RaceHelper.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/RaceHelper.java
@@ -1,10 +1,16 @@
package com.sap.sailing.racecommittee.app.utils;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
+import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
+import com.sap.sailing.domain.abstractlog.race.impl.SimpleRaceLogIdentifierImpl;
import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.gate.GateStartRacingProcedure;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.SeriesBase;
@@ -17,10 +23,6 @@ import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.impl.RaceGroupSeriesFleet;
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.GateStartTimingFragment;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-
public class RaceHelper {
public static String getRaceName(@Nullable ManagedRace race) {
return getRaceName(race, null);
@@ -245,4 +247,12 @@ public class RaceHelper {
}
return preselectedRaces;
}
+
+ public static SimpleRaceLogIdentifier getSimpleRaceLogIdentifier(@Nullable ManagedRace race) {
+ SimpleRaceLogIdentifier identifier = null;
+ if (race != null) {
+ identifier = new SimpleRaceLogIdentifierImpl(race.getRaceGroup().getName(), race.getRaceName(), race.getFleet().getName());
+ }
+ return identifier;
+ }
}