package org.gcube.portlets.user.reportgenerator.client.targets; import java.util.ArrayList; import org.gcube.portlets.d4sreporting.common.shared.Table; import org.gcube.portlets.d4sreporting.common.shared.TableCell; import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.MessageBoxEvent; import com.extjs.gxt.ui.client.widget.Info; import com.extjs.gxt.ui.client.widget.MessageBox; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.MouseOutEvent; import com.google.gwt.event.dom.client.MouseOutHandler; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.FocusPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.VerticalPanel; /** * * @author Massimiliano Assante ISTI-CNR * */ public class GenericTable extends Composite { public static final int DEFAULT_HEIGHT = 200; public static final int DEFAULT_ROWS_NUM = 5; public static final int DEFAULT_COLS_NUM = 2; private FocusPanel focusPanel = new FocusPanel(); private VerticalPanel myPanel = new VerticalPanel(); private FlexTable myTable; Presenter presenter; private int rows; private int cols; private int width; private boolean isEditTableMode = false; private AttributeSingleSelection attrSS; private Button cellMerger = new Button("Merge Cells"); private Button colMerger = new Button("Merge Selected"); private Button cancel = new Button("Cancel"); private Button resetTabelB = new Button("Reset Table"); private Button addRowB = new Button("Add Row"); private Button addColB = new Button("Add Col"); private Button deleteRowB = new Button("Del. Row"); private Button deleteColB = new Button("Del. Col"); private TextBox titleTB = new TextBox(); private TextBox descTB = new TextBox(); private int cellWidth; private int cellSpacing = 1; private int cellPadding = 0; private GenTableCell selectedCell = null; private Table originalTable; /** * constructor called when reading the model * @param sTable */ public GenericTable(Table sTable, Presenter presenter, int top, int left, int width, int height, boolean isLocked) { saveTable(sTable); commonConstructorCode(presenter); this.rows = sTable.getRowCount(); this.cols = sTable.getColsNo(); this.width = width; /** * construct the table */ for (int i = 0; i < rows; i++) { for (int j = 0; j < sTable.getCellCount(i); j++) { TableCell toPut = sTable.getValue(i, j); int cellWidth = toPut.getCellWidth(); //int cellHeight = toPut.getCellHeight(); int colspan = toPut.getColspan(); GenTableCell toAdd = new GenTableCell(i, j, cellWidth, colspan); toAdd.setText(toPut.getContent()); toAdd.setStyleName("tableBorder"); toAdd.setWidth(""+cellWidth+"px"); myTable.setWidget(i, j, toAdd); myTable.getFlexCellFormatter().setColSpan(i, j, colspan); toAdd.addClickHandler(cellClicker); } } HorizontalPanel controlPanel = getControlPanel(); VerticalPanel attributesPanel = getAttributesPanel(sTable); attributesPanel.setStyleName("tableAttributesPanel"); controlPanel.setStyleName("tableControlPanel"); myPanel.add(controlPanel); myPanel.add(myTable); myPanel.add(attributesPanel); myPanel.setStyleName("tablePanel"); for (int i = 0; i < controlPanel.getWidgetCount(); i++) { if (controlPanel.getWidget(i) instanceof Button) { Button b = (Button) controlPanel.getWidget(i); b.addStyleName("tableButton"); } } focusPanel.add(myPanel); initWidget(focusPanel); focusPanel.addMouseOutHandler(new MouseOutHandler() { @Override public void onMouseOut(MouseOutEvent event) { saveStatus(); } }); } private void saveTable(Table sTable) { originalTable = new Table(sTable.getColsNo()); originalTable.setTable(sTable.getTable()); } private void saveStatus() { presenter.storeChangeInSession(this); } /** * common Constructors Code */ private void commonConstructorCode(Presenter presenter) { this.presenter = presenter; myTable= new FlexTable(); myTable.setWidth("90%"); myTable.setCellSpacing(cellSpacing); myTable.setCellPadding(cellPadding); } /** * calculate the cell width * @param cols * @return */ private int getCellWidth(int cols) { int cellWidth = width / cols; return cellWidth; } private VerticalPanel getAttributesPanel(Table sTable) { VerticalPanel toReturn = new VerticalPanel(); HorizontalPanel hp1 = new HorizontalPanel(); HTML title = new HTML("Title: ", true); hp1.add(title); hp1.add(titleTB); titleTB.setWidth("135px"); titleTB.setText(sTable.getTitle()); HTML desc = new HTML(" Description: ", true); //desc.setStyleName("attributeArea"); hp1.add(desc); hp1.add(descTB); descTB.setWidth("435px"); descTB.setText(sTable.getDescription()); toReturn.add(hp1); if (sTable.getAttrArea() != null) { attrSS = new AttributeSingleSelection(presenter, 0, 0, 700, 0, sTable.getAttrArea()); } else attrSS = new AttributeSingleSelection(presenter, 0, 0, 700, 0, "DisplayType:Inline|Link|Popup"); toReturn.add(attrSS); return toReturn; } /** * * @return */ private HorizontalPanel getControlPanel() { final HorizontalPanel toReturn = new HorizontalPanel(); final Listener l = new Listener() { public void handleEvent(MessageBoxEvent ce) { Info.display("Info", "Table Edit Mode Enabled"); } }; resetTabelB.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { resetMe(); } }); addRowB.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { addRow(); } }); deleteRowB.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { deleteLastRow(); } }); addColB.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { addColumn(); } }); deleteColB.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { deleteLastColumn(); } }); cellMerger.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { if (! isEditTableMode) { isEditTableMode = true; MessageBox.alert("Table Edit Mode Enabled", "Click on the cells you want to merge", null); myTable.addStyleName("highlight_background"); cellMerger.setEnabled(false); //rowMerger.setVisible(true); colMerger.setVisible(true); cancel.setVisible(true); } } }); //the control buttons toReturn.add(resetTabelB); toReturn.add(addRowB); toReturn.add(addColB); toReturn.add(deleteRowB); toReturn.add(deleteColB); toReturn.add(cellMerger); toReturn.add(colMerger); toReturn.add(cancel); colMerger.setVisible(false); cancel.setVisible(false); toReturn.setSpacing(3); cancel.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { endEditMode(); } }); colMerger.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { mergeSelectedCols(); endEditMode(); } }); return toReturn; } /** * * End the edit mode */ private void endEditMode() { isEditTableMode = false; myTable.removeStyleName("highlight_background"); cellMerger.setEnabled(true); colMerger.setVisible(false); cancel.setVisible(false); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { try { GenTableCell tc = (GenTableCell) myTable.getWidget(i, j); if (tc.isSelected()) { tc.selected = false; tc.removeStyleName("selectedCell"); } }catch (IndexOutOfBoundsException e) { e.printStackTrace(); } } } } /** * merges the contiguos cols per row */ private void mergeSelectedCols() { for_i: for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { try { GenTableCell tc = (GenTableCell) myTable.getWidget(i, j); if (tc.isSelected()) { int nToMerge = checkContiguosColsPerRows(i, j); if (nToMerge > 1) { //myTable.removeCells(i, j+1, nToMerge-1); int cellsData[] = deleteCells(i, j+1, nToMerge-1); int colSpanDeleted = cellsData[0]; int deletedCellWidth = cellsData[1]; tc.setColspan(tc.getColspan()+colSpanDeleted); GWT.log("i=" + i + " j=" +j + " nTomerge" + nToMerge + " COLSPAN: " + tc.getColspan()); myTable.getFlexCellFormatter().setColSpan(i, j, tc.getColspan()); int newWidth = (tc.getWidth() + deletedCellWidth + cellSpacing * tc.getColspan() + tc.getColspan()); tc.setWidth(newWidth+"px"); tc.setCellWidth(newWidth); tc.removeStyleName("selectedCell"); continue for_i; } } } catch (IndexOutOfBoundsException e) { e.printStackTrace(); } } } } /** * * @param row the row of the cells to be removed * @column the column of the first cell to be removed * @num the number of cells to be removed * @return the total colspan of the cells in [0] is deleting, the total width of cells deleted in [1] */ private int[] deleteCells(int row, int col, int num) { int[] toReturn = new int[2]; toReturn[0] = 0; toReturn[1] = 0; for (int j = col; j < (col+num); j++) { toReturn[0] += ((GenTableCell) myTable.getWidget(row, j)).getColspan(); toReturn[1] += ((GenTableCell) myTable.getWidget(row, j)).getCellWidth(); } myTable.removeCells(row, col, num); GWT.log("REMOVED CELL from" + col + " to " + (col+num)); return toReturn; } /** * * @return */ private int checkContiguosColsPerRows(int i, int j) { int counter = 1; GenTableCell next = (GenTableCell) myTable.getWidget(i, j); j++; while (j < myTable.getCellCount(i)) { next = (GenTableCell) myTable.getWidget(i, j); if (next.isSelected()) counter++; else break; j++; } return counter; } public FlexTable getMyTable() { return myTable; } public void setMyTable(FlexTable myTable) { this.myTable = myTable; } public int getRowsNo() { return rows; } public void setRows(int rows) { this.rows = rows; } public int getCols() { return cols; } public void setCols(int cols) { this.cols = cols; } /** * * @return */ public Table getSerializable() { Table toReturn = new Table(this.cols); for (int i = 0; i < myTable.getRowCount(); i++) { toReturn.addRow(getRow(i)); } toReturn.setTitle(titleTB.getText()); toReturn.setDescription(descTB.getText()); toReturn.setAttrArea(attrSS.getSerializable()); return toReturn; } public ArrayList getRow(int i) { ArrayList toReturn = new ArrayList(); for (int j = 0; j < myTable.getCellCount(i); j++) { GenTableCell tb = (GenTableCell) myTable.getWidget(i, j); int colspan = tb.getColspan(); toReturn.add(new TableCell(tb.getText(), colspan, tb.getWidth(), tb.getHeight())); } return toReturn; } /** * */ ClickHandler cellClicker = new ClickHandler() { @Override public void onClick(ClickEvent event) { GenTableCell toSelect = (GenTableCell) event.getSource(); setSelected(toSelect); if (isEditTableMode) { if (! toSelect.isSelected()) { toSelect.addStyleName("selectedCell"); toSelect.setSelected(true); } else { toSelect.setSelected(false); toSelect.removeStyleName("selectedCell"); } } } }; /** * tells the presenter this tableb is selected */ private void setSelected(GenTableCell tc) { selectedCell = tc; } public GenTableCell getSelectedCell() { return selectedCell; } /** * delete the selected row from the table */ public void deleteLastRow() { deleteRow(rows-1); rows--; } private void deleteLastColumn() { deleteColumn(cols-1); } /** * adda a row at the bottom of the tableb */ public void addRow() { Table sTable = getSerializable(); //Window.alert("Adding row Above: " + rowIndex + " cells no: " + sTable.getCellCount(rowIndex)); int rowIndex = myTable.getRowCount(); for (int j = 0; j < myTable.getCellCount(rowIndex-1); j++) { TableCell toPut = sTable.getValue(rowIndex-1, j); int cellWidth = toPut.getCellWidth(); int cellHeight = toPut.getCellHeight(); int colspan = toPut.getColspan(); GenTableCell toAdd = new GenTableCell(rowIndex, j, cellWidth, colspan); toAdd.setText(toPut.getContent()); toAdd.setStyleName("tableBorder"); toAdd.setWidth(""+cellWidth+"px"); myTable.setWidget(rowIndex, j, toAdd); myTable.getFlexCellFormatter().setColSpan(rowIndex, j, colspan); toAdd.addClickHandler(cellClicker); } rows += 1; Info.display("Info", "Table Row added successfully"); } /** * add a column next to the last onw */ public void addColumn() { int colIndex = cols; int cellWidth = getCellWidth(cols+1); for (int i = 0; i < rows; i++) { GenTableCell toAdd = new GenTableCell(i, colIndex, cellWidth, 1); toAdd.setStyleName("tableBorder"); GWT.log("Width=" + cellWidth); myTable.setWidget(i, colIndex, toAdd); toAdd.addClickHandler(cellClicker); } cols++; updateCellsWidth(getCellWidth(cols)); Info.display("Info", "Table Column added successfully"); } private void updateCellsWidth(int newWidth) { Table sTable = getSerializable(); /** * construct the table */ for (int i = 0; i < rows; i++) { for (int j = 0; j < sTable.getCellCount(i); j++) { TableCell toPut = sTable.getValue(i, j); int cellWidth = newWidth; //int cellHeight = toPut.getCellHeight(); int colspan = toPut.getColspan(); GenTableCell toAdd = new GenTableCell(i, j, cellWidth, colspan); toAdd.setText(toPut.getContent()); toAdd.setStyleName("tableBorder"); toAdd.setWidth(""+cellWidth+"px"); myTable.setWidget(i, j, toAdd); myTable.getFlexCellFormatter().setColSpan(i, j, colspan); toAdd.addClickHandler(cellClicker); } } } /** * adda a column at the left of the selected cell of the selected tableb * TODO: next version */ public void addColumnLeft(int colindex) { // myTable.insertCell(beforeRow, beforeColumn) } /** * delete the rowIndex row from the table */ public void deleteRow(int rowIndex) { GWT.log("Removing row: " + rowIndex); if (rows == 1) { Info.display("Error", "Only one row left, delete the table"); } else { myTable.removeRow(rowIndex); Info.display("Info", "Table Row removed successfully"); } } /** * delete the colIndex column from the table */ public void deleteColumn(int colIndex) { GWT.log("Removing column: " + colIndex); if (cols <= 1) { Info.display("Error", "Only one column left, delete the table"); } else { //check if the column has all rows for (int i = 0; i < rows; i++) { try { myTable.getWidget(i, colIndex); } catch (IndexOutOfBoundsException e) { Info.display("Error", "Table Column cannot be removed as at least one row has merged cells"); return; } } // at this point you are sure there are no merged cells in the column to be deleted (last one) for (int i = 0; i < rows; i++) { myTable.removeCell(i, colIndex); } cols--; updateCellsWidth(getCellWidth(cols)); //Info.display("Info", "Table Column removed successfully"); } } protected void resetMe() { myTable.removeAllRows(); /** * construct the table */ for (int i = 0; i < originalTable.getRowCount(); i++) { for (int j = 0; j < originalTable.getColsNo(); j++) { int cellWidth = getCellWidth(originalTable.getColsNo()); GenTableCell toAdd = new GenTableCell(i, j, cellWidth, 1); toAdd.setText(""); toAdd.setStyleName("tableBorder"); toAdd.setWidth(""+cellWidth+"px"); myTable.setWidget(i, j, toAdd); toAdd.addClickHandler(cellClicker); } } } }