/*
* JBoss, Home of Professional Open Source
* Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.jboss.as.console.client.shared.viewframework;
import com.google.gwt.event.logical.shared.BeforeSelectionEvent;
import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import org.jboss.as.console.client.widgets.forms.AddressBinding;
import org.jboss.as.console.client.widgets.forms.FormMetaData;
import org.jboss.as.console.client.widgets.forms.FormToolStrip;
import org.jboss.as.console.client.widgets.forms.PropertyBinding;
import org.jboss.ballroom.client.widgets.forms.DisclosureGroupRenderer;
import org.jboss.ballroom.client.widgets.forms.EditListener;
import org.jboss.ballroom.client.widgets.forms.Form;
import org.jboss.ballroom.client.widgets.forms.FormAdapter;
import org.jboss.ballroom.client.widgets.forms.FormCallback;
import org.jboss.ballroom.client.widgets.forms.FormItem;
import org.jboss.ballroom.client.widgets.forms.FormValidation;
import org.jboss.ballroom.client.widgets.forms.FormValidator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Makes a Form with items automatically separated onto tabs.
*
* Note that this class doesn't yet support grouped FormItems.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2011 Red Hat Inc.
* @author Heiko Braun
*/
public class TabbedFormLayoutPanel<T> implements FormAdapter<T>, SingleEntityView<T> {
private Class<?> beanType;
private FormMetaData formMetaData;
private String resourceAddress;
private FormItemObserver[] observers;
private Map<String, FormAdapter<T>> forms;
private List<EditListener> listeners = new ArrayList<EditListener>();
private FormAdapter<T> lastFormAdded;
private Map<String,FormToolStrip> tools = new HashMap<String, FormToolStrip>();
private List<String> formItemNames = new ArrayList<String>();
private TabPanel tabPanel;
private EntityToDmrBridge bridge;
private AddressBinding address;
private List<SingleEntityView<T>> additionalViews = Collections.EMPTY_LIST;
private EnumSet<FrameworkButton> hideButtons;
public TabbedFormLayoutPanel(Class<?> beanType, FormMetaData formMetaData, EnumSet<FrameworkButton> hideButtons,
FormItemObserver... observers) {
this(beanType, formMetaData, null, hideButtons, observers);
}
public TabbedFormLayoutPanel(
Class<?> beanType, FormMetaData formMetaData, String resourceAddress,
EnumSet<FrameworkButton> hideButtons,
FormItemObserver... observers)
{
this.beanType = beanType;
this.formMetaData = formMetaData;
this.resourceAddress = resourceAddress;
this.observers = observers;
this.tabPanel = new TabPanel();
this.tabPanel.setStyleName("default-tabpanel");
this.forms = makeForms();
this.hideButtons = hideButtons;
}
@Override
public void addFormValidator(FormValidator formValidator) {
for (FormAdapter<T> form : forms.values()) {
form.addFormValidator(formValidator);
}
}
public Widget asWidget() {
// populate tabs
Set<String> keys = forms.keySet();
for(String key : keys) {
VerticalPanel layout = new VerticalPanel();
layout.setStyleName("fill-layout-width");
final FormAdapter<T> form = forms.get(key);
// toolstrip
final FormToolStrip<T> toolStrip = new FormToolStrip<T>(
form,
new FormToolStrip.FormCallback<T>() {
@Override
public void onSave(Map<String, Object> changeset) {
bridge.onSaveDetails(form.getEditedEntity(), form.getChangedValues());
}
@Override
public void onDelete(T entity) {
bridge.onRemove(entity);
}
}
);
tools.put(key, toolStrip);
// belongs to top level tools
toolStrip.providesDeleteOp(false);
//toolStrip.providesEditSaveOp(!hideButtons.contains(FrameworkButton.EDIT_SAVE));
layout.add(toolStrip.asWidget());
// help widgets
if (address != null) {
layout.add(HelpWidgetFactory.makeHelpWidget(address, form));
}
layout.add(form);
// add to tab panel
tabPanel.add(layout, key);
}
// cancel when switching forms
tabPanel.addBeforeSelectionHandler(new BeforeSelectionHandler<Integer>() {
@Override
public void onBeforeSelection(BeforeSelectionEvent<Integer> event) {
cancel();
}
});
// additional views
for(SingleEntityView tabView : additionalViews)
tabPanel.add(tabView.asWidget(), tabView.getTitle());
tabPanel.selectTab(0);
return tabPanel;
}
@Override
public void updatedEntity(T entity) {
for (FormAdapter<T> form : forms.values()) {
form.edit(entity);
}
}
private Map<String, FormAdapter<T>> makeForms() {
Map<String, FormAdapter<T>> formsMap = new LinkedHashMap<String, FormAdapter<T>>();
for (Map.Entry<String, List<PropertyBinding>> entry : formMetaData.getTabbedAttributes().entrySet())
{
if(!"CUSTOM".equals(entry.getKey())) // handled manually
{
FormAdapter<T> form = makeForm(entry.getValue());
formsMap.put(entry.getKey(), form);
formItemNames.addAll(form.getFormItemNames());
this.lastFormAdded = form;
}
}
return formsMap;
}
private FormAdapter<T> makeForm(List<PropertyBinding> bindings) {
Form<T> form = new Form(beanType, resourceAddress);
if (bindings.size() < 3) {
form.setNumColumns(1);
} else {
form.setNumColumns(2);
}
List<PropertyBinding> baseBindings = formMetaData.getBaseAttributes();
// FormItem[][] items = new FormItem[baseBindings.size()][];
List<FormItem[]> items = new ArrayList<FormItem[]>();
// for (PropertyBinding propBinding : baseBindings) {
for (PropertyBinding propBinding : bindings) {
if (baseBindings.contains(propBinding)) {
items.add(propBinding.getFormItemForEdit(observers));
}
}
form.setFields(items.toArray(new FormItem[items.size()][]));
for (String subgroup : formMetaData.getGroupNames()) {
List<PropertyBinding> groupBindings = formMetaData.getGroupedAttribtes(subgroup);
// FormItem[][] groupItems = new FormItem[groupBindings.size()][];
List<FormItem[]> groupItems = new ArrayList<FormItem[]>();
// for (PropertyBinding propBinding : groupBindings) {
for (PropertyBinding propBinding : bindings) {
if (groupBindings.contains(propBinding)) {
groupItems.add(propBinding.getFormItemForEdit(observers));
}
}
if (groupItems.size() > 0) {
form.setFieldsInGroup(subgroup, new DisclosureGroupRenderer(), groupItems.toArray(new FormItem[groupItems.size()][]));
}
}
return form;
}
@Override
public void editTransient(T newBean) {
for (FormAdapter<T> form : forms.values()) {
form.edit(newBean);
}
for (SingleEntityView<T> subView : additionalViews) {
subView.updatedEntity(newBean);
}
notifyListeners(newBean);
}
@Override
public void edit(T bean) {
for (FormAdapter<T> form : forms.values()) {
form.edit(bean);
}
for (SingleEntityView<T> subView : additionalViews) {
subView.updatedEntity(bean);
}
notifyListeners(bean);
}
protected void notifyListeners(T bean) {
for (EditListener listener : listeners) {
listener.editingBean(bean);
}
}
@Override
public void addEditListener(EditListener listener) {
this.listeners.add(listener);
}
@Override
public void bind(CellTable<T> table) {
for (FormAdapter<T> form : forms.values()) {
form.bind(table);
}
}
@Override
public void cancel() {
Set<String> keys = forms.keySet();
for (String key : keys) {
tools.get(key).doCancel();
}
}
@Override
public Map<String, Object> getChangedValues() {
Map<String, Object> changedValues = new HashMap<String, Object>();
for (FormAdapter<T> form : forms.values()) {
changedValues.putAll(form.getChangedValues());
}
return changedValues;
}
@Override
public Class<?> getConversionType() {
return this.beanType;
}
@Override
public T getEditedEntity() {
return this.lastFormAdded.getEditedEntity();
}
@Override
public List<String> getFormItemNames() {
return this.formItemNames;
}
@Override
public T getUpdatedEntity() {
return this.lastFormAdded.getUpdatedEntity();
}
@Override
public void removeEditListener(EditListener listener) {
this.listeners.remove(listener);
}
@Override
public void setEnabled(boolean isEnabled) {
Set<String> keys = forms.keySet();
for (String key : keys) {
FormAdapter form = forms.get(key);
form.setEnabled(isEnabled);
}
}
@Override
public FormValidation validate() {
FormValidation formValidation = new FormValidation();
for (FormAdapter<T> form : forms.values()) {
FormValidation tabValidation = form.validate();
for (String error : tabValidation.getErrors()) {
formValidation.addError(error);
}
}
return formValidation;
}
public void add(Widget widget, String title) {
tabPanel.add(widget, title);
}
public void setBridge(EntityToDmrBridge bridge) {
this.bridge = bridge;
}
public void setHelpAddress(AddressBinding address) {
this.address = address;
}
@Override
public void clearValues() {
Set<String> keys = forms.keySet();
for (String key : keys) {
FormAdapter form = forms.get(key);
form.clearValues();
}
}
@Override
public String getTitle() {
// no title for composite
return null;
}
public void setAdditionalViews(List<SingleEntityView<T>> additionalViews) {
this.additionalViews = additionalViews;
}
@Override
public String getFormItemTitle(String ref) {
throw new RuntimeException("Not implemented!");
}
@Override
public void setToolsCallback(FormCallback callback) {
// not supported
}
}