package org.ovirt.engine.ui.common.utils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.ovirt.engine.ui.common.presenter.AbstractModelBoundPopupPresenterWidget;
import org.ovirt.engine.ui.common.view.TabbedView;
import org.ovirt.engine.ui.common.widget.dialog.tab.OvirtTabListItem;
import org.ovirt.engine.ui.uicommonweb.models.TabName;
import org.ovirt.engine.ui.uicommonweb.models.ValidationCompleteEvent;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.HandlerRegistration;
/**
* Helper class that does all the calculations and work to determine which tab to switch to if any. The current
* active tab is invalid it won't switch tabs. It also manages the display of an invalid tab.
*/
public final class ValidationTabSwitchHelper {
/**
* Private constructor so you can't instantiate this class.
*/
private ValidationTabSwitchHelper() {
//Don't allow instances.
}
/**
* Register the {@code ValidationCompleteEvent} handler.
* @param eventBus The GWT event bus.
* @param presenterWidget The {@code PresenterWidget} containing the model that was validated.
* @param view The {@code View} to update based on state of the model.
* @return The {@code HandlerRegistration} so the caller can manage the handlers.
*/
public static HandlerRegistration registerValidationHandler(final EventBus eventBus,
final AbstractModelBoundPopupPresenterWidget<?, ?> presenterWidget, final TabbedView view) {
return eventBus.addHandler(ValidationCompleteEvent.getType(),
event -> {
//Make sure the model in the event is the one we are interested in.
if (event.getModel() != null && event.getModel().equals(presenterWidget.getModel())) {
//Get the invalid tab names from the model.
Set<TabName> invalidTabs = presenterWidget.getModel().getInvalidTabs();
//Get the tab names to dialog tab widget map from the view.
Map<TabName, OvirtTabListItem> mapping = view.getTabNameMapping();
markTabs(invalidTabs, mapping);
//Check if the current active tab is invalid, if so don't do anything.
for (TabName invalidTabName: invalidTabs) {
if (view.getTabPanel().getActiveTab().equals(mapping.get(invalidTabName))) {
return;
}
}
//The current tab is not invalid, switch to the top invalid tab.
switchTab(invalidTabs, mapping, view);
}
});
}
/**
* Iterate over the {@code DialogTab}s and mark them valid/invalid based on the passed in
* {@code Set} of invalid tab names.
* @param invalidTabs The set of invalid tab names.
* @param mapping The TabName to DialogTab mapping.
*/
private static void markTabs(Set<TabName> invalidTabs, Map<TabName, OvirtTabListItem> mapping) {
for (Map.Entry<TabName, OvirtTabListItem> entry: mapping.entrySet()) {
if (invalidTabs.contains(entry.getKey())) {
entry.getValue().markAsInvalid(null);
} else {
entry.getValue().markAsValid();
}
}
}
/**
* Switch to the lowest number invalid tab in the {@code TabbedView}. The tabbed view returns an ordered
* list of tabs that we can compare against the invalid tabs passed into this method.
* @param invalidTabs The {@code Set} of invalid tab names.
* @param mapping The TabName to DialogTab mapping.
* @param view The {@code TabbedView} containing the tabs.
*/
private static void switchTab(Set<TabName> invalidTabs, Map<TabName, OvirtTabListItem> mapping, TabbedView view) {
int lowestIndex = Integer.MAX_VALUE;
//Get all the tabs from the view.
List<OvirtTabListItem> allTabs = view.getTabPanel().getTabs();
//For each invalid tab find the index, and the lowest index will be the best fit.
for (TabName invalidTabName: invalidTabs) {
if (allTabs.indexOf(mapping.get(invalidTabName)) < lowestIndex) {
lowestIndex = allTabs.indexOf(mapping.get(invalidTabName));
}
}
if (lowestIndex != Integer.MAX_VALUE) {
view.getTabPanel().switchTab(allTabs.get(lowestIndex));
}
}
}