Fixed deprecations

This commit is contained in:
Steffen Schaefer committed 2015-01-27 15:42:50 +01:00
1 parent 0ccc1a5ebf
commit 98ad8ffdfb
4 files changed
+1118 -1114

No files matched your search

@@ -1,160 +1,161 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.List;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.FleetColors;
import com.sap.sailing.domain.common.dto.FleetDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.common.Color;
import com.sap.sse.gwt.client.controls.listedit.ExpandedListEditorUi;
public class FleetListEditableEditorComposite extends FleetListEditorComposite {
public FleetListEditableEditorComposite(List<FleetDTO> initialValues, StringMessages stringMessages,
ImageResource removeImage) {
super(initialValues, stringMessages, removeImage);
}
protected ExpandedListEditorUi<FleetDTO> getExpandedUI(StringMessages stringMessages, ImageResource editImage) {
return new ExpandedEditableUi(stringMessages, editImage);
}
private static class ExpandedEditableUi extends ExpandedListEditorUi<FleetDTO> {
public ExpandedEditableUi(StringMessages stringMessages, ImageResource editImage) {
super(stringMessages, editImage, false);
}
@Override
protected StringMessages getStringMessages() {
return (StringMessages) super.getStringMessages();
}
@Override
protected Widget createAddWidget() {
return new HorizontalPanel();
}
@Override
protected Widget createValueWidget(int rowIndex, final FleetDTO fleet) {
HorizontalPanel hPanel = new HorizontalPanel();
hPanel.setSpacing(4);
Label fleetLabel = new Label(getStringMessages().fleet() + " ");
fleetLabel.getElement().getStyle().setFontWeight(FontWeight.BOLD);
hPanel.add(fleetLabel);
final TextBox nameBox = createNameBox(fleet.getName());
nameBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
fleet.setName(nameBox.getText());
}
});
nameBox.ensureDebugId("NameTextBox");
hPanel.add(nameBox);
final IntegerBox orderNoBox = createOrderNoBox(fleet.getOrderNo());
orderNoBox.ensureDebugId("OrderNoIntegerBox");
orderNoBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
fleet.setOrderNo(orderNoBox.getValue());
}
});
final ListBox colorListBox = createColorListBox(nameBox, orderNoBox, fleet.getColor());
colorListBox.ensureDebugId("ColorListBox");
colorListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
fleet.setColor(getSelectedColor(colorListBox));
}
});
hPanel.add(new Label(getStringMessages().color() + " "));
hPanel.add(colorListBox);
hPanel.add(new Label(getStringMessages().rank() + " "));
hPanel.add(orderNoBox);
return hPanel;
}
private IntegerBox createOrderNoBox(final int orderNo) {
IntegerBox orderNoBox = new IntegerBox();
orderNoBox.setVisibleLength(3);
orderNoBox.setValue(orderNo);
return orderNoBox;
}
private TextBox createNameBox(final String name) {
final TextBox nameBox = new TextBox();
nameBox.setText(name);
return nameBox;
}
private ListBox createColorListBox(final TextBox nameBox, final IntegerBox orderNoBox, final Color color) {
final ListBox colorListBox = new ListBox(false);
colorListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
// set default order no of the selected color
int selIndex = colorListBox.getSelectedIndex();
if (selIndex == 0) {
orderNoBox.setValue(0);
} else {
String value = colorListBox.getValue(selIndex);
final FleetColors color = FleetColors.valueOf(value);
if (color != null) {
orderNoBox.setValue(color.getDefaultOrderNo());
nameBox.setValue(getColorText(color));
}
}
}
});
colorListBox.addItem(getStringMessages().noColor());
int index = 0;
int i = 0;
for (FleetColors value : FleetColors.values()) {
i++;
colorListBox.addItem(value.name());
if (value.getColor().equals(color)) {
index = i;
}
}
colorListBox.setSelectedIndex(index);
return colorListBox;
}
private Color getSelectedColor(ListBox colorListBox) {
Color result = null;
int selIndex = colorListBox.getSelectedIndex();
// the zero index represents the 'no color' option
if (selIndex > 0) {
String value = colorListBox.getValue(selIndex);
for (FleetColors color : FleetColors.values()) {
if (color.name().equals(value)) {
result = color.getColor();
break;
}
}
}
return result;
}
private String getColorText(FleetColors color) {
if (color == null) {
return getStringMessages().noColor();
}
return color.name().charAt(0) + color.name().toLowerCase().substring(1);
}
}
}
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.List;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.FleetColors;
import com.sap.sailing.domain.common.dto.FleetDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.common.Color;
import com.sap.sse.gwt.client.controls.listedit.ExpandedListEditorUi;
public class FleetListEditableEditorComposite extends FleetListEditorComposite {
public FleetListEditableEditorComposite(List<FleetDTO> initialValues, StringMessages stringMessages,
ImageResource removeImage) {
super(initialValues, stringMessages, removeImage);
}
protected ExpandedListEditorUi<FleetDTO> getExpandedUI(StringMessages stringMessages, ImageResource editImage) {
return new ExpandedEditableUi(stringMessages, editImage);
}
private static class ExpandedEditableUi extends ExpandedListEditorUi<FleetDTO> {
public ExpandedEditableUi(StringMessages stringMessages, ImageResource editImage) {
super(stringMessages, editImage, false);
}
@Override
protected StringMessages getStringMessages() {
return (StringMessages) super.getStringMessages();
}
@Override
protected Widget createAddWidget() {
return new HorizontalPanel();
}
@Override
protected Widget createValueWidget(int rowIndex, final FleetDTO fleet) {
HorizontalPanel hPanel = new HorizontalPanel();
hPanel.setSpacing(4);
Label fleetLabel = new Label(getStringMessages().fleet() + " ");
fleetLabel.getElement().getStyle().setFontWeight(FontWeight.BOLD);
hPanel.add(fleetLabel);
final TextBox nameBox = createNameBox(fleet.getName());
nameBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
fleet.setName(nameBox.getText());
}
});
nameBox.ensureDebugId("NameTextBox");
hPanel.add(nameBox);
final IntegerBox orderNoBox = createOrderNoBox(fleet.getOrderNo());
orderNoBox.ensureDebugId("OrderNoIntegerBox");
orderNoBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
fleet.setOrderNo(orderNoBox.getValue());
}
});
final ListBox colorListBox = createColorListBox(nameBox, orderNoBox, fleet.getColor());
colorListBox.ensureDebugId("ColorListBox");
colorListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
fleet.setColor(getSelectedColor(colorListBox));
}
});
hPanel.add(new Label(getStringMessages().color() + " "));
hPanel.add(colorListBox);
hPanel.add(new Label(getStringMessages().rank() + " "));
hPanel.add(orderNoBox);
return hPanel;
}
private IntegerBox createOrderNoBox(final int orderNo) {
IntegerBox orderNoBox = new IntegerBox();
orderNoBox.setVisibleLength(3);
orderNoBox.setValue(orderNo);
return orderNoBox;
}
private TextBox createNameBox(final String name) {
final TextBox nameBox = new TextBox();
nameBox.setText(name);
return nameBox;
}
private ListBox createColorListBox(final TextBox nameBox, final IntegerBox orderNoBox, final Color color) {
final ListBox colorListBox = new ListBox();
colorListBox.setMultipleSelect(false);
colorListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
// set default order no of the selected color
int selIndex = colorListBox.getSelectedIndex();
if (selIndex == 0) {
orderNoBox.setValue(0);
} else {
String value = colorListBox.getValue(selIndex);
final FleetColors color = FleetColors.valueOf(value);
if (color != null) {
orderNoBox.setValue(color.getDefaultOrderNo());
nameBox.setValue(getColorText(color));
}
}
}
});
colorListBox.addItem(getStringMessages().noColor());
int index = 0;
int i = 0;
for (FleetColors value : FleetColors.values()) {
i++;
colorListBox.addItem(value.name());
if (value.getColor().equals(color)) {
index = i;
}
}
colorListBox.setSelectedIndex(index);
return colorListBox;
}
private Color getSelectedColor(ListBox colorListBox) {
Color result = null;
int selIndex = colorListBox.getSelectedIndex();
// the zero index represents the 'no color' option
if (selIndex > 0) {
String value = colorListBox.getValue(selIndex);
for (FleetColors color : FleetColors.values()) {
if (color.name().equals(value)) {
result = color.getColor();
break;
}
}
}
return result;
}
private String getColorText(FleetColors color) {
if (color == null) {
return getStringMessages().noColor();
}
return color.name().charAt(0) + color.name().toLowerCase().substring(1);
}
}
}
@@ -1,466 +1,467 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.common.dto.BoatClassDTO;
import com.sap.sailing.gwt.ui.adminconsole.StructureImportListComposite.RegattaStructureProvider;
import com.sap.sailing.gwt.ui.client.RegattaRefresher;
import com.sap.sailing.gwt.ui.client.RegattaSelectionModel;
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.EventAndRegattaDTO;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator;
import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
public class StructureImportManagementPanel extends FlowPanel implements RegattaStructureProvider {
private final SailingServiceAsync sailingService;
private final ErrorReporter errorReporter;
private final StringMessages stringMessages;
private final RegattaRefresher regattaRefresher;
private final EventManagementPanel eventManagementPanel;
private final StructureImportListComposite regattaListComposite;
private final BusyIndicator busyIndicator;
private TextBox jsonURLTextBox;
private TextBox eventIDTextBox;
private Button listRegattasButton;
private Button importDetailsButton;
private VerticalPanel editSeriesPanel;
private final FlexTable regattaStructureGrid;
private List<EventDTO> existingEvents;
private ListBox sailingEventsListBox;
/**
* Holds one {@link RegattaDTO} for each distinct regatta structure. The user can work with this panel
* to adjust the defaults for each structure recognized, working with the table selection to show/hide
* structures related to regattas in the list. After having set the defaults, pressing the "Import Regatta..."
* button will apply these defaults during the creation of the regattas selected. When modifying the
* defaults such that a different {@link RegattaStructure} will be needed to describe the modified version,
* the old entry shall be removed and a new one with the {@link RegattaStructure} matching the modified
* {@link RegattaDTO} shall be inserted.
*/
private final Map<RegattaStructure, RegattaDTO> regattaDefaultsPerStructure;
/**
* Maps from the {@link RegattaDTO}s coming from the XRR import to the structure to be used when creating
* the regatta in the back-end. When a regatta is first added to this map, the {@link RegattaStructure} object
* is originally created using the key as construction parameter. Over time, the user may evolve the structure
* to be used for import using the editing UIs, leading to a different {@link RegattaStructure} to be associated
* where the key is no longer part of the equivalence class defined by the {@link RegattaStructure} value.
* A typical case is a modification in the fleet structure, e.g., because the fleets weren't correctly recognized
* during the import and required some manual intervention.<p>
*
* The default settings to be used when finally creating the regatta in the back-end are maintained
* in {@link #regattaDefaultsPerStructure} for which the values of this map can be used as key.
*/
private final Map<RegattaDTO, RegattaStructure> regattaStructures;
public StructureImportManagementPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter,
StringMessages stringMessages, RegattaRefresher regattaRefresher, EventManagementPanel eventManagementPanel) {
this.regattaDefaultsPerStructure = new HashMap<>();
this.regattaStructures = new HashMap<>();
this.eventManagementPanel = eventManagementPanel;
this.busyIndicator = new SimpleBusyIndicator();
this.sailingService = sailingService;
this.errorReporter = errorReporter;
this.stringMessages = stringMessages;
this.regattaRefresher = regattaRefresher;
this.regattaListComposite = new StructureImportListComposite(this.sailingService, new RegattaSelectionModel(
true), this.regattaRefresher, this, this.errorReporter, this.stringMessages);
regattaListComposite.ensureDebugId("RegattaListComposite");
createUI();
regattaListComposite.addSelectionChangeHandler(new Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
updateRegattaStructureGrid();
updateImportRegattasButtonEnabledness();
}
});
regattaStructureGrid = new FlexTable();
}
private void createUI() {
final Panel progressPanel = new FlowPanel();
progressPanel.add(busyIndicator);
Grid URLgrid = new Grid(2, 2);
Label eventIDLabel = new Label(stringMessages.event() + ":");
Label jsonURLLabel = new Label(stringMessages.jsonUrl() + ":");
eventIDTextBox = new TextBox();
eventIDTextBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
jsonURLTextBox.setText("http://manage2sail.com/api/public/links/event/" + eventIDTextBox.getValue()
+ "?accesstoken=bDAv8CwsTM94ujZ&mediaType=json");
}
});
eventIDTextBox.ensureDebugId("eventIDTextBox");
eventIDTextBox.setVisibleLength(50);
jsonURLTextBox = new TextBox();
jsonURLTextBox.ensureDebugId("JsonURLTextBox");
jsonURLTextBox.setVisibleLength(100);
jsonURLTextBox.getElement().setPropertyString("placeholder",
"http://manage2sail.com/api/public/links/event/d30883d3-2876-4d7e-af49-891af6cbae1b?accesstoken=bDAv8CwsTM94ujZ&mediaType=json");
listRegattasButton = new Button(this.stringMessages.listRegattas());
importDetailsButton = new Button(this.stringMessages.importRegattas());
importDetailsButton.setEnabled(false);
importDetailsButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (getSelectedEvent() != null) {
List<RegattaDTO> selectedOriginalRegattasFromXRR = regattaListComposite.getSelectedRegattas();
if (!selectedOriginalRegattasFromXRR.isEmpty()) {
createRegattas(selectedOriginalRegattasFromXRR, getSelectedEvent());
} else {
errorReporter.reportError(stringMessages.pleaseSelectAtLeastOneRegatta());
}
} else {
errorReporter.reportError(stringMessages.pleaseSelectAnEvent());
}
}
});
listRegattasButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
listRegattasAndTheirStructures();
}
});
VerticalPanel vp = new VerticalPanel();
HorizontalPanel buttonPanel = new HorizontalPanel();
URLgrid.setWidget(0, 0, eventIDLabel);
URLgrid.setWidget(0, 1, eventIDTextBox);
URLgrid.setWidget(1, 0, jsonURLLabel);
URLgrid.setWidget(1, 1, jsonURLTextBox);
vp.add(URLgrid);
vp.add(buttonPanel);
buttonPanel.add(listRegattasButton);
buttonPanel.add(importDetailsButton);
Grid grid = new Grid(1, 1);
vp.add(grid);
grid.setWidget(0, 0, regattaListComposite);
grid.getRowFormatter().setVerticalAlign(0, HasVerticalAlignment.ALIGN_TOP);
grid.getColumnFormatter().getElement(0/** 1 */).getStyle().setPaddingTop(2.0, Unit.EM);
editSeriesPanel = new VerticalPanel();
add(progressPanel);
add(vp);
add(editSeriesPanel);
}
/**
* Adds an event selector and a "create new event" button to the {@link #editSeriesPanel} in its first row
*/
private void createEventSelectionAndCreateEventButtonUI() {
Grid grid = new Grid(1, 2);
sailingEventsListBox = new ListBox(false);
sailingEventsListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
updateImportRegattasButtonEnabledness();
}
});
sailingEventsListBox.ensureDebugId("EventListBox");
grid.setWidget(0, 0, sailingEventsListBox);
Button newEventBtn = new Button(stringMessages.createNewEvent());
newEventBtn.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
openEventCreateDialog();
}
});
grid.setWidget(0, 1, newEventBtn);
editSeriesPanel.add(grid);
sailingService.getEvents(new AsyncCallback<List<EventDTO>>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(stringMessages.errorTryingToGetEvents(caught.getMessage()));
}
@Override
public void onSuccess(List<EventDTO> events) {
existingEvents = events;
sailingEventsListBox.addItem(stringMessages.selectSailingEvent());
for (EventDTO event : existingEvents) {
sailingEventsListBox.addItem(event.getName());
}
}
});
}
private void openEventCreateDialog() {
EventCreateDialog dialog = new EventCreateDialog(existingEvents, Collections.<LeaderboardGroupDTO>emptyList(), stringMessages,
new DialogCallback<EventDTO>() {
@Override
public void cancel() {
}
@Override
public void ok(final EventDTO newEvent) {
createEvent(newEvent);
}
});
dialog.show();
}
private void createEvent(final EventDTO newEvent) {
List<String> courseAreaNames = new ArrayList<String>();
for (CourseAreaDTO courseAreaDTO : newEvent.venue.getCourseAreas()) {
courseAreaNames.add(courseAreaDTO.getName());
}
sailingService.createEvent(newEvent.getName(), newEvent.getDescription(), newEvent.startDate, newEvent.endDate,
newEvent.venue.getName(), newEvent.isPublic, courseAreaNames, newEvent.getImageURLs(),
newEvent.getVideoURLs(), newEvent.getSponsorImageURLs(), newEvent.getLogoImageURL(),
newEvent.getOfficialWebsiteURL(), new AsyncCallback<EventDTO>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError(stringMessages.errorTryingToCreateNewEvent(newEvent.getName(), t.getMessage()));
}
@Override
public void onSuccess(EventDTO newEvent) {
existingEvents.add(newEvent);
sailingEventsListBox.addItem(newEvent.getName());
sailingEventsListBox.setSelectedIndex(sailingEventsListBox.getItemCount() - 1);
}
});
}
private void listRegattasAndTheirStructures() {
final String jsonURL;
if (eventIDTextBox.getValue() == null || eventIDTextBox.getValue().length() == 0) {
jsonURL = jsonURLTextBox.getValue();
} else {
jsonURL = "http://manage2sail.com/api/public/links/event/" + eventIDTextBox.getValue()
+ "?accesstoken=bDAv8CwsTM94ujZ&mediaType=json";
}
if (jsonURL == null || jsonURL.length() == 0) {
errorReporter.reportError(stringMessages.pleaseEnterNonEmptyUrl());
} else {
busyIndicator.setBusy(true);
sailingService.getRegattas(jsonURL, new AsyncCallback<Iterable<RegattaDTO>>() {
@Override
public void onFailure(Throwable caught) {
busyIndicator.setBusy(false);
errorReporter.reportError("Error trying to load regattas");
}
@Override
public void onSuccess(Iterable<RegattaDTO> regattas) {
busyIndicator.setBusy(false);
editSeriesPanel.clear();
fillRegattas(regattas);
updateImportRegattasButtonEnabledness();
createEventSelectionAndCreateEventButtonUI();
editSeriesPanel.add(regattaStructureGrid);
updateRegattaStructureGrid();
}
});
}
}
private void updateImportRegattasButtonEnabledness() {
importDetailsButton.setEnabled(!regattaListComposite.getSelectedRegattas().isEmpty() &&
getSelectedEvent() != null);
}
private void fillRegattas(Iterable<RegattaDTO> regattasFromXRR) {
regattaStructures.clear();
regattaDefaultsPerStructure.clear();
for (RegattaDTO regattaFromXRR : regattasFromXRR) {
RegattaStructure regattaStructure = new RegattaStructure(regattaFromXRR);
if (!regattaDefaultsPerStructure.containsKey(regattaStructure)) {
RegattaDTO defaultsForRegattasWithStructure = createRegattaDefaults(regattaFromXRR);
regattaDefaultsPerStructure.put(regattaStructure, defaultsForRegattasWithStructure);
}
regattaStructures.put(regattaFromXRR, regattaStructure);
}
regattaListComposite.fillRegattas((List<RegattaDTO>) regattasFromXRR);
}
/**
* Creates a new basically empty default regatta structure description object; this can be used as
* an initial template that a user can modify as needed before instantiating the template for a set
* of regattas.
*/
private RegattaDTO createRegattaDefaults(RegattaDTO regatta) {
RegattaDTO result = new RegattaDTO("Default", ScoringSchemeType.LOW_POINT);
result.boatClass = new BoatClassDTO(BoatClassDTO.DEFAULT_NAME, /* hull length in meters */ 5);
result.series = regatta.series;
return result;
}
/**
* Updates the grid holding the regatta structure descriptions with the corresponding "edit" buttons
*/
private void updateRegattaStructureGrid() {
while (regattaStructureGrid.getRowCount() > 0) {
regattaStructureGrid.removeRow(0);
}
final List<RegattaDTO> originalXRRImportedRegattasToConsider;
if (regattaListComposite.getSelectedRegattas().isEmpty()) {
originalXRRImportedRegattasToConsider = regattaListComposite.getAllRegattas();
} else {
originalXRRImportedRegattasToConsider = regattaListComposite.getSelectedRegattas();
}
final Set<RegattaStructure> structures = new HashSet<>();
for (RegattaDTO originalXRRImportedRegatta : originalXRRImportedRegattasToConsider) {
structures.add(regattaStructures.get(originalXRRImportedRegatta));
}
int i = 0;
for (RegattaStructure regattaStructure : structures) {
final int row = i;
updateRegattaStructureGridRow(row, regattaStructure);
i++;
}
}
/**
* Updates a single row in the {@link #regattaStructureGrid}
*/
private void updateRegattaStructureGridRow(final int row, final RegattaStructure regattaStructure) {
Button editBtn = new Button(stringMessages.editSeries());
editBtn.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
editRegattaDefaults(row, regattaStructure);
}
});
regattaStructureGrid.setWidget(row, 0, new Label(regattaStructure.toString()));
regattaStructureGrid.setWidget(row, 1, editBtn);
}
private void editRegattaDefaults(final int row, final RegattaStructure regattaStructure) {
List<EventDTO> existingEvents = new ArrayList<EventDTO>();
EventDTO selectedEvent = getSelectedEvent();
if (selectedEvent != null) {
existingEvents.add(getSelectedEvent());
}
DefaultRegattaCreateDialog dialog = new DefaultRegattaCreateDialog(existingEvents, regattaDefaultsPerStructure.get(regattaStructure),
sailingService, errorReporter, stringMessages, new DialogCallback<EventAndRegattaDTO>() {
@Override
public void cancel() {
}
@Override
public void ok(final EventAndRegattaDTO newRegattaWithEvent) {
final RegattaDTO newRegattaCreationDefaults = newRegattaWithEvent.getRegatta();
RegattaStructure newStructureEquivalenceClass = new RegattaStructure(newRegattaCreationDefaults);
final RegattaDTO replaced = regattaDefaultsPerStructure.put(newStructureEquivalenceClass, newRegattaCreationDefaults);
if (!regattaStructure.equals(newStructureEquivalenceClass)) {
// the creation defaults (probably particularly the fleet structure) was changed "incompatibly";
// if it equals another existing structure, use the creation defaults just edited for both and
// remove the grid line; otherwise replace the grid line;
// in any case update the StructureImportListComposite to reflect the changed structure
Map<RegattaDTO, RegattaStructure> updatesToPerform = new HashMap<>();
for (Entry<RegattaDTO, RegattaStructure> e : regattaStructures.entrySet()) {
if (e.getValue().equals(regattaStructure)) {
// found a regatta that referenced the old structure which is now obsolete; let the XRR-imported
// regatta point to the new structure
updatesToPerform.put(e.getKey(), newStructureEquivalenceClass);
}
}
regattaStructures.putAll(updatesToPerform); // let original XRR-imported regattas point to their new structure
regattaDefaultsPerStructure.remove(regattaStructure);
regattaListComposite.fillRegattas(regattaStructures.keySet());
if (replaced != null) {
// requires a re-build of the grid because we don't know the other row to update/remove
updateRegattaStructureGrid();
} else {
updateRegattaStructureGridRow(row, newStructureEquivalenceClass);
}
}
}
});
dialog.ensureDebugId("DefaultRegattaCreateDialog");
dialog.show();
}
private EventDTO getSelectedEvent() {
EventDTO result = null;
int selIndex = sailingEventsListBox.getSelectedIndex();
if (selIndex > 0) { // the zero index represents the 'no selection' text
String itemText = sailingEventsListBox.getItemText(selIndex);
for (EventDTO eventDTO : existingEvents) {
if (eventDTO.getName().equals(itemText)) {
result = eventDTO;
break;
}
}
}
return result;
}
private void createRegattas(final Iterable<RegattaDTO> selectedOriginalRegattasFromXRR, EventDTO newEvent) {
eventManagementPanel.fillEvents();
final Set<RegattaDTO> regattaConfigurationsToCreate = new HashSet<>();
for (RegattaDTO originalRegattaFromXRR : selectedOriginalRegattasFromXRR) {
RegattaDTO cloneFromDefaults = new RegattaDTO(regattaDefaultsPerStructure.get(regattaStructures.get(originalRegattaFromXRR)));
cloneFromDefaults.setName(originalRegattaFromXRR.getName());
cloneFromDefaults.boatClass = originalRegattaFromXRR.boatClass;
// copy the race columns from original to clone of template
Iterator<SeriesDTO> originalSeriesIter = originalRegattaFromXRR.series.iterator();
Iterator<SeriesDTO> cloneFromDefaultsSeriesIter = cloneFromDefaults.series.iterator();
while (originalSeriesIter.hasNext() && cloneFromDefaultsSeriesIter.hasNext()) {
SeriesDTO originalSeries = originalSeriesIter.next();
SeriesDTO cloneFromDefaultsSeries = cloneFromDefaultsSeriesIter.next();
cloneFromDefaultsSeries.setRaceColumns(originalSeries.getRaceColumns());
}
regattaConfigurationsToCreate.add(cloneFromDefaults);
}
sailingService.createRegattaStructure(regattaConfigurationsToCreate, newEvent, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(stringMessages.errorAddingResultImportUrl(caught.getMessage()));
}
@Override
public void onSuccess(Void result) {
regattaRefresher.fillRegattas();
Window.alert(stringMessages.successfullyCreatedRegattas());
}
});
}
@Override
public RegattaStructure getRegattaStructure(RegattaDTO regatta) {
return regattaStructures.get(regatta);
}
}
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.common.dto.BoatClassDTO;
import com.sap.sailing.gwt.ui.adminconsole.StructureImportListComposite.RegattaStructureProvider;
import com.sap.sailing.gwt.ui.client.RegattaRefresher;
import com.sap.sailing.gwt.ui.client.RegattaSelectionModel;
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.EventAndRegattaDTO;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.controls.busyindicator.BusyIndicator;
import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
public class StructureImportManagementPanel extends FlowPanel implements RegattaStructureProvider {
private final SailingServiceAsync sailingService;
private final ErrorReporter errorReporter;
private final StringMessages stringMessages;
private final RegattaRefresher regattaRefresher;
private final EventManagementPanel eventManagementPanel;
private final StructureImportListComposite regattaListComposite;
private final BusyIndicator busyIndicator;
private TextBox jsonURLTextBox;
private TextBox eventIDTextBox;
private Button listRegattasButton;
private Button importDetailsButton;
private VerticalPanel editSeriesPanel;
private final FlexTable regattaStructureGrid;
private List<EventDTO> existingEvents;
private ListBox sailingEventsListBox;
/**
* Holds one {@link RegattaDTO} for each distinct regatta structure. The user can work with this panel
* to adjust the defaults for each structure recognized, working with the table selection to show/hide
* structures related to regattas in the list. After having set the defaults, pressing the "Import Regatta..."
* button will apply these defaults during the creation of the regattas selected. When modifying the
* defaults such that a different {@link RegattaStructure} will be needed to describe the modified version,
* the old entry shall be removed and a new one with the {@link RegattaStructure} matching the modified
* {@link RegattaDTO} shall be inserted.
*/
private final Map<RegattaStructure, RegattaDTO> regattaDefaultsPerStructure;
/**
* Maps from the {@link RegattaDTO}s coming from the XRR import to the structure to be used when creating
* the regatta in the back-end. When a regatta is first added to this map, the {@link RegattaStructure} object
* is originally created using the key as construction parameter. Over time, the user may evolve the structure
* to be used for import using the editing UIs, leading to a different {@link RegattaStructure} to be associated
* where the key is no longer part of the equivalence class defined by the {@link RegattaStructure} value.
* A typical case is a modification in the fleet structure, e.g., because the fleets weren't correctly recognized
* during the import and required some manual intervention.<p>
*
* The default settings to be used when finally creating the regatta in the back-end are maintained
* in {@link #regattaDefaultsPerStructure} for which the values of this map can be used as key.
*/
private final Map<RegattaDTO, RegattaStructure> regattaStructures;
public StructureImportManagementPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter,
StringMessages stringMessages, RegattaRefresher regattaRefresher, EventManagementPanel eventManagementPanel) {
this.regattaDefaultsPerStructure = new HashMap<>();
this.regattaStructures = new HashMap<>();
this.eventManagementPanel = eventManagementPanel;
this.busyIndicator = new SimpleBusyIndicator();
this.sailingService = sailingService;
this.errorReporter = errorReporter;
this.stringMessages = stringMessages;
this.regattaRefresher = regattaRefresher;
this.regattaListComposite = new StructureImportListComposite(this.sailingService, new RegattaSelectionModel(
true), this.regattaRefresher, this, this.errorReporter, this.stringMessages);
regattaListComposite.ensureDebugId("RegattaListComposite");
createUI();
regattaListComposite.addSelectionChangeHandler(new Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
updateRegattaStructureGrid();
updateImportRegattasButtonEnabledness();
}
});
regattaStructureGrid = new FlexTable();
}
private void createUI() {
final Panel progressPanel = new FlowPanel();
progressPanel.add(busyIndicator);
Grid URLgrid = new Grid(2, 2);
Label eventIDLabel = new Label(stringMessages.event() + ":");
Label jsonURLLabel = new Label(stringMessages.jsonUrl() + ":");
eventIDTextBox = new TextBox();
eventIDTextBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
jsonURLTextBox.setText("http://manage2sail.com/api/public/links/event/" + eventIDTextBox.getValue()
+ "?accesstoken=bDAv8CwsTM94ujZ&mediaType=json");
}
});
eventIDTextBox.ensureDebugId("eventIDTextBox");
eventIDTextBox.setVisibleLength(50);
jsonURLTextBox = new TextBox();
jsonURLTextBox.ensureDebugId("JsonURLTextBox");
jsonURLTextBox.setVisibleLength(100);
jsonURLTextBox.getElement().setPropertyString("placeholder",
"http://manage2sail.com/api/public/links/event/d30883d3-2876-4d7e-af49-891af6cbae1b?accesstoken=bDAv8CwsTM94ujZ&mediaType=json");
listRegattasButton = new Button(this.stringMessages.listRegattas());
importDetailsButton = new Button(this.stringMessages.importRegattas());
importDetailsButton.setEnabled(false);
importDetailsButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (getSelectedEvent() != null) {
List<RegattaDTO> selectedOriginalRegattasFromXRR = regattaListComposite.getSelectedRegattas();
if (!selectedOriginalRegattasFromXRR.isEmpty()) {
createRegattas(selectedOriginalRegattasFromXRR, getSelectedEvent());
} else {
errorReporter.reportError(stringMessages.pleaseSelectAtLeastOneRegatta());
}
} else {
errorReporter.reportError(stringMessages.pleaseSelectAnEvent());
}
}
});
listRegattasButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
listRegattasAndTheirStructures();
}
});
VerticalPanel vp = new VerticalPanel();
HorizontalPanel buttonPanel = new HorizontalPanel();
URLgrid.setWidget(0, 0, eventIDLabel);
URLgrid.setWidget(0, 1, eventIDTextBox);
URLgrid.setWidget(1, 0, jsonURLLabel);
URLgrid.setWidget(1, 1, jsonURLTextBox);
vp.add(URLgrid);
vp.add(buttonPanel);
buttonPanel.add(listRegattasButton);
buttonPanel.add(importDetailsButton);
Grid grid = new Grid(1, 1);
vp.add(grid);
grid.setWidget(0, 0, regattaListComposite);
grid.getRowFormatter().setVerticalAlign(0, HasVerticalAlignment.ALIGN_TOP);
grid.getColumnFormatter().getElement(0/** 1 */).getStyle().setPaddingTop(2.0, Unit.EM);
editSeriesPanel = new VerticalPanel();
add(progressPanel);
add(vp);
add(editSeriesPanel);
}
/**
* Adds an event selector and a "create new event" button to the {@link #editSeriesPanel} in its first row
*/
private void createEventSelectionAndCreateEventButtonUI() {
Grid grid = new Grid(1, 2);
sailingEventsListBox = new ListBox();
sailingEventsListBox.setMultipleSelect(false);
sailingEventsListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
updateImportRegattasButtonEnabledness();
}
});
sailingEventsListBox.ensureDebugId("EventListBox");
grid.setWidget(0, 0, sailingEventsListBox);
Button newEventBtn = new Button(stringMessages.createNewEvent());
newEventBtn.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
openEventCreateDialog();
}
});
grid.setWidget(0, 1, newEventBtn);
editSeriesPanel.add(grid);
sailingService.getEvents(new AsyncCallback<List<EventDTO>>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(stringMessages.errorTryingToGetEvents(caught.getMessage()));
}
@Override
public void onSuccess(List<EventDTO> events) {
existingEvents = events;
sailingEventsListBox.addItem(stringMessages.selectSailingEvent());
for (EventDTO event : existingEvents) {
sailingEventsListBox.addItem(event.getName());
}
}
});
}
private void openEventCreateDialog() {
EventCreateDialog dialog = new EventCreateDialog(existingEvents, Collections.<LeaderboardGroupDTO>emptyList(), stringMessages,
new DialogCallback<EventDTO>() {
@Override
public void cancel() {
}
@Override
public void ok(final EventDTO newEvent) {
createEvent(newEvent);
}
});
dialog.show();
}
private void createEvent(final EventDTO newEvent) {
List<String> courseAreaNames = new ArrayList<String>();
for (CourseAreaDTO courseAreaDTO : newEvent.venue.getCourseAreas()) {
courseAreaNames.add(courseAreaDTO.getName());
}
sailingService.createEvent(newEvent.getName(), newEvent.getDescription(), newEvent.startDate, newEvent.endDate,
newEvent.venue.getName(), newEvent.isPublic, courseAreaNames, newEvent.getImageURLs(),
newEvent.getVideoURLs(), newEvent.getSponsorImageURLs(), newEvent.getLogoImageURL(),
newEvent.getOfficialWebsiteURL(), new AsyncCallback<EventDTO>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError(stringMessages.errorTryingToCreateNewEvent(newEvent.getName(), t.getMessage()));
}
@Override
public void onSuccess(EventDTO newEvent) {
existingEvents.add(newEvent);
sailingEventsListBox.addItem(newEvent.getName());
sailingEventsListBox.setSelectedIndex(sailingEventsListBox.getItemCount() - 1);
}
});
}
private void listRegattasAndTheirStructures() {
final String jsonURL;
if (eventIDTextBox.getValue() == null || eventIDTextBox.getValue().length() == 0) {
jsonURL = jsonURLTextBox.getValue();
} else {
jsonURL = "http://manage2sail.com/api/public/links/event/" + eventIDTextBox.getValue()
+ "?accesstoken=bDAv8CwsTM94ujZ&mediaType=json";
}
if (jsonURL == null || jsonURL.length() == 0) {
errorReporter.reportError(stringMessages.pleaseEnterNonEmptyUrl());
} else {
busyIndicator.setBusy(true);
sailingService.getRegattas(jsonURL, new AsyncCallback<Iterable<RegattaDTO>>() {
@Override
public void onFailure(Throwable caught) {
busyIndicator.setBusy(false);
errorReporter.reportError("Error trying to load regattas");
}
@Override
public void onSuccess(Iterable<RegattaDTO> regattas) {
busyIndicator.setBusy(false);
editSeriesPanel.clear();
fillRegattas(regattas);
updateImportRegattasButtonEnabledness();
createEventSelectionAndCreateEventButtonUI();
editSeriesPanel.add(regattaStructureGrid);
updateRegattaStructureGrid();
}
});
}
}
private void updateImportRegattasButtonEnabledness() {
importDetailsButton.setEnabled(!regattaListComposite.getSelectedRegattas().isEmpty() &&
getSelectedEvent() != null);
}
private void fillRegattas(Iterable<RegattaDTO> regattasFromXRR) {
regattaStructures.clear();
regattaDefaultsPerStructure.clear();
for (RegattaDTO regattaFromXRR : regattasFromXRR) {
RegattaStructure regattaStructure = new RegattaStructure(regattaFromXRR);
if (!regattaDefaultsPerStructure.containsKey(regattaStructure)) {
RegattaDTO defaultsForRegattasWithStructure = createRegattaDefaults(regattaFromXRR);
regattaDefaultsPerStructure.put(regattaStructure, defaultsForRegattasWithStructure);
}
regattaStructures.put(regattaFromXRR, regattaStructure);
}
regattaListComposite.fillRegattas((List<RegattaDTO>) regattasFromXRR);
}
/**
* Creates a new basically empty default regatta structure description object; this can be used as
* an initial template that a user can modify as needed before instantiating the template for a set
* of regattas.
*/
private RegattaDTO createRegattaDefaults(RegattaDTO regatta) {
RegattaDTO result = new RegattaDTO("Default", ScoringSchemeType.LOW_POINT);
result.boatClass = new BoatClassDTO(BoatClassDTO.DEFAULT_NAME, /* hull length in meters */ 5);
result.series = regatta.series;
return result;
}
/**
* Updates the grid holding the regatta structure descriptions with the corresponding "edit" buttons
*/
private void updateRegattaStructureGrid() {
while (regattaStructureGrid.getRowCount() > 0) {
regattaStructureGrid.removeRow(0);
}
final List<RegattaDTO> originalXRRImportedRegattasToConsider;
if (regattaListComposite.getSelectedRegattas().isEmpty()) {
originalXRRImportedRegattasToConsider = regattaListComposite.getAllRegattas();
} else {
originalXRRImportedRegattasToConsider = regattaListComposite.getSelectedRegattas();
}
final Set<RegattaStructure> structures = new HashSet<>();
for (RegattaDTO originalXRRImportedRegatta : originalXRRImportedRegattasToConsider) {
structures.add(regattaStructures.get(originalXRRImportedRegatta));
}
int i = 0;
for (RegattaStructure regattaStructure : structures) {
final int row = i;
updateRegattaStructureGridRow(row, regattaStructure);
i++;
}
}
/**
* Updates a single row in the {@link #regattaStructureGrid}
*/
private void updateRegattaStructureGridRow(final int row, final RegattaStructure regattaStructure) {
Button editBtn = new Button(stringMessages.editSeries());
editBtn.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
editRegattaDefaults(row, regattaStructure);
}
});
regattaStructureGrid.setWidget(row, 0, new Label(regattaStructure.toString()));
regattaStructureGrid.setWidget(row, 1, editBtn);
}
private void editRegattaDefaults(final int row, final RegattaStructure regattaStructure) {
List<EventDTO> existingEvents = new ArrayList<EventDTO>();
EventDTO selectedEvent = getSelectedEvent();
if (selectedEvent != null) {
existingEvents.add(getSelectedEvent());
}
DefaultRegattaCreateDialog dialog = new DefaultRegattaCreateDialog(existingEvents, regattaDefaultsPerStructure.get(regattaStructure),
sailingService, errorReporter, stringMessages, new DialogCallback<EventAndRegattaDTO>() {
@Override
public void cancel() {
}
@Override
public void ok(final EventAndRegattaDTO newRegattaWithEvent) {
final RegattaDTO newRegattaCreationDefaults = newRegattaWithEvent.getRegatta();
RegattaStructure newStructureEquivalenceClass = new RegattaStructure(newRegattaCreationDefaults);
final RegattaDTO replaced = regattaDefaultsPerStructure.put(newStructureEquivalenceClass, newRegattaCreationDefaults);
if (!regattaStructure.equals(newStructureEquivalenceClass)) {
// the creation defaults (probably particularly the fleet structure) was changed "incompatibly";
// if it equals another existing structure, use the creation defaults just edited for both and
// remove the grid line; otherwise replace the grid line;
// in any case update the StructureImportListComposite to reflect the changed structure
Map<RegattaDTO, RegattaStructure> updatesToPerform = new HashMap<>();
for (Entry<RegattaDTO, RegattaStructure> e : regattaStructures.entrySet()) {
if (e.getValue().equals(regattaStructure)) {
// found a regatta that referenced the old structure which is now obsolete; let the XRR-imported
// regatta point to the new structure
updatesToPerform.put(e.getKey(), newStructureEquivalenceClass);
}
}
regattaStructures.putAll(updatesToPerform); // let original XRR-imported regattas point to their new structure
regattaDefaultsPerStructure.remove(regattaStructure);
regattaListComposite.fillRegattas(regattaStructures.keySet());
if (replaced != null) {
// requires a re-build of the grid because we don't know the other row to update/remove
updateRegattaStructureGrid();
} else {
updateRegattaStructureGridRow(row, newStructureEquivalenceClass);
}
}
}
});
dialog.ensureDebugId("DefaultRegattaCreateDialog");
dialog.show();
}
private EventDTO getSelectedEvent() {
EventDTO result = null;
int selIndex = sailingEventsListBox.getSelectedIndex();
if (selIndex > 0) { // the zero index represents the 'no selection' text
String itemText = sailingEventsListBox.getItemText(selIndex);
for (EventDTO eventDTO : existingEvents) {
if (eventDTO.getName().equals(itemText)) {
result = eventDTO;
break;
}
}
}
return result;
}
private void createRegattas(final Iterable<RegattaDTO> selectedOriginalRegattasFromXRR, EventDTO newEvent) {
eventManagementPanel.fillEvents();
final Set<RegattaDTO> regattaConfigurationsToCreate = new HashSet<>();
for (RegattaDTO originalRegattaFromXRR : selectedOriginalRegattasFromXRR) {
RegattaDTO cloneFromDefaults = new RegattaDTO(regattaDefaultsPerStructure.get(regattaStructures.get(originalRegattaFromXRR)));
cloneFromDefaults.setName(originalRegattaFromXRR.getName());
cloneFromDefaults.boatClass = originalRegattaFromXRR.boatClass;
// copy the race columns from original to clone of template
Iterator<SeriesDTO> originalSeriesIter = originalRegattaFromXRR.series.iterator();
Iterator<SeriesDTO> cloneFromDefaultsSeriesIter = cloneFromDefaults.series.iterator();
while (originalSeriesIter.hasNext() && cloneFromDefaultsSeriesIter.hasNext()) {
SeriesDTO originalSeries = originalSeriesIter.next();
SeriesDTO cloneFromDefaultsSeries = cloneFromDefaultsSeriesIter.next();
cloneFromDefaultsSeries.setRaceColumns(originalSeries.getRaceColumns());
}
regattaConfigurationsToCreate.add(cloneFromDefaults);
}
sailingService.createRegattaStructure(regattaConfigurationsToCreate, newEvent, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(stringMessages.errorAddingResultImportUrl(caught.getMessage()));
}
@Override
public void onSuccess(Void result) {
regattaRefresher.fillRegattas();
Window.alert(stringMessages.successfullyCreatedRegattas());
}
});
}
@Override
public RegattaStructure getRegattaStructure(RegattaDTO regatta) {
return regattaStructures.get(regatta);
}
}
@@ -121,7 +121,8 @@ public class StringConstantsListEditorComposite extends ListEditorComposite<Stri
}
protected ListBox createListBox() {
ListBox result = new ListBox(false);
ListBox result = new ListBox();
result.setMultipleSelect(false);
updateSelectionListBox(result, availableConstantValuesToAdd);
return result;
}
@@ -1,487 +1,488 @@
package com.sap.sse.gwt.client.dialog;
import java.util.Date;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.LongBox;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.sap.sse.gwt.client.controls.IntegerBox;
/**
* An abstract data entry dialog class, capturing data of type <code>T</code>, with generic OK/Cancel buttons, title and
* message. Subclasses may override the {@link #show()} method to set the focus on their favorable initial entry field.
* Subclasses can specify a widget to show in the dialog to capture properties specific to the result type <code>T</code> by
* overriding the {@link #getAdditionalWidget()} method.
*
* @author Axel Uhl (d043530)
*/
public abstract class DataEntryDialog<T> {
private final DialogBox dateEntryDialog;
private final Validator<T> validator;
private final Button okButton;
private final Button cancelButton;
private final Label statusLabel;
private final FlowPanel panelForAdditionalWidget;
public static interface Validator<T> {
/**
* @return <code>null</code> in case the <code>valueToValidate</code> is valid; a user-readable error message otherwise
*/
String getErrorMessage(T valueToValidate);
}
public static interface DialogCallback<T> {
void ok(T editedObject);
void cancel();
}
/**
* @param validator
* an optional validator; if <code>null</code>, no validation of data entered is performed; otherwise,
* data validation is triggered upon any noticeable change in any of the elements constructed by
* {@link #createCheckbox(String)}, {@link #createTextBox(String)}, etc.
* @param callback
* will be called when the dialog if {@link AsyncCallback#onFailure(Throwable) cancelled} or
* {@link AsyncCallback#onSuccess(Object) confirmed}
*/
public DataEntryDialog(String title, String message, String okButtonName, String cancelButtonName,
Validator<T> validator, final DialogCallback<T> callback) {
this(title, message, okButtonName, cancelButtonName, validator, /* animationEnabled */ true, callback);
}
/**
* @param validator
* an optional validator; if <code>null</code>, no validation of data entered is performed; otherwise,
* data validation is triggered upon any noticeable change in any of the elements constructed by
* {@link #createCheckbox(String)}, {@link #createTextBox(String)}, etc.
* @param callback
* will be called when the dialog if {@link AsyncCallback#onFailure(Throwable) cancelled} or
* {@link AsyncCallback#onSuccess(Object) confirmed}
*/
public DataEntryDialog(String title, String message, String okButtonName, String cancelButtonName,
Validator<T> validator, boolean animationEnabled, final DialogCallback<T> callback) {
dateEntryDialog = new DialogBox();
dateEntryDialog.setText(title);
dateEntryDialog.setAnimationEnabled(animationEnabled);
this.validator = validator;
okButton = new Button(okButtonName);
okButton.getElement().getStyle().setMargin(3, Unit.PX);
okButton.ensureDebugId("OkButton");
FlowPanel dialogFPanel = new FlowPanel();
dialogFPanel.setWidth("100%");
statusLabel = new Label();
statusLabel.ensureDebugId("StatusLabel");
dialogFPanel.add(statusLabel);
if (message != null) {
Label messageLabel = new Label(message);
messageLabel.addStyleName("dialogMessageLabel");
dialogFPanel.add(messageLabel);
}
panelForAdditionalWidget = new FlowPanel();
panelForAdditionalWidget.setWidth("100%");
dialogFPanel.add(panelForAdditionalWidget);
FlowPanel buttonPanel = new FlowPanel();
dialogFPanel.add(buttonPanel);
buttonPanel.setStyleName("additionalWidgets");
buttonPanel.add(okButton);
cancelButton = new Button(cancelButtonName);
cancelButton.getElement().getStyle().setMargin(3, Unit.PX);
cancelButton.ensureDebugId("CancelButton");
buttonPanel.add(cancelButton);
cancelButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
dateEntryDialog.hide();
callback.cancel();
}
});
dateEntryDialog.setWidget(dialogFPanel);
okButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
dateEntryDialog.hide();
callback.ok(getResult());
}
});
}
protected boolean validate() {
String errorMessage = null;
if (validator != null) {
errorMessage = validator.getErrorMessage(getResult());
}
if (errorMessage == null) {
getStatusLabel().setText("");
getOkButton().setEnabled(true);
} else {
getStatusLabel().setText(errorMessage);
getStatusLabel().setStyleName("errorLabel");
getOkButton().setEnabled(false);
}
return errorMessage == null;
}
protected abstract T getResult();
/**
* Creates a text box with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in text box; <code>null</code> is permissible
*/
public TextBox createTextBox(String initialValue) {
return createTextBoxInternal(initialValue, 30);
}
/**
* Creates a text box with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in text box; <code>null</code> is permissible
* @param visibleLength the visible length of the text box
*/
public TextBox createTextBox(String initialValue, int visibleLength) {
return createTextBoxInternal(initialValue, visibleLength);
}
private TextBox createTextBoxInternal(String initialValue, int visibleLength) {
TextBox textBox = new TextBox();
textBox.setVisibleLength(visibleLength);
textBox.setText(initialValue == null ? "" : initialValue);
DialogUtils.addFocusUponKeyUpToggler(textBox);
textBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), textBox);
DialogUtils.linkEscapeToButton(getCancelButton(), textBox);
return textBox;
}
/**
* Creates a password text box with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in text box; <code>null</code> is permissible
*/
public PasswordTextBox createPasswordTextBox(String initialValue) {
return createPasswordTextBoxInternal(initialValue, 30);
}
/**
* Creates a password text box with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in text box; <code>null</code> is permissible
* @param visibleLength the visible length of the text box
*/
public PasswordTextBox createPasswordTextBox(String initialValue, int visibleLength) {
return createPasswordTextBoxInternal(initialValue, visibleLength);
}
private PasswordTextBox createPasswordTextBoxInternal(String initialValue, int visibleLength) {
PasswordTextBox parrwordTextBox = new PasswordTextBox();
parrwordTextBox.setVisibleLength(visibleLength);
parrwordTextBox.setText(initialValue == null ? "" : initialValue);
DialogUtils.addFocusUponKeyUpToggler(parrwordTextBox);
parrwordTextBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), parrwordTextBox);
DialogUtils.linkEscapeToButton(getCancelButton(), parrwordTextBox);
return parrwordTextBox;
}
/**
* Creates a text area with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue Initial value to show in text area; <code>null</code> is permissible
*/
public TextArea createTextArea(String initialValue) {
TextArea textArea = new TextArea();
textArea.setText(initialValue == null ? "" : initialValue);
DialogUtils.addFocusUponKeyUpToggler(textArea);
textArea.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent arg0) {
validate();
}
});
DialogUtils.linkEscapeToButton(getCancelButton(), textArea);
return textArea;
}
/**
* Creates a box for a long value with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in the long box; <code>null</code> is permissible
*/
public LongBox createLongBox(long initialValue, int visibleLength) {
LongBox longBox = new LongBox();
longBox.setVisibleLength(visibleLength);
longBox.setValue(initialValue);
DialogUtils.addFocusUponKeyUpToggler(longBox);
longBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), longBox);
DialogUtils.linkEscapeToButton(getCancelButton(), longBox);
return longBox;
}
public DoubleBox createDoubleBox(double initialValue, int visibleLength) {
return createDoubleBoxInternal(initialValue, visibleLength);
}
public DoubleBox createDoubleBox(int visibleLength) {
return createDoubleBoxInternal(null, visibleLength);
}
private DoubleBox createDoubleBoxInternal(Double initialValue, int visibleLength) {
DoubleBox doubleBox = new DoubleBox();
doubleBox.setVisibleLength(visibleLength);
doubleBox.setValue(initialValue);
DialogUtils.addFocusUponKeyUpToggler(doubleBox);
doubleBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), doubleBox);
DialogUtils.linkEscapeToButton(getCancelButton(), doubleBox);
return doubleBox;
}
public DateBox createDateBox(Date initialDate, int visibleLength) {
return createDateBoxInternal(initialDate, visibleLength);
}
public DateBox createDateBox(long initialTimeInMs, int visibleLength) {
return createDateBoxInternal(new Date(initialTimeInMs), visibleLength);
}
public DateBox createDateBox(int visibleLength) {
return createDateBoxInternal(null, visibleLength);
}
private DateBox createDateBoxInternal(Date initialDate, int visibleLength) {
DateBox dateBox = new DateBox();
dateBox.getTextBox().setVisibleLength(visibleLength);
dateBox.setFireNullValues(true);
dateBox.setValue(initialDate);
DialogUtils.addFocusUponKeyUpToggler(dateBox.getTextBox());
dateBox.addValueChangeHandler(new ValueChangeHandler<Date>() {
@Override
public void onValueChange(ValueChangeEvent<Date> event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), dateBox.getTextBox());
DialogUtils.linkEscapeToButton(getCancelButton(), dateBox.getTextBox());
return dateBox;
}
/**
* Creates a box for a integer value with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in the integer box; <code>null</code> is permissible
*/
public IntegerBox createIntegerBox(Integer initialValue, int visibleLength) {
IntegerBox intBox = new IntegerBox();
intBox.setVisibleLength(visibleLength);
intBox.setValue(initialValue);
DialogUtils.addFocusUponKeyUpToggler(intBox);
intBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), intBox);
DialogUtils.linkEscapeToButton(getCancelButton(), intBox);
return intBox;
}
public LongBox createLongBoxWithOptionalValue(Long initialValue, int visibleLength) {
LongBox longBox = new LongBox();
longBox.setVisibleLength(visibleLength);
longBox.setValue(initialValue);
DialogUtils.addFocusUponKeyUpToggler(longBox);
longBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), longBox);
DialogUtils.linkEscapeToButton(getCancelButton(), longBox);
return longBox;
}
public Label createHeadlineLabel(String headlineText) {
Label headlineLabel = new Label(headlineText);
headlineLabel.getElement().getStyle().setFontWeight(FontWeight.BOLD);
headlineLabel.getElement().getStyle().setPaddingTop(1, Unit.EM);
return headlineLabel;
}
public FlowPanel createHeadline(String headlineText, boolean regularHeadline) {
FlowPanel headlinePanel = new FlowPanel();
Label headlineLabel = new Label(headlineText);
if (regularHeadline) {
headlinePanel.addStyleName("dialogInnerHeadline");
} else {
headlinePanel.addStyleName("dialogInnerHeadlineOther");
}
headlinePanel.add(headlineLabel);
return headlinePanel;
}
public CheckBox createCheckbox(String checkboxLabel) {
CheckBox result = new CheckBox(checkboxLabel);
result.setWordWrap(false);
result.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), result);
DialogUtils.linkEscapeToButton(getCancelButton(), result);
return result;
}
public void addTooltip(IsWidget widget, String tooltip) {
widget.asWidget().setTitle(tooltip);
}
public RadioButton createRadioButton(String radioButtonGroupName, String radioButtonLabel) {
RadioButton result = new RadioButton(radioButtonGroupName, radioButtonLabel);
result.setWordWrap(false);
result.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), result);
DialogUtils.linkEscapeToButton(getCancelButton(), result);
return result;
}
/**
* Creates a standard label for input fields.
* The label has some default formatting like "no wrap" and a colon right after the label text
* @param name
* @return
*/
public Label createLabel(String name) {
Label result = new Label(name + ":");
result.setWordWrap(false);
return result;
}
public ListBox createListBox(boolean isMultipleSelect) {
ListBox result = new ListBox(isMultipleSelect);
result.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), result);
DialogUtils.linkEscapeToButton(getCancelButton(), result);
return result;
}
public void alignAllPanelWidgetsVertically(HorizontalPanel panel, HasVerticalAlignment.VerticalAlignmentConstant alignment) {
for (int i = 0; i < panel.getWidgetCount(); i++) {
panel.setCellVerticalAlignment(panel.getWidget(i), alignment);
}
}
/**
* Can contribute an additional widget to be displayed underneath the text entry field. If <code>null</code> is
* returned, no additional widget will be displayed. This is the default behavior of this default implementation.
*/
protected Widget getAdditionalWidget() {
return null;
}
protected Button getOkButton() {
return okButton;
}
protected Button getCancelButton() {
return cancelButton;
}
/**
* status label can be used to display status information within the dialog to the user
*/
protected Label getStatusLabel() {
return statusLabel;
}
protected void setCursor(Style.Cursor cursor) {
dateEntryDialog.getElement().getStyle().setCursor(cursor);
}
public void show() {
Widget additionalWidget = getAdditionalWidget();
if (additionalWidget != null) {
panelForAdditionalWidget.add(additionalWidget);
}
validate();
dateEntryDialog.center();
}
protected DialogBox getDialogBox() {
return dateEntryDialog;
}
public void ensureDebugId(String debugId) {
dateEntryDialog.ensureDebugId(debugId);
}
protected void addAutoHidePartner(Element element) {
dateEntryDialog.addAutoHidePartner(element);
}
}
package com.sap.sse.gwt.client.dialog;
import java.util.Date;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.LongBox;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.sap.sse.gwt.client.controls.IntegerBox;
/**
* An abstract data entry dialog class, capturing data of type <code>T</code>, with generic OK/Cancel buttons, title and
* message. Subclasses may override the {@link #show()} method to set the focus on their favorable initial entry field.
* Subclasses can specify a widget to show in the dialog to capture properties specific to the result type <code>T</code> by
* overriding the {@link #getAdditionalWidget()} method.
*
* @author Axel Uhl (d043530)
*/
public abstract class DataEntryDialog<T> {
private final DialogBox dateEntryDialog;
private final Validator<T> validator;
private final Button okButton;
private final Button cancelButton;
private final Label statusLabel;
private final FlowPanel panelForAdditionalWidget;
public static interface Validator<T> {
/**
* @return <code>null</code> in case the <code>valueToValidate</code> is valid; a user-readable error message otherwise
*/
String getErrorMessage(T valueToValidate);
}
public static interface DialogCallback<T> {
void ok(T editedObject);
void cancel();
}
/**
* @param validator
* an optional validator; if <code>null</code>, no validation of data entered is performed; otherwise,
* data validation is triggered upon any noticeable change in any of the elements constructed by
* {@link #createCheckbox(String)}, {@link #createTextBox(String)}, etc.
* @param callback
* will be called when the dialog if {@link AsyncCallback#onFailure(Throwable) cancelled} or
* {@link AsyncCallback#onSuccess(Object) confirmed}
*/
public DataEntryDialog(String title, String message, String okButtonName, String cancelButtonName,
Validator<T> validator, final DialogCallback<T> callback) {
this(title, message, okButtonName, cancelButtonName, validator, /* animationEnabled */ true, callback);
}
/**
* @param validator
* an optional validator; if <code>null</code>, no validation of data entered is performed; otherwise,
* data validation is triggered upon any noticeable change in any of the elements constructed by
* {@link #createCheckbox(String)}, {@link #createTextBox(String)}, etc.
* @param callback
* will be called when the dialog if {@link AsyncCallback#onFailure(Throwable) cancelled} or
* {@link AsyncCallback#onSuccess(Object) confirmed}
*/
public DataEntryDialog(String title, String message, String okButtonName, String cancelButtonName,
Validator<T> validator, boolean animationEnabled, final DialogCallback<T> callback) {
dateEntryDialog = new DialogBox();
dateEntryDialog.setText(title);
dateEntryDialog.setAnimationEnabled(animationEnabled);
this.validator = validator;
okButton = new Button(okButtonName);
okButton.getElement().getStyle().setMargin(3, Unit.PX);
okButton.ensureDebugId("OkButton");
FlowPanel dialogFPanel = new FlowPanel();
dialogFPanel.setWidth("100%");
statusLabel = new Label();
statusLabel.ensureDebugId("StatusLabel");
dialogFPanel.add(statusLabel);
if (message != null) {
Label messageLabel = new Label(message);
messageLabel.addStyleName("dialogMessageLabel");
dialogFPanel.add(messageLabel);
}
panelForAdditionalWidget = new FlowPanel();
panelForAdditionalWidget.setWidth("100%");
dialogFPanel.add(panelForAdditionalWidget);
FlowPanel buttonPanel = new FlowPanel();
dialogFPanel.add(buttonPanel);
buttonPanel.setStyleName("additionalWidgets");
buttonPanel.add(okButton);
cancelButton = new Button(cancelButtonName);
cancelButton.getElement().getStyle().setMargin(3, Unit.PX);
cancelButton.ensureDebugId("CancelButton");
buttonPanel.add(cancelButton);
cancelButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
dateEntryDialog.hide();
callback.cancel();
}
});
dateEntryDialog.setWidget(dialogFPanel);
okButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
dateEntryDialog.hide();
callback.ok(getResult());
}
});
}
protected boolean validate() {
String errorMessage = null;
if (validator != null) {
errorMessage = validator.getErrorMessage(getResult());
}
if (errorMessage == null) {
getStatusLabel().setText("");
getOkButton().setEnabled(true);
} else {
getStatusLabel().setText(errorMessage);
getStatusLabel().setStyleName("errorLabel");
getOkButton().setEnabled(false);
}
return errorMessage == null;
}
protected abstract T getResult();
/**
* Creates a text box with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in text box; <code>null</code> is permissible
*/
public TextBox createTextBox(String initialValue) {
return createTextBoxInternal(initialValue, 30);
}
/**
* Creates a text box with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in text box; <code>null</code> is permissible
* @param visibleLength the visible length of the text box
*/
public TextBox createTextBox(String initialValue, int visibleLength) {
return createTextBoxInternal(initialValue, visibleLength);
}
private TextBox createTextBoxInternal(String initialValue, int visibleLength) {
TextBox textBox = new TextBox();
textBox.setVisibleLength(visibleLength);
textBox.setText(initialValue == null ? "" : initialValue);
DialogUtils.addFocusUponKeyUpToggler(textBox);
textBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), textBox);
DialogUtils.linkEscapeToButton(getCancelButton(), textBox);
return textBox;
}
/**
* Creates a password text box with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in text box; <code>null</code> is permissible
*/
public PasswordTextBox createPasswordTextBox(String initialValue) {
return createPasswordTextBoxInternal(initialValue, 30);
}
/**
* Creates a password text box with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in text box; <code>null</code> is permissible
* @param visibleLength the visible length of the text box
*/
public PasswordTextBox createPasswordTextBox(String initialValue, int visibleLength) {
return createPasswordTextBoxInternal(initialValue, visibleLength);
}
private PasswordTextBox createPasswordTextBoxInternal(String initialValue, int visibleLength) {
PasswordTextBox parrwordTextBox = new PasswordTextBox();
parrwordTextBox.setVisibleLength(visibleLength);
parrwordTextBox.setText(initialValue == null ? "" : initialValue);
DialogUtils.addFocusUponKeyUpToggler(parrwordTextBox);
parrwordTextBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), parrwordTextBox);
DialogUtils.linkEscapeToButton(getCancelButton(), parrwordTextBox);
return parrwordTextBox;
}
/**
* Creates a text area with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue Initial value to show in text area; <code>null</code> is permissible
*/
public TextArea createTextArea(String initialValue) {
TextArea textArea = new TextArea();
textArea.setText(initialValue == null ? "" : initialValue);
DialogUtils.addFocusUponKeyUpToggler(textArea);
textArea.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent arg0) {
validate();
}
});
DialogUtils.linkEscapeToButton(getCancelButton(), textArea);
return textArea;
}
/**
* Creates a box for a long value with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in the long box; <code>null</code> is permissible
*/
public LongBox createLongBox(long initialValue, int visibleLength) {
LongBox longBox = new LongBox();
longBox.setVisibleLength(visibleLength);
longBox.setValue(initialValue);
DialogUtils.addFocusUponKeyUpToggler(longBox);
longBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), longBox);
DialogUtils.linkEscapeToButton(getCancelButton(), longBox);
return longBox;
}
public DoubleBox createDoubleBox(double initialValue, int visibleLength) {
return createDoubleBoxInternal(initialValue, visibleLength);
}
public DoubleBox createDoubleBox(int visibleLength) {
return createDoubleBoxInternal(null, visibleLength);
}
private DoubleBox createDoubleBoxInternal(Double initialValue, int visibleLength) {
DoubleBox doubleBox = new DoubleBox();
doubleBox.setVisibleLength(visibleLength);
doubleBox.setValue(initialValue);
DialogUtils.addFocusUponKeyUpToggler(doubleBox);
doubleBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), doubleBox);
DialogUtils.linkEscapeToButton(getCancelButton(), doubleBox);
return doubleBox;
}
public DateBox createDateBox(Date initialDate, int visibleLength) {
return createDateBoxInternal(initialDate, visibleLength);
}
public DateBox createDateBox(long initialTimeInMs, int visibleLength) {
return createDateBoxInternal(new Date(initialTimeInMs), visibleLength);
}
public DateBox createDateBox(int visibleLength) {
return createDateBoxInternal(null, visibleLength);
}
private DateBox createDateBoxInternal(Date initialDate, int visibleLength) {
DateBox dateBox = new DateBox();
dateBox.getTextBox().setVisibleLength(visibleLength);
dateBox.setFireNullValues(true);
dateBox.setValue(initialDate);
DialogUtils.addFocusUponKeyUpToggler(dateBox.getTextBox());
dateBox.addValueChangeHandler(new ValueChangeHandler<Date>() {
@Override
public void onValueChange(ValueChangeEvent<Date> event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), dateBox.getTextBox());
DialogUtils.linkEscapeToButton(getCancelButton(), dateBox.getTextBox());
return dateBox;
}
/**
* Creates a box for a integer value with a key-up listener attached which ensures the value is updated after each
* key-up event and the entire dialog is {@link #validate() validated} in this case.
*
* @param initialValue initial value to show in the integer box; <code>null</code> is permissible
*/
public IntegerBox createIntegerBox(Integer initialValue, int visibleLength) {
IntegerBox intBox = new IntegerBox();
intBox.setVisibleLength(visibleLength);
intBox.setValue(initialValue);
DialogUtils.addFocusUponKeyUpToggler(intBox);
intBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), intBox);
DialogUtils.linkEscapeToButton(getCancelButton(), intBox);
return intBox;
}
public LongBox createLongBoxWithOptionalValue(Long initialValue, int visibleLength) {
LongBox longBox = new LongBox();
longBox.setVisibleLength(visibleLength);
longBox.setValue(initialValue);
DialogUtils.addFocusUponKeyUpToggler(longBox);
longBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), longBox);
DialogUtils.linkEscapeToButton(getCancelButton(), longBox);
return longBox;
}
public Label createHeadlineLabel(String headlineText) {
Label headlineLabel = new Label(headlineText);
headlineLabel.getElement().getStyle().setFontWeight(FontWeight.BOLD);
headlineLabel.getElement().getStyle().setPaddingTop(1, Unit.EM);
return headlineLabel;
}
public FlowPanel createHeadline(String headlineText, boolean regularHeadline) {
FlowPanel headlinePanel = new FlowPanel();
Label headlineLabel = new Label(headlineText);
if (regularHeadline) {
headlinePanel.addStyleName("dialogInnerHeadline");
} else {
headlinePanel.addStyleName("dialogInnerHeadlineOther");
}
headlinePanel.add(headlineLabel);
return headlinePanel;
}
public CheckBox createCheckbox(String checkboxLabel) {
CheckBox result = new CheckBox(checkboxLabel);
result.setWordWrap(false);
result.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), result);
DialogUtils.linkEscapeToButton(getCancelButton(), result);
return result;
}
public void addTooltip(IsWidget widget, String tooltip) {
widget.asWidget().setTitle(tooltip);
}
public RadioButton createRadioButton(String radioButtonGroupName, String radioButtonLabel) {
RadioButton result = new RadioButton(radioButtonGroupName, radioButtonLabel);
result.setWordWrap(false);
result.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), result);
DialogUtils.linkEscapeToButton(getCancelButton(), result);
return result;
}
/**
* Creates a standard label for input fields.
* The label has some default formatting like "no wrap" and a colon right after the label text
* @param name
* @return
*/
public Label createLabel(String name) {
Label result = new Label(name + ":");
result.setWordWrap(false);
return result;
}
public ListBox createListBox(boolean isMultipleSelect) {
ListBox result = new ListBox();
result.setMultipleSelect(isMultipleSelect);
result.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
validate();
}
});
DialogUtils.linkEnterToButton(getOkButton(), result);
DialogUtils.linkEscapeToButton(getCancelButton(), result);
return result;
}
public void alignAllPanelWidgetsVertically(HorizontalPanel panel, HasVerticalAlignment.VerticalAlignmentConstant alignment) {
for (int i = 0; i < panel.getWidgetCount(); i++) {
panel.setCellVerticalAlignment(panel.getWidget(i), alignment);
}
}
/**
* Can contribute an additional widget to be displayed underneath the text entry field. If <code>null</code> is
* returned, no additional widget will be displayed. This is the default behavior of this default implementation.
*/
protected Widget getAdditionalWidget() {
return null;
}
protected Button getOkButton() {
return okButton;
}
protected Button getCancelButton() {
return cancelButton;
}
/**
* status label can be used to display status information within the dialog to the user
*/
protected Label getStatusLabel() {
return statusLabel;
}
protected void setCursor(Style.Cursor cursor) {
dateEntryDialog.getElement().getStyle().setCursor(cursor);
}
public void show() {
Widget additionalWidget = getAdditionalWidget();
if (additionalWidget != null) {
panelForAdditionalWidget.add(additionalWidget);
}
validate();
dateEntryDialog.center();
}
protected DialogBox getDialogBox() {
return dateEntryDialog;
}
public void ensureDebugId(String debugId) {
dateEntryDialog.ensureDebugId(debugId);
}
protected void addAutoHidePartner(Element element) {
dateEntryDialog.addAutoHidePartner(element);
}
}