Logo Search packages:      
Sourcecode: cacao-oj6 version File versions

NewReportDialog.java

/*
 * $Id$
 *
 * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package com.sun.javatest.exec;

import com.sun.javatest.InterviewParameters;
import com.sun.javatest.TestFilter;
import com.sun.javatest.report.CustomReport.ReportConfigPanel;
import com.sun.javatest.report.CustomReport;
import com.sun.javatest.report.Report;
import com.sun.javatest.report.ReportDirChooser;
import com.sun.javatest.Status;
import com.sun.javatest.report.Report.StartGenListener;
import com.sun.javatest.tool.ToolDialog;
import com.sun.javatest.tool.UIFactory;
import com.sun.javatest.util.DynamicArray;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.MouseInputAdapter;
import javax.swing.ComponentInputMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.text.Keymap;
import javax.swing.Timer;
import javax.swing.text.JTextComponent;

class NewReportDialog extends ToolDialog
{

    //----------------------------------------------------------------------------

    private static final String ACTION_MAP_KEY = "listMnemonics";

    interface Observer {
        // if ever made public, should rethink method names and if any helpful
        // parameters are passed

       /**
       * The dialog is done. Notify the observer to keep a snapshot of
       * current state.
         */
        public void update(Map l);

        // starting
        public void writingReport();
        
        // done
        public void wroteReport();

        // error creating report
        // upgrade to use resource bundle+key as message
        // the given error occured, and the user was informed
        public void errorWriting(String problem);
    }

    NewReportDialog(Component parent, UIFactory uif, FilterConfig f,
                ReportBrowser reportBrowser, ExecModel model) {
      super(parent, uif, "nrd");

        this.model = model;
        filterHandler = f.createFilterSelectionHandler();
      this.reportBrowser = reportBrowser;
    }

    public void setInterviewParameters(InterviewParameters p) {
       interviewParams = p;
    }

    // ---------------------------------------------------------------------------

    void setLastState(Map h) {
        String rd = (String) (h.get(REPORT_DIR));
        String filter = (String) (h.get(FILTER));

      if (dirBox == null)
          initGUI();

        dirBox.removeAllItems();
        if (rd != null && rd.length() > 0) 
           dirBox.addItem(rd);
        else
           dirBox.addItem("");

        if (filter != null && filter.length() > 0) 
           filterHandler.setFilter(filter);
    }

    Map getLastState() {
        String rd = (String) (dirBox.getSelectedItem());
        String filter = filterHandler.getActiveFilter().getName();
        Map lastState = new HashMap();

        if (rd != null && rd.length() > 0) 
           lastState.put(REPORT_DIR, rd);

        if (filter != null && filter.length() > 0) 
           lastState.put(FILTER, filter);

        return lastState;
    }

    void addObserver(Observer o) {
        obs = (Observer[])DynamicArray.append(obs, o);
    }

    void removeObserver(Observer o) {
        obs = (Observer[])DynamicArray.remove(obs, o);
    }

    // Notify the observers that a change has been made.
    private void notifyUpdate(Map s) {
        for (Observer o : obs) {
            o.update(s);
        }
    }

    private void notifyStarting() {
        for (Observer o : obs) {
            o.writingReport();
        }
    }

    private void notifyDone() {
        for (Observer o : obs) {
            o.wroteReport();
        }
    }

    private void notifyError(String problem) {
        for (Observer o : obs) {
            o.wroteReport();
        }
    }
    
    private void notifyErrorWriting(String problem) {
        for (Observer o : obs) {
            o.errorWriting(problem);
        }
    }

    // ---------------------------------------------------------------------------

    protected void initGUI() {
      setI18NTitle("nrd.title");

      JPanel body = new JPanel() {
            public Dimension getPreferredSize() {
                Dimension d = super.getPreferredSize();
                int dpi = uif.getDotsPerInch();
                return new Dimension(Math.max(d.width, 5 * dpi), d.height);
            }
          };
      body.setName("nrd.body");
      body.setFocusable(false);
      body.setLayout(new GridBagLayout());
      body.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

      int dpi = uif.getDotsPerInch();

      GridBagConstraints lc = new GridBagConstraints();
      lc.anchor = GridBagConstraints.EAST;
      lc.insets.right = 10;
      lc.insets.bottom = 11;
      lc.weighty = 0.0;
      lc.weightx = 0.0;
      lc.fill = GridBagConstraints.HORIZONTAL;
      lc.gridwidth = 1;

      // first row, directory name
      JLabel dirLabel = uif.createLabel("nrd.dir", true);
      body.add(dirLabel, lc);

      dirBox = uif.createChoice("nrd.dir.choice", true, dirLabel);
        dirBox.setMaximumRowCount(1);
      lc.weightx = 3.0;
      body.add(dirBox, lc);

      browseBtn = uif.createButton("nrd.browse", listener);
      browseBtn.setBorder(BorderFactory.createCompoundBorder(
          BorderFactory.createEtchedBorder(),
          BorderFactory.createEmptyBorder(0,3,0,3)));
      lc.gridwidth = GridBagConstraints.REMAINDER;
      lc.insets.left = 11;
      lc.weightx = 0.0;
      body.add(browseBtn, lc);

      // second row, filter
      lc.insets.left = 0;
      lc.gridwidth = 1;

      // add filter selector
        if (filterHandler != null) {
          JLabel filterLabel = uif.createLabel("nrd.filter", true);
          body.add(filterLabel, lc);
          
          JComponent selector = filterHandler.getFilterSelector();
          filterLabel.setLabelFor(selector);
          lc.gridwidth = GridBagConstraints.REMAINDER;
          lc.weightx = 4.0;
          lc.anchor = GridBagConstraints.WEST;
          lc.fill = GridBagConstraints.NONE;
          body.add(selector, lc);
      }

      // third row, the tabs
      lc.anchor = GridBagConstraints.NORTHWEST;
      lc.gridwidth = GridBagConstraints.REMAINDER;
      lc.fill = GridBagConstraints.BOTH;
      lc.insets.bottom = 12;
      lc.weighty = 4.0;
      lc.weighty = 1.0;

//------------------------------------------------------------------------  
        
        JPanel middle = uif.createPanel("nrd.middle", false);
        middle.setLayout(new BorderLayout());
        middle.setBorder(BorderFactory.createCompoundBorder(
                        uif.createTitledBorder("nrd.middle"),
                        BorderFactory.createEmptyBorder(12,12,12,12)));

      panes = new JComponent[] {
          createHtmlBlock(),
          createFilesBlock()
      };
        
      tabs = uif.createTabbedPane("nrd.tabs", panes);
      tabs.setTabPlacement(SwingConstants.TOP);
      tabs.setBorder(BorderFactory.createEmptyBorder());

        listModel = new DefaultListModel();

        // populate list and card panel
        final CardLayout cards = new CardLayout();
        final JPanel p = uif.createPanel("nrd.typecards", cards, false);

      cbHtml = uif.createCheckBox("nrd.type.html", true);
      //cbHtml.addActionListener(cbListener);
        listModel.addElement(cbHtml);
      p.add("nrd.type.html", tabs);

      cbPlain = uif.createCheckBox("nrd.type.pt", true);
        listModel.addElement(cbPlain);
      p.add("nrd.type.pt", uif.createPanel("nrd.blank", false));

      cbXml = uif.createCheckBox("nrd.type.xml", false);
        listModel.addElement(cbXml);
      p.add("nrd.type.xml", uif.createPanel("nrd.blank", false));

        getCustomReports(p);

        list = uif.createList("nrd.typel", listModel);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        SelectListener sl = new SelectListener(list, p, cards);
        list.addMouseListener(sl);
        list.addKeyListener(sl);
        list.addListSelectionListener(sl);
        list.setCellRenderer(new CheckBoxListCellRenderer());
      list.setBorder(BorderFactory.createCompoundBorder(
          BorderFactory.createEtchedBorder(),
          BorderFactory.createEmptyBorder(0,3,0,3)));

        infoArea = uif.createMessageArea("nrd.info");
        infoArea.setRows(3);
        Font f = infoArea.getFont();
        f = f.deriveFont(Font.PLAIN, f.getSize2D()-1);
        infoArea.setFont(f);
        
        // create container for right side (next to list)
        JPanel right = uif.createPanel("nrd.rptright", false);
        right.setLayout(new BorderLayout());
        right.add(infoArea, BorderLayout.PAGE_START);
        right.add(p, BorderLayout.CENTER);
        middle.add(right, BorderLayout.CENTER);

        middle.add(list, BorderLayout.WEST);
        body.add(middle, lc);
//-----------------------------------------------------------------
        
        Action listMnemonics = new AbstractAction() {

                  public void actionPerformed(ActionEvent e) {
                        int ord = Integer.parseInt(e.getActionCommand()) - 1;
                        if (ord == -1) ord = 9;
                        if (ord <= list.getModel().getSize()) {
                              list.requestFocusInWindow();
                              list.setSelectedIndex(ord);
                        }
                  }
            
        };
        
        ActionMap listActions = new ActionMap();
        InputMap listInput = new ComponentInputMap(list);
        
        list.setActionMap(listActions);
        list.setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, listInput);
        
        listActions.put(ACTION_MAP_KEY, listMnemonics);
        
        int itemCount = listModel.size();
        if (itemCount > 9) itemCount = 9;
        for (int i = 1; i <= itemCount; ++i) {
            listInput.put(KeyStroke.getKeyStroke(i + '0', InputEvent.ALT_DOWN_MASK), ACTION_MAP_KEY);
            JCheckBox box = ((JCheckBox)listModel.getElementAt(i - 1));
            box.setMnemonic(i + '0');
            box.setText(Character.toString((char)('0' + i)) + " " + box.getText());
        }
        
        if (listModel.size() == 10){
            listInput.put(KeyStroke.getKeyStroke('0', InputEvent.ALT_DOWN_MASK), ACTION_MAP_KEY);
            JCheckBox box = ((JCheckBox)listModel.getElementAt(9));
            box.setMnemonic('0');
            box.setText("0 " + box.getText());
        }
        
