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}