package org.ovirt.engine.ui.common.view.popup; import java.util.ArrayList; import java.util.List; import org.ovirt.engine.ui.common.idhandler.HasElementId; import org.ovirt.engine.ui.common.presenter.AbstractModelBoundPopupPresenterWidget; import org.ovirt.engine.ui.common.utils.ElementIdUtils; import org.ovirt.engine.ui.common.view.AbstractPopupView; import org.ovirt.engine.ui.common.widget.HasUiCommandClickHandlers; import org.ovirt.engine.ui.common.widget.IsProgressContentWidget; import org.ovirt.engine.ui.common.widget.UiCommandButton; import org.ovirt.engine.ui.common.widget.dialog.AbstractDialogPanel; import org.ovirt.engine.ui.common.widget.dialog.PopupNativeKeyPressHandler; import org.ovirt.engine.ui.common.widget.dialog.ProgressPopupContent; import org.ovirt.engine.ui.uicommonweb.UICommand; import org.ovirt.engine.ui.uicommonweb.models.Model; import com.google.gwt.event.dom.client.HasClickHandlers; import com.google.gwt.event.shared.EventBus; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.Widget; /** * Base class for popup views bound to a UiCommon Window model. * * @param <T> * Window model type. */ public abstract class AbstractModelBoundPopupView<T extends Model> extends AbstractPopupView<AbstractDialogPanel> implements AbstractModelBoundPopupPresenterWidget.ViewDef<T>, HasElementId, FocusableComponentsContainer { /** * Popup progress indicator widget */ private final IsProgressContentWidget progressContent; /** * Actual popup content */ private Widget popupContent; /** * Popup hash-name */ private String hashName; private String elementId = DOM.createUniqueId(); private final List<FocusableComponentsContainer> focusableButtons = new ArrayList<>(); public AbstractModelBoundPopupView(EventBus eventBus) { super(eventBus); this.progressContent = createProgressContentWidget(); } @Override protected void initWidget(AbstractDialogPanel widget) { super.initWidget(widget); this.popupContent = widget.getContent(); } protected UiCommandButton createCommandButton(String label, String uniqueId) { return new UiCommandButton(label); } protected IsProgressContentWidget createProgressContentWidget() { return new ProgressPopupContent(); } /** * Hook bound to "Title" property change on given model. */ @Override public void setTitle(String title) { asWidget().setHeader(title); } /** * Hook bound to "Message" property change on given model. */ @Override public void setMessage(String message) { // No-op, override as necessary } /** * Hook bound to "Items" property change on given model. * <p> * Called only if the model is a {@code ListModel}. */ @Override public void setItems(Iterable<?> items) { // No-op, override as necessary } /** * Hook bound to "HashName" property change on given model. */ @Override public void setHashName(String name) { this.hashName = name; } /** * Hook bound to "HelpTag" property change on given model. * <p> * Called only if the model's {@linkplain Model#getOpenDocumentationCommand Open * Documentation command} (open context-sensitive help) is available, passing it * as a parameter. */ @Override public void setHelpCommand(UICommand command) { asWidget().setHelpCommand(command); } @Override public HasUiCommandClickHandlers addFooterButton(String label, String uniqueId, boolean isPrimary) { UiCommandButton button = createCommandButton(label, uniqueId); asWidget().addFooterButton(button); focusableButtons.add(0, button); // Set button element ID for better accessibility button.asWidget().getElement().setId( ElementIdUtils.createElementId(elementId, uniqueId)); if (isPrimary) { button.setAsPrimary(); } return button; } public void addStatusWidget(Widget widget) { asWidget().addStatusWidget(widget); } @Override public void removeButtons() { asWidget().removeFooterButtons(); focusableButtons.clear(); } @Override public void startProgress(String progressMessage) { // Set dialog content to the progress indicator widget progressContent.setProgressMessage(progressMessage); asWidget().setContent(progressContent.asWidget()); // Hide dialog buttons when starting progress asWidget().setFooterPanelVisible(false); } @Override public void stopProgress() { // Set dialog content to the actual popup content widget asWidget().setContent(popupContent); // Show dialog buttons when stopping progress asWidget().setFooterPanelVisible(true); // Update tab index values updateTabIndexes(); // Now that the panel is visible we can try to focus focusInput(); } /** * Hook for setting initial focus when the View becomes visible. * <p> * For example: * * <pre> * userNameWidget.setFocus(true); * </pre> */ @Override public void focusInput() { // No-op, override as necessary } @Override public HasClickHandlers getCloseButton() { return null; } @Override public HasClickHandlers getCloseIconButton() { return asWidget().getCloseIconButton(); } @Override public void setPopupKeyPressHandler(PopupNativeKeyPressHandler handler) { asWidget().setKeyPressHandler(handler); } @Override public void setElementId(String elementId) { this.elementId = elementId; } protected String getHashName() { return hashName; } /** * Hook for assigning tab index to widgets contained in the View. * <p> * For example: * * <pre> * userNameWidget.setTabIndex(nextTabIndex++); * passwordWidget.setTabIndex(nextTabIndex++); * return nextTabIndex; * </pre> * * @param nextTabIndex * Currently available tab index value. * @return Next available tab index value. */ @Override public int setTabIndexes(int nextTabIndex) { // No-op, override as necessary return nextTabIndex; } @Override public void updateTabIndexes() { // Update tab indexes for popup view's content int nextTabIndex = setTabIndexes(1); // Update tab indexes for popup view's footer buttons for (FocusableComponentsContainer button : focusableButtons) { nextTabIndex = button.setTabIndexes(nextTabIndex); } } /** * Hook for initializing the View from given model. * <p> * Called once per model instance, before the initial {@link #edit} * call that fills the View with model's current data. * <p> * This is the right place for any model-specific (one-time) event * handler registration or initialization logic, for example: * * <pre> * model.getFoo().getPropertyChangedEvent().addListener( ... ); * model.getBar().getEntityChangedEvent().addListener( ... ); * </pre> * * @param model * Model instance assigned to the View. */ @Override public void init(T model) { // No-op, override as necessary } }