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.core;
022    
023    import java.io.IOException;
024    import java.io.ObjectInputStream;
025    import java.io.Serializable;
026    import java.util.ArrayList;
027    import java.util.Iterator;
028    import java.util.List;
029    
030    /**
031     * A workbook which can contain several spreadsheets.
032     * @author Einar Pehrson
033     */
034    public class Workbook implements Iterable<Spreadsheet>, Serializable {
035    
036            /** The unique version identifier used for serialization */
037            private static final long serialVersionUID = -6324252462576447242L;
038    
039            /** The spreadsheets of which the workbook consists */
040            private List<Spreadsheet> spreadsheets = new ArrayList<Spreadsheet>();
041    
042            /** The cell listeners that have been registered on the cell */
043            private transient List<WorkbookListener> listeners
044                    = new ArrayList<WorkbookListener>();
045    
046            /** The number of spreadsheets that have been created in the workbook */
047            private int createdSpreadsheets;
048    
049            /**
050             * Creates a new empty workbook.
051             */
052            public Workbook() {}
053    
054            /**
055             * Creates a new workbook, which initially contains the given number
056             * of blank spreadsheets.
057             * @param sheets the number of sheets to create initially
058             */
059            public Workbook(int sheets) {
060                    for (int i = 0; i < sheets; i++)
061                            spreadsheets.add(new SpreadsheetImpl(this,
062                                    getNextSpreadsheetTitle()));
063            }
064    
065            /**
066             * Creates a new workbook, using the given content matrix to create
067             * spreadsheets initially.
068             * @param contents the content matrices to use when creating spreadsheets
069             */
070            public Workbook(String[][]... contents) {
071                    for (String[][] content : contents)
072                            spreadsheets.add(new SpreadsheetImpl(this,
073                                    getNextSpreadsheetTitle(), content));
074            }
075    
076            /**
077             * Adds a blank spreadsheet to the end of the workbook.
078             */
079            public void addSpreadsheet() {
080                    Spreadsheet spreadsheet = new SpreadsheetImpl(this,
081                            getNextSpreadsheetTitle());
082                    spreadsheets.add(spreadsheet);
083                    fireSpreadsheetInserted(spreadsheet, spreadsheets.size() - 1);
084            }
085    
086            /**
087             * Adds a new spreadsheet to the workbook, in which cells are initialized
088             * with data from the given content matrix.
089             * @param content the contents of the cells in the spreadsheet
090             */
091            public void addSpreadsheet(String[][] content) {
092                    Spreadsheet spreadsheet = new SpreadsheetImpl(this,
093                            getNextSpreadsheetTitle(), content);
094                    spreadsheets.add(spreadsheet);
095                    fireSpreadsheetInserted(spreadsheet, spreadsheets.size() - 1);
096            }
097    
098            /**
099             * Returns the title to be used for the next spreadsheet added.
100             * @return the title to be used for the next spreadsheet added
101             */
102            private String getNextSpreadsheetTitle() {
103                    return SpreadsheetImpl.BASE_TITLE + " " + (createdSpreadsheets++ + 1);
104            }
105    
106            /**
107             * Adds a new blank spreadsheet to the workbook.
108             */
109            public void removeSpreadsheet(Spreadsheet spreadsheet) {
110                    spreadsheets.remove(spreadsheet);
111                    // Remove references to the spreadsheet in remaining spreadsheets!
112                    fireSpreadsheetRemoved(spreadsheet);
113            }
114    
115            /**
116             * Returns the spreadsheet at the given index.
117             * @param index the index of the spreadsheet in the workbook
118             * @return the spreadsheet at the given index
119             * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= |spreadsheets|)
120             */
121            public Spreadsheet getSpreadsheet(int index) throws IndexOutOfBoundsException {
122                    return spreadsheets.get(index);
123            }
124    
125            /**
126             * Returns the number of spreadsheets in the the workbook.
127             * @return the number of spreadsheets in the the workbook
128             */
129            public int getSpreadsheetCount() {
130                    return spreadsheets.size();
131            }
132    
133            /**
134             * Returns an iterator over the spreadsheets in the workbook.
135             * @return an iterator over the spreadsheets in the workbook
136             */
137            public Iterator<Spreadsheet> iterator() {
138                    return spreadsheets.iterator();
139            }
140    
141    /*
142     * EVENT HANDLING
143     */
144    
145            /**
146             * Registers the given listener on the workbook.
147             * @param listener the listener to be added
148             */
149            public void addWorkbookListener(WorkbookListener listener) {
150                    listeners.add(listener);
151            }
152    
153            /**
154             * Removes the given listener from the workbook.
155             * @param listener the listener to be removed
156             */
157            public void removeWorkbookListener(WorkbookListener listener) {
158                    listeners.remove(listener);
159            }
160    
161            /**
162             * Returns the listeners that have been registered on the workbook.
163             * @return the listeners that have been registered on the workbook
164             */
165            public WorkbookListener[] getWorkbookListeners() {
166                    return listeners.toArray(new WorkbookListener[listeners.size()]);
167            }
168    
169            /**
170             * Notifies all registered listeners that a spreadsheet has been inserted.
171             * @param spreadsheet the spreadsheet that was inserted
172             * @param index the index at which the spreadsheet was inserted
173             */
174            private void fireSpreadsheetInserted(Spreadsheet spreadsheet, int index) {
175                    for (WorkbookListener listener : listeners)
176                            listener.spreadsheetInserted(spreadsheet, index);
177            }
178    
179            /**
180             * Notifies all registered listeners that a spreadsheet has been removed.
181             * @param spreadsheet the spreadsheet that was removed
182             */
183            private void fireSpreadsheetRemoved(Spreadsheet spreadsheet) {
184                    for (WorkbookListener listener : listeners)
185                            listener.spreadsheetRemoved(spreadsheet);
186            }
187    
188            /**
189             * Notifies all registered listeners that a spreadsheet has been renamed.
190             * @param spreadsheet the spreadsheet that was renamed
191             */
192            @SuppressWarnings("unused")
193            private void fireSpreadsheetRenamed(Spreadsheet spreadsheet) {
194                    for (WorkbookListener listener : listeners)
195                            listener.spreadsheetRenamed(spreadsheet);
196            }
197    
198    /*
199     * GENERAL
200     */
201    
202            /**
203             * Customizes deserialization by recreating the listener list.
204             * @param stream the object input stream from which the object is to be read
205             * @throws IOException If any of the usual Input/Output related exceptions occur
206             * @throws ClassNotFoundException If the class of a serialized object cannot be found.
207             */
208            private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
209                    stream.defaultReadObject();
210                    listeners = new ArrayList<WorkbookListener>();
211            }
212    }