From 3ea7746f4d86e7f56b2508835a8e8e02dda4d778 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Mon, 29 Feb 2016 15:56:33 +0100 Subject: [PATCH 01/75] deep link server change --- .../AndroidManifest.xml | 16 ++++++ .../res/values-de/strings.xml | 1 + .../res/values/strings.xml | 1 + .../app/ui/activities/LoginActivity.java | 13 +++++ .../app/ui/fragments/LoginOnboarding.java | 30 ++--------- .../preference/GeneralPreferenceFragment.java | 27 +--------- .../racecommittee/app/utils/QRHelper.java | 54 +++++++++++++++++++ 7 files changed, 90 insertions(+), 52 deletions(-) create mode 100644 mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/QRHelper.java diff --git a/mobile/com.sap.sailing.racecommittee.app/AndroidManifest.xml b/mobile/com.sap.sailing.racecommittee.app/AndroidManifest.xml index ff63e9cb333..2e54399fa00 100644 --- a/mobile/com.sap.sailing.racecommittee.app/AndroidManifest.xml +++ b/mobile/com.sap.sailing.racecommittee.app/AndroidManifest.xml @@ -51,6 +51,22 @@ + + + + + + + + + + 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 a5052b5b831..5713d12e5a1 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 @@ -465,5 +465,6 @@ Select Race Getting Started http://www.sapsailing.com/gwt/Home.html?locale=de#SolutionsPlace:navigationTab=RaceCommitteeApp + Server erfolgreich geändert auf %1$s. \ No newline at end of file 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 f17e4036d2f..b26e93ce0a0 100644 --- a/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml +++ b/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml @@ -492,5 +492,6 @@ Select Race Getting Started http://www.sapsailing.com/gwt/Home.html?locale=en#SolutionsPlace:navigationTab=RaceCommitteeApp + Server successful changed to %1$s. \ No newline at end of file diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java index 346957719f2..2deca9ce6fb 100755 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java @@ -21,6 +21,7 @@ import android.os.Bundle; import android.os.Handler; import android.support.annotation.NonNull; import android.support.v4.content.LocalBroadcastManager; +import android.support.v7.app.AlertDialog; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; @@ -63,6 +64,7 @@ import com.sap.sailing.racecommittee.app.ui.fragments.lists.selection.CourseArea import com.sap.sailing.racecommittee.app.ui.fragments.lists.selection.EventSelectedListenerHost; import com.sap.sailing.racecommittee.app.ui.fragments.lists.selection.ItemSelectedListener; import com.sap.sailing.racecommittee.app.ui.fragments.lists.selection.PositionSelectedListenerHost; +import com.sap.sailing.racecommittee.app.utils.QRHelper; import com.sap.sailing.racecommittee.app.utils.StringHelper; import com.sap.sailing.racecommittee.app.utils.autoupdate.AutoUpdater; @@ -289,6 +291,17 @@ public class LoginActivity extends BaseActivity } } + String action = getIntent().getAction(); + if (Intent.ACTION_VIEW.equals(action)) { + AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AppTheme_AlertDialog); + builder.setTitle(R.string.app_name); + if (QRHelper.with(this).saveData(getIntent().getData().toString())) { + builder.setMessage(getString(R.string.server_deeplink_message, preferences.getServerBaseURL())); + } + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + } + // This is required to reactivate the loader manager after configuration change (screen rotation) getLoaderManager(); diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/LoginOnboarding.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/LoginOnboarding.java index afacb98e747..14b8aed4f28 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/LoginOnboarding.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/LoginOnboarding.java @@ -27,6 +27,7 @@ import com.sap.sailing.domain.common.impl.DeviceConfigurationQRCodeUtils; import com.sap.sailing.racecommittee.app.AppConstants; import com.sap.sailing.racecommittee.app.AppPreferences; import com.sap.sailing.racecommittee.app.R; +import com.sap.sailing.racecommittee.app.utils.QRHelper; import com.sap.sailing.racecommittee.app.utils.UrlHelper; import com.sap.sailing.racecommittee.app.utils.autoupdate.AutoUpdater; import com.sap.sse.common.Util; @@ -88,7 +89,7 @@ public class LoginOnboarding extends Fragment { builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - if (saveData(url.getText().toString() + "#" + DeviceConfigurationQRCodeUtils.fragmentKey + "=" + device_id.getText().toString())) { + if (QRHelper.with(getActivity()).saveData(url.getText().toString() + "#" + DeviceConfigurationQRCodeUtils.fragmentKey + "=" + device_id.getText().toString())) { LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(new Intent(AppConstants.INTENT_ACTION_RESET)); } } @@ -116,36 +117,11 @@ public class LoginOnboarding extends Fragment { break; case Activity.RESULT_OK: - saveData(data.getStringExtra("SCAN_RESULT")); + QRHelper.with(getActivity()).saveData(data.getStringExtra("SCAN_RESULT")); break; default: Toast.makeText(getActivity(), getString(R.string.error_scanning_qr, resultCode), Toast.LENGTH_LONG).show(); } } - - private boolean saveData(String content) { - try { - Util.Pair connectionConfiguration = DeviceConfigurationQRCodeUtils.splitQRContent(content); - - String identifier = connectionConfiguration.getA(); - URL apkUrl = UrlHelper.tryConvertToURL(connectionConfiguration.getB()); - - if (apkUrl != null) { - String serverUrl = UrlHelper.getServerUrl(apkUrl); - - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); - preferences.edit().putString(getString(R.string.preference_identifier_key), identifier).commit(); - preferences.edit().putString(getString(R.string.preference_server_url_key), serverUrl).commit(); - - new AutoUpdater(getActivity()).checkForUpdate(false); - return true; - } else { - Toast.makeText(getActivity(), getString(R.string.error_scanning_qr_malformed), Toast.LENGTH_LONG).show(); - } - } catch (IllegalArgumentException e) { - Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show(); - } - return false; - } } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java index 687ba0d1e6d..e1335d2e904 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java @@ -24,6 +24,7 @@ import com.sap.sailing.domain.common.impl.DeviceConfigurationQRCodeUtils; import com.sap.sailing.racecommittee.app.AppPreferences; import com.sap.sailing.racecommittee.app.BuildConfig; import com.sap.sailing.racecommittee.app.R; +import com.sap.sailing.racecommittee.app.utils.QRHelper; import com.sap.sailing.racecommittee.app.utils.UrlHelper; import com.sap.sailing.racecommittee.app.utils.autoupdate.AutoUpdater; import com.sap.sse.common.Util; @@ -187,31 +188,7 @@ public class GeneralPreferenceFragment extends BasePreferenceFragment { } if (resultCode == Activity.RESULT_OK) { - String content = data.getStringExtra("SCAN_RESULT"); - try { - Util.Pair connectionConfiguration = DeviceConfigurationQRCodeUtils.splitQRContent(content); - - String identifier = connectionConfiguration.getA(); - URL apkUrl = UrlHelper.tryConvertToURL(connectionConfiguration.getB()); - - if (apkUrl != null) { - String serverUrl = UrlHelper.getServerUrl(apkUrl); - - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); - preferences.edit().putString(getString(R.string.preference_identifier_key), identifier).commit(); - preferences.edit().putString(getString(R.string.preference_server_url_key), serverUrl).commit(); - - identifierPreference.getOnPreferenceChangeListener().onPreferenceChange(identifierPreference, identifier); - serverUrlPreference.setText(serverUrl); - serverUrlPreference.getOnPreferenceChangeListener().onPreferenceChange(serverUrlPreference, serverUrl); - - new AutoUpdater(getActivity()).checkForUpdate(false); - } else { - Toast.makeText(getActivity(), getString(R.string.error_scanning_qr_malformed), Toast.LENGTH_LONG).show(); - } - } catch (IllegalArgumentException e) { - Toast.makeText(getActivity(), getString(R.string.error_scanning_qr, e.getMessage()), Toast.LENGTH_LONG).show(); - } + QRHelper.with(getActivity()).saveData(data.getStringExtra("SCAN_RESULT")); } else { Toast.makeText(getActivity(), getString(R.string.error_scanning_qr, resultCode), Toast.LENGTH_LONG).show(); } diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/QRHelper.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/QRHelper.java new file mode 100644 index 00000000000..f4e755b6722 --- /dev/null +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/QRHelper.java @@ -0,0 +1,54 @@ +package com.sap.sailing.racecommittee.app.utils; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.widget.Toast; + +import com.sap.sailing.domain.common.impl.DeviceConfigurationQRCodeUtils; +import com.sap.sailing.racecommittee.app.R; +import com.sap.sailing.racecommittee.app.utils.autoupdate.AutoUpdater; +import com.sap.sse.common.Util; + +import java.net.URL; + +public class QRHelper { + + private Context mContext; + + private QRHelper(Context context) { + mContext = context; + } + + public static QRHelper with(Context context) { + return new QRHelper(context); + } + + public boolean saveData(String content) { + try { + Util.Pair connectionConfiguration = DeviceConfigurationQRCodeUtils.splitQRContent(content); + + String identifier = connectionConfiguration.getA(); + URL apkUrl = UrlHelper.tryConvertToURL(connectionConfiguration.getB()); + + if (apkUrl != null) { + String serverUrl = UrlHelper.getServerUrl(apkUrl); + + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext); + SharedPreferences.Editor editor = preferences.edit(); + editor.putString(mContext.getString(R.string.preference_identifier_key), identifier); + editor.putString(mContext.getString(R.string.preference_server_url_key), serverUrl); + editor.commit(); + + new AutoUpdater(mContext).checkForUpdate(false); + return true; + } else { + Toast.makeText(mContext, mContext.getString(R.string.error_scanning_qr_malformed), Toast.LENGTH_LONG).show(); + } + } catch (IllegalArgumentException e) { + Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show(); + } + return false; + } +} From 0910f032cc3b3ad6ef4882518aa31caf9992884e Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 29 Feb 2016 16:54:11 +0100 Subject: [PATCH 02/75] consolidated imports to avoid warnings Change-Id: I2abdf8efd22c07da16a5a1b8c6817ae2722cad1e --- .../racecommittee/app/ui/fragments/LoginOnboarding.java | 7 ------- .../ui/fragments/preference/GeneralPreferenceFragment.java | 7 ------- .../sailing/racecommittee/app/ui/views/PanelButton.java | 1 - .../com/sap/sailing/racecommittee/app/utils/QRHelper.java | 5 ++--- 4 files changed, 2 insertions(+), 18 deletions(-) diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/LoginOnboarding.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/LoginOnboarding.java index 14b8aed4f28..c0feda19177 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/LoginOnboarding.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/LoginOnboarding.java @@ -4,10 +4,8 @@ import android.app.Activity; import android.app.Fragment; import android.content.DialogInterface; import android.content.Intent; -import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.AlertDialog; import android.text.SpannableString; @@ -28,11 +26,6 @@ import com.sap.sailing.racecommittee.app.AppConstants; import com.sap.sailing.racecommittee.app.AppPreferences; import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.utils.QRHelper; -import com.sap.sailing.racecommittee.app.utils.UrlHelper; -import com.sap.sailing.racecommittee.app.utils.autoupdate.AutoUpdater; -import com.sap.sse.common.Util; - -import java.net.URL; public class LoginOnboarding extends Fragment { diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java index e1335d2e904..7f9ea488ee7 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/preference/GeneralPreferenceFragment.java @@ -1,10 +1,7 @@ package com.sap.sailing.racecommittee.app.ui.fragments.preference; -import java.net.URL; - import android.app.Activity; import android.content.Intent; -import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.preference.CheckBoxPreference; @@ -13,21 +10,17 @@ import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceCategory; -import android.preference.PreferenceManager; import android.preference.PreferenceScreen; import android.support.v7.app.AlertDialog; import android.widget.Toast; import com.sap.sailing.android.shared.ui.fragments.preference.BasePreferenceFragment; import com.sap.sailing.android.shared.ui.views.EditSetPreference; -import com.sap.sailing.domain.common.impl.DeviceConfigurationQRCodeUtils; import com.sap.sailing.racecommittee.app.AppPreferences; import com.sap.sailing.racecommittee.app.BuildConfig; import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.utils.QRHelper; -import com.sap.sailing.racecommittee.app.utils.UrlHelper; import com.sap.sailing.racecommittee.app.utils.autoupdate.AutoUpdater; -import com.sap.sse.common.Util; public class GeneralPreferenceFragment extends BasePreferenceFragment { diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/views/PanelButton.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/views/PanelButton.java index a319126493b..7832810898f 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/views/PanelButton.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/views/PanelButton.java @@ -9,7 +9,6 @@ import android.support.annotation.StringRes; import android.support.v7.app.AlertDialog; import android.util.AttributeSet; import android.view.View; -import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.Switch; diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/QRHelper.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/QRHelper.java index f4e755b6722..136aa1c36d7 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/QRHelper.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/utils/QRHelper.java @@ -1,6 +1,7 @@ package com.sap.sailing.racecommittee.app.utils; -import android.app.Activity; +import java.net.URL; + import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; @@ -11,8 +12,6 @@ import com.sap.sailing.racecommittee.app.R; import com.sap.sailing.racecommittee.app.utils.autoupdate.AutoUpdater; import com.sap.sse.common.Util; -import java.net.URL; - public class QRHelper { private Context mContext; From 5c7b4e25e7eae5085e23cf57c6d0ad2b47b89f3d Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Thu, 17 Mar 2016 15:11:39 +0100 Subject: [PATCH 03/75] refactored accuracy custom view --- .../res/layout/accuracy.xml | 4 ++-- .../racecommittee/app/ui/views/AccuracyView.java | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) 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 bb56ef5802b..02b5714d426 100644 --- a/mobile/com.sap.sailing.racecommittee.app/res/layout/accuracy.xml +++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/accuracy.xml @@ -1,5 +1,5 @@ - - \ No newline at end of file + \ No newline at end of file diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/views/AccuracyView.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/views/AccuracyView.java index 65e683b0995..88b14b10900 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/views/AccuracyView.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/views/AccuracyView.java @@ -19,18 +19,16 @@ public class AccuracyView extends LinearLayout { private ImageView mSegment03; public AccuracyView(Context context) { - super(context); - - init(); + this(context, null); } public AccuracyView(Context context, AttributeSet attrs) { - super(context, attrs); - - init(); + this(context, attrs, 0); } - private void init() { + public AccuracyView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + inflate(getContext(), R.layout.accuracy, this); } From 6b135f7978b5648cd6a99f9a33e1276976a5b728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bro=C3=9F?= Date: Mon, 21 Mar 2016 17:13:16 +0100 Subject: [PATCH 04/75] Move updateStartAndEndOfTracking to TrackedRaceImpl and set up some more handlers in DynamicTrackedRaceLogListener --- .../impl/RaceLogRaceTracker.java | 50 +------- .../domain/test/mock/MockedTrackedRace.java | 8 ++ ...ockedTrackedRaceWithStartTimeAndRanks.java | 4 + .../domain/tracking/DynamicTrackedRace.java | 1 + .../sailing/domain/tracking/TrackedRace.java | 15 +++ .../tracking/impl/DynamicTrackedRaceImpl.java | 8 +- .../impl/DynamicTrackedRaceLogListener.java | 17 +++ .../domain/tracking/impl/TrackedRaceImpl.java | 109 ++++++++++++++++++ .../gwt/ui/test/MockedTrackedRace.java | 8 ++ .../server/masterdata/DummyTrackedRace.java | 4 + 10 files changed, 175 insertions(+), 49 deletions(-) diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogRaceTracker.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogRaceTracker.java index 4a97ac5a46b..7a619ea19e3 100755 --- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogRaceTracker.java +++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogRaceTracker.java @@ -75,9 +75,7 @@ import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl; import com.sap.sse.common.NoCorrespondingServiceRegisteredException; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; -import com.sap.sse.common.Util.Pair; import com.sap.sse.common.WithID; -import com.sap.sse.common.impl.MillisecondsTimePoint; import difflib.PatchFailedException; @@ -239,50 +237,6 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener { return new RegattaLogDeviceMarkMappingFinder(params.getRegattaLog()).analyze(); } - /** - * Use mapping time ranges to set time start and end of tracking time for race - */ - private void updateStartAndEndOfTracking() { - // TODO bug 3196: this would need to be evaluated lazily in TrackedRaceImpl.getStartOfTracking / getEndOfTracking - final Pair trackingTimesFromRaceLog = trackedRace.getTrackingTimesFromRaceLogs(); - if (trackingTimesFromRaceLog == null) { - TimePoint earliestMappingStart = new MillisecondsTimePoint(Long.MAX_VALUE); - TimePoint latestMappingEnd = new MillisecondsTimePoint(Long.MIN_VALUE); - for (List> list : competitorMappings.values()) { - for (DeviceMapping mapping : list) { - earliestMappingStart = getUpdatedEarliestMappingStart(earliestMappingStart, mapping.getTimeRange().from()); - latestMappingEnd = getUpdatedLatestMappingEnd(latestMappingEnd, mapping.getTimeRange().to()); - } - } - for (List> list : markMappings.values()) { - for (DeviceMapping mapping : list) { - earliestMappingStart = getUpdatedEarliestMappingStart(earliestMappingStart, mapping.getTimeRange().from()); - latestMappingEnd = getUpdatedLatestMappingEnd(latestMappingEnd, mapping.getTimeRange().to()); - } - } - trackedRace.setStartOfTrackingReceived(earliestMappingStart == null ? TimePoint.BeginningOfTime : earliestMappingStart); - trackedRace.setEndOfTrackingReceived(latestMappingEnd == null ? TimePoint.EndOfTime : latestMappingEnd); - } - } - - private TimePoint getUpdatedEarliestMappingStart(TimePoint earliestMappingStart, final TimePoint from) { - if (from == null) { - earliestMappingStart = null; // no further updates; one open interval means startOfTracking shall be the beginning of time - } else if (earliestMappingStart != null && from.before(earliestMappingStart)) { - earliestMappingStart = from; - } - return earliestMappingStart; - } - - private TimePoint getUpdatedLatestMappingEnd(TimePoint latestMappingEnd, final TimePoint to) { - if (to == null) { - latestMappingEnd = null; // no further updates; one open interval means startOfTracking shall be the beginning of time - } else if (latestMappingEnd != null && to.after(latestMappingEnd)) { - latestMappingEnd = to; - } - return latestMappingEnd; - } - private boolean hasMappingAlreadyBeenLoaded( DeviceMapping newMapping, List> oldMappings) { if (oldMappings == null) { @@ -355,7 +309,7 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener { markMappingsByDevices.clear(); markMappingsByDevices.putAll(transformToMappingsByDevice(markMappings)); - updateStartAndEndOfTracking(); + trackedRace.updateStartAndEndOfTracking(); } private void onDeviceMarkMappingEvent(RegattaLogDeviceMarkMappingEvent event) { @@ -429,7 +383,7 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener { competitorMappings.putAll(newMappings); competitorMappingsByDevices.clear(); competitorMappingsByDevices.putAll(transformToMappingsByDevice(competitorMappings)); - updateStartAndEndOfTracking(); + trackedRace.updateStartAndEndOfTracking(); } private void onStartTrackingEvent(RaceLogStartTrackingEvent event) { diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java index 9b361a08525..de2a29faa94 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java @@ -1029,4 +1029,12 @@ public class MockedTrackedRace implements DynamicTrackedRace { @Override public void updateMarkPassingsAfterRaceLogChanges() { } + + @Override + public void updateStartAndEndOfTracking() { + } + + @Override + public void onFinishedTimeChangedByRaceCommittee(TimePoint newFinishedTime) { + } } diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java index 95715cebb2c..eb16408e1d3 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java @@ -649,4 +649,8 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { public IsManagedByCache resolve(SharedDomainFactory domainFactory) { return this; } + + @Override + public void updateStartAndEndOfTracking() { + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrackedRace.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrackedRace.java index 3c4177fce24..f7159f12c42 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrackedRace.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrackedRace.java @@ -128,6 +128,7 @@ public interface DynamicTrackedRace extends TrackedRace { void onCourseDesignChangedByRaceCommittee(CourseBase courseDesign); void onStartTimeChangedByRaceCommittee(TimePoint newStartTime); + void onFinishedTimeChangedByRaceCommittee(TimePoint newFinishedTime); void onAbortedByRaceCommittee(Flags flag); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java index 94fde1cf210..f8383086ef8 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java @@ -865,6 +865,10 @@ public interface TrackedRace extends Serializable, IsManagedByCache getTrackingTimesFromRaceLogs() { return null; } + + default Pair getStartAndFinishedTimeFromRaceLogs() { + return null; + } /** * Returns all marks found in the {@link #markTracks} map and the mark device mappings and mark @@ -875,4 +879,15 @@ public interface TrackedRace extends Serializable, IsManagedByCache getMarksFromRegattaLogs() { return getMarks(); } + + /** + * Forces update of start and end of tracking. + * Adheres to the following precedence order + * + * 1) RaceLogStartOfTrackingEvent/RaceLogEndOfTrackingEvent + * 2) RaceLogStartTimeEvent - x Minutes, Race finished + x Minutes + * 3) Earliest Mapping, Latest Mapping (of Marks and Competitors) + * 4) Leave previously (manually set start/end of tracking) + */ + public void updateStartAndEndOfTracking(); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java index c6b2997f97c..25ac24e8a64 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java @@ -978,6 +978,13 @@ DynamicTrackedRace, GPSTrackListener { } catch (IOException e) { logger.log(Level.INFO, "Exception trying to notify race status change listeners about start time change", e); } + updateStartAndEndOfTracking(); + } + + @Override + public void onFinishedTimeChangedByRaceCommittee(TimePoint newFinishedTime) { + logger.info("Finished time of race "+getRace().getName()+" updated by race committee to "+newFinishedTime); + updateStartAndEndOfTracking(); } @Override @@ -1010,5 +1017,4 @@ DynamicTrackedRace, GPSTrackListener { public DynamicGPSFixTrack getTrack(Mark mark) { return (DynamicGPSFixTrack) super.getTrack(mark); } - } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java index 2c27235f626..20a970cba88 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java @@ -13,6 +13,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogFinishPositioningConfirmed import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogFlagEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogPassChangeEvent; +import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartTimeEvent; @@ -31,6 +32,7 @@ import com.sap.sailing.domain.common.Wind; import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.WindSourceType; import com.sap.sailing.domain.common.impl.WindSourceImpl; +import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus; import com.sap.sailing.domain.markpassingcalculation.MarkPassingUpdateListener; import com.sap.sailing.domain.tracking.DynamicTrackedRace; import com.sap.sailing.domain.tracking.RaceLogWindFixDeclinationHelper; @@ -309,6 +311,14 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor { markPassingUpdateListener.removeFixedPassing(revokedEvent.getInvolvedBoats().get(0), ((RaceLogFixedMarkPassingEvent) revokedEvent).getZeroBasedIndexOfPassedWaypoint()); } + if (revokedEvent instanceof RaceLogDependentStartTimeEvent || revokedEvent instanceof RaceLogStartTimeEvent){ + analyzeStartTime(null); + } + if (revokedEvent instanceof RaceLogRaceStatusEvent){ + if (((RaceLogRaceStatusEvent) revokedEvent).getNextStatus().equals(RaceLogRaceStatus.FINISHED)){ + trackedRace.invalidateEndTime(); + } + } } } @@ -326,4 +336,11 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor { public void visit(RaceLogEndOfTrackingEvent event) { trackedRace.setEndOfTrackingReceived(event.getLogicalTimePoint()); } + + @Override + public void visit(RaceLogRaceStatusEvent event) { + if (event.getNextStatus().equals(RaceLogRaceStatus.FINISHED)){ + trackedRace.invalidateEndTime(); + } + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index 135ca76e571..bf7d47fb01e 100644 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -40,6 +40,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogGateLineOpeningTimeEvent; import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier; +import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishedTimeFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.TrackingTimesFinder; @@ -49,6 +50,8 @@ import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ReadonlyRacingProcedure; import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDefinedMarkAnalyzer; +import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceCompetitorMappingFinder; +import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceMarkMappingFinder; import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Course; @@ -111,6 +114,7 @@ import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException; import com.sap.sailing.domain.polars.PolarDataService; import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore; import com.sap.sailing.domain.racelog.tracking.GPSFixStore; +import com.sap.sailing.domain.racelogtracking.DeviceMapping; import com.sap.sailing.domain.ranking.OneDesignRankingMetric; import com.sap.sailing.domain.ranking.RankingMetric; import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo; @@ -156,6 +160,8 @@ import difflib.Patch; import difflib.PatchFailedException; public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials implements CourseListener { + private static final int TRACKING_BUFFER_IN_MINUTES = 5; + private static final long serialVersionUID = -4825546964220003507L; private static final Logger logger = Logger.getLogger(TrackedRaceImpl.class.getName()); @@ -722,11 +728,100 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl @Override public TimePoint getStartOfTracking() { + updateStartAndEndOfTracking();//FIXME: unclear whether change listeners etc similar to DynamicTrackedRace can be used here for caching and invalidation return startOfTrackingReceived; } + + /** + * Use mapping time ranges to set time start and end of tracking time for race + */ + public void updateStartAndEndOfTracking() { + final Pair trackingTimesFromRaceLog = this.getTrackingTimesFromRaceLogs(); + final Pair startAndFinishedTimesFromRaceLog = this.getStartAndFinishedTimeFromRaceLogs(); + + boolean startOfTrackingFound = false; + boolean endOfTrackingFound = false; + + if (trackingTimesFromRaceLog != null){ + if (trackingTimesFromRaceLog.getA() != null){ + setStartOfTrackingReceived(trackingTimesFromRaceLog.getA(), false); + startOfTrackingFound = true; + } + if (trackingTimesFromRaceLog.getB() != null){ + setEndOfTrackingReceived(trackingTimesFromRaceLog.getB(), false); + endOfTrackingFound = true; + } + } + + if(!startOfTrackingFound || !endOfTrackingFound){ + if (startAndFinishedTimesFromRaceLog != null){ + if (!startOfTrackingFound && startAndFinishedTimesFromRaceLog.getA() != null){ + setStartOfTrackingReceived(startAndFinishedTimesFromRaceLog.getA().minus(Duration.ONE_MINUTE.times(TRACKING_BUFFER_IN_MINUTES)), false); + startOfTrackingFound = true; + } + if (!endOfTrackingFound && startAndFinishedTimesFromRaceLog.getB() != null){ + setEndOfTrackingReceived(startAndFinishedTimesFromRaceLog.getB().plus(Duration.ONE_MINUTE.times(TRACKING_BUFFER_IN_MINUTES)), false); + endOfTrackingFound = true; + } + } + } + + if(!startOfTrackingFound || !endOfTrackingFound){ + TimePoint earliestMappingStart = new MillisecondsTimePoint(Long.MAX_VALUE); + TimePoint latestMappingEnd = new MillisecondsTimePoint(Long.MIN_VALUE); + Map>> markMappings = new HashMap>>(); + Map>> competitorMappings = new HashMap>>(); + for (RegattaLog regattaLog: attachedRegattaLogs.values()){ + competitorMappings.putAll(new RegattaLogDeviceCompetitorMappingFinder(regattaLog).analyze()); + markMappings.putAll(new RegattaLogDeviceMarkMappingFinder(regattaLog).analyze()); + } + for (List> list : competitorMappings.values()) { + for (DeviceMapping mapping : list) { + earliestMappingStart = getUpdatedEarliestMappingStart(earliestMappingStart, mapping.getTimeRange().from()); + latestMappingEnd = getUpdatedLatestMappingEnd(latestMappingEnd, mapping.getTimeRange().to()); + } + } + for (List> list : markMappings.values()) { + for (DeviceMapping mapping : list) { + earliestMappingStart = getUpdatedEarliestMappingStart(earliestMappingStart, mapping.getTimeRange().from()); + latestMappingEnd = getUpdatedLatestMappingEnd(latestMappingEnd, mapping.getTimeRange().to()); + } + } + + if (!startOfTrackingFound && earliestMappingStart != null){ + setStartOfTrackingReceived(earliestMappingStart, false); + } + + if (!endOfTrackingFound && latestMappingEnd != null){ + setEndOfTrackingReceived(latestMappingEnd, false); + } + } + } + + private TimePoint getUpdatedEarliestMappingStart(TimePoint earliestMappingStart, final TimePoint from) { + if (from == null) { + earliestMappingStart = null; // no further updates; one open interval means startOfTracking shall be the beginning of time + } else if (earliestMappingStart != null && from.before(earliestMappingStart)) { + earliestMappingStart = from; + } + return earliestMappingStart; + } + + private TimePoint getUpdatedLatestMappingEnd(TimePoint latestMappingEnd, final TimePoint to) { + if (to == null) { + latestMappingEnd = null; // no further updates; one open interval means startOfTracking shall be the beginning of time + } else if (latestMappingEnd != null && to.after(latestMappingEnd)) { + latestMappingEnd = to; + } + return latestMappingEnd; + } + + + @Override public TimePoint getEndOfTracking() { + updateStartAndEndOfTracking();//FIXME: unclear whether change listeners etc similar to DynamicTrackedRace can be used here for caching and invalidation return endOfTrackingReceived; } @@ -762,6 +857,20 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl } return null; } + + @Override + public Pair getStartAndFinishedTimeFromRaceLogs() { + //Only one of the RaceLogs should have valid data, so one doesn't have to compare all the + //start/finished time values in order to find the earliest startTime/latestFinishedTime + for (final RaceLog raceLog : attachedRaceLogs.values()) { + TimePoint startTime = new StartTimeFinder(raceLogResolver, raceLog).analyze().getStartTime(); + TimePoint finishedTime = new FinishedTimeFinder(raceLog).analyze(); + if (startTime != null || finishedTime != null){ + return new Util.Pair(startTime, finishedTime); + } + } + return null; + } /** * Calculates the start time of the race from various sources. The highest precedence take the {@link #attachedRaceLogs race logs}, diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java index d35c075b9f6..c6d813eb2a2 100755 --- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java @@ -790,4 +790,12 @@ public class MockedTrackedRace implements DynamicTrackedRace { @Override public void updateMarkPassingsAfterRaceLogChanges() { } + + @Override + public void updateStartAndEndOfTracking() { + } + + @Override + public void onFinishedTimeChangedByRaceCommittee(TimePoint newFinishedTime) { + } } diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java index 23b95da6c7e..e7b476f6081 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java @@ -624,4 +624,8 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials { public IsManagedByCache resolve(SharedDomainFactory domainFactory) { return this; } + + @Override + public void updateStartAndEndOfTracking() { + } } From 297b85f30feca02241de6b2fc4c7b022b367aa6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bro=C3=9F?= Date: Mon, 21 Mar 2016 17:35:21 +0100 Subject: [PATCH 05/75] Removes unused methods as RaceLogRaceStatusEvent not revocabke --- .../tracking/impl/DynamicTrackedRaceLogListener.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java index 20a970cba88..ceb97a8ea17 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java @@ -311,14 +311,6 @@ public class DynamicTrackedRaceLogListener extends BaseRaceLogEventVisitor { markPassingUpdateListener.removeFixedPassing(revokedEvent.getInvolvedBoats().get(0), ((RaceLogFixedMarkPassingEvent) revokedEvent).getZeroBasedIndexOfPassedWaypoint()); } - if (revokedEvent instanceof RaceLogDependentStartTimeEvent || revokedEvent instanceof RaceLogStartTimeEvent){ - analyzeStartTime(null); - } - if (revokedEvent instanceof RaceLogRaceStatusEvent){ - if (((RaceLogRaceStatusEvent) revokedEvent).getNextStatus().equals(RaceLogRaceStatus.FINISHED)){ - trackedRace.invalidateEndTime(); - } - } } } From 9193f6c6ade1014649c7fab2e57910d7b3aab032 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Wed, 23 Mar 2016 12:26:27 +0100 Subject: [PATCH 06/75] increased "running time" area size on phones (because of the update badge) --- mobile/com.sap.sailing.racecommittee.app/res/values/dimens.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9a25e9ac2cc..ec938467dab 100644 --- a/mobile/com.sap.sailing.racecommittee.app/res/values/dimens.xml +++ b/mobile/com.sap.sailing.racecommittee.app/res/values/dimens.xml @@ -4,7 +4,7 @@ 80dp 120dp 320dp - 120dp + 150dp 12dp 80dp From 35de1b61b021e05e52f7a8ce4f409123d2efa110 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Thu, 24 Mar 2016 10:32:43 +0100 Subject: [PATCH 07/75] refactor multiple wind input dialog --- .../res/layout/wind_list_item.xml | 11 -- .../res/layout/wind_multiple_dialog.xml | 14 -- .../ui/fragments/raceinfo/WindFragment.java | 121 +++++------------- 3 files changed, 31 insertions(+), 115 deletions(-) delete mode 100644 mobile/com.sap.sailing.racecommittee.app/res/layout/wind_list_item.xml delete mode 100644 mobile/com.sap.sailing.racecommittee.app/res/layout/wind_multiple_dialog.xml diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/wind_list_item.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/wind_list_item.xml deleted file mode 100644 index 779a62e9557..00000000000 --- a/mobile/com.sap.sailing.racecommittee.app/res/layout/wind_list_item.xml +++ /dev/null @@ -1,11 +0,0 @@ - - \ No newline at end of file diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/wind_multiple_dialog.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/wind_multiple_dialog.xml deleted file mode 100644 index 71816ba4982..00000000000 --- a/mobile/com.sap.sailing.racecommittee.app/res/layout/wind_multiple_dialog.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/WindFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/WindFragment.java index 6fffd92452e..3f71c638315 100644 --- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/WindFragment.java +++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/raceinfo/WindFragment.java @@ -1,5 +1,12 @@ package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo; +import java.lang.ref.WeakReference; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; + import android.annotation.SuppressLint; import android.content.BroadcastReceiver; import android.content.Context; @@ -18,12 +25,9 @@ import android.view.View; import android.view.ViewGroup; import android.webkit.WebSettings; import android.webkit.WebView; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; -import android.widget.ListView; import android.widget.NumberPicker; import android.widget.TextView; @@ -34,7 +38,6 @@ import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationServices; import com.sap.sailing.android.shared.logging.ExLog; import com.sap.sailing.android.shared.util.AppUtils; -import com.sap.sailing.android.shared.util.ScreenHelper; import com.sap.sailing.android.shared.util.ViewHelper; import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Position; @@ -63,13 +66,6 @@ import com.sap.sailing.racecommittee.app.utils.WindHelper; import com.sap.sse.common.TimePoint; import com.sap.sse.common.impl.MillisecondsTimePoint; -import java.lang.ref.WeakReference; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; - public class WindFragment extends BaseFragment implements CompassDirectionListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, OnRaceUpdatedListener { private final static String TAG = WindFragment.class.getName(); @@ -534,8 +530,31 @@ public class WindFragment extends BaseFragment implements CompassDirectionListen } private void showWindDialog() { + ArrayList races = new ArrayList<>(); + for (ManagedRace race : mManagedRaces) { + races.add(RaceHelper.getShortReverseRaceName(race, " / ", getRace())); + } + mSelectedRaces.clear(); + mSelectedRaces.addAll(RaceHelper.getPreSelectedRaces(mRacesByGroup, getRace())); + boolean[] selected = new boolean[mManagedRaces.size()]; + for (int i = 0; i < mManagedRaces.size(); i++) { + selected[i] = mSelectedRaces.contains(mManagedRaces.get(i)); + } + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AppTheme_AlertDialog); builder.setTitle(getString(R.string.wind_select_race)); + builder.setMultiChoiceItems(races.toArray(new String[races.size()]), selected, new DialogInterface.OnMultiChoiceClickListener() { + @Override + public void onClick(DialogInterface dialog, int which, boolean isChecked) { + ManagedRace race = mManagedRaces.get(which); + if (mSelectedRaces.contains(race)) { + mSelectedRaces.remove(race); + } + if (isChecked) { + mSelectedRaces.add(race); + } + } + }); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -544,75 +563,10 @@ public class WindFragment extends BaseFragment implements CompassDirectionListen } } }); - builder.setNegativeButton(R.string.cancel, null); - builder.setView(setupDialogView()); + builder.setNegativeButton(android.R.string.cancel, null); builder.show(); } - private View setupDialogView() { - LayoutInflater inflater = LayoutInflater.from(getActivity()); - View view = inflater.inflate(R.layout.wind_multiple_dialog, null); - ListView racesList = (ListView) view.findViewById(R.id.wind_races_list); - racesList.setAdapter(new WindAdapter(getActivity(), mManagedRaces)); - racesList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); - racesList.setOnItemClickListener(new ItemClickListener()); - preselectRacesInDialog(racesList); - - ViewGroup.LayoutParams layoutParams = racesList.getLayoutParams(); - layoutParams.height = 49 * mManagedRaces.size(); - int screenHeight = (int) (ScreenHelper.on(getActivity()).getScreenHeight() * 0.65); - if (layoutParams.height > screenHeight) { - layoutParams.height = screenHeight; - } - view.setLayoutParams(layoutParams); - - return view; - } - - private void preselectRacesInDialog(ListView racesList) { - mSelectedRaces.clear(); - mSelectedRaces.addAll(RaceHelper.getPreSelectedRaces(mRacesByGroup, getRace())); - for (int index = 0; index < mManagedRaces.size(); index++) { - ManagedRace race = mManagedRaces.get(index); - if (race != null) { - racesList.setItemChecked(index, mSelectedRaces.contains(race)); - } - } - } - - private static class WindAdapter extends ArrayAdapter { - - public WindAdapter(Context context, List races) { - super(context, R.layout.wind_list_item, wrap(races)); - } - - private static List wrap(List races) { - List wrapped = new ArrayList<>(); - for (ManagedRace race : races) { - wrapped.add(new ManagedRaceItem(race)); - } - return wrapped; - } - - } - - private static class ManagedRaceItem { - - private RaceGroupSeriesFleet group; - private ManagedRace race; - - public ManagedRaceItem(ManagedRace race) { - this.race = race; - this.group = new RaceGroupSeriesFleet(race); - } - - @Override - public String toString() { - return String.format("%s - %s", group.getDisplayName(true), race.getRaceName()); - } - - } - private static class IsTrackedReceiver extends BroadcastReceiver { private WeakReference