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.tool;
  28 
  29 import java.awt.Component;
  30 import java.awt.GridBagConstraints;
  31 import java.awt.GridBagLayout;
  32 import java.awt.event.ActionEvent;
  33 import java.awt.event.ActionListener;
  34 import java.util.Enumeration;
  35 import java.util.Map;
  36 import javax.swing.plaf.basic.BasicComboBoxRenderer;
  37 import javax.swing.Box;
  38 import javax.swing.ButtonGroup;
  39 import javax.swing.ButtonModel;
  40 import javax.swing.JCheckBox;
  41 import javax.swing.JComboBox;
  42 import javax.swing.JLabel;
  43 import javax.swing.JList;
  44 import javax.swing.JPanel;
  45 import javax.swing.JRadioButton;
  46 
  47 /**
  48  * Preferences for the desktop itself.
  49  */
  50 class DesktopPrefsPane extends PreferencesPane {
  51     DesktopPrefsPane(Desktop desktop, UIFactory uif) {
  52         this.desktop = desktop;
  53         this.uif = uif;
  54         setHelp("ui.prefs.appearance.csh");
  55         setLayout(new GridBagLayout());
  56         GridBagConstraints c = new GridBagConstraints();
  57         c.fill = GridBagConstraints.HORIZONTAL;
  58         c.gridwidth = GridBagConstraints.REMAINDER;
  59         c.weightx = 1;
  60         c.insets.bottom= 10; // set off subsequent entries
  61 
  62         //add(createDesktopStylePanel(), c);
  63         styleGrp = new ButtonGroup();  // to avoid NPE
  64 
  65         add(createToolTipsPanel(), c);
  66         add(createShutdownPanel(), c);
  67 
  68         c.fill = GridBagConstraints.BOTH;
  69         c.weighty = 1;
  70         add(Box.createVerticalGlue(), c);
  71     }
  72 
  73     public String getText() {
  74         return uif.getI18NString("dt.prefs.name");
  75     }
  76 
  77     @Override
  78     public void load(Map<String, String> m) {
  79         String styleName = m.get(Desktop.STYLE_PREF);
  80         if (styleName == null)
  81             styleName = Desktop.styleNames[desktop.getStyle()];
  82 
  83         for (Enumeration e = styleGrp.getElements(); e.hasMoreElements(); ) {
  84             JRadioButton rb = (JRadioButton)e.nextElement();
  85             if (rb.getActionCommand().equals(styleName)) {
  86                 rb.setSelected(true);
  87                 break;
  88             }
  89         }
  90         // tooltips
  91         String tipState = m.get(Desktop.TTIP_PREF);
  92         ttipsCheck.setSelected(tipState == null || tipState.equalsIgnoreCase("true"));
  93 
  94         boolean complete = false;       // used for delay and duration code
  95 
  96         String tipDelay = m.get(Desktop.TTIP_DELAY);
  97         try {
  98             int delay = Integer.parseInt(tipDelay);
  99 
 100             if (delay == Desktop.TTIP_DELAY_NONE) {
 101                 // no delay
 102                 ttDelay.setSelectedItem(tooltipDelays[0]);
 103                 complete = true;
 104             }
 105             else {
 106                 for (int i = 1; i < ttDelay.getItemCount(); i++) {
 107                     if ( ttDelay.getItemAt(i).intValue() == delay ) {
 108                         ttDelay.setSelectedIndex(i);
 109                         i = ttDelay.getItemCount(); // stop loop
 110                         complete = true;
 111                     }
 112                 }   // for
 113 
 114             }   // if/else
 115         }
 116         catch (NumberFormatException e) {
 117             complete = false;
 118         }
 119 
 120         ttDelay.setEnabled(ttipsCheck.isSelected());
 121         ttDuration.setEnabled(ttipsCheck.isSelected());
 122 
 123         // default
 124         if (!complete)
 125                 ttDelay.setSelectedIndex(1);
 126 
 127         complete = false;
 128         String tipDuration = m.get(Desktop.TTIP_DURATION);
 129         try {
 130             int duration = Integer.parseInt(tipDuration);
 131             if (duration == Desktop.TTIP_DURATION_FOREVER) {
 132                 // forever
 133                 ttDuration.setSelectedItem(tooltipDurations[tooltipDurations.length-1]);
 134                 complete = true;
 135             }
 136             else {
 137                 for (int i = 0; i < tooltipDurations.length-1; i++) {
 138                     if (duration == tooltipDurations[i].intValue()) {
 139                         ttDuration.setSelectedItem(tooltipDurations[i]);
 140                         complete = true;
 141                         i = tooltipDurations.length;    // stop loop
 142                     }
 143                 }   // for
 144             }   // if/else
 145         }   // try
 146         catch (NumberFormatException e) {
 147             complete = false;
 148         }   // catch
 149 
 150         // default
 151         if (!complete){
 152                 ttDuration.setSelectedItem(tooltipDurations[1]);
 153             }
 154 
 155         // make it happen
 156         syncTooltipPrefs();
 157 
 158         // save on exit
 159         String saveState = m.get(Desktop.SAVE_ON_EXIT_PREF);
 160         saveCheck.setSelected(saveState == null || "true".equalsIgnoreCase(saveState)); // true (null) by default
 161         String restoreState = m.get(Desktop.RESTORE_ON_START_PREF); // false by default
 162         restoreCheck.setSelected(restoreState == null || "true".equalsIgnoreCase(restoreState));
 163     }
 164 
 165     @Override
 166     public void save(Map<String, String> m) {
 167         ButtonModel bm = styleGrp.getSelection();
 168         if (bm != null) {
 169             String styleName = bm.getActionCommand();
 170             for (int i = 0; i < Desktop.styleNames.length; i++) {
 171                 if (styleName.equals(Desktop.styleNames[i])) {
 172                     desktop.setStyle(i);
 173                     m.put(Desktop.STYLE_PREF, styleName);
 174                     break;
 175                 }
 176             }
 177         }
 178 
 179         boolean tips = ttipsCheck.isSelected();
 180         m.put(Desktop.TTIP_PREF, String.valueOf(tips));
 181         desktop.setTooltipsEnabled(tips);
 182 
 183         int delay = getTooltipDelay();
 184         m.put(Desktop.TTIP_DELAY, Integer.toString(delay));
 185         desktop.setTooltipDelay(delay);
 186 
 187         int duration = getTooltipDuration();
 188         m.put(Desktop.TTIP_DURATION, Integer.toString(duration));
 189         desktop.setTooltipDuration(duration);
 190 
 191         m.put(Desktop.SAVE_ON_EXIT_PREF, String.valueOf(saveCheck.isSelected()));
 192         desktop.setSaveOnExit(saveCheck.isSelected());
 193 
 194         m.put(Desktop.RESTORE_ON_START_PREF, String.valueOf(restoreCheck.isSelected()));
 195         desktop.setRestoreOnStart(restoreCheck.isSelected());
 196 
 197         syncTooltipPrefs();
 198     }
 199 
 200     /**
 201      * Force the GUI and the actual settings to be synchronized.
 202      */
 203     private void syncTooltipPrefs() {
 204         boolean tips = ttipsCheck.isSelected();
 205         desktop.setTooltipsEnabled(tips);
 206 
 207         int delay = getTooltipDelay();
 208         desktop.setTooltipDelay(delay);
 209 
 210         int duration = getTooltipDuration();
 211         desktop.setTooltipDuration(duration);
 212     }
 213    /* MDI/SID views are removed
 214     private Component createDesktopStylePanel() {
 215         Box p = Box.createHorizontalBox();
 216         p.setBorder(uif.createTitledBorder("dt.prefs.style"));
 217         styleGrp = new ButtonGroup();
 218         for (int i = 0; i < Desktop.styleNames.length; i++) {
 219             String styleName = Desktop.styleNames[i];
 220             String uiKey = "dt.prefs." + styleName;
 221             JRadioButton b = uif.createRadioButton(uiKey, styleGrp);
 222             b.setActionCommand(styleName);
 223             p.add(b);
 224         }
 225         p.add(Box.createHorizontalGlue());
 226 
 227         return p;
 228     }
 229     */
 230 
 231     private Component createShutdownPanel() {
 232         Box p = Box.createVerticalBox();
 233         p.setBorder(uif.createTitledBorder("dt.prefs.shutdown"));
 234 
 235     saveCheck = uif.createCheckBox("dt.prefs.saveOnExit");
 236         p.add(saveCheck);
 237 
 238         restoreCheck = uif.createCheckBox("dt.prefs.restoreOnStart");
 239         p.add(restoreCheck);
 240 
 241         p.add(Box.createVerticalGlue());
 242         return p;
 243     }
 244 
 245     private Component createToolTipsPanel() {
 246         JPanel p = uif.createPanel("dt.prefs.tt", false);
 247 
 248         p.setLayout(new GridBagLayout());
 249         GridBagConstraints c = new GridBagConstraints();
 250         c.anchor = GridBagConstraints.WEST;
 251         c.ipadx = 3;
 252         c.ipady = 5;
 253         c.fill = GridBagConstraints.VERTICAL;
 254         c.insets.left = 3;
 255         c.insets.right = 3;
 256         c.insets.top = 2;
 257         c.insets.bottom = 2;
 258 
 259         p.setBorder(uif.createTitledBorder("dt.prefs.ttips"));
 260         ttipsCheck = uif.createCheckBox("dt.prefs.ttips");
 261         // override default name
 262         uif.setAccessibleName(ttipsCheck, "dt.prefs.ttips");
 263 
 264         ttipsCheck.addActionListener(new ActionListener() {
 265                 public void actionPerformed(ActionEvent e) {
 266                     boolean state = ttipsCheck.isSelected();
 267                     ttDelay.setEnabled(state);
 268                     ttDuration.setEnabled(state);
 269                 }
 270             });
 271         c.gridwidth = GridBagConstraints.REMAINDER;
 272         c.weightx = 1;
 273         p.add(ttipsCheck, c);
 274 
 275         loadTooltipResources();
 276 
 277         JLabel l = uif.createLabel("dt.prefs.ttDelay", true);
 278 
 279         ttDelay = uif.createChoice("dt.prefs.ttDelay", l);
 280         for (int i = 0; i < tooltipDelays.length; i++)
 281             ttDelay.addItem(tooltipDelays[i]);
 282 
 283         ttDelay.setSelectedItem(tooltipDelays[0]);
 284         ttDelay.setRenderer(new TipDelayRenderer());
 285 
 286         c.gridwidth = 1;
 287         c.weightx = 0;
 288         p.add(l, c);
 289 
 290         c.gridwidth = GridBagConstraints.REMAINDER;
 291         c.weightx = 1;
 292         p.add(ttDelay, c);
 293 
 294         l = uif.createLabel("dt.prefs.ttDuration", true);
 295 
 296         ttDuration = uif.createChoice("dt.prefs.ttDuration", l);
 297         for (int i = 0; i < tooltipDurations.length; i++)
 298             ttDuration.addItem(tooltipDurations[i]);
 299 
 300         ttDuration.setRenderer(new TipDurationRenderer());
 301         // nominate a reasonable choice
 302         ttDuration.setSelectedItem(tooltipDurations[
 303                 Math.max(tooltipDurations.length-2, 0)]);
 304 
 305         c.gridwidth = 1;
 306         c.weightx = 0;
 307         p.add(l, c);
 308 
 309         c.gridwidth = GridBagConstraints.REMAINDER;
 310         c.weightx = 1;
 311         p.add(ttDuration, c);
 312 
 313         return p;
 314     }
 315 
 316     private void loadTooltipResources() {
 317         tooltipDurations = new Integer[] { new Integer(1000),
 318                                            new Integer(2000),
 319                                            new Integer(3000),
 320                                            new Integer(5000),
 321                                            new Integer(10000),
 322                                            new Integer(15000),
 323                                            new Integer(-1) };
 324 
 325         tooltipDelays = new Integer[] { new Integer(0),
 326                                         new Integer(1000),
 327                                         new Integer(2000),
 328                                         new Integer(3000),
 329                                         new Integer(5000),
 330                                         new Integer(10000) };
 331     }
 332 
 333     /**
 334      * How long before a tooltip should be shown, as known by the GUI.
 335      * @return Zero for no delay, otherwise a delay in milliseconds.
 336      */
 337     private int getTooltipDelay() {
 338         Integer value = (Integer)(ttDelay.getSelectedItem());
 339         return value.intValue();
 340     }
 341 
 342     /**
 343      * How long tooltips should be shown, as known by the GUI.
 344      * @return <code>Desktop.TTIP_DURATION_FOREVER</code>, otherwise a duration in
 345      *         milliseconds.
 346      */
 347     private int getTooltipDuration() {
 348         int value = ((Integer) (ttDuration.getSelectedItem())).intValue();
 349         return (value < 0 ? Desktop.TTIP_DURATION_FOREVER : value);
 350     }
 351 
 352     private Desktop desktop;
 353     private UIFactory uif;
 354     private ButtonGroup styleGrp;
 355     private JCheckBox ttipsCheck;
 356     private JComboBox<Integer> ttDelay;
 357     private JComboBox<Integer> ttDuration;
 358     private JCheckBox saveCheck;
 359     private JCheckBox restoreCheck;
 360 
 361     private Integer[] tooltipDurations;
 362     private Integer[] tooltipDelays;
 363 
 364     // cache localized strings because renderers tend to run a lot
 365     private static String TIP_SHOW_FOREVER;
 366 
 367     private class TipDelayRenderer extends BasicComboBoxRenderer {
 368         @Override
 369         public Component getListCellRendererComponent(JList list,
 370                                               Object value,
 371                                               int index,
 372                                               boolean isSelected,
 373                                               boolean cellHasFocus) {
 374             Object theVal;
 375             if (value instanceof Integer) {
 376                 int val = ((Integer)value).intValue();
 377                 // convert to seconds and create localized text
 378                 theVal = uif.getI18NString("dt.prefs.ttDelay", new Integer(val/1000));
 379             }
 380             else {
 381                 theVal = value;
 382             }
 383 
 384             return super.getListCellRendererComponent(
 385                 list, theVal, index, isSelected, cellHasFocus);
 386         }
 387     }
 388 
 389     private class TipDurationRenderer extends BasicComboBoxRenderer {
 390         TipDurationRenderer() {
 391             synchronized (DesktopPrefsPane.this) {
 392                 if (TIP_SHOW_FOREVER  == null)
 393                     TIP_SHOW_FOREVER =
 394                         uif.getI18NString("dt.prefs.ttDuration.forev");
 395             }
 396         }
 397 
 398         @Override
 399         public Component getListCellRendererComponent(JList list,
 400                                               Object value,
 401                                               int index,
 402                                               boolean isSelected,
 403                                               boolean cellHasFocus) {
 404             Object theVal;
 405             if (value instanceof Integer) {
 406                 int val = ((Integer)value).intValue();
 407                 if (val > 0) {
 408                     // convert to seconds and create localized text
 409                     theVal = uif.getI18NString("dt.prefs.ttDuration.sec",
 410                                 new Integer(val/1000));
 411                 }
 412                 else
 413                     theVal = TIP_SHOW_FOREVER;
 414             }
 415             else {
 416                 theVal = value;
 417             }
 418 
 419             return super.getListCellRendererComponent(
 420                 list, theVal, index, isSelected, cellHasFocus);
 421         }
 422     }
 423 }