package org.ovirt.engine.ui.webadmin.section.main.presenter;
import java.util.List;
import org.ovirt.engine.core.compat.Event;
import org.ovirt.engine.core.compat.EventArgs;
import org.ovirt.engine.core.compat.IEventListener;
import org.ovirt.engine.core.compat.PropertyChangedEventArgs;
import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
import org.ovirt.engine.ui.uicommonweb.models.ListWithDetailsModel;
import org.ovirt.engine.ui.webadmin.uicommon.model.CommonModelChangeEvent;
import org.ovirt.engine.ui.webadmin.uicommon.model.DetailModelProvider;
import org.ovirt.engine.ui.webadmin.uicommon.model.SearchableDetailModelProvider;
import org.ovirt.engine.ui.webadmin.widget.table.OrderedMultiSelectionModel;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.cellview.client.LoadingStateChangeEvent.LoadingState;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ProxyEvent;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
/**
* Base class for sub tab presenters.
*
* @param <T>
* Main tab table row data type.
* @param <M>
* Main model type.
* @param <D>
* Detail model type.
* @param <V>
* View type.
* @param <P>
* Proxy type.
*/
public abstract class AbstractSubTabPresenter<T, M extends ListWithDetailsModel, D extends EntityModel, V extends AbstractSubTabPresenter.ViewDef<T>, P extends ProxyPlace<?>>
extends Presenter<V, P> {
public interface ViewDef<T> extends View {
/**
* Notifies the view that the main tab table selection has changed.
*/
void setMainTabSelectedItem(T selectedItem);
/**
* For table-based sub tab views, returns the selection model used by the sub tab table widget. Returns
* {@code null} otherwise.
*/
OrderedMultiSelectionModel<?> getTableSelectionModel();
void setLoadingState(LoadingState state);
}
private final PlaceManager placeManager;
private final DetailModelProvider<M, D> modelProvider;
private List<T> mainTabSelectedItems;
public AbstractSubTabPresenter(EventBus eventBus, V view, P proxy,
PlaceManager placeManager, DetailModelProvider<M, D> modelProvider) {
super(eventBus, view, proxy);
this.placeManager = placeManager;
this.modelProvider = modelProvider;
}
@Override
public boolean useManualReveal() {
return true;
}
@Override
protected void onBind() {
super.onBind();
OrderedMultiSelectionModel<?> tableSelectionModel = getView().getTableSelectionModel();
if (tableSelectionModel != null) {
registerHandler(tableSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
// Update detail model selection
updateDetailModelSelection();
}
}));
}
}
@Override
protected void onReveal() {
super.onReveal();
// Notify model provider that the tab has been revealed
modelProvider.onSubTabSelected();
}
@Override
protected void onReset() {
super.onReset();
// Clear table selection before starting
clearSelection();
}
/**
* Update the detail model selection with currently selected items in the table.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private void updateDetailModelSelection() {
if (modelProvider instanceof SearchableDetailModelProvider) {
((SearchableDetailModelProvider) modelProvider).setSelectedItems(getSelectedItems());
}
}
@Override
public void prepareFromRequest(PlaceRequest request) {
super.prepareFromRequest(request);
// Reveal presenter only when there is something selected in the main tab table
if (hasMainTabSelection()) {
getProxy().manualReveal(this);
} else {
getProxy().manualRevealFailed();
placeManager.revealPlace(getMainTabRequest());
}
}
boolean hasMainTabSelection() {
return mainTabSelectedItems != null && !mainTabSelectedItems.isEmpty();
}
T getMainTabSelectedItem() {
return hasMainTabSelection() ? mainTabSelectedItems.get(0) : null;
}
/**
* Notifies this sub tab presenter that the main tab table selection has changed.
*/
protected void updateMainTabSelection(List<T> mainTabSelectedItems) {
this.mainTabSelectedItems = mainTabSelectedItems;
T firstSelectedItem = getMainTabSelectedItem();
// Notify view of selection change
if (firstSelectedItem != null) {
getView().setMainTabSelectedItem(firstSelectedItem);
}
}
/**
* Returns the place request associated with the main tab presenter for this sub tab.
* <p>
* Will be revealed when the user tries to navigate to this sub tab while there is nothing selected in the main tab
* table.
*/
protected abstract PlaceRequest getMainTabRequest();
/**
* Returns {@code true} when the view exposes a table selection model.
*/
boolean hasTableSelectionModel() {
return getView().getTableSelectionModel() != null;
}
/**
* Returns items currently selected in the table.
*/
protected List<?> getSelectedItems() {
return hasTableSelectionModel() ? getView().getTableSelectionModel().getSelectedList() : null;
}
/**
* Deselects any selected values in the table.
*/
protected void clearSelection() {
if (hasTableSelectionModel()) {
getView().getTableSelectionModel().clear();
}
}
@ProxyEvent
public void onCommonModelChange(CommonModelChangeEvent event) {
modelProvider.getModel().getEntityChangedEvent().addListener(new IEventListener() {
@SuppressWarnings("unchecked")
@Override
public void eventRaised(Event ev, Object sender, EventArgs args) {
Object entity = modelProvider.getModel().getEntity();
if (entity != null) {
getView().setMainTabSelectedItem((T) entity);
}
}
});
modelProvider.getModel().getPropertyChangedEvent().addListener(new IEventListener() {
@Override
public void eventRaised(Event ev, Object sender, EventArgs args) {
PropertyChangedEventArgs pcArgs = (PropertyChangedEventArgs) args;
if ("Progress".equals(pcArgs.PropertyName)) {
if (modelProvider.getModel().getProgress() != null) {
getView().setLoadingState(LoadingState.LOADING);
}
}
}
});
}
}