    001package org.vishia.gral.swt;
    002
    003import java.util.Map;
    004import java.util.TreeMap;
    005
    006import org.eclipse.swt.SWT;
    007import org.eclipse.swt.events.SelectionEvent;
    008import org.eclipse.swt.events.SelectionListener;
    009import org.eclipse.swt.widgets.Control;
    010import org.eclipse.swt.widgets.Menu;
    011import org.eclipse.swt.widgets.MenuItem;
    012import org.eclipse.swt.widgets.Shell;
    013import org.eclipse.swt.widgets.Widget;
    014import org.vishia.gral.base.GralMenu;
    015import org.vishia.gral.base.GralWidget;
    016import org.vishia.gral.base.GralMng;
    017import org.vishia.gral.ifc.GralUserAction;
    018import org.vishia.util.Assert;
    019import org.vishia.util.KeyCode;
    020
    021/**This class describes either the menu bar of a window or a context menu of any widget.
    022 * It wraps the SWT Menu. All sub menus are contained in a tree parallel to the menu tree
    023 * of the implementation platform.
    024 * @author Hartmut Schorrig
    025 *
    026 */
    027public class SwtMenu extends GralMenu._GraphicImpl
    028{
    029
    030
    031
    032  /**This class wraps the {@link GralUserAction} for a menu action in Swt.
    033   */
    034  static class ActionUserMenuItem implements SelectionListener
    035  {
    036    final GralUserAction action;
    037
    038    public ActionUserMenuItem(GralUserAction action)
    039    { this.action = action;
    040    }
    041
    042    @Override
    043    public void widgetDefaultSelected(SelectionEvent e) {
    044      // TODO Auto-generated method stub
    045
    046    }
    047
    048    @Override
    049    public void widgetSelected(SelectionEvent e)
    050    { Object oWidgSwt = e.getSource();
    051      final GralWidget widgg;
    052      if(oWidgSwt instanceof Widget){
    053        Widget widgSwt = (Widget)oWidgSwt;
    054        Object oGralWidg = widgSwt.getData();
    055        if(oGralWidg instanceof GralWidget){
    056          widgg = (GralWidget)oGralWidg;
    057        } else { widgg = null; }
    058      } else { widgg = null; }
    059      try{
    060        action.exec(KeyCode.menuEntered, widgg);
    061      } catch(Exception exc){
    062        System.out.println(Assert.exceptionInfo("GralMenu - unexpected Exception; ", exc, 0, 7));
    063      }
    064    }
    065  }
    066
    067
    068
    069  protected final Shell window;
    070
    071
    072  /**It is the first level of menu hierarchy.
    073   *
    074   */
    075  private final Menu menuSwt;
    076
    077
    078
    079  /**Constructor of a context menu of any widget.
    080   * @param sName
    081   * @param parent
    082   * @param mng
    083   */
    084  protected SwtMenu(GralMenu gralMenu, GralWidget widgg, Control parent)
    085  {
    086    gralMenu.super(widgg);
    087    this.window = parent.getShell();
    088    this.menuSwt = new Menu(parent);
    089    parent.setMenu(menuSwt);
    090  }
    091
    092
    093  /**Constructor for the menu bar of a window. It creates the window's menu if it isn't existing yet.
    094   * @param sName
    095   * @param window
    096   * @param mng
    097   */
    098  protected SwtMenu(GralMenu gralMenu, GralWidget widgg, Shell window)
    099  {
    100    gralMenu.super(widgg);
    101    this.window = window;
    102    Menu menuWindow = window.getMenuBar();
    103    if(menuWindow == null){
    104      menuWindow = new Menu(window, SWT.BAR);
    105      window.setMenuBar(menuWindow);
    106    }
    107    this.menuSwt = menuWindow;
    108
    109  }
    110
    111
    112
    113
    114
    115
    116
    117  /**Adds an action with the menu path to this menu.
    118   * This method is package private. It is used by {@link SwtTable} to add a context menu with a special
    119   * SelectionListener.
    120   * @param nameWidg
    121   * @param sMenuPath
    122   * @param action
    123   */
    124  /*package private*/ private void XXXaddMenuItemGthread(GralWidget widggP, String nameWidg,
    125      String sMenuPath, SelectionListener action)
    126  {
    127    /*
    128    String[] names = sMenuPath.split("/");
    129    Map<String, GralMenu.MenuEntry> menustore = menus;
    130    int ii;
    131    Menu parentMenu = menuSwt;  //set initial, it will be a child then
    132    for(ii=0; ii<names.length-1; ++ii){
    133      //search all pre-menu entries before /. It may be existing, otherwise create it.
    134      String name = names[ii];
    135      final char cAccelerator;
    136      final int posAccelerator = name.indexOf('?');
    137      if(posAccelerator >=0){
    138        cAccelerator = Character.toUpperCase(name.charAt(posAccelerator));
    139        name = name.replace("&", "");
    140      } else {
    141        cAccelerator = 0;
    142      }
    143      MenuEntry menuEntry = menustore.get(name);
    144      if(menuEntry == null){
    145        //create it.
    146        menuEntry = new MenuEntry();
    147        menustore.put(name, menuEntry);
    148        menuEntry.name = name;
    149        menuEntry.subMenu = new TreeMap<String, MenuEntry>();
    150        MenuItem item = new MenuItem(parentMenu, SWT.CASCADE);
    151        item.setText(name);
    152        if(cAccelerator !=0){
    153          item.setAccelerator(SWT.CONTROL | cAccelerator);
    154        }
    155        Menu menu = new Menu(window, SWT.DROP_DOWN);
    156        item.setMenu(menu);
    157        menuEntry.menuImpl = menu;
    158      }
    159      menustore = menuEntry.subMenu;
    160      parentMenu = (Menu)menuEntry.menuImpl;
    161    }
    162    String name = names[ii];
    163    MenuItem item = new MenuItem(parentMenu, SWT.None);
    164    if(widggP != null){
    165      //An associated GralWidget
    166      item.setData(widggP);
    167    } else {
    168      item.setData(widgg);
    169    }
    170    item.setText(name);
    171    //item.setAccelerator(SWT.CONTROL | 'S');
    172    item.addSelectionListener(action);
    173    */
    174  }
    175
    176
    177
    178
    179  /**Creates the implementation for a menu node or entry.
    180   * @param oParentMenu return value of {@link #getMenuImpl()} or the {@link GralMenu.MenuEntry#menuImpl}, that is a menu node.
    181   * @param gralEntry The entry in the menu tree
    182   */
    183  @Override public void _implMenuItem(Object oParentMenu, GralMenu.MenuEntry gralEntry)
    184  { assert(gralEntry.menuImpl ==null);
    185    Menu parentMenu = (Menu) oParentMenu;
    186    MenuItem item = new MenuItem(parentMenu, gralEntry.subMenu !=null ? SWT.CASCADE : SWT.NONE);
    187    item.setText(gralEntry.name);
    188    item.setData(gralEntry.widgg);
    189    if(gralEntry.cAccelerator !=0){
    190      item.setAccelerator(SWT.CONTROL | gralEntry.cAccelerator);
    191    }
    192    if(gralEntry.subMenu !=null) {
    193      Menu menu = new Menu(window, SWT.DROP_DOWN);
    194      item.setMenu(menu);
    195      gralEntry.menuImpl = menu;   //The implementation is the (sub-) menu as parent for a menu item
    196    } else if(gralEntry.action !=null){
    197      gralEntry.menuImpl = item;   //The implementation is the menu item
    198      SelectionListener action = new ActionUserMenuItem(gralEntry.action);
    199      item.addSelectionListener(action);
    200    }
    201  }
    202
    203
    204
    205
    206  @Override
    207  public void setVisible(){
    208    menuSwt.setVisible(true);
    209  }
    210
    211
    212  @Override public Menu getMenuImpl(){ return menuSwt; }
    213
    214
    215}