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.command;
32
33 import java.io.DataInputStream;
34 import java.io.DataOutputStream;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.io.OutputStream;
38 import javax.microedition.lcdui.Alert;
39 import javax.microedition.lcdui.AlertType;
40 import javax.microedition.lcdui.Choice;
41 import javax.microedition.lcdui.ChoiceGroup;
42 import javax.microedition.lcdui.Command;
43 import javax.microedition.lcdui.CommandListener;
44 import javax.microedition.lcdui.Display;
45 import javax.microedition.lcdui.Displayable;
46 import javax.microedition.lcdui.Item;
47 import javax.microedition.lcdui.Spacer;
48 import palmed.edit.ITextBox;
49 import palmed.io.IRecord;
50 import palmed.io.IRecordFactory;
51 import palmed.io.ISerializable;
52 import palmed.ui.Dialog;
53
54 /***
55 * This dialog displays a list of editable user options.
56 *
57 * @author Mathieu Champlon
58 * @version $Revision$ $Date$
59 */
60 public final class PreferencesDialog extends Dialog implements CommandListener, ISerializable
61 {
62 /***
63 * The number of pixels to shift the popup menus.
64 */
65 private static final int POPUP_MENUS_SHIFT = 20;
66 /***
67 * The available values for line separator.
68 */
69 private static final String[] LINE_SEPARATORS =
70 {
71 "auto", "Windows (//r//n)", "Linux (//n)", "MacOS (//r)"
72 };
73 /***
74 * The available fonts.
75 */
76 private static final String[] FONTS =
77 {
78 "ProFontWindows_12", "ProggyCleanTTSZ_16", "Fixedsys TTF V5.00c_15"
79 };
80 /***
81 * The display.
82 */
83 private final Display display_;
84 /***
85 * The displayable to show when closing the dialog.
86 */
87 private final Displayable next_;
88 /***
89 * The text box.
90 */
91 private final ITextBox textBox_;
92 /***
93 * The validaiton commands.
94 */
95 private final Command okCommand_ = new Command( "Ok", Command.OK, 1 );
96 /***
97 * The cancelation command.
98 */
99 private final Command cancelCommand_ = new Command( "Cancel", Command.CANCEL, 1 );
100 /***
101 * The command to revert modified values.
102 */
103 private final Command revertCommand_ = new Command( "Revert", Command.CANCEL, 1 );
104 /***
105 * The separator choice.
106 */
107 private final Choice separator_;
108 /***
109 * The font choice.
110 */
111 private final Choice font_;
112 /***
113 * The record.
114 */
115 private final IRecord record_;
116
117 /***
118 * Create an 'about' dialog.
119 *
120 * @param display the application display
121 * @param next the displayable to show when 'OK' is pressed
122 * @param factory the record factory
123 * @param textBox the text box
124 */
125 public PreferencesDialog( final Display display, final Displayable next, final IRecordFactory factory,
126 final ITextBox textBox )
127 {
128 super( "Preferences" );
129 if( display == null )
130 throw new IllegalArgumentException( "parameter 'display' is null" );
131 if( next == null )
132 throw new IllegalArgumentException( "parameter 'next' is null" );
133 if( textBox == null )
134 throw new IllegalArgumentException( "parameter 'textBox' is null" );
135 display_ = display;
136 next_ = next;
137 textBox_ = textBox;
138 separator_ = appendChoice( "Line Separator", LINE_SEPARATORS );
139 font_ = appendChoice( "Font", FONTS );
140 record_ = factory.getIndex( this );
141 addCommand( okCommand_ );
142 addCommand( cancelCommand_ );
143 addCommand( revertCommand_ );
144 setCommandListener( this );
145 record_.restore();
146 apply();
147 }
148
149 private Choice appendChoice( final String label, final String[] choices )
150 {
151 final Spacer spacer = new Spacer( POPUP_MENUS_SHIFT, 0 );
152 spacer.setLayout( Item.LAYOUT_NEWLINE_BEFORE + Item.LAYOUT_2 );
153 final ChoiceGroup group = new ChoiceGroup( null, Choice.POPUP );
154 group.setLayout( Item.LAYOUT_2 );
155 for( int choice = 0; choice < choices.length; ++choice )
156 group.append( choices[choice], null );
157 appendMessage( label );
158 append( spacer );
159 append( group );
160 return group;
161 }
162
163 /***
164 * {@inheritDoc}
165 */
166 public void commandAction( final Command command, final Displayable displayable )
167 {
168 try
169 {
170 triggered( command );
171 }
172 catch( OutOfMemoryError e )
173 {
174 error( "Out of memory", e.getMessage() );
175 }
176 catch( Throwable e )
177 {
178 error( "Error", e.getMessage() );
179 }
180 }
181
182 private void error( final String title, final String message )
183 {
184 display_.setCurrent( new Alert( title, message, null, AlertType.ERROR ) );
185 }
186
187 private void triggered( final Command command )
188 {
189 if( command == okCommand_ )
190 {
191 apply();
192 record_.persist();
193 display_.setCurrent( next_ );
194 }
195 else if( command == cancelCommand_ )
196 {
197 record_.restore();
198 display_.setCurrent( next_ );
199 }
200 else
201 {
202 record_.restore();
203 }
204 }
205
206 private void apply()
207 {
208 String separator;
209 switch( separator_.getSelectedIndex() )
210 {
211 case 1 :
212 separator = "\r\n";
213 break;
214 case 2 :
215 separator = "\n";
216 break;
217 case 3 :
218 separator = "\r";
219 break;
220 default :
221 separator = null;
222 }
223 textBox_.setLineSeparator( separator );
224 textBox_.setFont( FONTS[font_.getSelectedIndex()] );
225 }
226
227 /***
228 * {@inheritDoc}
229 */
230 public void unmarshall( final InputStream stream ) throws IOException
231 {
232 final DataInputStream input = new DataInputStream( stream );
233 separator_.setSelectedIndex( input.readInt(), true );
234 font_.setSelectedIndex( input.readInt(), true );
235 }
236
237 /***
238 * {@inheritDoc}
239 */
240 public void marshall( final OutputStream stream ) throws IOException
241 {
242 final DataOutputStream output = new DataOutputStream( stream );
243 output.writeInt( separator_.getSelectedIndex() );
244 output.writeInt( font_.getSelectedIndex() );
245 }
246 }