mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-03 03:38:33 +08:00
Reimplement Table aggregation API #PL-2292
This commit is contained in:
parent
c52c1f40d6
commit
57a367d944
@ -60,7 +60,7 @@ def webToolkitLegacyModule = project(':cuba-web6-toolkit')
|
|||||||
def webModuleThemes = project(':cuba-web-themes')
|
def webModuleThemes = project(':cuba-web-themes')
|
||||||
def webLegacyModuleThemes = project(':cuba-web6-themes')
|
def webLegacyModuleThemes = project(':cuba-web6-themes')
|
||||||
|
|
||||||
def vaadinVersion = '7.2.6.cuba.0'
|
def vaadinVersion = '7.2.6.cuba.1'
|
||||||
def vaadinLegacyVersion = '6.6.1.161'
|
def vaadinLegacyVersion = '6.6.1.161'
|
||||||
def springVersion = '3.2.8.RELEASE'
|
def springVersion = '3.2.8.RELEASE'
|
||||||
def springSecurityVersion = '3.2.3.RELEASE'
|
def springSecurityVersion = '3.2.3.RELEASE'
|
||||||
|
@ -14,45 +14,50 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gorodnov
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
public class Aggregations {
|
public class Aggregations {
|
||||||
|
private static final Aggregations instance;
|
||||||
|
|
||||||
private static Aggregations instance = null;
|
static {
|
||||||
|
|
||||||
private Map<String, Aggregation> aggregationByName;
|
|
||||||
private Map<Class, Aggregation> aggregationByDatatype;
|
|
||||||
|
|
||||||
private Aggregations() {
|
|
||||||
aggregationByName = new HashMap<String, Aggregation>();
|
|
||||||
aggregationByDatatype = new HashMap<Class, Aggregation>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Aggregations getInstance() {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new Aggregations();
|
instance = new Aggregations();
|
||||||
instance.register(Datatypes.getNN(BigDecimal.class), new BigDecimalAggregation());
|
instance.register(Datatypes.getNN(BigDecimal.class), new BigDecimalAggregation());
|
||||||
instance.register(Datatypes.getNN(Integer.class), new LongAggregation());
|
instance.register(Datatypes.getNN(Integer.class), new LongAggregation());
|
||||||
instance.register(Datatypes.getNN(Long.class), new LongAggregation());
|
instance.register(Datatypes.getNN(Long.class), new LongAggregation());
|
||||||
instance.register(Datatypes.getNN(Double.class), new DoubleAggregation());
|
instance.register(Datatypes.getNN(Double.class), new DoubleAggregation());
|
||||||
instance.register(Datatypes.getNN(Date.class), new DateAggregation());
|
instance.register(Datatypes.getNN(Date.class), new DateAggregation());
|
||||||
instance.register(Datatypes.getNN(Boolean.class), new BasicAggregation<Boolean>(Boolean.class));
|
instance.register(Datatypes.getNN(Boolean.class), new BasicAggregation<>(Boolean.class));
|
||||||
instance.register(Datatypes.getNN(byte[].class), new BasicAggregation<byte[]>(byte[].class));
|
instance.register(Datatypes.getNN(byte[].class), new BasicAggregation<>(byte[].class));
|
||||||
// instance.register(Datatypes.getNN(Enum.class), new BasicAggregation());
|
instance.register(Datatypes.getNN(String.class), new BasicAggregation<>(String.class));
|
||||||
instance.register(Datatypes.getNN(String.class), new BasicAggregation<String>(String.class));
|
instance.register(Datatypes.getNN(UUID.class), new BasicAggregation<>(UUID.class));
|
||||||
instance.register(Datatypes.getNN(UUID.class), new BasicAggregation<UUID>(UUID.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Aggregations getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void register(Datatype datatype, Aggregation<T> aggregation) {
|
private Map<String, Aggregation> aggregationByName;
|
||||||
|
private Map<Class, Aggregation> aggregationByDatatype;
|
||||||
|
|
||||||
|
private Aggregations() {
|
||||||
|
aggregationByName = new HashMap<>();
|
||||||
|
aggregationByDatatype = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T> void register(Datatype datatype, Aggregation<T> aggregation) {
|
||||||
aggregationByDatatype.put(datatype.getJavaClass(), aggregation);
|
aggregationByDatatype.put(datatype.getJavaClass(), aggregation);
|
||||||
aggregationByName.put(datatype.getName(), aggregation);
|
aggregationByName.put(datatype.getName(), aggregation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Aggregation<T> get(String name) {
|
@SuppressWarnings("unchecked")
|
||||||
return aggregationByName.get(name);
|
public static <T> Aggregation<T> get(String name) {
|
||||||
|
return getInstance().aggregationByName.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Aggregation<T> get(Class<T> clazz) {
|
@SuppressWarnings("unchecked")
|
||||||
return aggregationByDatatype.get(clazz);
|
public static <T> Aggregation<T> get(Class<T> clazz) {
|
||||||
|
return getInstance().aggregationByDatatype.get(clazz);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,6 +8,10 @@ import com.haulmont.cuba.gui.aggregation.Aggregation;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gorodnov
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
public class BasicAggregation<T> implements Aggregation<T> {
|
public class BasicAggregation<T> implements Aggregation<T> {
|
||||||
|
|
||||||
private Class<T> clazz;
|
private Class<T> clazz;
|
||||||
@ -16,46 +20,57 @@ public class BasicAggregation<T> implements Aggregation<T> {
|
|||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public T sum(Collection<T> items) {
|
public T sum(Collection<T> items) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean allowSum() {
|
public boolean allowSum() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public T avg(Collection<T> items) {
|
public T avg(Collection<T> items) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean allowAvg() {
|
public boolean allowAvg() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public T min(Collection<T> items) {
|
public T min(Collection<T> items) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean allowMin() {
|
public boolean allowMin() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public T max(Collection<T> items) {
|
public T max(Collection<T> items) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean allowMax() {
|
public boolean allowMax() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int count(Collection<T> items) {
|
public int count(Collection<T> items) {
|
||||||
return items.size();
|
return items.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean allowCount() {
|
public boolean allowCount() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Class<T> getJavaClass() {
|
public Class<T> getJavaClass() {
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,10 @@ import com.haulmont.cuba.gui.aggregation.NumberAggregationHelper;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gorodnov
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
public abstract class BasicNumberAggregation<T extends Number> extends BasicAggregation <T> {
|
public abstract class BasicNumberAggregation<T extends Number> extends BasicAggregation <T> {
|
||||||
|
|
||||||
protected BasicNumberAggregation(Class<T> clazz) {
|
protected BasicNumberAggregation(Class<T> clazz) {
|
||||||
|
@ -6,12 +6,17 @@ package com.haulmont.cuba.gui.aggregation.impl;
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gorodnov
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
public class BigDecimalAggregation extends BasicNumberAggregation<BigDecimal> {
|
public class BigDecimalAggregation extends BasicNumberAggregation<BigDecimal> {
|
||||||
|
|
||||||
public BigDecimalAggregation() {
|
public BigDecimalAggregation() {
|
||||||
super(BigDecimal.class);
|
super(BigDecimal.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public BigDecimal convert(Double result) {
|
public BigDecimal convert(Double result) {
|
||||||
return BigDecimal.valueOf(result);
|
return BigDecimal.valueOf(result);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,10 @@ import com.haulmont.cuba.gui.aggregation.NumberAggregationHelper;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gorodnov
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
public class DateAggregation extends BasicAggregation<Date> {
|
public class DateAggregation extends BasicAggregation<Date> {
|
||||||
public DateAggregation() {
|
public DateAggregation() {
|
||||||
super(Date.class);
|
super(Date.class);
|
||||||
|
@ -4,11 +4,16 @@
|
|||||||
*/
|
*/
|
||||||
package com.haulmont.cuba.gui.aggregation.impl;
|
package com.haulmont.cuba.gui.aggregation.impl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gorodnov
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
public class DoubleAggregation extends BasicNumberAggregation<Double> {
|
public class DoubleAggregation extends BasicNumberAggregation<Double> {
|
||||||
public DoubleAggregation() {
|
public DoubleAggregation() {
|
||||||
super(Double.class);
|
super(Double.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Double convert(Double result) {
|
public Double convert(Double result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,16 @@
|
|||||||
*/
|
*/
|
||||||
package com.haulmont.cuba.gui.aggregation.impl;
|
package com.haulmont.cuba.gui.aggregation.impl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gorodnov
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
public class LongAggregation extends BasicNumberAggregation<Long> {
|
public class LongAggregation extends BasicNumberAggregation<Long> {
|
||||||
public LongAggregation() {
|
public LongAggregation() {
|
||||||
super(Long.class);
|
super(Long.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected Long convert(Double result) {
|
protected Long convert(Double result) {
|
||||||
return result.longValue();
|
return result.longValue();
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.haulmont.cuba.gui.components;
|
package com.haulmont.cuba.gui.components;
|
||||||
|
|
||||||
|
import com.haulmont.chile.core.model.MetaPropertyPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param <P>
|
|
||||||
*
|
|
||||||
* @author gorodnov
|
* @author gorodnov
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public class AggregationInfo<P> {
|
public class AggregationInfo {
|
||||||
|
|
||||||
public enum Type {
|
public enum Type {
|
||||||
SUM,
|
SUM,
|
||||||
@ -20,15 +20,15 @@ public class AggregationInfo<P> {
|
|||||||
MAX
|
MAX
|
||||||
}
|
}
|
||||||
|
|
||||||
private P propertyPath;
|
private MetaPropertyPath propertyPath;
|
||||||
private Type type;
|
private Type type;
|
||||||
private Formatter formatter;
|
private Formatter formatter;
|
||||||
|
|
||||||
public P getPropertyPath() {
|
public MetaPropertyPath getPropertyPath() {
|
||||||
return propertyPath;
|
return propertyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPropertyPath(P propertyPath) {
|
public void setPropertyPath(MetaPropertyPath propertyPath) {
|
||||||
this.propertyPath = propertyPath;
|
this.propertyPath = propertyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,12 @@ import com.haulmont.cuba.gui.components.AggregationInfo;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author grachev
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
public abstract class AggregatableDelegate<K> {
|
public abstract class AggregatableDelegate<K> {
|
||||||
|
public Map<Object, String> aggregate(AggregationInfo[] aggregationInfos, Collection<K> itemIds) {
|
||||||
public Map<Object, String> aggregate(AggregationInfo<MetaPropertyPath>[] aggregationInfos, Collection<K> itemIds) {
|
|
||||||
if (aggregationInfos == null || aggregationInfos.length == 0) {
|
if (aggregationInfos == null || aggregationInfos.length == 0) {
|
||||||
throw new NullPointerException("Aggregation must be executed at least by one field");
|
throw new NullPointerException("Aggregation must be executed at least by one field");
|
||||||
}
|
}
|
||||||
@ -23,12 +26,11 @@ public abstract class AggregatableDelegate<K> {
|
|||||||
return doAggregation(itemIds, aggregationInfos);
|
return doAggregation(itemIds, aggregationInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<Object, String> doAggregation(Collection<K> itemIds, AggregationInfo<MetaPropertyPath>[] aggregationInfos) {
|
protected Map<Object, String> doAggregation(Collection<K> itemIds, AggregationInfo[] aggregationInfos) {
|
||||||
final Map<Object, String> aggregationResults = new HashMap<Object, String>();
|
final Map<Object, String> aggregationResults = new HashMap<>();
|
||||||
for (final AggregationInfo<MetaPropertyPath> aggregationInfo : aggregationInfos) {
|
for (AggregationInfo aggregationInfo : aggregationInfos) {
|
||||||
|
Class rangeJavaClass = aggregationInfo.getPropertyPath().getRangeJavaClass();
|
||||||
final Aggregation aggregation = Aggregations.getInstance()
|
final Aggregation aggregation = Aggregations.get(rangeJavaClass);
|
||||||
.get(aggregationInfo.getPropertyPath().getRangeJavaClass());
|
|
||||||
|
|
||||||
final Object value = doPropertyAggregation(aggregationInfo, aggregation, itemIds);
|
final Object value = doPropertyAggregation(aggregationInfo, aggregation, itemIds);
|
||||||
|
|
||||||
@ -50,11 +52,9 @@ public abstract class AggregatableDelegate<K> {
|
|||||||
return aggregationResults;
|
return aggregationResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object doPropertyAggregation(
|
@SuppressWarnings("unchecked")
|
||||||
AggregationInfo<MetaPropertyPath> aggregationInfo,
|
protected Object doPropertyAggregation(AggregationInfo aggregationInfo, Aggregation aggregation,
|
||||||
Aggregation aggregation,
|
Collection<K> itemIds) {
|
||||||
Collection<K> itemIds
|
|
||||||
) {
|
|
||||||
List items = valuesByProperty(aggregationInfo.getPropertyPath(), itemIds);
|
List items = valuesByProperty(aggregationInfo.getPropertyPath(), itemIds);
|
||||||
switch (aggregationInfo.getType()) {
|
switch (aggregationInfo.getType()) {
|
||||||
case COUNT:
|
case COUNT:
|
||||||
@ -74,7 +74,7 @@ public abstract class AggregatableDelegate<K> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected List valuesByProperty(MetaPropertyPath propertyPath, Collection<K> itemIds) {
|
protected List valuesByProperty(MetaPropertyPath propertyPath, Collection<K> itemIds) {
|
||||||
final List<Object> values = new ArrayList<Object>(itemIds.size());
|
final List<Object> values = new ArrayList<>(itemIds.size());
|
||||||
for (final K itemId : itemIds) {
|
for (final K itemId : itemIds) {
|
||||||
final Object value = getItemValue(propertyPath, itemId);
|
final Object value = getItemValue(propertyPath, itemId);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
@ -311,6 +311,7 @@
|
|||||||
<xs:attribute name="columnControlVisible" type="xs:boolean"/>
|
<xs:attribute name="columnControlVisible" type="xs:boolean"/>
|
||||||
|
|
||||||
<xs:attribute name="aggregatable" type="xs:boolean"/>
|
<xs:attribute name="aggregatable" type="xs:boolean"/>
|
||||||
|
<xs:attribute name="showTotalAggregation" type="xs:boolean"/>
|
||||||
<xs:attribute name="presentations" type="xs:boolean"/>
|
<xs:attribute name="presentations" type="xs:boolean"/>
|
||||||
<xs:attribute name="allowPopupMenu" type="xs:boolean"/>
|
<xs:attribute name="allowPopupMenu" type="xs:boolean"/>
|
||||||
<xs:attribute name="allowMultiStringCells" type="xs:boolean"/>
|
<xs:attribute name="allowMultiStringCells" type="xs:boolean"/>
|
||||||
@ -834,15 +835,14 @@
|
|||||||
<xs:complexType name="tableColumnComponent">
|
<xs:complexType name="tableColumnComponent">
|
||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
<xs:element name="formatter" minOccurs="0" maxOccurs="1" type="formatterType"/>
|
<xs:element name="formatter" minOccurs="0" maxOccurs="1" type="formatterType"/>
|
||||||
<!--<xs:element name="calculatable" minOccurs="0" maxOccurs="1"/>-->
|
<xs:element name="aggregation" minOccurs="0" maxOccurs="1">
|
||||||
<!--<xs:element name="aggregation" minOccurs="0" maxOccurs="1">-->
|
<xs:complexType>
|
||||||
<!--<xs:complexType>-->
|
<xs:sequence>
|
||||||
<!--<xs:sequence>-->
|
<xs:element name="formatter" minOccurs="0" maxOccurs="1" type="formatterType"/>
|
||||||
<!--<xs:element name="formatter" minOccurs="0" maxOccurs="1" type="formatterType"/>-->
|
</xs:sequence>
|
||||||
<!--</xs:sequence>-->
|
<xs:attribute name="type" type="aggregation" use="required"/>
|
||||||
<!--<xs:attribute name="type" type="aggregation" use="required"/>-->
|
</xs:complexType>
|
||||||
<!--</xs:complexType>-->
|
</xs:element>
|
||||||
<!--</xs:element>-->
|
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
|
|
||||||
<xs:attributeGroup ref="requiresId"/>
|
<xs:attributeGroup ref="requiresId"/>
|
||||||
@ -853,6 +853,7 @@
|
|||||||
<xs:attribute name="clickAction" type="xs:string"/>
|
<xs:attribute name="clickAction" type="xs:string"/>
|
||||||
<xs:attribute name="collapsed" type="xs:boolean"/>
|
<xs:attribute name="collapsed" type="xs:boolean"/>
|
||||||
<xs:attribute name="maxTextLength" type="xs:integer"/>
|
<xs:attribute name="maxTextLength" type="xs:integer"/>
|
||||||
|
<xs:attribute name="calculatable" type="xs:boolean"/>
|
||||||
|
|
||||||
<!-- Additional attributes, use only for editable table -->
|
<!-- Additional attributes, use only for editable table -->
|
||||||
<xs:attributeGroup ref="hasOptions"/>
|
<xs:attributeGroup ref="hasOptions"/>
|
||||||
|
@ -297,7 +297,7 @@ public abstract class AbstractTableLoader<T extends Table> extends ComponentLoad
|
|||||||
Element aggregationElement = columnElement.element("aggregation");
|
Element aggregationElement = columnElement.element("aggregation");
|
||||||
if (aggregationElement != null) {
|
if (aggregationElement != null) {
|
||||||
final AggregationInfo aggregation = new AggregationInfo();
|
final AggregationInfo aggregation = new AggregationInfo();
|
||||||
aggregation.setPropertyPath(column.getId());
|
aggregation.setPropertyPath((MetaPropertyPath) column.getId());
|
||||||
aggregation.setType(AggregationInfo.Type.valueOf(aggregationElement.attributeValue("type")));
|
aggregation.setType(AggregationInfo.Type.valueOf(aggregationElement.attributeValue("type")));
|
||||||
Formatter formatter = loadFormatter(aggregationElement);
|
Formatter formatter = loadFormatter(aggregationElement);
|
||||||
aggregation.setFormatter(formatter == null ? column.getFormatter() : formatter);
|
aggregation.setFormatter(formatter == null ? column.getFormatter() : formatter);
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2014 Haulmont. All rights reserved.
|
||||||
|
* Use is subject to license terms, see http://www.cuba-platform.com/license for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.haulmont.cuba.web.toolkit.ui.client.aggregation;
|
||||||
|
|
||||||
|
import com.vaadin.client.ui.VScrollTable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VScrollTable API wrapper for {@link TableAggregationRow}
|
||||||
|
*
|
||||||
|
* @author artamonov
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public interface AggregatableTable {
|
||||||
|
|
||||||
|
VScrollTable.TableHead getHead();
|
||||||
|
|
||||||
|
String getStylePrimaryName();
|
||||||
|
|
||||||
|
String[] getVisibleColOrder();
|
||||||
|
|
||||||
|
String getColKeyByIndex(int index);
|
||||||
|
|
||||||
|
int getColWidth(String colKey);
|
||||||
|
|
||||||
|
void setColWidth(int colIndex, int w, boolean isDefinedWidth);
|
||||||
|
|
||||||
|
boolean isTextSelectionEnabled();
|
||||||
|
}
|
@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2014 Haulmont. All rights reserved.
|
||||||
|
* Use is subject to license terms, see http://www.cuba-platform.com/license for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.haulmont.cuba.web.toolkit.ui.client.aggregation;
|
||||||
|
|
||||||
|
import com.google.gwt.dom.client.Document;
|
||||||
|
import com.google.gwt.dom.client.Element;
|
||||||
|
import com.google.gwt.dom.client.Style;
|
||||||
|
import com.google.gwt.dom.client.TableCellElement;
|
||||||
|
import com.google.gwt.user.client.DOM;
|
||||||
|
import com.google.gwt.user.client.ui.Panel;
|
||||||
|
import com.google.gwt.user.client.ui.Widget;
|
||||||
|
import com.haulmont.cuba.web.toolkit.ui.client.Tools;
|
||||||
|
import com.vaadin.client.BrowserInfo;
|
||||||
|
import com.vaadin.client.UIDL;
|
||||||
|
import com.vaadin.client.ui.VScrollTable;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special aggregation row for {@link com.haulmont.cuba.web.toolkit.ui.client.table.CubaScrollTableWidget} and
|
||||||
|
* {@link com.haulmont.cuba.web.toolkit.ui.client.treetable.CubaTreeTableWidget}
|
||||||
|
*
|
||||||
|
* @author artamonov
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class TableAggregationRow extends Panel {
|
||||||
|
|
||||||
|
protected boolean initialized = false;
|
||||||
|
|
||||||
|
protected char[] aligns;
|
||||||
|
protected Element tr;
|
||||||
|
|
||||||
|
protected AggregatableTable tableWidget;
|
||||||
|
|
||||||
|
public TableAggregationRow(AggregatableTable tableWidget) {
|
||||||
|
this.tableWidget = tableWidget;
|
||||||
|
|
||||||
|
setElement(Document.get().createDivElement());
|
||||||
|
|
||||||
|
getElement().setClassName(tableWidget.getStylePrimaryName() + "-arow");
|
||||||
|
getElement().getStyle().setOverflow(Style.Overflow.HIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Widget> iterator() {
|
||||||
|
return new LinkedList<Widget>().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Widget child) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateFromUIDL(UIDL uidl) {
|
||||||
|
if (getElement().hasChildNodes()) {
|
||||||
|
getElement().removeAllChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
aligns = tableWidget.getHead().getColumnAlignments();
|
||||||
|
|
||||||
|
if (uidl.getChildCount() > 0) {
|
||||||
|
final Element table = DOM.createTable();
|
||||||
|
table.setAttribute("cellpadding", "0");
|
||||||
|
table.setAttribute("cellspacing", "0");
|
||||||
|
|
||||||
|
final Element tBody = DOM.createTBody();
|
||||||
|
tr = DOM.createTR();
|
||||||
|
|
||||||
|
tr.setClassName(tableWidget.getStylePrimaryName() + "-arow-row");
|
||||||
|
|
||||||
|
addCellsFromUIDL(uidl);
|
||||||
|
|
||||||
|
tBody.appendChild(tr);
|
||||||
|
table.appendChild(tBody);
|
||||||
|
getElement().appendChild(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
initialized = getElement().hasChildNodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addCellsFromUIDL(UIDL uidl) {
|
||||||
|
int colIndex = 0;
|
||||||
|
final Iterator cells = uidl.getChildIterator();
|
||||||
|
while (cells.hasNext() && colIndex < tableWidget.getVisibleColOrder().length) {
|
||||||
|
String columnId = tableWidget.getVisibleColOrder()[colIndex];
|
||||||
|
|
||||||
|
if (addSpecificCell(columnId, colIndex)) {
|
||||||
|
colIndex++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object cell = cells.next();
|
||||||
|
|
||||||
|
String style = "";
|
||||||
|
if (uidl.hasAttribute("style-" + columnId)) {
|
||||||
|
style = uidl.getStringAttribute("style-" + columnId);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean sorted = tableWidget.getHead().getHeaderCell(colIndex).isSorted();
|
||||||
|
|
||||||
|
if (cell instanceof String) {
|
||||||
|
addCell((String) cell, aligns[colIndex], style, sorted);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String colKey = tableWidget.getColKeyByIndex(colIndex);
|
||||||
|
int colWidth;
|
||||||
|
if ((colWidth = tableWidget.getColWidth(colKey)) > -1) {
|
||||||
|
tableWidget.setColWidth(colIndex, colWidth, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
colIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extension point for GroupTable divider column
|
||||||
|
protected boolean addSpecificCell(String columnId, int colIndex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addCell(String text, char align, String style, boolean sorted) {
|
||||||
|
final TableCellElement td = DOM.createTD().cast();
|
||||||
|
|
||||||
|
final Element container = DOM.createDiv();
|
||||||
|
container.setClassName(tableWidget.getStylePrimaryName() + "-cell-wrapper");
|
||||||
|
|
||||||
|
td.setClassName(tableWidget.getStylePrimaryName() + "-cell-content");
|
||||||
|
|
||||||
|
if (style != null && !style.equals("")) {
|
||||||
|
td.addClassName(tableWidget.getStylePrimaryName() + "-cell-content-" + style);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sorted) {
|
||||||
|
td.addClassName(tableWidget.getStylePrimaryName() + "-cell-content-sorted");
|
||||||
|
}
|
||||||
|
|
||||||
|
container.setInnerText(text);
|
||||||
|
|
||||||
|
setAlign(align, container);
|
||||||
|
|
||||||
|
td.appendChild(container);
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
Tools.textSelectionEnable(td, tableWidget.isTextSelectionEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setAlign(char align, final Element container) {
|
||||||
|
// CAUTION: copied from VScrollTableRow
|
||||||
|
switch (align) {
|
||||||
|
case VScrollTable.ALIGN_CENTER:
|
||||||
|
container.getStyle().setProperty("textAlign", "center");
|
||||||
|
break;
|
||||||
|
case VScrollTable.ALIGN_LEFT:
|
||||||
|
container.getStyle().setProperty("textAlign", "left");
|
||||||
|
break;
|
||||||
|
case VScrollTable.ALIGN_RIGHT:
|
||||||
|
default:
|
||||||
|
container.getStyle().setProperty("textAlign", "right");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCellWidth(int cellIx, int width) {
|
||||||
|
// CAUTION: copied from VScrollTableRow with small changes
|
||||||
|
final Element cell = DOM.getChild(tr, cellIx);
|
||||||
|
Style wrapperStyle = cell.getFirstChildElement().getStyle();
|
||||||
|
int wrapperWidth = width;
|
||||||
|
if (BrowserInfo.get().isWebkit()
|
||||||
|
|| BrowserInfo.get().isOpera10()) {
|
||||||
|
/*
|
||||||
|
* Some versions of Webkit and Opera ignore the width
|
||||||
|
* definition of zero width table cells. Instead, use 1px
|
||||||
|
* and compensate with a negative margin.
|
||||||
|
*/
|
||||||
|
if (width == 0) {
|
||||||
|
wrapperWidth = 1;
|
||||||
|
wrapperStyle.setMarginRight(-1, Style.Unit.PX);
|
||||||
|
} else {
|
||||||
|
wrapperStyle.clearMarginRight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wrapperStyle.setPropertyPx("width", wrapperWidth);
|
||||||
|
cell.getStyle().setPropertyPx("width", width);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInitialized() {
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHorizontalScrollPosition(int scrollLeft) {
|
||||||
|
getElement().setPropertyInt("scrollLeft", scrollLeft);
|
||||||
|
}
|
||||||
|
}
|
@ -11,13 +11,16 @@ import com.google.gwt.dom.client.TableCellElement;
|
|||||||
import com.google.gwt.user.client.DOM;
|
import com.google.gwt.user.client.DOM;
|
||||||
import com.google.gwt.user.client.Event;
|
import com.google.gwt.user.client.Event;
|
||||||
import com.haulmont.cuba.web.toolkit.ui.client.Tools;
|
import com.haulmont.cuba.web.toolkit.ui.client.Tools;
|
||||||
|
import com.haulmont.cuba.web.toolkit.ui.client.aggregation.TableAggregationRow;
|
||||||
import com.haulmont.cuba.web.toolkit.ui.client.table.CubaScrollTableWidget;
|
import com.haulmont.cuba.web.toolkit.ui.client.table.CubaScrollTableWidget;
|
||||||
import com.vaadin.client.BrowserInfo;
|
import com.vaadin.client.BrowserInfo;
|
||||||
|
import com.vaadin.client.ComponentConnector;
|
||||||
import com.vaadin.client.UIDL;
|
import com.vaadin.client.UIDL;
|
||||||
import com.vaadin.client.Util;
|
import com.vaadin.client.Util;
|
||||||
import com.vaadin.shared.ui.table.TableConstants;
|
import com.vaadin.shared.ui.table.TableConstants;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -245,6 +248,21 @@ public class CubaGroupTableWidget extends CubaScrollTableWidget {
|
|||||||
return new GroupTableFooter();
|
return new GroupTableFooter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TableAggregationRow createAggregationRow() {
|
||||||
|
return new TableAggregationRow(getAggregatableTable()) {
|
||||||
|
@Override
|
||||||
|
protected boolean addSpecificCell(String columnId, int colIndex) {
|
||||||
|
if (GROUP_DIVIDER_COLUMN_KEY.equals(columnId)) {
|
||||||
|
addCell("", aligns[colIndex], "", false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.addSpecificCell(columnId, colIndex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
protected class GroupTableHead extends CubaScrollTableHead {
|
protected class GroupTableHead extends CubaScrollTableHead {
|
||||||
public GroupTableHead() {
|
public GroupTableHead() {
|
||||||
availableCells.put(GROUP_DIVIDER_COLUMN_KEY, new GroupDividerHeaderCell());
|
availableCells.put(GROUP_DIVIDER_COLUMN_KEY, new GroupDividerHeaderCell());
|
||||||
@ -300,7 +318,7 @@ public class CubaGroupTableWidget extends CubaScrollTableWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected class CubaGroupTableRow extends CubaScrollTableRow {
|
protected class CubaGroupTableRow extends CubaScrollTableRow {
|
||||||
private TableCellElement groupDividerCell;
|
protected TableCellElement groupDividerCell;
|
||||||
|
|
||||||
public CubaGroupTableRow(UIDL uidl, char[] aligns) {
|
public CubaGroupTableRow(UIDL uidl, char[] aligns) {
|
||||||
super(uidl, aligns);
|
super(uidl, aligns);
|
||||||
@ -337,6 +355,9 @@ public class CubaGroupTableWidget extends CubaScrollTableWidget {
|
|||||||
private String groupKey;
|
private String groupKey;
|
||||||
private boolean expanded;
|
private boolean expanded;
|
||||||
|
|
||||||
|
private Integer colSpan;
|
||||||
|
private Boolean hasCells;
|
||||||
|
|
||||||
public CubaGroupTableGroupRow(UIDL uidl, char[] aligns) {
|
public CubaGroupTableGroupRow(UIDL uidl, char[] aligns) {
|
||||||
super(uidl, aligns);
|
super(uidl, aligns);
|
||||||
}
|
}
|
||||||
@ -355,7 +376,7 @@ public class CubaGroupTableWidget extends CubaScrollTableWidget {
|
|||||||
|
|
||||||
protected void setWidthForSpannedCell() {
|
protected void setWidthForSpannedCell() {
|
||||||
int spanWidth = 0;
|
int spanWidth = 0;
|
||||||
for (int ix = groupColIndex; ix < tHead.getVisibleCellCount(); ix++) {
|
for (int ix = groupColIndex; ix < colSpan; ix++) {
|
||||||
spanWidth += tHead.getHeaderCell(ix).getOffsetWidth();
|
spanWidth += tHead.getHeaderCell(ix).getOffsetWidth();
|
||||||
}
|
}
|
||||||
Util.setWidthExcludingPaddingAndBorder((Element) getElement().getChild(groupColIndex),
|
Util.setWidthExcludingPaddingAndBorder((Element) getElement().getChild(groupColIndex),
|
||||||
@ -392,6 +413,51 @@ public class CubaGroupTableWidget extends CubaScrollTableWidget {
|
|||||||
|
|
||||||
addGroupCell(uidl.getStringAttribute("groupCaption"));
|
addGroupCell(uidl.getStringAttribute("groupCaption"));
|
||||||
|
|
||||||
|
if (uidl.getChildCount() > 0) {
|
||||||
|
Iterator cells = uidl.getChildIterator();
|
||||||
|
while (colIndex < visibleColOrder.length) {
|
||||||
|
String columnId = visibleColOrder[colIndex];
|
||||||
|
|
||||||
|
if (GROUP_DIVIDER_COLUMN_KEY.equals(columnId)) { //paint cell for columns group divider
|
||||||
|
addDividerCell(aligns[colIndex]);
|
||||||
|
} else if (cells.hasNext()) {
|
||||||
|
final Object cell = cells.next();
|
||||||
|
|
||||||
|
String style = "";
|
||||||
|
if (uidl.hasAttribute("style-" + columnId)) {
|
||||||
|
style = uidl.getStringAttribute("style-" + columnId);
|
||||||
|
}
|
||||||
|
|
||||||
|
String description = null;
|
||||||
|
if (uidl.hasAttribute("descr-" + columnId)) {
|
||||||
|
description = uidl.getStringAttribute("descr-"
|
||||||
|
+ columnId);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean sorted = tHead.getHeaderCell(colIndex).isSorted();
|
||||||
|
if (cell instanceof String) {
|
||||||
|
addCell(uidl, cell.toString(), aligns[colIndex], style,
|
||||||
|
isRenderHtmlInCells(), sorted, description);
|
||||||
|
} else {
|
||||||
|
final ComponentConnector cellContent = client
|
||||||
|
.getPaintable((UIDL) cell);
|
||||||
|
|
||||||
|
addCell(uidl, cellContent.getWidget(), aligns[colIndex],
|
||||||
|
style, sorted, description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
colIndex++;
|
||||||
|
}
|
||||||
|
colSpan = 0;
|
||||||
|
hasCells = true;
|
||||||
|
} else {
|
||||||
|
TableCellElement td = getElement().getLastChild().cast();
|
||||||
|
colSpan = visibleColOrder.length - groupColIndex;
|
||||||
|
td.setColSpan(colSpan);
|
||||||
|
hasCells = false;
|
||||||
|
}
|
||||||
|
|
||||||
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
|
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
@ -402,7 +468,7 @@ public class CubaGroupTableWidget extends CubaScrollTableWidget {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setCellWidth(int cellIx, int width) {
|
protected void setCellWidth(int cellIx, int width) {
|
||||||
if (groupColIndex > cellIx) {
|
if (hasCells || groupColIndex > cellIx) {
|
||||||
super.setCellWidth(cellIx, width);
|
super.setCellWidth(cellIx, width);
|
||||||
} else {
|
} else {
|
||||||
setWidthForSpannedCell();
|
setWidthForSpannedCell();
|
||||||
@ -413,7 +479,6 @@ public class CubaGroupTableWidget extends CubaScrollTableWidget {
|
|||||||
// String only content is optimized by not using Label widget
|
// String only content is optimized by not using Label widget
|
||||||
Element tdElement = DOM.createTD();
|
Element tdElement = DOM.createTD();
|
||||||
final TableCellElement td = tdElement.cast();
|
final TableCellElement td = tdElement.cast();
|
||||||
td.setColSpan(visibleColOrder.length - groupColIndex);
|
|
||||||
initCellWithText(text, ALIGN_LEFT, "", false, true, null, td);
|
initCellWithText(text, ALIGN_LEFT, "", false, true, null, td);
|
||||||
|
|
||||||
// Enchance DOM for table cell
|
// Enchance DOM for table cell
|
||||||
|
@ -122,4 +122,12 @@ public class CubaScrollTableConnector extends TableConnector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateAdditionalRowData(UIDL uidl) {
|
||||||
|
UIDL arow = uidl.getChildByTagName("arow");
|
||||||
|
if (arow != null) {
|
||||||
|
getWidget().updateAggregationRow(arow);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -6,17 +6,19 @@
|
|||||||
package com.haulmont.cuba.web.toolkit.ui.client.table;
|
package com.haulmont.cuba.web.toolkit.ui.client.table;
|
||||||
|
|
||||||
import com.google.gwt.core.client.GWT;
|
import com.google.gwt.core.client.GWT;
|
||||||
|
import com.google.gwt.dom.client.Element;
|
||||||
import com.google.gwt.dom.client.Style;
|
import com.google.gwt.dom.client.Style;
|
||||||
import com.google.gwt.dom.client.TableCellElement;
|
import com.google.gwt.dom.client.TableCellElement;
|
||||||
import com.google.gwt.event.dom.client.*;
|
import com.google.gwt.event.dom.client.*;
|
||||||
import com.google.gwt.event.logical.shared.CloseEvent;
|
import com.google.gwt.event.logical.shared.CloseEvent;
|
||||||
import com.google.gwt.event.logical.shared.CloseHandler;
|
import com.google.gwt.event.logical.shared.CloseHandler;
|
||||||
import com.google.gwt.user.client.DOM;
|
import com.google.gwt.user.client.DOM;
|
||||||
import com.google.gwt.dom.client.Element;
|
|
||||||
import com.google.gwt.user.client.Event;
|
import com.google.gwt.user.client.Event;
|
||||||
import com.google.gwt.user.client.Window;
|
import com.google.gwt.user.client.Window;
|
||||||
import com.google.gwt.user.client.ui.*;
|
import com.google.gwt.user.client.ui.*;
|
||||||
import com.haulmont.cuba.web.toolkit.ui.client.Tools;
|
import com.haulmont.cuba.web.toolkit.ui.client.Tools;
|
||||||
|
import com.haulmont.cuba.web.toolkit.ui.client.aggregation.AggregatableTable;
|
||||||
|
import com.haulmont.cuba.web.toolkit.ui.client.aggregation.TableAggregationRow;
|
||||||
import com.haulmont.cuba.web.toolkit.ui.client.logging.ClientLogger;
|
import com.haulmont.cuba.web.toolkit.ui.client.logging.ClientLogger;
|
||||||
import com.haulmont.cuba.web.toolkit.ui.client.logging.ClientLoggerFactory;
|
import com.haulmont.cuba.web.toolkit.ui.client.logging.ClientLoggerFactory;
|
||||||
import com.vaadin.client.Focusable;
|
import com.vaadin.client.Focusable;
|
||||||
@ -47,6 +49,8 @@ public class CubaScrollTableWidget extends VScrollTable implements ShortcutActio
|
|||||||
|
|
||||||
protected boolean allowMultiStringCells = false;
|
protected boolean allowMultiStringCells = false;
|
||||||
|
|
||||||
|
protected TableAggregationRow aggregationRow;
|
||||||
|
|
||||||
protected CubaScrollTableWidget() {
|
protected CubaScrollTableWidget() {
|
||||||
// handle shortcuts
|
// handle shortcuts
|
||||||
DOM.sinkEvents(getElement(), Event.ONKEYDOWN);
|
DOM.sinkEvents(getElement(), Event.ONKEYDOWN);
|
||||||
@ -150,6 +154,23 @@ public class CubaScrollTableWidget extends VScrollTable implements ShortcutActio
|
|||||||
return (int) Math.round(totalRows * scrollBody.getRowHeight(true));
|
return (int) Math.round(totalRows * scrollBody.getRowHeight(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setColWidth(int colIndex, int w, boolean isDefinedWidth) {
|
||||||
|
super.setColWidth(colIndex, w, isDefinedWidth);
|
||||||
|
|
||||||
|
if (aggregationRow != null && aggregationRow.isInitialized()) {
|
||||||
|
aggregationRow.setCellWidth(colIndex, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAdditionalRowsHeight() {
|
||||||
|
if (aggregationRow != null) {
|
||||||
|
return aggregationRow.getOffsetHeight();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TableHead createTableHead() {
|
protected TableHead createTableHead() {
|
||||||
return new CubaScrollTableHead();
|
return new CubaScrollTableHead();
|
||||||
@ -172,6 +193,71 @@ public class CubaScrollTableWidget extends VScrollTable implements ShortcutActio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateAggregationRow(UIDL uidl) {
|
||||||
|
if (aggregationRow == null) {
|
||||||
|
aggregationRow = createAggregationRow();
|
||||||
|
insert(aggregationRow, getWidgetIndex(scrollBodyPanel));
|
||||||
|
}
|
||||||
|
aggregationRow.updateFromUIDL(uidl);
|
||||||
|
aggregationRow.setHorizontalScrollPosition(scrollLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TableAggregationRow createAggregationRow() {
|
||||||
|
return new TableAggregationRow(getAggregatableTable());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AggregatableTable getAggregatableTable() {
|
||||||
|
return new AggregatableTable() {
|
||||||
|
@Override
|
||||||
|
public TableHead getHead() {
|
||||||
|
return tHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStylePrimaryName() {
|
||||||
|
return CubaScrollTableWidget.this.getStylePrimaryName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getVisibleColOrder() {
|
||||||
|
return visibleColOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColKeyByIndex(int index) {
|
||||||
|
return CubaScrollTableWidget.this.getColKeyByIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColWidth(String colKey) {
|
||||||
|
return CubaScrollTableWidget.this.getColWidth(colKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColWidth(int colIndex, int w, boolean isDefinedWidth) {
|
||||||
|
CubaScrollTableWidget.this.setColWidth(colIndex, w, isDefinedWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTextSelectionEnabled() {
|
||||||
|
return textSelectionEnabled;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScroll(ScrollEvent event) {
|
||||||
|
if (isLazyScrollerActive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onScroll(event);
|
||||||
|
|
||||||
|
if (aggregationRow != null) {
|
||||||
|
aggregationRow.setHorizontalScrollPosition(scrollLeft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected class CubaScrollTableHead extends TableHead {
|
protected class CubaScrollTableHead extends TableHead {
|
||||||
|
|
||||||
protected final SimplePanel presentationsEditIcon = GWT.create(SimplePanel.class);
|
protected final SimplePanel presentationsEditIcon = GWT.create(SimplePanel.class);
|
||||||
|
@ -125,4 +125,12 @@ public class CubaTreeTableConnector extends TreeTableConnector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateAdditionalRowData(UIDL uidl) {
|
||||||
|
UIDL arow = uidl.getChildByTagName("arow");
|
||||||
|
if (arow != null) {
|
||||||
|
getWidget().updateAggregationRow(arow);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -17,6 +17,8 @@ import com.google.gwt.user.client.Event;
|
|||||||
import com.google.gwt.user.client.Window;
|
import com.google.gwt.user.client.Window;
|
||||||
import com.google.gwt.user.client.ui.*;
|
import com.google.gwt.user.client.ui.*;
|
||||||
import com.haulmont.cuba.web.toolkit.ui.client.Tools;
|
import com.haulmont.cuba.web.toolkit.ui.client.Tools;
|
||||||
|
import com.haulmont.cuba.web.toolkit.ui.client.aggregation.AggregatableTable;
|
||||||
|
import com.haulmont.cuba.web.toolkit.ui.client.aggregation.TableAggregationRow;
|
||||||
import com.haulmont.cuba.web.toolkit.ui.client.logging.ClientLogger;
|
import com.haulmont.cuba.web.toolkit.ui.client.logging.ClientLogger;
|
||||||
import com.haulmont.cuba.web.toolkit.ui.client.logging.ClientLoggerFactory;
|
import com.haulmont.cuba.web.toolkit.ui.client.logging.ClientLoggerFactory;
|
||||||
import com.vaadin.client.UIDL;
|
import com.vaadin.client.UIDL;
|
||||||
@ -45,6 +47,8 @@ public class CubaTreeTableWidget extends VTreeTable implements ShortcutActionHan
|
|||||||
protected ClientLogger logger = ClientLoggerFactory.getLogger("CubaTreeTableWidget");
|
protected ClientLogger logger = ClientLoggerFactory.getLogger("CubaTreeTableWidget");
|
||||||
protected boolean allowMultiStringCells = false;
|
protected boolean allowMultiStringCells = false;
|
||||||
|
|
||||||
|
protected TableAggregationRow aggregationRow;
|
||||||
|
|
||||||
public CubaTreeTableWidget() {
|
public CubaTreeTableWidget() {
|
||||||
hideColumnControlAfterClick = false;
|
hideColumnControlAfterClick = false;
|
||||||
}
|
}
|
||||||
@ -147,6 +151,23 @@ public class CubaTreeTableWidget extends VTreeTable implements ShortcutActionHan
|
|||||||
return currentRow == focusedRow && (!focusedRow.isSelected());
|
return currentRow == focusedRow && (!focusedRow.isSelected());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setColWidth(int colIndex, int w, boolean isDefinedWidth) {
|
||||||
|
super.setColWidth(colIndex, w, isDefinedWidth);
|
||||||
|
|
||||||
|
if (aggregationRow != null && aggregationRow.isInitialized()) {
|
||||||
|
aggregationRow.setCellWidth(colIndex, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAdditionalRowsHeight() {
|
||||||
|
if (aggregationRow != null) {
|
||||||
|
return aggregationRow.getOffsetHeight();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TableHead createTableHead() {
|
protected TableHead createTableHead() {
|
||||||
return new CubaTreeTableTableHead();
|
return new CubaTreeTableTableHead();
|
||||||
@ -168,6 +189,67 @@ public class CubaTreeTableWidget extends VTreeTable implements ShortcutActionHan
|
|||||||
Tools.textSelectionEnable(scrollBody.getElement(), textSelectionEnabled);
|
Tools.textSelectionEnable(scrollBody.getElement(), textSelectionEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateAggregationRow(UIDL uidl) {
|
||||||
|
if (aggregationRow == null) {
|
||||||
|
aggregationRow = createAggregationRow();
|
||||||
|
insert(aggregationRow, getWidgetIndex(scrollBodyPanel));
|
||||||
|
}
|
||||||
|
aggregationRow.updateFromUIDL(uidl);
|
||||||
|
aggregationRow.setHorizontalScrollPosition(scrollLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TableAggregationRow createAggregationRow() {
|
||||||
|
return new TableAggregationRow(new AggregatableTable() {
|
||||||
|
@Override
|
||||||
|
public TableHead getHead() {
|
||||||
|
return tHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStylePrimaryName() {
|
||||||
|
return CubaTreeTableWidget.this.getStylePrimaryName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getVisibleColOrder() {
|
||||||
|
return visibleColOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColKeyByIndex(int index) {
|
||||||
|
return CubaTreeTableWidget.this.getColKeyByIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColWidth(String colKey) {
|
||||||
|
return CubaTreeTableWidget.this.getColWidth(colKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColWidth(int colIndex, int w, boolean isDefinedWidth) {
|
||||||
|
CubaTreeTableWidget.this.setColWidth(colIndex, w, isDefinedWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTextSelectionEnabled() {
|
||||||
|
return textSelectionEnabled;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScroll(ScrollEvent event) {
|
||||||
|
if (isLazyScrollerActive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onScroll(event);
|
||||||
|
|
||||||
|
if (aggregationRow != null) {
|
||||||
|
aggregationRow.setHorizontalScrollPosition(scrollLeft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected class CubaTreeTableTableHead extends TableHead {
|
protected class CubaTreeTableTableHead extends TableHead {
|
||||||
|
|
||||||
protected final SimplePanel presentationsEditIcon = GWT.create(SimplePanel.class);
|
protected final SimplePanel presentationsEditIcon = GWT.create(SimplePanel.class);
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
package com.haulmont.cuba.web.gui.components;
|
package com.haulmont.cuba.web.gui.components;
|
||||||
|
|
||||||
import com.haulmont.bali.util.Dom4j;
|
import com.haulmont.bali.util.Dom4j;
|
||||||
|
import com.haulmont.chile.core.datatypes.Datatype;
|
||||||
|
import com.haulmont.chile.core.datatypes.Datatypes;
|
||||||
import com.haulmont.chile.core.model.Instance;
|
import com.haulmont.chile.core.model.Instance;
|
||||||
import com.haulmont.chile.core.model.MetaClass;
|
import com.haulmont.chile.core.model.MetaClass;
|
||||||
import com.haulmont.chile.core.model.MetaProperty;
|
import com.haulmont.chile.core.model.MetaProperty;
|
||||||
@ -17,6 +19,7 @@ import com.haulmont.cuba.gui.WindowManager;
|
|||||||
import com.haulmont.cuba.gui.components.*;
|
import com.haulmont.cuba.gui.components.*;
|
||||||
import com.haulmont.cuba.gui.components.CheckBox;
|
import com.haulmont.cuba.gui.components.CheckBox;
|
||||||
import com.haulmont.cuba.gui.components.Field;
|
import com.haulmont.cuba.gui.components.Field;
|
||||||
|
import com.haulmont.cuba.gui.components.Formatter;
|
||||||
import com.haulmont.cuba.gui.components.Table;
|
import com.haulmont.cuba.gui.components.Table;
|
||||||
import com.haulmont.cuba.gui.components.Window;
|
import com.haulmont.cuba.gui.components.Window;
|
||||||
import com.haulmont.cuba.gui.data.*;
|
import com.haulmont.cuba.gui.data.*;
|
||||||
@ -99,7 +102,7 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
|
|
||||||
protected RowsCount rowsCount;
|
protected RowsCount rowsCount;
|
||||||
|
|
||||||
protected Map<Table.Column, Object> aggregationCells = null;
|
protected Map<Table.Column, String> aggregationCells = null;
|
||||||
|
|
||||||
protected boolean usePresentations;
|
protected boolean usePresentations;
|
||||||
|
|
||||||
@ -111,10 +114,6 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
// Map column id to Printable representation
|
// Map column id to Printable representation
|
||||||
protected Map<String, Printable> printables = new HashMap<>();
|
protected Map<String, Printable> printables = new HashMap<>();
|
||||||
|
|
||||||
// disabled for #PL-2035
|
|
||||||
// Disable listener that points component value to follow the ds item.
|
|
||||||
// protected boolean disableItemListener = false;
|
|
||||||
|
|
||||||
protected static final int MAX_TEXT_LENGTH_GAP = 10;
|
protected static final int MAX_TEXT_LENGTH_GAP = 10;
|
||||||
|
|
||||||
protected Security security = AppBeans.get(Security.class);
|
protected Security security = AppBeans.get(Security.class);
|
||||||
@ -156,8 +155,9 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
columns.remove(column.getId());
|
columns.remove(column.getId());
|
||||||
columnsOrder.remove(column);
|
columnsOrder.remove(column);
|
||||||
|
|
||||||
// todo artamonov remove after fix #VAADIN-12980
|
if (!(component.getContainerDataSource() instanceof com.vaadin.data.Container.ItemSetChangeNotifier)) {
|
||||||
component.refreshRowCache();
|
component.refreshRowCache();
|
||||||
|
}
|
||||||
column.setOwner(null);
|
column.setOwner(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,28 +398,22 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAggregatable() {
|
public boolean isAggregatable() {
|
||||||
return false;
|
return component.isAggregatable();
|
||||||
// vaadin7
|
|
||||||
// return component.isAggregatable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAggregatable(boolean aggregatable) {
|
public void setAggregatable(boolean aggregatable) {
|
||||||
// vaadin7
|
component.setAggregatable(aggregatable);
|
||||||
// component.setAggregatable(aggregatable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setShowTotalAggregation(boolean showAggregation) {
|
public void setShowTotalAggregation(boolean showAggregation) {
|
||||||
// vaadin7
|
component.setShowTotalAggregation(showAggregation);
|
||||||
// component.setShowTotalAggregation(showAggregation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isShowTotalAggregation() {
|
public boolean isShowTotalAggregation() {
|
||||||
return false;
|
return component.isShowTotalAggregation();
|
||||||
// vaadin7
|
|
||||||
// return component.isShowTotalAggregation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -462,8 +456,6 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
if (datasource == null) return;
|
if (datasource == null) return;
|
||||||
|
|
||||||
final Set<Entity> selected = getSelected();
|
final Set<Entity> selected = getSelected();
|
||||||
// disabled for #PL-2035
|
|
||||||
// disableItemListener = true;
|
|
||||||
if (selected.isEmpty()) {
|
if (selected.isEmpty()) {
|
||||||
datasource.setItem(null);
|
datasource.setItem(null);
|
||||||
} else {
|
} else {
|
||||||
@ -472,8 +464,6 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
datasource.setItem(null);
|
datasource.setItem(null);
|
||||||
datasource.setItem(selected.iterator().next());
|
datasource.setItem(selected.iterator().next());
|
||||||
}
|
}
|
||||||
// disabled for #PL-2035
|
|
||||||
// disableItemListener = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -718,11 +708,10 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
component.setColumnCollapsed(column.getId(), true);
|
component.setColumnCollapsed(column.getId(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// vaadin7
|
if (column.getAggregation() != null && isAggregatable()) {
|
||||||
// if (column.getAggregation() != null && isAggregatable()) {
|
component.addContainerPropertyAggregation(column.getId(),
|
||||||
// component.addContainerPropertyAggregation(column.getId(),
|
WebComponentsHelper.convertAggregationType(column.getAggregation().getType()));
|
||||||
// WebComponentsHelper.convertAggregationType(column.getAggregation().getType()));
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,14 +728,14 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// vaadin7
|
if (aggregationCells != null) {
|
||||||
// if (aggregationCells != null) {
|
getDatasource().addListener(createAggregationDatasourceListener());
|
||||||
// getDatasource().addListener(createAggregationDatasourceListener());
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
setVisibleColumns(getPropertyColumns());
|
setVisibleColumns(getPropertyColumns());
|
||||||
|
|
||||||
if (AppBeans.get(UserSessionSource.class).getUserSession().isSpecificPermitted(ShowInfoAction.ACTION_PERMISSION)) {
|
Security security = AppBeans.get(Security.NAME);
|
||||||
|
if (security.isSpecificPermitted(ShowInfoAction.ACTION_PERMISSION)) {
|
||||||
ShowInfoAction action = (ShowInfoAction) getAction(ShowInfoAction.ACTION_ID);
|
ShowInfoAction action = (ShowInfoAction) getAction(ShowInfoAction.ACTION_ID);
|
||||||
if (action == null) {
|
if (action == null) {
|
||||||
action = new ShowInfoAction();
|
action = new ShowInfoAction();
|
||||||
@ -755,12 +744,15 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
action.setDatasource(datasource);
|
action.setDatasource(datasource);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rowsCount != null)
|
if (rowsCount != null) {
|
||||||
rowsCount.setDatasource(datasource);
|
rowsCount.setDatasource(datasource);
|
||||||
|
}
|
||||||
|
|
||||||
datasource.addListener(new CollectionDsActionsNotifier(this) {
|
datasource.addListener(new CollectionDsActionsNotifier(this) {
|
||||||
@Override
|
@Override
|
||||||
public void collectionChanged(CollectionDatasource ds, Operation operation, List<Entity> items) {
|
public void collectionChanged(CollectionDatasource ds, Operation operation, List<Entity> items) {
|
||||||
|
super.collectionChanged(ds, operation, items);
|
||||||
|
|
||||||
// #PL-2035, reload selection from ds
|
// #PL-2035, reload selection from ds
|
||||||
Set<Object> selectedItemIds = getSelectedItemIds();
|
Set<Object> selectedItemIds = getSelectedItemIds();
|
||||||
if (selectedItemIds == null) {
|
if (selectedItemIds == null) {
|
||||||
@ -786,18 +778,6 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// disabled for #PL-2035
|
|
||||||
// noinspection unchecked
|
|
||||||
// datasource.addListener(new CollectionDsActionsNotifier(this) {
|
|
||||||
// @Override
|
|
||||||
// public void itemChanged(Datasource ds, Entity prevItem, Entity item) {
|
|
||||||
// super.itemChanged(ds, prevItem, item);
|
|
||||||
// if (!disableItemListener && !getSelected().contains(item)) {
|
|
||||||
// setSelected(item);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
for (Action action : getActions()) {
|
for (Action action : getActions()) {
|
||||||
action.refreshState();
|
action.refreshState();
|
||||||
}
|
}
|
||||||
@ -1339,18 +1319,45 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<Object, Object> __handleAggregationResults(AggregationContainer.Context context, Map<Object, Object> results) {
|
protected Map<Object, Object> __handleAggregationResults(AggregationContainer.Context context,
|
||||||
|
Map<Object, Object> results) {
|
||||||
for (final Map.Entry<Object, Object> entry : results.entrySet()) {
|
for (final Map.Entry<Object, Object> entry : results.entrySet()) {
|
||||||
final Table.Column column = columns.get(entry.getKey());
|
final Table.Column column = columns.get(entry.getKey());
|
||||||
com.vaadin.ui.Label cell;
|
if (aggregationCells.get(column) != null) {
|
||||||
if ((cell = (com.vaadin.ui.Label) aggregationCells.get(column)) != null) {
|
Object value = entry.getValue();
|
||||||
WebComponentsHelper.setLabelText(cell, entry.getValue(), column.getFormatter());
|
String cellText = getFormattedValue(column, value);
|
||||||
entry.setValue(cell);
|
entry.setValue(cellText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getFormattedValue(Column column, Object value) {
|
||||||
|
String cellText;
|
||||||
|
if (value == null) {
|
||||||
|
cellText = "";
|
||||||
|
} else {
|
||||||
|
if (value instanceof String) {
|
||||||
|
cellText = (String) value;
|
||||||
|
} else {
|
||||||
|
Formatter formatter = column.getFormatter();
|
||||||
|
if (formatter != null) {
|
||||||
|
cellText = formatter.format(value);
|
||||||
|
} else {
|
||||||
|
Datatype datatype = Datatypes.get(value.getClass());
|
||||||
|
if (datatype != null) {
|
||||||
|
UserSessionSource sessionSource = AppBeans.get(UserSessionSource.NAME);
|
||||||
|
|
||||||
|
cellText = datatype.format(value, sessionSource.getLocale());
|
||||||
|
} else {
|
||||||
|
cellText = value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cellText;
|
||||||
|
}
|
||||||
|
|
||||||
protected class TablePropertyWrapper extends PropertyWrapper {
|
protected class TablePropertyWrapper extends PropertyWrapper {
|
||||||
|
|
||||||
private ValueChangeListener calcListener;
|
private ValueChangeListener calcListener;
|
||||||
@ -1622,14 +1629,7 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
if (aggregationCells == null) {
|
if (aggregationCells == null) {
|
||||||
aggregationCells = new HashMap<>();
|
aggregationCells = new HashMap<>();
|
||||||
}
|
}
|
||||||
aggregationCells.put(column, createAggregationCell());
|
aggregationCells.put(column, "");
|
||||||
}
|
|
||||||
|
|
||||||
protected com.vaadin.ui.Label createAggregationCell() {
|
|
||||||
com.vaadin.ui.Label label = new com.vaadin.ui.Label();
|
|
||||||
label.setWidth("-1px");
|
|
||||||
label.setParent(component);
|
|
||||||
return label;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CollectionDatasourceListener createAggregationDatasourceListener() {
|
protected CollectionDatasourceListener createAggregationDatasourceListener() {
|
||||||
@ -1640,9 +1640,8 @@ public abstract class WebAbstractTable<T extends com.vaadin.ui.Table & CubaEnhan
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void valueChanged(Entity source, String property, Object prevValue, Object value) {
|
public void valueChanged(Entity source, String property, Object prevValue, Object value) {
|
||||||
// vaadin7
|
final CollectionDatasource ds = WebAbstractTable.this.getDatasource();
|
||||||
// final CollectionDatasource ds = WebAbstractTable.this.getDatasource();
|
component.aggregate(new AggregationContainer.Context(ds.getItemIds()));
|
||||||
// component.aggregate(new AggregationContainer.Context(ds.getItemIds()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,30 +114,29 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable> implements G
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<Object, Object> __handleAggregationResults(AggregationContainer.Context context, Map<Object, Object> results) {
|
protected Map<Object, Object> __handleAggregationResults(AggregationContainer.Context context, Map<Object, Object> results) {
|
||||||
// vaadin7
|
if (context instanceof CubaGroupTable.GroupAggregationContext) {
|
||||||
// if (context instanceof com.haulmont.cuba.web.toolkit.ui.GroupTable.GroupAggregationContext) {
|
CubaGroupTable.GroupAggregationContext groupContext = (CubaGroupTable.GroupAggregationContext) context;
|
||||||
//
|
|
||||||
// com.haulmont.cuba.web.toolkit.ui.GroupTable.GroupAggregationContext groupContext =
|
for (final Map.Entry<Object, Object> entry : results.entrySet()) {
|
||||||
// (com.haulmont.cuba.web.toolkit.ui.GroupTable.GroupAggregationContext) context;
|
final Table.Column column = columns.get(entry.getKey());
|
||||||
//
|
GroupAggregationCells cells;
|
||||||
// for (final Map.Entry<Object, Object> entry : results.entrySet()) {
|
if ((cells = groupAggregationCells.get(column)) != null) {
|
||||||
// final Table.Column column = columns.get(entry.getKey());
|
String value = cells.getValue(groupContext.getGroupId());
|
||||||
// GroupAggregationCells cells;
|
String cellText = getFormattedValue(column, value);
|
||||||
// if ((cells = groupAggregationCells.get(column)) != null) {
|
entry.setValue(cellText);
|
||||||
// com.vaadin.ui.Label cell = cells.getCell(groupContext.getGroupId());
|
|
||||||
// if (cell != null) {
|
String groupValue = cells.getValue(groupContext.getGroupId());
|
||||||
// WebComponentsHelper.setLabelText(cell, entry.getValue(), column.getFormatter());
|
if (groupValue != null) {
|
||||||
// entry.setValue(cell);
|
String groupCellText = getFormattedValue(column, groupValue);
|
||||||
// }
|
entry.setValue(groupCellText);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
}
|
||||||
// return results;
|
|
||||||
//
|
return results;
|
||||||
// } else {
|
} else {
|
||||||
// return super.__handleAggregationResults(context, results);
|
return super.__handleAggregationResults(context, results);
|
||||||
// }
|
}
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -155,6 +154,7 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable> implements G
|
|||||||
component.expand(groupId);
|
component.expand(groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public void expandPath(Entity item) {
|
public void expandPath(Entity item) {
|
||||||
if (component.hasGroups()) {
|
if (component.hasGroups()) {
|
||||||
@ -214,8 +214,7 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable> implements G
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected class GroupTableDsWrapper extends SortableCollectionDsWrapper
|
protected class GroupTableDsWrapper extends SortableCollectionDsWrapper
|
||||||
implements GroupTableContainer,
|
implements GroupTableContainer, AggregationContainer {
|
||||||
AggregationContainer {
|
|
||||||
|
|
||||||
private boolean groupDatasource;
|
private boolean groupDatasource;
|
||||||
private List<Object> aggregationProperties = null;
|
private List<Object> aggregationProperties = null;
|
||||||
@ -324,7 +323,7 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable> implements G
|
|||||||
groupCells = new GroupAggregationCells();
|
groupCells = new GroupAggregationCells();
|
||||||
cells.put(column, groupCells);
|
cells.put(column, groupCells);
|
||||||
}
|
}
|
||||||
groupCells.addCell(groupId, createAggregationCell());
|
groupCells.addCell(groupId, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,13 +723,13 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable> implements G
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected class GroupAggregationCells {
|
protected class GroupAggregationCells {
|
||||||
private Map<Object, com.vaadin.ui.Label> cells = new HashMap<>();
|
private Map<Object, String> cells = new HashMap<>();
|
||||||
|
|
||||||
public void addCell(Object groupId, com.vaadin.ui.Label cell) {
|
public void addCell(Object groupId, String value) {
|
||||||
cells.put(groupId, cell);
|
cells.put(groupId, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public com.vaadin.ui.Label getCell(Object groupId) {
|
public String getValue(Object groupId) {
|
||||||
return cells.get(groupId);
|
return cells.get(groupId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -748,11 +747,7 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable> implements G
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void recalcAggregation(GroupInfo groupInfo) {
|
protected void recalcAggregation(GroupInfo groupInfo) {
|
||||||
// vaadin7
|
component.aggregate(new CubaGroupTable.GroupAggregationContext(component, groupInfo));
|
||||||
// component.aggregate(new com.haulmont.cuba.web.toolkit.ui.GroupTable.GroupAggregationContext(
|
|
||||||
// component,
|
|
||||||
// groupInfo
|
|
||||||
// ));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -160,11 +160,13 @@ public class WebTreeTable extends WebAbstractTable<CubaTreeTable> implements Tre
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public boolean isCaption(Object itemId) {
|
public boolean isCaption(Object itemId) {
|
||||||
return treeTableDatasource && ((TreeTableDatasource) datasource).isCaption(itemId);
|
return treeTableDatasource && ((TreeTableDatasource) datasource).isCaption(itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public String getCaption(Object itemId) {
|
public String getCaption(Object itemId) {
|
||||||
if (treeTableDatasource) {
|
if (treeTableDatasource) {
|
||||||
@ -212,11 +214,13 @@ public class WebTreeTable extends WebAbstractTable<CubaTreeTable> implements Tre
|
|||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public Object nextItemId(Object itemId) {
|
public Object nextItemId(Object itemId) {
|
||||||
return ((CollectionDatasource.Sortable) datasource).nextItemId(itemId);
|
return ((CollectionDatasource.Sortable) datasource).nextItemId(itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public Object prevItemId(Object itemId) {
|
public Object prevItemId(Object itemId) {
|
||||||
return ((CollectionDatasource.Sortable) datasource).prevItemId(itemId);
|
return ((CollectionDatasource.Sortable) datasource).prevItemId(itemId);
|
||||||
@ -232,11 +236,13 @@ public class WebTreeTable extends WebAbstractTable<CubaTreeTable> implements Tre
|
|||||||
return ((CollectionDatasource.Sortable) datasource).lastItemId();
|
return ((CollectionDatasource.Sortable) datasource).lastItemId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public boolean isFirstId(Object itemId) {
|
public boolean isFirstId(Object itemId) {
|
||||||
return ((CollectionDatasource.Sortable) datasource).isFirstId(itemId);
|
return ((CollectionDatasource.Sortable) datasource).isFirstId(itemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public boolean isLastId(Object itemId) {
|
public boolean isLastId(Object itemId) {
|
||||||
return ((CollectionDatasource.Sortable) datasource).isLastId(itemId);
|
return ((CollectionDatasource.Sortable) datasource).isLastId(itemId);
|
||||||
@ -268,7 +274,7 @@ public class WebTreeTable extends WebAbstractTable<CubaTreeTable> implements Tre
|
|||||||
@Override
|
@Override
|
||||||
public void addContainerPropertyAggregation(Object propertyId, Type type) {
|
public void addContainerPropertyAggregation(Object propertyId, Type type) {
|
||||||
if (aggregationProperties == null) {
|
if (aggregationProperties == null) {
|
||||||
aggregationProperties = new LinkedList<Object>();
|
aggregationProperties = new LinkedList<>();
|
||||||
} else if (aggregationProperties.contains(propertyId)) {
|
} else if (aggregationProperties.contains(propertyId)) {
|
||||||
throw new IllegalStateException("Such aggregation property is already exists");
|
throw new IllegalStateException("Such aggregation property is already exists");
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package com.haulmont.cuba.web.toolkit.ui;
|
package com.haulmont.cuba.web.toolkit.ui;
|
||||||
|
|
||||||
import com.haulmont.cuba.web.gui.components.presentations.TablePresentations;
|
import com.haulmont.cuba.web.gui.components.presentations.TablePresentations;
|
||||||
|
import com.haulmont.cuba.web.toolkit.data.AggregationContainer;
|
||||||
import com.vaadin.ui.Layout;
|
import com.vaadin.ui.Layout;
|
||||||
import com.vaadin.ui.Table;
|
import com.vaadin.ui.Table;
|
||||||
|
|
||||||
@ -15,7 +16,7 @@ import com.vaadin.ui.Table;
|
|||||||
* @author artamonov
|
* @author artamonov
|
||||||
* @version $Id$
|
* @version $Id$
|
||||||
*/
|
*/
|
||||||
public interface CubaEnhancedTable {
|
public interface CubaEnhancedTable extends AggregationContainer {
|
||||||
void setContextMenuPopup(Layout contextMenu);
|
void setContextMenuPopup(Layout contextMenu);
|
||||||
void hideContextMenuPopup();
|
void hideContextMenuPopup();
|
||||||
|
|
||||||
@ -50,4 +51,10 @@ public interface CubaEnhancedTable {
|
|||||||
* <b>For internal use only.</b>
|
* <b>For internal use only.</b>
|
||||||
*/
|
*/
|
||||||
void addGeneratedColumnInternal(Object id, Table.ColumnGenerator generatedColumn);
|
void addGeneratedColumnInternal(Object id, Table.ColumnGenerator generatedColumn);
|
||||||
|
|
||||||
|
boolean isAggregatable();
|
||||||
|
void setAggregatable(boolean aggregatable);
|
||||||
|
|
||||||
|
boolean isShowTotalAggregation();
|
||||||
|
void setShowTotalAggregation(boolean showTotalAggregation);
|
||||||
}
|
}
|
@ -8,6 +8,7 @@ package com.haulmont.cuba.web.toolkit.ui;
|
|||||||
import com.haulmont.chile.core.model.MetaPropertyPath;
|
import com.haulmont.chile.core.model.MetaPropertyPath;
|
||||||
import com.haulmont.cuba.gui.data.GroupInfo;
|
import com.haulmont.cuba.gui.data.GroupInfo;
|
||||||
import com.haulmont.cuba.web.gui.data.PropertyValueStringify;
|
import com.haulmont.cuba.web.gui.data.PropertyValueStringify;
|
||||||
|
import com.haulmont.cuba.web.toolkit.data.AggregationContainer;
|
||||||
import com.haulmont.cuba.web.toolkit.data.GroupTableContainer;
|
import com.haulmont.cuba.web.toolkit.data.GroupTableContainer;
|
||||||
import com.haulmont.cuba.web.toolkit.data.util.GroupTableContainerWrapper;
|
import com.haulmont.cuba.web.toolkit.data.util.GroupTableContainerWrapper;
|
||||||
import com.vaadin.data.Container;
|
import com.vaadin.data.Container;
|
||||||
@ -190,6 +191,9 @@ public class CubaGroupTable extends CubaTable implements GroupTableContainer {
|
|||||||
protected void paintRowAttributes(PaintTarget target, Object itemId) throws PaintException {
|
protected void paintRowAttributes(PaintTarget target, Object itemId) throws PaintException {
|
||||||
super.paintRowAttributes(target, itemId);
|
super.paintRowAttributes(target, itemId);
|
||||||
|
|
||||||
|
boolean hasAggregation = items instanceof AggregationContainer && isAggregatable()
|
||||||
|
&& !((AggregationContainer) items).getAggregationPropertyIds().isEmpty();
|
||||||
|
|
||||||
boolean hasGroups = hasGroups();
|
boolean hasGroups = hasGroups();
|
||||||
if (hasGroups) {
|
if (hasGroups) {
|
||||||
if (isGroup(itemId)) {
|
if (isGroup(itemId)) {
|
||||||
@ -201,7 +205,58 @@ public class CubaGroupTable extends CubaTable implements GroupTableContainer {
|
|||||||
final Object propertyValue = getGroupPropertyValue(itemId);
|
final Object propertyValue = getGroupPropertyValue(itemId);
|
||||||
target.addAttribute("groupCaption", formatGroupPropertyValue(itemId, propertyValue));
|
target.addAttribute("groupCaption", formatGroupPropertyValue(itemId, propertyValue));
|
||||||
|
|
||||||
// todo aggregation
|
if (hasAggregation) {
|
||||||
|
paintGroupAggregation(target, itemId,
|
||||||
|
((AggregationContainer) items).aggregate(new GroupAggregationContext(this, itemId)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Collection<?> getAggregationItemIds() {
|
||||||
|
if (hasGroups()) {
|
||||||
|
List itemIds = new LinkedList();
|
||||||
|
for (final Object groupId : rootGroups()) {
|
||||||
|
itemIds.addAll(getGroupItemIds(groupId));
|
||||||
|
}
|
||||||
|
return itemIds;
|
||||||
|
} else {
|
||||||
|
return items.getItemIds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void paintGroupAggregation(PaintTarget target, Object groupId, Map<Object, Object> aggregations)
|
||||||
|
throws PaintException {
|
||||||
|
boolean paintGroupProperty = false;
|
||||||
|
|
||||||
|
final Collection groupProperties = getGroupProperties();
|
||||||
|
final Object groupProperty = getGroupProperty(groupId);
|
||||||
|
|
||||||
|
for (final Object columnId : visibleColumns) {
|
||||||
|
if (columnId == null || isColumnCollapsed(columnId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupProperties.contains(columnId) && !paintGroupProperty) {
|
||||||
|
if (columnId.equals(groupProperty)) {
|
||||||
|
paintGroupProperty = true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getCellStyleGenerator() != null) {
|
||||||
|
String cellStyle = getCellStyleGenerator().getStyle(this, null, columnId);
|
||||||
|
if (cellStyle != null && !cellStyle.equals("")) {
|
||||||
|
target.addAttribute("style-" + columnIdMap.key(columnId), cellStyle + "-ag");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = (String) aggregations.get(columnId);
|
||||||
|
if (value != null) {
|
||||||
|
target.addText(value);
|
||||||
|
} else {
|
||||||
|
target.addText("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,4 +459,17 @@ public class CubaGroupTable extends CubaTable implements GroupTableContainer {
|
|||||||
public interface GroupPropertyValueFormatter {
|
public interface GroupPropertyValueFormatter {
|
||||||
String format(Object groupId, @Nullable Object value);
|
String format(Object groupId, @Nullable Object value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class GroupAggregationContext extends Context {
|
||||||
|
private Object groupId;
|
||||||
|
|
||||||
|
public GroupAggregationContext(GroupTableContainer datasource, Object groupId) {
|
||||||
|
super(datasource.getGroupItemIds(groupId));
|
||||||
|
this.groupId = groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getGroupId() {
|
||||||
|
return groupId;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,6 +9,7 @@ import com.google.common.collect.Iterables;
|
|||||||
import com.haulmont.cuba.web.gui.components.presentations.TablePresentations;
|
import com.haulmont.cuba.web.gui.components.presentations.TablePresentations;
|
||||||
import com.haulmont.cuba.web.gui.data.PropertyValueStringify;
|
import com.haulmont.cuba.web.gui.data.PropertyValueStringify;
|
||||||
import com.haulmont.cuba.web.toolkit.ShortcutActionManager;
|
import com.haulmont.cuba.web.toolkit.ShortcutActionManager;
|
||||||
|
import com.haulmont.cuba.web.toolkit.data.AggregationContainer;
|
||||||
import com.haulmont.cuba.web.toolkit.data.TableContainer;
|
import com.haulmont.cuba.web.toolkit.data.TableContainer;
|
||||||
import com.haulmont.cuba.web.toolkit.ui.client.table.CubaTableClientRpc;
|
import com.haulmont.cuba.web.toolkit.ui.client.table.CubaTableClientRpc;
|
||||||
import com.haulmont.cuba.web.toolkit.ui.client.table.CubaTableState;
|
import com.haulmont.cuba.web.toolkit.ui.client.table.CubaTableState;
|
||||||
@ -42,6 +43,10 @@ public class CubaTable extends com.vaadin.ui.Table implements TableContainer, Cu
|
|||||||
|
|
||||||
protected boolean autowirePropertyDsForFields = false;
|
protected boolean autowirePropertyDsForFields = false;
|
||||||
|
|
||||||
|
protected boolean showTotalAggregation = true;
|
||||||
|
|
||||||
|
protected boolean aggregatable = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CubaTableState getState() {
|
protected CubaTableState getState() {
|
||||||
return (CubaTableState) super.getState();
|
return (CubaTableState) super.getState();
|
||||||
@ -330,4 +335,129 @@ public class CubaTable extends com.vaadin.ui.Table implements TableContainer, Cu
|
|||||||
public void refreshCellStyles() {
|
public void refreshCellStyles() {
|
||||||
super.refreshRenderedCells();
|
super.refreshRenderedCells();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeContainerProperty(Object propertyId) throws UnsupportedOperationException {
|
||||||
|
if (editableColumns != null) {
|
||||||
|
editableColumns.remove(propertyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAggregatable() && items instanceof AggregationContainer) {
|
||||||
|
removeContainerPropertyAggregation(propertyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean removed = super.removeContainerProperty(propertyId);
|
||||||
|
|
||||||
|
if (removed) {
|
||||||
|
resetPageBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAggregatable() {
|
||||||
|
return this.aggregatable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAggregatable(boolean aggregatable) {
|
||||||
|
if (this.aggregatable != aggregatable) {
|
||||||
|
this.aggregatable = aggregatable;
|
||||||
|
markAsDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShowTotalAggregation() {
|
||||||
|
return showTotalAggregation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShowTotalAggregation(boolean showTotalAggregation) {
|
||||||
|
if (this.showTotalAggregation != showTotalAggregation) {
|
||||||
|
this.showTotalAggregation = showTotalAggregation;
|
||||||
|
markAsDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection getAggregationPropertyIds() {
|
||||||
|
if (items instanceof AggregationContainer) {
|
||||||
|
return ((AggregationContainer) items).getAggregationPropertyIds();
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Table container is not AggregationContainer: " + items.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getContainerPropertyAggregation(Object propertyId) {
|
||||||
|
if (items instanceof AggregationContainer) {
|
||||||
|
return ((AggregationContainer) items).getContainerPropertyAggregation(propertyId);
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Table container is not AggregationContainer: " + items.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addContainerPropertyAggregation(Object propertyId, Type type) {
|
||||||
|
if (items instanceof AggregationContainer) {
|
||||||
|
((AggregationContainer) items).addContainerPropertyAggregation(propertyId, type);
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Table container is not AggregationContainer: " + items.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeContainerPropertyAggregation(Object propertyId) {
|
||||||
|
if (items instanceof AggregationContainer) {
|
||||||
|
((AggregationContainer) items).removeContainerPropertyAggregation(propertyId);
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Table container is not AggregationContainer: " + items.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Object, Object> aggregate(Context context) {
|
||||||
|
if (items instanceof AggregationContainer && isAggregatable()) {
|
||||||
|
return ((AggregationContainer) items).aggregate(context);
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Table container is not AggregationContainer: " + items.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintAdditionalData(PaintTarget target) throws PaintException {
|
||||||
|
if (reqFirstRowToPaint == -1) {
|
||||||
|
boolean hasAggregation = items instanceof AggregationContainer && isAggregatable()
|
||||||
|
&& !((AggregationContainer) items).getAggregationPropertyIds().isEmpty();
|
||||||
|
|
||||||
|
if (hasAggregation && isShowTotalAggregation()) {
|
||||||
|
Context context = new Context(getAggregationItemIds());
|
||||||
|
paintAggregationRow(target, ((AggregationContainer) items).aggregate(context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Collection<?> getAggregationItemIds() {
|
||||||
|
return items.getItemIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void paintAggregationRow(PaintTarget target, Map<Object, Object> aggregations) throws PaintException {
|
||||||
|
target.startTag("arow");
|
||||||
|
for (final Object columnId : visibleColumns) {
|
||||||
|
if (columnId == null || isColumnCollapsed(columnId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getCellStyleGenerator() != null) {
|
||||||
|
String cellStyle = getCellStyleGenerator().getStyle(this, null, columnId);
|
||||||
|
if (cellStyle != null && !cellStyle.equals("")) {
|
||||||
|
target.addAttribute("style-"
|
||||||
|
+ columnIdMap.key(columnId), cellStyle + "-ag");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = (String) aggregations.get(columnId);
|
||||||
|
target.addText(value);
|
||||||
|
}
|
||||||
|
target.endTag("arow");
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,6 +9,7 @@ import com.google.common.collect.Iterables;
|
|||||||
import com.haulmont.cuba.web.gui.components.presentations.TablePresentations;
|
import com.haulmont.cuba.web.gui.components.presentations.TablePresentations;
|
||||||
import com.haulmont.cuba.web.gui.data.PropertyValueStringify;
|
import com.haulmont.cuba.web.gui.data.PropertyValueStringify;
|
||||||
import com.haulmont.cuba.web.toolkit.ShortcutActionManager;
|
import com.haulmont.cuba.web.toolkit.ShortcutActionManager;
|
||||||
|
import com.haulmont.cuba.web.toolkit.data.AggregationContainer;
|
||||||
import com.haulmont.cuba.web.toolkit.data.TableContainer;
|
import com.haulmont.cuba.web.toolkit.data.TableContainer;
|
||||||
import com.haulmont.cuba.web.toolkit.data.TreeTableContainer;
|
import com.haulmont.cuba.web.toolkit.data.TreeTableContainer;
|
||||||
import com.haulmont.cuba.web.toolkit.data.util.TreeTableContainerWrapper;
|
import com.haulmont.cuba.web.toolkit.data.util.TreeTableContainerWrapper;
|
||||||
@ -46,6 +47,10 @@ public class CubaTreeTable extends com.vaadin.ui.TreeTable implements TreeTableC
|
|||||||
|
|
||||||
protected boolean autowirePropertyDsForFields = false;
|
protected boolean autowirePropertyDsForFields = false;
|
||||||
|
|
||||||
|
protected boolean showTotalAggregation = true;
|
||||||
|
|
||||||
|
protected boolean aggregatable = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CubaTreeTableState getState() {
|
protected CubaTreeTableState getState() {
|
||||||
return (CubaTreeTableState) super.getState();
|
return (CubaTreeTableState) super.getState();
|
||||||
@ -394,4 +399,120 @@ public class CubaTreeTable extends com.vaadin.ui.TreeTable implements TreeTableC
|
|||||||
public void refreshCellStyles() {
|
public void refreshCellStyles() {
|
||||||
super.refreshRenderedCells();
|
super.refreshRenderedCells();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeContainerProperty(Object propertyId) throws UnsupportedOperationException {
|
||||||
|
if (editableColumns != null) {
|
||||||
|
editableColumns.remove(propertyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAggregatable() && items instanceof AggregationContainer) {
|
||||||
|
removeContainerPropertyAggregation(propertyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean removed = super.removeContainerProperty(propertyId);
|
||||||
|
|
||||||
|
if (removed) {
|
||||||
|
resetPageBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAggregatable() {
|
||||||
|
return this.aggregatable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAggregatable(boolean aggregatable) {
|
||||||
|
if (this.aggregatable != aggregatable) {
|
||||||
|
this.aggregatable = aggregatable;
|
||||||
|
markAsDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShowTotalAggregation() {
|
||||||
|
return showTotalAggregation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShowTotalAggregation(boolean showTotalAggregation) {
|
||||||
|
if (this.showTotalAggregation != showTotalAggregation) {
|
||||||
|
this.showTotalAggregation = showTotalAggregation;
|
||||||
|
markAsDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection getAggregationPropertyIds() {
|
||||||
|
if (items instanceof AggregationContainer) {
|
||||||
|
return ((AggregationContainer) items).getAggregationPropertyIds();
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Table container is not AggregationContainer: " + items.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getContainerPropertyAggregation(Object propertyId) {
|
||||||
|
if (items instanceof AggregationContainer) {
|
||||||
|
return ((AggregationContainer) items).getContainerPropertyAggregation(propertyId);
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Table container is not AggregationContainer: " + items.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addContainerPropertyAggregation(Object propertyId, Type type) {
|
||||||
|
if (items instanceof AggregationContainer) {
|
||||||
|
((AggregationContainer) items).addContainerPropertyAggregation(propertyId, type);
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Table container is not AggregationContainer: " + items.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeContainerPropertyAggregation(Object propertyId) {
|
||||||
|
if (items instanceof AggregationContainer) {
|
||||||
|
((AggregationContainer) items).removeContainerPropertyAggregation(propertyId);
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Table container is not AggregationContainer: " + items.getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Object, Object> aggregate(Context context) {
|
||||||
|
if (items instanceof AggregationContainer && isAggregatable()) {
|
||||||
|
return ((AggregationContainer) items).aggregate(context);
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Table container is not AggregationContainer: " + items.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintAdditionalData(PaintTarget target) throws PaintException {
|
||||||
|
if (reqFirstRowToPaint == -1 && items instanceof AggregationContainer && isAggregatable()
|
||||||
|
&& !((AggregationContainer) items).getAggregationPropertyIds().isEmpty() && isShowTotalAggregation()) {
|
||||||
|
paintAggregationRow(target, ((AggregationContainer) items).aggregate(new Context(items.getItemIds())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void paintAggregationRow(PaintTarget target, Map<Object, Object> aggregations) throws PaintException {
|
||||||
|
target.startTag("arow");
|
||||||
|
for (final Object columnId : visibleColumns) {
|
||||||
|
if (columnId == null || isColumnCollapsed(columnId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getCellStyleGenerator() != null) {
|
||||||
|
String cellStyle = getCellStyleGenerator().getStyle(this, null, columnId);
|
||||||
|
if (cellStyle != null && !cellStyle.equals("")) {
|
||||||
|
target.addAttribute("style-"
|
||||||
|
+ columnIdMap.key(columnId), cellStyle + "-ag");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = (String) aggregations.get(columnId);
|
||||||
|
target.addText(value);
|
||||||
|
}
|
||||||
|
target.endTag("arow");
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,6 +9,26 @@
|
|||||||
.#{$primaryStyleName} {
|
.#{$primaryStyleName} {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
|
.v-table-arow {
|
||||||
|
@include box-defaults;
|
||||||
|
|
||||||
|
border-top: 1px solid $theme_fieldBorderColor;
|
||||||
|
border-left: 1px solid $theme_fieldBorderColor;
|
||||||
|
border-right: 1px solid $theme_fieldBorderColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-table-arow-row {
|
||||||
|
@include box-defaults;
|
||||||
|
|
||||||
|
height: 24px;
|
||||||
|
background: #ccc;
|
||||||
|
border-right: 1px solid $theme_fieldBorderColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-table-arow-row > .v-table-cell-content {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.v-table-cell-content.boolean-cell-true .v-table-cell-wrapper {
|
.v-table-cell-content.boolean-cell-true .v-table-cell-wrapper {
|
||||||
color: transparent;
|
color: transparent;
|
||||||
font-size: 0px;
|
font-size: 0px;
|
||||||
|
@ -69,6 +69,7 @@ $theme_tableRowOddBackgroundColor: #f6f8fa;
|
|||||||
$theme_tableRowSelectionBackgroundColor: #c3e1ff;
|
$theme_tableRowSelectionBackgroundColor: #c3e1ff;
|
||||||
$theme_tableRowHoverBackgroundColor: #f5f4b9;
|
$theme_tableRowHoverBackgroundColor: #f5f4b9;
|
||||||
$theme_tableCellSeparatorColor: #edf3f9;
|
$theme_tableCellSeparatorColor: #edf3f9;
|
||||||
|
$theme_tableAggregationRowColor: #8398af;
|
||||||
|
|
||||||
$theme_treeSelectionColor: #5daee8;
|
$theme_treeSelectionColor: #5daee8;
|
||||||
$theme_treeCaptionColor: #1e3146;
|
$theme_treeCaptionColor: #1e3146;
|
||||||
|
@ -440,26 +440,12 @@
|
|||||||
border-top: 1px solid #71a4d5;
|
border-top: 1px solid #71a4d5;
|
||||||
border-left: 1px solid #71a4d5;
|
border-left: 1px solid #71a4d5;
|
||||||
border-right: 1px solid #71a4d5;
|
border-right: 1px solid #71a4d5;
|
||||||
background: #ccc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-table-arow-row {
|
.v-table-arow-row {
|
||||||
|
background: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IE6 hack */
|
|
||||||
/** html .v-table-scrollposition {*/
|
|
||||||
/*background: transparent;*/
|
|
||||||
/*
|
|
||||||
AlphaImageLoader uses src attribute relative to host page, not CSS
|
|
||||||
We need multiple different filters because we cannot be sure how host page is served compared to theme resources
|
|
||||||
TODO: This actually does not work as expected, since only the last filter is applied.
|
|
||||||
*/
|
|
||||||
/*filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../../ITMILL/themes/saneco/table/img/scroll-position-bg.png", sizingMethod="scale");*/
|
|
||||||
/*filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="../ITMILL/themes/saneco/table/img/scroll-position-bg.png", sizingMethod="scale");*/
|
|
||||||
/*filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="ITMILL/themes/saneco/table/img/scroll-position-bg.png", sizingMethod="scale");*/
|
|
||||||
/*filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="/ITMILL/themes/saneco/table/img/scroll-position-bg.png", sizingMethod="scale");*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
.v-pager {
|
.v-pager {
|
||||||
height: 20px;
|
height: 20px;
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
|
Loading…
Reference in New Issue
Block a user