SetupDialog.java
001 /*
002  * This class is part of DocWhatsUp, a bug profiling and -reporting lib.
003  
004  * Copyright (C)
005  
006  * This library is free software; you can redistribute it and/or modify it
007  * under the terms of the GNU General Public License as published by the
008  * Free Software Foundation; either version 2 of the License, or (at your
009  * option) any later version.
010  
011  * This program is distributed in the hope that it will be useful, but
012  * WITHOUT ANY WARRANTY; without even the implied warranty of
013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
014  * Public License for more details.
015  *  
016  * You should have received a copy of the GNU General Public License along
017  * with this program; if not, write to the Free Software Foundation, Inc.,
018  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019  
020  * EXTENSION:
021  * Linking DocWhatsUp statically or dynamically with other modules is making a
022  * combined work based on DocWhatsUp.  Thus, the terms and conditions of the 
023  * GNU General Public License cover the whole combination.
024  *
025  * As a special exception, the copyright holder of DocWhatsUp give you
026  * permission to link DocWhatsUp with independent modules that communicate with
027  * DocWhatsUp solely through the DocWhatsUp.java interface, regardless of the 
028  * license terms of these independent modules, and to copy and distribute the
029  * resulting combined work under terms of your choice, provided that
030  * every copy of the combined work is accompanied by a complete copy of
031  * the source code of DocWhatsUp (the version of DocWhatsUp used to produce the
032  * combined work), being distributed under the terms of the GNU General
033  * Public License plus this exception.  An independent module is a module
034  * which is not derived from or based on DocWhatsUp.
035 
036  * Note that people who make modified versions of DocWhatsUp are not obligated
037  * to grant this special exception for their modified versions; it is
038  * their choice whether to do so.  The GNU General Public License gives
039  * permission to release a modified version without this exception; this
040  * exception also makes it possible to release a modified version which
041  * carries forward this exception.
042  
043  * Author: Philipp Bartsch; codeshaker@gmx.net
044  */
045 
046 package org.shaker.dwu;
047 
048 import java.awt.BorderLayout;
049 import java.awt.Dialog;
050 import java.awt.Frame;
051 import java.awt.GridLayout;
052 import java.awt.event.ActionEvent;
053 import java.awt.event.ActionListener;
054 import java.awt.event.FocusEvent;
055 import java.awt.event.FocusListener;
056 
057 import javax.swing.Box;
058 import javax.swing.BoxLayout;
059 import javax.swing.JButton;
060 import javax.swing.JComponent;
061 import javax.swing.JDialog;
062 import javax.swing.JLabel;
063 import javax.swing.JPanel;
064 import javax.swing.JTextField;
065 import javax.swing.border.SoftBevelBorder;
066 
067 
068 /**
069  * This class visually helps the user with the mail setup process.
070  * It contains different steps that ask for aspects of the configuration.
071  
072  @author <A HREF="mailto:codeshaker@gmx.net">
073  *            Philipp Bartsch (codeshaker@gmx.net)</A>
074  *            <A HREF="../../../../gpl.txt">GPL License</A>
075  */
076 final class      SetupDialog
077       extends      JDialog
078       implements ActionListener,
079                  FocusListener  {
080 
081     /**ActionCommand: Disposes the wizard*/
082     private static  final     String      CMD_DISPOSE            = "CMD_DISPOSE";
083     /**ActionCommand: apply settings*/
084     private static  final     String      CMD_FINISH              = "CMD_FINISH";
085     /**ActionCommand: import settings*/
086     private static  final     String      CMD_IMPORT              = "CMD_IMPORT";
087     /**ActionCommand: next step*/
088     private static  final     String      CMD_NEXT_STEP        = "CMD_NEXT_STEP";
089     /**ActionCommand: previous step*/
090     private static  final     String      CMD_PREV_STEP       = "CMD_PREV_STEP";
091     /**Index of the server data step*/
092     private static  final     int          SERVER_STEP         = 3;
093     /**Index of the user data step*/
094     private static  final     int          USER_DATA_STEP         = 2;
095 
096     /**Index of the welcome step*/
097     private static  final     int          WELCOME_STEP         = 1;
098     /**The controlbar*/
099     private final JPanel controlContainer = new JPanel(new BorderLayout(00));
100     
101     /**Keeps the current step in mind*/
102     private       int      currentStep = 1;    
103     /**Next step button*/
104     private final JButton nextButton = GUIFactory.button("next_btn",
105                                                          this,
106                                                          CMD_NEXT_STEP,
107                                                          "next.png");
108     /**POP-Server textfield*/
109     private final JTextField popField = GUIFactory.textField ("",
110                                                               this);
111     /**POP-Server port textfield*/
112     private final JTextField popPortField = GUIFactory.textField ("110",
113                                                                   this);
114     /**Previous step button*/    
115     private final JButton prevButton = GUIFactory.button("previous_btn",                                                            
116                                                          this,                                                         
117                                                          CMD_PREV_STEP,
118                                                          "previous.png");
119     /**Container for the server settings step*/
120     private final JPanel serverPanel = new JPanel(new GridLayout(20));
121     /**SMTP-Server textfield*/                                                             
122     private final JTextField smtpField = GUIFactory.textField("mailserver.com",
123                                                                this);
124     /**SMTP-Server port textfield*/
125     private final JTextField smtpPortField = GUIFactory.textField ("25",
126                                                                    this);
127 
128     /**The statusbar*/
129     private final JLabel statusLabel = new JLabel(" ");
130     /**Container for the single steps*/
131     private final JPanel stepContainer = new JPanel(new BorderLayout(00));
132     /**Container for the user settings step*/
133     private final JPanel userDataPanel = new JPanel();
134     /**User`s mail address textfield*/
135     private final JTextField userMailField = GUIFactory.textField ("",
136                                                                    this);
137     /**Mail account textfield*/
138     private final JTextField userNameField = GUIFactory.textField ("",
139                                                                    this);
140 
141     /**Container for the welcome step*/
142     private final JPanel welcomePanel = new JPanel();
143     
144     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
145     //  INIT BLOCK
146     
147     /**
148      * Creates an ready-to-use instance of the SetupWizard.
149      
150      @param parent parental Dialog
151      @see java.awt.Dialog#Dialog(Dialog)
152      */
153     public SetupDialog (final Dialog parent) {
154         super(parent,
155               ToolBox.localize("wiz_title"));
156         setContentPane(new JPanel(new BorderLayout(00)));
157         
158         // init several components
159         initWidgets();
160         initStepContainer();
161         initWelcomeStep();
162         initUserDataStep();
163         initServerStep();
164         initControlContainer();
165                 
166         ToolBox.setSmartSize(this,
167                              490,
168                              350);
169         setModal(true);                                         
170     }
171 
172     /**
173      * Creates an ready-to-use instance of the SetupWizard. 
174      
175      @param parent parental Frame
176      @see java.awt.Window#Window(Frame)
177      */
178     public SetupDialog (final Frame parent) {
179         super(parent,
180               ToolBox.localize("wiz_title"));
181         setContentPane(new JPanel(new BorderLayout(00)));
182         
183         // init several components
184         initWidgets();
185         initStepContainer();
186         initWelcomeStep();
187         initUserDataStep();
188         initServerStep();
189         initControlContainer();
190                 
191         ToolBox.setSmartSize(this,
192                              500,
193                              370);
194         setModal(true);                                         
195     }
196 
197     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
198     //  PUBLIC BLOCK
199     
200     /**
201      * This method handles occuring events, like button usage etc.
202      *
203      @param ae    an ActionEvent
204      */
205     public void actionPerformed (final ActionEvent ae) {
206 
207         if (ae.getActionCommand().equals(CMD_DISPOSE)) {
208             dispose();
209         else if (ae.getActionCommand().equals(CMD_NEXT_STEP)) {
210             performNextStep();
211         else if (ae.getActionCommand().equals(CMD_PREV_STEP)) {
212             performPreviousStep();
213         else if (ae.getActionCommand().equals(CMD_FINISH)) {
214             if (checkStep(SERVER_STEP)) {
215                 DocWhatsUp.SETTINGS.setProperty(Settings.POP,            
216                                                 popField.getText());
217                 DocWhatsUp.SETTINGS.setProperty(Settings.POP_PORT,          
218                                                 popPortField.getText());
219                 DocWhatsUp.SETTINGS.setProperty(Settings.SMTP,
220                                                 smtpField.getText());
221                 DocWhatsUp.SETTINGS.setProperty(Settings.SMTP_PORT,
222                                                 smtpPortField.getText());                                                
223                 DocWhatsUp.SETTINGS.applyChanges();
224                 dispose();
225             }                        
226         else if (ae.getActionCommand().equals(CMD_IMPORT)) {
227             importSettings();
228         }
229     }
230     
231     /**
232      * Checks wheter the current step has all needed informations.
233      * Example: Userdata-step requests at least a valid mail address to switch
234      * to the following step.
235      
236      @param step        the current step
237      @return boolean    "valid" flag
238      */
239     private boolean checkStep (final int step) {
240         switch(step) {
241             case USER_DATA_STEP     :
242                 if (MailEngine.validateMail(userMailField.getText()))
243                     return true;
244                 else {
245                     resetStatusLabel("error_mail");
246                     return false;
247                 }
248             case SERVER_STEP        :
249                 
250                 if (!MailEngine.validateServer(smtpField
251                                                .getText())) {
252                     resetStatusLabel("error_smtp");
253                     return false;
254                 }
255                 if (popField.getText().length() 0
256                     && !MailEngine.validateServer(popField.getText())) {
257                     resetStatusLabel("error_pop");
258                     return false;
259                 }
260                 if (!MailEngine.validatePort(smtpPortField.getText())){
261                     resetStatusLabel("error_smtp_port");
262                     return false;
263                 }
264                 if (!MailEngine.validatePort(popPortField.getText())){
265                     resetStatusLabel("error_pop_port");
266                     return false;
267                 }
268                 return true;            
269             default                 :
270                 return true;
271         }
272 
273     }
274     /**
275      * Unused
276      *
277      @param fe the event object
278      @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
279      */
280     public void focusGained(final FocusEvent fe) {
281 
282     }
283     /**
284      * Applies entries, when textfields lose focus.
285      *
286      @param fe the event object
287      @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
288      */
289     public void focusLost(final FocusEvent fe) {
290         final JComponent source = (JComponentfe.getSource();
291 
292         if (source.equals(popField)) {
293             DocWhatsUp.SETTINGS.setProperty(Settings.POP,            
294                                                popField.getText())
295         else if (source.equals(popPortField)) {        
296             DocWhatsUp.SETTINGS.setProperty(Settings.POP_PORT,          
297                                                popPortField.getText())
298         else if (source.equals(userNameField)) {
299             DocWhatsUp.SETTINGS.setProperty(Settings.USER,
300                                               userNameField.getText());
301         else if (source.equals(userMailField)) {
302             DocWhatsUp.SETTINGS.setProperty(Settings.FROM,
303                                                userMailField.getText());
304         else if (source.equals(smtpField)) {
305             DocWhatsUp.SETTINGS.setProperty(Settings.SMTP,
306                                                smtpField.getText());
307         else if (source.equals(smtpPortField)) {
308             DocWhatsUp.SETTINGS.setProperty(Settings.SMTP_PORT,
309                                                smtpPortField.getText());
310         
311     }
312     
313     /**
314      * Calls the ImportEngine.
315      @see org.shaker.dwu.ImportEngine for a closer view
316      */
317     private void importSettings () {
318         if (ImportEngine.importSettings(this)) {
319             resetStatusLabel("import_ok_help");     
320         
321             Settings SETTINGS = DocWhatsUp.SETTINGS;
322                     
323             smtpField.setText(SETTINGS.getSMTPServer());
324             smtpPortField.setText(SETTINGS.getSMTPPort() "");                                    
325             popField.setText(SETTINGS.getPOPServer());
326             popPortField.setText(SETTINGS.getPOPPort() "");
327             userNameField.setText(SETTINGS.getUser());
328             userMailField.setText(SETTINGS.getSender().toString());
329         }
330     }
331     
332     /**
333      * Inits the button control panel. Contains a previous, next and cancel
334      * button.
335      
336      @return JPanel the button panel
337      */
338     private JPanel initButtonPanel () {
339         final JPanel master = new JPanel (new BorderLayout(00));
340 
341         final JPanel left = new JPanel (new BorderLayout(00));
342         final JPanel right = new JPanel (new BorderLayout(00));
343 
344         right.add(prevButton, BorderLayout.WEST);
345         right.add(nextButton, BorderLayout.EAST);
346 
347         left.add(GUIFactory.button("cancel_btn",
348                                    this,
349                                    CMD_DISPOSE,
350                                    "cancel.png")
351                  BorderLayout.WEST);
352 
353         master.add(left, BorderLayout.WEST);
354         master.add(right, BorderLayout.EAST);
355 
356         return master;
357     }
358 
359     /**
360      * Inits the lower pane, thats hold the buttonpane and the statuspane.
361      */
362     private void initControlContainer () {
363         controlContainer.add(initButtonPanel(), BorderLayout.CENTER);
364         controlContainer.add(statusLabel, BorderLayout.SOUTH);
365         getContentPane().add(controlContainer, BorderLayout.SOUTH);
366     }
367     
368     /**
369      * Inits the server panel. Its part of the "complex way". Contains a
370      * smtpserver textfield and a popserver textfield.
371      */
372     private void initServerStep () {
373 
374         final JPanel smtpPanel      = new JPanel (new BorderLayout(00));
375         final JPanel popPanel        = new JPanel (new BorderLayout(00));
376         final JPanel smtpSubPanel = new JPanel (new BorderLayout(33));
377         final JPanel popSubPanel  = new JPanel (new BorderLayout(33));
378     
379         smtpPanel.setBorder(GUIFactory.titledEBorder("brd_smtp"));
380 
381         smtpSubPanel.add(smtpField, BorderLayout.CENTER);
382         smtpSubPanel.add(smtpPortField, BorderLayout.EAST);
383 
384         smtpPanel.add(GUIFactory.textArea("smtp_help",
385                                           false,
386                                           true),
387                       BorderLayout.NORTH);
388         smtpPanel.add(Box.createVerticalStrut(5));
389         smtpPanel.add(smtpSubPanel, BorderLayout.SOUTH);
390         serverPanel.add(smtpPanel);
391 
392         popPanel.setBorder(GUIFactory.titledEBorder("brd_pop"));
393 
394         popSubPanel.add(popField, BorderLayout.CENTER);
395         popSubPanel.add(popPortField, BorderLayout.EAST);
396 
397         popPanel.add(GUIFactory.textArea("pop_help",
398                                          false,
399                                          true),
400                      BorderLayout.NORTH);
401         popPanel.add(Box.createVerticalStrut(5));
402         popPanel.add(popSubPanel, BorderLayout.SOUTH);
403         serverPanel.add(popPanel);
404     }
405 
406     /**
407      * Inits the container, that holds the single wizard steps.
408      */
409     private void initStepContainer () {
410         stepContainer.setBorder(new SoftBevelBorder(SoftBevelBorder.RAISED));
411         getContentPane().add(stepContainer, BorderLayout.CENTER);
412     }
413     
414     /**
415      * Inits the userdata panel. Its part of the "complex way". Contains a
416      * mailaddress- and a username textfield.
417      */
418     private void initUserDataStep () {
419 
420         userDataPanel.setLayout(new BoxLayout(userDataPanel, 
421                                               BoxLayout.Y_AXIS));
422 
423         final JPanel userMailPanel = new JPanel (new BorderLayout(00));
424         final JPanel userNamePanel = new JPanel (new BorderLayout(00));
425         
426         userMailPanel.setBorder(GUIFactory.titledEBorder("brd_mailaddr"));
427 
428         userMailPanel.add(GUIFactory.textArea("mailaddr_help",
429                                               false,
430                                               true),
431                           BorderLayout.NORTH);
432         userMailPanel.add(userMailField, BorderLayout.SOUTH);
433         userDataPanel.add(userMailPanel);
434 
435         userNamePanel.setBorder(GUIFactory.titledEBorder("brd_user"));
436 
437         userNamePanel.add(GUIFactory.textArea("acc_name_help",
438                                               false,
439                                               true),
440                           BorderLayout.NORTH);
441         userNamePanel.add(userNameField, BorderLayout.SOUTH);
442         userDataPanel.add(userNamePanel);
443        
444 
445     }
446     
447     /**
448      * Inits the inital welcomepane that describes the following steps.
449      */
450     private void initWelcomeStep () {
451         welcomePanel.setLayout(new BorderLayout(00));        
452         //
453         JPanel panel = new JPanel (new BorderLayout(00));
454         panel.setBorder(GUIFactory.titledEBorder("brd_dwu_intro"));
455         panel.add(GUIFactory.textArea("welcome_intro",
456                                       false,
457                                       true),
458                   BorderLayout.CENTER);
459         welcomePanel.add(panel,
460                          BorderLayout.CENTER);    
461         //                                      
462         panel = new JPanel (new BorderLayout(00));
463         panel.add(GUIFactory.textArea("import_help",
464                                       false,
465                                       true),
466                   BorderLayout.NORTH);
467         panel.add(GUIFactory.button("import_btn"
468                                     this, 
469                                     CMD_IMPORT, 
470                                     "wizard.png"),
471                   BorderLayout.CENTER);
472         panel.setBorder(GUIFactory.titledEBorder("brd_import"));
473         welcomePanel.add(panel,
474                          BorderLayout.SOUTH);        
475         
476         setNewStep(welcomePanel);
477     }
478     
479     /**
480      * Customizes some widgets. If it`s not the first time the wizard gets
481      * started, the single widgets get the custom values.
482      */
483     private void initWidgets () {
484         final Settings SETTINGS = DocWhatsUp.SETTINGS;
485         // is there a dwu properties file?        
486         if (Settings.isConfigurated()) {            
487             
488             // sets the previously given values
489             smtpField.setText(SETTINGS.getSMTPServer());
490             smtpPortField.setText(SETTINGS.getSMTPPort() "");                                    
491             popField.setText(SETTINGS.getPOPServer());
492             popPortField.setText(SETTINGS.getPOPPort() "");
493             userNameField.setText(SETTINGS.getUser());
494             userMailField.setText(SETTINGS.getSender().toString());
495         }
496         
497         prevButton.setEnabled(false);
498         //
499         statusLabel.setFont(GUIFactory.ARIAL_10P);
500         statusLabel.setBorder(GUIFactory.LOW);
501         statusLabel.setIconTextGap(5);
502     }
503 
504     /**
505      * Switches to the next wizard step.
506      */
507     private void performNextStep () {        
508         if (!checkStep(currentStep))
509             return;
510         else
511         resetStatusLabel(null);
512         switch(currentStep) {
513             case WELCOME_STEP        :  
514                 setNewStep(userDataPanel);
515                 currentStep = USER_DATA_STEP;
516                 setTitle(ToolBox.localize("user_data_title"));
517                 prevButton.setEnabled(true);
518                 break;
519             case USER_DATA_STEP     :
520                 setNewStep(serverPanel);
521                 currentStep = SERVER_STEP;
522                 setTitle(ToolBox.localize("server_title"));
523                 prevButton.setEnabled(true);
524                 nextButton.setText(ToolBox.localize("finish_btn"));
525                 nextButton.setToolTipText(ToolBox.localize("finish_btn_tt"));
526                 nextButton.setActionCommand(CMD_FINISH);
527                 nextButton.setFont(GUIFactory.ARIAL_10B);
528                 nextButton.setIcon(GUIFactory.getIcon("close.png"));
529                 break;                  
530         }
531         stepContainer.revalidate();
532         stepContainer.repaint();
533         ((JPanel)getContentPane()).revalidate();
534         getContentPane().repaint();
535     }
536 
537     /**
538      * Switches to the previous wizard step.
539      */
540     private void performPreviousStep () {
541         switch(currentStep) {
542             case USER_DATA_STEP:                
543                 setNewStep(welcomePanel);
544                 currentStep = WELCOME_STEP;
545                 setTitle(ToolBox.localize("wiz_title"));
546                 prevButton.setEnabled(false);
547                 break;
548             case SERVER_STEP:
549                 setNewStep(userDataPanel);
550                 currentStep = USER_DATA_STEP;
551                 setTitle(ToolBox.localize("user_data_title"));
552                 nextButton.setText(ToolBox.localize("next_btn"));
553                 nextButton.setToolTipText(ToolBox.localize("next_btn_tt"));
554                 nextButton.setActionCommand(CMD_NEXT_STEP);
555                 nextButton.setFont(GUIFactory.ARIAL_10P);
556                 nextButton.setIcon(GUIFactory.getIcon("next.png"));
557                 break;            
558         }
559         resetStatusLabel(null);
560         stepContainer.revalidate();
561         stepContainer.repaint();
562         ((JPanel)getContentPane()).revalidate();
563         getContentPane().repaint();
564     }
565 
566     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
567     //  PRIVATE BLOCK
568     
569     /**
570      * Resets the statusbar.
571      
572      @param dictKey the error`s dictionary key
573      */
574     private void resetStatusLabel (final String dictKey) {
575         if (dictKey != null) {
576             if (dictKey.startsWith("error")) {
577                 statusLabel.setForeground(GUIFactory.RED);
578                 statusLabel.setText(ToolBox.localize(dictKey));
579                 statusLabel.setIcon(GUIFactory.getIcon("message.png"));
580             else {
581                 statusLabel.setForeground(GUIFactory.BLUE);
582                 statusLabel.setText(ToolBox.localize(dictKey));
583                 statusLabel.setIcon(GUIFactory.getIcon("message.png"));
584             }                 
585         else {    
586             statusLabel.setText (" ");
587             statusLabel.setIcon(null);
588         }        
589     }
590     
591     /**
592      * Switches the wizard to a new step.
593      *
594      @param step the new step panel that has to be displayed
595      */
596     private void setNewStep (final JPanel step) {
597         stepContainer.removeAll();
598         stepContainer.add(step, BorderLayout.CENTER);
599         stepContainer.repaint();
600         stepContainer.revalidate();
601         getContentPane().repaint();
602         ((JPanel)getContentPane()).revalidate();
603     }
604 }