mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-23 22:19:13 +00:00
Merge branch 'master' into ubilabs--tracking_app--develop
This commit is contained in:
+2
-1
@@ -14,7 +14,8 @@ public enum FleetColors {
|
||||
RED (232, 74, 26, 0),
|
||||
PURPLE (212, 28, 175, 0),
|
||||
NEON_GREEN (118, 255, 33, 0),
|
||||
ORANGE (255, 174, 23, 0);
|
||||
ORANGE (255, 174, 23, 0),
|
||||
WHITE (250, 250, 250, 0);
|
||||
|
||||
private Color color;
|
||||
|
||||
|
||||
+3
-1
@@ -42,7 +42,9 @@ public enum MaxPointsReason {
|
||||
/** Retired */
|
||||
RET(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true),
|
||||
/** Uniform Flag Disqualification */
|
||||
UFD(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true);
|
||||
UFD(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true),
|
||||
/** Time limit Expired */
|
||||
TLE(/* discardable */ true, /* advanceCompetitorsTrackedWorse */ true);
|
||||
|
||||
private final boolean discardable;
|
||||
|
||||
|
||||
+3
-5
@@ -98,11 +98,9 @@ public class MultiRegattaListSteps extends Composite {
|
||||
}
|
||||
|
||||
private String getLeaderboardButtonStyle(RegattaState regattaState) {
|
||||
switch (regattaState) {
|
||||
case UPCOMING: return SharedResources.INSTANCE.mainCss().buttoninactive();
|
||||
case RUNNING: return SharedResources.INSTANCE.mainCss().buttonred();
|
||||
default: return SharedResources.INSTANCE.mainCss().buttonprimary();
|
||||
}
|
||||
String liveStyle = SharedResources.INSTANCE.mainCss().buttonred();
|
||||
String defaultStyle = SharedResources.INSTANCE.mainCss().buttonprimary();
|
||||
return RegattaState.RUNNING == regattaState ? liveStyle : defaultStyle;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -242,7 +242,7 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
|
||||
protected void fillCourseAreaListBox(EventDTO selectedEvent) {
|
||||
courseAreaListBox.addItem(stringMessages.selectCourseArea());
|
||||
for (CourseAreaDTO courseArea : selectedEvent.venue.getCourseAreas()) {
|
||||
courseAreaListBox.addItem(courseArea.getName());
|
||||
courseAreaListBox.addItem(courseArea.getName(), courseArea.id.toString());
|
||||
if (courseArea.id.equals(regatta.defaultCourseAreaUuid)) {
|
||||
courseAreaListBox.setSelectedIndex(courseAreaListBox.getItemCount() - 1);
|
||||
}
|
||||
@@ -270,9 +270,9 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
|
||||
EventDTO event = getSelectedEvent();
|
||||
int selIndex = courseAreaListBox.getSelectedIndex();
|
||||
if (selIndex > 0 && event != null) { // the zero index represents the 'no selection' text
|
||||
String itemText = courseAreaListBox.getItemText(selIndex);
|
||||
String selectedCourseAreaIdAsString = courseAreaListBox.getValue(selIndex);
|
||||
for (CourseAreaDTO courseAreaDTO : event.venue.getCourseAreas()) {
|
||||
if (courseAreaDTO.getName().equals(itemText)) {
|
||||
if (courseAreaDTO.id.toString().equals(selectedCourseAreaIdAsString)) {
|
||||
result = courseAreaDTO;
|
||||
break;
|
||||
}
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.resources.client.ImageResource;
|
||||
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.gwt.client.StringMessages;
|
||||
import com.sap.sse.gwt.client.controls.listedit.ExpandedListEditorUi;
|
||||
import com.sap.sse.gwt.client.controls.listedit.GenericStringListEditorComposite;
|
||||
import com.sap.sse.gwt.client.controls.listedit.GenericStringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.controls.listedit.ListEditorComposite;
|
||||
import com.sap.sse.gwt.client.controls.listedit.ListEditorUiStrategy;
|
||||
|
||||
public class CourseAreaListInlineEditorComposite extends GenericStringListInlineEditorComposite<CourseAreaDTO> {
|
||||
|
||||
public CourseAreaListInlineEditorComposite(Iterable<CourseAreaDTO> initialValues,
|
||||
ListEditorUiStrategy<CourseAreaDTO> activeUi) {
|
||||
super(initialValues, activeUi);
|
||||
}
|
||||
|
||||
public CourseAreaListInlineEditorComposite(Iterable<CourseAreaDTO> initialValues, StringMessages stringMessages,
|
||||
ImageResource removeImage, List<String> suggestValues, int textBoxSize) {
|
||||
super(initialValues, stringMessages, removeImage, suggestValues, textBoxSize);
|
||||
}
|
||||
|
||||
public static class CollapsedUi extends GenericStringListEditorComposite.CollapsedUi<CourseAreaDTO> {
|
||||
public CollapsedUi(StringMessages stringMessages, String dialogTitle, ExpandedListEditorUi<CourseAreaDTO> expandedUi) {
|
||||
super(stringMessages, dialogTitle, expandedUi);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListEditorComposite<CourseAreaDTO> createExpandedUi(Iterable<CourseAreaDTO> initialValues, ExpandedListEditorUi<CourseAreaDTO> ui) {
|
||||
return new CourseAreaListInlineEditorComposite(initialValues, ui);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CourseAreaDTO parse(String s) {
|
||||
return new CourseAreaDTO(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CourseAreaDTO parse(String s, CourseAreaDTO valueToUpdate) {
|
||||
final CourseAreaDTO result;
|
||||
if (Util.equalsWithNull(valueToUpdate.getName(), s)) {
|
||||
result = valueToUpdate;
|
||||
} else {
|
||||
result = parse(s);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String toString(CourseAreaDTO value) {
|
||||
return value.getName();
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -7,6 +7,7 @@ import java.util.List;
|
||||
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
@@ -45,6 +46,6 @@ public class EventCreateDialog extends EventDialog {
|
||||
imagesListComposite.fillImages(Collections.<ImageDTO>emptyList());
|
||||
videosListComposite.fillVideos(Collections.<VideoDTO>emptyList());
|
||||
// add default course area
|
||||
courseAreaNameList.setValue(Collections.singletonList("Default"));
|
||||
courseAreaNameList.setValue(Collections.singletonList(new CourseAreaDTO("Default")));
|
||||
}
|
||||
}
|
||||
|
||||
+19
-17
@@ -34,8 +34,8 @@ import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.VenueDTO;
|
||||
import com.sap.sse.gwt.client.IconResources;
|
||||
import com.sap.sse.gwt.client.controls.listedit.GenericStringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.controls.listedit.StringConstantsListEditorComposite;
|
||||
import com.sap.sse.gwt.client.controls.listedit.StringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
|
||||
@@ -50,12 +50,12 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
protected UUID id;
|
||||
protected TextBox officialWebsiteURLEntryField;
|
||||
protected Map<String, TextBox> sailorsInfoWebsiteURLEntryFields = new HashMap<>();
|
||||
protected StringListInlineEditorComposite courseAreaNameList;
|
||||
protected CourseAreaListInlineEditorComposite courseAreaNameList;
|
||||
protected StringConstantsListEditorComposite leaderboardGroupList;
|
||||
protected Map<String, LeaderboardGroupDTO> availableLeaderboardGroupsByName;
|
||||
protected ImagesListComposite imagesListComposite;
|
||||
protected VideosListComposite videosListComposite;
|
||||
|
||||
protected ImagesListComposite imagesListComposite;
|
||||
protected VideosListComposite videosListComposite;
|
||||
|
||||
protected static class EventParameterValidator implements Validator<EventDTO> {
|
||||
|
||||
private StringMessages stringMessages;
|
||||
@@ -76,8 +76,9 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
if (courseAreaNotEmpty) {
|
||||
for (CourseAreaDTO courseArea : eventToValidate.venue.getCourseAreas()) {
|
||||
courseAreaNotEmpty = courseArea.getName() != null && courseArea.getName().length() > 0;
|
||||
if (!courseAreaNotEmpty)
|
||||
if (!courseAreaNotEmpty) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,11 +139,17 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
validate();
|
||||
}
|
||||
};
|
||||
final ValueChangeHandler<Iterable<CourseAreaDTO>> courseAreaValueChangeHandler = new ValueChangeHandler<Iterable<CourseAreaDTO>>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<Iterable<CourseAreaDTO>> event) {
|
||||
validate();
|
||||
}
|
||||
};
|
||||
|
||||
courseAreaNameList = new StringListInlineEditorComposite(Collections.<String> emptyList(),
|
||||
new StringListInlineEditorComposite.ExpandedUi(stringMessages, IconResources.INSTANCE.removeIcon(), /* suggestValues */
|
||||
courseAreaNameList = new CourseAreaListInlineEditorComposite(Collections.<CourseAreaDTO> emptyList(),
|
||||
new GenericStringListInlineEditorComposite.ExpandedUi<CourseAreaDTO>(stringMessages, IconResources.INSTANCE.removeIcon(), /* suggestValues */
|
||||
SuggestedCourseAreaNames.suggestedCourseAreaNames, stringMessages.enterCourseAreaName(), 50));
|
||||
courseAreaNameList.addValueChangeHandler(valueChangeHandler);
|
||||
courseAreaNameList.addValueChangeHandler(courseAreaValueChangeHandler);
|
||||
List<String> leaderboardGroupNames = new ArrayList<>();
|
||||
for(LeaderboardGroupDTO leaderboardGroupDTO: availableLeaderboardGroups) {
|
||||
leaderboardGroupNames.add(leaderboardGroupDTO.getName());
|
||||
@@ -178,16 +185,11 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
|
||||
result.endDate = endDateBox.getValue();
|
||||
result.isPublic = isPublicCheckBox.getValue();
|
||||
result.id = id;
|
||||
List<CourseAreaDTO> courseAreas = new ArrayList<CourseAreaDTO>();
|
||||
for (String courseAreaName : courseAreaNameList.getValue()) {
|
||||
CourseAreaDTO courseAreaDTO = new CourseAreaDTO();
|
||||
courseAreaDTO.setName(courseAreaName);
|
||||
courseAreas.add(courseAreaDTO);
|
||||
}
|
||||
for (ImageDTO image: imagesListComposite.getAllImages()) {
|
||||
List<CourseAreaDTO> courseAreas = courseAreaNameList.getValue();
|
||||
for (ImageDTO image : imagesListComposite.getAllImages()) {
|
||||
result.addImage(image);
|
||||
}
|
||||
for (VideoDTO video: videosListComposite.getAllVideos()) {
|
||||
for (VideoDTO video : videosListComposite.getAllVideos()) {
|
||||
result.addVideo(video);
|
||||
}
|
||||
result.venue = new VenueDTO(venueEntryField.getText(), courseAreas);
|
||||
|
||||
+1
-9
@@ -6,7 +6,6 @@ import java.util.List;
|
||||
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
|
||||
@@ -29,17 +28,10 @@ public class EventEditDialog extends EventDialog {
|
||||
isPublicCheckBox = createCheckbox("");
|
||||
isPublicCheckBox.setValue(event.isPublic);
|
||||
id = event.id;
|
||||
|
||||
List<String> courseAreaNames = new ArrayList<>();
|
||||
if (event.venue.getCourseAreas() != null && event.venue.getCourseAreas().size() > 0) {
|
||||
for (CourseAreaDTO courseArea : event.venue.getCourseAreas()) {
|
||||
courseAreaNames.add(courseArea.getName());
|
||||
}
|
||||
}
|
||||
officialWebsiteURLEntryField = createTextBox(event.getOfficialWebsiteURL());
|
||||
officialWebsiteURLEntryField.setVisibleLength(50);
|
||||
sailorsInfoWebsiteURLEntryFields = createTextBoxesForLocalesAndDefault(event.getSailorsInfoWebsiteURLs());
|
||||
courseAreaNameList.setValue(courseAreaNames);
|
||||
courseAreaNameList.setValue(new ArrayList<>(event.venue.getCourseAreas()));
|
||||
List<String> leaderboardGroupNames = new ArrayList<>();
|
||||
for(LeaderboardGroupDTO leaderboardGroupDTO: event.getLeaderboardGroups()) {
|
||||
leaderboardGroupNames.add(leaderboardGroupDTO.getName());
|
||||
|
||||
+6
-6
@@ -130,9 +130,9 @@ public abstract class FlexibleLeaderboardDialog extends AbstractLeaderboardDialo
|
||||
}
|
||||
|
||||
private void fillCourseAreaListBox(EventDTO selectedEvent) {
|
||||
courseAreaListBox.addItem("Please select a course area...");
|
||||
courseAreaListBox.addItem(stringMessages.pleaseSelectACourseArea());
|
||||
for (CourseAreaDTO courseArea : selectedEvent.venue.getCourseAreas()) {
|
||||
courseAreaListBox.addItem(courseArea.getName());
|
||||
courseAreaListBox.addItem(courseArea.getName(), courseArea.id.toString());
|
||||
}
|
||||
courseAreaListBox.setEnabled(true);
|
||||
}
|
||||
@@ -156,10 +156,10 @@ public abstract class FlexibleLeaderboardDialog extends AbstractLeaderboardDialo
|
||||
CourseAreaDTO result = null;
|
||||
EventDTO event = getSelectedEvent();
|
||||
int selIndex = courseAreaListBox.getSelectedIndex();
|
||||
if(selIndex > 0 && event != null) { // the zero index represents the 'no selection' text
|
||||
String itemText = courseAreaListBox.getItemText(selIndex);
|
||||
for(CourseAreaDTO courseAreaDTO: event.venue.getCourseAreas()) {
|
||||
if(courseAreaDTO.getName().equals(itemText)) {
|
||||
if (selIndex > 0 && event != null) { // the zero index represents the 'no selection' text
|
||||
String selectedCourseAreaId = courseAreaListBox.getValue(selIndex);
|
||||
for (CourseAreaDTO courseAreaDTO : event.venue.getCourseAreas()) {
|
||||
if (courseAreaDTO.id.toString().equals(selectedCourseAreaId)) {
|
||||
result = courseAreaDTO;
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ import com.sap.sse.gwt.client.IconResources;
|
||||
import com.sap.sse.gwt.client.controls.IntegerBox;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator;
|
||||
import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator;
|
||||
import com.sap.sse.gwt.client.controls.listedit.GenericStringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.controls.listedit.StringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
import com.sap.sse.gwt.client.media.ImageDTO;
|
||||
@@ -139,7 +140,7 @@ public abstract class ImageDialog extends DataEntryDialog<ImageDTO> {
|
||||
});
|
||||
|
||||
tagsListEditor = new StringListInlineEditorComposite(Collections.<String> emptyList(),
|
||||
new StringListInlineEditorComposite.ExpandedUi(stringMessages, IconResources.INSTANCE.removeIcon(), /* suggestValues */
|
||||
new GenericStringListInlineEditorComposite.ExpandedUi<String>(stringMessages, IconResources.INSTANCE.removeIcon(), /* suggestValues */
|
||||
MediaConstants.imageTagSuggestions, "Enter tags for the image", 30));
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -31,6 +31,7 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
|
||||
import com.sap.sse.gwt.client.IconResources;
|
||||
import com.sap.sse.gwt.client.controls.listedit.GenericStringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.controls.listedit.StringListEditorComposite;
|
||||
import com.sap.sse.gwt.client.controls.listedit.StringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
@@ -234,7 +235,7 @@ public class SeriesEditDialog extends DataEntryDialog<SeriesDescriptor> {
|
||||
return selectedSeries;
|
||||
}
|
||||
|
||||
private class RaceNamesEditorUi extends StringListInlineEditorComposite.ExpandedUi {
|
||||
private class RaceNamesEditorUi extends GenericStringListInlineEditorComposite.ExpandedUi<String> {
|
||||
private final RegattaDTO regatta;
|
||||
|
||||
private final ListBox addRacesFromListBox;
|
||||
|
||||
+2
-1
@@ -22,6 +22,7 @@ import com.sap.sse.common.media.MimeType;
|
||||
import com.sap.sse.gwt.adminconsole.URLFieldWithFileUpload;
|
||||
import com.sap.sse.gwt.client.IconResources;
|
||||
import com.sap.sse.gwt.client.controls.IntegerBox;
|
||||
import com.sap.sse.gwt.client.controls.listedit.GenericStringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.controls.listedit.StringListInlineEditorComposite;
|
||||
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
|
||||
import com.sap.sse.gwt.client.media.VideoDTO;
|
||||
@@ -89,7 +90,7 @@ public abstract class VideoDialog extends DataEntryDialog<VideoDTO> {
|
||||
});
|
||||
thumbnailURLAndUploadComposite = new URLFieldWithFileUpload(stringMessages);
|
||||
tagsListEditor = new StringListInlineEditorComposite(Collections.<String> emptyList(),
|
||||
new StringListInlineEditorComposite.ExpandedUi(stringMessages, IconResources.INSTANCE.removeIcon(), /* suggestValues */
|
||||
new GenericStringListInlineEditorComposite.ExpandedUi<String>(stringMessages, IconResources.INSTANCE.removeIcon(), /* suggestValues */
|
||||
MediaConstants.videoTagSuggestions, "Enter tags for the video", 50));
|
||||
}
|
||||
|
||||
|
||||
+23
-1
@@ -6,7 +6,7 @@ import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.common.dto.NamedDTO;
|
||||
|
||||
/**
|
||||
* Equality and hash code are based on the course area's name, as inherited from {@link NamedDTO}.
|
||||
* Equality and hash code are based on the course area's {@link #id}.
|
||||
*/
|
||||
public class CourseAreaDTO extends NamedDTO implements IsSerializable {
|
||||
private static final long serialVersionUID = -5279690838452265454L;
|
||||
@@ -18,4 +18,26 @@ public class CourseAreaDTO extends NamedDTO implements IsSerializable {
|
||||
public CourseAreaDTO(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = prime * ((id == null) ? 0 : id.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CourseAreaDTO other = (CourseAreaDTO) obj;
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 1.3 KiB |
+2
@@ -11,6 +11,8 @@
|
||||
<booleanAttribute key="default_auto_start" value="true"/>
|
||||
<intAttribute key="default_start_level" value="4"/>
|
||||
<booleanAttribute key="includeOptional" value="true"/>
|
||||
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.pde.ui.launcher.PDESourceLookupDirector"/>
|
||||
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <sourceLookupDirector> <sourceContainers duplicates="false"> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;classpathContainer path=&quot;org.eclipse.jdt.launching.JRE_CONTAINER&quot;/&gt;&#13;&#10;" typeId="org.eclipse.jdt.launching.sourceContainer.classpathContainer"/> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;default/&gt;&#13;&#10;" typeId="org.eclipse.debug.core.containerType.default"/> </sourceContainers> </sourceLookupDirector> "/>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||
|
||||
+4
-2
@@ -7,7 +7,6 @@ import com.google.gwt.user.client.ui.Grid;
|
||||
import com.google.gwt.user.client.ui.HTMLTable.Cell;
|
||||
import com.google.gwt.user.client.ui.Image;
|
||||
import com.google.gwt.user.client.ui.PushButton;
|
||||
import com.google.gwt.user.client.ui.ValueBoxBase;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sse.gwt.client.StringMessages;
|
||||
@@ -108,7 +107,10 @@ public abstract class ExpandedListEditorUi<ValueType> extends ListEditorUi<Value
|
||||
onRowRemoved();
|
||||
}
|
||||
|
||||
protected void setValueFromValueWidget(ValueBoxBase<ValueType> valueWidget, ValueType newValue, boolean fireEvents) {
|
||||
/**
|
||||
* @param valueWidget a widget returned previously from {@link #createValueWidget(int, Object)}
|
||||
*/
|
||||
protected void setValueFromValueWidget(Widget valueWidget, ValueType newValue, boolean fireEvents) {
|
||||
for (int i = 0; i < expandedValuesGrid.getRowCount(); i++) {
|
||||
Widget gridWidget = expandedValuesGrid.getWidget(i, 0);
|
||||
if (gridWidget.getElement() == valueWidget.getElement()) {
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
package com.sap.sse.gwt.client.controls.listedit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.event.dom.client.KeyUpEvent;
|
||||
import com.google.gwt.event.dom.client.KeyUpHandler;
|
||||
import com.google.gwt.resources.client.ImageResource;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.gwt.client.StringMessages;
|
||||
|
||||
/**
|
||||
* A list editor that renders values of type {@code ValueType} as {@link String}s and lets the user edit them
|
||||
* as strings. For this to work, implementing subclasses need to specify the
|
||||
*
|
||||
* @author Lukas Niemeier
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
* @param <ValueType>
|
||||
*/
|
||||
public abstract class GenericStringListEditorComposite<ValueType> extends ListEditorComposite<ValueType> {
|
||||
protected GenericStringListEditorComposite(Iterable<ValueType> initialValues, StringMessages stringMessages,
|
||||
ImageResource removeImage, Iterable<String> suggestValues) {
|
||||
super(initialValues, new ExpandedUi<ValueType>(stringMessages, removeImage, suggestValues));
|
||||
}
|
||||
|
||||
protected GenericStringListEditorComposite(Iterable<ValueType> initialValues, StringMessages stringMessages,
|
||||
ImageResource removeImage, Iterable<String> suggestValues, String placeholderTextForAddTextbox) {
|
||||
super(initialValues, new ExpandedUi<ValueType>(stringMessages, removeImage, suggestValues, placeholderTextForAddTextbox));
|
||||
}
|
||||
|
||||
protected GenericStringListEditorComposite(Iterable<ValueType> initialValues, ListEditorUiStrategy<ValueType> activeUi) {
|
||||
super(initialValues, activeUi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a new value provided as string {@code s} into a new object of type {@code ValueType}
|
||||
*/
|
||||
abstract protected ValueType parse(String s);
|
||||
|
||||
/**
|
||||
* Tries to update an existing value {@code valueToUpdate} from the string specification {@code s}.
|
||||
* If an in-place update works, {@code valueToUpdate} is returned, otherwise a new {@code ValueType}
|
||||
* object is created using {@link #parse(String)}.
|
||||
*/
|
||||
abstract protected ValueType parse(String s, ValueType valueToUpdate);
|
||||
|
||||
/**
|
||||
* Renders a {@code value} as {@link String} for representation in labels and text input fields. It
|
||||
* must be symmetric with {@link #parse(String, Object)} such that if in-place updates are generally supported
|
||||
* by the implementation then {@code toString(parse(s, v)).equals(s)} must be satisfied.
|
||||
*/
|
||||
abstract protected String toString(ValueType value);
|
||||
|
||||
public abstract static class CollapsedUi<ValueType> extends CollapsedListEditorUi<ValueType> {
|
||||
|
||||
public CollapsedUi(StringMessages stringMessages, String dialogTitle, ExpandedListEditorUi<ValueType> expandedUi) {
|
||||
super(stringMessages, dialogTitle, expandedUi);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCollapsedValueText(Iterable<ValueType> value) {
|
||||
StringBuilder valuesText = new StringBuilder();
|
||||
for (int i = 0; i < Util.size(value); i++) {
|
||||
if (i > 0) {
|
||||
valuesText.append(',');
|
||||
}
|
||||
valuesText.append(Util.get(value, i));
|
||||
}
|
||||
String condensedValue = valuesText.toString();
|
||||
return condensedValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExpandedUi<ValueType> extends ExpandedListEditorUi<ValueType> {
|
||||
|
||||
protected final MultiWordSuggestOracle inputOracle;
|
||||
protected final String placeholderTextForAddTextbox;
|
||||
|
||||
|
||||
public ExpandedUi(StringMessages stringMessages, ImageResource removeImage, Iterable<String> suggestValues) {
|
||||
this(stringMessages, removeImage, suggestValues, /* placeholderTextForAddTextbox */ null);
|
||||
}
|
||||
|
||||
public ExpandedUi(StringMessages stringMessages, ImageResource removeImage, Iterable<String> suggestValues, String placeholderTextForAddTextbox) {
|
||||
super(stringMessages, removeImage, /*canRemoveItems*/true);
|
||||
this.placeholderTextForAddTextbox = placeholderTextForAddTextbox;
|
||||
this.inputOracle = new MultiWordSuggestOracle();
|
||||
for (String suggestValue : suggestValues) {
|
||||
inputOracle.add(suggestValue);
|
||||
}
|
||||
List<String> defaultSuggestions = new ArrayList<>();
|
||||
Util.addAll(suggestValues, defaultSuggestions);
|
||||
this.inputOracle.setDefaultSuggestionsFromText(defaultSuggestions);
|
||||
}
|
||||
|
||||
protected GenericStringListEditorComposite<ValueType> getContext() {
|
||||
return (GenericStringListEditorComposite<ValueType>) context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContext(ListEditorComposite<ValueType> context) {
|
||||
super.setContext(context);
|
||||
for (final ValueType value : context.getValue()) {
|
||||
inputOracle.add(getContext().toString(value));
|
||||
}
|
||||
}
|
||||
|
||||
protected SuggestBox createSuggestBox() {
|
||||
final SuggestBox result = new SuggestBox(inputOracle);
|
||||
if (placeholderTextForAddTextbox != null) {
|
||||
result.getElement().setAttribute("placeholder", placeholderTextForAddTextbox);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Widget createAddWidget() {
|
||||
final SuggestBox inputBox = createSuggestBox();
|
||||
inputBox.ensureDebugId("InputSuggestBox");
|
||||
final Button addButton = new Button(getStringMessages().add());
|
||||
addButton.ensureDebugId("AddButton");
|
||||
addButton.setEnabled(false);
|
||||
addButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
addValue(getContext().parse(inputBox.getValue()));
|
||||
inputBox.setText("");
|
||||
}
|
||||
});
|
||||
inputBox.addKeyUpHandler(new KeyUpHandler() {
|
||||
@Override
|
||||
public void onKeyUp(KeyUpEvent event) {
|
||||
addButton.setEnabled(!inputBox.getValue().isEmpty());
|
||||
}
|
||||
});
|
||||
HorizontalPanel panel = new HorizontalPanel();
|
||||
panel.add(inputBox);
|
||||
panel.add(addButton);
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Widget createValueWidget(int rowIndex, ValueType newValue) {
|
||||
return new Label(getContext().toString(newValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package com.sap.sse.gwt.client.controls.listedit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.dom.client.InputElement;
|
||||
import com.google.gwt.event.dom.client.KeyUpEvent;
|
||||
import com.google.gwt.event.dom.client.KeyUpHandler;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.resources.client.ImageResource;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sse.gwt.client.StringMessages;
|
||||
|
||||
/**
|
||||
* In its expanded view, as opposed to its superclass which renders the values only as {@link Label}, this
|
||||
* class renders the values as {@link TextBox} and allows users to edit the values in place, without having
|
||||
* to remove and add them.
|
||||
*/
|
||||
public abstract class GenericStringListInlineEditorComposite<ValueType> extends GenericStringListEditorComposite<ValueType> {
|
||||
public GenericStringListInlineEditorComposite(Iterable<ValueType> initialValues, StringMessages stringMessages,
|
||||
ImageResource removeImage, List<String> suggestValues, int textBoxSize) {
|
||||
super(initialValues, new ExpandedUi<ValueType>(stringMessages, removeImage, suggestValues, textBoxSize));
|
||||
}
|
||||
|
||||
public GenericStringListInlineEditorComposite(Iterable<ValueType> initialValues, ListEditorUiStrategy<ValueType> activeUi) {
|
||||
super(initialValues, activeUi);
|
||||
}
|
||||
|
||||
public static class ExpandedUi<ValueType> extends GenericStringListEditorComposite.ExpandedUi<ValueType> {
|
||||
private final int textBoxSize;
|
||||
|
||||
public ExpandedUi(StringMessages stringMessages, ImageResource removeImage, List<String> suggestValues, int textBoxSize) {
|
||||
this(stringMessages, removeImage, suggestValues, /* placeholderTextForAddTextbox */ null, textBoxSize);
|
||||
}
|
||||
|
||||
public ExpandedUi(StringMessages stringMessages, ImageResource removeImage, List<String> suggestValues, String placeholderTextForAddTextbox, int textBoxSize) {
|
||||
super(stringMessages, removeImage, suggestValues, placeholderTextForAddTextbox);
|
||||
this.textBoxSize = textBoxSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SuggestBox createSuggestBox() {
|
||||
SuggestBox result = super.createSuggestBox();
|
||||
InputElement inputElement = result.getElement().cast();
|
||||
inputElement.setSize(textBoxSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Widget createValueWidget(final int rowIndex, ValueType newValue) {
|
||||
final TextBox textBox = new TextBox();
|
||||
textBox.setVisibleLength(textBoxSize);
|
||||
textBox.ensureDebugId("ValueTextBox");
|
||||
textBox.setValue(getContext().toString(newValue));
|
||||
textBox.addKeyUpHandler(new KeyUpHandler() {
|
||||
@Override
|
||||
public void onKeyUp(KeyUpEvent event) {
|
||||
textBox.setFocus(false);
|
||||
// this ensures that the value is copied into the TextBox.getValue() result and a ChangeEvent is fired
|
||||
textBox.setFocus(true);
|
||||
}
|
||||
});
|
||||
textBox.addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
ValueType oldValue = getContext().getValue().get(rowIndex);
|
||||
ValueType newValue = getContext().parse(event.getValue(), oldValue);
|
||||
setValueFromValueWidget(textBox, newValue, /* fireEvents */ true);
|
||||
}
|
||||
});
|
||||
return textBox;
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
-96
@@ -1,23 +1,18 @@
|
||||
package com.sap.sse.gwt.client.controls.listedit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.event.dom.client.KeyUpEvent;
|
||||
import com.google.gwt.event.dom.client.KeyUpHandler;
|
||||
import com.google.gwt.resources.client.ImageResource;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.gwt.client.StringMessages;
|
||||
|
||||
public class StringListEditorComposite extends ListEditorComposite<String> {
|
||||
/**
|
||||
* A simple string list editor for {@link String} values with trivial implementations for parsing and
|
||||
* serializing to strings.
|
||||
*
|
||||
* @author Lukas Niemeier
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class StringListEditorComposite extends GenericStringListEditorComposite<String> {
|
||||
public StringListEditorComposite(Iterable<String> initialValues, StringMessages stringMessages,
|
||||
String popupDialogTitle, ImageResource removeImage, Iterable<String> suggestValues) {
|
||||
this(initialValues, stringMessages, popupDialogTitle, removeImage, suggestValues, /* placeholderTextForAddTextbox */ null);
|
||||
@@ -26,113 +21,46 @@ public class StringListEditorComposite extends ListEditorComposite<String> {
|
||||
public StringListEditorComposite(Iterable<String> initialValues, StringMessages stringMessages,
|
||||
String popupDialogTitle, ImageResource removeImage, Iterable<String> suggestValues, String placeholderTextForAddTextbox) {
|
||||
super(initialValues, new CollapsedUi(stringMessages, popupDialogTitle,
|
||||
new ExpandedUi(stringMessages, removeImage, suggestValues, placeholderTextForAddTextbox)));
|
||||
new ExpandedUi<String>(stringMessages, removeImage, suggestValues, placeholderTextForAddTextbox)));
|
||||
}
|
||||
|
||||
public StringListEditorComposite(Iterable<String> initialValues, StringMessages stringMessages,
|
||||
ImageResource removeImage, Iterable<String> suggestValues) {
|
||||
super(initialValues, new ExpandedUi(stringMessages, removeImage, suggestValues));
|
||||
super(initialValues, new ExpandedUi<String>(stringMessages, removeImage, suggestValues));
|
||||
}
|
||||
|
||||
public StringListEditorComposite(Iterable<String> initialValues, StringMessages stringMessages,
|
||||
ImageResource removeImage, Iterable<String> suggestValues, String placeholderTextForAddTextbox) {
|
||||
super(initialValues, new ExpandedUi(stringMessages, removeImage, suggestValues, placeholderTextForAddTextbox));
|
||||
super(initialValues, new ExpandedUi<String>(stringMessages, removeImage, suggestValues, placeholderTextForAddTextbox));
|
||||
}
|
||||
|
||||
public StringListEditorComposite(Iterable<String> initialValues, ListEditorUiStrategy<String> activeUi) {
|
||||
super(initialValues, activeUi);
|
||||
}
|
||||
|
||||
public static class CollapsedUi extends CollapsedListEditorUi<String> {
|
||||
|
||||
public static class CollapsedUi extends GenericStringListEditorComposite.CollapsedUi<String> {
|
||||
public CollapsedUi(StringMessages stringMessages, String dialogTitle, ExpandedListEditorUi<String> expandedUi) {
|
||||
super(stringMessages, dialogTitle, expandedUi);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCollapsedValueText(Iterable<String> value) {
|
||||
StringBuilder valuesText = new StringBuilder();
|
||||
for (int i = 0; i < Util.size(value); i++) {
|
||||
if (i > 0) {
|
||||
valuesText.append(',');
|
||||
}
|
||||
valuesText.append(Util.get(value, i));
|
||||
}
|
||||
String condensedValue = valuesText.toString();
|
||||
return condensedValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListEditorComposite<String> createExpandedUi(Iterable<String> initialValues, ExpandedListEditorUi<String> ui) {
|
||||
return new StringListEditorComposite(initialValues, ui);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExpandedUi extends ExpandedListEditorUi<String> {
|
||||
@Override
|
||||
protected String parse(String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
protected final MultiWordSuggestOracle inputOracle;
|
||||
protected final String placeholderTextForAddTextbox;
|
||||
@Override
|
||||
protected String parse(String s, String valueToUpdate) {
|
||||
return Util.equalsWithNull(valueToUpdate, s) ? valueToUpdate : s; // try to preserve identity where possible
|
||||
}
|
||||
|
||||
|
||||
public ExpandedUi(StringMessages stringMessages, ImageResource removeImage, Iterable<String> suggestValues) {
|
||||
this(stringMessages, removeImage, suggestValues, /* placeholderTextForAddTextbox */ null);
|
||||
}
|
||||
|
||||
public ExpandedUi(StringMessages stringMessages, ImageResource removeImage, Iterable<String> suggestValues, String placeholderTextForAddTextbox) {
|
||||
super(stringMessages, removeImage, /*canRemoveItems*/true);
|
||||
this.placeholderTextForAddTextbox = placeholderTextForAddTextbox;
|
||||
this.inputOracle = new MultiWordSuggestOracle();
|
||||
for (String suggestValue : suggestValues) {
|
||||
inputOracle.add(suggestValue);
|
||||
}
|
||||
List<String> defaultSuggestions = new ArrayList<>();
|
||||
Util.addAll(suggestValues, defaultSuggestions);
|
||||
this.inputOracle.setDefaultSuggestionsFromText(defaultSuggestions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContext(ListEditorComposite<String> context) {
|
||||
super.setContext(context);
|
||||
inputOracle.addAll(context.getValue());
|
||||
}
|
||||
|
||||
protected SuggestBox createSuggestBox() {
|
||||
final SuggestBox result = new SuggestBox(inputOracle);
|
||||
if (placeholderTextForAddTextbox != null) {
|
||||
result.getElement().setAttribute("placeholder", placeholderTextForAddTextbox);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Widget createAddWidget() {
|
||||
final SuggestBox inputBox = createSuggestBox();
|
||||
inputBox.ensureDebugId("InputSuggestBox");
|
||||
final Button addButton = new Button(getStringMessages().add());
|
||||
addButton.ensureDebugId("AddButton");
|
||||
addButton.setEnabled(false);
|
||||
addButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
addValue(inputBox.getValue());
|
||||
inputBox.setText("");
|
||||
}
|
||||
});
|
||||
inputBox.addKeyUpHandler(new KeyUpHandler() {
|
||||
@Override
|
||||
public void onKeyUp(KeyUpEvent event) {
|
||||
addButton.setEnabled(!inputBox.getValue().isEmpty());
|
||||
}
|
||||
});
|
||||
HorizontalPanel panel = new HorizontalPanel();
|
||||
panel.add(inputBox);
|
||||
panel.add(addButton);
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Widget createValueWidget(int rowIndex, String newValue) {
|
||||
return new Label(newValue);
|
||||
}
|
||||
@Override
|
||||
protected String toString(String value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-68
@@ -1,30 +1,15 @@
|
||||
package com.sap.sse.gwt.client.controls.listedit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.dom.client.InputElement;
|
||||
import com.google.gwt.event.dom.client.KeyUpEvent;
|
||||
import com.google.gwt.event.dom.client.KeyUpHandler;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.resources.client.ImageResource;
|
||||
import com.google.gwt.user.client.ui.SuggestBox;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.TextBox;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sse.gwt.client.StringMessages;
|
||||
|
||||
/**
|
||||
* In its expanded view, as opposed to its superclass which renders the values only as {@link Label}, this
|
||||
* class renders the values as {@link TextBox} and allows users to edit the values in place, without having
|
||||
* to remove and add them.
|
||||
*/
|
||||
public class StringListInlineEditorComposite extends StringListEditorComposite {
|
||||
public StringListInlineEditorComposite(List<String> initialValues, StringMessages stringMessages,
|
||||
String popupDialogTitle, ImageResource removeImage, List<String> suggestValues, int textBoxSize) {
|
||||
super(initialValues, new CollapsedUi(stringMessages, popupDialogTitle,
|
||||
new ExpandedUi(stringMessages, removeImage, suggestValues, textBoxSize)));
|
||||
}
|
||||
|
||||
public StringListInlineEditorComposite(Iterable<String> initialValues, StringMessages stringMessages,
|
||||
ImageResource removeImage, List<String> suggestValues, int textBoxSize) {
|
||||
super(initialValues, new ExpandedUi(stringMessages, removeImage, suggestValues, textBoxSize));
|
||||
}
|
||||
|
||||
public StringListInlineEditorComposite(Iterable<String> initialValues, ListEditorUiStrategy<String> activeUi) {
|
||||
super(initialValues, activeUi);
|
||||
}
|
||||
@@ -39,51 +24,4 @@ public class StringListInlineEditorComposite extends StringListEditorComposite {
|
||||
return new StringListInlineEditorComposite(initialValues, ui);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExpandedUi extends StringListEditorComposite.ExpandedUi {
|
||||
private final int textBoxSize;
|
||||
|
||||
public ExpandedUi(StringMessages stringMessages, ImageResource removeImage, List<String> suggestValues, int textBoxSize) {
|
||||
this(stringMessages, removeImage, suggestValues, /* placeholderTextForAddTextbox */ null, textBoxSize);
|
||||
}
|
||||
|
||||
public ExpandedUi(StringMessages stringMessages, ImageResource removeImage, List<String> suggestValues, String placeholderTextForAddTextbox, int textBoxSize) {
|
||||
super(stringMessages, removeImage, suggestValues, placeholderTextForAddTextbox);
|
||||
this.textBoxSize = textBoxSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SuggestBox createSuggestBox() {
|
||||
SuggestBox result = super.createSuggestBox();
|
||||
InputElement inputElement = result.getElement().cast();
|
||||
inputElement.setSize(textBoxSize);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Widget createValueWidget(final int rowIndex, String newValue) {
|
||||
final TextBox textBox = new TextBox();
|
||||
textBox.setVisibleLength(textBoxSize);
|
||||
textBox.ensureDebugId("ValueTextBox");
|
||||
textBox.setValue(newValue);
|
||||
|
||||
textBox.addKeyUpHandler(new KeyUpHandler() {
|
||||
@Override
|
||||
public void onKeyUp(KeyUpEvent event) {
|
||||
textBox.setFocus(false);
|
||||
// this ensures that the value is copied into the TextBox.getValue() result and a ChangeEvent is fired
|
||||
textBox.setFocus(true);
|
||||
}
|
||||
});
|
||||
|
||||
textBox.addValueChangeHandler(new ValueChangeHandler<String>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<String> event) {
|
||||
String newValue = event.getValue();
|
||||
setValueFromValueWidget(textBox, newValue, true);
|
||||
}
|
||||
});
|
||||
return textBox;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-1
@@ -7,6 +7,7 @@ import org.junit.Before;
|
||||
|
||||
import com.sap.sse.common.mail.MailException;
|
||||
import com.sap.sse.mail.MailService;
|
||||
import com.sap.sse.mail.MailServiceResolver;
|
||||
import com.sap.sse.mail.impl.MailServiceImpl;
|
||||
import com.sap.sse.replication.testsupport.AbstractServerReplicationTestSetUp;
|
||||
import com.sap.sse.replication.testsupport.AbstractServerWithSingleServiceReplicationTest;
|
||||
@@ -24,7 +25,14 @@ public class AbstractMailServiceReplicationTest extends AbstractServerWithSingle
|
||||
}
|
||||
|
||||
public static MailServiceImpl createMailCountingService(final boolean canSendMail) {
|
||||
return new MailServiceImpl(null) {
|
||||
final MailServiceImpl[] mailService = new MailServiceImpl[1];
|
||||
MailServiceResolver mailServiceResolver = new MailServiceResolver() {
|
||||
@Override
|
||||
public MailService getMailService() {
|
||||
return mailService[0];
|
||||
}
|
||||
};
|
||||
mailService[0] = new MailServiceImpl(null, mailServiceResolver) {
|
||||
@Override
|
||||
protected void internalSendMail(String toAddress, String subject, ContentSetter contentSetter)
|
||||
throws MailException {
|
||||
@@ -34,6 +42,7 @@ public class AbstractMailServiceReplicationTest extends AbstractServerWithSingle
|
||||
}
|
||||
}
|
||||
};
|
||||
return mailService[0];
|
||||
}
|
||||
|
||||
public static class MailServerReplicationTestSetUp extends AbstractServerReplicationTestSetUp<MailService, MailServiceImpl> {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.sap.sse.mail;
|
||||
|
||||
import javax.mail.Multipart;
|
||||
|
||||
import com.sap.sse.common.IsManagedByCache;
|
||||
import com.sap.sse.common.mail.MailException;
|
||||
import com.sap.sse.mail.impl.ReplicableMailService;
|
||||
import com.sap.sse.replication.Replicable;
|
||||
@@ -22,7 +23,7 @@ import com.sap.sse.util.ClearStateTestSupport;
|
||||
* @author Fredrik Teschke
|
||||
*
|
||||
*/
|
||||
public interface MailService extends ReplicableWithObjectInputStream<ReplicableMailService, MailOperation<?>>, ClearStateTestSupport {
|
||||
public interface MailService extends ReplicableWithObjectInputStream<ReplicableMailService, MailOperation<?>>, ClearStateTestSupport, IsManagedByCache<MailServiceResolver> {
|
||||
void sendMail(String toAddress, String subject, String body) throws MailException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.sap.sse.mail;
|
||||
|
||||
|
||||
public interface MailServiceResolver {
|
||||
/**
|
||||
* @return {@code null} if this service is not known
|
||||
*/
|
||||
MailService getMailService();
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
|
||||
import com.sap.sse.mail.MailService;
|
||||
import com.sap.sse.osgi.CachedOsgiTypeBasedServiceFinderFactory;
|
||||
import com.sap.sse.replication.Replicable;
|
||||
import com.sap.sse.util.ClearStateTestSupport;
|
||||
|
||||
@@ -34,7 +35,8 @@ public class Activator implements BundleActivator {
|
||||
logger.log(Level.SEVERE, "Couldn't read mail properties from " + propertiesfile.getCanonicalPath(), ioe);
|
||||
}
|
||||
|
||||
MailService mailService = new MailServiceImpl(mailProperties);
|
||||
MailService mailService = new MailServiceImpl(mailProperties, new MailServiceResolverAgainstOsgiRegistryImpl(
|
||||
new CachedOsgiTypeBasedServiceFinderFactory(context).createServiceFinder(MailService.class)));
|
||||
registration = context.registerService(MailService.class, mailService, null);
|
||||
final Dictionary<String, String> replicableServiceProperties = new Hashtable<>();
|
||||
replicableServiceProperties.put(Replicable.OSGi_Service_Registry_ID_Property_Name, mailService.getId()
|
||||
|
||||
@@ -24,11 +24,14 @@ import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.mail.internet.MimeUtility;
|
||||
|
||||
import com.sap.sse.common.IsManagedByCache;
|
||||
import com.sap.sse.common.mail.MailException;
|
||||
import com.sap.sse.mail.MailServiceResolver;
|
||||
import com.sap.sse.replication.OperationExecutionListener;
|
||||
import com.sap.sse.replication.OperationWithResult;
|
||||
import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||
import com.sap.sse.replication.impl.OperationWithResultWithIdWrapper;
|
||||
import com.sap.sse.util.ObjectInputStreamResolvingAgainstCache;
|
||||
|
||||
public class MailServiceImpl implements ReplicableMailService {
|
||||
private static final Logger logger = Logger.getLogger(MailServiceImpl.class.getName());
|
||||
@@ -45,9 +48,12 @@ public class MailServiceImpl implements ReplicableMailService {
|
||||
private ThreadLocal<Boolean> currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster = ThreadLocal
|
||||
.withInitial(() -> false);
|
||||
|
||||
public MailServiceImpl(Properties mailProperties) {
|
||||
private final MailServiceResolver mailServiceResolver;
|
||||
|
||||
public MailServiceImpl(Properties mailProperties, MailServiceResolver mailServiceResolver) {
|
||||
this.mailProperties = mailProperties;
|
||||
this.operationExecutionListeners = new ConcurrentHashMap<>();
|
||||
this.mailServiceResolver = mailServiceResolver;
|
||||
}
|
||||
|
||||
private class SMTPAuthenticator extends javax.mail.Authenticator {
|
||||
@@ -66,7 +72,7 @@ public class MailServiceImpl implements ReplicableMailService {
|
||||
return mailProperties != null && mailProperties.containsKey("mail.transport.protocol");
|
||||
}
|
||||
|
||||
//protected for testing purposes
|
||||
// protected for testing purposes
|
||||
protected void internalSendMail(String toAddress, String subject, ContentSetter contentSetter) throws MailException {
|
||||
if (canSendMail()) {
|
||||
if (toAddress != null) {
|
||||
@@ -104,11 +110,9 @@ public class MailServiceImpl implements ReplicableMailService {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.warning("No mail properties provided. Cannot send e-mail about "
|
||||
+ subject
|
||||
+ " to "
|
||||
+ toAddress
|
||||
+ ". This could also mean that this is running on a replica server in which case this is perfectly fine.");
|
||||
logger.warning("No mail properties provided. Cannot send e-mail about " + subject + " to " + toAddress
|
||||
+ ". This could also mean that this is running on a replica server in which case this is perfectly fine. "
|
||||
+ "The master "+getMasterDescriptor()+" will handle the mail sending operation in this case.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +166,12 @@ public class MailServiceImpl implements ReplicableMailService {
|
||||
|
||||
@Override
|
||||
public ObjectInputStream createObjectInputStreamResolvingAgainstCache(InputStream is) throws IOException {
|
||||
return new ObjectInputStream(is);
|
||||
return new ObjectInputStreamResolvingAgainstCache<MailServiceResolver>(is, mailServiceResolver) {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public IsManagedByCache<MailServiceResolver> resolve(MailServiceResolver cache) {
|
||||
return cache.getMailService();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
package com.sap.sse.mail.impl;
|
||||
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.TypeBasedServiceFinder;
|
||||
import com.sap.sse.mail.MailService;
|
||||
import com.sap.sse.mail.MailServiceResolver;
|
||||
|
||||
public class MailServiceResolverAgainstOsgiRegistryImpl implements MailServiceResolver {
|
||||
private final TypeBasedServiceFinder<MailService> serviceFinder;
|
||||
|
||||
public MailServiceResolverAgainstOsgiRegistryImpl(TypeBasedServiceFinder<MailService> serviceFinder) {
|
||||
this.serviceFinder = serviceFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MailService getMailService() {
|
||||
try {
|
||||
return serviceFinder.findService(null);
|
||||
} catch (NoCorrespondingServiceRegisteredException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,9 +34,12 @@ public abstract class ObjectInputStreamResolvingAgainstCache<C> extends ObjectIn
|
||||
/**
|
||||
* Package protected on purpose; instances to be created using a factory method on the {@link Replicable}. This
|
||||
* constructor {@link #enableResolveObject(boolean) enables resolving} by default.
|
||||
*
|
||||
* @param cache must not be {@code null}
|
||||
*/
|
||||
protected ObjectInputStreamResolvingAgainstCache(InputStream in, C cache) throws IOException {
|
||||
super(in);
|
||||
assert cache != null;
|
||||
this.cache = cache;
|
||||
enableResolveObject(true);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.sap.sailing.android.tracking.app"
|
||||
android:versionCode="1"
|
||||
android:versionName="1 - Altitude">
|
||||
android:versionCode="7"
|
||||
android:versionName="1.5">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="14"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.sap.sailing.android.buoy.positioning.app"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
android:versionCode="7"
|
||||
android:versionName="1.5">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="14"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="com.sap.sailing.racecommittee.app"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionCode="7"
|
||||
android:versionName="7 - Laser">
|
||||
android:versionCode="13"
|
||||
android:versionName="1.5">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="14"
|
||||
|
||||
Reference in New Issue
Block a user