| /** |
| * |
| * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * 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: |
| * Florian Pirchner - Initial implementation |
| * |
| */ |
| package org.eclipse.osbp.ecview.extension.grid.presentation; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.databinding.Binding; |
| import org.eclipse.core.databinding.observable.IObservable; |
| import org.eclipse.core.databinding.observable.list.IObservableList; |
| import org.eclipse.core.databinding.observable.value.IObservableValue; |
| import org.eclipse.core.databinding.observable.value.WritableValue; |
| import org.eclipse.emf.databinding.EMFObservables; |
| import org.eclipse.emf.databinding.EMFProperties; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart; |
| import org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart; |
| import org.eclipse.osbp.ecview.core.common.editpart.IFieldEditpart; |
| import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint; |
| import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableCollectionEndpoint; |
| import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableMultiSelectionEndpoint; |
| import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableSelectionEndpoint; |
| import org.eclipse.osbp.ecview.core.common.model.core.YField; |
| import org.eclipse.osbp.ecview.core.databinding.emf.model.ECViewModelBindable; |
| import org.eclipse.osbp.ecview.core.extension.model.extension.YSearchField; |
| import org.eclipse.osbp.ecview.core.extension.model.extension.YSelectionType; |
| import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.ISearchFieldEditpart; |
| import org.eclipse.osbp.ecview.core.util.emf.ModelUtil; |
| import org.eclipse.osbp.ecview.extension.grid.CxGrid; |
| import org.eclipse.osbp.ecview.extension.grid.CxGridCellStyleGenerator; |
| import org.eclipse.osbp.ecview.extension.grid.CxGridColumn; |
| import org.eclipse.osbp.ecview.extension.grid.CxGridFactory; |
| import org.eclipse.osbp.ecview.extension.grid.CxGridFooterRow; |
| import org.eclipse.osbp.ecview.extension.grid.CxGridGroupable; |
| import org.eclipse.osbp.ecview.extension.grid.CxGridGroupedCell; |
| import org.eclipse.osbp.ecview.extension.grid.CxGridHeaderRow; |
| import org.eclipse.osbp.ecview.extension.grid.CxGridMetaCell; |
| import org.eclipse.osbp.ecview.extension.grid.CxGridPackage; |
| import org.eclipse.osbp.ecview.extension.grid.CxGridSortable; |
| import org.eclipse.osbp.ecview.extension.grid.editparts.IGridCellStyleGeneratorEditpart; |
| import org.eclipse.osbp.ecview.extension.grid.editparts.IGridColumnEditpart; |
| import org.eclipse.osbp.ecview.extension.grid.editparts.IGridEditpart; |
| import org.eclipse.osbp.ecview.extension.grid.editparts.presentation.IGridPresentation; |
| import org.eclipse.osbp.ecview.extension.grid.memento.CxGridMemento; |
| import org.eclipse.osbp.ecview.extension.grid.memento.CxGridMementoColumn; |
| import org.eclipse.osbp.ecview.extension.grid.memento.CxGridMementoFactory; |
| import org.eclipse.osbp.ecview.extension.grid.memento.CxGridMementoSortable; |
| import org.eclipse.osbp.runtime.common.annotations.DtoUtils; |
| import org.eclipse.osbp.runtime.common.dispose.AbstractDisposable; |
| import org.eclipse.osbp.runtime.common.i18n.II18nService; |
| import org.eclipse.osbp.runtime.common.state.ISharedStateContext; |
| import org.eclipse.osbp.runtime.designer.api.IDesignerService.IDesignListener; |
| import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IBindingManager; |
| import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractEmbeddedWidgetPresenter; |
| import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util; |
| import org.eclipse.osbp.runtime.web.vaadin.common.data.BeanServiceLazyLoadingContainer; |
| import org.eclipse.osbp.runtime.web.vaadin.common.data.DeepResolvingBeanItemContainer; |
| import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchService; |
| import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchServiceFactory; |
| import org.eclipse.osbp.runtime.web.vaadin.common.data.INestedPropertyAble; |
| import org.eclipse.osbp.runtime.web.vaadin.components.fields.search.ISearchField; |
| import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinProperties; |
| import org.eclipse.osbp.runtime.web.vaadin.databinding.values.IVaadinObservableList; |
| import org.eclipse.osbp.runtime.web.vaadin.databinding.values.IVaadinObservableValue; |
| import org.eclipse.osbp.runtime.web.vaadin.databinding.values.SetToListAdapter; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.vaadin.data.Container; |
| import com.vaadin.data.fieldgroup.FieldGroup; |
| import com.vaadin.data.fieldgroup.FieldGroup.CommitEvent; |
| import com.vaadin.data.fieldgroup.FieldGroup.CommitException; |
| import com.vaadin.data.sort.Sort; |
| import com.vaadin.data.sort.SortOrder; |
| import com.vaadin.data.util.IndexedContainer; |
| import com.vaadin.data.util.converter.Converter; |
| import com.vaadin.data.util.filter.And; |
| import com.vaadin.data.util.filter.Compare; |
| import com.vaadin.event.SortEvent; |
| import com.vaadin.shared.data.sort.SortDirection; |
| import com.vaadin.ui.Component; |
| import com.vaadin.ui.Field; |
| import com.vaadin.ui.Grid; |
| import com.vaadin.ui.Grid.ColumnVisibilityChangeEvent; |
| import com.vaadin.ui.Grid.FooterRow; |
| import com.vaadin.ui.Grid.HeaderRow; |
| import com.vaadin.ui.renderers.Renderer; |
| |
| /** |
| * This presenter is responsible to render a text field on the given layout. |
| */ |
| public class GridPresentation extends AbstractEmbeddedWidgetPresenter<Grid> |
| implements IGridPresentation<Grid>, IDesignListener{ |
| |
| /** The Constant LOGGER. */ |
| private static final Logger LOGGER = LoggerFactory |
| .getLogger(GridPresentation.class); |
| |
| /** The grid. */ |
| private Grid grid; |
| |
| /** The model access. */ |
| private ModelAccess modelAccess; |
| |
| /** The user changed handler. */ |
| private UserChangedHandler userChangedHandler = new UserChangedHandler(); |
| |
| /** The create columns. */ |
| private boolean createColumns; |
| |
| /** The columns. */ |
| private Set<ColumnWrapper> columns = new HashSet<>(); |
| |
| /** The grouping headers. */ |
| private Map<CxGridHeaderRow, HeaderRow> groupingHeaders = new HashMap<CxGridHeaderRow, HeaderRow>(); |
| |
| /** The grouping footers. */ |
| private Map<CxGridFooterRow, FooterRow> groupingFooters = new HashMap<CxGridFooterRow, FooterRow>(); |
| |
| /** The filtering header. */ |
| private HeaderRow filteringHeader; |
| |
| /** The filtering header fields. */ |
| private Map<CxGridColumn, ISearchFieldEditpart> filteringHeaderFields = new HashMap<CxGridColumn, ISearchFieldEditpart>(); |
| |
| /** The selection binding. */ |
| private Binding selectionBinding; |
| |
| /** The filter changed tracker. */ |
| // to handle changed filters |
| private WritableValue filterChangedTracker; |
| |
| /** The current memento. */ |
| private CxGridMemento currentMemento; |
| |
| /** The cell filters. */ |
| private GridCellFilter cellFilters; |
| |
| /** |
| * The constructor. |
| * |
| * @param editpart |
| * The editpart of that editpart. |
| */ |
| public GridPresentation(IElementEditpart editpart) { |
| super((IGridEditpart) editpart); |
| this.modelAccess = new ModelAccess((CxGrid) editpart.getModel()); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale) |
| */ |
| @Override |
| protected void doUpdateLocale(Locale locale) { |
| // no need to set the locale to the ui elements. Is handled by vaadin |
| // internally. |
| |
| // update the captions |
| applyCaptions(); |
| } |
| |
| /** |
| * Applies the labels to the widgets. |
| */ |
| protected void applyCaptions() { |
| |
| // applies the column properties |
| if (createColumns) { |
| createColumns(); |
| } |
| |
| Util.applyCaptions(getI18nService(), modelAccess.getLabel(), |
| modelAccess.getLabelI18nKey(), getLocale(), grid); |
| |
| grid.setEditorCancelCaption(Util.getCaption(getI18nService(), "Cancel", |
| modelAccess.yField.getEditorCancelI18nLabelKey(), getLocale())); |
| grid.setEditorSaveCaption(Util.getCaption(getI18nService(), "Save", |
| modelAccess.yField.getEditorSaveI18nLabelKey(), getLocale())); |
| |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ecview.extension.grid.editparts.presentation.IGridPresentation#setFilter(java.util.Map) |
| */ |
| @Override |
| public void setFilter(Map<String, Object> filter) { |
| List<Container.Filter> filters = new ArrayList<>(); |
| for (Map.Entry<String, Object> entry : filter.entrySet()) { |
| filters.add(new Compare.Equal(entry.getKey(), entry.getValue())); |
| } |
| |
| Container.Filterable filterable = (Container.Filterable) grid |
| .getContainerDataSource(); |
| filterable.removeAllContainerFilters(); |
| filterable.addContainerFilter(new And(filters |
| .toArray(new Container.Filter[filters.size()]))); |
| } |
| |
| /** |
| * Applies the column setting to the grid. |
| */ |
| protected void createColumns() { |
| |
| resetHeader(); |
| resetFooter(); |
| |
| // reset the column reference in the editparts |
| for (CxGridColumn cxColumn : modelAccess.yField.getColumns()) { |
| IGridColumnEditpart editpart = ModelUtil.getEditpart( |
| getViewContext(), cxColumn); |
| editpart.setColumnReference(null); |
| } |
| |
| // set the visible columns and icons |
| List<String> visibleColumns = new ArrayList<String>(); |
| Collection<?> propertyIds = grid.getContainerDataSource() |
| .getContainerPropertyIds(); |
| for (CxGridColumn cxColumn : modelAccess.yField.getColumns()) { |
| if (!cxColumn.isHidden() |
| && (propertyIds.contains(cxColumn.getPropertyPath()) || isNestedColumn(cxColumn))) { |
| visibleColumns.add(cxColumn.getPropertyPath()); |
| cxColumn.setLabelI18nKey(cxColumn.getPropertyPath()); |
| } |
| } |
| |
| if (visibleColumns.size() > 0) { |
| // reset all columns |
| grid.removeAllColumns(); |
| } |
| |
| // add nested properties |
| if (grid.getContainerDataSource() instanceof INestedPropertyAble) { |
| INestedPropertyAble<?> container = (INestedPropertyAble<?>) grid |
| .getContainerDataSource(); |
| for (String property : visibleColumns) { |
| if (property.contains(".")) { |
| container.addNestedContainerProperty(property); |
| } |
| } |
| } |
| |
| if (visibleColumns.size() > 0) { |
| // create the columns based on the model |
| // |
| grid.setColumns(visibleColumns.toArray(new Object[visibleColumns |
| .size()])); |
| grid.setColumnOrder(visibleColumns |
| .toArray(new Object[visibleColumns.size()])); |
| |
| // traverse the columns again and set other properties |
| for (CxGridColumn cxColumn : modelAccess.yField.getColumns()) { |
| if (!cxColumn.isHidden() |
| && (propertyIds.contains(cxColumn.getPropertyPath()) || isNestedColumn(cxColumn))) { |
| String columnId = cxColumn.getPropertyPath(); |
| |
| IGridColumnEditpart editpart = ModelUtil.getEditpart( |
| getViewContext(), cxColumn); |
| Grid.Column column = grid.getColumn(columnId); |
| |
| editpart.setColumnReference(new ColumnWrapper(cxColumn, |
| column)); |
| editpart.initializeColumn(); |
| } |
| } |
| } |
| |
| updateCellStyleGenerator(); |
| createHeaderMetaCells(); |
| createFilteringHeader(); |
| createFooterMetaCells(); |
| createSortOrder(); |
| } |
| |
| /** |
| * Creates the sort order. |
| */ |
| protected void createSortOrder() { |
| CxGrid cxGrid = modelAccess.yField; |
| |
| if (cxGrid.getSortOrder().size() > 0) { |
| Sort sort = null; |
| for (CxGridSortable memSort : cxGrid.getSortOrder()) { |
| if (sort == null) { |
| sort = Sort.by(memSort.getColumn().getPropertyId(), |
| toDirection(memSort)); |
| } else { |
| sort = sort.then(memSort.getColumn().getPropertyId(), |
| toDirection(memSort)); |
| } |
| } |
| grid.sort(sort); |
| } |
| } |
| |
| /** |
| * Creates the header meta cells. |
| */ |
| protected void createHeaderMetaCells() { |
| |
| resetHeader(); |
| |
| // create the new header |
| CxGrid cxGrid = modelAccess.yField; |
| |
| for (CxGridHeaderRow cxHeader : cxGrid.getHeaders()) { |
| HeaderRow headerRow = grid.prependHeaderRow(); |
| groupingHeaders.put(cxHeader, headerRow); |
| |
| // create the grouping headers |
| // |
| for (CxGridGroupedCell groupingColumn : cxHeader.getGroupings()) { |
| List<Grid.HeaderCell> headerCells = getCells(headerRow, |
| groupingColumn); |
| Grid.HeaderCell cell = headerRow.join(headerCells |
| .toArray(new Grid.HeaderCell[headerCells.size()])); |
| |
| // apply the caption of the cell |
| String caption = Util.getCaption(getI18nService(), |
| groupingColumn.getLabel(), |
| groupingColumn.getLabelI18nKey(), getLocale()); |
| |
| if (groupingColumn.isUseHTML()) { |
| cell.setHtml(caption); |
| } else { |
| cell.setText(caption); |
| } |
| } |
| |
| // create the custom cells |
| // |
| for (CxGridMetaCell cxCell : cxHeader.getCustomCells()) { |
| Grid.HeaderCell cell = headerRow.getCell(cxCell.getTarget() |
| .getPropertyId()); |
| if (cell == null) { |
| continue; |
| } |
| |
| if (cxCell.getElement() != null) { |
| IEmbeddableEditpart ep = ModelUtil.getEditpart( |
| getViewContext(), cxCell.getElement()); |
| if (ep != null) { |
| Component component = (Component) ep.render(null); |
| cell.setComponent(component); |
| } |
| } else { |
| String caption = Util.getCaption(getI18nService(), |
| cxCell.getLabel(), cxCell.getLabelI18nKey(), |
| getLocale()); |
| if (cxCell.isUseHTML()) { |
| cell.setHtml(caption); |
| } else { |
| cell.setText(caption); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Reset header. |
| */ |
| protected void resetHeader() { |
| // reset the old header |
| for (HeaderRow header : groupingHeaders.values()) { |
| grid.removeHeaderRow(header); |
| } |
| groupingHeaders.clear(); |
| |
| // dispose the cell component field |
| // |
| for (CxGridHeaderRow cxHeader : modelAccess.yField.getHeaders()) { |
| for (CxGridMetaCell cxCell : cxHeader.getCustomCells()) { |
| if (cxCell.getElement() != null) { |
| IEmbeddableEditpart ep = ModelUtil.findEditpart(cxCell |
| .getElement()); |
| if (ep != null && !ep.isDisposed()) { |
| ep.requestDispose(); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Reset filter. |
| */ |
| protected void resetFilter() { |
| // dispose all the rendered search fields |
| for (ISearchFieldEditpart ep : filteringHeaderFields.values()) { |
| ep.dispose(); |
| } |
| filteringHeaderFields.clear(); |
| |
| if (cellFilters != null) { |
| cellFilters.destroy(); |
| cellFilters = null; |
| } else { |
| // reset the old header |
| if (filteringHeader != null) { |
| grid.removeHeaderRow(filteringHeader); |
| } |
| } |
| |
| filteringHeader = null; |
| } |
| |
| /** |
| * Creates the filtering header. |
| */ |
| protected void createFilteringHeader() { |
| |
| resetFilter(); |
| |
| CxGrid cxGrid = modelAccess.yField; |
| if (!cxGrid.isFilteringVisible()) { |
| return; |
| } |
| |
| if (cxGrid.isCustomFilters()) { |
| createCustomFilters(cxGrid); |
| } else { |
| createAutoFilters(); |
| } |
| } |
| |
| /** |
| * Creates the auto filters. |
| */ |
| protected void createAutoFilters() { |
| cellFilters = new GridCellFilter(grid); |
| Container.Filterable container = (Container.Filterable) grid |
| .getContainerDataSource(); |
| for (Grid.Column column : grid.getColumns()) { |
| Class<?> propertyType = container.getType(column.getPropertyId()); |
| if (Number.class.isAssignableFrom(propertyType) |
| || isPrimitiveNumber(propertyType)) { |
| cellFilters.setNumberFilter(column.getPropertyId()); |
| } else if (propertyType == String.class) { |
| cellFilters.setTextFilter(column.getPropertyId(), true, false); |
| } else if (propertyType == Date.class) { |
| cellFilters.setDateFilter(column.getPropertyId()); |
| } else if (propertyType == Boolean.class |
| || propertyType == Boolean.TYPE) { |
| cellFilters.setBooleanFilter(column.getPropertyId()); |
| } else if (propertyType.isEnum()) { |
| cellFilters.setComboBoxFilter(column.getPropertyId(), |
| Arrays.asList(propertyType.getEnumConstants())); |
| } else if (DtoUtils.getDomainKeyField(propertyType) != null) { |
| cellFilters.setDtoFilter(column.getPropertyId(), propertyType, |
| ""); |
| } |
| } |
| } |
| |
| /** |
| * Checks if is primitive number. |
| * |
| * @param propertyType |
| * the property type |
| * @return true, if is primitive number |
| */ |
| private boolean isPrimitiveNumber(Class<?> propertyType) { |
| return propertyType == Byte.TYPE || propertyType == Double.TYPE |
| || propertyType == Float.TYPE || propertyType == Integer.TYPE |
| || propertyType == Long.TYPE || propertyType == Short.TYPE; |
| } |
| |
| /** |
| * Creates the custom filters. |
| * |
| * @param cxGrid |
| * the cx grid |
| */ |
| protected void createCustomFilters(CxGrid cxGrid) { |
| filteringHeader = grid.appendHeaderRow(); |
| for (CxGridColumn cxColumn : cxGrid.getColumns()) { |
| Grid.HeaderCell cell = filteringHeader.getCell(cxColumn |
| .getPropertyId()); |
| if (cell == null) { |
| continue; |
| } |
| |
| // render the search field |
| YSearchField cxSearchField = cxColumn.getSearchField(); |
| if (cxSearchField != null) { |
| ISearchFieldEditpart editpart = ModelUtil.getEditpart( |
| getViewContext(), cxSearchField); |
| filteringHeaderFields.put(cxColumn, editpart); |
| ISearchField component = (ISearchField) editpart.render(null); |
| component.bindFilterChanged(filterChangedTracker); |
| |
| cell.setComponent((Component) component); |
| } |
| } |
| } |
| |
| /** |
| * Refresh filter. |
| * |
| * @return the object |
| */ |
| private Object refreshFilter() { |
| Set<Container.Filter> filters = new HashSet<Container.Filter>(); |
| for (ISearchFieldEditpart ep : filteringHeaderFields.values()) { |
| Container.Filter f = (Container.Filter) ep.getFilter(); |
| if (f != null) { |
| filters.add(f); |
| } |
| } |
| |
| try { |
| Container.Filterable filterable = (Container.Filterable) grid |
| .getContainerDataSource(); |
| filterable.removeAllContainerFilters(); |
| filterable.addContainerFilter(new And(filters |
| .toArray(new Container.Filter[filters.size()]))); |
| } catch (Exception e) { |
| LOGGER.error("{}", e); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Creates the footer meta cells. |
| */ |
| protected void createFooterMetaCells() { |
| |
| resetFooter(); |
| |
| // create the new header |
| CxGrid cxGrid = modelAccess.yField; |
| |
| for (CxGridFooterRow cxFooter : cxGrid.getFooters()) { |
| FooterRow footerRow = grid.appendFooterRow(); |
| groupingFooters.put(cxFooter, footerRow); |
| for (CxGridGroupedCell groupingColumn : cxFooter.getGroupings()) { |
| List<Grid.FooterCell> footerCells = getCells(footerRow, |
| groupingColumn); |
| Grid.FooterCell cell = footerRow.join(footerCells |
| .toArray(new Grid.FooterCell[footerCells.size()])); |
| |
| // apply the caption of the cell |
| String caption = Util.getCaption(getI18nService(), |
| groupingColumn.getLabel(), |
| groupingColumn.getLabelI18nKey(), getLocale()); |
| |
| if (groupingColumn.isUseHTML()) { |
| cell.setHtml(caption); |
| } else { |
| cell.setText(caption); |
| } |
| } |
| |
| // create the custom cells |
| // |
| for (CxGridMetaCell cxCell : cxFooter.getCustomCells()) { |
| Grid.FooterCell cell = footerRow.getCell(cxCell.getTarget() |
| .getPropertyId()); |
| if (cell == null) { |
| continue; |
| } |
| |
| if (cxCell.getElement() != null) { |
| IEmbeddableEditpart ep = ModelUtil.getEditpart( |
| getViewContext(), cxCell.getElement()); |
| if (ep != null) { |
| Component component = (Component) ep.render(null); |
| cell.setComponent(component); |
| } |
| } else { |
| String caption = Util.getCaption(getI18nService(), |
| cxCell.getLabel(), cxCell.getLabelI18nKey(), |
| getLocale()); |
| if (cxCell.isUseHTML()) { |
| cell.setHtml(caption); |
| } else { |
| cell.setText(caption); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Reset footer. |
| */ |
| protected void resetFooter() { |
| // reset the old header |
| for (FooterRow header : groupingFooters.values()) { |
| grid.removeFooterRow(header); |
| } |
| groupingFooters.clear(); |
| |
| // dispose the cell component field |
| // |
| for (CxGridFooterRow cxFooter : modelAccess.yField.getFooters()) { |
| for (CxGridMetaCell cxCell : cxFooter.getCustomCells()) { |
| if (cxCell.getElement() != null) { |
| IEmbeddableEditpart ep = ModelUtil.findEditpart(cxCell |
| .getElement()); |
| if (ep != null && !ep.isDisposed()) { |
| ep.requestDispose(); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Gets the cells. |
| * |
| * @param row |
| * the row |
| * @param groupingColumn |
| * the grouping column |
| * @return the cells |
| */ |
| private List<Grid.HeaderCell> getCells(HeaderRow row, |
| CxGridGroupedCell groupingColumn) { |
| List<Grid.HeaderCell> cells = new ArrayList<Grid.HeaderCell>(); |
| for (CxGridGroupable column : groupingColumn.getGroupables()) { |
| if (column instanceof CxGridColumn) { |
| // if it is a column, then use the property id to get the cell |
| // |
| String id = ((CxGridColumn) column).getPropertyId(); |
| Grid.HeaderCell cell = row.getCell(id); |
| if (cell != null) { |
| cells.add(cell); |
| } |
| } else if (column instanceof CxGridGroupedCell) { |
| // if it is a grouped cell, then collect all properties of it |
| // |
| cells.addAll(getCells(row, (CxGridGroupedCell) column)); |
| } |
| } |
| return cells; |
| } |
| |
| /** |
| * Gets the cells. |
| * |
| * @param row |
| * the row |
| * @param groupingColumn |
| * the grouping column |
| * @return the cells |
| */ |
| private List<Grid.FooterCell> getCells(FooterRow row, |
| CxGridGroupedCell groupingColumn) { |
| List<Grid.FooterCell> cells = new ArrayList<Grid.FooterCell>(); |
| for (CxGridGroupable column : groupingColumn.getGroupables()) { |
| if (column instanceof CxGridColumn) { |
| // if it is a column, then use the property id to get the cell |
| // |
| String id = ((CxGridColumn) column).getPropertyId(); |
| Grid.FooterCell cell = row.getCell(id); |
| if (cell != null) { |
| cells.add(cell); |
| } |
| } else if (column instanceof CxGridGroupedCell) { |
| // if it is a grouped cell, then collect all properties of it |
| // |
| cells.addAll(getCells(row, (CxGridGroupedCell) column)); |
| } |
| } |
| return cells; |
| } |
| |
| /** |
| * Checks if is nested column. |
| * |
| * @param cxColumn |
| * the cx column |
| * @return true, if is nested column |
| */ |
| protected boolean isNestedColumn(CxGridColumn cxColumn) { |
| return cxColumn.getPropertyPath() != null |
| && cxColumn.getPropertyPath().contains("."); |
| } |
| |
| /** |
| * Returns the column header. |
| * |
| * @param cxColumn |
| * the cx column |
| * @return the column header |
| */ |
| private String getColumnHeader(CxGridColumn cxColumn) { |
| String result = null; |
| II18nService service = getI18nService(); |
| if (service != null && cxColumn.getLabelI18nKey() != null) { |
| result = service.getValue(cxColumn.getLabelI18nKey(), getLocale()); |
| } |
| |
| if (result == null || result.equals("")) { |
| result = cxColumn.getLabel(); |
| } |
| |
| if (result == null || result.equals("")) { |
| result = cxColumn.getPropertyPath(); |
| } |
| |
| return result; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#doCreateWidget(java.lang.Object) |
| */ |
| @SuppressWarnings({ "unchecked", "rawtypes", "serial" }) |
| @Override |
| public Grid doCreateWidget(Object parent) { |
| if (grid == null) { |
| |
| // tracks changes in the filters |
| filterChangedTracker = new WritableValue(); |
| filterChangedTracker.addValueChangeListener(e -> refreshFilter()); |
| |
| CxGrid cxGrid = modelAccess.yField; |
| |
| grid = new Grid(); |
| setupComponent(grid, getCastedModel()); |
| |
| associateWidget(grid, cxGrid); |
| |
| if (modelAccess.isCssIdValid()) { |
| grid.setId(modelAccess.getCssID()); |
| } else { |
| grid.setId(getEditpart().getId()); |
| } |
| |
| if (modelAccess.isCssClassValid()) { |
| grid.addStyleName(modelAccess.getCssClass()); |
| } else { |
| grid.addStyleName(CSS_CLASS_CONTROL); |
| } |
| |
| createColumns = false; |
| if (cxGrid.getType() == String.class) { |
| IndexedContainer datasource = new IndexedContainer(); |
| grid.setContainerDataSource(datasource); |
| } else { |
| if (cxGrid.getType() != null) { |
| IBeanSearchService<?> service = null; |
| IBeanSearchServiceFactory factory = getViewContext() |
| .getService( |
| IBeanSearchServiceFactory.class.getName()); |
| if (factory != null) { |
| service = factory.createService(cxGrid.getType()); |
| } |
| if (cxGrid.isUseBeanService() && service != null) { |
| ISharedStateContext sharedState = getViewContext() |
| .getService(ISharedStateContext.class.getName()); |
| BeanServiceLazyLoadingContainer<?> datasource = new BeanServiceLazyLoadingContainer( |
| service, cxGrid.getType(), sharedState); |
| |
| // Filter filter = createFilter(); |
| // if (filter != null) { |
| // datasource.addContainerFilter(filter); |
| // } |
| |
| grid.setContainerDataSource(datasource); |
| } else { |
| DeepResolvingBeanItemContainer datasource = new DeepResolvingBeanItemContainer( |
| cxGrid.getType()); |
| grid.setContainerDataSource(datasource); |
| } |
| createColumns = true; |
| } else { |
| IndexedContainer container = new IndexedContainer(); |
| container.addContainerProperty("for", String.class, null); |
| container.addContainerProperty("preview", String.class, |
| null); |
| container.addItem(new String[] { "Some value", "other" }); |
| grid.setContainerDataSource(container); |
| } |
| } |
| |
| // updates the selection type |
| updateSelectionType(); |
| |
| // creates the binding for the field |
| createBindings(cxGrid, grid); |
| |
| if (modelAccess.isCssClassValid()) { |
| grid.addStyleName(modelAccess.getCssClass()); |
| } |
| |
| // notify field about save |
| grid.getEditorFieldGroup().addCommitHandler( |
| new FieldGroup.CommitHandler() { |
| @Override |
| public void preCommit(CommitEvent commitEvent) |
| throws CommitException { |
| |
| } |
| |
| @Override |
| public void postCommit(CommitEvent commitEvent) |
| throws CommitException { |
| Object itemId = grid.getEditedItemId(); |
| modelAccess.yField.setEditorSaved(itemId); |
| } |
| }); |
| |
| applyCaptions(); |
| |
| setupUserCallbacks(cxGrid); |
| |
| } |
| |
| return grid; |
| } |
| |
| /** |
| // * Creates a predefined filter for the grid. |
| // * |
| // * @return |
| // */ |
| // private Filter createFilter() { |
| // CxGrid grid = modelAccess.yField; |
| // if (grid.getFilters().isEmpty()) { |
| // return null; |
| // } |
| // |
| // List<Filter> filters = new ArrayList<>(); |
| // for (YFilter yFilter : grid.getFilters()) { |
| // Filter filter = new Compare.Equal(yFilter.getPropertyPath(), |
| // yFilter.getFilterValue()); |
| // filters.add(filter); |
| // } |
| // return new And(filters.toArray(new Filter[filters.size()])); |
| // } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#castEObject(java.lang.Object) |
| */ |
| @Override |
| protected CxGrid castEObject(Object model) { |
| return (CxGrid) super.castEObject(model); |
| } |
| |
| /** |
| * Creates the bindings. |
| * |
| * @param yGrid |
| * the y grid |
| * @param widget |
| * the widget |
| */ |
| protected void createBindings(CxGrid yGrid, Grid widget) { |
| super.createBindings(yGrid, widget, null); |
| |
| // bind the editorEnabled property |
| IVaadinObservableValue editorEnabledUiObservable = VaadinProperties |
| .accessor(Grid.class, "editorEnabled").observe(widget); |
| IObservableValue editorEnabledModelObservable = EMFObservables |
| .observeValue(castEObject(yGrid), |
| CxGridPackage.eINSTANCE.getCxGrid_EditorEnabled()); |
| registerBinding(createBindings(editorEnabledUiObservable, |
| editorEnabledModelObservable)); |
| |
| // bind the footerVisible property |
| IVaadinObservableValue footerVisibleUiObservable = VaadinProperties |
| .accessor(Grid.class, "footerVisible").observe(widget); |
| IObservableValue footerVisibleModelObservable = EMFObservables |
| .observeValue(castEObject(yGrid), |
| CxGridPackage.eINSTANCE.getCxGrid_FooterVisible()); |
| registerBinding(createBindings(footerVisibleUiObservable, |
| footerVisibleModelObservable)); |
| // add a value change listener to update the memento |
| footerVisibleModelObservable.addValueChangeListener(e -> { |
| if (currentMemento == null |
| || currentMemento.isFooterVisible() != grid |
| .isFooterVisible()) { |
| updateMemento(); |
| } |
| }); |
| |
| // bind the headerVisible property |
| IVaadinObservableValue headerVisibleUiObservable = VaadinProperties |
| .accessor(Grid.class, "headerVisible").observe(widget); |
| IObservableValue headerVisibleModelObservable = EMFObservables |
| .observeValue(castEObject(yGrid), |
| CxGridPackage.eINSTANCE.getCxGrid_HeaderVisible()); |
| registerBinding(createBindings(headerVisibleUiObservable, |
| headerVisibleModelObservable)); |
| // add a value change listener to update the memento |
| headerVisibleModelObservable.addValueChangeListener(e -> { |
| if (currentMemento == null |
| || currentMemento.isHeaderVisible() != grid |
| .isHeaderVisible()) { |
| updateMemento(); |
| } |
| }); |
| |
| // bind the columnReorderingAllowed property |
| IVaadinObservableValue columnReorderingAllowedUiObservable = VaadinProperties |
| .accessor(Grid.class, "columnReorderingAllowed") |
| .observe(widget); |
| IObservableValue columnReorderingAllowedModelObservable = EMFObservables |
| .observeValue(castEObject(yGrid), CxGridPackage.eINSTANCE |
| .getCxGrid_ColumnReorderingAllowed()); |
| registerBinding(createBindings(columnReorderingAllowedUiObservable, |
| columnReorderingAllowedModelObservable)); |
| |
| if (!modelAccess.yField.isUseBeanService()) { |
| // if use bean service, the container is responsible to collect |
| // data. So we must not have a binding from the container to the |
| // YGrid#collection attribute. |
| Container.Indexed container = grid.getContainerDataSource(); |
| // bind the rows |
| registerBinding(createBindings_ContainerContents( |
| castEObject(getModel()), |
| CxGridPackage.Literals.CX_GRID__COLLECTION, |
| (Container.ItemSetChangeNotifier) container, |
| yGrid.getType())); |
| } |
| // update the selection binding |
| updateSelectionBinding(); |
| } |
| |
| /** |
| * Updates the selection binding for the grid. |
| */ |
| protected void updateSelectionBinding() { |
| |
| CxGrid yGrid = modelAccess.yField; |
| |
| if (selectionBinding != null) { |
| unregisterBinding(selectionBinding); |
| selectionBinding = null; |
| } |
| |
| // create the model binding from widget to ECView-model |
| if (yGrid.getSelectionType() == YSelectionType.MULTI) { |
| selectionBinding = createBindingsMultiSelection( |
| castEObject(getModel()), |
| CxGridPackage.Literals.CX_GRID__MULTI_SELECTION, grid, |
| yGrid.getType()); |
| // create the model binding from widget to ECView-model |
| registerBinding(selectionBinding); |
| } else { |
| // create the model binding from widget to ECView-model |
| selectionBinding = createBindingsSingleSelection( |
| castEObject(getModel()), |
| CxGridPackage.Literals.CX_GRID__SELECTION, grid, |
| yGrid.getType()); |
| registerBinding(selectionBinding); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ecview.extension.grid.editparts.presentation.IGridPresentation#updateSelectionType() |
| */ |
| @Override |
| public void updateSelectionType() { |
| grid.setSelectionMode(modelAccess.yField.getSelectionType() == YSelectionType.MULTI ? Grid.SelectionMode.MULTI |
| : Grid.SelectionMode.SINGLE); |
| updateSelectionBinding(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getWidget() |
| */ |
| @Override |
| public Grid getWidget() { |
| return grid; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#isRendered() |
| */ |
| @Override |
| public boolean isRendered() { |
| return grid != null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#internalDispose() |
| */ |
| @Override |
| protected void internalDispose() { |
| try { |
| unrender(); |
| } finally { |
| super.internalDispose(); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#doUnrender() |
| */ |
| @Override |
| public void doUnrender() { |
| if (grid != null) { |
| |
| // unbind all active bindings |
| unbind(); |
| |
| // remove assocations |
| unassociateWidget(grid); |
| |
| resetFooter(); |
| resetHeader(); |
| resetFilter(); |
| |
| currentMemento = null; |
| grid = null; |
| } |
| } |
| |
| /** |
| * Creates the bindings single selection. |
| * |
| * @param model |
| * the model |
| * @param modelFeature |
| * the model feature |
| * @param field |
| * the field |
| * @param collectionType |
| * the collection type |
| * @return the binding |
| */ |
| protected Binding createBindingsSingleSelection(CxGrid model, |
| EStructuralFeature modelFeature, final Grid field, |
| Class<?> collectionType) { |
| IBindingManager bindingManager = getViewContext() |
| .getService( |
| org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class |
| .getName()); |
| if (bindingManager != null) { |
| // bind the value of yText to textRidget |
| IObservableValue modelObservable = EMFProperties |
| .value(modelFeature).observe(model); |
| IVaadinObservableValue uiObservable = VaadinProperties |
| .propertyGridSelectionValueProperty(collectionType) |
| .observe(field); |
| final Binding binding = bindingManager.bindValue(uiObservable, |
| modelObservable, null, null); |
| |
| return binding; |
| } |
| return null; |
| } |
| |
| /** |
| * Creates the bindings multi selection. |
| * |
| * @param model |
| * the model |
| * @param modelFeature |
| * the model feature |
| * @param field |
| * the field |
| * @param collectionType |
| * the collection type |
| * @return the binding |
| */ |
| protected Binding createBindingsMultiSelection(CxGrid model, |
| EStructuralFeature modelFeature, final Grid field, |
| Class<?> collectionType) { |
| IBindingManager bindingManager = getViewContext() |
| .getService( |
| org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class |
| .getName()); |
| if (bindingManager != null) { |
| // bind the value of yText to textRidget |
| IObservableList modelObservable = EMFProperties.list(modelFeature) |
| .observe(model); |
| IVaadinObservableList uiObservable = new SetToListAdapter( |
| VaadinProperties.propertyGridSelectionSetPropertyAsSet( |
| collectionType).observe(field), field); |
| |
| final Binding binding = bindingManager.bindList(uiObservable, |
| modelObservable, null, null); |
| |
| return binding; |
| } |
| return null; |
| } |
| |
| /** |
| * Is used by the editpart to update the header. |
| */ |
| public void updateHeader() { |
| createHeaderMetaCells(); |
| updateMemento(); |
| } |
| |
| /** |
| * Is used by the editpart to update the footer. |
| */ |
| public void updateFooter() { |
| createFooterMetaCells(); |
| updateMemento(); |
| } |
| |
| /** |
| * Is used by the editpart to update the columns. |
| */ |
| public void updateColumns() { |
| createColumns(); |
| updateMemento(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ecview.extension.grid.editparts.presentation.IGridPresentation#updateFilter() |
| */ |
| @Override |
| public void updateFilter() { |
| createFilteringHeader(); |
| updateMemento(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ecview.extension.grid.editparts.presentation.IGridPresentation#updateCellStyleGenerator() |
| */ |
| @Override |
| public void updateCellStyleGenerator() { |
| CxGridCellStyleGenerator cxGenerator = modelAccess.yField |
| .getCellStyleGenerator(); |
| if (cxGenerator != null) { |
| IGridCellStyleGeneratorEditpart ep = ModelUtil.getEditpart( |
| getViewContext(), cxGenerator); |
| Grid.CellStyleGenerator generator = (Grid.CellStyleGenerator) ep |
| .getDelegate(); |
| grid.setCellStyleGenerator(generator); |
| } else { |
| grid.setCellStyleGenerator(null); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.runtime.common.memento.IMementoHandler#applyMemento(java.lang.Object) |
| */ |
| @Override |
| public void applyMemento(Object value) { |
| boolean isRendered = isRendered(); |
| try { |
| if (isRendered) { |
| // unrender the grid to increase performance |
| getEditpart().requestUnrender(); |
| } |
| |
| doApplyMemento(value); |
| } finally { |
| if (isRendered) { |
| // render the grid again |
| getEditpart().requestRender(); |
| } |
| } |
| } |
| |
| /** |
| * Do apply memento. |
| * |
| * @param value |
| * the value |
| */ |
| protected void doApplyMemento(Object value) { |
| CxGrid cxGrid = modelAccess.yField; |
| |
| CxGridMemento cxMemento = (CxGridMemento) value; |
| currentMemento = cxMemento; |
| |
| // apply the grid properties |
| // |
| cxGrid.setEditorEnabled(cxMemento.isEditorEnabled()); |
| cxGrid.setFilteringVisible(cxMemento.isFilterVisible()); |
| cxGrid.setHeaderVisible(cxMemento.isHeaderVisible()); |
| cxGrid.setFooterVisible(cxMemento.isFooterVisible()); |
| |
| // apply the columns to the grid and the setting to each column |
| // |
| List<CxGridColumn> tempColumns = new ArrayList<>(cxGrid.getColumns()); |
| List<CxGridColumn> cxOrderedColumns = new ArrayList<>(cxGrid |
| .getColumns().size()); |
| for (CxGridMementoColumn memColumn : cxMemento.getColumns()) { |
| CxGridColumn cxColumn = findCxColumn(memColumn.getPropertyId()); |
| if (cxColumn != null) { |
| // add the columns in the order of the memento |
| cxOrderedColumns.add(cxColumn); |
| tempColumns.remove(cxColumn); |
| |
| cxColumn.setEditable(memColumn.isEditable()); |
| cxColumn.setHidden(memColumn.isHidden()); |
| cxColumn.setHideable(memColumn.isHideable()); |
| cxColumn.setSortable(memColumn.isSortable()); |
| cxColumn.setExpandRatio(memColumn.getExpandRatio()); |
| if (memColumn.getWidth() > 0) { |
| cxColumn.setWidth(memColumn.getWidth()); |
| } |
| } |
| } |
| |
| // set all columns that are not in the memento as hidden |
| // |
| for (CxGridColumn cxColumn : tempColumns) { |
| cxColumn.setHideable(true); |
| cxColumn.setHidden(true); |
| } |
| |
| // set the new columns to the grid |
| cxGrid.getColumns().clear(); |
| cxGrid.getColumns().addAll(cxOrderedColumns); |
| |
| // update the sortorder |
| // |
| List<CxGridSortable> cxSortables = new ArrayList<>(cxMemento |
| .getSortOrders().size()); |
| if (cxMemento.getSortOrders().size() > 0) { |
| for (CxGridMementoSortable memSort : cxMemento.getSortOrders()) { |
| |
| CxGridColumn cxColumn = findCxColumn(memSort.getColumn() |
| .getPropertyId()); |
| if (cxColumn != null) { |
| CxGridSortable cxSortable = CxGridFactory.eINSTANCE |
| .createCxGridSortable(); |
| cxSortable.setColumn(cxColumn); |
| cxSortable.setDescending(memSort.isDescending()); |
| cxSortables.add(cxSortable); |
| } |
| } |
| cxGrid.getSortOrder().addAll(cxSortables); |
| } |
| } |
| |
| /** |
| * To direction. |
| * |
| * @param cxSortable |
| * the cx sortable |
| * @return the sort direction |
| */ |
| private SortDirection toDirection(CxGridSortable cxSortable) { |
| return cxSortable.isDescending() ? SortDirection.DESCENDING |
| : SortDirection.ASCENDING; |
| } |
| |
| /** |
| * Gets the memento. |
| * |
| * @return the memento |
| */ |
| private Object getMemento() { |
| CxGridMemento cxMemento = CxGridMementoFactory.eINSTANCE |
| .createCxGridMemento(); |
| |
| currentMemento = cxMemento; |
| |
| cxMemento.setId(getMementoId()); |
| cxMemento.setGridId(getCastedModel().getId()); |
| cxMemento.setEditorEnabled(grid.isEditorEnabled()); |
| cxMemento.setHeaderVisible(grid.isHeaderVisible()); |
| cxMemento.setFooterVisible(grid.isFooterVisible()); |
| cxMemento.setFilterVisible(filteringHeader != null); |
| |
| Map<Object, CxGridMementoColumn> tempColumns = new HashMap<>(); |
| for (Grid.Column column : grid.getColumns()) { |
| CxGridMementoColumn cxColumn = CxGridMementoFactory.eINSTANCE |
| .createCxGridMementoColumn(); |
| cxColumn.setEditable(column.isEditable()); |
| cxColumn.setExpandRatio(column.getExpandRatio()); |
| cxColumn.setHideable(column.isHidable()); |
| cxColumn.setHidden(column.isHidden()); |
| cxColumn.setSortable(column.isSortable()); |
| cxColumn.setWidth((int) column.getWidth()); |
| cxColumn.setPropertyId((String) column.getPropertyId()); |
| cxMemento.getColumns().add(cxColumn); |
| |
| tempColumns.put(cxColumn.getPropertyId(), cxColumn); |
| } |
| |
| for (SortOrder sortOrder : grid.getSortOrder()) { |
| CxGridMementoSortable cxSortable = CxGridMementoFactory.eINSTANCE |
| .createCxGridMementoSortable(); |
| CxGridMementoColumn cxColumn = tempColumns.get(sortOrder |
| .getPropertyId()); |
| if (cxColumn == null) { |
| LOGGER.warn("Column is not available :" |
| + sortOrder.getPropertyId()); |
| continue; |
| } |
| |
| cxSortable.setColumn(cxColumn); |
| cxSortable |
| .setDescending(sortOrder.getDirection() == SortDirection.DESCENDING); |
| |
| cxMemento.getSortOrders().add(cxSortable); |
| } |
| |
| return cxMemento; |
| } |
| |
| /** |
| * Gets the memento id. |
| * |
| * @return the memento id |
| */ |
| protected String getMementoId() { |
| return castEObject(getCastedModel()).getMementoId(); |
| } |
| |
| /** |
| * Handles the memento, if it is enabled by the grid. |
| * |
| * @param cxGrid |
| * the new up user callbacks |
| */ |
| protected void setupUserCallbacks(CxGrid cxGrid) { |
| // then add listeners to the grid |
| // |
| grid.addColumnReorderListener(e -> { |
| if (e.isUserOriginated()) { |
| userChangedHandler.userChangedColumnOrder(); |
| updateMemento(); |
| } |
| }); |
| |
| grid.addColumnVisibilityChangeListener(e -> { |
| if (e.isUserOriginated()) { |
| userChangedHandler.userChangedColumnVisibility(e); |
| updateMemento(); |
| } |
| }); |
| |
| grid.addSortListener(e -> { |
| if (e.isUserOriginated()) { |
| userChangedHandler.userChangedSortOrder(e); |
| updateMemento(); |
| } |
| }); |
| |
| } |
| |
| /** |
| * Find column wrapper. |
| * |
| * @param column |
| * the column |
| * @return the column wrapper |
| */ |
| private ColumnWrapper findColumnWrapper(Grid.Column column) { |
| return columns.stream().filter(e -> e.column == column).findFirst() |
| .orElse(null); |
| } |
| |
| /** |
| * Find column wrapper. |
| * |
| * @param propertyId |
| * the property id |
| * @return the column wrapper |
| */ |
| private ColumnWrapper findColumnWrapper(String propertyId) { |
| return columns.stream() |
| .filter(e -> e.column.getPropertyId().equals(propertyId)) |
| .findFirst().orElse(null); |
| } |
| |
| /** |
| * Find cx column. |
| * |
| * @param propertyId |
| * the property id |
| * @return the cx grid column |
| */ |
| private CxGridColumn findCxColumn(String propertyId) { |
| CxGrid cxGrid = modelAccess.yField; |
| return cxGrid.getColumns().stream() |
| .filter(e -> e.getPropertyId().equals(propertyId)).findFirst() |
| .orElse(null); |
| } |
| |
| /** |
| * Updates the memento. |
| */ |
| protected void updateMemento() { |
| if (modelAccess.yField.isMementoEnabled()) { |
| IGridEditpart ep = (IGridEditpart) getEditpart(); |
| ep.saveMemento(getMemento()); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#internalGetObservableEndpoint(org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint) |
| */ |
| @Override |
| protected IObservable internalGetObservableEndpoint( |
| YEmbeddableBindingEndpoint bindableValue) { |
| if (bindableValue == null) { |
| throw new IllegalArgumentException( |
| "BindableValue must not be null!"); |
| } |
| |
| if (bindableValue instanceof YEmbeddableCollectionEndpoint) { |
| return internalGetCollectionEndpoint(); |
| } else if (bindableValue instanceof YEmbeddableSelectionEndpoint) { |
| return internalGetSelectionEndpoint((YEmbeddableSelectionEndpoint) bindableValue); |
| } else if (bindableValue instanceof YEmbeddableMultiSelectionEndpoint) { |
| return internalGetMultiSelectionEndpoint(); |
| } |
| throw new IllegalArgumentException("Not a valid input: " |
| + bindableValue); |
| } |
| |
| /** |
| * Returns the observable to observe the collection. |
| * |
| * @return the i observable list |
| */ |
| protected IObservableList internalGetCollectionEndpoint() { |
| // return the observable value for text |
| return EMFProperties.list(CxGridPackage.Literals.CX_GRID__COLLECTION) |
| .observe(getModel()); |
| } |
| |
| /** |
| * Returns the observable to observe the selection. |
| * |
| * @param yEndpoint |
| * the y endpoint |
| * @return the i observable value |
| */ |
| @SuppressWarnings("restriction") |
| protected IObservableValue internalGetSelectionEndpoint( |
| YEmbeddableSelectionEndpoint yEndpoint) { |
| |
| String attributePath = ECViewModelBindable.getAttributePath( |
| CxGridPackage.Literals.CX_GRID__SELECTION, |
| yEndpoint.getAttributePath()); |
| |
| // return the observable value |
| return ECViewModelBindable.observeValue(castEObject(getModel()), |
| attributePath, modelAccess.yField.getType(), |
| modelAccess.yField.getEmfNsURI()); |
| } |
| |
| /** |
| * Returns the observable to observe the selection. |
| * |
| * @return the i observable list |
| */ |
| protected IObservableList internalGetMultiSelectionEndpoint() { |
| // return the observable value for text |
| return EMFProperties.list(CxGridPackage.Literals.CX_GRID__SELECTION) |
| .observe(getModel()); |
| } |
| |
| /** |
| * An internal helper class. |
| */ |
| private static class ModelAccess { |
| |
| /** The y field. */ |
| private final CxGrid yField; |
| |
| /** |
| * Instantiates a new model access. |
| * |
| * @param yLayout |
| * the y layout |
| */ |
| public ModelAccess(CxGrid yLayout) { |
| super(); |
| this.yField = yLayout; |
| } |
| |
| /** |
| * Gets the css class. |
| * |
| * @return the css class |
| * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssClass() |
| */ |
| public String getCssClass() { |
| return yField.getCssClass(); |
| } |
| |
| /** |
| * Returns true, if the css class is not null and not empty. |
| * |
| * @return true, if is css class valid |
| */ |
| public boolean isCssClassValid() { |
| return getCssClass() != null && !getCssClass().equals(""); |
| } |
| |
| /** |
| * Gets the css id. |
| * |
| * @return the css id |
| * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssID() |
| */ |
| public String getCssID() { |
| return yField.getCssID(); |
| } |
| |
| /** |
| * Returns true, if the css id is not null and not empty. |
| * |
| * @return true, if is css id valid |
| */ |
| public boolean isCssIdValid() { |
| return getCssID() != null && !getCssID().equals(""); |
| } |
| |
| /** |
| * Returns the label. |
| * |
| * @return the label |
| */ |
| public String getLabel() { |
| return yField.getLabel(); |
| } |
| |
| /** |
| * Returns the label I18n key. |
| * |
| * @return the label i18n key |
| */ |
| public String getLabelI18nKey() { |
| return yField.getLabelI18nKey(); |
| } |
| } |
| |
| /** |
| * The Class ColumnWrapper. |
| */ |
| private class ColumnWrapper extends AbstractDisposable implements |
| IGridColumnEditpart.ColumnReference { |
| |
| /** The cx column. */ |
| private CxGridColumn cxColumn; |
| |
| /** The column. */ |
| private Grid.Column column; |
| |
| /** |
| * Instantiates a new column wrapper. |
| * |
| * @param cxColumn |
| * the cx column |
| * @param column |
| * the column |
| */ |
| public ColumnWrapper(CxGridColumn cxColumn, Grid.Column column) { |
| super(); |
| this.cxColumn = cxColumn; |
| this.column = column; |
| |
| columns.add(this); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ecview.extension.grid.editparts.IGridColumnEditpart.ColumnReference#setConverter(java.lang.Object) |
| */ |
| @Override |
| public void setConverter(Object converter) { |
| if (converter != null && converter instanceof Converter) { |
| column.setConverter((Converter<?, ?>) converter); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ecview.extension.grid.editparts.IGridColumnEditpart.ColumnReference#setRenderer(java.lang.Object, java.lang.Object) |
| */ |
| @SuppressWarnings({ "unchecked", "rawtypes" }) |
| @Override |
| public void setRenderer(Object renderer, Object converter) { |
| if (renderer == null) { |
| LOGGER.debug("Null renderer not allowed"); |
| return; |
| } |
| if (converter == null) { |
| column.setRenderer((Renderer) renderer); |
| } else { |
| column.setRenderer((Renderer) renderer, (Converter) converter); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ecview.extension.grid.editparts.IGridColumnEditpart.ColumnReference#updateProperties() |
| */ |
| @Override |
| public void updateProperties() { |
| column.setHeaderCaption(getColumnHeader(cxColumn)); |
| column.setHidden(cxColumn.isHidden()); |
| column.setHidable(cxColumn.isHideable()); |
| column.setEditable(cxColumn.isEditable()); |
| if (cxColumn.getMinWidthPixels() > -1) { |
| column.setMinimumWidth(cxColumn.getMinWidthPixels()); |
| } |
| if (cxColumn.getMaxWidthPixels() > 0) { |
| column.setMaximumWidth(cxColumn.getMaxWidthPixels()); |
| } |
| if (cxColumn.getWidth() > -1) { |
| column.setWidth(cxColumn.getWidth()); |
| } else { |
| column.setWidthUndefined(); |
| } |
| column.setSortable(cxColumn.isSortable()); |
| if (cxColumn.getExpandRatio() > -1) { |
| column.setExpandRatio(cxColumn.getExpandRatio()); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ecview.extension.grid.editparts.IGridColumnEditpart.ColumnReference#updateEditorField() |
| */ |
| @Override |
| public void updateEditorField() { |
| if (!cxColumn.isEditable()) { |
| column.setEditorField(null); |
| } else { |
| YField cxField = cxColumn.getEditorField(); |
| Field<?> field = null; |
| if (cxField != null) { |
| IFieldEditpart editpart = ModelUtil.getEditpart( |
| getViewContext(), cxField); |
| field = (Field<?>) editpart.render(null); |
| field.setSizeFull(); |
| } |
| column.setEditorField(field); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.runtime.common.dispose.AbstractDisposable#internalDispose() |
| */ |
| @Override |
| protected void internalDispose() { |
| |
| // remove this column from the cached columns |
| columns.remove(this); |
| |
| YField cxField = cxColumn.getEditorField(); |
| if (cxField != null) { |
| IFieldEditpart editpart = ModelUtil.findEditpart(cxField); |
| if (editpart != null) { |
| editpart.dispose(); |
| } |
| } |
| } |
| } |
| |
| /** |
| * The Class UserChangedHandler. |
| */ |
| private class UserChangedHandler { |
| |
| /** |
| * User changed sort order. |
| * |
| * @param e |
| * the e |
| */ |
| private void userChangedSortOrder(SortEvent e) { |
| List<CxGridSortable> cxSortOrder = new ArrayList<>(); |
| for (SortOrder sortOrder : e.getSortOrder()) { |
| ColumnWrapper wrapper = findColumnWrapper((String) sortOrder |
| .getPropertyId()); |
| |
| CxGridSortable cxSortable = CxGridFactory.eINSTANCE |
| .createCxGridSortable(); |
| cxSortOrder.add(cxSortable); |
| if (wrapper != null) { |
| cxSortable.setColumn(wrapper.cxColumn); |
| } |
| cxSortable |
| .setDescending(sortOrder.getDirection() == SortDirection.DESCENDING); |
| } |
| |
| CxGrid cxGrid = modelAccess.yField; |
| try { |
| cxGrid.eSetDeliver(false); |
| modelAccess.yField.getSortOrder().clear(); |
| modelAccess.yField.getSortOrder().addAll(cxSortOrder); |
| } finally { |
| cxGrid.eSetDeliver(true); |
| } |
| |
| } |
| |
| /** |
| * User changed column visibility. |
| * |
| * @param e |
| * the e |
| */ |
| private void userChangedColumnVisibility(ColumnVisibilityChangeEvent e) { |
| Grid.Column affected = e.getColumn(); |
| ColumnWrapper wrapper = findColumnWrapper(affected); |
| if (wrapper == null) { |
| LOGGER.warn("No column available for " |
| + affected.getHeaderCaption()); |
| return; |
| } |
| |
| CxGrid cxGrid = modelAccess.yField; |
| try { |
| cxGrid.eSetDeliver(false); |
| // update the column in the model |
| CxGridColumn cxColumn = wrapper.cxColumn; |
| cxColumn.setHidden(e.isHidden()); |
| } finally { |
| cxGrid.eSetDeliver(true); |
| } |
| } |
| |
| /** |
| * User changed column order. |
| */ |
| private void userChangedColumnOrder() { |
| List<CxGridColumn> cxColumns = new ArrayList<>(); |
| for (Grid.Column column : grid.getColumns()) { |
| ColumnWrapper wrapper = findColumnWrapper(column); |
| cxColumns.add(wrapper.cxColumn); |
| } |
| |
| CxGrid cxGrid = modelAccess.yField; |
| try { |
| cxGrid.eSetDeliver(false); |
| cxGrid.getColumns().clear(); |
| cxGrid.getColumns().addAll(cxColumns); |
| } finally { |
| cxGrid.eSetDeliver(true); |
| } |
| } |
| } |
| } |