X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.spreadsheet.ui%2Fsrc%2Forg%2Fsimantics%2Fspreadsheet%2Fui%2FSpreadsheetModel.java;fp=bundles%2Forg.simantics.spreadsheet.ui%2Fsrc%2Forg%2Fsimantics%2Fspreadsheet%2Fui%2FSpreadsheetModel.java;h=9b4ef34e34bf3051a1b4f4e507eef83b4f33c0a3;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SpreadsheetModel.java b/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SpreadsheetModel.java new file mode 100644 index 000000000..9b4ef34e3 --- /dev/null +++ b/bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/SpreadsheetModel.java @@ -0,0 +1,1116 @@ +package org.simantics.spreadsheet.ui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.imageio.ImageIO; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.DefaultListModel; +import javax.swing.ImageIcon; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JColorChooser; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JToggleButton; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.TableColumnModelEvent; +import javax.swing.event.TableColumnModelListener; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.TableColumn; + +import org.eclipse.core.runtime.Platform; +import org.eclipse.swt.widgets.Display; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.binding.Binding; +import org.simantics.datatypes.literal.RGB; +import org.simantics.scenegraph.INode; +import org.simantics.scenegraph.swing.JScrollPaneSG; +import org.simantics.spreadsheet.Adaptable; +import org.simantics.spreadsheet.CellEditor; +import org.simantics.spreadsheet.CellEditor.Transaction; +import org.simantics.spreadsheet.ClientModel; +import org.simantics.spreadsheet.ClientModel.OperationMode; +import org.simantics.spreadsheet.SheetCommands; +import org.simantics.spreadsheet.common.cell.Parsers; +import org.simantics.spreadsheet.common.cell.StringCellParser; +import org.simantics.spreadsheet.event.model.RemoveCellHandler; +import org.simantics.spreadsheet.util.SpreadsheetUtils; +import org.simantics.ui.colors.Colors; +import org.simantics.ui.dnd.LocalObjectTransfer; +import org.simantics.ui.dnd.LocalObjectTransferable; +import org.simantics.ui.fonts.Fonts; +import org.simantics.utils.ui.dialogs.ShowMessage; +import org.simantics.utils.ui.jface.ActiveSelectionProvider; + +@SuppressWarnings({ "rawtypes", "unchecked" }) +public class SpreadsheetModel { + + final private Adaptable serverInterface; + final private ClientModel clientModel; + final private ActiveSelectionProvider selectionProvider; + protected Clipboard system; + protected StringCellParser[] parsers = new StringCellParser[] { Parsers.COMMAND_PARSER, Parsers.EXPRESSION_PARSER, Parsers.TEXT_PARSER }; + + public SpreadsheetModel(Adaptable serverInterface, ActiveSelectionProvider selectionProvider) { + + this.serverInterface = serverInterface; + this.clientModel = new ClientModelImpl(); + this.selectionProvider = selectionProvider; + + } + + public ClientModel getClientModel() { + return clientModel; + } + + public SpreadsheetTable getTable() { + return table; + } + + private JTextField expression; + private JButton foreground; + private JButton background; + private JButton font; + private JButton align_left; + private JButton align_hcenter; + private JButton align_right; + private JButton align_top; + private JButton align_vcenter; + private JButton align_bottom; + private JComboBox borders; + public JComboBox inputSource; + public JComboBox sheets; + private JButton lock; + private JButton unlock; + private JButton merge; + private JButton unmerge; + private ExpressionTextListener etl; + private SpreadsheetTable table; + @SuppressWarnings("unused") + private ExcelAdapter excel; + @SuppressWarnings("unused") + private boolean columnMarginsDirty = false; + + private ItemListener itemListener = null; + private ItemListener sheetsListener = null; + private ItemListener initialConditionsListener = null; + + private JComboBox initialConditions; + private JButton saveIc; + private JButton context; + private JToggleButton operationMode; + + private JCheckBox iterationEnabled; + private JTextField iterationLimit; + + public JComponent createComponent(final INode node) { + + Properties props = serverInterface.getAdapter(Properties.class); + + boolean addExpressionField = props == null || "true".equalsIgnoreCase(props.getProperty(SpreadsheetModelProperties.SHEET_EXPRESSION_VISIBLE, "true")); + + final JPanel panel = new JPanel(new BorderLayout()); + + final DefaultListModel lm = new DefaultListModel() { + + private static final long serialVersionUID = 5246691801867533053L; + + public Object getElementAt(int index) { + Object result = super.getElementAt(index); + if(result instanceof String) return result; + else return "" + (index + 1); + } + + }; + + if (addExpressionField) { + + foreground = new JButton(); + foreground.setToolTipText("Assign foreground color to selection"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/paintbrush.png")); + foreground.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + foreground.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + Color c = JColorChooser.showDialog(foreground, "asd", Colors.awt(Colors.rgb(0, 0, 0))); + if (c == null) + return; + RGB.Integer color = Colors.integerRGB(c); + + editSelection(ClientModel.FOREGROUND, color, RGB.Integer.BINDING); + } + }); + + background = new JButton(); + background.setToolTipText("Assign background color to selection"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/paintcan.png")); + background.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + background.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + Color c = JColorChooser.showDialog(background, "asd", Colors.awt(Colors.rgb(0, 0, 0))); + if (c == null) + return; + + RGB.Integer color = Colors.integerRGB(c); + + editSelection(ClientModel.BACKGROUND, color, RGB.Integer.BINDING); + } + }); + + String[] availableInitialConditions = clientModel.getPossiblePropertyAt(ClientModel.STATES, ClientModel.STATES_AVAILABLE); + String currentInitialCondition = clientModel.getPossiblePropertyAt(ClientModel.STATES, ClientModel.STATES_CURRENT); + + initialConditions = new JComboBox<>(); + for(String sheet : availableInitialConditions) + initialConditions.addItem(sheet); + + initialConditions.setSelectedItem(currentInitialCondition); + + initialConditionsListener = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent arg0) { + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor != null) { + if(arg0.getStateChange() == ItemEvent.SELECTED) + editor.edit(null, ClientModel.STATES, ClientModel.STATES_CURRENT, arg0.getItem(), null, null); + } + } + }; + + initialConditions.addItemListener(initialConditionsListener); + + saveIc = new JButton(); + saveIc.setText("Save IC"); + saveIc.setToolTipText("Save current Initial Condition"); + saveIc.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + + SheetCommands commands = serverInterface.getAdapter(SheetCommands.class); + commands.saveState(); + } + }); + + font = new JButton(); + font.setToolTipText("Assign font to selection"); + + font.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFontChooser fontChooser = new JFontChooser(); + int result = fontChooser.showDialog(font); + if (result == JFontChooser.OK_OPTION) { + + Font font = fontChooser.getSelectedFont(); + System.out.println("Selected Font : " + font); + + org.simantics.datatypes.literal.Font f = Fonts.fromAWT(font); + + editSelection(ClientModel.FONT, f, org.simantics.datatypes.literal.Font.BINDING); + } + } + }); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/font.png")); + font.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + align_left = new JButton(); + align_left.setToolTipText("Align selection to left"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_left.png")); + align_left.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + align_left.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + editSelectionAlignment(0, null); + } + }); + + align_hcenter = new JButton(); + align_hcenter.setToolTipText("Align selection horizontally to center"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_center.png")); + align_hcenter.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + align_hcenter.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + editSelectionAlignment(1, null); + } + }); + + align_right = new JButton(); + align_right.setToolTipText("Align selection to right"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_right.png")); + align_right.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + align_right.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + editSelectionAlignment(2, null); + } + }); + + align_top = new JButton(); + align_top.setToolTipText("Align selection to top"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_top.png")); + align_top.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + align_top.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + editSelectionAlignment(null, 0); + } + }); + + align_vcenter = new JButton(); + align_vcenter.setToolTipText("Align selection vertically to center"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_middle.png")); + align_vcenter.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + align_vcenter.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + editSelectionAlignment(null, 1); + } + }); + + align_bottom = new JButton(); + align_bottom.setToolTipText("Align selection to bottom"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_bottom.png")); + align_bottom.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + align_bottom.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + editSelectionAlignment(null, 2); + } + }); + + borders = new JComboBox(); + borders.addItem("No borders"); + borders.addItem("Bottom border"); + borders.addItem("Top border"); + borders.addItem("Left border"); + borders.addItem("Right border"); + borders.addActionListener(new ActionListener() { + + Map work = new HashMap(); + + int getCurrent(String location, int row, int column) { + CellValue value = (CellValue)table.getValueAt(row, column); + int border = value != null ? value.border : 0; + work.put(location, border); + return border; + } + + void setCurrent(String location, int border) { + work.put(location, border); + } + + @Override + public void actionPerformed(ActionEvent e) { + + work.clear(); + + int index = borders.getSelectedIndex(); + + final int[] selectedColumns = table.getSelectedColumns(); + final int[] selectedRows = table.getSelectedRows(); + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor == null) return; + + for(int col : selectedColumns) { + for(int row : selectedRows) { + + String location = SpreadsheetUtils.cellName(row, col); + + // No + if(index == 0) { + if(col > 0) { + String left = SpreadsheetUtils.cellName(row, col-1); + setCurrent(left, getCurrent(left, row, col-1) & 2); + } + if(row > 0) { + String up = SpreadsheetUtils.cellName(row-1, col); + setCurrent(up, getCurrent(up, row-1, col) & 1); + } + setCurrent(location, 0); + } + // Bottom + else if(index == 1) { + setCurrent(location, getCurrent(location, row, col) | 2); + } + // Top + else if(index == 2) { + if(row > 0) { + String up = SpreadsheetUtils.cellName(row-1, col); + setCurrent(up, getCurrent(up, row-1, col) | 2); + } + } + // Left + else if(index == 3) { + if(col > 0) { + String left = SpreadsheetUtils.cellName(row, col-1); + setCurrent(left, getCurrent(left, row, col-1) | 1); + } + } + // Right + else if(index == 4) { + setCurrent(location, getCurrent(location, row, col) | 1); + } + + } + + } + OperationMode mode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT); + Transaction transaction = editor.startTransaction(mode); + for(Map.Entry entry : work.entrySet()) { + String location = entry.getKey(); + Integer border = entry.getValue(); + editor.edit(transaction, location, ClientModel.BORDER, border, Bindings.INTEGER, null); + } + transaction.commit(); + + } + }); + + + lock = new JButton(); + lock.setToolTipText("Lock selection"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/lock.png")); + lock.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + lock.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + editSelection(ClientModel.LOCKED, true, Bindings.BOOLEAN); + } + }); + + unlock = new JButton(); + unlock.setToolTipText("Unlock selection"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/lock_open.png")); + unlock.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + unlock.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + editSelection(ClientModel.LOCKED, false, Bindings.BOOLEAN); + } + }); + + merge = new JButton(); + merge.setToolTipText("Merge cells"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/link.png")); + merge.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + merge.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + final int[] selectedColumns = table.getSelectedColumns(); + final int[] selectedRows = table.getSelectedRows(); + + if (isRectangularSelection(table)) { + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor == null) return; + + OperationMode mode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT); + Transaction transaction = editor.startTransaction(mode); + + Rectangle selection = new Rectangle(selectedColumns[0], selectedRows[0], selectedColumns.length, selectedRows.length); + List spans = clientModel.getSpans(); + + boolean found = true; + while (found) { + found = false; + Iterator iter = spans.iterator(); + while (iter.hasNext()) { + Rectangle span = iter.next(); + if (selection.intersects(span)) { + selection = selection.union(span); + found = true; + String location = SpreadsheetUtils.cellName(span.y, span.x); + editor.edit(transaction, location, ClientModel.ROW_SPAN, 1, Bindings.INTEGER, null); + editor.edit(transaction, location, ClientModel.COLUMN_SPAN, 1, Bindings.INTEGER, null); + iter.remove(); + } + } + } + + String location = SpreadsheetUtils.cellName(selection.y, selection.x); + if (selection.height > 1) { + editor.edit(transaction, location, ClientModel.ROW_SPAN, selection.height, Bindings.INTEGER, null); + } + if (selection.width > 1) { + editor.edit(transaction, location, ClientModel.COLUMN_SPAN, selection.width, Bindings.INTEGER, null); + } + transaction.commit(); + + } else { + //ShowMessage.showError(, message); + Display.getDefault().asyncExec(new Runnable() { + public void run() { + ShowMessage.showWarning("Merging cells failed", "Selected range is not rectangular."); + } + }); + } + } + }); + + unmerge = new JButton(); + unmerge.setToolTipText("Unmerge cells"); + + try { + Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/link_break.png")); + unmerge.setIcon(new ImageIcon(img)); + } catch (IOException ex) { + } + + unmerge.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor == null) return; + + OperationMode mode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT); + Transaction transaction = editor.startTransaction(mode); + editSelection(editor, transaction, ClientModel.ROW_SPAN, 1, Bindings.INTEGER); + editSelection(editor, transaction, ClientModel.COLUMN_SPAN, 1, Bindings.INTEGER); + transaction.commit(); + } + }); + + String[] availableSources = clientModel.getPossiblePropertyAt(ClientModel.SOURCES, ClientModel.SOURCES_AVAILABLE); + String[] availableSheets = clientModel.getPossiblePropertyAt(ClientModel.SHEETS, ClientModel.SHEETS_AVAILABLE); + String currentSheet = clientModel.getPossiblePropertyAt(ClientModel.SHEETS, ClientModel.SHEETS_CURRENT); + @SuppressWarnings("unused") + String currentSource = clientModel.getPossiblePropertyAt(ClientModel.SOURCES, ClientModel.SOURCES_CURRENT); + + inputSource = new JComboBox(); + for(String source : availableSources) + inputSource.addItem(source); + + sheets = new JComboBox(); + for(String sheet : availableSheets) + sheets.addItem(sheet); + + sheets.setSelectedItem(currentSheet); + + sheetsListener = new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent arg0) { + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if (editor != null) { + if (arg0.getStateChange() == ItemEvent.SELECTED) + editor.edit(null, ClientModel.SHEETS, ClientModel.SHEETS_CURRENT, arg0.getItem(), null, + null); + } + } + }; + + itemListener = new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent arg0) { + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor != null) { + if(arg0.getStateChange() == ItemEvent.SELECTED) + editor.edit(null, ClientModel.SOURCES, ClientModel.SOURCES_CURRENT, arg0.getItem(), null, null); + } + + } + + }; + + inputSource.addItemListener(itemListener); + + new DropTarget(inputSource,DnDConstants.ACTION_COPY_OR_MOVE,new DropTargetListener() { + + @Override + public void dropActionChanged(DropTargetDragEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void drop(DropTargetDropEvent dtde) { + + try { + Transferable transferable = dtde.getTransferable(); + + if( transferable.isDataFlavorSupported( + LocalObjectTransferable.FLAVOR ) ) { + + dtde.acceptDrop( DnDConstants.ACTION_MOVE ); + + transferable.getTransferData(LocalObjectTransferable.FLAVOR ); + Object obj = LocalObjectTransfer.getTransfer().getObject(); + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor != null) { + editor.edit(null, ClientModel.SOURCES, ClientModel.SOURCES_CURRENT, obj, null, null); + } + + dtde.getDropTargetContext().dropComplete( true ); + + } + else { + dtde.rejectDrop(); + } + } catch( IOException exception ) { + exception.printStackTrace(); + dtde.rejectDrop(); + } catch( UnsupportedFlavorException ufException ) { + ufException.printStackTrace(); + dtde.rejectDrop(); + } + + } + + @Override + public void dragOver(DropTargetDragEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void dragExit(DropTargetEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void dragEnter(DropTargetDragEvent arg0) { + // TODO Auto-generated method stub + + } + + }); + + expression = new JTextField(); + etl = new ExpressionTextListener(expression, serverInterface.getAdapter(CellEditor.class)); + expression.addFocusListener(etl); + expression.addKeyListener(etl); + + sheets.addItemListener(sheetsListener); + + + context = new JButton("Change context"); + + context.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + + Frame frame = (Frame) SwingUtilities.getRoot(context); + String result = JOptionPane.showInputDialog(frame, "Context URI"); + if (result != null && !result.isEmpty()) { + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor != null) { + editor.edit(null, ClientModel.CONTEXT, ClientModel.CONTEXT_CURRENT, result, null, null); + } + } + } + }); + + OperationMode currentMode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT); + String text; + if (currentMode.equals(OperationMode.OPERATION)) + text = "Operation Mode"; + else + text = "Edit Mode"; + operationMode = new JToggleButton(text); + operationMode.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + + OperationMode currentMode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT); + OperationMode newMode; + String newText; + if (currentMode.equals(OperationMode.OPERATION)) { + System.err.println("Current mode is operation"); + newMode = OperationMode.EDIT_MODE; + newText = "Edit Mode"; + } else { + System.err.println("Current mode is read-only"); + newMode = OperationMode.OPERATION; + newText = "Operation Mode"; + } + System.err.println("Setting new text " + newText + " to replace old " + operationMode.getText()); + operationMode.setText(newText); + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor != null) { + editor.edit(null, ClientModel.MODE, ClientModel.MODE_CURRENT, newMode, null, null); + } + } + }); + + iterationEnabled = new JCheckBox("Iteration Enabled"); + iterationEnabled.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + System.out.println("state is " + iterationEnabled.isSelected()); + } + }); + + iterationLimit = new JTextField("100"); + iterationLimit.setEnabled(false); + iterationLimit.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + + } + }); + + } + + Font font = new Font("Courier", Font.PLAIN, 14); + + UIManager.put(SpreadsheetTable.uiClassID, SpreadsheetTableUI.class.getCanonicalName()); + final JList rowHeader = new JList(lm); + table = new SpreadsheetTable(node, (CellEditor)serverInterface.getAdapter(CellEditor.class), clientModel, lm, rowHeader) { + + private static final long serialVersionUID = 4553572254034185984L; + + @Override + protected void mouseDragFinished() { + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor == null) return; + + TableColumn column = table.getTableHeader().getResizingColumn(); + if(column == null) return; + + int[] current = clientModel.getColumnWidths(); + if(column.getModelIndex() >= current.length) { + current = Arrays.copyOf(current, column.getModelIndex()+1); + } + + current[column.getModelIndex()] = column.getWidth(); + + editor.edit(null, ClientModel.HEADERS, ClientModel.HEADERS_COL_WIDTHS, current, Bindings.INT_ARRAY, null); + + } + + }; + + ((ClientTableModel)table.getModel()).setModel(this); + + InputMap im = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + Action deleteAction = new AbstractAction() { + private static final long serialVersionUID = 428343700053346645L; + + @SuppressWarnings("unused") + public void actionPerformed(ActionEvent ae) { + System.out.println("deleteaction"); + RemoveCellHandler removeHandler = serverInterface.getAdapter(RemoveCellHandler.class); + int[] rowSelection = table.getSelectedRows(); + int[] columnSelection = table.getSelectedColumns(); + for (int i = 0; i < columnSelection.length; i++) { + for (int j = 0; j < rowSelection.length; j++) { + int row = rowSelection[j]; + int column = columnSelection[i]; + System.out.println("deleteaction " + row + " " + column); + Object cell = table.getValueAt(row, column); + // RemoveHandler remove = cell.getAdapter(RemoveHandler.class); + // remove.handle(); + } + } + } + }; + KeyStroke delete = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0); + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), delete); + table.getActionMap().put(im.get(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)), deleteAction); + + table.setFont(font); + + @SuppressWarnings("unused") + DropTarget dropTarget = new DropTarget(table, + new TableDropTargetListener(table, serverInterface, clientModel)); + + if(serverInterface != null) + excel = new ExcelAdapter(table, clientModel, serverInterface, parsers); + + table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + + table.setColumnSelectionAllowed(true); + + rowHeader.setFixedCellWidth(40); + + rowHeader.setCellRenderer(new RowHeaderRenderer(table)); + rowHeader.setBackground(DefaultLookup.GRAY); + + table.getModel().addTableModelListener(new TableModelListener() { + + @Override + public void tableChanged(TableModelEvent e) { + int currentRows = rowHeader.getModel().getSize(); + int tableRows = table.getModel().getRowCount(); + if(currentRows != tableRows) { + lm.setSize(tableRows); + } + } + }); + + JScrollPaneSG scroll = new JScrollPaneSG(table, node); + + scroll.setRowHeaderView(rowHeader); + + table.getParent().setBackground(DefaultLookup.GRAY); + table.getTableHeader().setBackground(DefaultLookup.GRAY); + rowHeader.getParent().setBackground(DefaultLookup.GRAY); + scroll.getViewport().setBackground(DefaultLookup.GRAY); + + table.getTableHeader().setDefaultRenderer(new ColumnHeaderRenderer()); + + scroll.setBackground(DefaultLookup.GRAY); + + if(selectionProvider != null) { + + SelectionListener listener = new SelectionListener(table, expression, etl, selectionProvider, serverInterface, clientModel); + table.getSelectionModel().addListSelectionListener(listener); + table.getColumnModel().getSelectionModel() + .addListSelectionListener(listener); + + } + + table.getColumnModel().addColumnModelListener(new TableColumnModelListener() { + + @Override + public void columnSelectionChanged(ListSelectionEvent e) { + // System.out.println("columnSelectionChanged " + e); + } + + @Override + public void columnRemoved(TableColumnModelEvent e) { + // System.out.println("columnRemoved " + e); + } + + @Override + public void columnMoved(TableColumnModelEvent e) { + // System.out.println("columnMoved " + e); + } + + @Override + public void columnMarginChanged(ChangeEvent e) { + columnMarginsDirty = true; + } + + @Override + public void columnAdded(TableColumnModelEvent e) { + // System.out.println("columnAdded " + e); + } + + }); + + new TableRowResizer(table) { + + @Override + public void onResize(int row, int height) { + + if(row < 0) return; + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor == null) return; + + int[] current = clientModel.getRowHeights(); + if(row >= current.length) { + current = Arrays.copyOf(current, row+1); + } + + current[row] = height; + + editor.edit(null, ClientModel.HEADERS, ClientModel.HEADERS_ROW_HEIGHTS, current, Bindings.INT_ARRAY, null); + + rowHeader.setCellRenderer(new RowHeaderRenderer(table)); + + } + + }; + + if (addExpressionField) { + + JPanel tools = new JPanel(new GridBagLayout()); + panel.add(tools, BorderLayout.PAGE_START); + + GridBagConstraints c = new GridBagConstraints(); + + c.gridx = 0; + c.anchor = GridBagConstraints.WEST; + tools.add(this.font, c); + + c.gridx = 1; + tools.add(foreground, c); + + c.gridx = 2; + tools.add(background, c); + + c.gridx = 3; + tools.add(align_left, c); + c.gridx = 4; + tools.add(align_hcenter, c); + c.gridx = 5; + tools.add(align_right, c); + + c.gridx = 6; + tools.add(align_top, c); + c.gridx = 7; + tools.add(align_vcenter, c); + c.gridx = 8; + tools.add(align_bottom, c); + + c.gridx = 9; + tools.add(borders, c); + + c.gridx = 10; + tools.add(lock, c); + c.gridx = 11; + tools.add(unlock, c); + + c.gridx = 12; + tools.add(merge, c); + c.gridx = 13; + tools.add(unmerge, c); + + c.gridx = 14; + tools.add(inputSource, c); + + c.gridx = 15; + tools.add(sheets, c); + + c.gridx = 16; + tools.add(initialConditions, c); + + c.gridx = 17; + tools.add(saveIc, c); + + c.gridx = 18; + tools.add(context, c); + + c.gridx = 19; + tools.add(operationMode, c); + + c.gridx = 20; + tools.add(iterationEnabled, c); + + c.gridx = 21; + tools.add(iterationLimit, c); + + c.gridx = 0; + c.gridy = 1; + c.gridwidth = 22; + c.gridheight = 1; + c.weighty = 0.0; + c.weightx = 1.0; + c.fill = GridBagConstraints.HORIZONTAL; + + tools.add(expression,c); + + } + panel.add(scroll, BorderLayout.CENTER); + + return panel; + + } + + private boolean isRectangularSelection(SpreadsheetTable table) { + int[] selectedColumns = table.getSelectedColumns(); + int[] selectedRows = table.getSelectedRows(); + + if ((selectedColumns.length == 0) || (selectedRows.length == 0)) { + return false; + } + + for (int row = 0; row < selectedRows.length - 1; row++) { + if (selectedRows[row + 1] != selectedRows[row] + 1) { + return false; + } + } + + for (int column = 0; column < selectedColumns.length - 1; column++) { + if (selectedColumns[column + 1] != selectedColumns[column] + 1) { + return false; + } + } + + return true; + } + + private void editSelection(String property, Object value, Binding binding) { + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor == null) return; + +// Transaction transaction = editor.startTransaction(); + editSelection(editor, null, property, value, binding); +// transaction.commit(); + } + + private void editSelection(CellEditor editor, Transaction transaction, String property, Object value, Binding binding) { + for(int col : table.getSelectedColumns()) { + for(int row : table.getSelectedRows()) { + String location = SpreadsheetUtils.cellName(row, col); + editor.edit(transaction, location, property, value, binding, null); + } + } + } + + + private void editSelectionAlignment(Integer horizontal, Integer vertical) { + final int[] selectedColumns = table.getSelectedColumns(); + final int[] selectedRows = table.getSelectedRows(); + + CellEditor editor = serverInterface.getAdapter(CellEditor.class); + if(editor == null) return; + +// Transaction transaction = editor.startTransaction(); + for(int col : selectedColumns) { + for(int row : selectedRows) { + String location = SpreadsheetUtils.cellName(row, col); + + CellValue value = (CellValue)table.getValueAt(row, col); + int align = value != null ? value.align : 0; + + if (horizontal != null) { + align = (align & 12) + horizontal; + } + if (vertical != null) { + align = (align & 3) + (vertical << 2); + } + +// editor.edit(transaction, location, ClientModel.ALIGN, align, Bindings.INTEGER); + editor.edit(null, location, ClientModel.ALIGN, align, Bindings.INTEGER, null); + + } + } +// transaction.commit(); + } + + public ClientModel getClientInterface() { + + return clientModel; + + } + + public void setSources() { + // If expression fields are not visible, do nothing. + if (inputSource == null) + return; + + String[] available = (String[])getClientModel().getPossiblePropertyAt(ClientModel.SOURCES, ClientModel.SOURCES_AVAILABLE); + String current = (String)getClientModel().getPossiblePropertyAt(ClientModel.SOURCES, ClientModel.SOURCES_CURRENT); + + inputSource.removeItemListener(itemListener); + inputSource.removeAllItems(); + for(String a : available) + inputSource.addItem(a); + inputSource.setSelectedItem(current); + inputSource.addItemListener(itemListener); + + } + + +} \ No newline at end of file