//-----------------------------------------------------------------
        JPanel bottom = createBackupOpsPane();
        bottom.setBorder(BorderFactory.createCompoundBorder(
                        uif.createTitledBorder("nrd.backup"),
                        BorderFactory.createEmptyBorder(12,12,12,12)));
        
        body.add(bottom, lc);        
      setBody(body);
//--------------------------------------------------------------------------------------
        
        okBtn = uif.createButton("nrd.ok", listener);
        cancelBtn = uif.createCancelButton("nrd.cancel", listener);
      setButtons(new JButton[] { okBtn, cancelBtn, }, cancelBtn);

        list.setSelectedIndex(0);
      setState(Report.getSettingsPrefs());
    }

    /** 
     * Options for the HTML report.
     */
    private JComponent createHtmlBlock() {
      JPanel p = uif.createPanel("nrd.htmlops", new GridBagLayout(),
                            false);
      p.setName("htmlops");
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.fill = GridBagConstraints.NONE;
      gbc.anchor = GridBagConstraints.WEST;
      gbc.gridwidth = 2;
      gbc.gridy = 0;

      // info about this block of buttons
      JTextArea info = uif.createMessageArea("nrd.htmlops");
      //info.setBorder(BorderFactory.createLineBorder(Color.black));
      p.add(info, gbc);

      // checkboxes
      // these are given settings here, but setting will be reloaded
      // elsewhere before the user sees them
      JCheckBox cb = uif.createCheckBox("nrd.htmlops.config", true);
      cbConfig = cb;
      cbConfig.addActionListener(cbListener);
      htmlGroup.addElement(cb);
      gbc.gridy = 1;
      p.add(cb, gbc);

      // question log
      gbc.gridwidth = 1;
      gbc.gridy = 2;
      cb = cbQl = uif.createCheckBox("nrd.htmlops.ql", true);
      configGroup.addElement(cb);
      htmlGroup.addElement(cb);
      p.add(uif.createHorizontalStrut(25), gbc);
      p.add(cb, gbc);

      // environment
      gbc.gridy = 3;
      cb = cbEnv = uif.createCheckBox("nrd.htmlops.env", false);
      configGroup.addElement(cb);
      htmlGroup.addElement(cb);
      p.add(uif.createHorizontalStrut(25), gbc);
      p.add(cb, gbc);

      // standard values
      gbc.gridy = 4;
      cb = cbStd = uif.createCheckBox("nrd.htmlops.std", false);
      configGroup.addElement(cb);
      htmlGroup.addElement(cb);
      p.add(uif.createHorizontalStrut(25), gbc);
      p.add(cb, gbc);

      // result summary
      gbc.gridy = 5;
      gbc.gridwidth = 2;
      cb = cbResults = uif.createCheckBox("nrd.htmlops.res", true);
      htmlGroup.addElement(cb);
      p.add(cb, gbc);

      // keyword summary
      cb = cbKws = uif.createCheckBox("nrd.htmlops.kw", true);
      htmlGroup.addElement(cb);
      gbc.gridy = 6;
      p.add(cb, gbc);

      JScrollPane sp = uif.createScrollPane(p,
            ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
            ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

      sp.setViewportBorder(BorderFactory.createCompoundBorder(
          BorderFactory.createEmptyBorder(10, 5, 5, 5),
          uif.createTitledBorder("nrd.htmlops")
      ));
        sp.addPropertyChangeListener("enabled", new PanelEnableListener(sp));
      return sp;
    }

    /** 
     * Options for the HTML report files.
     */
    private JComponent createFilesBlock() {
      JPanel p = uif.createPanel("nrd.htmlf", new GridBagLayout(),
                            false);
      p.setName("htmlf");
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.fill = GridBagConstraints.BOTH;
      gbc.anchor = GridBagConstraints.WEST;
      //gbc.gridx = 0;
      gbc.gridwidth = 3;
      gbc.gridy = 0;

      // info about this block of buttons
      JTextArea info = uif.createMessageArea("nrd.htmlf");
      //info.setBorder(BorderFactory.createLineBorder(Color.black));
      p.add(info, gbc);

      // settings are given here, but settings will be reloaded
      // elsewhere before the user sees them

      // index.html and/or report.html
      JLabel lab = uif.createLabel("nrd.htmlf.main", false);
      gbc.gridy = 1;
      p.add(lab, gbc);

      gbc.gridwidth = 1;
      gbc.gridy = 2;
      JCheckBox cb = cbHtmlRpt = uif.createCheckBox("nrd.htmlf.rpt", true);
      cbHtmlRpt.addActionListener(cbListener);
      htmlGroup.addElement(cb);
      p.add(uif.createHorizontalStrut(25), gbc);
      gbc.gridwidth = 2;
      p.add(cb, gbc);

      gbc.gridy = 3;
      gbc.gridwidth = 1;
      cb = cbHtmlInd = uif.createCheckBox("nrd.htmlf.idx", false);
      cbHtmlInd.addActionListener(cbListener);
      htmlGroup.addElement(cb);
      p.add(uif.createHorizontalStrut(25), gbc);
      gbc.gridwidth = 2;
      p.add(cb, gbc);

      // pass, fail, error, notrun files
      gbc.gridy = 4;
      gbc.gridwidth = 3;
      lab = uif.createLabel("nrd.htmlf.xtra", false);
      p.add(lab, gbc);

      gbc.gridy = 5;
      cb = uif.createCheckBox("nrd.htmlf.pass", true);
      htmlGroup.addElement(cb);
      cbPass = cb;
      gbc.gridwidth = 1;
      p.add(uif.createHorizontalStrut(25), gbc);
      p.add(cb, gbc);

      cb = cbErr = uif.createCheckBox("nrd.htmlf.err", true);
      htmlGroup.addElement(cb);
      p.add(cb, gbc);

      gbc.gridy = 6;
      cb = cbFail = uif.createCheckBox("nrd.htmlf.fail", true);
      htmlGroup.addElement(cb);
      p.add(uif.createHorizontalStrut(25), gbc);
      p.add(cb, gbc);

      cb = cbNr = uif.createCheckBox("nrd.htmlf.nr", true);
      htmlGroup.addElement(cb);
      p.add(cb, gbc);

      JScrollPane sp = uif.createScrollPane(p,
            ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
            ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

      sp.setViewportBorder(BorderFactory.createCompoundBorder(
          BorderFactory.createEmptyBorder(10, 5, 5, 5),
          uif.createTitledBorder("nrd.htmlf")
      ));
        
        sp.addPropertyChangeListener("enabled", new PanelEnableListener(sp));
      return sp;
    }
    
    private JPanel createBackupOpsPane() {
        JPanel p = uif.createPanel("nrd.backup", new GridBagLayout(),
                            false);        
      p.setName("backup");
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.fill = GridBagConstraints.BOTH;
      gbc.anchor = GridBagConstraints.WEST;
      gbc.gridx = 0;
      gbc.gridwidth = 3;

      // info about this block of buttons
      JTextArea info = uif.createMessageArea("nrd.backup");
      //info.setBorder(BorderFactory.createLineBorder(Color.black));
      p.add(info, gbc);

      // checkboxes
      // these are given settings here, but setting will be reloaded
      // elsewhere before the user sees them
      JCheckBox cb = cbBak = uif.createCheckBox("nrd.backup.bak", true);
      cbBak.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                if (numBak != null) {
                  numBak.setEnabled(cbBak.isSelected());
                }
            }
          });
      p.add(cb, gbc);

      gbc.gridwidth = 1;
      gbc.gridy = 2;
      gbc.gridx = GridBagConstraints.RELATIVE;
      p.add(uif.createHorizontalStrut(25), gbc);

      JLabel lab = uif.createLabel("nrd.backup.bak.level", true);
      p.add(lab, gbc);

      // backup levels
      numBak = uif.createInputField("nrd.backup.bak.level", 2, lab);
      gbc.insets.left = 12;
      numBak.setText("1");

      Action action = new AbstractAction() {
          public void actionPerformed(ActionEvent e) {
                JTextField src = (JTextField) (e.getSource());
                String cmd = e.getActionCommand();
                char ch = cmd.charAt(0);
                int savedDot = src.getCaret().getDot();
                int savedMark = src.getCaret().getMark();
                String savedText = src.getText();

                // reject all non-numeric chars
                if (Character.isDigit(ch) && ch != '0') {
                  Action delegate = new javax.swing.text.DefaultEditorKit.InsertContentAction();
                  delegate.actionPerformed(e);

                  String newText = src.getText();
                  // reject new input if it leaves an invalid value,
                  // i.e. more than one digit (>9)
                  if (newText.length() > 1) {
                      src.setText(savedText);
                  }
                }
            }
          };
      Keymap keymap = numBak.addKeymap("intField", numBak.getKeymap());
      keymap.setDefaultAction(action);
      numBak.setKeymap(keymap);

      p.add(numBak, gbc);

      p.setMaximumSize(p.getPreferredSize());
        return p;
    }
    

    /**
     * @return number of custom reports added
     */
    private int getCustomReports(JPanel p) {
        int result = 0;

        ContextManager cm = model.getContextManager();
        if (cm == null)
            return 0;

        customReports = cm.getCustomReports();
        if (customReports == null || customReports.length == 0) {
            customReports = null;
            return 0;
        }

        customBoxes = new HashMap();

        for (int i = 0; i < customReports.length; i++) { 
            JCheckBox cb = new JCheckBox(customReports[i].getName());
            cb.setName(customReports[i].getReportId());
            listModel.addElement(cb);
            customBoxes.put(cb, customReports[i]);

            ReportConfigPanel[] ops = customReports[i].getOptionPanes();
            if (ops == null || ops.length == 0) {
                // no config panels, use blank
                p.add(customReports[i].getReportId(),
                        uif.createPanel("nrd.blank", false));
            }
            else {
                // tabbed pane for all supplied panels
                JTabbedPane tp = uif.createTabbedPane("nrd.custom.tabs");
                for (int j = 0; j < ops.length; j++)
                    tp.addTab(ops[j].getPanelName(), ops[j]);

                p.add(customReports[i].getReportId(), tp);
            }
            result++;
        }   // for

        return result;
    }

    private void showReportChooserDialog() {
        ReportDirChooser rdc = getReportDirChooser();
        rdc.setMode(ReportDirChooser.NEW);
        int option = rdc.showDialog(dirBox);
        if (option != JFileChooser.APPROVE_OPTION)
            return;

        dirBox.setSelectedItem(rdc.getSelectedFile().getAbsolutePath());
    }

    private ReportDirChooser getReportDirChooser() {
        if (reportDirChooser == null)
            reportDirChooser = new ReportDirChooser();
        return reportDirChooser;
    }

    void showReportBrowser(File f) {
        if(f.equals(new File(reportDir, Report.INDEX_FILE_NAME))) {
            reportBrowser.show(f);
        }
        else {
            String[] names = Report.getHtmlReportFilenames();
            Vector possible = new Vector();

            for (int i = 0; i < names.length; i++) {
                File rpt = new File(reportDir, names[i]);
                if (rpt.exists() && rpt.canRead())
                    possible.add(rpt);
                else
                    rpt = null;
            }

            if (possible.size() > 0) {
                // show the most recently dated file
                File rpt = null;
                File newestF = null;
                long newestTime = 0;

                for (int i = 0; i < possible.size(); i++) {
                    File file = (File)(possible.elementAt(i));
                    if (file.lastModified() > newestTime) {
                        newestF = file;
                        newestTime = file.lastModified();
                    }
                } // for
                reportBrowser.show(newestF);
            }
            else
                reportBrowser.show(reportDir);
        }
    }

    /** 
     * Normally called by the background thread.
     */
    private void runReport(Report.Settings settings) throws IOException {
      if (interviewParams != null) {
            Report r = new Report();

            // if no work directory selected, throw exception.
            if (interviewParams.getWorkDirectory() == null) {
              throw new IOException(uif.getI18NString("nrd.noWorkDir.err"));
            }
            r.addStartGenListener(new ReportGenListener());
          r.writeReports(settings, reportDir, getActiveCustomReports());

      }
      else {
          throw new IOException(uif.getI18NString("nrd.nullParams.err"));
      }
    }

    private ArrayList getActiveCustomReports() {

        ArrayList customReps = new ArrayList();
        if (customBoxes != null && customBoxes.size() > 0) {
            Iterator it = customBoxes.keySet().iterator();
            while (it.hasNext()) {
                JCheckBox box = (JCheckBox)(it.next());
                if (box.isSelected()) {
                    customReps.add(customBoxes.get(box));
                }
            }   
        }
        return customReps;
    }

    private boolean isEmptyDirectory(File f) {
        return (f.isDirectory() && f.list().length == 0);
    }

    private void updateCheckboxStates() {
      // config buttons done before html buttons to ensure that
      // config gets disabled if HTML reporting is off

      if (!cbHtml.isSelected()) {
          for (int i = 0; i < htmlGroup.size(); i++)
            ((JCheckBox)(htmlGroup.elementAt(i))).setEnabled(cbHtml.isSelected());
      }
      else {
          for (int i = 0; i < htmlGroup.size(); i++)
            ((JCheckBox)(htmlGroup.elementAt(i))).setEnabled(cbHtml.isSelected());
          for (int i = 0; i < configGroup.size(); i++)
            ((JCheckBox)(configGroup.elementAt(i))).setEnabled(cbConfig.isSelected());
      }
    }

    private Report.Settings captureState() {
      Report.Settings snap = new Report.Settings(interviewParams);

      snap.setEnableHtmlReport(cbHtml.isSelected());
      snap.setEnableXmlReport(cbXml.isSelected());
      snap.setEnablePlainReport(cbPlain.isSelected());

      snap.setShowConfigSection(cbConfig.isSelected());
      snap.setShowEnvLog(cbEnv.isSelected());
      snap.setShowQuestionLog(cbQl.isSelected());
      snap.setShowStdValues(cbStd.isSelected());
      snap.setShowResults(cbResults.isSelected());
      snap.setShowKeywordSummary(cbKws.isSelected());

      snap.setHtmlMainReport(cbHtmlRpt.isSelected(), cbHtmlInd.isSelected());
      snap.setEnableHtmlStateFile(Status.PASSED, cbPass.isSelected());
      snap.setEnableHtmlStateFile(Status.FAILED, cbFail.isSelected());
      snap.setEnableHtmlStateFile(Status.ERROR, cbErr.isSelected());
      snap.setEnableHtmlStateFile(Status.NOT_RUN, cbNr.isSelected());

      snap.setEnableBackups(cbBak.isSelected());

      try {
          int i = Integer.parseInt(numBak.getText());
          snap.setBackupLevels(i);
      }
      catch (NumberFormatException e) {
      }

        TestFilter filter = filterHandler.getActiveFilter();

        // see Report.Settings for info on what this is:
        if (filter instanceof ParameterFilter)
            snap.setAllowInitFilesOptimize(true);
        else
            snap.setAllowInitFilesOptimize(false);

      snap.setFilter(filter);

      return snap;
    }

    private void setState(Report.Settings snap) {
      if (snap == null)
          return;

      lastSettings = snap;


      cbHtml.setSelected(snap.isHtmlEnabled());
      cbXml.setSelected(snap.isXmlEnabled());
      cbPlain.setSelected(snap.isPlainEnabled());

      // ---
      boolean section = snap.isConfigSectionEnabled();
      cbConfig.setSelected(section);

      cbEnv.setSelected(snap.isEnvEnabled());
      cbQl.setSelected(snap.isQuestionLogEnabled());
      cbStd.setSelected(snap.isStdEnabled());

      cbEnv.setEnabled(section);
      cbQl.setEnabled(section);
      cbStd.setEnabled(section);

      // ---
      cbResults.setSelected(snap.isResultsEnabled());
      cbKws.setSelected(snap.isKeywordSummaryEnabled());

      cbHtmlRpt.setSelected(snap.isReportHtmlEnabled());
      cbHtmlInd.setSelected(snap.isIndexHtmlEnabled());
      cbPass.setSelected(snap.isStateFileEnabled(Status.PASSED));
      cbFail.setSelected(snap.isStateFileEnabled(Status.FAILED));
      cbErr.setSelected(snap.isStateFileEnabled(Status.ERROR));
      cbNr.setSelected(snap.isStateFileEnabled(Status.NOT_RUN));

      cbBak.setSelected(snap.isBackupsEnabled());
      numBak.setText(Integer.toString(snap.getBackupLevel()));

      // a null value will be ignored
      filterHandler.setFilter(snap.getTestFilter());
    }

    private ActionListener cbListener = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
          Object src = e.getSource();

          if (src == cbHtml || src == cbConfig)
            updateCheckboxStates();
          else if (src == cbBak) {
            numBak.setEnabled(cbBak.isSelected());
          }
      }
    };
    
    private ActionListener listener = new ActionListener() {
      public void actionPerformed(ActionEvent e) {
          Object src = e.getSource();

          if (src == browseBtn) {
            showReportChooserDialog();
          } 
          else if (src == cancelBtn) {
            // revert settings
            // hide dialog
            setState(lastSettings);
            setVisible(false);
          } 
          else if (src == okBtn) {
            String s = (String) dirBox.getSelectedItem(); 

            // check null input
            if (s == null || s.length() == 0) {
                uif.showError("nrd.emptyInput");
                return;
            }

            // check for empty input
            if (cbBak.isSelected() && numBak.getText().equals("")) {
                uif.showError("nrd.emptyBak");
                // select the last tab (assumes this has the backup settings)
                tabs.setSelectedIndex(tabs.getTabCount()-1);
                return;
            }
                
                // validate custom reports
                Iterator it = getActiveCustomReports().iterator();
                while (it.hasNext()) {
                    CustomReport cr = (CustomReport) it.next();
                    String error = cr.validateOptions();
                    if (error != null) {
                        for (int i = 0; i < listModel.getSize(); i++ ) {
                            JCheckBox cb = (JCheckBox)listModel.elementAt(i);
                            if (cb.getName().equals(cr.getReportId())) {
                                list.setSelectedIndex(i);
                            }
                        }
                        uif.showError("nrd.optionsErr", new Object[] {error} );
                        return;
                    }
                }

            reportDir = new File(s);

            try {
                // check if dir needs to be created.
                if (!reportDir.isDirectory()) {
                  reportDir.mkdirs();
                }
                else {
                      // check if dir is a report dir
                  if (!Report.isReportDirectory(reportDir) &&
                      !isEmptyDirectory(reportDir)) {
                      uif.showError("nrd.cantUse", reportDir);
                      return;
                  }
                }

                // XXX save settings in prefs

                setVisible(false);
                lastSettings = captureState();
                    notifyStarting();
                doBgReport(lastSettings);
            }
            catch (SecurityException se) {
                uif.showError("nrd.cantCreate", se.getMessage());
            }
          }
      }

      // does work on background thread
      private void doBgReport(final Report.Settings snap) {
          /*final JDialog*/ waitDialog = uif.createWaitDialog("nrd.wait", parent);
 
            final Stopper stopper = new Stopper();
          final Thread worker = new Thread() {
            public void run() {
                try {
                  runReport(snap);
                  // go away to switch back to GUI thread
                  finishReport(waitDialog, snap, stopper);
                }
                    catch (CustomReport.ReportException ie) { 
                        showError("nrd.custom", ie.getMessage(), waitDialog); 
                        notifyError(ie.getMessage());
                    }
                catch (IOException ie) {
                  showError("nrd.cantWrite", ie.getMessage(), waitDialog);
                        notifyError(ie.getMessage());
                  // should reshow dialog
                }
                catch (SecurityException se) {
                  showError("nrd.cantCreate", se.getMessage(), waitDialog);
                        notifyError(se.getMessage());
                  // should reshow dialog
                }
                    catch (RuntimeException re) {
                        showError("nrd.errorWriting", re.getMessage(), waitDialog);
                        notifyErrorWriting(re.getMessage());
                    }
            }   // run()
          };      // thread

            // this code is copied from ReportTool....
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.fill = GridBagConstraints.NONE;
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.insets.bottom = 10;
            gbc.insets.top = 10;
            gbc.gridy = 2;
            gbc.gridx = 0;
            JButton cancelBtn = uif.createButton("nrd.cancel");
            waitDialog.getContentPane().add(cancelBtn, gbc);
            waitDialog.pack();
            final String cancelling = uif.getI18NString("nrd.cancelling");
            cancelBtn.addActionListener( new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JButton butt = (JButton) e.getSource();
                    butt.setEnabled(false);
                    Component[] cmp = waitDialog.getContentPane().getComponents();
                    if (worker != null && worker.isAlive()) {
                        stopper.waitWasHidden = true;
                        worker.interrupt();
                    }
                    for ( int i = 0; i < cmp.length; i++) {
                        if("nrd.wait".equals(cmp[i].getName())) {
                            if (cmp[i] instanceof JTextComponent) {
                                ((JTextComponent)cmp[i]).setText(cancelling);
                            }
                            break;
                        }
                    }

                }
            });
            
            
            
            
          ActionListener al = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                // show dialog if still processing
                if (worker.isAlive()) {
                  waitDialog.show();
                }
            }
          };

          // show wait dialog if operation is still running after
          // WAIT_DIALOG_DELAY
          Timer timer = new Timer(WAIT_DIALOG_DELAY, al);
          timer.setRepeats(false);
          timer.start();

          // do it!
          worker.start();
      }

      private void finishReport(final JDialog waitDialog,
                          final Report.Settings snap, final Stopper stopper) {
          // done generating report, switch back to GUI thread
          EventQueue.invokeLater(new Runnable() {
                public void run() {
                  waitDialog.hide();
                        if(!stopper.waitWasHidden) {
                            int r = uif.showYesNoDialog("nrd.showReport");

                            switch (r) {
                            case JOptionPane.YES_OPTION:
                                File index = new File(reportDir, Report.INDEX_FILE_NAME);
                                if(index.exists() && index.canRead()) {
                                    showReportBrowser(index);
                                }
                                else {
                                    showReportBrowser(selectFileToShow(snap));
                                }
                                break;
                            case JOptionPane.NO_OPTION:
                                break;
                            default:
                                break;
                            }
                        }

                        notifyDone();
                  notifyUpdate(getLastState());
                }
            }
          );
      }
        

      /**
       * @param uiKey Key to use to call <tt>UIFactory.showError()</tt>
       * @param msg The localized error message to show.
       */
      private void showError(final String uiKey, final String msg,
                        final JDialog waitDialog) {
          // switch back to GUI thread
          EventQueue.invokeLater(new Runnable() {
                public void run() {
                  waitDialog.hide();
                  uif.showError(uiKey, msg);
                }
            }
          );
      }

      /**
       * Decide which file in the report dir to show to the user when
       * they ask to view a generated 'report'.
       */
      private File selectFileToShow(Report.Settings snap) {
          File result = new File(reportDir, Report.INDEX_FILE_NAME);
            
            if(!result.exists()) {
                if (snap.isHtmlEnabled()) {
                    // show main report file or file listing
                    result = searchForFile(reportDir, Report.getHtmlReportFilenames());
                    if (result == null)
                        result = reportDir;
                }
                /* not useful right now to see raw xml, could do XSLT later
                else if (snap.isPlainEnabled()) {
                    // show that file
                    result = searchForFile(reportDir, Report.getPlainReportFilenames());
                    if (result == null)
                        result = reportDir;
                }
                else if (snap.isXmlEnabled()) {
                    result = new File(reportDir, "xml");
                }
                */
                else {
                    result = reportDir;
                }
            }
            
          return result;
      }

      private File searchForFile(File dir, String[] names) {
          for (int i = 0; i < names.length; i++) {
            File f = new File(reportDir, names[i]);
            if (f.exists()) {
                return f;
            }
          }   // for

          return null;
      }
    };
    
    
    //------------------------------end of listener--------------------------
       
    private static class Stopper {
        boolean waitWasHidden = false;
    }
    
    private class ReportGenListener implements StartGenListener {
        public void startReportGeneration(Report.Settings s, String reportID) {
            String reportName;
            if(reportID.equals("xml") || reportID.equals("pt") || 
                                                reportID.equals("html")) {
                reportName = uif.getI18NString("nrd.type." + reportID + ".ckb");
            }
            else {
                reportName = reportID;
            }

            String status = uif.getI18NString("nrd.wait.report_gen", 
                                                new String[] {reportName});

            Component[] cmp = waitDialog.getContentPane().getComponents();
            for ( int i = 0; i < cmp.length; i++) {
                if("nrd.wait".equals(cmp[i].getName())) {
                    if (cmp[i] instanceof JTextComponent) {
                        ((JTextComponent)cmp[i]).setText(status);
                    }
                    break;
                }
            }
        }
    }
    
    /**
     * This listener changes options state against checkboxes
     */
