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