001    /*
002     * Copyright (c) 2005 Jens Schou, Staffan Gustafsson, Björn Lanneskog, 
003     * Einar Pehrson and Sebastian Kekkonen
004     *
005     * This file is part of
006     * CleanSheets Extension for Test Cases
007     *
008     * CleanSheets Extension for Test Cases is free software; you can
009     * redistribute it and/or modify it under the terms of the GNU General Public
010     * License as published by the Free Software Foundation; either version 2 of
011     * the License, or (at your option) any later version.
012     *
013     * CleanSheets Extension for Test Cases is distributed in the hope that
014     * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
015     * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016     * See the GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with CleanSheets Extension for Test Cases; if not, write to the
020     * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
021     * Boston, MA  02111-1307  USA
022     */
023    package csheets.ext.test.ui;
024    
025    import java.awt.BorderLayout;
026    import java.util.Set;
027    
028    import javax.swing.JPanel;
029    import javax.swing.JScrollPane;
030    import javax.swing.event.TableModelEvent;
031    import javax.swing.event.TableModelListener;
032    import javax.swing.table.DefaultTableModel;
033    
034    import csheets.core.Cell;
035    import csheets.core.Value;
036    import csheets.ext.test.TestCase;
037    import csheets.ext.test.TestCaseParam;
038    import csheets.ext.test.TestExtension;
039    import csheets.ext.test.TestableCell;
040    import csheets.ext.test.TestableCellListener;
041    import csheets.ui.ctrl.SelectionEvent;
042    import csheets.ui.ctrl.SelectionListener;
043    import csheets.ui.ctrl.UIController;
044    
045    /**
046     * A panel for displaying test cases and providing editing of their validation
047     * states.
048     * @author Björn Lanneskog
049     * @author Einar Pehrson
050     */
051    @SuppressWarnings("serial")
052    public class TestCasePanel extends JPanel implements SelectionListener,
053                    TestableCellListener {
054            
055            /** Array which contains labels of columns in the table.*/
056            public static final String[] columnNames = {"Formula", "Result", "Validation state"};
057                    
058            /** The table model for this table.*/
059            private DefaultTableModel tableModel;
060            
061            /** The viewable table. */
062            private TestCaseTable table;
063    
064            /** Determines whether the table arranger should respond to events. */
065            private boolean listening = true;
066    
067            /**
068             * Creates a new test case panel.
069             * @param uiController the user interface controller
070             */
071            public TestCasePanel(UIController uiController) {
072                    // Creates and configures table
073                    tableModel = new DefaultTableModel(columnNames, 0);
074                    table = new TestCaseTable(tableModel);
075                    tableModel.addTableModelListener(new ValidationStateChanger(uiController));
076                    
077                    // Configures layout and adds components
078                    setLayout(new BorderLayout());
079                    JScrollPane tableScrollPane = new JScrollPane(table);
080                    add(tableScrollPane, BorderLayout.CENTER);
081            }
082    
083            /**
084             * Updates the table of precedents when the active cell is changed.
085             * @param event the selection event that was fired
086             */
087            public void selectionChanged(SelectionEvent event) {
088                    Cell cell = event.getCell();
089                    if (cell != null) {
090                            TestableCell activeCell = (TestableCell)cell.getExtension(TestExtension.NAME);
091                            activeCell.addTestableCellListener(this);
092                            testCasesChanged(activeCell);
093                    } else
094                            // Clears the table
095                            tableModel.setRowCount(0);
096    
097                    // Stops listening to previous active cell
098                    if (event.getPreviousCell() != null)
099                            ((TestableCell)event.getPreviousCell().getExtension(TestExtension.NAME))
100                                    .removeTestableCellListener(this);
101            }
102    
103            /**
104             * Updates the table of test cases when they have changed.
105             * @param cell the cell in which the event occurred
106             */
107            public void testCasesChanged(TestableCell cell) {
108                    // Clears the table
109                    tableModel.setRowCount(0);
110    
111                    if (cell.hasTestCases()) {
112                            // Fetches the cell's formula, and displays it in the column header
113                            // String[] colNames = {cell.getFormula().toString(), "Result", "Validation state"};
114                            // tableModel.setColumnIdentifiers(colNames);
115            
116                            // Adds the test cases to the table
117                            Set<TestCase> testCases = cell.getTestCases();
118                            tableModel.setRowCount(testCases.size());
119                            int row = 0;
120                            listening = false;
121                            for (TestCase testCase : testCases) {
122                                    tableModel.setValueAt(testCase, row, 0);
123                                    tableModel.setValueAt(testCase.evaluate(), row, 1);
124                                    tableModel.setValueAt(testCase.getValidationState(), row++, 2);
125                            }
126                            listening = true;
127                    } // else
128                            // Clears the table header
129                            // tableModel.setColumnIdentifiers(columnNames);
130                    table.packColumns();
131            }
132    
133            public void testCaseParametersChanged(TestableCell cell) {}
134    
135            /**
136             * A table model listener for setting the validation state of test cases.
137             * @author Einar Pehrson
138             */
139            protected class ValidationStateChanger implements TableModelListener {
140    
141                    /** The user interface controller */
142                    private UIController uiController;
143    
144                    /**
145                     * Creates a new validation state changer
146                     * @param uiController the user interface controller
147                     */
148                    public ValidationStateChanger(UIController uiController) {
149                            this.uiController = uiController;
150                    }
151    
152                    /**
153                     * Sets the validation state of a test case.
154                     * @param e the event that was fired
155                     */
156                    public void tableChanged(TableModelEvent e) {
157                            if(listening && e.getType() == TableModelEvent.UPDATE
158                                            && e.getFirstRow() >= 0) {
159                                    // Stops listening
160                                    listening = false;
161    
162                                    // Updates test case
163                                    TestCase testCase = (TestCase)tableModel.getValueAt(e.getFirstRow(), 0);
164                                    TestCase.ValidationState state = (TestCase.ValidationState)
165                                            tableModel.getValueAt(e.getFirstRow(), 2);
166                                    if (state != testCase.getValidationState()) {
167                                            testCase.setValidationState(state);
168            
169                                            // Updates resulting param
170                                            TestableCell cell = testCase.getCell();
171                                            Value result = testCase.evaluate();
172                                            switch (state) {
173                                                    case VALID:
174                                                            cell.addTestCaseParam(testCase.evaluate(),
175                                                                    TestCaseParam.Type.DERIVED);
176                                                            break;
177                                                    case PENDING:
178                                                    case REJECTED:
179                                                            TestCaseParam resultParam = null;
180                                                            for (TestCaseParam param : cell.getTestCaseParams())
181                                                                    if (result.equals(param.getValue()))
182                                                                            resultParam = param;
183                                                            if (resultParam != null)
184                                                                    cell.removeTestCaseParam(resultParam,
185                                                                            TestCaseParam.Type.DERIVED);
186                                            }
187                                            uiController.setWorkbookModified(cell.getSpreadsheet().getWorkbook());
188                                    }
189    
190                                    // Resumes
191                                    listening = true;
192                            }
193                    }
194            }
195    }