01193     private class SelectListener extends MouseInputAdapter implements KeyListener, ListSelectionListener {

        /**
         * @param lst JList of checkboxes
         * @param p parent Panel
         * @param cardLayout The CardLayout for options
         */
01200         SelectListener(JList lst, JPanel p, CardLayout cardLayout ) {
            list = lst;
            listModel = list.getModel();
            lastSelected = listModel.getElementAt(0);
            panel = p;
            cards = cardLayout;
        }
        
        public void keyTyped(KeyEvent e) {
            if (e.getKeyChar() == ' ') {
                process(list.getSelectedIndex());
            }
        }

        public void mouseClicked(MouseEvent e) {
            if (e.getPoint().getX() <= emptyCBW) {
                process(list.locationToIndex(e.getPoint()));
            }
        }

        public void valueChanged(ListSelectionEvent e) {
            int index = list.getSelectedIndex();
            JCheckBox box = (JCheckBox)(listModel.getElementAt(index));

            if (lastSelected != box) {
                cards.show(panel, box.getName());
                lastSelected = box;
            }
            enablePanel(box);
        }

        private void enablePanel(final JCheckBox box) {
            for (int i = 0; i < panel.getComponentCount(); i++) {
                JComponent tab = (JComponent) panel.getComponent(i);
                tab.setEnabled(box.isSelected());
            }
            if (customBoxes != null) {
                CustomReport rep = (CustomReport) customBoxes.get(box);
                if (rep != null && rep.getOptionPanes() != null) {
                    for (int i = 0; i < rep.getOptionPanes().length; i++) {
                        rep.getOptionPanes()[i].setEnabled(box.isSelected());
                    }
                } else if (box == cbHtml) {
                    for (int i = 0; i < panes.length; i++) {
                        panes[i].setEnabled(box.isSelected());
                    }
                }
            }

            if (box == cbHtml)
                infoArea.setText(uif.getI18NString("nrd.info.html.txt"));
            else if (box == cbPlain)
                infoArea.setText(uif.getI18NString("nrd.info.plain.txt"));
            else if (box == cbXml)
                infoArea.setText(uif.getI18NString("nrd.info.xml.txt"));
            else if (customBoxes != null) {
                CustomReport rep = (CustomReport) customBoxes.get(box);
                if (rep != null)
                    infoArea.setText(rep.getDescription());
            }

        }
        
        private void process(final int index) {
            JCheckBox box = (JCheckBox)(listModel.getElementAt(index));

            if (lastSelected == box) {
                box.doClick();
                list.repaint();     // important!
                enablePanel(box);
            }
            lastSelected = box;
        }

        public void keyReleased(KeyEvent e) {
        }

        public void keyPressed(KeyEvent e) {
        }

        Object lastSelected;
        JList list; 
        ListModel listModel;
        JPanel panel;
        CardLayout cards;
        double emptyCBW = new JCheckBox("").getPreferredSize().getWidth() + 2;
    }

    /*
     * PropertyChangeListener for enabling/disabling container's content
     */
    private class PanelEnableListener implements PropertyChangeListener {
        /**
         * @param container Container for controlling 
         */
        PanelEnableListener(Container container) {
            theContainer = container;
        }
        /**
         * Catches changes of "enabled" property 
         * and changes enabled status for all child components
         */
        public void propertyChange(PropertyChangeEvent evt) {
            if ("enabled".equals(evt.getPropertyName())) {
                boolean oldV = ((Boolean) evt.getOldValue()).booleanValue();
                boolean newV = ((Boolean) evt.getNewValue()).booleanValue();
                if (oldV && !newV) {
                    // disable
                    Iterator chIt = collectChildren(theContainer, new ArrayList()).iterator();
                    enabledComp = new HashSet();
                    while (chIt.hasNext()) {
                        Component c = (Component) chIt.next();
                        if (c.isEnabled()) {
                            enabledComp.add(c);
                            c.setEnabled(false);
                        }
                    }
                    
                } else if (!oldV && newV && enabledComp != null) { 
                    // enable
                    Iterator chIt = collectChildren(theContainer, new ArrayList()).iterator();
                    while (chIt.hasNext()) {
                        Component c = (Component) chIt.next();
                        if (enabledComp.contains(c)) {
                            c.setEnabled(true);
                        }
                    }
                }
            }
        }
        
        /**
         * Recursively gathers all children components
         */
        private Collection collectChildren(Container comp, Collection c) {
            Component [] ch = comp.getComponents();
            for(int i = 0; i < ch.length; i++) {
                c.add(ch[i]);
                if (ch[i] instanceof Container) {
                    collectChildren((Container) ch[i],  c);
                }
            }
            return c;
        }
        
        private Container theContainer;
        private HashSet enabledComp;
    }
    
    private class CheckBoxListCellRenderer implements ListCellRenderer {
        public Component getListCellRendererComponent(
                    JList list,
                    Object value,
                    int index,
                    boolean isSelected,
                    boolean cellHasFocus) {
            // assert: value is a JCheckBox
            JComponent comp = (JComponent)value;
            if (isSelected) {
                comp.setOpaque(true);
                comp.setBackground(MetalLookAndFeel.getTextHighlightColor());
            }
            else {
                comp.setOpaque(false);
                comp.setForeground(Color.black);
            }

            return comp;
         }
    }

    private Observer[] obs = new Observer[0];
    private ExecModel model;

    private ReportDirChooser reportDirChooser;

    private DefaultListModel listModel;
    private JList list;
    private JTextArea infoArea;
    private CustomReport[] customReports;
    private HashMap customBoxes;

    private JComponent[] panes;
    private JCheckBox cbHtml;
    private JCheckBox cbPlain;
    private JCheckBox cbXml;

    private JCheckBox cbConfig;
    private JCheckBox cbQl;
    private JCheckBox cbEnv;
    private JCheckBox cbStd;
    private JCheckBox cbResults;
    private JCheckBox cbKws;

    private JCheckBox cbPass;
    private JCheckBox cbFail;
    private JCheckBox cbErr;
    private JCheckBox cbNr;
    private JCheckBox cbHtmlRpt;
    private JCheckBox cbHtmlInd;

    private JCheckBox cbBak;
    private JTextField numBak;

    private Vector htmlGroup = new Vector();
    private Vector configGroup = new Vector();

    private File reportDir;
    private JButton browseBtn;
    private JButton okBtn;
    private JButton cancelBtn;
    private JComboBox dirBox;

    private JTabbedPane tabs;

    private Report.Settings lastSettings;

    private ReportBrowser reportBrowser;
    private InterviewParameters interviewParams;
    private FilterSelectionHandler filterHandler;

    // keys for option values used for save & restore
    static final String REPORT_DIR = "reportDir";
    private static final String FILTER = "filter";
    private static final int WAIT_DIALOG_DELAY = 3000;          // 3 second delay
    
    private JDialog waitDialog;
    
}

Generated by  Doxygen 1.6.0   Back to index