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}