/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*******************************************************************************/
package org.ebayopensource.turmeric.policy.adminui.client.view.policy;
import java.util.HashSet;
import java.util.Set;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
/**
* When {@link FlexCellFormatter#setRowSpan(int, int, int)} is used, it causes unexpected shifting for cells
* on rows below spanned one, because {@link FlexTable#prepareCell(int, int)} is naive and does not take into
* account fact of spanning (well, often <code>setRowSpan()</code> is invoked after adding cells, so may be we
* should say that <code>setRowSpan()</code> is guilty).
* <p>
* See http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/8a76929f78946c00 for discussion
* about this problem.
* <p>
* In any case, this helper class tried to fix row span problem that that {@link FlexTable} can be used as
* normal grid with arbitrary col/row spanning.
*
* @author scheglov_ke
*/
public class FlexTableHelper {
/**
* Fixes problem with {@link FlexCellFormatter#setRowSpan(int, int, int)},
* see comment for.
*
* @param flexTable
* the flex table {@link #FlexTableHelper}.
*/
public static void fixRowSpan(final FlexTable flexTable) {
Set<Element> tdToRemove = new HashSet<Element>();
{
int rowCount = flexTable.getRowCount();
for (int row = 0; row < rowCount; row++) {
int cellCount = flexTable.getCellCount(row);
for (int cell = 0; cell < cellCount; cell++) {
int colSpan = flexTable.getFlexCellFormatter().getColSpan(row, cell);
int rowSpan = flexTable.getFlexCellFormatter().getRowSpan(row, cell);
if (rowSpan != 1) {
int column = getColumnOfCell(flexTable, row, cell);
for (int row2 = row + 1; row2 < row + rowSpan; row2++) {
int baseCell2 = getCellOfColumn(flexTable, row2, column);
for (int cell2 = baseCell2; cell2 < baseCell2 + colSpan; cell2++) {
if (cell2 != -1) {
Element td = flexTable.getCellFormatter().getElement(row2, cell2);
tdToRemove.add(td);
}
}
}
}
}
}
}
// remove TD elements
for (Element td : tdToRemove) {
Element tr = DOM.getParent(td);
DOM.removeChild(tr, td);
}
}
private static int getColumnOfCell(final FlexTable flexTable, final int row, final int cell) {
int column = 0;
for (int _cell = 0; _cell < cell; _cell++) {
int colSpan = getColSpan(flexTable, row, _cell);
column += colSpan;
}
return column;
}
private static int getCellOfColumn(final FlexTable flexTable, final int row, final int column) {
int cellCount = flexTable.getCellCount(row);
int currentColumn = 0;
for (int cell = 0; cell < cellCount; cell++) {
int colSpan = getColSpan(flexTable, row, cell);
if (currentColumn == column) {
return cell;
}
currentColumn += colSpan;
}
return -1;
}
private static int getColSpan(final FlexTable flexTable, final int row, final int cell) {
return flexTable.getFlexCellFormatter().getColSpan(row, cell);
}
}