mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/GT-3115-dragonmacer-decompiler-find-actions'
This commit is contained in:
commit
5f19814d48
30 changed files with 833 additions and 223 deletions
|
@ -395,6 +395,13 @@ public abstract class DockingAction implements DockingActionIf {
|
|||
buffer.append('\n');
|
||||
buffer.append(" MENU GROUP: ").append(menuBarData.getMenuGroup());
|
||||
buffer.append('\n');
|
||||
|
||||
String parentGroup = popupMenuData.getParentMenuGroup();
|
||||
if (parentGroup != null) {
|
||||
buffer.append(" PARENT GROUP: ").append(parentGroup);
|
||||
buffer.append('\n');
|
||||
}
|
||||
|
||||
Icon icon = menuBarData.getMenuIcon();
|
||||
if (icon != null && icon instanceof ImageIconWrapper) {
|
||||
ImageIconWrapper wrapper = (ImageIconWrapper) icon;
|
||||
|
@ -412,6 +419,12 @@ public abstract class DockingAction implements DockingActionIf {
|
|||
buffer.append(" POPUP GROUP: ").append(popupMenuData.getMenuGroup());
|
||||
buffer.append('\n');
|
||||
|
||||
String parentGroup = popupMenuData.getParentMenuGroup();
|
||||
if (parentGroup != null) {
|
||||
buffer.append(" PARENT GROUP: ").append(parentGroup);
|
||||
buffer.append('\n');
|
||||
}
|
||||
|
||||
String menuSubGroup = popupMenuData.getMenuSubGroup();
|
||||
if (menuSubGroup != MenuData.NO_SUBGROUP) {
|
||||
buffer.append(" POPUP SUB-GROUP: ").append(menuSubGroup);
|
||||
|
|
|
@ -31,6 +31,7 @@ public class MenuData {
|
|||
private Icon icon;
|
||||
private int mnemonic = NO_MNEMONIC;
|
||||
private String menuGroup;
|
||||
private String parentMenuGroup;
|
||||
|
||||
/**
|
||||
* The subgroup string. This string is used to sort items within a
|
||||
|
@ -73,11 +74,14 @@ public class MenuData {
|
|||
this.icon = menuData.icon;
|
||||
this.menuGroup = menuData.menuGroup;
|
||||
this.menuSubGroup = menuData.menuSubGroup;
|
||||
this.parentMenuGroup = menuData.parentMenuGroup;
|
||||
this.mnemonic = menuData.mnemonic;
|
||||
}
|
||||
|
||||
public MenuData cloneData() {
|
||||
return new MenuData(menuPath, icon, menuGroup, mnemonic, menuSubGroup);
|
||||
MenuData newData = new MenuData(menuPath, icon, menuGroup, mnemonic, menuSubGroup);
|
||||
newData.parentMenuGroup = parentMenuGroup;
|
||||
return newData;
|
||||
}
|
||||
|
||||
protected void firePropertyChanged(MenuData oldData) {
|
||||
|
@ -113,11 +117,20 @@ public class MenuData {
|
|||
/**
|
||||
* Returns the icon assigned to this action's menu. Null indicates that this action does not
|
||||
* have a menu icon
|
||||
* @return the icon
|
||||
*/
|
||||
public Icon getMenuIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the group for the menu item created by this data. This value determines which
|
||||
* section inside of the tool's popup menu the menu item will be placed. If you need to
|
||||
* control the ordering <b>within a section</b>, then provide a value for
|
||||
* {@link #setMenuSubGroup(String)}.
|
||||
*
|
||||
* @return the group
|
||||
*/
|
||||
public String getMenuGroup() {
|
||||
return menuGroup;
|
||||
}
|
||||
|
@ -126,11 +139,24 @@ public class MenuData {
|
|||
* Returns the subgroup string. This string is used to sort items within a
|
||||
* {@link #getMenuGroup() toolbar group}. This value is not required. If not specified,
|
||||
* then the value will effectively place this item at the end of its specified group.
|
||||
* @return the sub-group
|
||||
*/
|
||||
public String getMenuSubGroup() {
|
||||
return menuSubGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the group for the parent menu of the menu item created by this data. That is,
|
||||
* this value is effectively the same as {@link #getMenuGroup()}, but for the parent menu
|
||||
* item of this data's item. Setting this value is only valid if the {@link #getMenuPath()}
|
||||
* has a length greater than 1.
|
||||
*
|
||||
* @return the parent group
|
||||
*/
|
||||
public String getParentMenuGroup() {
|
||||
return parentMenuGroup;
|
||||
}
|
||||
|
||||
public void setIcon(Icon newIcon) {
|
||||
if (icon == newIcon) {
|
||||
return;
|
||||
|
@ -154,11 +180,38 @@ public class MenuData {
|
|||
if (SystemUtilities.isEqual(menuSubGroup, newSubGroup)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newSubGroup == null) {
|
||||
newSubGroup = NO_SUBGROUP;
|
||||
}
|
||||
|
||||
MenuData oldData = cloneData();
|
||||
menuSubGroup = newSubGroup;
|
||||
firePropertyChanged(oldData);
|
||||
}
|
||||
|
||||
/**
|
||||
* See the description in {@link #getParentMenuGroup()}
|
||||
*
|
||||
* @param newParentMenuGroup the parent group
|
||||
*/
|
||||
public void setParentMenuGroup(String newParentMenuGroup) {
|
||||
if (menuPath.length <= 1) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot set the parent menu group for a menu item " + "that has no parent");
|
||||
}
|
||||
|
||||
if (SystemUtilities.isEqual(parentMenuGroup, newParentMenuGroup)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MenuData oldData = cloneData();
|
||||
parentMenuGroup = newParentMenuGroup;
|
||||
firePropertyChanged(oldData);
|
||||
|
||||
this.parentMenuGroup = newParentMenuGroup;
|
||||
}
|
||||
|
||||
public void setMenuPath(String[] newPath) {
|
||||
if (newPath == null || newPath.length == 0) {
|
||||
throw new IllegalArgumentException("Menu path cannot be null or empty");
|
||||
|
|
|
@ -102,28 +102,8 @@ public class MenuManager implements ManagedMenuItem {
|
|||
checkForSwingThread();
|
||||
resetMenus();
|
||||
MenuData menuData = usePopupPath ? action.getPopupMenuData() : action.getMenuBarData();
|
||||
String[] actionMenuPath = menuData.getMenuPath();
|
||||
if (actionMenuPath.length > level + 1) {
|
||||
String subMenuName = actionMenuPath[level];
|
||||
String cleanSubMenuName = stripMnemonicAmp(subMenuName);
|
||||
MenuManager mgr = subMenus.get(cleanSubMenuName);
|
||||
|
||||
if (mgr == null) {
|
||||
char mnemonic = getMnemonicKey(subMenuName);
|
||||
|
||||
int submenuLevel = level + 1;
|
||||
String[] submenuPath = new String[submenuLevel];
|
||||
System.arraycopy(actionMenuPath, 0, submenuPath, 0, submenuLevel);
|
||||
String submenuGroup = menuGroupMap.getMenuGroup(submenuPath);
|
||||
if (submenuGroup == null) {
|
||||
submenuGroup = subMenuName;
|
||||
}
|
||||
|
||||
mgr = new MenuManager(cleanSubMenuName, submenuPath, mnemonic, submenuLevel,
|
||||
submenuGroup, usePopupPath, menuHandler, menuGroupMap);
|
||||
subMenus.put(cleanSubMenuName, mgr);
|
||||
managedMenuItems.add(mgr);
|
||||
}
|
||||
if (isSubMenu(menuData)) {
|
||||
MenuManager mgr = getSubMenu(menuData);
|
||||
mgr.addAction(action);
|
||||
}
|
||||
else {
|
||||
|
@ -131,6 +111,70 @@ public class MenuManager implements ManagedMenuItem {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isSubMenu(MenuData menuData) {
|
||||
String[] actionMenuPath = menuData.getMenuPath();
|
||||
return actionMenuPath.length > level + 1;
|
||||
}
|
||||
|
||||
private MenuManager getSubMenu(MenuData menuData) {
|
||||
|
||||
String[] fullPath = menuData.getMenuPath();
|
||||
String displayName = fullPath[level];
|
||||
char mnemonic = getMnemonicKey(displayName);
|
||||
String realName = stripMnemonicAmp(displayName);
|
||||
MenuManager subMenu = subMenus.get(realName);
|
||||
if (subMenu != null) {
|
||||
return subMenu;
|
||||
}
|
||||
|
||||
int subMenuLevel = level + 1;
|
||||
String[] subMenuPath = new String[subMenuLevel];
|
||||
System.arraycopy(fullPath, 0, subMenuPath, 0, subMenuLevel);
|
||||
|
||||
String subMenuGroup = getSubMenuGroup(menuData, realName, subMenuPath);
|
||||
subMenu = new MenuManager(realName, subMenuPath, mnemonic, subMenuLevel, subMenuGroup,
|
||||
usePopupPath, menuHandler, menuGroupMap);
|
||||
subMenus.put(realName, subMenu);
|
||||
managedMenuItems.add(subMenu);
|
||||
|
||||
return subMenu;
|
||||
}
|
||||
|
||||
private String getSubMenuGroup(MenuData menuData, String menuName, String[] subMenuPath) {
|
||||
|
||||
// prefer the group defined in the menu data, if any
|
||||
String pullRightGroup = getPullRightMenuGroup(menuData);
|
||||
if (pullRightGroup != null) {
|
||||
return pullRightGroup;
|
||||
}
|
||||
|
||||
// check the global registry
|
||||
pullRightGroup = menuGroupMap.getMenuGroup(subMenuPath);
|
||||
if (pullRightGroup != null) {
|
||||
return pullRightGroup;
|
||||
}
|
||||
|
||||
// default to the menu name
|
||||
return menuName;
|
||||
}
|
||||
|
||||
private String getPullRightMenuGroup(MenuData menuData) {
|
||||
|
||||
// note: currently, the client can specify the group for the pull-right menu only for
|
||||
// the immediate parent of the menu item. We can change this later if we find
|
||||
// we have a need for a multi-level cascaded menu that needs to specify groups for
|
||||
// each pull-right in the menu path
|
||||
|
||||
String[] actionMenuPath = menuData.getMenuPath();
|
||||
int leafLevel = actionMenuPath.length - 1;
|
||||
boolean isParentOfLeaf = level == (leafLevel - 1);
|
||||
if (!isParentOfLeaf) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return menuData.getParentMenuGroup();
|
||||
}
|
||||
|
||||
public DockingActionIf getAction(String actionName) {
|
||||
for (ManagedMenuItem item : managedMenuItems) {
|
||||
if (item instanceof MenuItemManager) {
|
||||
|
@ -158,17 +202,18 @@ public class MenuManager implements ManagedMenuItem {
|
|||
}
|
||||
|
||||
/***
|
||||
* Removes the Mnemonic indicator character (&) from the text.
|
||||
* @param str the text to strip.
|
||||
* Removes the Mnemonic indicator character (&) from the text
|
||||
* @param text the text to strip
|
||||
* @return the stripped mnemonic
|
||||
*/
|
||||
public static String stripMnemonicAmp(String str) {
|
||||
int ampLoc = str.indexOf('&');
|
||||
public static String stripMnemonicAmp(String text) {
|
||||
int ampLoc = text.indexOf('&');
|
||||
if (ampLoc < 0) {
|
||||
return str;
|
||||
return text;
|
||||
}
|
||||
String s = str.substring(0, ampLoc);
|
||||
if (ampLoc < (str.length() - 1)) {
|
||||
s += str.substring(++ampLoc);
|
||||
String s = text.substring(0, ampLoc);
|
||||
if (ampLoc < (text.length() - 1)) {
|
||||
s += text.substring(++ampLoc);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -182,7 +227,8 @@ public class MenuManager implements ManagedMenuItem {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a Menu hierarchy of all the actions.
|
||||
* Returns a Menu hierarchy of all the actions
|
||||
* @return the menu
|
||||
*/
|
||||
public JMenu getMenu() {
|
||||
if (menu == null) {
|
||||
|
@ -236,9 +282,6 @@ public class MenuManager implements ManagedMenuItem {
|
|||
return menuSubGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see docking.menu.ManagedMenuItem#dispose()
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
for (ManagedMenuItem item : managedMenuItems) {
|
||||
|
@ -249,7 +292,8 @@ public class MenuManager implements ManagedMenuItem {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a JPopupMenu for the action hierarchy.
|
||||
* Returns a JPopupMenu for the action hierarchy
|
||||
* @return the popup menu
|
||||
*/
|
||||
public JPopupMenu getPopupMenu() {
|
||||
if (popupMenu == null) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue