001    /*
002     * Copyright (c) 2005 Einar Pehrson <einar@pehrson.nu>.
003     *
004     * This file is part of
005     * CleanSheets - a spreadsheet application for the Java platform.
006     *
007     * CleanSheets is free software; you can redistribute it and/or modify
008     * it under the terms of the GNU General Public License as published by
009     * the Free Software Foundation; either version 2 of the License, or
010     * (at your option) any later version.
011     *
012     * CleanSheets is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015     * GNU General Public License for more details.
016     *
017     * You should have received a copy of the GNU General Public License
018     * along with CleanSheets; if not, write to the Free Software
019     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
020     */
021    package csheets.ui.sheet;
022    
023    import javax.swing.table.AbstractTableModel;
024    
025    import csheets.core.Address;
026    import csheets.core.Cell;
027    import csheets.core.CellListener;
028    import csheets.core.Spreadsheet;
029    import csheets.ui.ctrl.UIController;
030    
031    /**
032     * An table model that provides a table with data from a spreadsheet.
033     * @author Einar Pehrson
034     */
035    @SuppressWarnings("serial")
036    public class SpreadsheetTableModel extends AbstractTableModel {
037    
038            /** The spreadsheet that provides the data */
039            private Spreadsheet spreadsheet;
040    
041            /** The user interface controller */
042            private UIController uiController;
043    
044            /** The cell listener that monitors all cells in the spreadsheet */
045            private CellListener cellListener = new CellChangeListener();
046    
047            /**
048             * Creates a spreadsheet table model.
049             * @param spreadsheet the spreadsheet that provides the data
050             * @param uiController the user interface controller
051             */
052            public SpreadsheetTableModel(Spreadsheet spreadsheet, UIController uiController) {
053                    this.spreadsheet = spreadsheet;
054                    this.uiController = uiController;
055                    spreadsheet.addCellListener(cellListener);
056            }
057    
058            /**
059             * Returns <code>Cell.class</code> for all columns.
060             * @param column the column whose data type is requested
061             * @return <code>Cell.class</code>
062             */
063            public Class<?> getColumnClass(int column) {
064                    return Cell.class;
065            }
066    
067            public int getRowCount() {
068                    return Math.max(128, spreadsheet.getRowCount() + 1);
069            }
070    
071            public int getColumnCount() {
072                    return Math.max(52, spreadsheet.getRowCount() + 1);
073            }
074    
075            /**
076             * Returns the spreadsheet that provides the data.
077             * @return the spreadsheet that provides the data
078             */
079            public Spreadsheet getSpreadsheet() {
080                    return spreadsheet;
081            }
082    
083            /**
084             * Returns the cell at the given row and column in the spreadsheet.
085             * @param row the row index of the cell being requested
086             * @param column the column index of the cell being requested
087             * @return the cell at the given address
088             * @see Spreadsheet#getCell(Address)
089             */
090            public Object getValueAt(int row, int column) {
091                    if (column <= spreadsheet.getColumnCount() && row <= spreadsheet.getRowCount())
092                            return spreadsheet.getCell(new Address(column, row));
093                    else
094                            return null;
095            }
096    
097            /**
098             * Implemented as a no-op, since the table's <code>CellEditor</code>
099             * instance updates the content of cells.
100             * @param value the value to set
101             * @param row the row index of the cell to change
102             * @param column the column index of the cell to change
103             * @see Cell#setContent(String)
104             */
105            public void setValueAt(Object value, int row, int column) {}
106    
107            /**
108             * Overridden to allow editing of the table.
109             * @param row the row whose value is to be queried
110             * @param column the column whose value is to be queried                 
111             * @return true if the cell at the given row and column is editable
112             */
113            public boolean isCellEditable(int row, int column) {
114                    return true;
115            }
116    
117            /**
118             * A cell listener that monitors all cells in the spreadsheet, fires table
119             * model events when values change, and notifies the UI controller when
120             * cell content changes.
121             */
122            private class CellChangeListener implements CellListener {
123    
124                    /**
125                     * Creates a new cell change listener.
126                     */
127                    public CellChangeListener() {}
128    
129                    /**
130                     * Fires a table model event to reflect that the cell was updated.
131                     * @param cell the cell that was modified
132                     */
133                    public void valueChanged(Cell cell) {
134                            fireTableCellUpdated(cell.getAddress().getRow(),
135                                    cell.getAddress().getColumn());
136                    }
137    
138                    /**
139                     * Notifies the UI controller that the workbook has been modified.
140                     * @param cell the cell that was modified
141                     */
142                    public void contentChanged(Cell cell) {
143                            uiController.setWorkbookModified(cell.getSpreadsheet().getWorkbook());
144                    }
145    
146                    public void dependentsChanged(Cell cell) {}
147                    public void cellCleared(Cell cell) {}
148                    public void cellCopied(Cell cell, Cell source) {}
149            }
150    }