Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Unified Diff: frontend/client/src/autotest/tko/Spreadsheet.java

Issue 1595019: Merge remote branch 'origin/upstream' into tempbranch (Closed)
Patch Set: Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: frontend/client/src/autotest/tko/Spreadsheet.java
diff --git a/frontend/client/src/autotest/tko/Spreadsheet.java b/frontend/client/src/autotest/tko/Spreadsheet.java
index 4d25130386ae19c5ae8ecbc9f2fae118d4322944..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/frontend/client/src/autotest/tko/Spreadsheet.java
+++ b/frontend/client/src/autotest/tko/Spreadsheet.java
@@ -1,587 +0,0 @@
-package autotest.tko;
-
-import autotest.common.UnmodifiableSublistView;
-import autotest.common.Utils;
-import autotest.common.ui.RightClickTable;
-
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.ContextMenuEvent;
-import com.google.gwt.event.dom.client.ContextMenuHandler;
-import com.google.gwt.event.dom.client.DomEvent;
-import com.google.gwt.event.dom.client.ScrollEvent;
-import com.google.gwt.event.dom.client.ScrollHandler;
-import com.google.gwt.user.client.DeferredCommand;
-import com.google.gwt.user.client.IncrementalCommand;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.Composite;
-import com.google.gwt.user.client.ui.FlexTable;
-import com.google.gwt.user.client.ui.HTMLTable;
-import com.google.gwt.user.client.ui.Panel;
-import com.google.gwt.user.client.ui.ScrollPanel;
-import com.google.gwt.user.client.ui.SimplePanel;
-import com.google.gwt.user.client.ui.Widget;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class Spreadsheet extends Composite
- implements ScrollHandler, ClickHandler, ContextMenuHandler {
-
- private static final int MIN_TABLE_SIZE_PX = 90;
- private static final int WINDOW_BORDER_PX = 15;
- private static final int SCROLLBAR_FUDGE = 16;
- private static final String BLANK_STRING = "(empty)";
- private static final int CELL_PADDING_PX = 2;
- private static final int TD_BORDER_PX = 1;
- private static final String HIGHLIGHTED_CLASS = "highlighted";
- private static final int CELLS_PER_ITERATION = 1000;
-
- private Header rowFields, columnFields;
- private List<Header> rowHeaderValues = new ArrayList<Header>();
- private List<Header> columnHeaderValues = new ArrayList<Header>();
- private Map<Header, Integer> rowHeaderMap = new HashMap<Header, Integer>();
- private Map<Header, Integer> columnHeaderMap = new HashMap<Header, Integer>();
- protected CellInfo[][] dataCells, rowHeaderCells, columnHeaderCells;
- private RightClickTable rowHeaders = new RightClickTable();
- private RightClickTable columnHeaders = new RightClickTable();
- private FlexTable parentTable = new FlexTable();
- private FragmentedTable dataTable = new FragmentedTable();
- private int rowsPerIteration;
- private Panel rowHeadersClipPanel, columnHeadersClipPanel;
- private ScrollPanel scrollPanel = new ScrollPanel(dataTable);
- private TableRenderer renderer = new TableRenderer();
-
- private SpreadsheetListener listener;
-
- public interface SpreadsheetListener {
- public void onCellClicked(CellInfo cellInfo, boolean isRightClick);
- }
-
- public static interface Header extends List<String> {}
- public static class HeaderImpl extends ArrayList<String> implements Header {
- public HeaderImpl() {
- }
-
- public HeaderImpl(Collection<? extends String> arg0) {
- super(arg0);
- }
-
- public static Header fromBaseType(List<String> baseType) {
- return new HeaderImpl(baseType);
- }
- }
-
- public static class CellInfo {
- public Header row, column;
- public String contents;
- public String color;
- public Integer widthPx, heightPx;
- public int rowSpan = 1, colSpan = 1;
- public int testCount = 0;
- public int testIndex;
-
- public CellInfo(Header row, Header column, String contents) {
- this.row = row;
- this.column = column;
- this.contents = contents;
- }
-
- public boolean isHeader() {
- return !isEmpty() && (row == null || column == null);
- }
-
- public boolean isEmpty() {
- return row == null && column == null;
- }
- }
-
- private class RenderCommand implements IncrementalCommand {
- private int state = 0;
- private int rowIndex = 0;
- private IncrementalCommand onFinished;
-
- public RenderCommand(IncrementalCommand onFinished) {
- this.onFinished = onFinished;
- }
-
- private void renderSomeRows() {
- renderer.renderRowsAndAppend(dataTable, dataCells,
- rowIndex, rowsPerIteration, true);
- rowIndex += rowsPerIteration;
- if (rowIndex > dataCells.length) {
- state++;
- }
- }
-
- public boolean execute() {
- switch (state) {
- case 0:
- computeRowsPerIteration();
- computeHeaderCells();
- break;
- case 1:
- renderHeaders();
- expandRowHeaders();
- break;
- case 2:
- // resize everything to the max dimensions (the window size)
- fillWindow(false);
- break;
- case 3:
- // set main table to match header sizes
- matchRowHeights(rowHeaders, dataCells);
- matchColumnWidths(columnHeaders, dataCells);
- dataTable.setVisible(false);
- break;
- case 4:
- // render the main data table
- renderSomeRows();
- return true;
- case 5:
- dataTable.updateBodyElems();
- dataTable.setVisible(true);
- break;
- case 6:
- // now expand headers as necessary
- // this can be very slow, so put it in it's own cycle
- matchRowHeights(dataTable, rowHeaderCells);
- break;
- case 7:
- matchColumnWidths(dataTable, columnHeaderCells);
- renderHeaders();
- break;
- case 8:
- // shrink the scroller if the table ended up smaller than the window
- fillWindow(true);
- DeferredCommand.addCommand(onFinished);
- return false;
- }
-
- state++;
- return true;
- }
- }
-
- public Spreadsheet() {
- dataTable.setStyleName("spreadsheet-data");
- killPaddingAndSpacing(dataTable);
-
- rowHeaders.setStyleName("spreadsheet-headers");
- killPaddingAndSpacing(rowHeaders);
- rowHeadersClipPanel = wrapWithClipper(rowHeaders);
-
- columnHeaders.setStyleName("spreadsheet-headers");
- killPaddingAndSpacing(columnHeaders);
- columnHeadersClipPanel = wrapWithClipper(columnHeaders);
-
- scrollPanel.setStyleName("spreadsheet-scroller");
- scrollPanel.setAlwaysShowScrollBars(true);
- scrollPanel.addScrollHandler(this);
-
- parentTable.setStyleName("spreadsheet-parent");
- killPaddingAndSpacing(parentTable);
- parentTable.setWidget(0, 1, columnHeadersClipPanel);
- parentTable.setWidget(1, 0, rowHeadersClipPanel);
- parentTable.setWidget(1, 1, scrollPanel);
-
- setupTableInput(dataTable);
- setupTableInput(rowHeaders);
- setupTableInput(columnHeaders);
-
- initWidget(parentTable);
- }
-
- private void setupTableInput(RightClickTable table) {
- table.addContextMenuHandler(this);
- table.addClickHandler(this);
- }
-
- protected void killPaddingAndSpacing(HTMLTable table) {
- table.setCellSpacing(0);
- table.setCellPadding(0);
- }
-
- /*
- * Wrap a widget with a panel that will clip its contents rather than grow
- * too much.
- */
- protected Panel wrapWithClipper(Widget w) {
- SimplePanel wrapper = new SimplePanel();
- wrapper.add(w);
- wrapper.setStyleName("clipper");
- return wrapper;
- }
-
- public void setHeaderFields(Header rowFields, Header columnFields) {
- this.rowFields = rowFields;
- this.columnFields = columnFields;
- }
-
- private void addHeader(List<Header> headerList, Map<Header, Integer> headerMap,
- List<String> header) {
- Header headerObject = HeaderImpl.fromBaseType(header);
- assert !headerMap.containsKey(headerObject);
- headerList.add(headerObject);
- headerMap.put(headerObject, headerMap.size());
- }
-
- public void addRowHeader(List<String> header) {
- addHeader(rowHeaderValues, rowHeaderMap, header);
- }
-
- public void addColumnHeader(List<String> header) {
- addHeader(columnHeaderValues, columnHeaderMap, header);
- }
-
- private int getHeaderPosition(Map<Header, Integer> headerMap, Header header) {
- assert headerMap.containsKey(header);
- return headerMap.get(header);
- }
-
- private int getRowPosition(Header rowHeader) {
- return getHeaderPosition(rowHeaderMap, rowHeader);
- }
-
- private int getColumnPosition(Header columnHeader) {
- return getHeaderPosition(columnHeaderMap, columnHeader);
- }
-
- /**
- * Must be called after adding headers but before adding data
- */
- public void prepareForData() {
- dataCells = new CellInfo[rowHeaderValues.size()][columnHeaderValues.size()];
- }
-
- public CellInfo getCellInfo(int row, int column) {
- Header rowHeader = rowHeaderValues.get(row);
- Header columnHeader = columnHeaderValues.get(column);
- if (dataCells[row][column] == null) {
- dataCells[row][column] = new CellInfo(rowHeader, columnHeader, "");
- }
- return dataCells[row][column];
- }
-
- private CellInfo getCellInfo(CellInfo[][] cells, int row, int column) {
- if (cells[row][column] == null) {
- cells[row][column] = new CellInfo(null, null, " ");
- }
- return cells[row][column];
- }
-
- /**
- * Render the data into HTML tables. Done through a deferred command.
- */
- public void render(IncrementalCommand onFinished) {
- DeferredCommand.addCommand(new RenderCommand(onFinished));
- }
-
- private void renderHeaders() {
- renderer.renderRows(rowHeaders, rowHeaderCells, false);
- renderer.renderRows(columnHeaders, columnHeaderCells, false);
- }
-
- public void computeRowsPerIteration() {
- int cellsPerRow = columnHeaderValues.size();
- rowsPerIteration = Math.max(CELLS_PER_ITERATION / cellsPerRow, 1);
- dataTable.setRowsPerFragment(rowsPerIteration);
- }
-
- private void computeHeaderCells() {
- rowHeaderCells = new CellInfo[rowHeaderValues.size()][rowFields.size()];
- fillHeaderCells(rowHeaderCells, rowFields, rowHeaderValues, true);
-
- columnHeaderCells = new CellInfo[columnFields.size()][columnHeaderValues.size()];
- fillHeaderCells(columnHeaderCells, columnFields, columnHeaderValues, false);
- }
-
- /**
- * TODO (post-1.0) - this method needs good cleanup and documentation
- */
- private void fillHeaderCells(CellInfo[][] cells, Header fields, List<Header> headerValues,
- boolean isRows) {
- int headerSize = fields.size();
- String[] lastFieldValue = new String[headerSize];
- CellInfo[] lastCellInfo = new CellInfo[headerSize];
- int[] counter = new int[headerSize];
- boolean newHeader;
- for (int headerIndex = 0; headerIndex < headerValues.size(); headerIndex++) {
- Header header = headerValues.get(headerIndex);
- newHeader = false;
- for (int fieldIndex = 0; fieldIndex < headerSize; fieldIndex++) {
- String fieldValue = header.get(fieldIndex);
- if (newHeader || !fieldValue.equals(lastFieldValue[fieldIndex])) {
- newHeader = true;
- Header currentHeader = getSubHeader(header, fieldIndex + 1);
- String cellContents = formatHeader(fields.get(fieldIndex), fieldValue);
- CellInfo cellInfo;
- if (isRows) {
- cellInfo = new CellInfo(currentHeader, null, cellContents);
- cells[headerIndex][fieldIndex] = cellInfo;
- } else {
- cellInfo = new CellInfo(null, currentHeader, cellContents);
- cells[fieldIndex][counter[fieldIndex]] = cellInfo;
- counter[fieldIndex]++;
- }
- lastFieldValue[fieldIndex] = fieldValue;
- lastCellInfo[fieldIndex] = cellInfo;
- } else {
- incrementSpan(lastCellInfo[fieldIndex], isRows);
- }
- }
- }
- }
-
- private String formatHeader(String field, String value) {
- if (value.equals("")) {
- return BLANK_STRING;
- }
- value = Utils.escape(value);
- if (field.equals("kernel")) {
- // line break after each /, for long paths
- value = value.replace("/", "/<br>").replace("/<br>/<br>", "//");
- }
- return value;
- }
-
- private void incrementSpan(CellInfo cellInfo, boolean isRows) {
- if (isRows) {
- cellInfo.rowSpan++;
- } else {
- cellInfo.colSpan++;
- }
- }
-
- private Header getSubHeader(Header header, int length) {
- if (length == header.size()) {
- return header;
- }
- List<String> subHeader = new UnmodifiableSublistView<String>(header, 0, length);
- return new HeaderImpl(subHeader);
- }
-
- private void matchRowHeights(HTMLTable from, CellInfo[][] to) {
- int lastColumn = to[0].length - 1;
- int rowCount = from.getRowCount();
- for (int row = 0; row < rowCount; row++) {
- int height = getRowHeight(from, row);
- getCellInfo(to, row, lastColumn).heightPx = height - 2 * CELL_PADDING_PX;
- }
- }
-
- private void matchColumnWidths(HTMLTable from, CellInfo[][] to) {
- int lastToRow = to.length - 1;
- int lastFromRow = from.getRowCount() - 1;
- for (int column = 0; column < from.getCellCount(lastFromRow); column++) {
- int width = getColumnWidth(from, column);
- getCellInfo(to, lastToRow, column).widthPx = width - 2 * CELL_PADDING_PX;
- }
- }
-
- protected String getTableCellText(HTMLTable table, int row, int column) {
- Element td = table.getCellFormatter().getElement(row, column);
- Element div = td.getFirstChildElement();
- if (div == null)
- return null;
- String contents = Utils.unescape(div.getInnerHTML());
- if (contents.equals(BLANK_STRING))
- contents = "";
- return contents;
- }
-
- public void clear() {
- rowHeaderValues.clear();
- columnHeaderValues.clear();
- rowHeaderMap.clear();
- columnHeaderMap.clear();
- dataCells = rowHeaderCells = columnHeaderCells = null;
- dataTable.reset();
-
- setRowHeadersOffset(0);
- setColumnHeadersOffset(0);
- }
-
- /**
- * Make the spreadsheet fill the available window space to the right and bottom
- * of its position.
- */
- public void fillWindow(boolean useTableSize) {
- int newHeightPx = Window.getClientHeight() - (columnHeaders.getAbsoluteTop() +
- columnHeaders.getOffsetHeight());
- newHeightPx = adjustMaxDimension(newHeightPx);
- int newWidthPx = Window.getClientWidth() - (rowHeaders.getAbsoluteLeft() +
- rowHeaders.getOffsetWidth());
- newWidthPx = adjustMaxDimension(newWidthPx);
- if (useTableSize) {
- newHeightPx = Math.min(newHeightPx, rowHeaders.getOffsetHeight());
- newWidthPx = Math.min(newWidthPx, columnHeaders.getOffsetWidth());
- }
-
- // apply the changes all together
- rowHeadersClipPanel.setHeight(getSizePxString(newHeightPx));
- columnHeadersClipPanel.setWidth(getSizePxString(newWidthPx));
- scrollPanel.setSize(getSizePxString(newWidthPx + SCROLLBAR_FUDGE),
- getSizePxString(newHeightPx + SCROLLBAR_FUDGE));
- }
-
- /**
- * Adjust a maximum table dimension to allow room for edge decoration and
- * always maintain a minimum height
- */
- protected int adjustMaxDimension(int maxDimensionPx) {
- return Math.max(maxDimensionPx - WINDOW_BORDER_PX - SCROLLBAR_FUDGE,
- MIN_TABLE_SIZE_PX);
- }
-
- protected String getSizePxString(int sizePx) {
- return sizePx + "px";
- }
-
- /**
- * Ensure the row header clip panel allows the full width of the row headers
- * to display.
- */
- protected void expandRowHeaders() {
- int width = rowHeaders.getOffsetWidth();
- rowHeadersClipPanel.setWidth(getSizePxString(width));
- }
-
- private Element getCellElement(HTMLTable table, int row, int column) {
- return table.getCellFormatter().getElement(row, column);
- }
-
- private Element getCellElement(CellInfo cellInfo) {
- assert cellInfo.row != null || cellInfo.column != null;
- Element tdElement;
- if (cellInfo.row == null) {
- tdElement = getCellElement(columnHeaders, 0, getColumnPosition(cellInfo.column));
- } else if (cellInfo.column == null) {
- tdElement = getCellElement(rowHeaders, getRowPosition(cellInfo.row), 0);
- } else {
- tdElement = getCellElement(dataTable, getRowPosition(cellInfo.row),
- getColumnPosition(cellInfo.column));
- }
- Element cellElement = tdElement.getFirstChildElement();
- assert cellElement != null;
- return cellElement;
- }
-
- protected int getColumnWidth(HTMLTable table, int column) {
- // using the column formatter doesn't seem to work
- int numRows = table.getRowCount();
- return table.getCellFormatter().getElement(numRows - 1, column).getOffsetWidth() -
- TD_BORDER_PX;
- }
-
- protected int getRowHeight(HTMLTable table, int row) {
- // see getColumnWidth()
- int numCols = table.getCellCount(row);
- return table.getCellFormatter().getElement(row, numCols - 1).getOffsetHeight() -
- TD_BORDER_PX;
- }
-
- /**
- * Update floating headers.
- */
- @Override
- public void onScroll(ScrollEvent event) {
- int scrollLeft = scrollPanel.getHorizontalScrollPosition();
- int scrollTop = scrollPanel.getScrollPosition();
-
- setColumnHeadersOffset(-scrollLeft);
- setRowHeadersOffset(-scrollTop);
- }
-
- protected void setRowHeadersOffset(int offset) {
- rowHeaders.getElement().getStyle().setPropertyPx("top", offset);
- }
-
- protected void setColumnHeadersOffset(int offset) {
- columnHeaders.getElement().getStyle().setPropertyPx("left", offset);
- }
-
- @Override
- public void onClick(ClickEvent event) {
- handleEvent(event, false);
- }
-
- @Override
- public void onContextMenu(ContextMenuEvent event) {
- handleEvent(event, true);
- }
-
- private void handleEvent(DomEvent<?> event, boolean isRightClick) {
- if (listener == null)
- return;
-
- assert event.getSource() instanceof RightClickTable;
- HTMLTable.Cell tableCell = ((RightClickTable) event.getSource()).getCellForDomEvent(event);
- int row = tableCell.getRowIndex();
- int column = tableCell.getCellIndex();
-
- CellInfo[][] cells;
- if (event.getSource() == rowHeaders) {
- cells = rowHeaderCells;
- column = adjustRowHeaderColumnIndex(row, column);
- }
- else if (event.getSource() == columnHeaders) {
- cells = columnHeaderCells;
- }
- else {
- assert event.getSource() == dataTable;
- cells = dataCells;
- }
- CellInfo cell = cells[row][column];
- if (cell == null || cell.isEmpty())
- return; // don't report clicks on empty cells
-
- listener.onCellClicked(cell, isRightClick);
- }
-
- /**
- * In HTMLTables, a cell with rowspan > 1 won't count in column indices for the extra rows it
- * spans, which will mess up column indices for other cells in those rows. This method adjusts
- * the column index passed to onCellClicked() to account for that.
- */
- private int adjustRowHeaderColumnIndex(int row, int column) {
- for (int i = 0; i < rowFields.size(); i++) {
- if (rowHeaderCells[row][i] != null) {
- return i + column;
- }
- }
-
- throw new RuntimeException("Failed to find non-null cell");
- }
-
- public void setListener(SpreadsheetListener listener) {
- this.listener = listener;
- }
-
- public void setHighlighted(CellInfo cell, boolean highlighted) {
- Element cellElement = getCellElement(cell);
- if (highlighted) {
- cellElement.setClassName(HIGHLIGHTED_CLASS);
- } else {
- cellElement.setClassName("");
- }
- }
-
- public List<Integer> getAllTestIndices() {
- List<Integer> testIndices = new ArrayList<Integer>();
-
- for (CellInfo[] row : dataCells) {
- for (CellInfo cellInfo : row) {
- if (cellInfo != null && !cellInfo.isEmpty()) {
- testIndices.add(cellInfo.testIndex);
- }
- }
- }
-
- return testIndices;
- }
-}
« no previous file with comments | « frontend/client/src/autotest/tko/FragmentedTable.java ('k') | frontend/client/src/autotest/tko/SpreadsheetDataProcessor.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698