Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/virtuosotechnologies/asaph/standardmodel/BaseSongBlock.java


1   /*
2   ================================================================================
3   
4     FILE:  BaseSongBlock.java
5     
6     PROJECT:
7     
8       Asaph
9     
10    CONTENTS:
11    
12      Base class for SongBlock implementations
13    
14    PROGRAMMERS:
15    
16      Daniel Azuma (DA)  <dazuma@kagi.com>
17    
18    COPYRIGHT:
19    
20      Copyright (C) 2003  Daniel Azuma  (dazuma@kagi.com)
21      
22      This program is free software; you can redistribute it and/or
23      modify it under the terms of the GNU General Public License as
24      published by the Free Software Foundation; either version 2
25      of the License, or (at your option) any later version.
26      
27      This program is distributed in the hope that it will be useful,
28      but WITHOUT ANY WARRANTY; without even the implied warranty of
29      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30      GNU General Public License for more details.
31      
32      You should have received a copy of the GNU General Public
33      License along with this program; if not, write to
34        Free Software Foundation, Inc.
35        59 Temple Place, Suite 330
36        Boston, MA 02111-1307 USA
37  
38  ================================================================================
39  */
40  
41  
42  package com.virtuosotechnologies.asaph.standardmodel;
43  
44  import java.io.IOException;
45  import javax.swing.undo.AbstractUndoableEdit;
46  import javax.swing.undo.CannotUndoException;
47  import javax.swing.undo.CannotRedoException;
48  import javax.swing.event.UndoableEditListener;
49  import org.xml.sax.SAXException;
50  import org.xml.sax.Attributes;
51  import org.xml.sax.ErrorHandler;
52  import org.xml.sax.Locator;
53  
54  import com.virtuosotechnologies.lib.util.StringID;
55  import com.virtuosotechnologies.lib.xml.XMLUnparser;
56  
57  import com.virtuosotechnologies.asaph.model.SongLine;
58  import com.virtuosotechnologies.asaph.model.SongBlock;
59  import com.virtuosotechnologies.asaph.model.notation.NotationFactory;
60  
61  
62  /**
63   * Base class for SongBlock implementations
64   */
65  /*package*/ abstract class BaseSongBlock
66  extends BaseSongMember
67  implements
68    SongBlock
69  {
70    private int indentLevel_;
71    private ListHelper lineList_;
72    private StringID id_;
73    
74    
75    /*package*/ BaseSongBlock(
76      StdSong parent,
77      StringID id,
78      int indentLevel)
79    {
80      super(parent);
81      indentLevel_ = indentLevel;
82      lineList_ = new ListHelper(this);
83      id_ = id;
84    }
85    
86    
87    /*package*/ void handleChordSetDeleted(
88      StdChordSet chordSet,
89      UndoableEditListener undoListener)
90    {
91      for (StdSongLine line = (StdSongLine)lineList_.getNextObject(null);
92        line != null; line = (StdSongLine)lineList_.getNextObject(line))
93      {
94        line.handleChordSetDeleted(chordSet, undoListener);
95      }
96    }
97    
98    
99    /*package*/ void unparse(
100     XMLUnparser unparser)
101   throws
102     IOException
103   {
104     unparser.startMultiLineElement(XMLConstants.BLOCK_ELEMENT);
105     unparser.addAttribute(XMLConstants.BLOCK_ID_ATTRIBUTE, id_.getValue());
106     if (indentLevel_ != 0)
107     {
108       unparser.addAttribute(XMLConstants.BLOCK_INDENT_ATTRIBUTE,
109         Integer.toString(indentLevel_));
110     }
111     unparseVariationAttribute(unparser);
112     for (StdSongLine line = (StdSongLine)lineList_.getNextObject(null);
113       line != null; line = (StdSongLine)lineList_.getNextObject(line))
114     {
115       line.unparse(unparser);
116     }
117     unparser.endElement(XMLConstants.BLOCK_ELEMENT);
118   }
119   
120   
121   /*package*/ abstract void unparseVariationAttribute(
122     XMLUnparser unparser)
123   throws
124     IOException;
125   
126   
127   /*package*/ class ParseHandler
128   extends ParseHandlerBase
129   {
130     private StdSong song_;
131     private NotationFactory notationFactory_;
132     
133     /*package*/ ParseHandler(
134       ErrorHandler errorHandler,
135       Locator locator,
136       StdSong song,
137       NotationFactory notationFactory)
138     {
139       super(errorHandler, locator, XMLConstants.BLOCK_ELEMENT);
140       song_ = song;
141       notationFactory_ = notationFactory;
142     }
143     
144     /*package*/ ParseHandlerBase localStartElement(
145       String uri,
146       String localName,
147       String qName,
148       Attributes attributes)
149     throws
150       SAXException
151     {
152       if (localName.equals(XMLConstants.LINE_ELEMENT))
153       {
154         String indentStr = attributes.getValue(XMLConstants.LINE_INDENT_ATTRIBUTE);
155         int indent = 0;
156         if (indentStr != null)
157         {
158           try
159           {
160             indent = Integer.parseInt(indentStr);
161           }
162           catch (NumberFormatException ex)
163           {
164             reportError(ResourceAccess.Strings.buildString(
165               "xml_MalformedIndent", indentStr));
166           }
167         }
168         StdSongLine line = new StdSongLine(BaseSongBlock.this, indent);
169         lineList_.appendObject(line, null);
170         return line.new ParseHandler(getErrorHandler(), getDocumentLocator(), song_,
171           notationFactory_);
172       }
173       else
174       {
175         return super.localStartElement(uri, localName, qName, attributes);
176       }
177     }
178   }
179   
180   
181   //-------------------------------------------------------------------------
182   // Methods of SongBlock
183   //-------------------------------------------------------------------------
184   
185   /**
186    * Get the indent level
187    *
188    * @return indent level
189    */
190   public int getIndentLevel()
191   {
192     return indentLevel_;
193   }
194   
195   
196   /**
197    * Get the number of lines
198    *
199    * @return number of lines
200    */
201   public int getLineCount()
202   {
203     return lineList_.getCount();
204   }
205   
206   
207   /**
208    * Get the nth line
209    *
210    * @param n index
211    * @return line
212    */
213   public SongLine getNthLine(
214     int n)
215   {
216     return (StdSongLine)lineList_.getNthObject(n);
217   }
218   
219   
220   /**
221    * Get the next line following reference.
222    * If reference is null, returns the first line.
223    * If reference is the last line, returns null;
224    *
225    * @param reference reference SongLine
226    * @return next line
227    * @exception IllegalArgumentException reference is not a member
228    */
229   public SongLine getNextLine(
230     SongLine reference)
231   {
232     return (StdSongLine)lineList_.getNextObject(reference);
233   }
234   
235   
236   /**
237    * Get the previous line preceding reference.
238    * If reference is null, returns the last line.
239    * If reference is the first line, returns null;
240    *
241    * @param reference reference SongLine
242    * @return previous line
243    * @exception IllegalArgumentException reference is not a member
244    */
245   public SongLine getPreviousLine(
246     SongLine reference)
247   {
248     return (StdSongLine)lineList_.getPreviousObject(reference);
249   }
250   
251   
252   /**
253    * Get a string ID that can be used to serialize references to this
254    * SongBlock. The ID is guaranteed to be unique among SongBlocks within
255    * the owning Song, and will remain the same for the same SongBlock across
256    * different executions of the tool. However, two SongBlocks from different
257    * Songs may have the same string ID, and the same string ID may be
258    * shared between SongBlocks, Variations and ChordSets within the same
259    * Song.
260    *
261    * @return a unique serializable String ID for this SongBlock
262    */
263   public String getSerializableID()
264   {
265     return id_.getValue();
266   }
267   
268   
269   /**
270    * Set the indent level
271    *
272    * @param indent new indent level
273    * @param undoListener listener to notify if an undoable edit is generated,
274    *     or null to suppress generation of undoable edits
275    */
276   public void setIndentLevel(
277     final int indent,
278     UndoableEditListener undoListener)
279   {
280     final int oldIndent = indentLevel_;
281     indentLevel_ = indent;
282     if (undoListener != null)
283     {
284       internalReportUndoableEdit(undoListener,
285         new AbstractUndoableEdit()
286         {
287           public void undo()
288           throws CannotUndoException
289           {
290             super.undo();
291             indentLevel_ = oldIndent;
292           }
293           
294           public void redo()
295           throws CannotRedoException
296           {
297             super.redo();
298             indentLevel_ = indent;
299           }
300         });
301     }
302   }
303   
304   
305   /**
306    * Add a line at the given position.
307    *
308    * @param before insert before this line, or at the end if null
309    * @param undoListener listener to notify if an undoable edit is generated,
310    *     or null to suppress generation of undoable edits
311    * @return added SongLine
312    * @exception IllegalArgumentException before is not a member
313    */
314   public SongLine insertLineBefore(
315     SongLine before,
316     UndoableEditListener undoListener)
317   {
318     StdSongLine nline = new StdSongLine(this);
319     lineList_.insertObjectBefore(nline, before, undoListener);
320     return nline;
321   }
322   
323   
324   /**
325    * Add a line at the given position.
326    *
327    * @param after insert after this line, or at the beginning if null
328    * @param undoListener listener to notify if an undoable edit is generated,
329    *     or null to suppress generation of undoable edits
330    * @return added SongLine
331    * @exception IllegalArgumentException after is not a member
332    */
333   public SongLine insertLineAfter(
334     SongLine after,
335     UndoableEditListener undoListener)
336   {
337     StdSongLine nline = new StdSongLine(this);
338     lineList_.insertObjectAfter(nline, after, undoListener);
339     return nline;
340   }
341   
342   
343   /**
344    * Remove the given line.
345    *
346    * @param line line to remove
347    * @param undoListener listener to notify if an undoable edit is generated,
348    *     or null to suppress generation of undoable edits
349    * @exception IllegalArgumentException line is not present
350    * @exception NullPointerException line was null
351    */
352   public void removeLine(
353     SongLine line,
354     UndoableEditListener undoListener)
355   {
356     lineList_.removeObject(line, undoListener);
357   }
358 }