teichmann@5861: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
teichmann@5861: * Software engineering by Intevation GmbH
teichmann@5861: *
teichmann@5993: * This file is Free Software under the GNU AGPL (>=v3)
teichmann@5861: * and comes with ABSOLUTELY NO WARRANTY! Check out the
teichmann@5993: * documentation coming with Dive4Elements River for details.
teichmann@5861: */
teichmann@5861:
teichmann@5835: package org.dive4elements.river.client.client.ui;
raimund@256:
gernotbelger@9064: import java.util.List;
gernotbelger@9171: import java.util.Map;
gernotbelger@9171: import java.util.TreeMap;
gernotbelger@9064:
gernotbelger@9064: import org.dive4elements.river.client.client.Config;
gernotbelger@9064: import org.dive4elements.river.client.client.FLYSConstants;
gernotbelger@9064: import org.dive4elements.river.client.client.services.CSVExportService;
gernotbelger@9064: import org.dive4elements.river.client.client.services.CSVExportServiceAsync;
gernotbelger@9064:
raimund@256: import com.google.gwt.core.client.GWT;
christian@4184: import com.google.gwt.i18n.client.NumberFormat;
gernotbelger@9314: import com.google.gwt.safehtml.shared.SafeHtmlUtils;
raimund@256: import com.google.gwt.user.client.rpc.AsyncCallback;
gernotbelger@9167: import com.smartgwt.client.data.Record;
christian@4184: import com.smartgwt.client.types.ListGridFieldType;
ingo@550: import com.smartgwt.client.util.SC;
raimund@256: import com.smartgwt.client.widgets.Canvas;
raimund@256: import com.smartgwt.client.widgets.grid.ListGrid;
raimund@256: import com.smartgwt.client.widgets.grid.ListGridField;
christian@4184: import com.smartgwt.client.widgets.layout.VLayout;
gernotbelger@9167: import com.smartgwt.client.widgets.tab.Tab;
gernotbelger@9167: import com.smartgwt.client.widgets.tab.TabSet;
raimund@256:
raimund@256: /**
raimund@256: * This UIProvider creates a widget that displays calculated data in a table.
raimund@256: *
raimund@256: * @author Raimund Renkert
raimund@256: */
gernotbelger@9064: public class TableDataPanel {
felix@810: /** The message class that provides i18n strings. */
raimund@256: protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
raimund@256:
gernotbelger@9064: protected CSVExportServiceAsync exportService = GWT.create(CSVExportService.class);
raimund@256:
felix@810: /** A container that will contain the location or the distance panel. */
raimund@256: protected VLayout container;
raimund@256:
felix@810: /** The export type. */
raimund@256: protected String name;
raimund@256:
felix@810: /** The UUID of the collection. */
raimund@256: protected String uuid;
raimund@256:
felix@810: /** The table. */
raimund@256: protected ListGrid dataTable;
raimund@256:
gernotbelger@9167: private final TabSet tabSet;
gernotbelger@9167:
raimund@256: /**
felix@7616: * Creates a new TableDataPanel instance.
raimund@256: */
raimund@256: public TableDataPanel() {
gernotbelger@9064: this.container = new VLayout();
gernotbelger@9064: this.dataTable = new ListGrid();
gernotbelger@9167: this.tabSet = new TabSet();
gernotbelger@9064: this.name = "";
raimund@256: }
raimund@256:
raimund@256: /**
felix@810: * This method creates a widget that contains a table.
raimund@256: *
raimund@256: * @return a panel.
raimund@256: */
raimund@256: public Canvas create() {
gernotbelger@9064: final Config config = Config.getInstance();
gernotbelger@9064: final String locale = config.getLocale();
gernotbelger@9064: this.dataTable.setEmptyMessage(this.MESSAGES.empty_table());
gernotbelger@9064: this.dataTable.setShowHeaderContextMenu(false);
gernotbelger@9064: this.dataTable.setCanDragSelectText(true);
raimund@256:
gernotbelger@9064: this.exportService.getCSV(locale, this.uuid, this.name, new AsyncCallback>() {
gernotbelger@9064: @Override
gernotbelger@9064: public void onFailure(final Throwable caught) {
gernotbelger@9064: GWT.log("Could not receive csv.");
gernotbelger@9064: SC.warn(caught.getMessage());
gernotbelger@9064: }
raimund@256:
gernotbelger@9064: @Override
gernotbelger@9064: public void onSuccess(final List l) {
gernotbelger@9064: GWT.log("Recieved csv with " + l.size() + " lines.");
gernotbelger@9064: setData(l);
raimund@256: }
gernotbelger@9064: });
gernotbelger@9064: this.container.addMember(this.dataTable);
raimund@256:
gernotbelger@9064: return this.container;
raimund@256: }
raimund@256:
gernotbelger@9064: public void setName(final String name) {
gernotbelger@9064: this.name = name;
raimund@256: }
raimund@256:
gernotbelger@9064: public void setUuid(final String uuid) {
gernotbelger@9064: this.uuid = uuid;
raimund@256: }
raimund@256:
raimund@259: /**
christian@4184: * This method sets the data to a dynamic table.
raimund@259: *
gernotbelger@9064: * @param list
gernotbelger@9064: * List of String[] containing the data.
raimund@259: */
gernotbelger@9167:
gernotbelger@9064: public void setData(final List list) {
ingo@1289: if (list == null || list.size() < 2) {
gernotbelger@9064: this.dataTable.setEmptyMessage(this.MESSAGES.error_no_calc_result());
gernotbelger@9064: this.dataTable.redraw();
ingo@1289: return;
ingo@1289: }
ingo@1289:
gernotbelger@9064: final Config config = Config.getInstance();
gernotbelger@9064: final String locale = config.getLocale();
ingo@1486:
ingo@1486: NumberFormat nf;
ingo@1486: if (locale.equals("de")) {
ingo@1486: nf = NumberFormat.getFormat("#,##");
gernotbelger@9064: } else {
ingo@1486: nf = NumberFormat.getFormat("#.##");
ingo@1486: }
gernotbelger@9171: final Map> tabData = getTabData(list);
gernotbelger@9167: if (tabData.size() == 1) {
gernotbelger@9326: createTable(this.dataTable, tabData.get(tabData.keySet().iterator().next()), nf);
gernotbelger@9167:
gernotbelger@9167: } else if (tabData.size() > 1) {
gernotbelger@9167:
gernotbelger@9171: for (final String key : tabData.keySet()) {
gernotbelger@9171: final List items = tabData.get(key);
gernotbelger@9167:
gernotbelger@9167: final ListGrid table = new ListGrid();
gernotbelger@9167:
gernotbelger@9326: createTable(table, items, nf);
gernotbelger@9167: final Tab tab = new Tab();
gernotbelger@9171: tab.setTitle(key);
gernotbelger@9167: tab.setPane(table);
gernotbelger@9167: this.tabSet.addTab(tab);
gernotbelger@9167: }
gernotbelger@9167: this.tabSet.selectTab(0);
gernotbelger@9167: this.container.removeChild(this.dataTable);
gernotbelger@9167: this.container.addChild(this.tabSet);
gernotbelger@9167: this.tabSet.setWidth100();
gernotbelger@9167: this.tabSet.setHeight100();
gernotbelger@9167: }
gernotbelger@9167: }
gernotbelger@9167:
gernotbelger@9326: private void createTable(final ListGrid dataTableTab, final List list, final NumberFormat nf) {
ingo@1486:
gernotbelger@9064: final String[] header = list.get(0);
gernotbelger@9064: final String[] displayField = new String[header.length];
ingo@1289:
gernotbelger@9064: final ListGridField[] fields = new ListGridField[header.length];
ingo@1486:
gernotbelger@9064: for (int i = 0; i < header.length; i++) {
gernotbelger@9064: final ListGridField f = new ListGridField(String.valueOf(i));
raimund@259: fields[i] = f;
raimund@259: f.setTitle(header[i]);
raimund@906:
raimund@906: try {
gernotbelger@9064: /*
gernotbelger@9064: * Try to determine the type with the first
gernotbelger@9167: * non empty element. -> WARUM??! OK, nur Formatierung/Sortierung
gernotbelger@9064: */
andre@8632: for (int j = 1; j < list.size(); j++) {
andre@8632: if (!list.get(j)[i].isEmpty()) {
andre@8632: nf.parse(list.get(j)[i]);
andre@8632: f.setType(ListGridFieldType.FLOAT);
gernotbelger@9167:
andre@8632: break;
andre@8632: }
andre@8632: }
raimund@906: }
gernotbelger@9064: catch (final NumberFormatException nfe) {
raimund@906: f.setType(ListGridFieldType.TEXT);
raimund@906: }
felix@7617:
felix@7602: // To keep server-side formatting and i18n also of
felix@7602: // float values, we will store the value once formatted 'as is'
felix@7602: // to be displayed and once as e.g. float to allow functions like
felix@7602: // sorting on it.
gernotbelger@9167: displayField[i] = "$" + i + "_displayField";
felix@7602: f.setDisplayField(displayField[i]);
felix@7602: f.setValueField(String.valueOf(i));
felix@7602: f.setSortByDisplayField(false);
gernotbelger@9167: }
gernotbelger@9167: dataTableTab.setFields(fields);
raimund@259:
gernotbelger@9167: for (int i = 1; i < list.size(); i++) { // index bei 1, da erster Eintrag Header ist
gernotbelger@9167:
gernotbelger@9064: final String[] sItem = list.get(i);
gernotbelger@9167: final Record r = new Record();
gernotbelger@9064: for (int j = 0; j < sItem.length; j++) {
felix@7602: // See above, display 'as is' from server, but keep value
felix@7602: // in machine-usable way (float), to allow numeric sorting.
gernotbelger@9353: final String item = sItem[j];
gernotbelger@9353: final String encodedText = SafeHtmlUtils.htmlEscapeAllowEntities(item);
gernotbelger@9353:
gernotbelger@9314: r.setAttribute(displayField[j], encodedText);
felix@7602: if (fields[j].getType() == ListGridFieldType.TEXT) {
gernotbelger@9314: r.setAttribute(String.valueOf(j), item);
gernotbelger@9064: } else {
felix@7617: try {
gernotbelger@9314: final Float valueFloatSortable = (float) nf.parse(item);
gernotbelger@9167: r.setAttribute(String.valueOf(j), valueFloatSortable);
felix@7617: }
gernotbelger@9064: catch (final NumberFormatException nfe) {
gernotbelger@9314: r.setAttribute(String.valueOf(j), item);
felix@7617: }
felix@7602: }
gernotbelger@9167:
raimund@256: }
gernotbelger@9167:
gernotbelger@9167: dataTableTab.addData(r);
raimund@256: }
raimund@256: }
gernotbelger@9167:
gernotbelger@9171: private Map> getTabData(final List raw) {
gernotbelger@9171: // Condition: tableTitle must be first
gernotbelger@9171: final Map> tabs = new TreeMap>(); // auto-sort
gernotbelger@9167:
gernotbelger@9171: if (raw.get(0)[0].startsWith(this.MESSAGES.export_csv_title())) {
gernotbelger@9171: // Bedingung für Tabs
gernotbelger@9171: int lastIndex = 0;
gernotbelger@9171: String lastTableTitle = "";
gernotbelger@9171:
gernotbelger@9171: for (int i = 0; i < raw.size(); i++) {
gernotbelger@9171:
gernotbelger@9171: final String[] row = raw.get(i);
gernotbelger@9171: if (row[0].startsWith(this.MESSAGES.export_csv_title())) {
gernotbelger@9171:
gernotbelger@9171: if (i > 0) {
gernotbelger@9171: tabs.put(makeKeyTitle(lastTableTitle, tabs.size()), raw.subList((lastIndex + 1), (i))); // toIndex exclusive (without
gernotbelger@9171: // tabTitle-Line of the next tab, which is
gernotbelger@9171: // stored in the current row (raw.get(i));
gernotbelger@9171: // fromIndex
gernotbelger@9171: // inclusive ->
gernotbelger@9171: // without tabTitle from the past tab ->
gernotbelger@9171: // lastindex+1
gernotbelger@9171: }
gernotbelger@9171: lastTableTitle = row[0].replace(this.MESSAGES.export_csv_title(), "");
gernotbelger@9171: lastIndex = i;
gernotbelger@9171: }
gernotbelger@9171:
gernotbelger@9171: if (i == (raw.size() - 1)) {
gernotbelger@9171: tabs.put(makeKeyTitle(lastTableTitle, tabs.size()), raw.subList((lastIndex + 1), i + 1));
gernotbelger@9171: // last result-tab:
gernotbelger@9171: // toIndex exclusive -> last i + 1
gernotbelger@9171: // fromIndex inclusive: lastInde +1 -> no title-line included
gernotbelger@9171: }
gernotbelger@9171:
gernotbelger@9167: }
gernotbelger@9171: } else {
gernotbelger@9171: // plainOld Table, no TABS
gernotbelger@9171: tabs.put("", raw);
gernotbelger@9167: }
gernotbelger@9167:
gernotbelger@9167: return tabs;
gernotbelger@9167: }
gernotbelger@9171:
gernotbelger@9171: private String makeKeyTitle(final String title, final int index) {
gernotbelger@9171: return new StringBuilder().append("(").append((index + 1)).append(") ").append(title).toString();
gernotbelger@9171: }
raimund@256: }
raimund@256: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :