1 /* 2 * $Id$ 3 * 4 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. 5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 only, as 9 * published by the Free Software Foundation. Oracle designates this 10 * particular file as subject to the "Classpath" exception as provided 11 * by Oracle in the LICENSE file that accompanied this code. 12 * 13 * This code is distributed in the hope that it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 * version 2 for more details (a copy is included in the LICENSE file that 17 * accompanied this code). 18 * 19 * You should have received a copy of the GNU General Public License version 20 * 2 along with this work; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22 * 23 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24 * or visit www.oracle.com if you need additional information or have any 25 * questions. 26 */ 27 package com.sun.javatest.exec; 28 29 import com.sun.javatest.InterviewParameters; 30 import com.sun.javatest.TestFilter; 31 import com.sun.javatest.report.CustomReport.ReportConfigPanel; 32 import com.sun.javatest.report.CustomReport; 33 import com.sun.javatest.report.Report; 34 import com.sun.javatest.report.ReportDirChooser; 35 import com.sun.javatest.Status; 36 import com.sun.javatest.report.Report.StartGenListener; 37 import com.sun.javatest.report.ReportSettings; 38 import com.sun.javatest.tool.ToolDialog; 39 import com.sun.javatest.tool.UIFactory; 40 import com.sun.javatest.util.DynamicArray; 41 42 import java.awt.BorderLayout; 43 import java.awt.CardLayout; 44 import java.awt.Component; 45 import java.awt.Container; 46 import java.awt.Dimension; 47 import java.awt.Font; 48 import java.awt.event.ActionEvent; 49 import java.awt.event.ActionListener; 50 import java.awt.event.InputEvent; 51 import java.awt.event.KeyEvent; 52 import java.awt.event.KeyListener; 53 import java.awt.event.MouseEvent; 54 import java.awt.EventQueue; 55 import java.awt.GridBagConstraints; 56 import java.awt.GridBagLayout; 57 import java.beans.PropertyChangeEvent; 58 import java.beans.PropertyChangeListener; 59 import java.io.File; 60 import java.io.IOException; 61 import java.util.ArrayList; 62 import java.util.Collection; 63 import java.util.HashMap; 64 import java.util.HashSet; 65 import java.util.Iterator; 66 import java.util.Map; 67 68 import javax.swing.AbstractAction; 69 import javax.swing.Action; 70 import javax.swing.BorderFactory; 71 import javax.swing.DefaultListModel; 72 import javax.swing.event.ChangeEvent; 73 import javax.swing.event.ChangeListener; 74 import javax.swing.event.ListSelectionEvent; 75 import javax.swing.event.ListSelectionListener; 76 import javax.swing.event.MouseInputAdapter; 77 import javax.swing.JButton; 78 import javax.swing.JCheckBox; 79 import javax.swing.JComponent; 80 import javax.swing.JDialog; 81 import javax.swing.JFileChooser; 82 import javax.swing.JLabel; 83 import javax.swing.JList; 84 import javax.swing.JOptionPane; 85 import javax.swing.JPanel; 86 import javax.swing.JScrollPane; 87 import javax.swing.JTabbedPane; 88 import javax.swing.JTextArea; 89 import javax.swing.JTextField; 90 import javax.swing.KeyStroke; 91 import javax.swing.ListCellRenderer; 92 import javax.swing.ListModel; 93 import javax.swing.ListSelectionModel; 94 import javax.swing.ScrollPaneConstants; 95 import javax.swing.SwingConstants; 96 import javax.swing.text.Keymap; 97 import javax.swing.Timer; 98 import javax.swing.text.JTextComponent; 99 100 class NewReportDialog extends ToolDialog 101 { 102 103 //---------------------------------------------------------------------------- 104 105 private static final String ACTION_MAP_KEY = "listMnemonics"; 106 107 interface Observer { 108 // if ever made public, should rethink method names and if any helpful 109 // parameters are passed 110 111 /** 112 * The dialog is done. Notify the observer to keep a snapshot of 113 * current state. 114 */ 115 public void update(Map<String, String> l); 116 117 // starting 118 public void writingReport(); 119 120 // done 121 public void wroteReport(); 122 123 // error creating report 124 // upgrade to use resource bundle+key as message 125 // the given error occurred, and the user was informed 126 public void errorWriting(String problem); 127 } 128 129 NewReportDialog(Component parent, UIFactory uif, FilterConfig f, 130 ReportBrowser reportBrowser, ExecModel model) { 131 super(parent, uif, "nrd"); 132 133 this.model = model; 134 filterHandler = f.createFilterSelectionHandler(); 135 this.reportBrowser = reportBrowser; 136 } 137 138 public void setInterviewParameters(InterviewParameters p) { 139 interviewParams = p; 140 } 141 142 // --------------------------------------------------------------------------- 143 144 void setLastState(Map h) { 145 String rd = (String) (h.get(REPORT_DIR)); 146 String filter = (String) (h.get(FILTER)); 147 148 if (dirField == null) 149 initGUI(); 150 151 dirField.setText(rd); 152 153 if (filter != null && filter.length() > 0) 154 filterHandler.setFilter(filter); 155 156 updateHtmlCheckboxStates(); 157 updateCofCheckboxStates(); 158 } 159 160 Map<String, String> getLastState() { 161 String rd = dirField.getText(); 162 String filter = filterHandler.getActiveFilter().getName(); 163 Map<String, String> lastState = new HashMap<>(); 164 165 if (rd != null && rd.length() > 0) 166 lastState.put(REPORT_DIR, rd); 167 168 if (filter != null && filter.length() > 0) 169 lastState.put(FILTER, filter); 170 171 return lastState; 172 } 173 174 void addObserver(Observer o) { 175 obs = (Observer[])DynamicArray.append(obs, o); 176 } 177 178 void removeObserver(Observer o) { 179 obs = (Observer[])DynamicArray.remove(obs, o); 180 } 181 182 // Notify the observers that a change has been made. 183 private void notifyUpdate(Map<String, String> s) { 184 for (Observer o : obs) { 185 o.update(s); 186 } 187 } 188 189 private void notifyStarting() { 190 for (Observer o : obs) { 191 o.writingReport(); 192 } 193 } 194 195 private void notifyDone() { 196 for (Observer o : obs) { 197 o.wroteReport(); 198 } 199 } 200 201 private void notifyError(String problem) { 202 for (Observer o : obs) { 203 o.wroteReport(); 204 } 205 } 206 207 private void notifyErrorWriting(String problem) { 208 for (Observer o : obs) { 209 o.errorWriting(problem); 210 } 211 } 212 213 // --------------------------------------------------------------------------- 214 215 protected void initGUI() { 216 setHelp("report.newReport.csh"); 217 setI18NTitle("nrd.title"); 218 219 JPanel body = new JPanel() { 220 public Dimension getPreferredSize() { 221 Dimension d = super.getPreferredSize(); 222 int dpi = uif.getDotsPerInch(); 223 return new Dimension(Math.max(d.width, 5 * dpi), d.height); 224 } 225 }; 226 body.setName("nrd.body"); 227 body.setFocusable(false); 228 body.setLayout(new GridBagLayout()); 229 body.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 230 231 int dpi = uif.getDotsPerInch(); 232 233 GridBagConstraints lc = new GridBagConstraints(); 234 lc.anchor = GridBagConstraints.EAST; 235 lc.insets.right = 10; 236 lc.insets.bottom = 11; 237 lc.weighty = 0.0; 238 lc.weightx = 0.0; 239 lc.fill = GridBagConstraints.HORIZONTAL; 240 lc.gridwidth = 1; 241 242 // first row, directory name 243 JLabel dirLabel = uif.createLabel("nrd.dir", true); 244 body.add(dirLabel, lc); 245 246 dirField = uif.createInputField("nrd.dir.choice", dirLabel); 247 lc.weightx = 3.0; 248 body.add(dirField, lc); 249 250 browseBtn = uif.createButton("nrd.browse", listener); 251 browseBtn.setBorder(BorderFactory.createCompoundBorder( 252 BorderFactory.createEtchedBorder(), 253 BorderFactory.createEmptyBorder(0,3,0,3))); 254 lc.gridwidth = GridBagConstraints.REMAINDER; 255 lc.insets.left = 11; 256 lc.weightx = 0.0; 257 body.add(browseBtn, lc); 258 259 // second row, filter 260 lc.insets.left = 0; 261 lc.gridwidth = 1; 262 263 // add filter selector 264 if (filterHandler != null) { 265 JLabel filterLabel = uif.createLabel("nrd.filter", true); 266 body.add(filterLabel, lc); 267 268 JComponent selector = filterHandler.getFilterSelector(); 269 filterLabel.setLabelFor(selector); 270 lc.gridwidth = GridBagConstraints.REMAINDER; 271 lc.weightx = 4.0; 272 lc.anchor = GridBagConstraints.WEST; 273 lc.fill = GridBagConstraints.NONE; 274 body.add(selector, lc); 275 } 276 277 // third row, the tabs 278 lc.anchor = GridBagConstraints.NORTHWEST; 279 lc.gridwidth = GridBagConstraints.REMAINDER; 280 lc.fill = GridBagConstraints.BOTH; 281 lc.insets.bottom = 12; 282 lc.weighty = 1.0; 283 284 //------------------------------------------------------------------------ 285 286 JPanel middle = uif.createPanel("nrd.middle", false); 287 middle.setLayout(new BorderLayout()); 288 middle.setBorder(BorderFactory.createCompoundBorder( 289 uif.createTitledBorder("nrd.middle"), 290 BorderFactory.createEmptyBorder(12,12,12,12))); 291 292 panes = new JComponent[] { 293 createHtmlBlock(), 294 createFilesBlock(), 295 createKflBlock() 296 }; 297 298 tabs = uif.createTabbedPane("nrd.tabs", panes); 299 tabs.setTabPlacement(SwingConstants.TOP); 300 tabs.setBorder(BorderFactory.createEmptyBorder()); 301 302 listModel = new DefaultListModel<>(); 303 304 // populate list and card panel 305 final CardLayout cards = new CardLayout(); 306 final JPanel p = uif.createPanel("nrd.typecards", cards, false); 307 308 cbHtml = uif.createCheckBox("nrd.type.html", true); 309 //cbHtml.addActionListener(cbListener); 310 listModel.addElement(cbHtml); 311 p.add("nrd.type.html", tabs); 312 313 cbPlain = uif.createCheckBox("nrd.type.pt", true); 314 listModel.addElement(cbPlain); 315 p.add("nrd.type.pt", uif.createPanel("nrd.blank", false)); 316 317 cbXml = uif.createCheckBox("nrd.type.xml", false); 318 listModel.addElement(cbXml); 319 p.add("nrd.type.xml", uif.createPanel("nrd.blank", false)); 320 321 cbCof = uif.createCheckBox("nrd.type.cof", false); 322 listModel.addElement(cbCof); 323 324 JPanel cofpanel = createCofPane(); 325 p.add("nrd.type.cof", cofpanel); 326 327 getCustomReports(p); 328 329 list = uif.createList("nrd.typel", listModel); 330 list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 331 SelectListener sl = new SelectListener(list, p, cards); 332 list.addMouseListener(sl); 333 list.addKeyListener(sl); 334 list.addListSelectionListener(sl); 335 list.setCellRenderer(new CheckBoxListCellRenderer()); 336 list.setBorder(BorderFactory.createCompoundBorder( 337 BorderFactory.createEtchedBorder(), 338 BorderFactory.createEmptyBorder(0,3,0,3))); 339 340 infoArea = uif.createMessageArea("nrd.info"); 341 infoArea.setRows(3); 342 Font f = infoArea.getFont(); 343 f = f.deriveFont(Font.PLAIN, f.getSize2D()-1); 344 infoArea.setFont(f); 345 346 // create container for right side (next to list) 347 JPanel right = uif.createPanel("nrd.rptright", false); 348 right.setLayout(new BorderLayout()); 349 right.add(infoArea, BorderLayout.PAGE_START); 350 right.add(p, BorderLayout.CENTER); 351 middle.add(right, BorderLayout.CENTER); 352 353 JScrollPane listPane = uif.createScrollPane(list); 354 355 middle.add(listPane, BorderLayout.WEST); 356 body.add(middle, lc); 357 //----------------------------------------------------------------- 358 359 Action listMnemonics = new AbstractAction() { 360 361 public void actionPerformed(ActionEvent e) { 362 int ord; 363 try { 364 ord = Integer.parseInt(e.getActionCommand()) - 1; 365 } catch (Exception ex) { 366 // ignore 367 return; 368 } 369 if (ord == -1) ord = 9; 370 if (ord <= list.getModel().getSize()) { 371 list.requestFocusInWindow(); 372 list.setSelectedIndex(ord); 373 } 374 } 375 376 }; 377 378 list.getActionMap().put(ACTION_MAP_KEY, listMnemonics); 379 380 int itemCount = listModel.size(); 381 if (itemCount > 9) itemCount = 9; 382 for (int i = 1; i <= itemCount; ++i) { 383 list.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(i + '0', InputEvent.ALT_DOWN_MASK), ACTION_MAP_KEY); 384 JCheckBox box = listModel.getElementAt(i - 1); 385 box.setMnemonic(i + '0'); 386 box.setText(Character.toString((char)('0' + i)) + " " + box.getText()); 387 } 388 389 if (listModel.size() == 10){ 390 list.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('0', InputEvent.ALT_DOWN_MASK), ACTION_MAP_KEY); 391 JCheckBox box = listModel.getElementAt(9); 392 box.setMnemonic('0'); 393 box.setText("0 " + box.getText()); 394 } 395 396 //----------------------------------------------------------------- 397 JPanel bottom = createBackupOpsPane(); 398 bottom.setBorder(BorderFactory.createCompoundBorder( 399 uif.createTitledBorder("nrd.backup"), 400 BorderFactory.createEmptyBorder(12,12,12,12))); 401 402 body.add(bottom, lc); 403 setBody(body); 404 //-------------------------------------------------------------------------------------- 405 406 okBtn = uif.createButton("nrd.ok", listener); 407 sl.setOkBtn(okBtn); 408 cancelBtn = uif.createCancelButton("nrd.cancel", listener); 409 JButton helpBtn = uif.createHelpButton("nrd.help","report.newReport.csh" ); 410 setButtons(new JButton[] { okBtn, cancelBtn, helpBtn }, cancelBtn); 411 412 list.setSelectedIndex(0); 413 setState(Report.getSettingsPrefs()); 414 } 415 416 /** 417 * Options for the HTML report. 418 */ 419 private JComponent createHtmlBlock() { 420 JPanel p = uif.createPanel("nrd.htmlops", new GridBagLayout(), 421 false); 422 p.setName("htmlops"); 423 GridBagConstraints gbc = new GridBagConstraints(); 424 gbc.fill = GridBagConstraints.NONE; 425 gbc.anchor = GridBagConstraints.WEST; 426 gbc.gridwidth = 2; 427 gbc.gridy = 0; 428 429 // info about this block of buttons 430 JTextArea info = uif.createMessageArea("nrd.htmlops"); 431 //info.setBorder(BorderFactory.createLineBorder(Color.black)); 432 p.add(info, gbc); 433 434 // checkboxes 435 // these are given settings here, but setting will be reloaded 436 // elsewhere before the user sees them 437 JCheckBox cb = uif.createCheckBox("nrd.htmlops.config", true); 438 cbConfig = cb; 439 cbConfig.addActionListener(cbHtmlListener); 440 htmlGroup.add(cb); 441 gbc.gridy = 1; 442 p.add(cb, gbc); 443 444 // question log 445 gbc.gridwidth = 1; 446 gbc.gridy = 2; 447 cb = cbQl = uif.createCheckBox("nrd.htmlops.ql", true); 448 configGroup.add(cb); 449 htmlGroup.add(cb); 450 p.add(uif.createHorizontalStrut(25), gbc); 451 p.add(cb, gbc); 452 453 // environment 454 gbc.gridy = 3; 455 cb = cbEnv = uif.createCheckBox("nrd.htmlops.env", false); 456 configGroup.add(cb); 457 htmlGroup.add(cb); 458 p.add(uif.createHorizontalStrut(25), gbc); 459 p.add(cb, gbc); 460 461 // standard values 462 gbc.gridy = 4; 463 cb = cbStd = uif.createCheckBox("nrd.htmlops.std", false); 464 configGroup.add(cb); 465 htmlGroup.add(cb); 466 p.add(uif.createHorizontalStrut(25), gbc); 467 p.add(cb, gbc); 468 469 // result summary 470 gbc.gridy = 5; 471 gbc.gridwidth = 2; 472 cb = cbResults = uif.createCheckBox("nrd.htmlops.res", true); 473 htmlGroup.add(cb); 474 p.add(cb, gbc); 475 476 // KFL summary 477 gbc.gridy = 6; 478 gbc.gridwidth = 2; 479 cb = cbKfl = uif.createCheckBox("nrd.htmlops.kfl", true); 480 htmlGroup.add(cb); 481 p.add(cb, gbc); 482 483 // keyword summary 484 cb = cbKws = uif.createCheckBox("nrd.htmlops.kw", true); 485 htmlGroup.add(cb); 486 gbc.gridy = 7; 487 p.add(cb, gbc); 488 489 JScrollPane sp = uif.createScrollPane(p, 490 ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, 491 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); 492 493 sp.setViewportBorder(BorderFactory.createCompoundBorder( 494 BorderFactory.createEmptyBorder(10, 5, 5, 5), 495 uif.createTitledBorder("nrd.htmlops") 496 )); 497 sp.addPropertyChangeListener("enabled", new PanelEnableListener(sp)); 498 return sp; 499 } 500 501 /** 502 * Options for the HTML report files. 503 */ 504 private JComponent createFilesBlock() { 505 JPanel p = uif.createPanel("nrd.htmlf", new GridBagLayout(), 506 false); 507 p.setName("htmlf"); 508 GridBagConstraints gbc = new GridBagConstraints(); 509 gbc.fill = GridBagConstraints.BOTH; 510 gbc.anchor = GridBagConstraints.WEST; 511 //gbc.gridx = 0; 512 gbc.gridwidth = 3; 513 gbc.gridy = 0; 514 515 // info about this block of buttons 516 JTextArea info = uif.createMessageArea("nrd.htmlf"); 517 //info.setBorder(BorderFactory.createLineBorder(Color.black)); 518 p.add(info, gbc); 519 520 // settings are given here, but settings will be reloaded 521 // elsewhere before the user sees them 522 523 // index.html and/or report.html 524 JLabel lab = uif.createLabel("nrd.htmlf.main", false); 525 gbc.gridy = 1; 526 p.add(lab, gbc); 527 528 gbc.gridwidth = 1; 529 gbc.gridy = 2; 530 JCheckBox cb = cbHtmlRpt = uif.createCheckBox("nrd.htmlf.rpt", true); 531 cbHtmlRpt.addActionListener(cbHtmlListener); 532 htmlGroup.add(cb); 533 p.add(uif.createHorizontalStrut(25), gbc); 534 gbc.gridwidth = 2; 535 p.add(cb, gbc); 536 537 gbc.gridy = 3; 538 gbc.gridwidth = 1; 539 cb = cbHtmlInd = uif.createCheckBox("nrd.htmlf.idx", false); 540 cbHtmlInd.addActionListener(cbHtmlListener); 541 htmlGroup.add(cb); 542 p.add(uif.createHorizontalStrut(25), gbc); 543 gbc.gridwidth = 2; 544 p.add(cb, gbc); 545 546 // pass, fail, error, notrun files 547 gbc.gridy = 4; 548 gbc.gridwidth = 3; 549 lab = uif.createLabel("nrd.htmlf.xtra", false); 550 p.add(lab, gbc); 551 552 gbc.gridy = 5; 553 cb = uif.createCheckBox("nrd.htmlf.pass", true); 554 htmlGroup.add(cb); 555 cbPass = cb; 556 gbc.gridwidth = 1; 557 p.add(uif.createHorizontalStrut(25), gbc); 558 p.add(cb, gbc); 559 560 cb = cbErr = uif.createCheckBox("nrd.htmlf.err", true); 561 htmlGroup.add(cb); 562 p.add(cb, gbc); 563 564 gbc.gridy = 6; 565 cb = cbFail = uif.createCheckBox("nrd.htmlf.fail", true); 566 htmlGroup.add(cb); 567 p.add(uif.createHorizontalStrut(25), gbc); 568 p.add(cb, gbc); 569 570 cb = cbNr = uif.createCheckBox("nrd.htmlf.nr", true); 571 htmlGroup.add(cb); 572 p.add(cb, gbc); 573 574 JScrollPane sp = uif.createScrollPane(p, 575 ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, 576 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); 577 578 sp.setViewportBorder(BorderFactory.createCompoundBorder( 579 BorderFactory.createEmptyBorder(10, 5, 5, 5), 580 uif.createTitledBorder("nrd.htmlf") 581 )); 582 583 sp.addPropertyChangeListener("enabled", new PanelEnableListener(sp)); 584 return sp; 585 } 586 587 /** 588 * Options for COF report 589 */ 590 private JPanel createCofPane() { 591 JPanel cofpanel = uif.createPanel("nrd.cofops"); 592 cofpanel.setLayout(new GridBagLayout()); 593 cbCofTestCases = uif.createCheckBox("nrd.cofops.allowtestcases", true); 594 GridBagConstraints cb = new GridBagConstraints(); 595 cb.anchor = GridBagConstraints.NORTHWEST; 596 cb.weightx = 1.; 597 cb.weighty = 1.; 598 cb.ipadx = 8; 599 cb.ipady = 8; 600 cofpanel.add(cbCofTestCases, cb); 601 cofpanel.addPropertyChangeListener("enabled", new PanelEnableListener(cofpanel)); 602 return cofpanel; 603 } 604 605 /** 606 * Options for the KFL report files. 607 */ 608 private JComponent createKflBlock() { 609 JPanel p = uif.createPanel("nrd.htmlkfl", new GridBagLayout(), 610 false); 611 p.setName("htmlkfl"); 612 GridBagConstraints gbc = new GridBagConstraints(); 613 gbc.fill = GridBagConstraints.BOTH; 614 gbc.anchor = GridBagConstraints.NORTHWEST; 615 //gbc.gridx = 0; 616 gbc.gridwidth = 3; 617 gbc.gridy = 0; 618 619 // info about this block of buttons 620 JTextArea info = uif.createMessageArea("nrd.htmlkfl"); 621 //info.setBorder(BorderFactory.createLineBorder(Color.black)); 622 p.add(info, gbc); 623 624 // settings are given here, but settings will be reloaded 625 // elsewhere before the user sees them 626 627 // general KFL options 628 JLabel lab = uif.createLabel("nrd.htmlkfl.ops", false); 629 gbc.gridy = 1; 630 p.add(lab, gbc); 631 632 gbc.gridwidth = 1; 633 gbc.gridy = 2; 634 635 JCheckBox cb = cbKflTc = uif.createCheckBox("nrd.htmlkfl.checktc", true); 636 cbKflTc.addActionListener(cbHtmlListener); 637 cbKflTc.setSelected(true); 638 kflGroup.add(cb); 639 p.add(uif.createHorizontalStrut(25), gbc); 640 gbc.gridwidth = 2; 641 p.add(cb, gbc); 642 643 // kfl file options 644 gbc.gridy = 3; 645 gbc.gridwidth = 3; 646 lab = uif.createLabel("nrd.htmlkfl.xtra", false); 647 p.add(lab, gbc); 648 649 gbc.gridy = 4; 650 gbc.gridwidth = 1; 651 652 cb = cbKflF2f = uif.createCheckBox("nrd.htmlkfl.f2f", true); 653 cbKflF2f.addActionListener(cbHtmlListener); 654 cbKflF2f.setSelected(true); 655 kflGroup.add(cb); 656 p.add(uif.createHorizontalStrut(25), gbc); 657 gbc.gridwidth = 2; 658 p.add(cb, gbc); 659 660 gbc.gridy = 5; 661 gbc.gridwidth = 1; 662 cb = cbKflF2e = uif.createCheckBox("nrd.htmlkfl.f2e", false); 663 cbKflF2e.addActionListener(cbHtmlListener); 664 cbKflF2e.setSelected(true); 665 htmlGroup.add(cb); 666 p.add(uif.createHorizontalStrut(25), gbc); 667 gbc.gridwidth = 2; 668 p.add(cb, gbc); 669 670 gbc.gridy = 6; 671 gbc.gridwidth = 1; 672 cb = cbKflMissing = uif.createCheckBox("nrd.htmlkfl.missing", false); 673 cbKflMissing.addActionListener(cbHtmlListener); 674 cbKflMissing.setSelected(true); 675 htmlGroup.add(cb); 676 p.add(uif.createHorizontalStrut(25), gbc); 677 gbc.gridwidth = 2; 678 p.add(cb, gbc); 679 680 JScrollPane sp = uif.createScrollPane(p, 681 ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, 682 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); 683 684 sp.setViewportBorder(BorderFactory.createCompoundBorder( 685 BorderFactory.createEmptyBorder(10, 5, 5, 5), 686 uif.createTitledBorder("nrd.htmlkfl") 687 )); 688 689 sp.addPropertyChangeListener("enabled", new PanelEnableListener(sp)); 690 return sp; 691 } 692 693 private JPanel createBackupOpsPane() { 694 JPanel p = uif.createPanel("nrd.backup", new GridBagLayout(), 695 false); 696 p.setName("backup"); 697 GridBagConstraints gbc = new GridBagConstraints(); 698 gbc.fill = GridBagConstraints.BOTH; 699 gbc.anchor = GridBagConstraints.WEST; 700 gbc.gridx = 0; 701 gbc.gridwidth = 3; 702 703 // info about this block of buttons 704 JTextArea info = uif.createMessageArea("nrd.backup"); 705 //info.setBorder(BorderFactory.createLineBorder(Color.black)); 706 p.add(info, gbc); 707 708 // checkboxes 709 // these are given settings here, but setting will be reloaded 710 // elsewhere before the user sees them 711 JCheckBox cb = cbBak = uif.createCheckBox("nrd.backup.bak", true); 712 cbBak.addChangeListener(new ChangeListener() { 713 public void stateChanged(ChangeEvent e) { 714 if (numBak != null) { 715 numBak.setEnabled(cbBak.isSelected()); 716 } 717 } 718 }); 719 p.add(cb, gbc); 720 721 gbc.gridwidth = 1; 722 gbc.gridy = 2; 723 gbc.gridx = GridBagConstraints.RELATIVE; 724 p.add(uif.createHorizontalStrut(25), gbc); 725 726 JLabel lab = uif.createLabel("nrd.backup.bak.level", true); 727 p.add(lab, gbc); 728 729 // backup levels 730 numBak = uif.createInputField("nrd.backup.bak.level", 2, lab); 731 gbc.insets.left = 12; 732 numBak.setText("1"); 733 734 Action action = new AbstractAction() { 735 public void actionPerformed(ActionEvent e) { 736 JTextField src = (JTextField) (e.getSource()); 737 String cmd = e.getActionCommand(); 738 char ch = cmd.charAt(0); 739 int savedDot = src.getCaret().getDot(); 740 int savedMark = src.getCaret().getMark(); 741 String savedText = src.getText(); 742 743 // reject all non-numeric chars 744 if (Character.isDigit(ch) && ch != '0') { 745 Action delegate = new javax.swing.text.DefaultEditorKit.InsertContentAction(); 746 delegate.actionPerformed(e); 747 748 String newText = src.getText(); 749 // reject new input if it leaves an invalid value, 750 // i.e. more than one digit (>9) 751 if (newText.length() > 1) { 752 src.setText(savedText); 753 } 754 } 755 } 756 }; 757 Keymap keymap = numBak.addKeymap("intField", numBak.getKeymap()); 758 keymap.setDefaultAction(action); 759 numBak.setKeymap(keymap); 760 761 p.add(numBak, gbc); 762 763 p.setMaximumSize(p.getPreferredSize()); 764 return p; 765 } 766 767 768 /** 769 * @return number of custom reports added 770 */ 771 private int getCustomReports(JPanel p) { 772 int result = 0; 773 774 ContextManager cm = model.getContextManager(); 775 if (cm == null) 776 return 0; 777 778 customReports = cm.getCustomReports(); 779 if (customReports == null || customReports.length == 0) { 780 customReports = null; 781 return 0; 782 } 783 784 customBoxes = new HashMap<>(); 785 786 for (int i = 0; i < customReports.length; i++) { 787 JCheckBox cb = new JCheckBox(customReports[i].getName()); 788 cb.setName(customReports[i].getReportId()); 789 listModel.addElement(cb); 790 customBoxes.put(cb, customReports[i]); 791 792 ReportConfigPanel[] ops = customReports[i].getOptionPanes(); 793 if (ops == null || ops.length == 0) { 794 // no config panels, use blank 795 p.add(customReports[i].getReportId(), 796 uif.createPanel("nrd.blank", false)); 797 } 798 else { 799 // tabbed pane for all supplied panels 800 JTabbedPane tp = uif.createTabbedPane("nrd.custom.tabs"); 801 for (int j = 0; j < ops.length; j++) 802 tp.addTab(ops[j].getPanelName(), ops[j]); 803 804 p.add(customReports[i].getReportId(), tp); 805 } 806 result++; 807 } // for 808 809 return result; 810 } 811 812 813 /** 814 * Walks through the list of check boxes. 815 * @return false iff none of check boxes is selected, true otherwise 816 */ 817 private boolean hasSelectedCheckBox() { 818 for (int i = 0; i < listModel.getSize(); i++) { 819 if (((JCheckBox)listModel.getElementAt(i)).isSelected()) { 820 return true; 821 } 822 } 823 return false; 824 } 825 826 827 private void showReportChooserDialog() { 828 ReportDirChooser rdc = getReportDirChooser(); 829 rdc.setMode(ReportDirChooser.NEW); 830 int option = rdc.showDialog(dirField); 831 if (option != JFileChooser.APPROVE_OPTION) 832 return; 833 834 dirField.setText(rdc.getSelectedFile().getAbsolutePath()); 835 } 836 837 private ReportDirChooser getReportDirChooser() { 838 if (reportDirChooser == null) 839 reportDirChooser = new ReportDirChooser(); 840 return reportDirChooser; 841 } 842 843 void showReportBrowser(File f) { 844 if(f.equals(new File(reportDir, Report.INDEX_FILE_NAME))) { 845 reportBrowser.show(f); 846 } 847 else { 848 String[] names = Report.getHtmlReportFilenames(); 849 ArrayList<File> possible = new ArrayList<>(); 850 851 for (int i = 0; i < names.length; i++) { 852 File rpt = new File(reportDir, names[i]); 853 if (rpt.exists() && rpt.canRead()) 854 possible.add(rpt); 855 else 856 rpt = null; 857 } 858 859 if (possible.size() > 0) { 860 // show the most recently dated file 861 File rpt = null; 862 File newestF = null; 863 long newestTime = 0; 864 865 for (int i = 0; i < possible.size(); i++) { 866 File file = (File)(possible.get(i)); 867 if (file.lastModified() > newestTime) { 868 newestF = file; 869 newestTime = file.lastModified(); 870 } 871 } // for 872 reportBrowser.show(newestF); 873 } 874 else 875 reportBrowser.show(reportDir); 876 } 877 } 878 879 /** 880 * Normally called by the background thread. 881 */ 882 private void runReport(ReportSettings settings) throws IOException { 883 if (interviewParams != null) { 884 Report r = new Report(); 885 886 // if no work directory selected, throw exception. 887 if (interviewParams.getWorkDirectory() == null) { 888 throw new IOException(uif.getI18NString("nrd.noWorkDir.err")); 889 } 890 r.addStartGenListener(new ReportGenListener()); 891 settings.setCustomReports(getActiveCustomReports()); 892 r.writeReports(settings, reportDir ); 893 894 } 895 else { 896 throw new IOException(uif.getI18NString("nrd.nullParams.err")); 897 } 898 } 899 900 private ArrayList<CustomReport> getActiveCustomReports() { 901 902 ArrayList<CustomReport> customReps = new ArrayList<>(); 903 if (customBoxes != null && customBoxes.size() > 0) { 904 Iterator it = customBoxes.keySet().iterator(); 905 while (it.hasNext()) { 906 JCheckBox box = (JCheckBox)(it.next()); 907 if (box.isSelected()) { 908 customReps.add(customBoxes.get(box)); 909 } 910 } 911 } 912 return customReps; 913 } 914 915 private boolean isEmptyDirectory(File f) { 916 return (f.isDirectory() && f.list().length == 0); 917 } 918 919 private void updateHtmlCheckboxStates() { 920 // config buttons done before html buttons to ensure that 921 // config gets disabled if HTML reporting is off 922 923 if (!cbHtml.isSelected()) { 924 for (int i = 0; i < htmlGroup.size(); i++) 925 ((JCheckBox)(htmlGroup.get(i))).setEnabled(false); 926 } 927 else { 928 for (int i = 0; i < htmlGroup.size(); i++) 929 ((JCheckBox)(htmlGroup.get(i))).setEnabled(true); 930 for (int i = 0; i < configGroup.size(); i++) 931 ((JCheckBox)(configGroup.get(i))).setEnabled(cbConfig.isSelected()); 932 } 933 } 934 935 936 private void updateCofCheckboxStates() { 937 if (!cbCof.isSelected()) { 938 cbCofTestCases.setEnabled(false); 939 } else { 940 cbCofTestCases.setEnabled(true); 941 } 942 } 943 944 private ReportSettings captureState() { 945 ReportSettings snap = new ReportSettings(interviewParams); 946 947 snap.setEnableHtmlReport(cbHtml.isSelected()); 948 snap.setEnableXmlReport(cbXml.isSelected()); 949 snap.setEnablePlainReport(cbPlain.isSelected()); 950 snap.setEnableCOFReport(cbCof.isSelected()); 951 952 snap.setUseTestCases(cbCofTestCases.isSelected()); 953 954 snap.setShowConfigSection(cbConfig.isSelected()); 955 snap.setShowEnvLog(cbEnv.isSelected()); 956 snap.setShowQuestionLog(cbQl.isSelected()); 957 snap.setShowStdValues(cbStd.isSelected()); 958 snap.setShowResults(cbResults.isSelected()); 959 snap.setShowKflReport(cbKfl.isSelected()); 960 snap.setShowKeywordSummary(cbKws.isSelected()); 961 962 snap.setHtmlMainReport(cbHtmlRpt.isSelected(), cbHtmlInd.isSelected()); 963 snap.setEnableHtmlStateFile(Status.PASSED, cbPass.isSelected()); 964 snap.setEnableHtmlStateFile(Status.FAILED, cbFail.isSelected()); 965 snap.setEnableHtmlStateFile(Status.ERROR, cbErr.isSelected()); 966 snap.setEnableHtmlStateFile(Status.NOT_RUN, cbNr.isSelected()); 967 968 snap.setEnableKflF2e(cbKflF2e.isSelected()); 969 snap.setEnableKflF2f(cbKflF2f.isSelected()); 970 snap.setEnableKflMissing(cbKflMissing.isSelected()); 971 snap.setEnableKflTestCases(cbKflTc.isSelected()); 972 973 snap.setEnableBackups(cbBak.isSelected()); 974 975 try { 976 int i = Integer.parseInt(numBak.getText()); 977 snap.setBackupLevels(i); 978 } 979 catch (NumberFormatException e) { 980 } 981 982 TestFilter filter = filterHandler.getActiveFilter(); 983 984 // see Report.Settings for info on what this is: 985 /* 986 // commented out because Optimization will be enforced 987 // when filter is ParameterFilter 988 if (filter instanceof ParameterFilter) 989 snap.setAllowInitFilesOptimize(true); 990 else 991 snap.setAllowInitFilesOptimize(false); 992 */ 993 994 snap.setFilter(filter); 995 996 return snap; 997 } 998 999 private void setState(ReportSettings snap) { 1000 if (snap == null) 1001 return; 1002 1003 lastSettings = snap; 1004 1005 1006 cbHtml.setSelected(snap.isHtmlEnabled()); 1007 cbXml.setSelected(snap.isXmlEnabled()); 1008 cbPlain.setSelected(snap.isPlainEnabled()); 1009 boolean isCofEnabled = snap.isCOFEnabled(); 1010 cbCof.setSelected(isCofEnabled); 1011 1012 cbCofTestCases.setSelected(snap.isCOFTestCasesEnabled()); 1013 cbCofTestCases.setEnabled(isCofEnabled); 1014 1015 // --- 1016 boolean section = snap.isConfigSectionEnabled(); 1017 cbConfig.setSelected(section); 1018 1019 cbEnv.setSelected(snap.isEnvEnabled()); 1020 cbQl.setSelected(snap.isQuestionLogEnabled()); 1021 cbStd.setSelected(snap.isStdEnabled()); 1022 1023 cbEnv.setEnabled(section); 1024 cbQl.setEnabled(section); 1025 cbStd.setEnabled(section); 1026 1027 // --- 1028 cbResults.setSelected(snap.isResultsEnabled()); 1029 cbKfl.setSelected(snap.isKflEnabled()); 1030 cbKws.setSelected(snap.isKeywordSummaryEnabled()); 1031 1032 cbHtmlRpt.setSelected(snap.isReportHtmlEnabled()); 1033 cbHtmlInd.setSelected(snap.isIndexHtmlEnabled()); 1034 cbPass.setSelected(snap.isStateFileEnabled(Status.PASSED)); 1035 cbFail.setSelected(snap.isStateFileEnabled(Status.FAILED)); 1036 cbErr.setSelected(snap.isStateFileEnabled(Status.ERROR)); 1037 cbNr.setSelected(snap.isStateFileEnabled(Status.NOT_RUN)); 1038 1039 cbKflF2e.setSelected(snap.isKflF2eEnabled()); 1040 cbKflF2f.setSelected(snap.isKflF2fEnabled()); 1041 cbKflMissing.setSelected(snap.isKflMissingEnabled()); 1042 cbKflTc.setSelected(snap.isKflTestCasesEnabled()); 1043 1044 cbBak.setSelected(snap.isBackupsEnabled()); 1045 numBak.setText(Integer.toString(snap.getBackupLevel())); 1046 1047 // a null value will be ignored 1048 filterHandler.setFilter(snap.getTestFilter()); 1049 } 1050 1051 private ActionListener cbHtmlListener = new ActionListener() { 1052 public void actionPerformed(ActionEvent e) { 1053 Object src = e.getSource(); 1054 1055 if (src == cbHtml || src == cbConfig) 1056 updateHtmlCheckboxStates(); 1057 else if (src == cbBak) { 1058 numBak.setEnabled(cbBak.isSelected()); 1059 } else if (src == cbCof) 1060 updateCofCheckboxStates(); 1061 } 1062 }; 1063 1064 private ActionListener listener = new ActionListener() { 1065 public void actionPerformed(ActionEvent e) { 1066 Object src = e.getSource(); 1067 1068 if (src == browseBtn) { 1069 showReportChooserDialog(); 1070 } 1071 else if (src == cancelBtn) { 1072 // revert settings 1073 // hide dialog 1074 setVisible(false); 1075 1076 setState(lastSettings); 1077 if (okBtn != null) { 1078 okBtn.setEnabled(hasSelectedCheckBox()); 1079 } 1080 } 1081 else if (src == okBtn) { 1082 String s = (String) dirField.getText(); 1083 1084 // check null input 1085 if (s == null || s.length() == 0) { 1086 uif.showError("nrd.emptyInput"); 1087 return; 1088 } 1089 1090 // check for empty input 1091 if (cbBak.isSelected() && numBak.getText().equals("")) { 1092 uif.showError("nrd.emptyBak"); 1093 // select the last tab (assumes this has the backup settings) 1094 tabs.setSelectedIndex(tabs.getTabCount()-1); 1095 return; 1096 } 1097 1098 // validate custom reports 1099 Iterator it = getActiveCustomReports().iterator(); 1100 while (it.hasNext()) { 1101 CustomReport cr = (CustomReport) it.next(); 1102 String error = cr.validateOptions(); 1103 if (error != null) { 1104 for (int i = 0; i < listModel.getSize(); i++ ) { 1105 JCheckBox cb = listModel.elementAt(i); 1106 if (cb.getName().equals(cr.getReportId())) { 1107 list.setSelectedIndex(i); 1108 } 1109 } 1110 uif.showError("nrd.optionsErr", new Object[] {error} ); 1111 return; 1112 } 1113 } 1114 1115 reportDir = new File(s); 1116 1117 try { 1118 // check if dir needs to be created. 1119 if (!reportDir.isDirectory()) { 1120 reportDir.mkdirs(); 1121 } 1122 else { 1123 // check if dir is a report dir 1124 if (!Report.isReportDirectory(reportDir) && 1125 !isEmptyDirectory(reportDir)) { 1126 uif.showError("nrd.cantUse", reportDir); 1127 return; 1128 } 1129 } 1130 1131 // XXX save settings in prefs 1132 1133 setVisible(false); 1134 lastSettings = captureState(); 1135 notifyStarting(); 1136 doBgReport(lastSettings); 1137 } 1138 catch (SecurityException se) { 1139 uif.showError("nrd.cantCreate", se.getMessage()); 1140 } 1141 } 1142 } 1143 1144 // does work on background thread 1145 private void doBgReport(final ReportSettings snap) { 1146 /*final JDialog*/ waitDialog = uif.createWaitDialog("nrd.wait", parent); 1147 1148 final Stopper stopper = new Stopper(); 1149 final Thread worker = new Thread() { 1150 public void run() { 1151 try { 1152 runReport(snap); 1153 // go away to switch back to GUI thread 1154 finishReport(waitDialog, snap, stopper); 1155 } 1156 catch (CustomReport.ReportException ie) { 1157 showError("nrd.custom", ie.getMessage(), waitDialog); 1158 notifyError(ie.getMessage()); 1159 } 1160 catch (IOException ie) { 1161 showError("nrd.cantWrite", ie.getMessage(), waitDialog); 1162 notifyError(ie.getMessage()); 1163 // should reshow dialog 1164 } 1165 catch (SecurityException se) { 1166 showError("nrd.cantCreate", se.getMessage(), waitDialog); 1167 notifyError(se.getMessage()); 1168 // should reshow dialog 1169 } 1170 catch (RuntimeException re) { 1171 showError("nrd.errorWriting", re.getMessage(), waitDialog); 1172 notifyErrorWriting(re.getMessage()); 1173 } 1174 } // run() 1175 }; // thread 1176 1177 // this code is copied from ReportTool.... 1178 GridBagConstraints gbc = new GridBagConstraints(); 1179 gbc.fill = GridBagConstraints.NONE; 1180 gbc.anchor = GridBagConstraints.CENTER; 1181 gbc.insets.bottom = 10; 1182 gbc.insets.top = 10; 1183 gbc.gridy = 2; 1184 gbc.gridx = 0; 1185 JButton cancelBtn = uif.createButton("nrd.cancel"); 1186 waitDialog.getContentPane().add(cancelBtn, gbc); 1187 waitDialog.pack(); 1188 final String cancelling = uif.getI18NString("nrd.cancelling"); 1189 cancelBtn.addActionListener( new ActionListener() { 1190 public void actionPerformed(ActionEvent e) { 1191 JButton butt = (JButton) e.getSource(); 1192 butt.setEnabled(false); 1193 Component[] cmp = waitDialog.getContentPane().getComponents(); 1194 if (worker != null && worker.isAlive()) { 1195 stopper.waitWasHidden = true; 1196 worker.interrupt(); 1197 } 1198 for ( int i = 0; i < cmp.length; i++) { 1199 if("nrd.wait".equals(cmp[i].getName())) { 1200 if (cmp[i] instanceof JTextComponent) { 1201 ((JTextComponent)cmp[i]).setText(cancelling); 1202 } 1203 break; 1204 } 1205 } 1206 1207 } 1208 }); 1209 1210 1211 1212 1213 ActionListener al = new ActionListener() { 1214 public void actionPerformed(ActionEvent evt) { 1215 // show dialog if still processing 1216 if (worker.isAlive()) { 1217 waitDialog.show(); 1218 } 1219 } 1220 }; 1221 1222 // show wait dialog if operation is still running after 1223 // WAIT_DIALOG_DELAY 1224 Timer timer = new Timer(WAIT_DIALOG_DELAY, al); 1225 timer.setRepeats(false); 1226 timer.start(); 1227 1228 // do it! 1229 worker.start(); 1230 } 1231 1232 private void finishReport(final JDialog waitDialog, 1233 final ReportSettings snap, final Stopper stopper) { 1234 // done generating report, switch back to GUI thread 1235 EventQueue.invokeLater(new Runnable() { 1236 public void run() { 1237 waitDialog.hide(); 1238 if(!stopper.waitWasHidden) { 1239 int r = uif.showYesNoDialog("nrd.showReport"); 1240 1241 switch (r) { 1242 case JOptionPane.YES_OPTION: 1243 File index = new File(reportDir, Report.INDEX_FILE_NAME); 1244 if(index.exists() && index.canRead()) { 1245 showReportBrowser(index); 1246 } 1247 else { 1248 showReportBrowser(selectFileToShow(snap)); 1249 } 1250 break; 1251 case JOptionPane.NO_OPTION: 1252 break; 1253 default: 1254 break; 1255 } 1256 } 1257 1258 notifyDone(); 1259 notifyUpdate(getLastState()); 1260 } 1261 } 1262 ); 1263 } 1264 1265 1266 /** 1267 * @param uiKey Key to use to call <tt>UIFactory.showError()</tt> 1268 * @param msg The localized error message to show. 1269 */ 1270 private void showError(final String uiKey, final String msg, 1271 final JDialog waitDialog) { 1272 // switch back to GUI thread 1273 EventQueue.invokeLater(new Runnable() { 1274 public void run() { 1275 waitDialog.hide(); 1276 uif.showError(uiKey, msg); 1277 } 1278 } 1279 ); 1280 } 1281 1282 /** 1283 * Decide which file in the report dir to show to the user when 1284 * they ask to view a generated 'report'. 1285 */ 1286 private File selectFileToShow(ReportSettings snap) { 1287 File result = new File(reportDir, Report.INDEX_FILE_NAME); 1288 1289 if(!result.exists()) { 1290 if (snap.isHtmlEnabled()) { 1291 // show main report file or file listing 1292 result = searchForFile(reportDir, Report.getHtmlReportFilenames()); 1293 if (result == null) 1294 result = reportDir; 1295 } 1296 /* not useful right now to see raw xml, could do XSLT later 1297 else if (snap.isPlainEnabled()) { 1298 // show that file 1299 result = searchForFile(reportDir, Report.getPlainReportFilenames()); 1300 if (result == null) 1301 result = reportDir; 1302 } 1303 else if (snap.isXmlEnabled()) { 1304 result = new File(reportDir, "xml"); 1305 } 1306 */ 1307 else { 1308 result = reportDir; 1309 } 1310 } 1311 1312 return result; 1313 } 1314 1315 private File searchForFile(File dir, String[] names) { 1316 for (int i = 0; i < names.length; i++) { 1317 File f = new File(reportDir, names[i]); 1318 if (f.exists()) { 1319 return f; 1320 } 1321 } // for 1322 1323 return null; 1324 } 1325 }; 1326 1327 1328 //------------------------------end of listener-------------------------- 1329 1330 private static class Stopper { 1331 boolean waitWasHidden = false; 1332 } 1333 1334 private class ReportGenListener implements StartGenListener { 1335 public void startReportGeneration(ReportSettings s, String reportID) { 1336 String reportName; 1337 if(reportID.equals("xml") || reportID.equals("pt") || 1338 reportID.equals("html")) { 1339 reportName = uif.getI18NString("nrd.type." + reportID + ".ckb"); 1340 } 1341 else { 1342 reportName = reportID; 1343 } 1344 1345 String status = uif.getI18NString("nrd.wait.report_gen", 1346 new String[] {reportName}); 1347 1348 Component[] cmp = waitDialog.getContentPane().getComponents(); 1349 for ( int i = 0; i < cmp.length; i++) { 1350 if("nrd.wait".equals(cmp[i].getName())) { 1351 if (cmp[i] instanceof JTextComponent) { 1352 ((JTextComponent)cmp[i]).setText(status); 1353 } 1354 break; 1355 } 1356 } 1357 } 1358 } 1359 1360 /** 1361 * This listener changes options state against checkboxes 1362 */ 1363 private class SelectListener extends MouseInputAdapter implements KeyListener, ListSelectionListener { 1364 1365 /** 1366 * @param lst JList of checkboxes 1367 * @param p parent Panel 1368 * @param cardLayout The CardLayout for options 1369 */ 1370 SelectListener(JList lst, JPanel p, CardLayout cardLayout ) { 1371 list = lst; 1372 listModel = list.getModel(); 1373 lastSelected = listModel.getElementAt(0); 1374 panel = p; 1375 cards = cardLayout; 1376 } 1377 1378 public void keyTyped(KeyEvent e) { 1379 if (e.getKeyChar() == ' ') { 1380 process(list.getSelectedIndex()); 1381 } 1382 } 1383 1384 @Override 1385 public void mouseClicked(MouseEvent e) { 1386 if (e.getPoint().getX() <= emptyCBW) { 1387 process(list.locationToIndex(e.getPoint())); 1388 } 1389 } 1390 1391 public void valueChanged(ListSelectionEvent e) { 1392 int index = list.getSelectedIndex(); 1393 if (index < 0) { 1394 // no element selected in the list 1395 return; 1396 } 1397 JCheckBox box = (JCheckBox)(listModel.getElementAt(index)); 1398 1399 if (lastSelected != box) { 1400 cards.show(panel, box.getName()); 1401 lastSelected = box; 1402 } 1403 enablePanel(box); 1404 } 1405 1406 private void enablePanel(final JCheckBox box) { 1407 for (int i = 0; i < panel.getComponentCount(); i++) { 1408 JComponent tab = (JComponent) panel.getComponent(i); 1409 tab.setEnabled(box.isSelected()); 1410 } 1411 if (customBoxes != null) { 1412 CustomReport rep = (CustomReport) customBoxes.get(box); 1413 if (rep != null && rep.getOptionPanes() != null) { 1414 for (int i = 0; i < rep.getOptionPanes().length; i++) { 1415 rep.getOptionPanes()[i].setEnabled(box.isSelected()); 1416 } 1417 } else if (box == cbHtml) { 1418 for (int i = 0; i < panes.length; i++) { 1419 panes[i].setEnabled(box.isSelected()); 1420 } 1421 } 1422 } 1423 1424 if (box == cbHtml) 1425 infoArea.setText(uif.getI18NString("nrd.info.html.txt")); 1426 else if (box == cbPlain) 1427 infoArea.setText(uif.getI18NString("nrd.info.plain.txt")); 1428 else if (box == cbXml) 1429 infoArea.setText(uif.getI18NString("nrd.info.xml.txt")); 1430 else if (box == cbCof) 1431 infoArea.setText(uif.getI18NString("nrd.info.cof.txt")); 1432 else if (customBoxes != null) { 1433 CustomReport rep = (CustomReport) customBoxes.get(box); 1434 if (rep != null) 1435 infoArea.setText(rep.getDescription()); 1436 } 1437 1438 } 1439 1440 private void process(final int index) { 1441 if (index < 0) { 1442 return; 1443 } 1444 JCheckBox box = (JCheckBox)(listModel.getElementAt(index)); 1445 1446 if (lastSelected == box) { 1447 box.doClick(); 1448 if (okBtn != null) { 1449 okBtn.setEnabled(hasSelectedCheckBox()); 1450 } 1451 if (box == cbHtml) { 1452 updateHtmlCheckboxStates(); 1453 } 1454 if (box == cbCof) { 1455 updateCofCheckboxStates(); 1456 } 1457 list.repaint(); // important! 1458 enablePanel(box); 1459 } 1460 lastSelected = box; 1461 } 1462 1463 public void keyReleased(KeyEvent e) { 1464 } 1465 1466 public void keyPressed(KeyEvent e) { 1467 } 1468 1469 /** 1470 * Sets the button to change enable/disable state. If none of 1471 * check boxes is selected, the button will be disabled until a check 1472 * box is selected. 1473 * @param okBtn - button 1474 */ 1475 private void setOkBtn(JButton okBtn) { 1476 this.okBtn = okBtn; 1477 } 1478 1479 Object lastSelected; 1480 JList list; 1481 ListModel listModel; 1482 JPanel panel; 1483 CardLayout cards; 1484 JButton okBtn = null; // should be disable iff all check boxes are off 1485 double emptyCBW = new JCheckBox("").getPreferredSize().getWidth() + 2; 1486 } 1487 1488 /* 1489 * PropertyChangeListener for enabling/disabling container's content 1490 */ 1491 private class PanelEnableListener implements PropertyChangeListener { 1492 /** 1493 * @param container Container for controlling 1494 */ 1495 PanelEnableListener(Container container) { 1496 theContainer = container; 1497 } 1498 /** 1499 * Catches changes of "enabled" property 1500 * and changes enabled status for all child components 1501 */ 1502 public void propertyChange(PropertyChangeEvent evt) { 1503 if ("enabled".equals(evt.getPropertyName())) { 1504 boolean oldV = ((Boolean) evt.getOldValue()).booleanValue(); 1505 boolean newV = ((Boolean) evt.getNewValue()).booleanValue(); 1506 if (oldV && !newV) { 1507 // disable 1508 Iterator chIt = collectChildren(theContainer, new ArrayList<Component>()).iterator(); 1509 enabledComp = new HashSet<>(); 1510 while (chIt.hasNext()) { 1511 Component c = (Component) chIt.next(); 1512 if (c.isEnabled()) { 1513 enabledComp.add(c); 1514 c.setEnabled(false); 1515 } 1516 } 1517 1518 } else if (!oldV && newV && enabledComp != null) { 1519 // enable 1520 Iterator chIt = collectChildren(theContainer, new ArrayList<Component>()).iterator(); 1521 while (chIt.hasNext()) { 1522 Component c = (Component) chIt.next(); 1523 if (enabledComp.contains(c)) { 1524 c.setEnabled(true); 1525 } 1526 } 1527 } 1528 } 1529 } 1530 1531 /** 1532 * Recursively gathers all children components 1533 */ 1534 private Collection collectChildren(Container comp, Collection<Component> c) { 1535 Component [] ch = comp.getComponents(); 1536 for(int i = 0; i < ch.length; i++) { 1537 c.add(ch[i]); 1538 if (ch[i] instanceof Container) { 1539 collectChildren((Container) ch[i], c); 1540 } 1541 } 1542 return c; 1543 } 1544 1545 private Container theContainer; 1546 private HashSet<Component> enabledComp; 1547 } 1548 1549 private class CheckBoxListCellRenderer implements ListCellRenderer<JComponent> { 1550 public Component getListCellRendererComponent( 1551 JList<? extends JComponent> list, 1552 JComponent value, 1553 int index, 1554 boolean isSelected, 1555 boolean cellHasFocus) { 1556 // assert: value is a JCheckBox 1557 JComponent comp = value; 1558 if (isSelected) { 1559 comp.setOpaque(true); 1560 comp.setBackground(list.getSelectionBackground()); 1561 comp.setForeground(list.getSelectionForeground()); 1562 } 1563 else { 1564 comp.setOpaque(false); 1565 comp.setForeground(list.getForeground()); 1566 } 1567 1568 return comp; 1569 } 1570 } 1571 1572 private Observer[] obs = new Observer[0]; 1573 private ExecModel model; 1574 1575 private ReportDirChooser reportDirChooser; 1576 1577 private DefaultListModel<JCheckBox> listModel; 1578 private JList<? extends JComponent> list; 1579 private JTextArea infoArea; 1580 private CustomReport[] customReports; 1581 private HashMap<JCheckBox, CustomReport> customBoxes; 1582 1583 private JComponent[] panes; 1584 private JCheckBox cbHtml; 1585 private JCheckBox cbPlain; 1586 private JCheckBox cbXml; 1587 private JCheckBox cbCof; 1588 1589 private JCheckBox cbCofTestCases; 1590 1591 private JCheckBox cbConfig; 1592 private JCheckBox cbQl; 1593 private JCheckBox cbEnv; 1594 private JCheckBox cbStd; 1595 private JCheckBox cbKfl; 1596 private JCheckBox cbResults; 1597 private JCheckBox cbKws; 1598 1599 private JCheckBox cbPass; 1600 private JCheckBox cbFail; 1601 private JCheckBox cbErr; 1602 private JCheckBox cbNr; 1603 private JCheckBox cbHtmlRpt; 1604 private JCheckBox cbHtmlInd; 1605 1606 private JCheckBox cbKflTc; 1607 private JCheckBox cbKflF2f; 1608 private JCheckBox cbKflF2e; 1609 private JCheckBox cbKflMissing; 1610 1611 private JCheckBox cbBak; 1612 private JTextField numBak; 1613 1614 private ArrayList<JCheckBox> htmlGroup = new ArrayList<>(); 1615 private ArrayList<JCheckBox> configGroup = new ArrayList<>(); 1616 private ArrayList<JCheckBox> kflGroup = new ArrayList<>(); 1617 1618 private File reportDir; 1619 private JButton browseBtn; 1620 private JButton okBtn; 1621 private JButton cancelBtn; 1622 private JTextField dirField; 1623 1624 private JTabbedPane tabs; 1625 1626 private ReportSettings lastSettings; 1627 1628 private ReportBrowser reportBrowser; 1629 private InterviewParameters interviewParams; 1630 private FilterSelectionHandler filterHandler; 1631 1632 // keys for option values used for save & restore 1633 static final String REPORT_DIR = "reportDir"; 1634 private static final String FILTER = "filter"; 1635 private static final int WAIT_DIALOG_DELAY = 3000; // 3 second delay 1636 1637 private JDialog waitDialog; 1638 1639 }