mirror of
https://gitee.com/jmix/cuba.git
synced 2024-11-30 10:17:43 +08:00
GroupTable Component #PL-1903
This commit is contained in:
parent
466b0ee033
commit
b3f24dc297
@ -62,7 +62,7 @@ def desktopModule = project(':cuba-desktop')
|
||||
def uiTestModule = project(':cuba-test-ui')
|
||||
def portalModule = project(':cuba-portal')
|
||||
|
||||
def vaadinVersion = '7.0.1.h.M1'
|
||||
def vaadinVersion = '7.0.2.h.M1'
|
||||
|
||||
def servletApi = [group: 'org.apache.tomcat', name: 'servlet-api', version: '6.0.20']
|
||||
def groovyArtifact = [group: 'org.codehaus.groovy', name: 'groovy', version: '1.7.10']
|
||||
@ -349,7 +349,7 @@ configure(webToolkitModule) {
|
||||
dependencyModules = [webModule]
|
||||
widgetSetClass = 'com.haulmont.cuba.web.toolkit.ui.WidgetSet'
|
||||
//jvmArgs('-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000')
|
||||
compilerArgs = ['-style' : 'PRETTY', '-logLevel' : 'INFO', '-localWorkers' : '2']
|
||||
compilerArgs = ['-style' : 'DETAILED', '-logLevel' : 'INFO', '-localWorkers' : '2', '-draftCompile' : 'true']
|
||||
}
|
||||
|
||||
task webArchive(dependsOn: buildWidgetSet, type: Zip) {
|
||||
|
@ -28,7 +28,7 @@
|
||||
webkit based browsers including Google Chrome.
|
||||
-->
|
||||
<!-- vaadin7 -->
|
||||
<set-property name="user.agent" value="safari, gecko1_8"/>
|
||||
<set-property name="user.agent" value="safari"/>
|
||||
|
||||
<!--
|
||||
To enable SuperDevMode, uncomment this line.
|
||||
|
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.web.toolkit.ui.client;
|
||||
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.google.gwt.user.client.Element;
|
||||
import com.haulmont.cuba.web.toolkit.ui.client.sys.ToolsImpl;
|
||||
import com.vaadin.client.RenderInformation;
|
||||
|
||||
/**
|
||||
* @author gorodnov
|
||||
* @version $Id$
|
||||
*/
|
||||
public class Tools {
|
||||
private static ToolsImpl impl;
|
||||
|
||||
static {
|
||||
impl = new ToolsImpl();
|
||||
}
|
||||
|
||||
public static int parseSize(String s) {
|
||||
return impl.parseSize(s);
|
||||
}
|
||||
|
||||
public static String format(String s) {
|
||||
return impl.format(s);
|
||||
}
|
||||
|
||||
public static void removeChildren(Element e) {
|
||||
int childCount = DOM.getChildCount(e);
|
||||
if (childCount > 0) {
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
DOM.removeChild(e, DOM.getChild(e, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setInnerHTML(Element elem, String text) {
|
||||
impl.setInnerHTML(elem, text);
|
||||
}
|
||||
|
||||
public static void setInnerText(Element elem, String text) {
|
||||
impl.setInnerText(elem, text);
|
||||
}
|
||||
|
||||
public static boolean isRadio(Element elem) {
|
||||
return impl.isRadio(elem);
|
||||
}
|
||||
|
||||
public static boolean isCheckbox(Element elem) {
|
||||
return impl.isCheckbox(elem);
|
||||
}
|
||||
|
||||
public static void textSelectionEnable(Element el, boolean b) {
|
||||
impl.textSelectionEnable(el, b);
|
||||
}
|
||||
|
||||
public static void removeElementWithEvents(Element el) {
|
||||
impl.removeElementWithEvents(el);
|
||||
}
|
||||
|
||||
public static String setStyleName(Element el, String style) {
|
||||
if (style == null) throw new RuntimeException("Style cannot be null");
|
||||
style = style.trim();
|
||||
DOM.setElementProperty(el, "className", style);
|
||||
return style;
|
||||
}
|
||||
|
||||
public static String getStyleName(Element el) {
|
||||
return DOM.getElementProperty(el, "className");
|
||||
}
|
||||
|
||||
public static String addStyleName(Element el, String style) {
|
||||
if (style == null) throw new RuntimeException("Style cannot be null");
|
||||
style = style.trim();
|
||||
el.addClassName(style);
|
||||
return style;
|
||||
}
|
||||
|
||||
public static void removeStyleName(Element el, String style) {
|
||||
if (style == null) throw new RuntimeException("Style cannot be null");
|
||||
style = style.trim();
|
||||
el.removeClassName(style);
|
||||
}
|
||||
|
||||
public static String setStylePrimaryName(Element el, String style) {
|
||||
if (style == null) throw new RuntimeException("Style cannot be null");
|
||||
style = style.trim();
|
||||
impl.updatePrimaryAndDependentStyleNames(el, style);
|
||||
return style;
|
||||
}
|
||||
|
||||
public static String getStylePrimaryName(Element el) {
|
||||
String className = DOM.getElementProperty(el, "className");
|
||||
int spaceIdx = className.indexOf(' ');
|
||||
if (spaceIdx >= 0) {
|
||||
return className.substring(0, spaceIdx);
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
public static String addStyleDependentName(Element el, String styleSuffix) {
|
||||
String s = getStylePrimaryName(el) + '-' + styleSuffix;
|
||||
addStyleName(el, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
public static void removeStyleDependentName(Element el, String styleSuffix) {
|
||||
removeStyleName(el, getStylePrimaryName(el) + '-' + styleSuffix);
|
||||
}
|
||||
|
||||
public static boolean hasStyleDependentName(Element el, String styleSuffix) {
|
||||
return hasStyleName(el, getStylePrimaryName(el) + '-' + styleSuffix);
|
||||
}
|
||||
|
||||
public static boolean hasStyleName(Element el, String style) {
|
||||
if (style == null) throw new RuntimeException("Style cannot be null");
|
||||
style = style.trim();
|
||||
return impl.hasStyleName(el, style);
|
||||
}
|
||||
|
||||
public static String[] getStyleNames(Element el) {
|
||||
return getStyleName(el).split("[\\s+]");
|
||||
}
|
||||
|
||||
public static RenderInformation.Size definePaddingBorders(Element el) {
|
||||
String w = DOM.getStyleAttribute(el, "width");
|
||||
String h = DOM.getStyleAttribute(el, "height");
|
||||
|
||||
DOM.setStyleAttribute(el, "overflow", "hidden");
|
||||
DOM.setStyleAttribute(el, "width", "0px");
|
||||
DOM.setStyleAttribute(el, "height", "0px");
|
||||
|
||||
RenderInformation.Size s = new RenderInformation.Size();
|
||||
s.setWidth(el.getOffsetWidth());
|
||||
s.setHeight(el.getOffsetHeight());
|
||||
|
||||
DOM.setStyleAttribute(el, "width", w);
|
||||
DOM.setStyleAttribute(el, "height", h);
|
||||
DOM.setStyleAttribute(el, "overflow", "");
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.web.toolkit.ui.client.sys;
|
||||
|
||||
import com.google.gwt.dom.client.Element;
|
||||
|
||||
/**
|
||||
* @author gorodnov
|
||||
* @version $Id$
|
||||
*/
|
||||
public class ToolsImpl {
|
||||
public native int parseSize(String s) /*-{
|
||||
try {
|
||||
var result = /^(\d+)(%|px|em|ex|in|cm|mm|pt|pc)$/.exec(s);
|
||||
return parseInt(result[1]);
|
||||
} catch (e) {
|
||||
return -1;
|
||||
}
|
||||
}-*/;
|
||||
|
||||
public native String format(String message) /*-{
|
||||
return message.replace(/\[br\]/g, "<br/>")
|
||||
.replace(/\[b\]/g, "<b>")
|
||||
.replace(/\[\/b\]/g, "</b>")
|
||||
.replace(/\[i\]/g, "<i>")
|
||||
.replace(/\[\/i\]/g, "</i>");
|
||||
}-*/;
|
||||
|
||||
public native void setInnerHTML(Element elem, String text) /*-{
|
||||
elem.innerHTML = text; //todo gorodnov: support line breaks
|
||||
}-*/;
|
||||
|
||||
public native void setInnerText(Element elem, String text) /*-{
|
||||
while (elem.firstChild) {
|
||||
elem.removeChild(elem.firstChild);
|
||||
}
|
||||
if (text != null) {
|
||||
var arr = new Array();
|
||||
arr = text.replace(/\r/g, "").split("\n");
|
||||
if (arr.length > 0) {
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i]) {
|
||||
elem.appendChild($doc.createTextNode(arr[i]));
|
||||
elem.appendChild($doc.createElement("br"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
elem.appendChild($doc.createTextNode(text));
|
||||
}
|
||||
}
|
||||
}-*/;
|
||||
|
||||
public native boolean isRadio(Element e) /*-{
|
||||
return (e && e.tagName.toUpperCase() == "INPUT" && e.type == "radio");
|
||||
}-*/;
|
||||
|
||||
public native boolean isCheckbox(Element e) /*-{
|
||||
return (e && e.tagName.toUpperCase() == "INPUT" && e.type == "checkbox");
|
||||
}-*/;
|
||||
|
||||
public native void textSelectionEnable(Element el, boolean b) /*-{
|
||||
|
||||
// CAUTION Do not use jQuery disable text selection pack, it caches html nodes and we have memory leaks
|
||||
|
||||
if (typeof document.falseFunction != "function") {
|
||||
document.falseFunction = function() {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
var walkEach = function(element, action) {
|
||||
if (typeof element != "undefined") {
|
||||
action(element);
|
||||
var children = element.childNodes;
|
||||
if (typeof children != "undefined") {
|
||||
for (var i = 0; i < children.length; i++)
|
||||
if (children[i].nodeType == 1)
|
||||
walkEach(children[i], action);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!b) {
|
||||
// disable
|
||||
if ($wnd.jQuery.browser.mozilla) {
|
||||
walkEach(el, function(x) {
|
||||
if (typeof x.style == "undefined")
|
||||
x.style = {};
|
||||
x.style.MozUserSelect = "none";
|
||||
});
|
||||
} else if ($wnd.jQuery.browser.msie) {
|
||||
walkEach(el, function(x) {
|
||||
x.onselectstart = document.falseFunction;
|
||||
});
|
||||
} else if ($wnd.jQuery.browser.webkit) {
|
||||
walkEach(el, function(x) {
|
||||
if (typeof x.style == "undefined")
|
||||
x.style = {};
|
||||
x.style.webkitUserSelect = "none";
|
||||
});
|
||||
} else {
|
||||
walkEach(el, function(x) {
|
||||
x.addEventListener("selectstart", document.falseFunction, true);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// enable
|
||||
if ($wnd.jQuery.browser.mozilla) {
|
||||
walkEach(el, function(x) {
|
||||
if (typeof x.style == "undefined")
|
||||
x.style = {};
|
||||
x.style.MozUserSelect = "";
|
||||
});
|
||||
} else if ($wnd.jQuery.browser.msie) {
|
||||
walkEach(el, function(x) {
|
||||
x.onselectstart = null;
|
||||
});
|
||||
} else if ($wnd.jQuery.browser.webkit) {
|
||||
walkEach(el, function(x) {
|
||||
if (typeof x.style == "undefined")
|
||||
x.style = {};
|
||||
x.style.webkitUserSelect = "";
|
||||
});
|
||||
} else {
|
||||
walkEach(el, function(x) {
|
||||
x.removeEventListener("selectstart", document.falseFunction, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
walkEach = null;
|
||||
}-*/;
|
||||
|
||||
public native void removeElementWithEvents(Element el) /*-{
|
||||
$wnd.jQuery(el).remove();
|
||||
}-*/;
|
||||
|
||||
public native void updatePrimaryAndDependentStyleNames(Element elem,
|
||||
String newPrimaryStyle) /*-{
|
||||
var classes = elem.className.split(/\s+/);
|
||||
if (!classes) {
|
||||
return;
|
||||
}
|
||||
|
||||
var oldPrimaryStyle = classes[0];
|
||||
var oldPrimaryStyleLen = oldPrimaryStyle.length;
|
||||
|
||||
classes[0] = newPrimaryStyle;
|
||||
for (var i = 1, n = classes.length; i < n; i++) {
|
||||
var name = classes[i];
|
||||
if (name.length > oldPrimaryStyleLen
|
||||
&& name.charAt(oldPrimaryStyleLen) == '-'
|
||||
&& name.indexOf(oldPrimaryStyle) == 0) {
|
||||
classes[i] = newPrimaryStyle + name.substring(oldPrimaryStyleLen);
|
||||
}
|
||||
}
|
||||
elem.className = classes.join(" ");
|
||||
}-*/;
|
||||
|
||||
public native boolean hasStyleName(Element el, String style) /*-{
|
||||
var classes = elem.className.split(/\s+/);
|
||||
if (!classes) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < classes.length; i++) {
|
||||
if (classes[i] == style) return true;
|
||||
}
|
||||
return false;
|
||||
}-*/;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.web.toolkit.ui.client.table;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.haulmont.cuba.web.toolkit.ui.CubaGroupTable;
|
||||
import com.vaadin.client.ApplicationConnection;
|
||||
import com.vaadin.client.UIDL;
|
||||
import com.vaadin.client.ui.table.TableConnector;
|
||||
import com.vaadin.shared.ui.Connect;
|
||||
|
||||
/**
|
||||
* @author artamonov
|
||||
* @version $Id$
|
||||
*/
|
||||
@Connect(CubaGroupTable.class)
|
||||
public class CubaGroupTableConnector extends TableConnector {
|
||||
|
||||
@Override
|
||||
public CubaGroupTableWidget getWidget() {
|
||||
return (CubaGroupTableWidget) super.getWidget();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CubaGroupTableWidget createWidget() {
|
||||
return GWT.create(CubaGroupTableWidget.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
|
||||
if (uidl.hasVariable("groupColumns"))
|
||||
getWidget().updateGroupColumns(uidl.getStringArrayVariableAsSet("groupColumns"));
|
||||
else
|
||||
getWidget().updateGroupColumns(null);
|
||||
|
||||
super.updateFromUIDL(uidl, client);
|
||||
}
|
||||
}
|
@ -0,0 +1,468 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.web.toolkit.ui.client.table;
|
||||
|
||||
import com.google.gwt.dom.client.TableCellElement;
|
||||
import com.google.gwt.user.client.DOM;
|
||||
import com.google.gwt.user.client.Element;
|
||||
import com.google.gwt.user.client.Event;
|
||||
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 com.vaadin.shared.ui.table.TableConstants;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author artamonov
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CubaGroupTableWidget extends VScrollTable {
|
||||
|
||||
public static final String CLASSNAME = "cuba-grouptable";
|
||||
public static final String GROUP_DIVIDER_COLUMN_KEY = "-1";
|
||||
|
||||
protected Set<String> groupColumns;
|
||||
|
||||
public void updateGroupColumns(Set<String> groupColumns) {
|
||||
this.groupColumns = groupColumns;
|
||||
}
|
||||
|
||||
private void addGroupColumn(String colKey) {
|
||||
if (groupColumns == null) {
|
||||
groupColumns = new HashSet<String>();
|
||||
}
|
||||
groupColumns.add(colKey);
|
||||
}
|
||||
|
||||
private void removeGroupColumn(String colKey) {
|
||||
if (groupColumns != null) {
|
||||
groupColumns.remove(colKey);
|
||||
if (groupColumns.size() == 0)
|
||||
groupColumns = null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isGroupColumn(String cid) {
|
||||
return groupColumns != null && groupColumns.contains(cid);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getVisibleColsCount(String[] strings) {
|
||||
return strings.length + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHeaderColumns(String[] strings, int colIndex) {
|
||||
boolean dividerPainted = false;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < strings.length; i++) {
|
||||
final String cid = strings[i];
|
||||
if (!isGroupColumn(cid) && !dividerPainted) {
|
||||
//paint group columns divider
|
||||
visibleColOrder[colIndex] = GROUP_DIVIDER_COLUMN_KEY;
|
||||
tHead.enableColumn(GROUP_DIVIDER_COLUMN_KEY, colIndex++);
|
||||
dividerPainted = true;
|
||||
}
|
||||
visibleColOrder[colIndex] = cid;
|
||||
tHead.enableColumn(cid, colIndex);
|
||||
colIndex++;
|
||||
}
|
||||
|
||||
if (!dividerPainted) {
|
||||
visibleColOrder[colIndex] = GROUP_DIVIDER_COLUMN_KEY;
|
||||
tHead.enableColumn(GROUP_DIVIDER_COLUMN_KEY, colIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateFooterColumns(String[] strings, int colIndex) {
|
||||
boolean dividerPainted = false;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < strings.length; i++) {
|
||||
final String cid = strings[i];
|
||||
if (!isGroupColumn(cid) && !dividerPainted) {
|
||||
//paint group columns divider
|
||||
tFoot.enableColumn(GROUP_DIVIDER_COLUMN_KEY, colIndex++);
|
||||
dividerPainted = true;
|
||||
}
|
||||
tFoot.enableColumn(cid, colIndex);
|
||||
colIndex++;
|
||||
}
|
||||
if (!dividerPainted) {
|
||||
tFoot.enableColumn(GROUP_DIVIDER_COLUMN_KEY, colIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void reOrderColumn(String columnKey, int newIndex) {
|
||||
// CAUTION This method copied from VScrollTable
|
||||
// Added grouping support
|
||||
|
||||
final int oldIndex = getColIndexByKey(columnKey);
|
||||
|
||||
// Change header order
|
||||
tHead.moveCell(oldIndex, newIndex);
|
||||
|
||||
// Change footer order
|
||||
tFoot.moveCell(oldIndex, newIndex);
|
||||
|
||||
/*
|
||||
* Build new columnOrder and update it to server Note that columnOrder
|
||||
* also contains collapsed columns so we cannot directly build it from
|
||||
* cells vector Loop the old columnOrder and append in order to new
|
||||
* array unless on moved columnKey. On new index also put the moved key
|
||||
* i == index on columnOrder, j == index on newOrder
|
||||
*/
|
||||
final String oldKeyOnNewIndex = visibleColOrder[newIndex];
|
||||
if (showRowHeaders) {
|
||||
newIndex--; // columnOrder don't have rowHeader
|
||||
}
|
||||
|
||||
// Grouping support
|
||||
final int groupDividerIndex = getColIndexByKey(GROUP_DIVIDER_COLUMN_KEY);
|
||||
if (isGroupColumn(columnKey)) {
|
||||
if (newIndex > 0 && newIndex >= groupDividerIndex) {
|
||||
removeGroupColumn(columnKey);
|
||||
newIndex--;
|
||||
}
|
||||
} else {
|
||||
if (newIndex <= groupDividerIndex) {
|
||||
addGroupColumn(columnKey);
|
||||
}
|
||||
if (newIndex > 0 && newIndex > groupDividerIndex) {
|
||||
newIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
if (!GROUP_DIVIDER_COLUMN_KEY.equals(oldKeyOnNewIndex)) {
|
||||
for (int i = 0; i < columnOrder.length; i++) {
|
||||
if (columnOrder[i].equals(oldKeyOnNewIndex)) {
|
||||
break; // break loop at target
|
||||
}
|
||||
if (isCollapsedColumn(columnOrder[i])) {
|
||||
newIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finally we can build the new columnOrder for server
|
||||
final String[] newOrder = new String[columnOrder.length];
|
||||
for (int i = 0, j = 0; j < newOrder.length; i++) {
|
||||
if (j == newIndex) {
|
||||
newOrder[j] = columnKey;
|
||||
j++;
|
||||
}
|
||||
if (i == columnOrder.length) {
|
||||
break;
|
||||
}
|
||||
if (columnOrder[i].equals(columnKey)) {
|
||||
continue;
|
||||
}
|
||||
newOrder[j] = columnOrder[i];
|
||||
j++;
|
||||
}
|
||||
columnOrder = newOrder;
|
||||
// also update visibleColumnOrder
|
||||
int colIndex = showRowHeaders ? 1 : 0;
|
||||
boolean dividerPainted = false;
|
||||
for (int j = 0; j < newOrder.length; j++) {
|
||||
final String cid = newOrder[j];
|
||||
if (!isGroupColumn(cid) && !dividerPainted) {
|
||||
//paint group columns divider
|
||||
visibleColOrder[colIndex++] = GROUP_DIVIDER_COLUMN_KEY;
|
||||
dividerPainted = true;
|
||||
}
|
||||
if (!isCollapsedColumn(cid)) {
|
||||
visibleColOrder[colIndex++] = cid;
|
||||
}
|
||||
}
|
||||
|
||||
// Grouping sypport
|
||||
if (groupColumns != null) {
|
||||
// collect new grouped columns
|
||||
final String[] groupedColumns = new String[groupColumns.size()];
|
||||
for (int i = 0, j = 0; i < columnOrder.length; i++) {
|
||||
final String colKey = columnOrder[i];
|
||||
if (isGroupColumn(colKey)) {
|
||||
groupedColumns[j++] = colKey;
|
||||
}
|
||||
if (j == groupedColumns.length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
client.updateVariable(paintableId, "groupedcolumns", groupedColumns, false);
|
||||
}
|
||||
|
||||
// CAUTION we use immediate update of column order
|
||||
client.updateVariable(paintableId, "columnorder", columnOrder, true);
|
||||
if (client.hasEventListeners(this,
|
||||
TableConstants.COLUMN_REORDER_EVENT_ID)) {
|
||||
client.sendPendingVariableChanges();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VScrollTableBody createScrollBody() {
|
||||
return new GroupTableBody();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TableHead createTableHead() {
|
||||
return new GroupTableHead();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TableFooter createTableFooter() {
|
||||
return new GroupTableFooter();
|
||||
}
|
||||
|
||||
protected class GroupTableHead extends TableHead {
|
||||
public GroupTableHead() {
|
||||
super();
|
||||
availableCells.put(GROUP_DIVIDER_COLUMN_KEY, new GroupDividerHeaderCell());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
super.clear();
|
||||
availableCells.put(GROUP_DIVIDER_COLUMN_KEY, new GroupDividerHeaderCell());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillAdditionalUpdatedCells(HashSet<String> updated) {
|
||||
updated.add(GROUP_DIVIDER_COLUMN_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
protected class GroupTableFooter extends TableFooter {
|
||||
public GroupTableFooter() {
|
||||
availableCells.put(GROUP_DIVIDER_COLUMN_KEY, new GroupDividerFooterCell());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
super.clear();
|
||||
availableCells.put(GROUP_DIVIDER_COLUMN_KEY, new GroupDividerFooterCell());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillAdditionalUpdatedCells(HashSet<String> updated) {
|
||||
updated.add(GROUP_DIVIDER_COLUMN_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
protected class GroupTableBody extends VScrollTableBody {
|
||||
|
||||
@Override
|
||||
protected VScrollTableRow createRow(UIDL uidl, char[] aligns2) {
|
||||
if (uidl.hasAttribute("groupKey")) {
|
||||
return new GroupTableGroupRow(uidl, aligns2); //creates a group row
|
||||
}
|
||||
else
|
||||
return new GroupTableRow(uidl, aligns2);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addRow(VScrollTableRow row) {
|
||||
super.addRow(row);
|
||||
if (row instanceof GroupTableGroupRow
|
||||
&& ((GroupTableGroupRow) row).isExpanded()) {
|
||||
row.addStyleName("v-expanded");
|
||||
}
|
||||
}
|
||||
|
||||
protected class GroupTableRow extends VScrollTableRow {
|
||||
|
||||
public GroupTableRow(UIDL uidl, char[] aligns) {
|
||||
super(uidl, aligns);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean addSpecificCell(Object columnId, int colIndex) {
|
||||
if (GROUP_DIVIDER_COLUMN_KEY.equals(columnId)) {
|
||||
addCell("", aligns[colIndex], "", false, false, null);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected class GroupTableGroupRow extends GroupTableRow {
|
||||
private String colKey;
|
||||
private String groupKey;
|
||||
private boolean expanded;
|
||||
|
||||
private int colIndex = -1;
|
||||
|
||||
private boolean hasCells = false;
|
||||
|
||||
public GroupTableGroupRow(UIDL uidl, char[] aligns) {
|
||||
super(uidl, aligns);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addCellsFromUIDL(UIDL uidl, char[] aligns, int colIndex, int visibleColumnIndex) {
|
||||
colKey = uidl.getStringAttribute("colKey");
|
||||
groupKey = uidl.getStringAttribute("groupKey");
|
||||
expanded = uidl.hasAttribute("expanded") && uidl.getBooleanAttribute("expanded");
|
||||
|
||||
while (colIndex < visibleColOrder.length && !visibleColOrder[colIndex].equals(colKey)) {
|
||||
//draw empty cells
|
||||
Element td = DOM.createTD();
|
||||
|
||||
final TableCellElement tdCell = td.cast();
|
||||
initCellWithText("", ALIGN_LEFT, "", false, true, null, tdCell);
|
||||
|
||||
td.setClassName(CubaGroupTableWidget.this.getStylePrimaryName() + "-cell-content");
|
||||
DOM.appendChild(getElement(), td);
|
||||
colIndex++;
|
||||
}
|
||||
|
||||
if (colIndex >= visibleColOrder.length)
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
|
||||
//paint "+" and group caption
|
||||
this.colIndex = colIndex;
|
||||
|
||||
addGroupCell(uidl.getStringAttribute("groupCaption"));
|
||||
|
||||
if (uidl.getChildCount() > 0) {
|
||||
super.addCellsFromUIDL(uidl, aligns, colIndex, visibleColumnIndex);
|
||||
hasCells = true;
|
||||
} else {
|
||||
Element td = DOM.getChild(getElement(), DOM.getChildCount(getElement()) - 1);
|
||||
DOM.setElementAttribute(td, "colSpan", String.valueOf(visibleColOrder.length - this.colIndex));
|
||||
hasCells = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void addGroupCell(String text) {
|
||||
// String only content is optimized by not using Label widget
|
||||
final TableCellElement td = DOM.createTD().cast();
|
||||
initCellWithText(text, ALIGN_LEFT, "", false, true, null, td);
|
||||
|
||||
// Enchance DOM for table cell
|
||||
Element container = (Element) td.getChild(0);
|
||||
String containerInnerHTML = container.getInnerHTML();
|
||||
|
||||
container.setInnerHTML("");
|
||||
|
||||
Element groupDiv = DOM.createDiv();
|
||||
DOM.setInnerHTML(groupDiv, " ");
|
||||
Tools.setStyleName(groupDiv, CLASSNAME + "-group-cell");
|
||||
DOM.appendChild(container, groupDiv);
|
||||
|
||||
Element contentDiv = DOM.createDiv();
|
||||
contentDiv.setInnerHTML(containerInnerHTML);
|
||||
Tools.setStyleName(contentDiv, CLASSNAME + "-float");
|
||||
DOM.appendChild(container, contentDiv);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBrowserEvent(Event event) {
|
||||
final Element targetElement = DOM.eventGetTarget(event);
|
||||
switch (DOM.eventGetType(event)) {
|
||||
case Event.ONCLICK:
|
||||
if (BrowserInfo.get().getWebkitVersion() > 0 && DOM.getElementPropertyBoolean(targetElement, "__cell")) {
|
||||
scrollBodyPanel.setFocus(true);
|
||||
}
|
||||
handleRowClick(event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleRowClick(Event event) {
|
||||
if (isExpanded()) {
|
||||
client.updateVariable(paintableId, "collapse", getGroupKey(), true);
|
||||
} else {
|
||||
client.updateVariable(paintableId, "expand", getGroupKey(), true);
|
||||
}
|
||||
DOM.eventCancelBubble(event, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleClickEvent(Event event, Element targetTdOrTr,
|
||||
boolean immediate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showContextMenu(Event event) {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
public String getColKey() {
|
||||
return colKey;
|
||||
}
|
||||
|
||||
public String getGroupKey() {
|
||||
return groupKey;
|
||||
}
|
||||
|
||||
public int getColIndex() {
|
||||
return colIndex;
|
||||
}
|
||||
|
||||
public boolean isExpanded() {
|
||||
return expanded;
|
||||
}
|
||||
|
||||
public boolean hasCells() {
|
||||
return hasCells;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveCol(int oldIndex, int newIndex) {
|
||||
//do nothing, columns reordering will be process on the server
|
||||
}
|
||||
}
|
||||
|
||||
protected class GroupDividerHeaderCell extends HeaderCell {
|
||||
public GroupDividerHeaderCell() {
|
||||
super(GROUP_DIVIDER_COLUMN_KEY, null);
|
||||
setWidth("10px");
|
||||
DOM.setElementProperty(td, "className", CLASSNAME + "-group-div");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBrowserEvent(Event event) {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleCaptionEvent(Event event) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
|
||||
protected class GroupDividerFooterCell extends FooterCell {
|
||||
|
||||
public GroupDividerFooterCell() {
|
||||
super(GROUP_DIVIDER_COLUMN_KEY, null);
|
||||
setWidth("10px");
|
||||
DOM.setElementProperty(td, "className", CLASSNAME + "-group-div");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBrowserEvent(Event event) {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleCaptionEvent(Event event) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
}
|
@ -24,8 +24,6 @@ import com.haulmont.cuba.web.toolkit.data.AggregationContainer;
|
||||
import com.haulmont.cuba.web.toolkit.data.GroupTableContainer;
|
||||
import com.haulmont.cuba.web.toolkit.ui.CubaGroupTable;
|
||||
import com.vaadin.data.Item;
|
||||
import com.vaadin.server.PaintException;
|
||||
import com.vaadin.server.PaintTarget;
|
||||
import com.vaadin.server.Resource;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.dom4j.Element;
|
||||
@ -66,22 +64,22 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable>
|
||||
// return b;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void paintContent(PaintTarget target) throws PaintException {
|
||||
super.paintContent(target);
|
||||
paintSpecificContent(target);
|
||||
}
|
||||
|
||||
// vaadin7
|
||||
// @Override
|
||||
// public void groupBy(Object[] properties) {
|
||||
// groupBy(properties, rerender);
|
||||
// public void paintContent(PaintTarget target) throws PaintException {
|
||||
// super.paintContent(target);
|
||||
// paintSpecificContent(target);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void groupBy(Object[] properties) {
|
||||
groupBy(properties, rerender);
|
||||
}
|
||||
};
|
||||
initComponent(component);
|
||||
|
||||
// vaadin7
|
||||
// component.setGroupPropertyValueFormatter(new AggregatableGroupPropertyValueFormatter());
|
||||
component.setGroupPropertyValueFormatter(new AggregatableGroupPropertyValueFormatter());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -95,12 +93,11 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable>
|
||||
|
||||
groupPropertiesElement = element.addElement("groupProperties");
|
||||
|
||||
// vaadin7
|
||||
// final Collection<?> groupProperties = component.getGroupProperties();
|
||||
// for (Object groupProperty : groupProperties) {
|
||||
// final Element groupPropertyElement = groupPropertiesElement.addElement("property");
|
||||
// groupPropertyElement.addAttribute("id", groupProperty.toString());
|
||||
// }
|
||||
final Collection<?> groupProperties = component.getGroupProperties();
|
||||
for (Object groupProperty : groupProperties) {
|
||||
final Element groupPropertyElement = groupPropertiesElement.addElement("property");
|
||||
groupPropertyElement.addAttribute("id", groupProperty.toString());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -112,10 +109,9 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable>
|
||||
final Element groupPropertiesElement = element.element("groupProperties");
|
||||
if (groupPropertiesElement != null) {
|
||||
final List elements = groupPropertiesElement.elements("property");
|
||||
final List<MetaPropertyPath> properties = new ArrayList<MetaPropertyPath>(elements.size());
|
||||
final List<MetaPropertyPath> properties = new ArrayList<>(elements.size());
|
||||
for (final Object o : elements) {
|
||||
final MetaPropertyPath property = datasource.getMetaClass().getPropertyEx(
|
||||
((Element) o).attributeValue("id")
|
||||
final MetaPropertyPath property = datasource.getMetaClass().getPropertyPath(((Element) o).attributeValue("id")
|
||||
);
|
||||
properties.add(property);
|
||||
}
|
||||
@ -162,39 +158,32 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable>
|
||||
|
||||
@Override
|
||||
public void groupBy(Object[] properties) {
|
||||
// vaadin7
|
||||
// component.groupBy(properties);
|
||||
component.groupBy(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expandAll() {
|
||||
// vaadin7
|
||||
// component.expandAll();
|
||||
component.expandAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expand(GroupInfo groupId) {
|
||||
// vaadin7
|
||||
// component.expand(groupId);
|
||||
component.expand(groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collapseAll() {
|
||||
// vaadin7
|
||||
// component.collapseAll();
|
||||
component.collapseAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collapse(GroupInfo groupId) {
|
||||
// vaadin7
|
||||
// component.collapse(groupId);
|
||||
component.collapse(groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpanded(GroupInfo groupId) {
|
||||
// vaadin7
|
||||
// return component.isExpanded(groupId);
|
||||
return false;
|
||||
return component.isExpanded(groupId);
|
||||
}
|
||||
|
||||
protected class GroupTableDsWrapper extends SortableCollectionDsWrapper
|
||||
@ -428,6 +417,7 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable>
|
||||
@Override
|
||||
public void collapse(Object id) {
|
||||
if (isGroup(id)) {
|
||||
//noinspection RedundantCast
|
||||
expanded.remove((GroupInfo)id);
|
||||
resetCachedItems();
|
||||
}
|
||||
@ -435,6 +425,7 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable>
|
||||
|
||||
@Override
|
||||
public boolean isExpanded(Object id) {
|
||||
//noinspection RedundantCast
|
||||
return isGroup(id) && expanded.contains((GroupInfo)id);
|
||||
}
|
||||
|
||||
@ -617,18 +608,16 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable>
|
||||
@Override
|
||||
public void stateChanged(Datasource<Entity> ds, Datasource.State prevState, Datasource.State state) {
|
||||
rerender = false;
|
||||
// vaadin7
|
||||
// Collection groupProperties = component.getGroupProperties();
|
||||
// component.groupBy(groupProperties.toArray());
|
||||
Collection groupProperties = component.getGroupProperties();
|
||||
component.groupBy(groupProperties.toArray());
|
||||
super.stateChanged(ds, prevState, state);
|
||||
rerender = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectionChanged(CollectionDatasource ds, Operation operation, List<Entity> items) {
|
||||
// vaadin7
|
||||
// Collection groupProperties = component.getGroupProperties();
|
||||
// component.groupBy(groupProperties.toArray());
|
||||
Collection groupProperties = component.getGroupProperties();
|
||||
component.groupBy(groupProperties.toArray());
|
||||
super.collectionChanged(ds, operation, items);
|
||||
}
|
||||
}
|
||||
@ -639,15 +628,12 @@ public class WebGroupTable extends WebAbstractTable<CubaGroupTable>
|
||||
@Override
|
||||
public String format(Object groupId, Object value) {
|
||||
String formattedValue = super.format(groupId, value);
|
||||
// vaadin7
|
||||
// int count = WebGroupTable.this.component.getGroupItemsCount(groupId);
|
||||
// return String.format("%s (%d)", formattedValue == null ? "" : formattedValue, count);
|
||||
return formattedValue;
|
||||
int count = WebGroupTable.this.component.getGroupItemsCount(groupId);
|
||||
return String.format("%s (%d)", formattedValue == null ? "" : formattedValue, count);
|
||||
}
|
||||
}
|
||||
|
||||
protected class DefaultGroupPropertyValueFormatter
|
||||
implements com.haulmont.cuba.web.toolkit.ui.GroupTable.GroupPropertyValueFormatter {
|
||||
protected class DefaultGroupPropertyValueFormatter implements CubaGroupTable.GroupPropertyValueFormatter {
|
||||
|
||||
@Override
|
||||
public String format(Object groupId, Object value) {
|
||||
|
@ -2,11 +2,6 @@
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
|
||||
* Author: Nikolay Gorodnov
|
||||
* Created: 10.11.2009 18:00:23
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
package com.haulmont.cuba.web.toolkit.data;
|
||||
|
||||
@ -14,6 +9,10 @@ import com.vaadin.data.Container;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author gorodnov
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface GroupTableContainer extends Container.Sortable {
|
||||
void groupBy(Object[] properties);
|
||||
|
||||
@ -44,4 +43,4 @@ public interface GroupTableContainer extends Container.Sortable {
|
||||
void collapse(Object id);
|
||||
|
||||
boolean isExpanded(Object id);
|
||||
}
|
||||
}
|
@ -1,19 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Copyright (c) 2008 Haulmont Technology Ltd. All Rights Reserved.
|
||||
* Haulmont Technology proprietary and confidential.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.web.toolkit.ui;
|
||||
|
||||
import com.haulmont.cuba.gui.data.GroupInfo;
|
||||
import com.haulmont.cuba.web.gui.data.PropertyValueStringify;
|
||||
import com.haulmont.cuba.web.toolkit.data.GroupTableContainer;
|
||||
import com.haulmont.cuba.web.toolkit.data.util.GroupTableContainerWrapper;
|
||||
import com.vaadin.data.Container;
|
||||
import com.vaadin.data.Property;
|
||||
import com.vaadin.data.util.IndexedContainer;
|
||||
import com.vaadin.server.KeyMapper;
|
||||
import com.vaadin.server.PaintException;
|
||||
import com.vaadin.server.PaintTarget;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author artamonov
|
||||
* @author gorodnov
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CubaGroupTable extends com.vaadin.ui.Table {
|
||||
public class CubaGroupTable extends com.vaadin.ui.Table implements GroupTableContainer {
|
||||
|
||||
private KeyMapper groupIdMap = new KeyMapper();
|
||||
|
||||
private GroupPropertyValueFormatter groupPropertyValueFormatter;
|
||||
|
||||
@Override
|
||||
public void setContainerDataSource(Container newDataSource) {
|
||||
if (newDataSource == null) {
|
||||
newDataSource = new IndexedContainer();
|
||||
}
|
||||
|
||||
super.setContainerDataSource(new GroupTableContainerWrapper(newDataSource));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatPropertyValue(Object rowId, Object colId, Property<?> property) {
|
||||
@ -22,4 +45,299 @@ public class CubaGroupTable extends com.vaadin.ui.Table {
|
||||
|
||||
return super.formatPropertyValue(rowId, colId, property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintContent(PaintTarget target) throws PaintException {
|
||||
super.paintContent(target);
|
||||
|
||||
if (hasGroups()) {
|
||||
final Collection groupProperties = getGroupProperties();
|
||||
final String[] groupColumns = new String[groupProperties.size()];
|
||||
|
||||
int index = 0;
|
||||
for (final Object groupColumnId : groupProperties) {
|
||||
groupColumns[index++] = columnIdMap.key(groupColumnId);
|
||||
}
|
||||
target.addVariable(this, "groupColumns", groupColumns);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean changeVariables(Map<String, Object> variables) {
|
||||
boolean clientNeedsContentRefresh = super.changeVariables(variables);
|
||||
|
||||
boolean needsResetPageBuffer = false;
|
||||
Object[] newGroupProperties = null;
|
||||
|
||||
if (variables.containsKey("columnorder") && !variables.containsKey("groupedcolumns")) {
|
||||
newGroupProperties = new Object[0];
|
||||
} else if (variables.containsKey("groupedcolumns")) {
|
||||
final Object[] ids = (Object[]) variables.get("groupedcolumns");
|
||||
final Object[] groupProperties = new Object[ids.length];
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
groupProperties[i] = columnIdMap.get(ids[i].toString());
|
||||
}
|
||||
newGroupProperties = groupProperties;
|
||||
// Deny group by generated columns
|
||||
if (!columnGenerators.isEmpty()) {
|
||||
List<Object> notGeneratedProperties = new ArrayList<>();
|
||||
for (Object id : newGroupProperties) {
|
||||
if (!columnGenerators.containsKey(id))
|
||||
notGeneratedProperties.add(id);
|
||||
}
|
||||
newGroupProperties = notGeneratedProperties.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (variables.containsKey("collapsedcolumns")) {
|
||||
boolean needToRegroup = false;
|
||||
final List<Object> groupProperties = new ArrayList<>(getGroupProperties());
|
||||
for (int index = 0; index < groupProperties.size(); index++) {
|
||||
final Object propertyId = groupProperties.get(index);
|
||||
if (isColumnCollapsed(propertyId)) {
|
||||
groupProperties.subList(index, groupProperties.size())
|
||||
.clear();
|
||||
needToRegroup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (needToRegroup) {
|
||||
newGroupProperties = groupProperties.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (variables.containsKey("expand")) {
|
||||
Object groupId = groupIdMap.get((String) variables.get("expand"));
|
||||
expand(groupId, false);
|
||||
clientNeedsContentRefresh = true;
|
||||
needsResetPageBuffer = true;
|
||||
}
|
||||
|
||||
if (variables.containsKey("collapse")) {
|
||||
Object groupId = groupIdMap.get((String) variables.get("collapse"));
|
||||
collapse(groupId, false);
|
||||
clientNeedsContentRefresh = true;
|
||||
needsResetPageBuffer = true;
|
||||
}
|
||||
|
||||
if (newGroupProperties != null) {
|
||||
groupBy(newGroupProperties, false);
|
||||
}
|
||||
|
||||
if (needsResetPageBuffer) {
|
||||
resetPageBuffer();
|
||||
}
|
||||
|
||||
return clientNeedsContentRefresh;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintRowAttributes(PaintTarget target, Object itemId) throws PaintException {
|
||||
super.paintRowAttributes(target, itemId);
|
||||
|
||||
boolean hasGroups = hasGroups();
|
||||
if (hasGroups) {
|
||||
if (isGroup(itemId)) {
|
||||
target.addAttribute("colKey", columnIdMap.key(getGroupProperty(itemId)));
|
||||
target.addAttribute("groupKey", groupIdMap.key(itemId));
|
||||
if (isExpanded(itemId))
|
||||
target.addAttribute("expanded", true);
|
||||
|
||||
final Object propertyValue = getGroupPropertyValue(itemId);
|
||||
target.addAttribute("groupCaption", formatGroupPropertyValue(itemId, propertyValue));
|
||||
|
||||
// todo aggregation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LinkedHashSet<Object> getItemIdsInRange(Object startItemId, final int length) {
|
||||
Set<Object> rootIds = super.getItemIdsInRange(startItemId, length);
|
||||
LinkedHashSet<Object> ids = new LinkedHashSet<>();
|
||||
for (Object itemId: rootIds) {
|
||||
if (itemId instanceof GroupInfo) {
|
||||
if (!isExpanded(itemId)) {
|
||||
Collection<?> itemIds = getGroupItemIds(itemId);
|
||||
ids.addAll(itemIds);
|
||||
expand(itemId, true);
|
||||
}
|
||||
|
||||
List<GroupInfo> children = (List<GroupInfo>) getChildren(itemId);
|
||||
for (GroupInfo groupInfo : children) {
|
||||
if (!isExpanded(groupInfo)) {
|
||||
expand(groupInfo, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ids.add(itemId);
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isColumnNeedsToRefreshRendered(Object colId) {
|
||||
final GroupTableContainer items = (GroupTableContainer) this.items;
|
||||
final boolean groupped = items.hasGroups();
|
||||
|
||||
return !groupped || !getGroupProperties().contains(colId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isItemNeedsToRefreshRendered(Object itemId) {
|
||||
final GroupTableContainer items = (GroupTableContainer) this.items;
|
||||
final boolean groupped = items.hasGroups();
|
||||
|
||||
return !groupped || !items.isGroup(itemId);
|
||||
}
|
||||
|
||||
protected String formatGroupPropertyValue(Object groupId, Object groupValue) {
|
||||
return groupPropertyValueFormatter != null
|
||||
? groupPropertyValueFormatter.format(groupId, groupValue)
|
||||
: (groupValue == null ? "" : groupValue.toString());
|
||||
}
|
||||
|
||||
protected void expand(Object id, boolean rerender) {
|
||||
final int pageIndex = getCurrentPageFirstItemIndex();
|
||||
((GroupTableContainer) items).expand(id);
|
||||
setCurrentPageFirstItemIndex(pageIndex, false);
|
||||
if (rerender) {
|
||||
resetPageBuffer();
|
||||
refreshRenderedCells();
|
||||
markAsDirty();
|
||||
}
|
||||
}
|
||||
|
||||
protected void collapse(Object id, boolean rerender) {
|
||||
final int pageIndex = getCurrentPageFirstItemIndex();
|
||||
((GroupTableContainer) items).collapse(id);
|
||||
setCurrentPageFirstItemIndex(pageIndex, false);
|
||||
if (rerender) {
|
||||
resetPageBuffer();
|
||||
refreshRenderedCells();
|
||||
markAsDirty();
|
||||
}
|
||||
}
|
||||
|
||||
protected void groupBy(Object[] properties, boolean rerender) {
|
||||
((GroupTableContainer) items).groupBy(properties);
|
||||
if (rerender) {
|
||||
resetPageBuffer();
|
||||
refreshRenderedCells();
|
||||
markAsDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<?> getGroupProperties() {
|
||||
Collection<?> groupProperties = ((GroupTableContainer) items).getGroupProperties();
|
||||
// Deny group by generated columns
|
||||
if (!columnGenerators.isEmpty()) {
|
||||
List<Object> notGeneratedGroupProps = new ArrayList<>();
|
||||
for (Object id : groupProperties) {
|
||||
if (!columnGenerators.containsKey(id))
|
||||
notGeneratedGroupProps.add(id);
|
||||
}
|
||||
return notGeneratedGroupProps;
|
||||
} else
|
||||
return groupProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expandAll() {
|
||||
final int pageIndex = getCurrentPageFirstItemIndex();
|
||||
((GroupTableContainer) items).expandAll();
|
||||
setCurrentPageFirstItemIndex(pageIndex, false);
|
||||
resetPageBuffer();
|
||||
refreshRenderedCells();
|
||||
markAsDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void expand(Object id) {
|
||||
expand(id, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collapseAll() {
|
||||
final int pageIndex = getCurrentPageFirstItemIndex();
|
||||
((GroupTableContainer) items).collapseAll();
|
||||
setCurrentPageFirstItemIndex(pageIndex, false);
|
||||
resetPageBuffer();
|
||||
refreshRenderedCells();
|
||||
markAsDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collapse(Object id) {
|
||||
collapse(id, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGroups() {
|
||||
return ((GroupTableContainer) items).hasGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void groupBy(Object[] properties) {
|
||||
groupBy(properties, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGroup(Object itemId) {
|
||||
return ((GroupTableContainer) items).isGroup(itemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<?> rootGroups() {
|
||||
return ((GroupTableContainer) items).rootGroups();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasChildren(Object id) {
|
||||
return ((GroupTableContainer) items).hasChildren(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<?> getChildren(Object id) {
|
||||
return ((GroupTableContainer) items).getChildren(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGroupProperty(Object itemId) {
|
||||
return ((GroupTableContainer) items).getGroupProperty(itemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGroupPropertyValue(Object itemId) {
|
||||
return ((GroupTableContainer) items).getGroupPropertyValue(itemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<?> getGroupItemIds(Object itemId) {
|
||||
return ((GroupTableContainer) items).getGroupItemIds(itemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupItemsCount(Object itemId) {
|
||||
return ((GroupTableContainer) items).getGroupItemsCount(itemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpanded(Object id) {
|
||||
return ((GroupTableContainer) items).isExpanded(id);
|
||||
}
|
||||
|
||||
public GroupPropertyValueFormatter getGroupPropertyValueFormatter() {
|
||||
return groupPropertyValueFormatter;
|
||||
}
|
||||
|
||||
public void setGroupPropertyValueFormatter(GroupPropertyValueFormatter groupPropertyValueFormatter) {
|
||||
this.groupPropertyValueFormatter = groupPropertyValueFormatter;
|
||||
}
|
||||
|
||||
public interface GroupPropertyValueFormatter {
|
||||
String format(Object groupId, Object value);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user