1 package org.simantics.spreadsheet.ui;
3 import java.awt.BorderLayout;
5 import java.awt.Dimension;
6 import java.awt.FlowLayout;
10 import java.awt.Rectangle;
11 import java.awt.datatransfer.Clipboard;
12 import java.awt.datatransfer.Transferable;
13 import java.awt.datatransfer.UnsupportedFlavorException;
14 import java.awt.dnd.DnDConstants;
15 import java.awt.dnd.DropTarget;
16 import java.awt.dnd.DropTargetDragEvent;
17 import java.awt.dnd.DropTargetDropEvent;
18 import java.awt.dnd.DropTargetEvent;
19 import java.awt.dnd.DropTargetListener;
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.awt.event.ItemEvent;
23 import java.awt.event.ItemListener;
24 import java.awt.event.KeyEvent;
25 import java.io.IOException;
26 import java.util.Arrays;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.List;
32 import java.util.Properties;
34 import javax.imageio.ImageIO;
35 import javax.swing.AbstractAction;
36 import javax.swing.Action;
37 import javax.swing.DefaultListModel;
38 import javax.swing.ImageIcon;
39 import javax.swing.InputMap;
40 import javax.swing.JButton;
41 import javax.swing.JCheckBox;
42 import javax.swing.JColorChooser;
43 import javax.swing.JComboBox;
44 import javax.swing.JComponent;
45 import javax.swing.JList;
46 import javax.swing.JOptionPane;
47 import javax.swing.JPanel;
48 import javax.swing.JTable;
49 import javax.swing.JTextField;
50 import javax.swing.JToggleButton;
51 import javax.swing.KeyStroke;
52 import javax.swing.SwingUtilities;
53 import javax.swing.UIManager;
54 import javax.swing.event.ChangeEvent;
55 import javax.swing.event.ListSelectionEvent;
56 import javax.swing.event.TableColumnModelEvent;
57 import javax.swing.event.TableColumnModelListener;
58 import javax.swing.event.TableModelEvent;
59 import javax.swing.event.TableModelListener;
60 import javax.swing.table.TableColumn;
62 import org.eclipse.core.runtime.Platform;
63 import org.eclipse.swt.widgets.Display;
64 import org.simantics.databoard.Bindings;
65 import org.simantics.databoard.binding.Binding;
66 import org.simantics.datatypes.literal.RGB;
67 import org.simantics.scenegraph.INode;
68 import org.simantics.scenegraph.swing.JScrollPaneSG;
69 import org.simantics.spreadsheet.Adaptable;
70 import org.simantics.spreadsheet.CellEditor;
71 import org.simantics.spreadsheet.ClientModel;
72 import org.simantics.spreadsheet.OperationMode;
73 import org.simantics.spreadsheet.SheetCommands;
74 import org.simantics.spreadsheet.Spreadsheets;
75 import org.simantics.spreadsheet.Transaction;
76 import org.simantics.spreadsheet.common.cell.Parsers;
77 import org.simantics.spreadsheet.common.cell.StringCellParser;
78 import org.simantics.spreadsheet.event.model.RemoveCellHandler;
79 import org.simantics.ui.colors.Colors;
80 import org.simantics.ui.dnd.LocalObjectTransfer;
81 import org.simantics.ui.dnd.LocalObjectTransferable;
82 import org.simantics.ui.fonts.Fonts;
83 import org.simantics.utils.ui.awt.WrapLayout;
84 import org.simantics.utils.ui.dialogs.ShowMessage;
85 import org.simantics.utils.ui.jface.ActiveSelectionProvider;
87 @SuppressWarnings({ "rawtypes", "unchecked" })
88 public class SpreadsheetModel {
90 final private static String OPERATIONMODE = "Operation Mode";
91 final private static String EDITMODE = "Edit Mode";
93 final private Adaptable serverInterface;
94 final private ClientModel clientModel;
95 final private ActiveSelectionProvider selectionProvider;
96 protected Clipboard system;
97 protected StringCellParser[] parsers = new StringCellParser[] { Parsers.COMMAND_PARSER, Parsers.EXPRESSION_PARSER, Parsers.TEXT_PARSER };
99 public SpreadsheetModel(Adaptable serverInterface, ActiveSelectionProvider selectionProvider) {
101 this.serverInterface = serverInterface;
102 this.clientModel = new ClientModelImpl();
103 this.selectionProvider = selectionProvider;
107 public ClientModel getClientModel() {
111 public SpreadsheetTable getTable() {
115 private JTextField expression;
116 private JButton foreground;
117 private JButton background;
118 private JButton font;
119 private JButton align_left;
120 private JButton align_hcenter;
121 private JButton align_right;
122 private JButton align_top;
123 private JButton align_vcenter;
124 private JButton align_bottom;
125 private JComboBox borders;
126 public JComboBox inputSource;
127 public JComboBox sheets;
128 private JButton lock;
129 private JButton unlock;
130 private JButton merge;
131 private JButton unmerge;
132 private ExpressionTextListener etl;
133 private SpreadsheetTable table;
134 @SuppressWarnings("unused")
135 private ExcelAdapter excel;
136 @SuppressWarnings("unused")
137 private boolean columnMarginsDirty = false;
139 private ItemListener itemListener = null;
140 private ItemListener sheetsListener = null;
141 private ItemListener initialConditionsListener = null;
143 private JComboBox initialConditions;
144 private JButton saveIc;
145 private JButton context;
146 private JToggleButton operationMode;
148 private JCheckBox iterationEnabled;
149 private JTextField iterationLimit;
151 public JComponent createComponent(final INode node) {
153 Properties props = serverInterface.getAdapter(Properties.class);
155 boolean addExpressionField = props == null || "true".equalsIgnoreCase(props.getProperty(SpreadsheetModelProperties.SHEET_EXPRESSION_VISIBLE, "true"));
157 final JPanel panel = new JPanel(new BorderLayout());
159 final DefaultListModel lm = new DefaultListModel() {
161 private static final long serialVersionUID = 5246691801867533053L;
163 public Object getElementAt(int index) {
164 Object result = super.getElementAt(index);
165 if(result instanceof String) return result;
166 else return "" + (index + 1);
171 if (addExpressionField) {
173 foreground = new JButton();
174 foreground.setToolTipText("Assign foreground color to selection");
177 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/paintbrush.png"));
178 foreground.setIcon(new ImageIcon(img));
179 } catch (IOException ex) {
181 foreground.addActionListener(new ActionListener() {
183 public void actionPerformed(ActionEvent e) {
185 Color c = JColorChooser.showDialog(foreground, "asd", Colors.awt(Colors.rgb(0, 0, 0)));
188 RGB.Integer color = Colors.integerRGB(c);
190 editSelection(ClientModel.FOREGROUND, color, RGB.Integer.BINDING);
194 background = new JButton();
195 background.setToolTipText("Assign background color to selection");
198 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/paintcan.png"));
199 background.setIcon(new ImageIcon(img));
200 } catch (IOException ex) {
203 background.addActionListener(new ActionListener() {
205 public void actionPerformed(ActionEvent e) {
207 Color c = JColorChooser.showDialog(background, "asd", Colors.awt(Colors.rgb(0, 0, 0)));
211 RGB.Integer color = Colors.integerRGB(c);
213 editSelection(ClientModel.BACKGROUND, color, RGB.Integer.BINDING);
217 String[] availableInitialConditions = clientModel.getPossiblePropertyAt(ClientModel.STATES, ClientModel.STATES_AVAILABLE);
218 String currentInitialCondition = clientModel.getPossiblePropertyAt(ClientModel.STATES, ClientModel.STATES_CURRENT);
220 initialConditions = new JComboBox<>();
221 for(String sheet : availableInitialConditions)
222 initialConditions.addItem(sheet);
224 initialConditions.setSelectedItem(currentInitialCondition);
226 initialConditionsListener = new ItemListener() {
228 public void itemStateChanged(ItemEvent arg0) {
230 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
232 if(arg0.getStateChange() == ItemEvent.SELECTED)
233 editor.edit(null, ClientModel.STATES, ClientModel.STATES_CURRENT, arg0.getItem(), null, null);
238 initialConditions.addItemListener(initialConditionsListener);
240 saveIc = new JButton();
241 saveIc.setText("Save IC");
242 saveIc.setToolTipText("Save current Initial Condition");
243 saveIc.addActionListener(new ActionListener() {
246 public void actionPerformed(ActionEvent e) {
248 SheetCommands commands = serverInterface.getAdapter(SheetCommands.class);
249 commands.saveState();
253 font = new JButton();
254 font.setToolTipText("Assign font to selection");
256 font.addActionListener(new ActionListener() {
258 public void actionPerformed(ActionEvent e) {
259 JFontChooser fontChooser = new JFontChooser();
260 int result = fontChooser.showDialog(font);
261 if (result == JFontChooser.OK_OPTION) {
263 Font font = fontChooser.getSelectedFont();
264 System.out.println("Selected Font : " + font);
266 org.simantics.datatypes.literal.Font f = Fonts.fromAWT(font);
268 editSelection(ClientModel.FONT, f, org.simantics.datatypes.literal.Font.BINDING);
274 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/font.png"));
275 font.setIcon(new ImageIcon(img));
276 } catch (IOException ex) {
279 align_left = new JButton();
280 align_left.setToolTipText("Align selection to left");
283 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_left.png"));
284 align_left.setIcon(new ImageIcon(img));
285 } catch (IOException ex) {
288 align_left.addActionListener(new ActionListener() {
290 public void actionPerformed(ActionEvent e) {
291 editSelectionAlignment(0, null);
295 align_hcenter = new JButton();
296 align_hcenter.setToolTipText("Align selection horizontally to center");
299 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_center.png"));
300 align_hcenter.setIcon(new ImageIcon(img));
301 } catch (IOException ex) {
304 align_hcenter.addActionListener(new ActionListener() {
306 public void actionPerformed(ActionEvent e) {
307 editSelectionAlignment(1, null);
311 align_right = new JButton();
312 align_right.setToolTipText("Align selection to right");
315 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_right.png"));
316 align_right.setIcon(new ImageIcon(img));
317 } catch (IOException ex) {
320 align_right.addActionListener(new ActionListener() {
322 public void actionPerformed(ActionEvent e) {
323 editSelectionAlignment(2, null);
327 align_top = new JButton();
328 align_top.setToolTipText("Align selection to top");
331 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_top.png"));
332 align_top.setIcon(new ImageIcon(img));
333 } catch (IOException ex) {
336 align_top.addActionListener(new ActionListener() {
338 public void actionPerformed(ActionEvent e) {
339 editSelectionAlignment(null, 0);
343 align_vcenter = new JButton();
344 align_vcenter.setToolTipText("Align selection vertically to center");
347 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_middle.png"));
348 align_vcenter.setIcon(new ImageIcon(img));
349 } catch (IOException ex) {
352 align_vcenter.addActionListener(new ActionListener() {
354 public void actionPerformed(ActionEvent e) {
355 editSelectionAlignment(null, 1);
359 align_bottom = new JButton();
360 align_bottom.setToolTipText("Align selection to bottom");
363 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/shape_align_bottom.png"));
364 align_bottom.setIcon(new ImageIcon(img));
365 } catch (IOException ex) {
368 align_bottom.addActionListener(new ActionListener() {
370 public void actionPerformed(ActionEvent e) {
371 editSelectionAlignment(null, 2);
375 borders = new JComboBox();
376 borders.addItem("No borders");
377 borders.addItem("Bottom border");
378 borders.addItem("Top border");
379 borders.addItem("Left border");
380 borders.addItem("Right border");
381 borders.addActionListener(new ActionListener() {
383 Map<String,Integer> work = new HashMap<String,Integer>();
385 int getCurrent(String location, int row, int column) {
386 CellValue value = (CellValue)table.getValueAt(row, column);
387 int border = value != null ? value.border : 0;
388 work.put(location, border);
392 void setCurrent(String location, int border) {
393 work.put(location, border);
397 public void actionPerformed(ActionEvent e) {
401 int index = borders.getSelectedIndex();
403 final int[] selectedColumns = table.getSelectedColumns();
404 final int[] selectedRows = table.getSelectedRows();
406 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
407 if(editor == null) return;
409 for(int col : selectedColumns) {
410 for(int row : selectedRows) {
412 String location = Spreadsheets.cellName(row, col);
417 String left = Spreadsheets.cellName(row, col-1);
418 setCurrent(left, getCurrent(left, row, col-1) & 2);
421 String up = Spreadsheets.cellName(row-1, col);
422 setCurrent(up, getCurrent(up, row-1, col) & 1);
424 setCurrent(location, 0);
427 else if(index == 1) {
428 setCurrent(location, getCurrent(location, row, col) | 2);
431 else if(index == 2) {
433 String up = Spreadsheets.cellName(row-1, col);
434 setCurrent(up, getCurrent(up, row-1, col) | 2);
438 else if(index == 3) {
440 String left = Spreadsheets.cellName(row, col-1);
441 setCurrent(left, getCurrent(left, row, col-1) | 1);
445 else if(index == 4) {
446 setCurrent(location, getCurrent(location, row, col) | 1);
452 OperationMode mode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
453 Transaction transaction = editor.startTransaction(mode);
454 for(Map.Entry<String, Integer> entry : work.entrySet()) {
455 String location = entry.getKey();
456 Integer border = entry.getValue();
457 editor.edit(transaction, location, ClientModel.BORDER, border, Bindings.INTEGER, null);
459 transaction.commit();
465 lock = new JButton();
466 lock.setToolTipText("Lock selection");
469 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/lock.png"));
470 lock.setIcon(new ImageIcon(img));
471 } catch (IOException ex) {
474 lock.addActionListener(new ActionListener() {
476 public void actionPerformed(ActionEvent e) {
477 editSelection(ClientModel.LOCKED, true, Bindings.BOOLEAN);
481 unlock = new JButton();
482 unlock.setToolTipText("Unlock selection");
485 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/lock_open.png"));
486 unlock.setIcon(new ImageIcon(img));
487 } catch (IOException ex) {
490 unlock.addActionListener(new ActionListener() {
492 public void actionPerformed(ActionEvent e) {
493 editSelection(ClientModel.LOCKED, false, Bindings.BOOLEAN);
497 merge = new JButton();
498 merge.setToolTipText("Merge cells");
501 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/link.png"));
502 merge.setIcon(new ImageIcon(img));
503 } catch (IOException ex) {
506 merge.addActionListener(new ActionListener() {
508 public void actionPerformed(ActionEvent e) {
510 final int[] selectedColumns = table.getSelectedColumns();
511 final int[] selectedRows = table.getSelectedRows();
513 if (isRectangularSelection(table)) {
515 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
516 if(editor == null) return;
518 OperationMode mode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
519 Transaction transaction = editor.startTransaction(mode);
521 Rectangle selection = new Rectangle(selectedColumns[0], selectedRows[0], selectedColumns.length, selectedRows.length);
522 List<Rectangle> spans = clientModel.getSpans();
524 boolean found = true;
527 Iterator<Rectangle> iter = spans.iterator();
528 while (iter.hasNext()) {
529 Rectangle span = iter.next();
530 if (selection.intersects(span)) {
531 selection = selection.union(span);
533 String location = Spreadsheets.cellName(span.y, span.x);
534 editor.edit(transaction, location, ClientModel.ROW_SPAN, 1, Bindings.INTEGER, null);
535 editor.edit(transaction, location, ClientModel.COLUMN_SPAN, 1, Bindings.INTEGER, null);
541 String location = Spreadsheets.cellName(selection.y, selection.x);
542 if (selection.height > 1) {
543 editor.edit(transaction, location, ClientModel.ROW_SPAN, selection.height, Bindings.INTEGER, null);
545 if (selection.width > 1) {
546 editor.edit(transaction, location, ClientModel.COLUMN_SPAN, selection.width, Bindings.INTEGER, null);
548 transaction.commit();
551 //ShowMessage.showError(, message);
552 Display.getDefault().asyncExec(new Runnable() {
554 ShowMessage.showWarning("Merging cells failed", "Selected range is not rectangular.");
561 unmerge = new JButton();
562 unmerge.setToolTipText("Unmerge cells");
565 Image img = ImageIO.read(Platform.getBundle("com.famfamfam.silk").getResource("icons/link_break.png"));
566 unmerge.setIcon(new ImageIcon(img));
567 } catch (IOException ex) {
570 unmerge.addActionListener(new ActionListener() {
572 public void actionPerformed(ActionEvent e) {
574 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
575 if(editor == null) return;
577 OperationMode mode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
578 Transaction transaction = editor.startTransaction(mode);
579 editSelection(editor, transaction, ClientModel.ROW_SPAN, 1, Bindings.INTEGER);
580 editSelection(editor, transaction, ClientModel.COLUMN_SPAN, 1, Bindings.INTEGER);
581 transaction.commit();
585 String[] availableSources = clientModel.getPossiblePropertyAt(ClientModel.SOURCES, ClientModel.SOURCES_AVAILABLE);
586 String[] availableSheets = clientModel.getPossiblePropertyAt(ClientModel.SHEETS, ClientModel.SHEETS_AVAILABLE);
587 String currentSheet = clientModel.getPossiblePropertyAt(ClientModel.SHEETS, ClientModel.SHEETS_CURRENT);
588 @SuppressWarnings("unused")
589 String currentSource = clientModel.getPossiblePropertyAt(ClientModel.SOURCES, ClientModel.SOURCES_CURRENT);
591 inputSource = new JComboBox();
592 for(String source : availableSources)
593 inputSource.addItem(source);
595 sheets = new JComboBox();
596 for(String sheet : availableSheets)
597 sheets.addItem(sheet);
599 sheets.setSelectedItem(currentSheet);
601 sheetsListener = new ItemListener() {
604 public void itemStateChanged(ItemEvent arg0) {
606 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
607 if (editor != null) {
608 if (arg0.getStateChange() == ItemEvent.SELECTED) {
609 editor.edit(null, ClientModel.SHEETS, ClientModel.SHEETS_CURRENT, arg0.getItem(), null, null);
610 HashSet<String> targets = new HashSet<>();
611 targets.add(ClientModel.MODE);
612 resetSelections(editor, targets);
618 itemListener = new ItemListener() {
621 public void itemStateChanged(ItemEvent arg0) {
623 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
625 if(arg0.getStateChange() == ItemEvent.SELECTED) {
626 editor.edit(null, ClientModel.SOURCES, ClientModel.SOURCES_CURRENT, arg0.getItem(), null, null);
634 inputSource.addItemListener(itemListener);
636 new DropTarget(inputSource,DnDConstants.ACTION_COPY_OR_MOVE,new DropTargetListener() {
639 public void dropActionChanged(DropTargetDragEvent arg0) {
640 // TODO Auto-generated method stub
645 public void drop(DropTargetDropEvent dtde) {
648 Transferable transferable = dtde.getTransferable();
650 if( transferable.isDataFlavorSupported(
651 LocalObjectTransferable.FLAVOR ) ) {
653 dtde.acceptDrop( DnDConstants.ACTION_MOVE );
655 transferable.getTransferData(LocalObjectTransferable.FLAVOR );
656 Object obj = LocalObjectTransfer.getTransfer().getObject();
658 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
660 editor.edit(null, ClientModel.SOURCES, ClientModel.SOURCES_CURRENT, obj, null, null);
663 dtde.getDropTargetContext().dropComplete( true );
669 } catch( IOException exception ) {
670 exception.printStackTrace();
672 } catch( UnsupportedFlavorException ufException ) {
673 ufException.printStackTrace();
680 public void dragOver(DropTargetDragEvent arg0) {
681 // TODO Auto-generated method stub
686 public void dragExit(DropTargetEvent arg0) {
687 // TODO Auto-generated method stub
692 public void dragEnter(DropTargetDragEvent arg0) {
693 // TODO Auto-generated method stub
699 expression = new JTextField();
700 etl = new ExpressionTextListener(expression, serverInterface.getAdapter(CellEditor.class));
701 expression.addFocusListener(etl);
702 expression.addKeyListener(etl);
704 //Large default size so that the expression field is clearly visible
705 expression.setPreferredSize(new Dimension(600, 32));
707 sheets.addItemListener(sheetsListener);
710 context = new JButton("Change context");
712 context.addActionListener(new ActionListener() {
715 public void actionPerformed(ActionEvent e) {
717 Frame frame = (Frame) SwingUtilities.getRoot(context);
718 String result = JOptionPane.showInputDialog(frame, "Context URI");
719 if (result != null && !result.isEmpty()) {
720 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
722 editor.edit(null, ClientModel.CONTEXT, ClientModel.CONTEXT_CURRENT, result, null, null);
728 OperationMode currentMode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
730 if (currentMode.equals(OperationMode.OPERATION))
731 text = OPERATIONMODE;
734 operationMode = new JToggleButton(text);
735 operationMode.addActionListener(new ActionListener() {
738 public void actionPerformed(ActionEvent e) {
740 OperationMode currentMode = clientModel.getPropertyAt(ClientModel.MODE, ClientModel.MODE_CURRENT);
741 OperationMode newMode;
743 if (currentMode.equals(OperationMode.OPERATION)) {
744 System.err.println("Current mode is operation");
745 newMode = OperationMode.EDIT_MODE;
746 newText = "Edit Mode";
748 System.err.println("Current mode is read-only");
749 newMode = OperationMode.OPERATION;
750 newText = "Operation Mode";
752 System.err.println("Setting new text " + newText + " to replace old " + operationMode.getText());
753 operationMode.setText(newText);
755 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
757 editor.edit(null, ClientModel.MODE, ClientModel.MODE_CURRENT, newMode, null, null);
762 iterationEnabled = new JCheckBox("Iteration Enabled");
763 iterationEnabled.addActionListener(new ActionListener() {
766 public void actionPerformed(ActionEvent e) {
767 System.out.println("state is " + iterationEnabled.isSelected());
768 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
770 editor.edit(null, ClientModel.ITERATION_ENABLED, ClientModel.ITERATION_ENABLED, iterationEnabled.isSelected(), null, null);
775 iterationLimit = new JTextField("100");
776 iterationLimit.setEnabled(false);
777 iterationLimit.addActionListener(new ActionListener() {
780 public void actionPerformed(ActionEvent e) {
787 Font font = new Font("Courier", Font.PLAIN, 14);
789 UIManager.put(SpreadsheetTable.uiClassID, SpreadsheetTableUI.class.getCanonicalName());
790 final JList rowHeader = new JList(lm);
791 table = new SpreadsheetTable(node, (CellEditor)serverInterface.getAdapter(CellEditor.class), clientModel, lm, rowHeader) {
793 private static final long serialVersionUID = 4553572254034185984L;
796 protected void mouseDragFinished() {
798 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
799 if(editor == null) return;
801 TableColumn column = table.getTableHeader().getResizingColumn();
802 if(column == null) return;
804 int[] current = clientModel.getColumnWidths();
805 if(column.getModelIndex() >= current.length) {
806 current = Arrays.copyOf(current, column.getModelIndex()+1);
809 current[column.getModelIndex()] = column.getWidth();
811 editor.edit(null, ClientModel.HEADERS, ClientModel.HEADERS_COL_WIDTHS, current, Bindings.INT_ARRAY, null);
817 ((ClientTableModel)table.getModel()).setModel(this);
819 InputMap im = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
820 Action deleteAction = new AbstractAction() {
821 private static final long serialVersionUID = 428343700053346645L;
823 @SuppressWarnings("unused")
824 public void actionPerformed(ActionEvent ae) {
825 System.out.println("deleteaction");
826 RemoveCellHandler removeHandler = serverInterface.getAdapter(RemoveCellHandler.class);
827 int[] rowSelection = table.getSelectedRows();
828 int[] columnSelection = table.getSelectedColumns();
829 for (int i = 0; i < columnSelection.length; i++) {
830 for (int j = 0; j < rowSelection.length; j++) {
831 int row = rowSelection[j];
832 int column = columnSelection[i];
833 System.out.println("deleteaction " + row + " " + column);
834 Object cell = table.getValueAt(row, column);
835 // RemoveHandler remove = cell.getAdapter(RemoveHandler.class);
841 KeyStroke delete = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
842 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), delete);
843 table.getActionMap().put(im.get(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0)), deleteAction);
847 @SuppressWarnings("unused")
848 DropTarget dropTarget = new DropTarget(table,
849 new TableDropTargetListener(table, serverInterface, clientModel));
851 if(serverInterface != null)
852 excel = new ExcelAdapter(table, clientModel, serverInterface, parsers);
854 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
856 table.setColumnSelectionAllowed(true);
858 rowHeader.setFixedCellWidth(40);
860 rowHeader.setCellRenderer(new RowHeaderRenderer(table));
861 rowHeader.setBackground(DefaultLookup.GRAY);
863 table.getModel().addTableModelListener(new TableModelListener() {
866 public void tableChanged(TableModelEvent e) {
867 int currentRows = rowHeader.getModel().getSize();
868 int tableRows = table.getModel().getRowCount();
869 if(currentRows != tableRows) {
870 lm.setSize(tableRows);
875 JScrollPaneSG scroll = new JScrollPaneSG(table, node);
877 scroll.setRowHeaderView(rowHeader);
879 table.getParent().setBackground(DefaultLookup.GRAY);
880 table.getTableHeader().setBackground(DefaultLookup.GRAY);
881 rowHeader.getParent().setBackground(DefaultLookup.GRAY);
882 scroll.getViewport().setBackground(DefaultLookup.GRAY);
884 table.getTableHeader().setDefaultRenderer(new ColumnHeaderRenderer());
886 scroll.setBackground(DefaultLookup.GRAY);
888 if(selectionProvider != null) {
890 SelectionListener listener = new SelectionListener(table, expression, etl, selectionProvider, serverInterface, clientModel);
891 table.getSelectionModel().addListSelectionListener(listener);
892 table.getColumnModel().getSelectionModel()
893 .addListSelectionListener(listener);
897 table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
900 public void columnSelectionChanged(ListSelectionEvent e) {
901 // System.out.println("columnSelectionChanged " + e);
905 public void columnRemoved(TableColumnModelEvent e) {
906 // System.out.println("columnRemoved " + e);
910 public void columnMoved(TableColumnModelEvent e) {
911 // System.out.println("columnMoved " + e);
915 public void columnMarginChanged(ChangeEvent e) {
916 columnMarginsDirty = true;
920 public void columnAdded(TableColumnModelEvent e) {
921 // System.out.println("columnAdded " + e);
926 new TableRowResizer(table) {
929 public void onResize(int row, int height) {
933 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
934 if(editor == null) return;
936 int[] current = clientModel.getRowHeights();
937 if(row >= current.length) {
938 current = Arrays.copyOf(current, row+1);
941 current[row] = height;
943 editor.edit(null, ClientModel.HEADERS, ClientModel.HEADERS_ROW_HEIGHTS, current, Bindings.INT_ARRAY, null);
945 rowHeader.setCellRenderer(new RowHeaderRenderer(table));
951 if (addExpressionField) {
953 JPanel tools = new JPanel(new WrapLayout(FlowLayout.LEADING, 0, 0));
954 panel.add(tools, BorderLayout.PAGE_START);
956 tools.add(this.font);
958 tools.add(foreground);
960 tools.add(background);
962 tools.add(align_left);
963 tools.add(align_hcenter);
964 tools.add(align_right);
966 tools.add(align_top);
967 tools.add(align_vcenter);
968 tools.add(align_bottom);
978 tools.add(inputSource);
982 tools.add(initialConditions);
988 tools.add(operationMode);
990 tools.add(iterationEnabled);
992 tools.add(iterationLimit);
994 tools.add(expression);
997 panel.add(scroll, BorderLayout.CENTER);
1003 private void resetSelections(CellEditor editor, HashSet<String> targets) {
1004 if(targets.contains(ClientModel.MODE)) {
1005 editor.edit(null, ClientModel.MODE, ClientModel.MODE_CURRENT, OperationMode.OPERATION, null, null);
1006 operationMode.setText(OPERATIONMODE);
1010 private boolean isRectangularSelection(SpreadsheetTable table) {
1011 int[] selectedColumns = table.getSelectedColumns();
1012 int[] selectedRows = table.getSelectedRows();
1014 if ((selectedColumns.length == 0) || (selectedRows.length == 0)) {
1018 for (int row = 0; row < selectedRows.length - 1; row++) {
1019 if (selectedRows[row + 1] != selectedRows[row] + 1) {
1024 for (int column = 0; column < selectedColumns.length - 1; column++) {
1025 if (selectedColumns[column + 1] != selectedColumns[column] + 1) {
1033 private void editSelection(String property, Object value, Binding binding) {
1034 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
1035 if(editor == null) return;
1037 // Transaction transaction = editor.startTransaction();
1038 editSelection(editor, null, property, value, binding);
1039 // transaction.commit();
1042 private void editSelection(CellEditor editor, Transaction transaction, String property, Object value, Binding binding) {
1043 for(int col : table.getSelectedColumns()) {
1044 for(int row : table.getSelectedRows()) {
1045 String location = Spreadsheets.cellName(row, col);
1046 editor.edit(transaction, location, property, value, binding, null);
1052 private void editSelectionAlignment(Integer horizontal, Integer vertical) {
1053 final int[] selectedColumns = table.getSelectedColumns();
1054 final int[] selectedRows = table.getSelectedRows();
1056 CellEditor editor = serverInterface.getAdapter(CellEditor.class);
1057 if(editor == null) return;
1059 // Transaction transaction = editor.startTransaction();
1060 for(int col : selectedColumns) {
1061 for(int row : selectedRows) {
1062 String location = Spreadsheets.cellName(row, col);
1064 CellValue value = (CellValue)table.getValueAt(row, col);
1065 int align = value != null ? value.align : 0;
1067 if (horizontal != null) {
1068 align = (align & 12) + horizontal;
1070 if (vertical != null) {
1071 align = (align & 3) + (vertical << 2);
1074 // editor.edit(transaction, location, ClientModel.ALIGN, align, Bindings.INTEGER);
1075 editor.edit(null, location, ClientModel.ALIGN, align, Bindings.INTEGER, null);
1079 // transaction.commit();
1082 public ClientModel getClientInterface() {
1088 public void setSources() {
1089 // If expression fields are not visible, do nothing.
1090 if (inputSource == null)
1093 String[] available = (String[])getClientModel().getPossiblePropertyAt(ClientModel.SOURCES, ClientModel.SOURCES_AVAILABLE);
1094 String current = (String)getClientModel().getPossiblePropertyAt(ClientModel.SOURCES, ClientModel.SOURCES_CURRENT);
1096 inputSource.removeItemListener(itemListener);
1097 inputSource.removeAllItems();
1098 for(String a : available)
1099 inputSource.addItem(a);
1100 inputSource.setSelectedItem(current);
1101 inputSource.addItemListener(itemListener);