View Javadoc

1   /***
2    * Redistribution  and use  in source  and binary  forms, with  or without
3    * modification, are permitted provided  that the following conditions are
4    * met :
5    *
6    * . Redistributions  of  source  code  must  retain  the  above copyright
7    *   notice, this list of conditions and the following disclaimer.
8    *
9    * . Redistributions in  binary form  must reproduce  the above  copyright
10   *   notice, this list of conditions  and the following disclaimer in  the
11   *   documentation and/or other materials provided with the distribution.
12   *
13   * . The name of the author may not be used to endorse or promote products
14   *   derived from this software without specific prior written permission.
15   *
16   * THIS SOFTWARE IS  PROVIDED BY THE  AUTHOR ``AS IS''  AND ANY EXPRESS  OR
17   * IMPLIED  WARRANTIES,  INCLUDING,  BUT   NOT  LIMITED  TO,  THE   IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE ARE
19   * DISCLAIMED.  IN NO  EVENT SHALL  THE AUTHOR  BE LIABLE  FOR ANY  DIRECT,
20   * INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL  DAMAGES
21   * (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT OF  SUBSTITUTE  GOODS OR
22   * SERVICES;  LOSS  OF USE,  DATA,  OR PROFITS;  OR  BUSINESS INTERRUPTION)
23   * HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN  CONTRACT,
24   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25   * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE, EVEN  IF  ADVISED OF  THE
26   * POSSIBILITY OF SUCH DAMAGE.
27   *
28   * $Id$
29   */
30  
31  package palmed.edit;
32  
33  import java.io.IOException;
34  import java.io.InputStream;
35  import java.io.OutputStream;
36  import palmed.edit.selection.SelectionDeletion;
37  import palmed.edit.selection.Cut;
38  import palmed.edit.selection.CharacterDeletion;
39  import palmed.edit.selection.NewLineInsertion;
40  import palmed.edit.selection.IAction;
41  import palmed.edit.selection.ILineVisitor;
42  import palmed.edit.selection.ISelection;
43  import palmed.edit.selection.ISelectionView;
44  import palmed.edit.selection.Paste;
45  import palmed.edit.selection.Selection;
46  import palmed.edit.selection.CharacterInsertion;
47  import palmed.edit.selection.SelectionReplacement;
48  import palmed.edit.selection.UndoManager;
49  import palmed.edit.text.IText;
50  import palmed.edit.util.Coordinate;
51  import palmed.edit.view.IContent;
52  import palmed.edit.view.IView;
53  
54  /***
55   * This class encapsulates text and selection manipulations.
56   *
57   * @author Mathieu Champlon
58   * @version $Revision$ $Date$
59   */
60  public final class Content implements IContent, ISelectionView
61  {
62      /***
63       * The code of the first valid characters.
64       */
65      private static final int FIRST_VALID_CHARACTER = 32;
66      /***
67       * the code of the last valid character.
68       */
69      private static final int LAST_VALID_CHARACTER = 0xFF;
70      /***
71       * The maximum number of actions to keep for undo.
72       */
73      private static final int UNDO_STACK_SIZE = 10;
74      /***
75       * The text.
76       */
77      private final IText text_;
78      /***
79       * The selection manager.
80       */
81      private final ISelection selection_;
82      /***
83       * The undo manager.
84       */
85      private final UndoManager manager_;
86      /***
87       * The current insertion point.
88       */
89      private Coordinate insertion_;
90  
91      /***
92       * Create a content.
93       *
94       * @param text the text
95       */
96      public Content( final IText text )
97      {
98          if( text == null )
99              throw new IllegalArgumentException( "parameter 'text' is null" );
100         text_ = text;
101         selection_ = new Selection( text );
102         selection_.register( this );
103         manager_ = new UndoManager( UNDO_STACK_SIZE );
104     }
105 
106     /***
107      * {@inheritDoc}
108      */
109     public void type( final int keyCode )
110     {
111         if( isValid( keyCode ) )
112         {
113             if( selection_.isEmpty() )
114                 execute( new CharacterInsertion( selection_, text_, (char)keyCode, insertion_ ) );
115             else
116                 execute( new SelectionReplacement( selection_, text_, (char)keyCode, insertion_ ) );
117         }
118     }
119 
120     private boolean isValid( final int keyCode )
121     {
122         return keyCode >= FIRST_VALID_CHARACTER && keyCode <= LAST_VALID_CHARACTER;
123     }
124 
125     /***
126      * {@inheritDoc}
127      */
128     public void enter()
129     {
130         execute( new NewLineInsertion( selection_, text_, insertion_ ) );
131     }
132 
133     /***
134      * {@inheritDoc}
135      */
136     public void backspace()
137     {
138         if( selection_.isEmpty() )
139             execute( new CharacterDeletion( selection_ ) );
140         else
141             execute( new SelectionDeletion( selection_ ) );
142     }
143 
144     /***
145      * {@inheritDoc}
146      */
147     public void drag( final int x, final int y )
148     {
149         selection_.extend( x, y );
150         manager_.skip();
151     }
152 
153     /***
154      * {@inheritDoc}
155      */
156     public void click( final int x, final int y )
157     {
158         selection_.extend( x, y );
159         selection_.clear();
160         manager_.skip();
161     }
162 
163     /***
164      * {@inheritDoc}
165      */
166     public void accept( final ILineVisitor visitor, final int y )
167     {
168         selection_.accept( visitor, y );
169     }
170 
171     /***
172      * {@inheritDoc}
173      */
174     public void register( final IView view )
175     {
176         text_.register( view );
177         selection_.register( view );
178     }
179 
180     /***
181      * {@inheritDoc}
182      */
183     public void marshall( final OutputStream stream ) throws IOException
184     {
185         selection_.marshall( stream );
186         text_.marshall( stream );
187         manager_.marshall( stream );
188     }
189 
190     /***
191      * {@inheritDoc}
192      */
193     public void unmarshall( final InputStream stream ) throws IOException
194     {
195         selection_.unmarshall( stream );
196         text_.unmarshall( stream );
197         manager_.unmarshall( stream );
198     }
199 
200     /***
201      * {@inheritDoc}
202      */
203     public void clear()
204     {
205         selection_.reset();
206         text_.clear();
207         manager_.clear();
208     }
209 
210     /***
211      * {@inheritDoc}
212      */
213     public void update( final Coordinate position )
214     {
215         insertion_ = position;
216     }
217 
218     /***
219      * {@inheritDoc}
220      */
221     public void copy( final OutputStream stream ) throws IOException
222     {
223         selection_.copy( stream );
224     }
225 
226     /***
227      * {@inheritDoc}
228      */
229     public void cut( final OutputStream stream )
230     {
231         if( !selection_.isEmpty() )
232             execute( new Cut( selection_, stream ) );
233     }
234 
235     /***
236      * {@inheritDoc}
237      */
238     public void paste( final InputStream stream )
239     {
240         execute( new Paste( selection_, stream ) );
241     }
242 
243     private void execute( final IAction action )
244     {
245         action.perform();
246         manager_.add( action );
247     }
248 
249     /***
250      * {@inheritDoc}
251      */
252     public void undo()
253     {
254         manager_.undo();
255     }
256 
257     /***
258      * {@inheritDoc}
259      */
260     public void redo()
261     {
262         manager_.redo();
263     }
264 }