package org.ovirt.engine.ui.common.presenter;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.GwtEvent.Type;
import com.gwtplatform.mvp.client.ChangeTabHandler;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.PresenterWidget;
import com.gwtplatform.mvp.client.RequestTabsEvent;
import com.gwtplatform.mvp.client.RequestTabsHandler;
import com.gwtplatform.mvp.client.TabContainerPresenter;
import com.gwtplatform.mvp.client.TabPanel;
import com.gwtplatform.mvp.client.TabView;
import com.gwtplatform.mvp.client.proxy.Proxy;
import com.gwtplatform.mvp.client.proxy.RevealContentHandler;
import com.gwtplatform.mvp.client.proxy.TabContentProxy;
/**
* A {@link TabContainerPresenter} that handles tabs added dynamically during runtime.
* <p>
* To add new tab during runtime, create and bind its proxy to listen to GWTP {@link RequestTabsEvent} for the given tab
* container presenter.
*
* @param <V>
* View type.
* @param <P>
* Proxy type.
*/
public abstract class DynamicTabContainerPresenter<V extends TabView & DynamicTabContainerPresenter.DynamicTabPanel, P extends Proxy<?>>
extends TabContainerPresenter<V, P> {
/**
* Tab panel interface used with {@link DynamicTabContainerPresenter}.
*/
public interface DynamicTabPanel extends TabPanel {
/**
* Sets the currently active tab's history token.
*/
void setActiveTabHistoryToken(String historyToken);
}
private static final Logger logger = Logger.getLogger(DynamicTabContainerPresenter.class.getName());
private final Object tabContentSlot;
private final Type<RequestTabsHandler> requestTabsEventType;
public DynamicTabContainerPresenter(EventBus eventBus, V view, P proxy,
Object tabContentSlot,
Type<RequestTabsHandler> requestTabsEventType,
Type<ChangeTabHandler> changeTabEventType,
Type<RevealContentHandler<?>> slot) {
super(eventBus, view, proxy, tabContentSlot,
requestTabsEventType, changeTabEventType, slot);
this.tabContentSlot = tabContentSlot;
this.requestTabsEventType = requestTabsEventType;
}
@Override
// TODO-GWT: override setInSlot to get hold of TabContentProxy in case of Presenter
// When moving to new GWTP slot API, make sure to override setInSlot(IsSlot<T>, T) instead.
// Also, check all overrides of legacy setInSlot(Object, PresenterWidget<?>) as well as other
// deprecated methods and replace them with non-deprecated method overrides.
public void setInSlot(Object slot, PresenterWidget<?> content) {
super.setInSlot(slot, content);
// Update the view with regard to current tab's history token
// in order to retain "active" tab after refreshing all tabs
if (slot == tabContentSlot) {
try {
Presenter<?, ?> presenter = (Presenter<?, ?>) content;
TabContentProxy<?> proxy = (TabContentProxy<?>) presenter.getProxy();
// Following is needed to address a bug in GWTP legacy slot handling.
// https://groups.google.com/forum/#!topic/gwt-platform/eDpwOubUCmE
getView().setActiveTab(proxy.getTab());
// Following is needed to inform the TabPanel about the history token.
getView().setActiveTabHistoryToken(proxy.getTargetHistoryToken());
} catch (Exception e) {
logger.log(Level.SEVERE, "Error while updating tab view", e); //$NON-NLS-1$
}
}
}
@Override
protected void onBind() {
super.onBind();
registerHandler(getEventBus().addHandler(RedrawDynamicTabContainerEvent.getType(),
event -> {
if (requestTabsEventType == event.getRequestTabsEventType()) {
Scheduler.get().scheduleDeferred(() -> {
// Remove all tabs
getView().removeTabs();
// Re-add tabs in response to RequestTabsEvent
RequestTabsEvent.fire(DynamicTabContainerPresenter.this,
requestTabsEventType, DynamicTabContainerPresenter.this);
});
}
}));
}
}