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 */
021package csheets.ui.sheet;
022
023import javax.swing.table.AbstractTableModel;
024
025import csheets.core.Address;
026import csheets.core.Cell;
027import csheets.core.CellListener;
028import csheets.core.Spreadsheet;
029import 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")
036public 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}