1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.jhylafax;
21
22 import static net.sf.jhylafax.JHylaFAX.i18n;
23 import java.awt.event.ActionEvent;
24 import javax.swing.Action;
25 import javax.swing.Icon;
26 import javax.swing.JComponent;
27 import javax.swing.JFrame;
28 import javax.swing.JLabel;
29 import javax.swing.JPasswordField;
30 import javax.swing.JSpinner;
31 import javax.swing.JTextField;
32 import javax.swing.SpinnerNumberModel;
33 import org.xnap.commons.gui.Builder;
34 import org.xnap.commons.gui.action.AbstractXNapAction;
35 import org.xnap.commons.gui.util.GUIHelper;
36 import org.xnap.commons.gui.util.IconHelper;
37 import org.xnap.commons.gui.wizard.WizardDialog;
38 import org.xnap.commons.gui.wizard.WizardPage;
39 import org.xnap.commons.util.PortRange;
40 import org.xnap.commons.util.SystemHelper;
41 import com.jgoodies.forms.builder.DefaultFormBuilder;
42 import com.jgoodies.forms.layout.FormLayout;
43
44
45
46
47
48
49 public class SettingsWizard extends WizardDialog implements LocaleChangeListener {
50
51 private static final int WIDTH = 500;
52
53 private GeneralPage generalPage;
54 private NotifyPage notifyPage;
55 private ProgramsPage programsPage;
56 private IntroductionPage introPage;
57
58 public SettingsWizard(JFrame owner) {
59 super(owner);
60
61 introPage = new IntroductionPage();
62 addPage(introPage, "intro");
63
64 generalPage = new GeneralPage();
65 addPage(generalPage, "general");
66
67 notifyPage = new NotifyPage();
68 addPage(notifyPage, "notify");
69
70 programsPage = new ProgramsPage();
71 addPage(programsPage, "programs");
72
73 updateLabels();
74 revert();
75
76 pack();
77 }
78
79 private DefaultFormBuilder createForm() {
80 FormLayout layout = new FormLayout("left:max(20dlu;pref), 3dlu, pref, pref:grow(0.5), pref:grow(0.5)", "");
81 DefaultFormBuilder builder = new DefaultFormBuilder(layout);
82 builder.setDefaultDialogBorder();
83 return builder;
84 }
85
86 public void revert() {
87 generalPage.revert();
88 notifyPage.revert();
89 programsPage.revert();
90 }
91
92 public void updateLabels()
93 {
94 setTitle(i18n.tr("JHylaFAX Setup Wizard"));
95
96 introPage.updateLabels();
97 generalPage.updateLabels();
98 notifyPage.updateLabels();
99 programsPage.updateLabels();
100 }
101
102 private class IntroductionPage implements WizardPage {
103
104 private DefaultFormBuilder builder;
105 private JLabel introLabel;
106
107 public IntroductionPage() {
108 builder = createForm();
109
110 introLabel = builder.append("");
111 builder.nextLine();
112 }
113
114 public boolean apply() {
115 if (!Settings.HAS_SEEN_WIZARD.getValue()) {
116 JHylaFAX.getInstance().resetAllTables();
117 Settings.HAS_SEEN_WIZARD.setValue(true);
118 }
119 return true;
120 }
121
122 public String getDescription() {
123 return i18n.tr("Easily setup JHylaFAX in 3 steps.");
124 }
125
126 public Icon getIcon() {
127 return null;
128 }
129
130 public JComponent getPanel() {
131 return builder.getPanel();
132 }
133
134 public String getTitle() {
135 return i18n.tr("JHylaFAX Setup Wizard");
136 }
137
138 public void updateLabels() {
139 introLabel.setText(GUIHelper.tt(i18n.tr(
140 "JHylaFAX is a Java client for the HylaFAX fax server. " +
141 "It is licensed under the " +
142 "<b>General Public License (GPL)</b>, see about for details." +
143 "<p>" +
144 "<p>Setup requires three simple steps:" +
145 "<ol>" +
146 "<li>Server connection and authentication" +
147 "<li>Sender and notifcation" +
148 "<li>External viewer programs" +
149 "</ol>" +
150 "<p>Thank you for using JHylaFAX. "), WIDTH));
151 }
152
153 }
154
155 private class GeneralPage implements WizardPage {
156
157 private DefaultFormBuilder builder;
158 private JLabel hostnameLabel;
159 private JTextField hostnameTextField;
160 private JLabel passwordLabel;
161 private JPasswordField passwordTextField;
162 private JLabel portLabel;
163 private JSpinner portSpinner;
164 private SpinnerNumberModel portSpinnerModel;
165 private JLabel usernameLabel;
166 private JTextField usernameTextField;
167 private JLabel hostnameDescriptionLabel;
168 private JLabel usernameDescriptionLabel;
169
170 public GeneralPage() {
171 builder = createForm();
172
173 hostnameDescriptionLabel = new JLabel();
174 builder.append(hostnameDescriptionLabel, 5);
175 builder.nextLine();
176
177 hostnameTextField = new JTextField(Constants.DEFAULT_COLUMNS);
178 hostnameLabel = builder.append("", hostnameTextField, 3);
179 builder.nextLine();
180
181 portSpinnerModel = new SpinnerNumberModel();
182 portSpinnerModel.setMinimum(PortRange.MIN_PORT);
183 portSpinnerModel.setMaximum(PortRange.MAX_PORT);
184 portSpinner = new JSpinner(portSpinnerModel);
185 portSpinner.setEditor(new JSpinner.NumberEditor(portSpinner, "#"));
186 portLabel = builder.append("", portSpinner);
187 builder.nextLine();
188
189 usernameDescriptionLabel = new JLabel();
190 builder.append(usernameDescriptionLabel, 5);
191 builder.nextLine();
192
193 usernameTextField = new JTextField(Constants.DEFAULT_COLUMNS);
194 usernameLabel = builder.append("", usernameTextField, 3);
195 builder.nextLine();
196 }
197
198 public boolean apply() {
199 Settings.HOSTNAME.setValue(hostnameTextField.getText());
200 Settings.PORT.setValue(portSpinnerModel.getNumber().intValue());
201 Settings.USERNAME.setValue(usernameTextField.getText());
202 return true;
203 }
204
205 public String getDescription() {
206 return i18n.tr("The connection to the fax server is configured here.");
207 }
208
209 public Icon getIcon() {
210 return IconHelper.getTitleIcon("connect_established.png");
211 }
212
213 public JComponent getPanel() {
214 return builder.getPanel();
215 }
216
217 public String getTitle() {
218 return i18n.tr("HylaFAX Server Connection");
219 }
220
221 public void revert() {
222 hostnameTextField.setText(Settings.HOSTNAME.getValue());
223 portSpinnerModel.setValue(Settings.PORT.getValue());
224 usernameTextField.setText(Settings.USERNAME.getValue());
225 }
226
227 public void updateLabels() {
228 hostnameDescriptionLabel.setText(GUIHelper.tt(i18n.tr("Enter the host and port of your HylaFAX server:"), WIDTH));
229 hostnameLabel.setText(i18n.tr("Host"));
230 portLabel.setText(i18n.tr("Port"));
231
232 usernameDescriptionLabel.setText(GUIHelper.tt(i18n.tr("Enter a username that is used to login to the server:"), WIDTH));
233 usernameLabel.setText(i18n.tr("Username"));
234 }
235 }
236
237 private class NotifyPage implements WizardPage {
238
239 private JTextField fullnameTextField;
240 private DefaultFormBuilder builder;
241 private JTextField emailTextField;
242 private JLabel emailLabel;
243 private JLabel fullnameLabel;
244 private JLabel fullnameDescriptionLabel;
245 private JLabel emailDescriptionLabel;
246
247 public NotifyPage() {
248 builder = createForm();
249
250 fullnameDescriptionLabel = new JLabel();
251 builder.append(fullnameDescriptionLabel, 5);
252 builder.nextLine();
253
254 fullnameTextField = new JTextField(Constants.DEFAULT_COLUMNS);
255 fullnameLabel = builder.append("", fullnameTextField, 3);
256 builder.nextLine();
257
258 emailDescriptionLabel = new JLabel();
259 builder.append(emailDescriptionLabel, 5);
260 builder.nextLine();
261
262 emailTextField = new JTextField(Constants.DEFAULT_COLUMNS);
263 emailLabel = builder.append("", emailTextField, 3);
264 builder.nextLine();
265
266 }
267
268 public void updateLabels() {
269 fullnameDescriptionLabel.setText(GUIHelper.tt(i18n.tr("Enter a name that is used to identify the sender:"), WIDTH));
270 fullnameLabel.setText(i18n.tr("Name"));
271 emailDescriptionLabel.setText(GUIHelper.tt(i18n.tr("Enter an email address to receive notification when a fax has been sent or cancelled:"), WIDTH));
272 emailLabel.setText(i18n.tr("Email"));
273 }
274
275 public boolean apply() {
276 Settings.FULLNAME.setValue(fullnameTextField.getText());
277 Settings.EMAIL.setValue(emailTextField.getText());
278 return true;
279 }
280
281 public String getDescription() {
282 return i18n.tr("The sender's name and an email address for notifications are configured here.");
283 }
284
285 public Icon getIcon() {
286 return IconHelper.getTitleIcon("kontact_mail.png");
287 }
288
289 public JComponent getPanel() {
290 return builder.getPanel();
291 }
292
293 public String getTitle() {
294 return i18n.tr("Sender and Notification");
295 }
296
297 public void revert() {
298 fullnameTextField.setText(Settings.FULLNAME.getValue());
299 emailTextField.setText(Settings.EMAIL.getValue());
300 }
301
302 }
303
304 private class ProgramsPage implements WizardPage {
305
306 private DefaultFormBuilder builder;
307 private ExecutableChooserPanel viewerPathFileChooserPanel;
308 private JLabel viewerPathLabel;
309 private ExecutableChooserPanel docViewerPathFileChooserPanel;
310 private JLabel docViewerPathLabel;
311 private String docViewer;
312 private String viewer;
313 private SearchProgramsAction searchProgramsAction;
314 private JLabel viewerDescriptionLabel;
315 private JLabel searchDescriptionLabel;
316 private JLabel docViewerDescriptionLabel;
317 private JLabel descriptionLabel;
318
319 public ProgramsPage() {
320 builder = createForm();
321
322 descriptionLabel = new JLabel();
323 builder.append(descriptionLabel, 5);
324 builder.nextLine();
325
326 viewerDescriptionLabel = new JLabel();
327 builder.append(viewerDescriptionLabel, 5);
328 builder.nextLine();
329
330 viewerPathFileChooserPanel = new ExecutableChooserPanel(Constants.DEFAULT_COLUMNS);
331 viewerPathFileChooserPanel.setDialogParent(SettingsWizard.this);
332 viewerPathLabel = builder.append("", viewerPathFileChooserPanel, 3);
333 builder.nextLine();
334
335 docViewerDescriptionLabel = new JLabel();
336 builder.append(docViewerDescriptionLabel, 5);
337 builder.nextLine();
338
339 docViewerPathFileChooserPanel = new ExecutableChooserPanel(Constants.DEFAULT_COLUMNS);
340 docViewerPathFileChooserPanel.setDialogParent(SettingsWizard.this);
341 docViewerPathLabel = builder.append("", docViewerPathFileChooserPanel, 3);
342 builder.nextLine();
343
344 searchDescriptionLabel = new JLabel();
345 builder.append(searchDescriptionLabel, 5);
346 builder.nextLine();
347
348 builder.append("");
349 builder.nextLine();
350
351 searchProgramsAction = new SearchProgramsAction();
352 builder.append(Builder.createButton(searchProgramsAction));
353 builder.nextLine();
354 }
355
356 public void revert() {
357 searchForPrograms();
358
359 if (!"".equals(Settings.VIEWER_PATH.getValue())) {
360 viewerPathFileChooserPanel.getTextField().setText(Settings.VIEWER_PATH.getValue());
361 }
362 else {
363 viewerPathFileChooserPanel.getTextField().setText(viewer);
364 }
365
366 if (!"".equals(Settings.DOC_VIEWER_PATH.getValue())) {
367 docViewerPathFileChooserPanel.getTextField().setText(Settings.DOC_VIEWER_PATH.getValue());
368 }
369 else {
370 docViewerPathFileChooserPanel.getTextField().setText(docViewer);
371 }
372 }
373
374 private void searchForPrograms() {
375 if (SystemHelper.IS_WINDOWS) {
376 if (SystemHelper.IS_WINDOWS_XP) {
377 viewer= "rundll32.exe shimgvw.dll,ImageView_Fullscreen $f";
378 }
379 else {
380 String path = System.getenv("ProgramFiles");
381 viewer = searchExecutable(new String[][] {
382 { path + "\\Windows NT\\Accessories\\ImageVue", "kodakimg.exe", "$f" },
383 });
384 }
385 docViewer = searchExecutable(new String[][] {
386 { null, "gsview32.exe", "$f" },
387 });
388
389 }
390 else if (SystemHelper.IS_MACOSX) {
391 viewer = "open -a Preview.app $f";
392 docViewer = "open -a Preview.app $f";
393 }
394 else {
395 viewer = searchExecutable(new String[][] {
396 { "/usr/bin", "kfax", "$f" },
397 });
398 docViewer = searchExecutable(new String[][] {
399 { "/usr/bin", "gv", "$f" },
400 { "/usr/bin", "kghostview", "$f" },
401 });
402 }
403 }
404
405 private String searchExecutable(String[][] programs) {
406 return programs[0][1] + " " + programs[0][2];
407
408
409
410
411
412
413
414
415 }
416
417 public void updateLabels() {
418 descriptionLabel.setText(GUIHelper.tt(i18n.tr("JHylaFAX depends on external programs to display received and sent faxes. " +
419 "You can either enter the path of a program or use Search to let JHylaFAX suggest a program." +
420 "You may use $f as a placeholder for the filename that is passed as a parameter."), WIDTH));
421
422 viewerDescriptionLabel.setText(GUIHelper.tt(i18n.tr("Enter the path of a programm that can handle TIFF G3 files:"), WIDTH));
423 viewerPathLabel.setText(i18n.tr("Fax Viewer"));
424 docViewerDescriptionLabel.setText(GUIHelper.tt(i18n.tr("Enter the path of a programm that can handle PostScript files:"), WIDTH));
425 docViewerPathLabel.setText(i18n.tr("Document Viewer"));
426 searchProgramsAction.putValue(Action.NAME, i18n.tr("Search"));
427 }
428
429 public boolean apply()
430 {
431 Settings.VIEWER_PATH.setValue(viewerPathFileChooserPanel.getTextField().getText());
432 Settings.DOC_VIEWER_PATH.setValue(docViewerPathFileChooserPanel.getTextField().getText());
433
434 return true;
435 }
436
437 public String getDescription() {
438 return i18n.tr("Viewer programs are configured here.");
439 }
440
441 public Icon getIcon() {
442 return IconHelper.getTitleIcon("misc.png");
443 }
444
445 public JComponent getPanel() {
446 return builder.getPanel();
447 }
448
449 public String getTitle() {
450 return i18n.tr("External Programs");
451 }
452
453 private class SearchProgramsAction extends AbstractXNapAction {
454
455 public SearchProgramsAction() {
456 putValue(ICON_FILENAME, "find.png");
457 }
458
459 public void actionPerformed(ActionEvent e)
460 {
461 searchForPrograms();
462 viewerPathFileChooserPanel.getTextField().setText(viewer);
463 docViewerPathFileChooserPanel.getTextField().setText(docViewer);
464 }
465
466 }
467
468 }
469
470
471 }