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.text;
32
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.OutputStream;
36 import palmed.edit.util.Coordinate;
37
38 /***
39 * This class implements a text chunk.
40 *
41 * @author Mathieu Champlon
42 * @version $Revision$ $Date$
43 */
44 final class Chunk implements ITextView, ICachable, IChunk
45 {
46 /***
47 * The underlying text.
48 */
49 private IText text_;
50 /***
51 * The current number of columns and lines of the text.
52 */
53 private int columns_, lines_;
54 /***
55 * First and last line length for caching purpose.
56 */
57 private int firstLineLength_, lastLineLength_;
58 /***
59 * The modification flag.
60 */
61 private boolean hasBeenModified_;
62 /***
63 * The cache.
64 */
65 private final ICache cache_;
66
67 /***
68 * Create a text chunk.
69 *
70 * @param cache the cache
71 */
72 public Chunk( final ICache cache )
73 {
74 if( cache == null )
75 throw new IllegalArgumentException( "parameter 'cache' is null" );
76 cache_ = cache;
77 text_ = new Text();
78 text_.register( this );
79 }
80
81 private IText getText()
82 {
83 if( text_ == null )
84 {
85 text_ = new Text();
86 cache_.wake( this );
87 text_.register( this );
88 }
89 return text_;
90 }
91
92 /***
93 * {@inheritDoc}
94 */
95 public void sleep()
96 {
97 text_ = null;
98 }
99
100 /***
101 * {@inheritDoc}
102 */
103 public int getHeight()
104 {
105 return lines_;
106 }
107
108 /***
109 * {@inheritDoc}
110 */
111 public void update( final int columns, final int lines )
112 {
113 columns_ = columns;
114 lines_ = lines - 1;
115 firstLineLength_ = getText().getLine( 0 ).length();
116 lastLineLength_ = getText().getLine( lines_ ).length();
117 }
118
119 /***
120 * {@inheritDoc}
121 */
122 public void modified( final boolean status )
123 {
124 hasBeenModified_ = status;
125 }
126
127 /***
128 * {@inheritDoc}
129 */
130 public boolean hasBeenModified()
131 {
132 return hasBeenModified_;
133 }
134
135 /***
136 * {@inheritDoc}
137 */
138 public int handle( final ILineExtractor functor, final int line )
139 {
140 final int lines = lines_;
141 if( line <= lines )
142 functor.select( getText(), line );
143 return lines;
144 }
145
146 /***
147 * {@inheritDoc}
148 */
149 public Coordinate handle( final ITextExtractor functor, final Coordinate start, final Coordinate from,
150 final Coordinate to )
151 {
152 final int lines = lines_;
153 if( from.y_ - start.y_ <= lines )
154 {
155 final int length = lastLineLength_;
156 final Coordinate translatedFrom = translate( from, start );
157 final Coordinate translatedTo = translate( to, start );
158 if( !translatedTo.equals( translatedFrom ) )
159 functor.select( getText(), translatedFrom, translatedTo );
160 if( from.y_ - start.y_ == 0 )
161 return new Coordinate( start.x_ + length, start.y_ + lines );
162 return new Coordinate( length, start.y_ + lines );
163 }
164 return new Coordinate( start.x_, start.y_ + lines );
165 }
166
167 private Coordinate translate( final Coordinate coordinate, final Coordinate start )
168 {
169 if( coordinate.y_ < start.y_ )
170 return new Coordinate( 0, 0 );
171 if( coordinate.y_ > start.y_ + lines_ )
172 return new Coordinate( lastLineLength_, lines_ );
173 final int y = coordinate.y_ - start.y_;
174 if( coordinate.x_ <= start.x_ )
175 return new Coordinate( 0, y );
176 final int x = getText().getLine( y ).length();
177 if( coordinate.x_ >= start.x_ + x )
178 return new Coordinate( x, y );
179 return new Coordinate( coordinate.x_ - start.x_, y );
180 }
181
182 /***
183 * {@inheritDoc}
184 */
185 public int count( final Coordinate size, final int previous )
186 {
187 final int length = previous + firstLineLength_;
188 size.x_ = Math.max( size.x_, Math.max( length, columns_ ) );
189 size.y_ += lines_;
190 if( lines_ > 0 )
191 return lastLineLength_;
192 return length;
193 }
194
195 /***
196 * {@inheritDoc}
197 */
198 public void marshall( final OutputStream stream ) throws IOException
199 {
200 getText().marshall( stream );
201 }
202
203 /***
204 * {@inheritDoc}
205 */
206 public void unmarshall( final InputStream stream ) throws IOException
207 {
208 getText().unmarshall( stream );
209 }
210
211 /***
212 * {@inheritDoc}
213 */
214 public void read( final InputStream stream ) throws IOException
215 {
216 getText().read( stream );
217 }
218
219 /***
220 * {@inheritDoc}
221 */
222 public void write( final OutputStream stream ) throws IOException
223 {
224 getText().write( stream );
225 }
226 }