--- /dev/null
+/*******************************************************************************\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.spreadsheet.ui;\r
+\r
+import java.awt.Color;\r
+import java.awt.Font;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
+\r
+import javax.swing.table.DefaultTableModel;\r
+\r
+import org.simantics.spreadsheet.ClientModel;\r
+import org.simantics.spreadsheet.ClientModel.ClientModelListener;\r
+import org.simantics.spreadsheet.ClientModel.OperationMode;\r
+import org.simantics.spreadsheet.graph.SpreadsheetStyle;\r
+import org.simantics.spreadsheet.util.SpreadsheetUtils;\r
+import org.simantics.ui.colors.Colors;\r
+import org.simantics.ui.fonts.Fonts;\r
+import org.simantics.utils.threads.AWTThread;\r
+\r
+final public class ClientTableModel extends DefaultTableModel {\r
+\r
+ private static final long serialVersionUID = 226747623479756815L;\r
+ private final ClientModel model;\r
+ \r
+ public ClientTableModel(ClientModel model) {\r
+ this.model = model;\r
+ }\r
+ \r
+ public void setModel(final SpreadsheetModel model) {\r
+ \r
+ final SpreadsheetTable table = model.getTable();\r
+ \r
+ this.model.addListener(new ClientModelListener() {\r
+\r
+ private AtomicBoolean dirtyStructure = new AtomicBoolean(false);\r
+ private AtomicBoolean dirtyHeaderSizes = new AtomicBoolean(false);\r
+ private AtomicBoolean dirtyValues = new AtomicBoolean(false);\r
+ private AtomicBoolean dirtySources = new AtomicBoolean(false);\r
+ \r
+ @Override\r
+ public void columnLabels(String[] labels) {\r
+ dirtyStructure.set(true);\r
+ }\r
+\r
+ @Override\r
+ public void rowLabels(String[] labels) {\r
+ dirtyStructure.set(true);\r
+ }\r
+\r
+ @Override\r
+ public void rows(int amount) {\r
+ dirtyStructure.set(true);\r
+ }\r
+\r
+ @Override\r
+ public void columns(int amount) {\r
+ dirtyStructure.set(true);\r
+ }\r
+ \r
+ @Override\r
+ public void sources(final String[] available, final String current) {\r
+ dirtySources.set(true);\r
+ }\r
+\r
+ @Override\r
+ public void columnWidths(int[] widths) {\r
+ dirtyHeaderSizes.set(true);\r
+ }\r
+ \r
+ @Override\r
+ public void cleared(String location) {\r
+ dirtyValues.set(true);\r
+ }\r
+\r
+ @Override\r
+ public void propertyChange(String location, String property, Object value) {\r
+ dirtyValues.set(true);\r
+ }\r
+ \r
+ @Override\r
+ public void flush() {\r
+ \r
+ final boolean structure = dirtyStructure.compareAndSet(true, false);\r
+ final boolean values = dirtyValues.compareAndSet(true, false);\r
+ final boolean headerSizes = dirtyHeaderSizes.compareAndSet(true, false);\r
+ final boolean sources = dirtySources.compareAndSet(true, false);\r
+ \r
+ if(sources) {\r
+ AWTThread.getThreadAccess().asyncExec(new Runnable() {\r
+ @Override\r
+ public void run() {\r
+ \r
+ model.setSources();\r
+ \r
+ }\r
+ });\r
+ }\r
+\r
+ if (Spreadsheet.DEBUG)\r
+ System.out.println("ClientTableModel.ClientModelListener.flush: structure=" + structure + ", values=" + values + ", headerSizes=" + headerSizes);\r
+ \r
+ if(structure || values || headerSizes) {\r
+ \r
+ AWTThread.getThreadAccess().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ \r
+ int[] cc = table.getSelectedColumns();\r
+ int[] rc = table.getSelectedRows();\r
+ \r
+ if(structure) fireTableStructureChanged();\r
+ if(values) fireTableDataChanged();\r
+\r
+ if (headerSizes)\r
+ table.applyHeaderSizes(ClientTableModel.this.model);\r
+\r
+ if(rc.length == 1 && cc.length == 1) {\r
+ table.setColumnSelectionInterval(cc[0], cc[0]);\r
+ table.setRowSelectionInterval(rc[0], rc[0]);\r
+ }\r
+ \r
+ }\r
+ \r
+ });\r
+ \r
+ }\r
+ \r
+ }\r
+ \r
+ });\r
+ \r
+ }\r
+ \r
+ @Override\r
+ public Object getValueAt(int row, int column) {\r
+ String location = SpreadsheetUtils.cellName(row, column);\r
+ \r
+// System.out.println("CellValue for location " + location);\r
+ \r
+ Color foregroundColor = null;\r
+ Color backgroundColor = null;\r
+ Font font = null;\r
+ int borderValue = 0;\r
+ int alignValue = 0;\r
+ String formatString = null;\r
+ int formatIndex = 0;\r
+ SpreadsheetStyle style = model.getPropertyAt(location, "style");\r
+ if (style != null) {\r
+ foregroundColor = style.foreground != null ? Colors.awt(style.foreground) : null;\r
+ backgroundColor = style.background != null ? Colors.awt(style.background) : null;\r
+ font = style.font != null ? Fonts.awt(style.font) : null;\r
+ alignValue = style.align;\r
+ borderValue = style.border;\r
+ \r
+ formatString = style.formatString;\r
+ formatIndex = style.formatIndex;\r
+ }\r
+\r
+ Boolean editable = model.getPropertyAt(location, "editable");\r
+ boolean editableValue = editable != null ? editable : false;\r
+ \r
+ OperationMode currentMode = model.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);\r
+ if (!OperationMode.OPERATION.equals(currentMode))\r
+ editableValue = true;\r
+ \r
+ return new CellValue(SpreadsheetUtils.getFormattedLabel(model, row, column, formatIndex, formatString), font, foregroundColor, backgroundColor, borderValue, alignValue, editableValue);\r
+ }\r
+ \r
+ @Override\r
+ public int getColumnCount() {\r
+ return model.getColumns();\r
+ }\r
+ \r
+ @Override\r
+ public String getColumnName(int column) {\r
+ String[] names = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_LABELS);\r
+ if(column < names.length) return names[column];\r
+ else return super.getColumnName(column);\r
+ }\r
+ \r
+ @Override\r
+ public int getRowCount() {\r
+ //TODO: haxx for initialization\r
+ if(model == null) return 0;\r
+ return model.getRows();\r
+ }\r
+ \r
+// void applyHeaderSizes() {\r
+// \r
+// }\r
+// \r
+//// synchronized void applyDimensions() {\r
+////\r
+//// boolean fitRows = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_FIT_ROWS);\r
+//// boolean fitColumns = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_FIT_COLS);\r
+////\r
+//// int currentRows = getRowCount();\r
+//// int currentCols = getColumnCount();\r
+////\r
+//// int maxRow = model.getRows();\r
+//// int maxColumn = model.getColumns();\r
+//// \r
+//// int rowCount = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_ROW_COUNT);\r
+//// int columnCount = model.getPropertyAt(ClientModel.DIMENSIONS, ClientModel.DIMENSIONS_COL_COUNT);\r
+//// \r
+//// if(Spreadsheet.DEBUG) {\r
+//// System.out.println("SimpleContainerTableModel.applyDimensions " + Thread.currentThread().getName());\r
+//// System.out.println("-current model rows " + currentRows);\r
+//// System.out.println("-current model cols " + currentCols);\r
+////// if(listener != null) {\r
+////// System.out.println("-current table rows " + table.getRowModel().getSize());\r
+////// System.out.println("-current table cols " + table.getColumnModel().getColumnCount());\r
+////// }\r
+//// System.out.println("-target rows " + rowCount);\r
+//// System.out.println("-target cols " + columnCount);\r
+//// System.out.println("-fit rows " + fitRows);\r
+//// System.out.println("-fit cols " + fitColumns);\r
+//// }\r
+//// \r
+//// if(fitRows) {\r
+//// if(maxRow != currentRows) {\r
+//// setRowCount(maxRow);\r
+//// if(table != null) table.getRowModel().setSize(maxRow);\r
+//// setColumnWidths();\r
+//// }\r
+//// } else {\r
+//// if(rowCount != currentRows) {\r
+//// setRowCount(rowCount);\r
+//// if(table != null) table.getRowModel().setSize(rowCount);\r
+//// setColumnWidths();\r
+//// }\r
+//// }\r
+//// if(fitColumns) {\r
+//// if(maxColumn != currentCols) {\r
+//// setColumnCount(maxColumn);\r
+////// applyLabels();\r
+//// setColumnWidths();\r
+//// }\r
+//// } else {\r
+//// if(columnCount != currentCols) {\r
+//// setColumnCount(columnCount);\r
+////// applyLabels();\r
+//// setColumnWidths();\r
+//// }\r
+//// }\r
+//// \r
+//// }\r
+// \r
+//// private synchronized void applyLabels() {\r
+//// \r
+//// if(Spreadsheet.DEBUG) System.out.println("SimpleContainerTableModel.applyLabels");\r
+//// \r
+//// for(Map.Entry<String, HashMap<String, Object>> e : cells.entrySet()) {\r
+//// String location = e.getKey();\r
+//// Range r = SpreadsheetUtils.decodeCellAbsolute(location);\r
+//// if(r.startRow >= getRowCount() || r.startColumn >= getColumnCount()) continue;\r
+//// String label = (String)e.getValue().get("Label");\r
+//// if(Spreadsheet.DEBUG) System.out.println("setLabel '" + label + "' at " + location + " " + getRowCount() + " " + getColumnCount());\r
+//// setValueAt(label, r.startRow, r.startColumn); \r
+//// }\r
+//// \r
+//// }\r
+// \r
+// private synchronized void setColumnWidths() {\r
+//\r
+// if(Spreadsheet.DEBUG) System.out.println("SimpleContainerTableModel.setColumnWidths");\r
+// \r
+// if(table != null) {\r
+//\r
+// int[] columnWidths = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_WIDTHS);\r
+//\r
+// int columnCount = table.getColumnModel().getColumnCount();\r
+// \r
+// for(int i = 0; i < columnWidths.length && i < columnCount ; i++) \r
+// { \r
+// TableColumn column = table.getColumnModel().getColumn(i);\r
+// int preferred = columnWidths[i];\r
+// if(preferred > 0)\r
+// column.setPreferredWidth(preferred); \r
+// }\r
+// \r
+// }\r
+// \r
+// }\r
+// \r
+// synchronized String[] createColumnIdentifiers(String[] defined) {\r
+//\r
+// int currentCols = getColumnCount();\r
+// String[] identifiers = new String[currentCols];\r
+// int i=0;\r
+// for(;i<defined.length && i<currentCols;i++) {\r
+// identifiers[i] = defined[i];\r
+// }\r
+// for(;i<currentCols;i++) {\r
+// identifiers[i] = SpreadsheetUtils.columnName(i);\r
+// }\r
+// return identifiers;\r
+//\r
+// }\r
+// \r
+// @Override\r
+// public String getColumnName(int column) {\r
+// new Exception("getColumnName " + column).printStackTrace();\r
+// String[] names = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_LABELS);\r
+// if(column < names.length) return names[column];\r
+// else return super.getColumnName(column);\r
+// }\r
+// \r
+// synchronized void applyHeaders() {\r
+//\r
+// AWTThread.getThreadAccess().asyncExec(new Runnable() {\r
+//\r
+// @Override\r
+// public void run() {\r
+//\r
+// String[] columnLabels = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_COL_LABELS);\r
+// String[] filledColumnLabels = createColumnIdentifiers(columnLabels);\r
+// String[] rowLabels = model.getPropertyAt(ClientModel.HEADERS, ClientModel.HEADERS_ROW_LABELS);\r
+//\r
+// if(Spreadsheet.DEBUG) {\r
+// System.out.println("SimpleContainerTableModel.applyHeaders");\r
+// System.out.println("-columnLabels=" + Arrays.toString(columnLabels));\r
+// System.out.println("-filledColumnLabels=" + Arrays.toString(filledColumnLabels));\r
+// System.out.println("-rowLabels=" + Arrays.toString(rowLabels));\r
+// }\r
+// \r
+// setColumnIdentifiers(filledColumnLabels);\r
+// \r
+//// if(listener != null) {\r
+//// listener.rowLabels(rowLabels);\r
+//// }\r
+// \r
+// if(table != null) {\r
+// table.getRowModel().ensureCapacity(rowLabels.length);\r
+// int i=0;\r
+// for(;i<rowLabels.length && i<table.getRowModel().size();i++) {\r
+// table.getRowModel().setElementAt(rowLabels[i], i);\r
+// }\r
+// for(;i<rowLabels.length;i++) {\r
+// table.getRowModel().addElement(rowLabels[i]);\r
+// }\r
+// }\r
+// \r
+//// applyLabels();\r
+// \r
+// }\r
+// \r
+// });\r
+// \r
+// }\r
+ \r
+}\r