Package org.jmol.popup

Source Code of org.jmol.popup.SimplePopup$MenuItemListener

/* $RCSfile$
* $Author: hansonr $
* $Date: 2010-05-11 15:47:18 -0500 (Tue, 11 May 2010) $
* $Revision: 13064 $
*
* Copyright (C) 2000-2005  The Jmol Development Team
*
* Contact: jmol-developers@lists.sf.net
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library 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
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jmol.popup;

import org.jmol.api.*;
import org.jmol.util.Logger;
import org.jmol.util.TextFormat;

import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Enumeration;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Hashtable;
import java.util.List;
import java.util.ArrayList;

import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;

public class SimplePopup {

  //list is saved in http://www.stolaf.edu/academics/chemapps/jmol/docs/misc
  protected final static boolean dumpList = false;

  //public void finalize() {
  //  System.out.println("JmolPopup " + this + " finalize");
  //}

  protected JmolViewer viewer;
  protected Component display;
  protected MenuItemListener mil;
  protected CheckboxMenuItemListener cmil;
  protected boolean asPopup = true;

  protected Properties menuText = new Properties();
 
  protected String nullModelSetName, modelSetName;
  protected String modelSetFileName, modelSetRoot;
 
  protected Hashtable modelSetInfo, modelInfo;
  protected JPopupMenu frankPopup;

  protected Hashtable htMenus = new Hashtable();
  protected List NotPDB = new ArrayList();
  protected List PDBOnly = new ArrayList();
  protected List UnitcellOnly = new ArrayList();
  protected List SingleModelOnly = new ArrayList();
  protected List FramesOnly = new ArrayList();
  protected List VibrationOnly = new ArrayList();
  protected List SymmetryOnly = new ArrayList();
  protected List SignedOnly = new ArrayList();
  protected List AppletOnly = new ArrayList();
  protected List ChargesOnly = new ArrayList();
  protected List TemperatureOnly = new ArrayList();

  protected boolean isPDB;
  protected boolean isSymmetry;
  protected boolean isUnitCell;
  protected boolean isMultiFrame;
  protected boolean isLastFrame;
  protected boolean isMultiConfiguration;
  protected boolean isVibration;
  protected boolean isApplet;
  protected boolean isSigned;
  protected boolean isZapped;
  protected boolean haveCharges;
  protected boolean haveBFactors;
  protected String altlocs;

  protected int modelIndex, modelCount, atomCount;

  protected JPopupMenu swingPopup;

  SimplePopup(JmolViewer viewer) {
    this.viewer = viewer;
    asPopup = true;
    display = viewer.getDisplay();
    mil = new MenuItemListener();
    cmil = new CheckboxMenuItemListener();
  }

  private boolean isHorizontal = false;
 
  public SimplePopup(JmolViewer viewer, String title, PopupResource bundle, boolean isHorizontal) {
    this(viewer);
    this.isHorizontal = isHorizontal;
    build(title, swingPopup = new JPopupMenu(title), bundle);
  }

  private boolean allowSignedFeatures;
 
  protected void build(String title, Object popupMenu, PopupResource bundle) {
    if (isHorizontal && popupMenu instanceof JPopupMenu) {
      JPopupMenu pm = (JPopupMenu) popupMenu;
      //BoxLayout bl = new BoxLayout(pm, BoxLayout.LINE_AXIS);
      GridLayout bl = new GridLayout(3,4);
      pm.setLayout(bl);

    }
    htMenus.put(title, popupMenu);
    allowSignedFeatures = (!viewer.isApplet() || viewer.getBooleanProperty("_signedApplet"));
    addMenuItems("", title, popupMenu, bundle);
  }

  protected int thisx, thisy;

  public void show(int x, int y) {
    show(x, y, true);
  }

  protected void updateForShow() {
    // depends upon implementation
  }
 
  public void show(int x, int y, boolean doPopup) {
    thisx = x;
    thisy = y;
    updateForShow();
    for (Enumeration keys = htCheckbox.keys(); keys.hasMoreElements();) {
      String key = (String) keys.nextElement();
      Object item = htCheckbox.get(key);
      String basename = key.substring(0, key.indexOf(":"));
      boolean b = viewer.getBooleanProperty(basename);
      setCheckBoxState(item, b);
    }
    showPopupMenu(thisx, thisy);
  }

  static protected void addCurrentItem(StringBuffer sb, char type, int level, String name, String label, String script, String flags) {
    sb.append(type).append(level).append('\t').append(name);
    if(label == null) {
      sb.append(".\n");
      return;
    }
    sb.append("\t").append(label)
        .append("\t").append(script == null || script.length() == 0 ? "-" : script)
        .append("\t").append(flags)
        .append("\n");
  }

  final static int UPDATE_ALL = 0;
  final static int UPDATE_CONFIG = 1;
  final static int UPDATE_SHOW = 2;
  int updateMode;

  protected String getMenuText(String key) {
    String str = menuText.getProperty(key);
    return (str == null ? key : str);
  }

  boolean checkBoolean(Hashtable info, String key) {
    Object value = (info == null ? null : info.get(key));
    return !(value == null || value instanceof Boolean && !((Boolean) (value)).booleanValue());
  }

  protected void getViewerData() {
    isApplet = viewer.isApplet();
    isSigned = (viewer.getBooleanProperty("_signedApplet"));
    modelSetName = viewer.getModelSetName();
    modelSetFileName = viewer.getModelSetFileName();
    int i = modelSetFileName.lastIndexOf(".");
    isZapped = ("zapped".equals(modelSetName));
    if (isZapped || "string".equals(modelSetFileName)
        || "files".equals(modelSetFileName)
        || "string[]".equals(modelSetFileName))
      modelSetFileName = "";
    modelSetRoot = modelSetFileName.substring(0, i < 0 ? modelSetFileName.length() : i);
    if (modelSetRoot.length() == 0)
      modelSetRoot = "Jmol";
    modelIndex = viewer.getDisplayModelIndex();
    modelCount = viewer.getModelCount();
    atomCount = viewer.getAtomCountInModel(modelIndex);
    modelSetInfo = viewer.getModelSetAuxiliaryInfo();
    modelInfo = viewer.getModelAuxiliaryInfo(modelIndex);
    if (modelInfo == null)
      modelInfo = new Hashtable();
    isPDB = checkBoolean(modelSetInfo, "isPDB");
    isSymmetry = checkBoolean(modelInfo, "hasSymmetry");
    isUnitCell = checkBoolean(modelInfo, "notionalUnitcell");
    isMultiFrame = (modelCount > 1);
    isLastFrame = (modelIndex == modelCount - 1);
    altlocs = viewer.getAltLocListInModel(modelIndex);
    isMultiConfiguration = (altlocs.length() > 0);
    isVibration = (viewer.modelHasVibrationVectors(modelIndex));
    haveCharges = (viewer.havePartialCharges());
    haveBFactors = (viewer.getBooleanProperty("haveBFactors"));
  }

  void updateFileTypeDependentMenus() {
    for (int i = 0; i < NotPDB.size(); i++)
      enableMenu(NotPDB.get(i), !isPDB);
    for (int i = 0; i < PDBOnly.size(); i++)
      enableMenu(PDBOnly.get(i), isPDB);
    for (int i = 0; i < UnitcellOnly.size(); i++)
      enableMenu(UnitcellOnly.get(i), isUnitCell);
    for (int i = 0; i < SingleModelOnly.size(); i++)
      enableMenu(SingleModelOnly.get(i), isLastFrame);
    for (int i = 0; i < FramesOnly.size(); i++)
      enableMenu(FramesOnly.get(i), isMultiFrame);
    for (int i = 0; i < VibrationOnly.size(); i++)
      enableMenu(VibrationOnly.get(i), isVibration);
    for (int i = 0; i < SymmetryOnly.size(); i++)
      enableMenu(SymmetryOnly.get(i), isSymmetry && isUnitCell);
    for (int i = 0; i < SignedOnly.size(); i++)
      enableMenu(SignedOnly.get(i), isSigned || !isApplet);
    for (int i = 0; i < AppletOnly.size(); i++)
      enableMenu(AppletOnly.get(i), isApplet);
    for (int i = 0; i < ChargesOnly.size(); i++)
      enableMenu(ChargesOnly.get(i), haveCharges);
    for (int i = 0; i < TemperatureOnly.size(); i++)
      enableMenu(TemperatureOnly.get(i), haveBFactors);
  }

  private ButtonGroup group;

  protected void addMenuItems(String parentId, String key, Object menu,
                            PopupResource popupResourceBundle) {
    String id = parentId + "." + key;
    String value = popupResourceBundle.getStructure(key);
    //Logger.debug(id + " --- " + value);
    if (value == null) {
      addMenuItem(menu, "#" + key, "", "");
      return;
    }
    // process predefined @terms
    StringTokenizer st = new StringTokenizer(value);
    String item;
    while (value.indexOf("@") >= 0) {
      String s = "";
      while (st.hasMoreTokens())
        s += " " + ((item = st.nextToken()).startsWith("@")
            ? popupResourceBundle.getStructure(item) : item);
      value = s.substring(1);
      st = new StringTokenizer(value);
    }
    while (st.hasMoreTokens()) {
      item = st.nextToken();
      String label = popupResourceBundle.getWord(item);
      Object newMenu = null;
      String script = "";
      boolean isCB = false;
      if (label.equals("null")) {
        // user has taken this menu item out
        continue;
      } else if (item.indexOf("Menu") >= 0) {
        if (item.indexOf("more") < 0)
          group = null;
        Object subMenu = newMenu(label, id + "." + item);       
        addMenuSubMenu(menu, subMenu);
        htMenus.put(item, subMenu);
        if (item.indexOf("Computed") < 0)
          addMenuItems(id, item, subMenu, popupResourceBundle);
        checkSpecialMenu(item, subMenu, label);
        newMenu = subMenu;
      } else if ("-".equals(item)) {
        addMenuSeparator(menu);
        continue;
      } else if (item.endsWith("Checkbox") || (isCB = (item.endsWith("CB") || item.endsWith("RD")))) {
        // could be "PRD" -- set picking checkbox
        script = popupResourceBundle.getStructure(item);
        String basename = item.substring(0, item.length() - (!isCB ? 8 : 2));
        boolean isRadio = (isCB && item.endsWith("RD"));
        if (script == null || script.length() == 0 && !isRadio)
          script = "set " + basename + " T/F";
        newMenu = addCheckboxMenuItem(menu, label, basename
            + ":" + script, id + "." + item, isRadio);
        if (isRadio) {
          if (group == null)
            group = new ButtonGroup();
          group.add((JMenuItem) newMenu);
        }
      } else {
        script = popupResourceBundle.getStructure(item);
        if (script == null)
          script = item;
        newMenu = addMenuItem(menu, label, script, id + "." + item);
      }

      if (!allowSignedFeatures && item.startsWith("SIGNED"))
        enableMenu(newMenu, false);
      if (item.indexOf("VARIABLE") >= 0)
        htMenus.put(item, newMenu);
      // menus or menu items:
      if (item.indexOf("!PDB") >= 0) {
        NotPDB.add(newMenu);
      } else if (item.indexOf("PDB") >= 0) {
        PDBOnly.add(newMenu);
      }
      if (item.indexOf("URL") >= 0) {
        AppletOnly.add(newMenu);
      } else if (item.indexOf("CHARGE") >= 0) {
        ChargesOnly.add(newMenu);
      } else if (item.indexOf("BFACTORS") >= 0) {
        TemperatureOnly.add(newMenu);
      } else if (item.indexOf("UNITCELL") >= 0) {
        UnitcellOnly.add(newMenu);
      }
     
      if (item.indexOf("!FRAMES") >= 0) {
        SingleModelOnly.add(newMenu);
      } else if (item.indexOf("FRAMES") >= 0) {
        FramesOnly.add(newMenu);
      }
     
      if (item.indexOf("VIBRATION") >= 0) {
        VibrationOnly.add(newMenu);
      } else if (item.indexOf("SYMMETRY") >= 0) {
        SymmetryOnly.add(newMenu);
      }
      if (item.startsWith("SIGNED"))
        SignedOnly.add(newMenu);

      if (dumpList) {
        String str = item.endsWith("Menu") ? "----" : id + "." + item + "\t"
            + label + "\t" + fixScript(id + "." + item, script);
        str = "addMenuItem('\t" + str + "\t')";
        Logger.info(str);
      }
    }
  }

  protected void checkSpecialMenu(String item, Object subMenu, String word) {
    // special considerations here
  }

  protected Hashtable htCheckbox = new Hashtable();

  void rememberCheckbox(String key, Object checkboxMenuItem) {
    htCheckbox.put(key + "::" + htCheckbox.size(), checkboxMenuItem);
  }

  /**
   * (1) setOption --> set setOption true or set setOption false
   *
   * @param item
   *
   * @param what
   *          option to set
   * @param TF
   *          true or false
   */
  protected void setCheckBoxValue(JMenuItem item, String what, boolean TF) {
    if (what.indexOf("##") < 0) {
      int pt = what.indexOf(":");
      if (pt < 0) {
        Logger.error("check box " + item.getName() + " IS " + what);
        return;
      }
      // name:trueAction|falseAction
      String basename = what.substring(0, pt);
      if (viewer.getBooleanProperty(basename) == TF)
        return;
      if (basename.endsWith("P!")) {
        if (basename.indexOf("??") >= 0) {
          what = setCheckBoxOption(item, basename, what);
        } else {
          if (what == null)
            return;
          if (!TF)
            return;
          what = "set picking " + basename.substring(0, basename.length() - 2);
        }
      } else {
        what = what.substring(pt + 1);
        if ((pt = what.indexOf("|")) >= 0)
          what = (TF ? what.substring(0, pt) : what.substring(pt + 1)).trim();
        what = TextFormat.simpleReplace(what, "T/F", (TF ? " TRUE" : " FALSE"));
      }
    }
    viewer.evalStringQuiet(what);
  }

  protected String setCheckBoxOption(JMenuItem item, String name, String what) {
    return null;
  }

  String currentMenuItemId = null;

  class MenuItemListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      checkMenuClick(e.getSource(), e.getActionCommand());
    }
  }

  class CheckboxMenuItemListener implements ItemListener {
    public void itemStateChanged(ItemEvent e) {
      restorePopupMenu();
      setCheckBoxValue(e.getSource());
      String id = getId(e.getSource());
      if (id != null) {
        currentMenuItemId = id;
      }
      //Logger.debug("CheckboxMenuItemListener() " + e.getSource());
    }
  }

  protected String fixScript(String id, String script) {
    int pt;
    if (script == "" || id.endsWith("Checkbox"))
      return script;

    if (script.indexOf("SELECT") == 0) {
      return "select thisModel and (" + script.substring(6) + ")";
    }

    if ((pt = id.lastIndexOf("[")) >= 0) {
      // setSpin
      id = id.substring(pt + 1);
      if ((pt = id.indexOf("]")) >= 0)
        id = id.substring(0, pt);
      id = id.replace('_', ' ');
      if (script.indexOf("[]") < 0)
        script = "[] " + script;
      return TextFormat.simpleReplace(script, "[]", id);
    } else if (script.indexOf("?FILEROOT?") >= 0) {
      script = TextFormat.simpleReplace(script, "FILEROOT?", modelSetRoot);
    } else if (script.indexOf("?FILE?") >= 0) {
      script = TextFormat.simpleReplace(script, "FILE?", modelSetFileName);
    } else if (script.indexOf("?PdbId?") >= 0) {
      script = TextFormat.simpleReplace(script, "PdbId?", "=xxxx");
    }
    return script;
  }

  public void checkMenuClick(Object source, String script) {
    restorePopupMenu();
    if (script == null || script.length() == 0)
      return;
    if (script.equals("MAIN")) {
      show(thisx, thisy);
      return;
    }
    String id = getId(source);
    if (id != null) {
      script = fixScript(id, script);
      currentMenuItemId = id;
    }
    viewer.evalStringQuiet(script);
  }

  void restorePopupMenu() {
    // main menu only
  }

  Object addMenuItem(Object menuItem, String entry) {
    return addMenuItem(menuItem, entry, "", null);
  }

  Object addCheckboxMenuItem(Object menu, String entry, String basename,
                             String id, boolean isRadio) {
    Object item = addCheckboxMenuItem(menu, entry, basename, id, false, isRadio);
    rememberCheckbox(basename, item);
    return item;
  }

  ////////////////////////////////////////////////////////////////

  protected void showPopupMenu(int x, int y) {
    if (display == null)
      return;
    try {
      swingPopup.show(display, x, y);
    } catch (Exception e) {
      Logger.error("popup error: " + e.getMessage());
      // browser in Java 1.6.0_10 is blocking setting WindowAlwaysOnTop

    }
  }

  void addToMenu(Object menu, JComponent item) {
    if (menu instanceof JPopupMenu) {
      ((JPopupMenu) menu).add(item);
    } else if (menu instanceof JMenu) {
      ((JMenu) menu).add(item);
    } else {
      Logger.warn("cannot add object to menu: " + menu);
    }
  }

  ////////////////////////////////////////////////////////////////

  void addMenuSeparator(Object menu) {
    if (menu instanceof JPopupMenu)
      ((JPopupMenu) menu).addSeparator();
    else
      ((JMenu) menu).addSeparator();
  }

  Object addMenuItem(Object menu, String entry, String script, String id) {
    JMenuItem jmi = new JMenuItem(entry);
    updateButton(jmi, entry, script);
    jmi.addActionListener(mil);
    jmi.setName(id == null ? ((Component) menu).getName() + "." : id);
    addToMenu(menu, jmi);
    return jmi;
  }

  protected void setLabel(Object menu, String entry) {
    if (menu instanceof JMenuItem)
      ((JMenuItem) menu).setText(entry);
    else
      ((JMenu) menu).setText(entry);
  }

  String getId(Object menu) {
    return ((Component) menu).getName();
  }

  void setCheckBoxValue(Object source) {
    JMenuItem jcmi = (JMenuItem) source;
    setCheckBoxValue(jcmi, jcmi.getActionCommand(), jcmi.isSelected());
  }

  void setCheckBoxState(Object item, boolean state) {
    if (item instanceof JCheckBoxMenuItem)
      ((JCheckBoxMenuItem) item).setState(state);
    else
      ((JRadioButtonMenuItem) item).setArmed(state);
    ((JMenuItem) item).setSelected(state);
  }

  protected ImageIcon getIcon(String name) {
    return null; // subclassed
  }

  void updateButton(AbstractButton b, String entry, String script) {
    ImageIcon icon = null;
    if (entry.startsWith("<")) {
      int pt = entry.indexOf(">");
      icon = getIcon(entry.substring(1, pt));
      entry = entry.substring(pt + 1);
    }

    if (icon != null)
      b.setIcon(icon);
    if (entry != null)
      b.setText(entry);
    if (script != null)
      b.setActionCommand(script);
  }
 
  Object addCheckboxMenuItem(Object menu, String entry, String basename,
                             String id, boolean state, boolean isRadio) {
    JMenuItem jm;
    if (isRadio) {
      JRadioButtonMenuItem jr = new JRadioButtonMenuItem(entry);
      jm = jr;
      jr.setArmed(state);
    } else {
      JCheckBoxMenuItem jcmi = new JCheckBoxMenuItem(entry);
      jm = jcmi;
      jcmi.setState(state);
    }
    jm.setSelected(state);
    jm.addItemListener(cmil);
    jm.setActionCommand(basename);
    updateButton(jm, entry, basename);
    jm.setName(id == null ? ((Component) menu).getName() + "." : id);
    addToMenu(menu, jm);
    return jm;
  }

  Object cloneMenu(Object menu) {
    return null;
  }

  void addMenuSubMenu(Object menu, Object subMenu) {
    addToMenu(menu, (JMenu) subMenu);
  }

  Object newMenu(String entry, String id) {
    JMenu jm = new JMenu(entry);
    updateButton(jm, entry, null);
    jm.setName(id);
    jm.setAutoscrolls(true);
    return jm;
  }

  void setAutoscrolls(Object menu) {
    ((JMenu) menu).setAutoscrolls(true);
  }

  void renameMenu(Object menu, String entry) {
    ((JMenu) menu).setText(entry);
  }

  int getMenuItemCount(Object menu) {
    return ((JMenu) menu).getItemCount();
  }

  void removeMenuItem(Object menu, int index) {
    ((JMenu) menu).remove(index);
  }

  void removeAll(Object menu) {
    ((JMenu) menu).removeAll();
  }

  void enableMenu(Object menu, boolean enable) {
    if (menu instanceof JMenuItem) {
      enableMenuItem(menu, enable);
      return;
    }
    try {
      ((JMenu) menu).setEnabled(enable);
    } catch (Exception e) {
      //no menu item;
    }
  }

  void enableMenuItem(Object item, boolean enable) {
    try {
      ((JMenuItem) item).setEnabled(enable);
    } catch (Exception e) {
      //no menu item;
    }
  }

}
TOP

Related Classes of org.jmol.popup.SimplePopup$MenuItemListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.