1   /**
2    * Distribution License:
3    * BibleDesktop is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU General Public License, version 2 as published by
5    * the Free Software Foundation. This program is distributed in the hope
6    * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7    * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *       http://www.gnu.org/copyleft/gpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * Copyright: 2005
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: BibleComboBoxModel.java 2223 2012-01-26 21:28:02Z dmsmith $
21   */
22  package org.crosswire.bibledesktop.book;
23  
24  import java.io.IOException;
25  import java.io.ObjectInputStream;
26  
27  import javax.swing.AbstractListModel;
28  import javax.swing.ComboBoxModel;
29  
30  import org.crosswire.common.util.Logger;
31  import org.crosswire.jsword.passage.Verse;
32  import org.crosswire.jsword.versification.BibleBook;
33  import org.crosswire.jsword.versification.Versification;
34  import org.crosswire.jsword.versification.system.Versifications;
35  
36  /**
37   * A ComboBoxModel for selecting book/chapter/verse.
38   * 
39   * @see gnu.gpl.License for license details.<br>
40   *      The copyright to this program is held by it's authors.
41   * @author Joe Walker [joe at eireneh dot com]
42   */
43  /**
44   *
45   *
46   * @see gnu.gpl.License for license details.
47   *      The copyright to this program is held by it's authors.
48   * @author DM Smith [dmsmith555 at yahoo dot com]
49   */
50  public class BibleComboBoxModel extends AbstractListModel implements ComboBoxModel {
51      /**
52       * The level of the book combo.
53       */
54      protected enum Level {
55          /**
56           * For when the we are a book level combo
57           */
58          BOOK,
59  
60          /**
61           * For when the we are a chapter level combo
62           */
63          CHAPTER,
64  
65          /**
66           * For when the we are a verse level combo
67           */
68          VERSE,
69      }
70  
71      /**
72       * Simple ctor for choosing verses
73       */
74      protected BibleComboBoxModel(BibleComboBoxModelSet set, Level level) {
75          this.set = set;
76          this.level = level;
77  
78          switch (level) {
79          case BOOK:
80              selected = set.getVerse().getBook().getBookName();
81              break;
82  
83          case CHAPTER:
84              selected = Integer.valueOf(set.getVerse().getChapter());
85              break;
86  
87          case VERSE:
88              selected = Integer.valueOf(set.getVerse().getVerse());
89              break;
90  
91          default:
92              assert false : level;
93          }
94      }
95  
96      /* (non-Javadoc)
97       * @see javax.swing.ComboBoxModel#setSelectedItem(java.lang.Object)
98       */
99      public void setSelectedItem(Object selected) {
100         log.debug("setSelectedItem(" + selected + ") level=" + level);
101 
102         switch (level) {
103         case BOOK:
104             BibleBook book = (BibleBook) selected;
105             assert book != null;
106             setBook(book);
107             break;
108 
109         case CHAPTER:
110             Integer csel = (Integer) selected;
111             setChapter(csel.intValue());
112             break;
113 
114         case VERSE:
115             Integer vsel = (Integer) selected;
116             setVerse(vsel.intValue());
117             break;
118 
119         default:
120             assert false : level;
121         }
122 
123         this.selected = selected;
124     }
125 
126     /* (non-Javadoc)
127      * @see javax.swing.ComboBoxModel#getSelectedItem()
128      */
129     public Object getSelectedItem() {
130         return selected;
131     }
132 
133     /* (non-Javadoc)
134      * @see javax.swing.ListModel#getSize()
135      */
136     public int getSize() {
137         switch (level) {
138         case BOOK:
139             return v11n.getBooks().getBookCount();
140 
141         case CHAPTER:
142             return v11n.getLastChapter(set.getVerse().getBook());
143 
144         case VERSE:
145             return v11n.getLastVerse(set.getVerse().getBook(), set.getVerse().getChapter());
146 
147         default:
148             assert false : level;
149             return 0;
150         }
151     }
152 
153     /* (non-Javadoc)
154      * @see javax.swing.ListModel#getElementAt(int)
155      */
156     public Object getElementAt(int index) {
157         switch (level) {
158         case BOOK:
159             return v11n.getBooks().getBook(index);
160         default:
161             return Integer.valueOf(index + 1);
162 
163         }
164     }
165 
166     /**
167      * Accessor for the book
168      */
169     public void setBook(BibleBook book) {
170         // Try to honor current chapter and verse
171         // Use 1 if it is not possible
172         Verse old = set.getVerse();
173         int chapter = old.getChapter();
174         int verse = old.getVerse();
175 
176         chapter = Math.min(chapter, v11n.getLastChapter(book));
177         verse = Math.min(verse, v11n.getLastVerse(book, chapter));
178 
179         Verse update = new Verse(book, chapter, verse);
180         set.setVerse(update);
181     }
182 
183     /**
184      * Accessor for the chapter
185      */
186     public void setChapter(int chapter) {
187         // Try to honor current verse
188         // Use 1 if it is not possible
189         Verse old = set.getVerse();
190         BibleBook book = old.getBook();
191         int verse = old.getVerse();
192 
193         verse = Math.min(verse, v11n.getLastVerse(book, chapter));
194 
195         Verse update = new Verse(book, chapter, verse);
196         set.setVerse(update);
197     }
198 
199     /**
200      * Accessor for the chapter
201      */
202     public void setVerse(int verse) {
203         Verse old = set.getVerse();
204         Verse update = new Verse(old.getBook(), old.getChapter(), verse);
205         set.setVerse(update);
206     }
207 
208     /* (non-Javadoc)
209      * @see javax.swing.AbstractListModel#fireContentsChanged(java.lang.Object, int, int)
210      */
211     @Override
212     protected void fireContentsChanged(Object source, int index0, int index1) {
213         super.fireContentsChanged(source, index0, index1);
214     }
215 
216     /**
217      * Serialization support.
218      * 
219      * @param is
220      * @throws IOException
221      * @throws ClassNotFoundException
222      */
223     private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
224         // Broken but we don't serialize views
225         set = null;
226         selected = null;
227         // AV11N(DMS): Is this right?
228         v11n = Versifications.instance().getDefaultVersification();
229         is.defaultReadObject();
230     }
231 
232     /**
233      * The log stream
234      */
235     private static final Logger log = Logger.getLogger(BibleComboBoxModel.class);
236 
237     // AV11N(DMS): Is this right?
238     private transient Versification v11n = Versifications.instance().getDefaultVersification();
239 
240     /**
241      * Shared settings
242      */
243     private transient BibleComboBoxModelSet set;
244 
245     /**
246      * What is currently selected?
247      */
248     private transient Object selected;
249 
250     /**
251      * Are we a book, chapter or verse selector
252      */
253     protected Level level;
254 
255     /**
256      * Serialization ID
257      */
258     private static final long serialVersionUID = 3616449020667442997L;
259 }
260