1 /* 2 * $Id$ 3 * 4 * Copyright (c) 2002, 2011, 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 java.awt.BorderLayout; 30 import java.awt.Component; 31 import java.awt.Dimension; 32 import java.awt.Graphics; 33 import java.awt.GridBagConstraints; 34 import java.awt.GridBagLayout; 35 import java.awt.GridLayout; 36 import java.awt.event.ActionEvent; 37 import java.awt.event.ActionListener; 38 import java.awt.event.ItemEvent; 39 import java.awt.event.ItemListener; 40 import java.util.Arrays; 41 import java.util.HashSet; 42 import javax.swing.BorderFactory; 43 import javax.swing.Icon; 44 import javax.swing.JButton; 45 import javax.swing.JCheckBox; 46 import javax.swing.JComboBox; 47 import javax.swing.JComponent; 48 import javax.swing.JLabel; 49 import javax.swing.JList; 50 import javax.swing.JPanel; 51 import javax.swing.JPopupMenu; 52 import javax.swing.JScrollPane; 53 import javax.swing.JTextField; 54 import javax.swing.event.ChangeEvent; 55 import javax.swing.event.ChangeListener; 56 import javax.swing.event.ListSelectionEvent; 57 import javax.swing.event.ListSelectionListener; 58 import javax.swing.text.Caret; 59 60 import com.sun.javatest.InterviewParameters; 61 import com.sun.javatest.Keywords; 62 import com.sun.javatest.TestSuite; 63 import com.sun.javatest.Parameters.KeywordsParameters; 64 import com.sun.javatest.Parameters.MutableKeywordsParameters; 65 import com.sun.javatest.tool.UIFactory; 66 import com.sun.javatest.tool.jthelp.ContextHelpManager; 67 import java.awt.Container; 68 import java.awt.Dialog; 69 import java.awt.Frame; 70 import java.awt.Insets; 71 import java.awt.Point; 72 import java.awt.Toolkit; 73 import javax.swing.JDialog; 74 import javax.swing.WindowConstants; 75 76 /** 77 * Standard values, keyword pane. 78 */ 79 class CE_KeywordsPane extends CE_StdPane { 80 CE_KeywordsPane(UIFactory uif, InterviewParameters config) { 81 super(uif, config, "keywords"); 82 83 updateConfig(); 84 initGUI(); 85 } 86 87 boolean isOKToClose() { 88 if (mutableKeywordsParameters == null) 89 return true; 90 91 if (!selectCheck.isSelected()) 92 return true; 93 94 try { 95 TestSuite ts = config.getTestSuite(); 96 String[] validKeywords = ts.getKeywords(); 97 HashSet<String> validKeywordsSet; 98 if (validKeywords == null) 99 validKeywordsSet = null; 100 else 101 validKeywordsSet = new HashSet<String>(Arrays.asList(validKeywords)); 102 103 String kc = (String) (keywordsChoice.getSelectedItem()); 104 String type; 105 if (kc.equals(ANY_OF)) 106 type = Keywords.ANY_OF; 107 else if (kc.equals(ALL_OF)) 108 type = Keywords.ALL_OF; 109 else 110 type = Keywords.EXPR; 111 Keywords k = Keywords.create(type, keywordsField.getText(), 112 validKeywordsSet); 113 return true; 114 } catch (Keywords.Fault e) { 115 uif.showError("ce.keywords.invalid", e.getMessage()); 116 return false; 117 } 118 } 119 120 void updateConfig() { 121 // track interview changes 122 keywordsParameters = config.getKeywordsParameters(); 123 if (keywordsParameters != null 124 && keywordsParameters instanceof MutableKeywordsParameters) 125 mutableKeywordsParameters = (MutableKeywordsParameters) keywordsParameters; 126 else 127 mutableKeywordsParameters = null; 128 } 129 130 void load() { 131 updateConfig(); 132 133 // update GUI 134 if (mutableKeywordsParameters != null) { 135 selectCheck.setEnabled(true); 136 setEnabled(true); 137 int km = mutableKeywordsParameters.getKeywordsMode(); 138 selectCheck.setSelected(km == MutableKeywordsParameters.MATCH_KEYWORDS); 139 140 int kmm = mutableKeywordsParameters.getMatchKeywordsMode(); 141 switch (kmm) { 142 case MutableKeywordsParameters.ANY_OF: 143 keywordsChoice.setSelectedItem(ANY_OF); 144 break; 145 146 case MutableKeywordsParameters.ALL_OF: 147 keywordsChoice.setSelectedItem(ALL_OF); 148 break; 149 150 case MutableKeywordsParameters.EXPR: 151 keywordsChoice.setSelectedItem(EXPR); 152 break; 153 } 154 155 String kmv = mutableKeywordsParameters.getMatchKeywordsValue(); 156 keywordsField.setText(kmv == null ? "" : kmv); 157 } else if (keywordsParameters != null) { 158 setEnabled(true); 159 String expr = keywordsParameters.getKeywords().toString(); 160 selectCheck.setSelected(expr.length() == 0); 161 selectCheck.setEnabled(false); 162 163 keywordsChoice.setSelectedItem(EXPR); 164 keywordsField.setText(expr); 165 keywordsChoice.setEnabled(false); 166 } else { 167 setEnabled(false); // may be too late to hide tab 168 selectCheck.setEnabled(false); 169 170 keywordsChoice.setSelectedItem(EXPR); 171 keywordsField.setText(""); 172 keywordsChoice.setEnabled(false); 173 } 174 175 enableKeywordFields(); 176 } 177 178 void save() { 179 if (mutableKeywordsParameters != null) { 180 int km = (selectCheck.isSelected() 181 ? MutableKeywordsParameters.MATCH_KEYWORDS 182 : MutableKeywordsParameters.NO_KEYWORDS); 183 mutableKeywordsParameters.setKeywordsMode(km); 184 185 String kc = (String) (keywordsChoice.getSelectedItem()); 186 int kmm; 187 if (kc.equals(ANY_OF)) 188 kmm = MutableKeywordsParameters.ANY_OF; 189 else if (kc.equals(ALL_OF)) 190 kmm = MutableKeywordsParameters.ALL_OF; 191 else 192 kmm = MutableKeywordsParameters.EXPR; 193 mutableKeywordsParameters.setMatchKeywords(kmm, keywordsField.getText()); 194 } 195 } 196 197 private void initGUI() { 198 ContextHelpManager.setHelpIDString(this, "confEdit.keywordsTab.csh"); 199 200 JPanel p = uif.createPanel("ce.keywords", new BorderLayout(), false); 201 202 // ----- body ----- 203 JPanel body = uif.createPanel("ce.keywords.body", 204 new GridBagLayout(), 205 false); 206 body.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5)); 207 208 GridBagConstraints c = new GridBagConstraints(); 209 c.gridwidth = GridBagConstraints.REMAINDER; 210 c.fill = GridBagConstraints.HORIZONTAL; 211 c.weightx = 1; 212 213 selectCheck = uif.createCheckBox("ce.keywords.select"); 214 selectCheck.addChangeListener(listener); 215 body.add(selectCheck, c); 216 217 String[] kc = {ANY_OF, ALL_OF, EXPR}; 218 keywordsChoice = uif.createChoice("ce.keywords.choice", kc); 219 keywordsChoice.addItemListener(listener); 220 c.gridwidth = 1; 221 c.insets.left = 17; 222 c.weightx = 0; 223 body.add(keywordsChoice, c); 224 225 keywordsField = uif.createInputField("ce.keywords.field", 20); 226 uif.setAccessibleName(keywordsField, "ce.keywords.field"); 227 c.fill = GridBagConstraints.HORIZONTAL; 228 c.gridwidth = GridBagConstraints.REMAINDER; 229 c.insets.left = 0; 230 c.weightx = 1; 231 body.add(keywordsField, c); 232 233 p.add(body, BorderLayout.CENTER); 234 235 // ----- foot ----- 236 JPanel foot = uif.createPanel("ce.keywords.foot", 237 new GridBagLayout(), 238 false); 239 foot.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 240 241 Icon dropDownIcon = new DropDownIcon(); 242 243 c.anchor = GridBagConstraints.EAST; 244 c.fill = GridBagConstraints.NONE; 245 c.insets.left = 5; 246 c.gridwidth = 1; 247 keywordBtn = uif.createButton("ce.keywords.keyword", listener); 248 keywordBtn.setIcon(dropDownIcon); 249 keywordBtn.setHorizontalTextPosition(JLabel.LEADING); 250 foot.add(keywordBtn, c); 251 252 c.weightx = 0; 253 opBtn = uif.createButton("ce.keywords.op", listener); 254 opBtn.setIcon(dropDownIcon); 255 opBtn.setHorizontalTextPosition(JLabel.LEADING); 256 foot.add(opBtn, c); 257 p.add(foot, BorderLayout.SOUTH); 258 259 addBody(p); 260 261 String[] opItems = { AND, OR, NOT, PARENS }; 262 opPopup = uif.createPopupMenu("ce.keywords.op", opItems, listener); 263 264 keywords = config.getTestSuite().getKeywords(); 265 266 if (keywords != null) { 267 if (keywords.length == 0) { 268 // this test suite explicitly does not support keywords, 269 // so disable the entire pane 270 setEnabled(false); 271 } else { 272 // this test suite specifies valid keywords, 273 // so create a popup menu for them 274 keywordPopup = uif.createPopupMenu("ce.keywords.keyword"); 275 keywordChooser = false; 276 for (int i = 0; i < keywords.length; i++) 277 keywordPopup.add(uif.createLiteralMenuItem(keywords[i], listener)); 278 if (keywordPopup.getPreferredSize().getHeight() > (Toolkit.getDefaultToolkit().getScreenSize().height - 50)) { 279 keywordPopup = null; 280 keywordChooser = true; 281 } 282 } 283 } 284 } 285 286 private class KeywordChooser extends JDialog { 287 288 private JScrollPane sp; 289 private JList<String> lst; 290 private JButton ok, cancel; 291 292 KeywordChooser(Dialog parent, String [] keywords, Listener listener ) { 293 super(parent); 294 initUI(keywords, listener); 295 } 296 297 KeywordChooser(Frame parent, String [] keywords, Listener listener ) { 298 super(parent); 299 initUI(keywords, listener); 300 } 301 302 KeywordChooser(String [] keywords, Listener listener ) { 303 super(); 304 initUI(keywords, listener); 305 } 306 307 private void initUI(String [] keywords, final Listener listener ) { 308 GridBagConstraints gbc; 309 310 sp = new JScrollPane(); 311 lst = new JList<>(keywords); 312 313 ok = uif.createButton("keywordChooser.insert", new ActionListener() { 314 public void actionPerformed(ActionEvent e) { 315 Object[] sels = lst.getSelectedValues(); 316 String inserted = ""; 317 for (int i = 0; i < sels.length; i++) { 318 inserted += sels[i] + " "; 319 } 320 listener.insert(inserted.trim()); 321 lst.clearSelection(); 322 setVisible(false); 323 dispose(); 324 } 325 }); 326 327 328 cancel = uif.createButton("keywordChooser.cancel", new ActionListener() { 329 public void actionPerformed(ActionEvent e) { 330 lst.clearSelection(); 331 setVisible(false); 332 dispose(); 333 } 334 }) ; 335 336 JPanel btnP = new JPanel(); 337 btnP.setLayout(new GridLayout(1,2,5,0)); 338 btnP.add(cancel); 339 btnP.add(ok); 340 341 getContentPane().setLayout(new GridBagLayout()); 342 343 setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 344 345 setModal(true); 346 setUndecorated(true); 347 JPopupMenu samplePopup = new JPopupMenu(); 348 getRootPane().setBorder(samplePopup.getBorder()); 349 350 sp.setViewportView(lst); 351 lst.setBackground(samplePopup.getBackground()); 352 353 gbc = new GridBagConstraints(); 354 gbc.gridwidth = 2; 355 gbc.fill = GridBagConstraints.BOTH; 356 gbc.weightx = 1.0; 357 gbc.weighty = 1.0; 358 gbc.insets = new Insets(5, 5, 5, 5); 359 getContentPane().add(sp, gbc); 360 gbc = new GridBagConstraints(); 361 gbc.gridx = 1; 362 gbc.gridy = 1; 363 gbc.anchor = GridBagConstraints.SOUTHEAST; 364 gbc.insets = new Insets(0, 5, 5, 5); 365 getContentPane().add(btnP, gbc); 366 pack(); 367 Dimension s = getPreferredSize(); 368 s.height = (int) (Toolkit.getDefaultToolkit().getScreenSize().height * 0.75); 369 ok.setEnabled(false); 370 lst.addListSelectionListener(new ListSelectionListener() { 371 public void valueChanged(ListSelectionEvent e) { 372 ok.setEnabled(lst.getSelectedIndex() != -1); 373 } 374 }); 375 376 setSize(s); 377 } 378 379 private void setLocationRelativeToXY(Component xC, Component yC) { 380 setLocationRelativeTo(xC); 381 Point xP = getLocation(); 382 setLocationRelativeTo(yC); 383 Point yP = getLocation(); 384 setLocation(new Point(xP.x, yP.y)); 385 } 386 387 } 388 389 390 private void enableKeywordFields() { 391 boolean b = selectCheck.isEnabled() && selectCheck.isSelected(); 392 keywordsChoice.setEnabled(b); 393 keywordsField.setEnabled(b); 394 opBtn.setEnabled(b && keywordsChoice.getSelectedItem().equals(EXPR)); 395 keywordBtn.setEnabled(b && (keywordPopup != null || keywordChooser)); 396 } 397 398 private KeywordsParameters keywordsParameters; 399 private MutableKeywordsParameters mutableKeywordsParameters; 400 private JCheckBox selectCheck; 401 private JComboBox keywordsChoice; 402 private JTextField keywordsField; 403 private JButton keywordBtn; 404 private JPopupMenu keywordPopup; 405 private JButton opBtn; 406 private JPopupMenu opPopup; 407 private Listener listener = new Listener(); 408 409 private static final String ALL_OF = "allOf"; 410 private static final String ANY_OF = "anyOf"; 411 private static final String EXPR = "expr"; 412 private static final String IGNORE = "ignore"; 413 414 private static final String AND = "and"; 415 private static final String OR = "or"; 416 private static final String NOT = "not"; 417 private static final String PARENS = "parens"; 418 419 private boolean keywordChooser; 420 private String[] keywords; 421 422 private class Listener 423 implements ActionListener, ChangeListener, ItemListener { 424 // ---------- ActionListener ----------------------------------- 425 426 public void actionPerformed(ActionEvent e) { 427 Component src = (Component) (e.getSource()); 428 String cmd = e.getActionCommand(); 429 if (src == keywordBtn) { 430 if (keywordPopup != null) { 431 show(keywordBtn, keywordPopup); 432 } else if (keywordChooser) { 433 KeywordChooser kc; 434 Container parent = toolDialog.getDialogParent(); 435 if (parent instanceof Dialog) { 436 kc = new KeywordChooser((Dialog)parent, keywords, listener); 437 } 438 else if (parent instanceof Frame) { 439 kc = new KeywordChooser((Frame)parent, keywords, listener); 440 } 441 else { 442 kc = new KeywordChooser(keywords, listener); 443 } 444 kc.setLocationRelativeToXY(keywordBtn, CE_KeywordsPane.this); 445 kc.setVisible(true); 446 } 447 } 448 else if (src == opBtn) 449 show(opBtn, opPopup); 450 else if (cmd.equals(AND)) 451 insert("&"); 452 else if (cmd.equals(OR)) 453 insert("|"); 454 else if (cmd.equals(NOT)) 455 insert("!"); 456 else if (cmd.equals(PARENS)) { 457 insert("()"); 458 keywordsField.setCaretPosition(keywordsField.getCaretPosition() - 1); 459 } else if (src.getParent() == keywordPopup) 460 insert(cmd); 461 } 462 463 // show a popup menu relative to its invoking button 464 private void show(Component ref, JPopupMenu menu) { 465 menu.show(ref, 0, ref.getHeight()); 466 } 467 468 // insert text into the keywords field 469 void insert(String s) { 470 if (s.length() == 0) 471 return; 472 473 String t = keywordsField.getText(); 474 475 Caret caret = keywordsField.getCaret(); 476 int p1 = Math.min(caret.getDot(), caret.getMark()); 477 int p2 = Math.max(caret.getDot(), caret.getMark()); 478 479 boolean needSpaceBefore = Character.isLetterOrDigit(s.charAt(0)) 480 && (p1 > 0) && Character.isLetterOrDigit(t.charAt(p1 - 1)); 481 if (needSpaceBefore) 482 s = " " + s; 483 484 boolean needSpaceAfter = Character.isLetterOrDigit(s.charAt(s.length() - 1)) 485 && (p2 < t.length()) && Character.isLetterOrDigit(t.charAt(p2)); 486 if (needSpaceAfter) 487 s = s + " "; 488 489 keywordsField.replaceSelection(s); 490 } 491 492 // ---------- ChangeListener ----------------------------------- 493 494 public void stateChanged(ChangeEvent e) { 495 enableKeywordFields(); 496 } 497 498 // ---------- ItemListener ----------------------------------- 499 500 public void itemStateChanged(ItemEvent e) { 501 enableKeywordFields(); 502 } 503 } 504 505 private static class DropDownIcon implements Icon { 506 507 public void paintIcon(Component c, Graphics g, int x, int y) { 508 JComponent component = (JComponent)c; 509 int iconWidth = getIconWidth(); 510 511 g.translate( x, y ); 512 g.setColor( component.isEnabled() ? 513 UIFactory.Colors.CONTROL_INFO.getValue() : 514 UIFactory.Colors.CONTROL_SHADOW.getValue() ); 515 g.drawLine( 0, 0, iconWidth - 1, 0 ); 516 g.drawLine( 1, 1, 1 + (iconWidth - 3), 1 ); 517 g.drawLine( 2, 2, 2 + (iconWidth - 5), 2 ); 518 g.drawLine( 3, 3, 3 + (iconWidth - 7), 3 ); 519 g.drawLine( 4, 4, 4 + (iconWidth - 9), 4 ); 520 521 g.translate( -x, -y ); 522 } 523 524 public int getIconWidth() { return 10; } 525 526 public int getIconHeight() { return 5; } 527 528 } 529 }