/*******************************************************************************
* Copyright (c) 2007, 2014 compeople AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* compeople AG - initial API and implementation
*******************************************************************************/
package org.eclipse.riena.example.client.controllers;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.databinding.beans.PojoObservables;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.validation.IValidator;
import org.eclipse.riena.core.marker.IMarker;
import org.eclipse.riena.internal.navigation.ui.filter.UIFilterRuleRidgetDisabledMarker;
import org.eclipse.riena.internal.navigation.ui.filter.UIFilterRuleRidgetHiddenMarker;
import org.eclipse.riena.internal.navigation.ui.filter.UIFilterRuleRidgetMandatoryMarker;
import org.eclipse.riena.internal.navigation.ui.filter.UIFilterRuleRidgetOutputMarker;
import org.eclipse.riena.internal.navigation.ui.filter.UIFilterRuleRidgetValidator;
import org.eclipse.riena.navigation.IApplicationNode;
import org.eclipse.riena.navigation.INavigationNode;
import org.eclipse.riena.navigation.ISubModuleNode;
import org.eclipse.riena.navigation.NavigationNodeUtility;
import org.eclipse.riena.navigation.ui.controllers.SubModuleController;
import org.eclipse.riena.ui.core.marker.DisabledMarker;
import org.eclipse.riena.ui.core.marker.ErrorMarker;
import org.eclipse.riena.ui.core.marker.HiddenMarker;
import org.eclipse.riena.ui.core.marker.MandatoryMarker;
import org.eclipse.riena.ui.core.marker.OutputMarker;
import org.eclipse.riena.ui.core.marker.ValidationTime;
import org.eclipse.riena.ui.filter.IUIFilter;
import org.eclipse.riena.ui.filter.IUIFilterRule;
import org.eclipse.riena.ui.filter.impl.UIFilter;
import org.eclipse.riena.ui.ridgets.IActionListener;
import org.eclipse.riena.ui.ridgets.IActionRidget;
import org.eclipse.riena.ui.ridgets.IBasicMarkableRidget;
import org.eclipse.riena.ui.ridgets.IComboRidget;
import org.eclipse.riena.ui.ridgets.IRidget;
import org.eclipse.riena.ui.ridgets.ISingleChoiceRidget;
import org.eclipse.riena.ui.ridgets.ITextRidget;
import org.eclipse.riena.ui.ridgets.validation.MaxLength;
import org.eclipse.riena.ui.ridgets.validation.MinLength;
import org.eclipse.riena.ui.ridgets.validation.ValidEmailAddress;
/**
* Controller of the sub module that demonstrates UI filters for ridgets.
*/
public class FilterSubModuleController extends SubModuleController {
private IComboRidget filterTypeValues;
private IComboRidget globalFilterTypeValues;
private FilterModel filterModel;
private FilterModel globalFilterModel;
private MarkerModel markerModel;
private IActionRidget addFilter;
private IActionRidget globalAddFilter;
private IActionRidget addMarker;
private IActionRidget removeMarker;
private final IMarker[] markers = new IMarker[] { new ErrorMarker(), new MandatoryMarker(), new HiddenMarker(),
new OutputMarker(), new DisabledMarker() };
/**
* Enumeration of different kind of UI filters.
*/
private enum FilterType {
MARKER("Marker", new MandatoryMarker(), new HiddenMarker(), new OutputMarker(), new DisabledMarker()), //$NON-NLS-1$
VALIDATOR("Validator", new MinLength(3), new MaxLength(10), new ValidEmailAddress()); //$NON-NLS-1$
private final String text;
private final Object[] args;
private FilterType(final String text, final Object... args) {
this.text = text;
this.args = args;
}
@Override
public String toString() {
return text;
}
public Object[] getArgs() {
return args;
}
}
@Override
public void afterBind() {
super.afterBind();
initMarkerGroup();
initLocalFilterGroup();
initGlobalFilterGroup();
rebindFilterTypeValues(filterModel, filterTypeValues, addFilter);
rebindFilterTypeValues(globalFilterModel, globalFilterTypeValues, globalAddFilter);
}
/**
* Initializes the ridgets of the marker group.
*/
private void initMarkerGroup() {
final IComboRidget ridgetToMarkID = getRidget("ridgetToMarkID"); //$NON-NLS-1$
markerModel = new MarkerModel();
ridgetToMarkID.bindToModel(markerModel, "ids", MarkerModel.class, null, markerModel, "selectedId"); //$NON-NLS-1$ //$NON-NLS-2$
ridgetToMarkID.updateFromModel();
final IComboRidget markersCombo = getRidget("markers"); //$NON-NLS-1$
markersCombo.bindToModel(markerModel, "markers", MarkerModel.class, null, markerModel, "selectedMarker"); //$NON-NLS-1$ //$NON-NLS-2$
markersCombo.updateFromModel();
addMarker = getRidget("addMarker"); //$NON-NLS-1$
addMarker.addListener(new IActionListener() {
public void callback() {
doAddMarker();
}
});
removeMarker = getRidget("removeMarker"); //$NON-NLS-1$
removeMarker.addListener(new IActionListener() {
public void callback() {
doRemoveMarker();
}
});
}
/**
* Initializes the ridgets for adding <i>local</i> UI filters.
*/
private void initLocalFilterGroup() {
final IComboRidget ridgetID = getRidget("ridgetID"); //$NON-NLS-1$
filterModel = new FilterModel();
ridgetID.bindToModel(filterModel, "ids", FilterModel.class, null, filterModel, "selectedId"); //$NON-NLS-1$ //$NON-NLS-2$
ridgetID.updateFromModel();
final ISingleChoiceRidget filterType = getRidget("filterType"); //$NON-NLS-1$
filterType.addPropertyChangeListener(new FilterTypeChangeListener());
filterType.bindToModel(filterModel, "types", filterModel, "selectedType"); //$NON-NLS-1$ //$NON-NLS-2$
filterType.updateFromModel();
filterTypeValues = getRidget("filterTypeValues"); //$NON-NLS-1$
filterTypeValues.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(final PropertyChangeEvent evt) {
if (addFilter != null) {
addFilter.setEnabled(evt.getNewValue() != null);
}
}
});
addFilter = getRidget("addFilter"); //$NON-NLS-1$
addFilter.addListener(new IActionListener() {
public void callback() {
doAddFilter();
}
});
final IActionRidget removeFilters = getRidget("removeFilters"); //$NON-NLS-1$
removeFilters.addListener(new IActionListener() {
public void callback() {
doRemoveFilters();
}
});
}
/**
* Initializes the ridgets for adding <i>local</i> UI filters.
*/
private void initGlobalFilterGroup() {
final ITextRidget ridgetID = getRidget("globalRidgetID"); //$NON-NLS-1$
globalFilterModel = new FilterModel();
ridgetID.bindToModel(globalFilterModel, "selectedId"); //$NON-NLS-1$
ridgetID.updateFromModel();
final ISingleChoiceRidget filterType = getRidget("globalFilterType"); //$NON-NLS-1$
filterType.addPropertyChangeListener(new FilterTypeChangeListener());
filterType.bindToModel(globalFilterModel, "types", globalFilterModel, "selectedType"); //$NON-NLS-1$ //$NON-NLS-2$
filterType.updateFromModel();
globalFilterTypeValues = getRidget("globalFilterTypeValues"); //$NON-NLS-1$
globalFilterTypeValues.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(final PropertyChangeEvent evt) {
if (globalAddFilter != null) {
globalAddFilter.setEnabled(evt.getNewValue() != null);
}
}
});
globalAddFilter = getRidget("globalAddFilter"); //$NON-NLS-1$
globalAddFilter.addListener(new IActionListener() {
public void callback() {
doGlobalAddFilter();
}
});
final IActionRidget removeFilters = getRidget("globalRemoveFilters"); //$NON-NLS-1$
removeFilters.addListener(new IActionListener() {
public void callback() {
doGlobalRemoveFilters();
}
});
}
/**
* Adds a filter to the node of this sub module.
*/
private void doAddFilter() {
final Collection<IUIFilterRule> attributes = new ArrayList<IUIFilterRule>(1);
attributes.add(createFilterRule(filterModel, true));
final IUIFilter filter = new UIFilter(attributes);
getNavigationNode().addFilter(filter);
}
/**
* Adds a filter to the node of the application.
*/
private void doGlobalAddFilter() {
final Collection<IUIFilterRule> attributes = new ArrayList<IUIFilterRule>(1);
attributes.add(createFilterRule(globalFilterModel, false));
final IUIFilter filter = new UIFilter(attributes);
final IApplicationNode applNode = getNavigationNode().getParentOfType(IApplicationNode.class);
applNode.addFilter(filter);
}
/**
* Creates a filter rule for a ridget, dependent on the selected type of
* filter.
*
* @param model
* model with selections.
* @return filter rule
*/
private IUIFilterRule createFilterRule(final FilterModel model, final boolean local) {
IUIFilterRule attribute = null;
String id = model.getSelectedId();
if (local) {
final INavigationNode<ISubModuleNode> node = getNavigationNode();
id = NavigationNodeUtility.getNodeLongId(node) + "/" + id; //$NON-NLS-1$
} else {
id = "*/" + id; //$NON-NLS-1$
}
final Object filterValue = model.getSelectedFilterTypeValue();
final FilterType type = model.getSelectedType();
if (type == FilterType.MARKER) {
if (filterValue instanceof OutputMarker) {
attribute = new UIFilterRuleRidgetOutputMarker(id);
} else if (filterValue instanceof DisabledMarker) {
attribute = new UIFilterRuleRidgetDisabledMarker(id);
} else if (filterValue instanceof MandatoryMarker) {
attribute = new UIFilterRuleRidgetMandatoryMarker(id);
} else if (filterValue instanceof HiddenMarker) {
attribute = new UIFilterRuleRidgetHiddenMarker(id);
}
} else if (type == FilterType.VALIDATOR) {
if (filterValue instanceof IValidator) {
attribute = new UIFilterRuleRidgetValidator(id, (IValidator) filterValue,
ValidationTime.ON_UI_CONTROL_EDIT);
}
}
return attribute;
}
/**
* Removes all filters form the node of this sub module.
*/
private void doRemoveFilters() {
getNavigationNode().removeAllFilters();
}
/**
* Removes all filters form the node of application.
*/
private void doGlobalRemoveFilters() {
final IApplicationNode applNode = getNavigationNode().getParentOfType(IApplicationNode.class);
applNode.removeAllFilters();
}
/**
* The combo box for filter values is update with the given model. Also the
* add button is enabled or disabled.
*
* @param model
* @param typeValues
* combo box
* @param add
* add button
*/
private void rebindFilterTypeValues(final FilterModel model, final IComboRidget typeValues, final IActionRidget add) {
if (model == null) {
return;
}
model.setSelectedFilterTypeValue(null);
if (typeValues != null) {
typeValues.bindToModel(new WritableList(Arrays.asList(model.getSelectedType().getArgs()), Object.class),
FilterModel.class, null, PojoObservables.observeValue(model, "selectedFilterTypeValue")); //$NON-NLS-1$
typeValues.updateFromModel();
}
if (add != null) {
add.setEnabled(model.getSelectedFilterTypeValue() != null);
}
}
/**
* Adds a marker to a ridget.
*/
private void doAddMarker() {
if (markerModel.getSelectedId() != null) {
final IBasicMarkableRidget ridget = getRidget(markerModel.getSelectedId());
ridget.addMarker(markerModel.getSelectedMarker().getMarker());
}
}
/**
* Removes a marker to a ridget.
*/
private void doRemoveMarker() {
if (markerModel.getSelectedId() != null) {
final IBasicMarkableRidget ridget = getRidget(markerModel.getSelectedId());
ridget.removeMarker(markerModel.getSelectedMarker().getMarker());
}
}
/**
* After changing the type the combo boxes with the values must be updated.
*/
private class FilterTypeChangeListener implements PropertyChangeListener {
public void propertyChange(final PropertyChangeEvent evt) {
rebindFilterTypeValues(filterModel, filterTypeValues, addFilter);
rebindFilterTypeValues(globalFilterModel, globalFilterTypeValues, globalAddFilter);
}
}
/**
* Model this the ID of the ridgets of the UI control group.
*/
private abstract class AbstractModel {
private List<String> ids;
private String selectedId;
public List<String> getIds() {
if (ids == null) {
ids = new ArrayList<String>();
final Collection<? extends IRidget> ridgets = getRidgets();
for (final IRidget ridget : ridgets) {
if ((ridget.getID() != null) && (ridget.getID().startsWith("ui_"))) { //$NON-NLS-1$
ids.add(ridget.getID());
}
}
}
return ids;
}
@SuppressWarnings("unused")
public void setSelectedId(final String selectedId) {
this.selectedId = selectedId;
}
public String getSelectedId() {
if (selectedId == null) {
selectedId = getIds().get(0);
}
return selectedId;
}
}
/**
* Model with markers of the marker group.
*/
private class MarkerModel extends AbstractModel {
private MarkerWrapper selectedMarker;
private List<MarkerWrapper> markerWrappers;
public void setSelectedMarker(final MarkerWrapper selectedMarker) {
this.selectedMarker = selectedMarker;
}
public MarkerWrapper getSelectedMarker() {
return selectedMarker;
}
@SuppressWarnings("unused")
public List<MarkerWrapper> getMarkers() {
if (markerWrappers == null) {
markerWrappers = new ArrayList<MarkerWrapper>(markers.length);
for (final IMarker marker : markers) {
markerWrappers.add(new MarkerWrapper(marker));
}
setSelectedMarker(markerWrappers.get(0));
}
return markerWrappers;
}
}
/**
* Model with the filter types and value of the filter groups.
*/
private class FilterModel extends AbstractModel {
private List<FilterType> types;
private FilterType selectedType;
private Object selectedFilterTypeValue;
public List<FilterType> getTypes() {
if (types == null) {
types = new ArrayList<FilterType>();
types.add(FilterType.MARKER);
types.add(FilterType.VALIDATOR);
}
return types;
}
@SuppressWarnings("unused")
public void setSelectedType(final FilterType selectedType) {
this.selectedType = selectedType;
}
public FilterType getSelectedType() {
if (selectedType == null) {
selectedType = getTypes().get(0);
}
return selectedType;
}
public void setSelectedFilterTypeValue(final Object selectedFilterTypeValue) {
this.selectedFilterTypeValue = selectedFilterTypeValue;
}
public Object getSelectedFilterTypeValue() {
return selectedFilterTypeValue;
}
}
/**
* Wrapper for IMarker with an own {@code toString()} method.
*/
private static class MarkerWrapper {
private final IMarker marker;
public MarkerWrapper(final IMarker marker) {
this.marker = marker;
}
public IMarker getMarker() {
return marker;
}
@Override
public String toString() {
if (getMarker() == null) {
return ""; //$NON-NLS-1$
}
return getMarker().getClass().getSimpleName();
}
}
}