mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-1440 fixing issue global actions shared across windows getting the
wrong context
This commit is contained in:
parent
b7ef0fffed
commit
c625da90a4
6 changed files with 157 additions and 120 deletions
|
@ -100,7 +100,7 @@ public class ActionToGuiMapper {
|
||||||
|
|
||||||
void update() {
|
void update() {
|
||||||
menuAndToolBarManager.update();
|
menuAndToolBarManager.update();
|
||||||
contextChangedAll();
|
contextChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
@ -117,12 +117,8 @@ public class ActionToGuiMapper {
|
||||||
return menuBarMenuHandler;
|
return menuBarMenuHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void contextChangedAll() {
|
void contextChanged() {
|
||||||
menuAndToolBarManager.contextChangedAll();
|
menuAndToolBarManager.contextChanged();
|
||||||
}
|
|
||||||
|
|
||||||
void contextChanged(ComponentPlaceholder placeHolder) {
|
|
||||||
menuAndToolBarManager.contextChanged(placeHolder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupActionManager getPopupActionManager() {
|
PopupActionManager getPopupActionManager() {
|
||||||
|
|
|
@ -159,7 +159,7 @@ public class ComponentPlaceholder {
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
DetachedWindowNode getWindowNode() {
|
DetachedWindowNode getDetachedWindowNode() {
|
||||||
Node node = compNode.parent;
|
Node node = compNode.parent;
|
||||||
while (node != null) {
|
while (node != null) {
|
||||||
if (node instanceof DetachedWindowNode) {
|
if (node instanceof DetachedWindowNode) {
|
||||||
|
@ -170,6 +170,17 @@ public class ComponentPlaceholder {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowNode getWindowNode() {
|
||||||
|
Node node = compNode.parent;
|
||||||
|
while (node != null) {
|
||||||
|
if (node instanceof WindowNode) {
|
||||||
|
return (WindowNode) node;
|
||||||
|
}
|
||||||
|
node = node.parent;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
WindowNode getTopLevelNode() {
|
WindowNode getTopLevelNode() {
|
||||||
if (compNode == null) {
|
if (compNode == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -279,9 +290,9 @@ public class ComponentPlaceholder {
|
||||||
|
|
||||||
// makes sure that the given window is not in an iconified state
|
// makes sure that the given window is not in an iconified state
|
||||||
private void activateWindow() {
|
private void activateWindow() {
|
||||||
DetachedWindowNode windowNode = getWindowNode();
|
DetachedWindowNode windowNode = getDetachedWindowNode();
|
||||||
if (windowNode != null) {
|
if (windowNode != null) {
|
||||||
Window window = getWindowNode().getWindow();
|
Window window = getDetachedWindowNode().getWindow();
|
||||||
if (window instanceof Frame) {
|
if (window instanceof Frame) {
|
||||||
Frame frame = (Frame) window;
|
Frame frame = (Frame) window;
|
||||||
frame.setState(Frame.NORMAL);
|
frame.setState(Frame.NORMAL);
|
||||||
|
|
|
@ -630,7 +630,7 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
||||||
placeholder.update();
|
placeholder.update();
|
||||||
scheduleUpdate();
|
scheduleUpdate();
|
||||||
|
|
||||||
DetachedWindowNode wNode = placeholder.getWindowNode();
|
DetachedWindowNode wNode = placeholder.getDetachedWindowNode();
|
||||||
if (wNode != null) {
|
if (wNode != null) {
|
||||||
wNode.updateTitle();
|
wNode.updateTitle();
|
||||||
}
|
}
|
||||||
|
@ -2225,19 +2225,16 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
||||||
}
|
}
|
||||||
|
|
||||||
public void contextChanged(ComponentProvider provider) {
|
public void contextChanged(ComponentProvider provider) {
|
||||||
|
// if provider is specified, update its local menu and tool bar actions
|
||||||
if (provider == null) {
|
if (provider != null) {
|
||||||
actionToGuiMapper.contextChangedAll(); // this updates the actions for all windows
|
ComponentPlaceholder placeholder = getActivePlaceholder(provider);
|
||||||
return;
|
if (placeholder != null) {
|
||||||
|
placeholder.contextChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ComponentPlaceholder placeholder = getActivePlaceholder(provider);
|
// always update the global tool menu and tool bar actions
|
||||||
if (placeholder == null) {
|
actionToGuiMapper.contextChanged();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
placeholder.contextChanged();
|
|
||||||
actionToGuiMapper.contextChanged(placeholder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2326,12 +2323,16 @@ public class DockingWindowManager implements PropertyChangeListener, Placeholder
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void notifyContextListeners(ComponentPlaceholder placeHolder, ActionContext actionContext) {
|
/**
|
||||||
|
* This call will notify any context listeners that the context has changed.
|
||||||
if (placeHolder == focusedPlaceholder) {
|
*
|
||||||
for (DockingContextListener listener : contextListeners) {
|
* <p>Our {@link #contextChanged(ComponentProvider)} method will eventually call back into this
|
||||||
listener.contextChanged(actionContext);
|
* method after any buffering has taken place.
|
||||||
}
|
* @param context the context
|
||||||
|
*/
|
||||||
|
void doContextChanged(ActionContext context) {
|
||||||
|
for (DockingContextListener listener : contextListeners) {
|
||||||
|
listener.contextChanged(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,12 @@ import docking.action.DockingActionIf;
|
||||||
import docking.menu.MenuGroupMap;
|
import docking.menu.MenuGroupMap;
|
||||||
import docking.menu.MenuHandler;
|
import docking.menu.MenuHandler;
|
||||||
import ghidra.util.Swing;
|
import ghidra.util.Swing;
|
||||||
|
import ghidra.util.task.AbstractSwingUpdateManager;
|
||||||
|
import ghidra.util.task.SwingUpdateManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to manage all the global actions that show up on the main tool menubar or toolbar
|
||||||
|
*/
|
||||||
public class GlobalMenuAndToolBarManager implements DockingWindowListener {
|
public class GlobalMenuAndToolBarManager implements DockingWindowListener {
|
||||||
|
|
||||||
private Map<WindowNode, WindowActionManager> windowToActionManagerMap;
|
private Map<WindowNode, WindowActionManager> windowToActionManagerMap;
|
||||||
|
@ -29,6 +34,12 @@ public class GlobalMenuAndToolBarManager implements DockingWindowListener {
|
||||||
private final MenuGroupMap menuGroupMap;
|
private final MenuGroupMap menuGroupMap;
|
||||||
private final DockingWindowManager windowManager;
|
private final DockingWindowManager windowManager;
|
||||||
|
|
||||||
|
// set the max delay low enough so that users can't interact with out-of-date actions before
|
||||||
|
// they get updated
|
||||||
|
private SwingUpdateManager updateManager =
|
||||||
|
new SwingUpdateManager(AbstractSwingUpdateManager.DEFAULT_MIN_DELAY, 500,
|
||||||
|
"Context Update Manager", () -> updateActions());
|
||||||
|
|
||||||
public GlobalMenuAndToolBarManager(DockingWindowManager windowManager, MenuHandler menuHandler,
|
public GlobalMenuAndToolBarManager(DockingWindowManager windowManager, MenuHandler menuHandler,
|
||||||
MenuGroupMap menuGroupMap) {
|
MenuGroupMap menuGroupMap) {
|
||||||
|
|
||||||
|
@ -77,11 +88,15 @@ public class GlobalMenuAndToolBarManager implements DockingWindowListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
for (WindowActionManager actionManager : windowToActionManagerMap.values()) {
|
// make sure this is on the swing thread to avoid clearing stuff while the swing update
|
||||||
actionManager.dispose();
|
// manager is firing its processContextChanged() call
|
||||||
}
|
Swing.runIfSwingOrRunLater(() -> {
|
||||||
windowToActionManagerMap.clear();
|
updateManager.dispose();
|
||||||
|
for (WindowActionManager actionManager : windowToActionManagerMap.values()) {
|
||||||
|
actionManager.dispose();
|
||||||
|
}
|
||||||
|
windowToActionManagerMap.clear();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -113,13 +128,7 @@ public class GlobalMenuAndToolBarManager implements DockingWindowListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dockingWindowFocusChanged(WindowNode windowNode) {
|
public void dockingWindowFocusChanged(WindowNode windowNode) {
|
||||||
//update global menus and toolbars for this window
|
updateManager.updateLater();
|
||||||
ComponentPlaceholder lastFocused = windowNode.getLastFocusedProviderInWindow();
|
|
||||||
WindowActionManager windowActionManager = windowToActionManagerMap.get(windowNode);
|
|
||||||
if (windowActionManager == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
windowActionManager.contextChanged(lastFocused);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeWindowActionManager(WindowNode windowNode) {
|
private void removeWindowActionManager(WindowNode windowNode) {
|
||||||
|
@ -135,8 +144,7 @@ public class GlobalMenuAndToolBarManager implements DockingWindowListener {
|
||||||
new WindowActionManager(windowNode, menuHandler, windowManager, menuGroupMap);
|
new WindowActionManager(windowNode, menuHandler, windowManager, menuGroupMap);
|
||||||
windowToActionManagerMap.put(windowNode, newActionManager);
|
windowToActionManagerMap.put(windowNode, newActionManager);
|
||||||
newActionManager.setActions(actionsForWindow);
|
newActionManager.setActions(actionsForWindow);
|
||||||
ComponentPlaceholder lastFocused = windowNode.getLastFocusedProviderInWindow();
|
updateManager.updateLater();
|
||||||
newActionManager.contextChanged(lastFocused);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DockingActionIf> getActionsForWindow(WindowNode windowNode) {
|
private List<DockingActionIf> getActionsForWindow(WindowNode windowNode) {
|
||||||
|
@ -152,34 +160,80 @@ public class GlobalMenuAndToolBarManager implements DockingWindowListener {
|
||||||
return actionsForWindow;
|
return actionsForWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void contextChangedAll() {
|
public void contextChanged() {
|
||||||
Swing.runIfSwingOrRunLater(this::updateAllWindowActions);
|
// schedule an update for all the global actions
|
||||||
|
updateManager.updateLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAllWindowActions() {
|
private void updateActions() {
|
||||||
|
|
||||||
|
//
|
||||||
|
// The focused window's actions must be notified after all other windows in order to
|
||||||
|
// prevent incorrect context updates. We will first update all non-focused windows,
|
||||||
|
// then the focused window and then finally tell the Docking Window Manager to update.
|
||||||
|
//
|
||||||
|
WindowNode focusedWindowNode = getFocusedWindowNode();
|
||||||
|
Set<DockingActionIf> focusedWindowActions = getWindowActions(focusedWindowNode);
|
||||||
|
|
||||||
|
ActionContext globalContext = windowManager.getDefaultToolContext();
|
||||||
for (WindowNode windowNode : windowToActionManagerMap.keySet()) {
|
for (WindowNode windowNode : windowToActionManagerMap.keySet()) {
|
||||||
ComponentPlaceholder lastFocused = windowNode.getLastFocusedProviderInWindow();
|
if (windowNode == focusedWindowNode) {
|
||||||
windowToActionManagerMap.get(windowNode).contextChanged(lastFocused);
|
continue; // the focused window will be called after this loop later
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowActionManager actionManager = windowToActionManagerMap.get(windowNode);
|
||||||
|
ActionContext localContext = getContext(windowNode);
|
||||||
|
actionManager.contextChanged(globalContext, localContext, focusedWindowActions);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now update the focused window's actions
|
||||||
|
WindowActionManager actionManager = windowToActionManagerMap.get(focusedWindowNode);
|
||||||
|
ActionContext focusedContext = getContext(focusedWindowNode);
|
||||||
|
if (actionManager != null) {
|
||||||
|
actionManager.contextChanged(globalContext, focusedContext, Collections.emptySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the docking window manager ; no focused context when no window is focused
|
||||||
|
if (focusedContext != null) {
|
||||||
|
windowManager.doContextChanged(focusedContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void contextChanged(ComponentPlaceholder placeHolder) {
|
private ActionContext getContext(WindowNode windowNode) {
|
||||||
if (placeHolder == null) {
|
if (windowNode == null) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowNode topLevelNode = placeHolder.getTopLevelNode();
|
ActionContext context = null;
|
||||||
if (topLevelNode == null) {
|
ComponentPlaceholder placeholder = windowNode.getLastFocusedProviderInWindow();
|
||||||
return;
|
if (placeholder != null) {
|
||||||
|
ComponentProvider provider = placeholder.getProvider();
|
||||||
|
if (provider != null) {
|
||||||
|
context = provider.getActionContext(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (context == null) {
|
||||||
if (topLevelNode.getLastFocusedProviderInWindow() != placeHolder) {
|
context = new ActionContext();
|
||||||
return; // actions in this window are not currently responding to this provider
|
|
||||||
}
|
|
||||||
|
|
||||||
WindowActionManager windowActionManager = windowToActionManagerMap.get(topLevelNode);
|
|
||||||
if (windowActionManager != null) {
|
|
||||||
windowActionManager.contextChanged(placeHolder);
|
|
||||||
}
|
}
|
||||||
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<DockingActionIf> getWindowActions(WindowNode windowNode) {
|
||||||
|
if (windowNode != null) {
|
||||||
|
WindowActionManager windowActionManager = windowToActionManagerMap.get(windowNode);
|
||||||
|
if (windowActionManager != null) {
|
||||||
|
return windowActionManager.getOriginalActions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private WindowNode getFocusedWindowNode() {
|
||||||
|
ComponentPlaceholder focusedComponent = windowManager.getFocusedComponent();
|
||||||
|
if (focusedComponent == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return focusedComponent.getWindowNode();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import javax.swing.JMenuBar;
|
||||||
|
|
||||||
import docking.action.DockingActionIf;
|
import docking.action.DockingActionIf;
|
||||||
import docking.menu.*;
|
import docking.menu.*;
|
||||||
import ghidra.util.task.SwingUpdateManager;
|
|
||||||
|
|
||||||
public class WindowActionManager {
|
public class WindowActionManager {
|
||||||
private Map<DockingActionIf, DockingActionProxy> actionToProxyMap;
|
private Map<DockingActionIf, DockingActionProxy> actionToProxyMap;
|
||||||
|
@ -29,25 +28,18 @@ public class WindowActionManager {
|
||||||
private ToolBarManager toolBarMgr;
|
private ToolBarManager toolBarMgr;
|
||||||
private final WindowNode node;
|
private final WindowNode node;
|
||||||
|
|
||||||
private final DockingWindowManager winMgr;
|
|
||||||
private boolean disposed;
|
private boolean disposed;
|
||||||
|
|
||||||
private ComponentPlaceholder placeHolderForScheduledActionUpdate;
|
WindowActionManager(WindowNode node, MenuHandler menuBarHandler,
|
||||||
private Runnable updateActionsRunnable = () -> processContextChanged();
|
|
||||||
private SwingUpdateManager updateManager =
|
|
||||||
new SwingUpdateManager(500, 500, "Context Update Manager", updateActionsRunnable);
|
|
||||||
|
|
||||||
public WindowActionManager(WindowNode node, MenuHandler menuBarHandler,
|
|
||||||
DockingWindowManager winMgr, MenuGroupMap menuGroupMap) {
|
DockingWindowManager winMgr, MenuGroupMap menuGroupMap) {
|
||||||
|
|
||||||
this.node = node;
|
this.node = node;
|
||||||
this.winMgr = winMgr;
|
|
||||||
actionToProxyMap = new HashMap<>();
|
actionToProxyMap = new HashMap<>();
|
||||||
menuBarMgr = new MenuBarManager(menuBarHandler, menuGroupMap);
|
menuBarMgr = new MenuBarManager(menuBarHandler, menuGroupMap);
|
||||||
toolBarMgr = new ToolBarManager(winMgr);
|
toolBarMgr = new ToolBarManager(winMgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActions(List<DockingActionIf> actionList) {
|
void setActions(List<DockingActionIf> actionList) {
|
||||||
menuBarMgr.clearActions();
|
menuBarMgr.clearActions();
|
||||||
toolBarMgr.clearActions();
|
toolBarMgr.clearActions();
|
||||||
actionToProxyMap.clear();
|
actionToProxyMap.clear();
|
||||||
|
@ -56,7 +48,7 @@ public class WindowActionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAction(DockingActionIf action) {
|
void addAction(DockingActionIf action) {
|
||||||
if (action.getMenuBarData() != null || action.getToolBarData() != null) {
|
if (action.getMenuBarData() != null || action.getToolBarData() != null) {
|
||||||
DockingActionProxy proxyAction = new DockingActionProxy(action);
|
DockingActionProxy proxyAction = new DockingActionProxy(action);
|
||||||
actionToProxyMap.put(action, proxyAction);
|
actionToProxyMap.put(action, proxyAction);
|
||||||
|
@ -65,7 +57,7 @@ public class WindowActionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAction(DockingActionIf action) {
|
void removeAction(DockingActionIf action) {
|
||||||
DockingActionProxy proxyAction = actionToProxyMap.remove(action);
|
DockingActionProxy proxyAction = actionToProxyMap.remove(action);
|
||||||
if (proxyAction != null) {
|
if (proxyAction != null) {
|
||||||
menuBarMgr.removeAction(proxyAction);
|
menuBarMgr.removeAction(proxyAction);
|
||||||
|
@ -73,11 +65,11 @@ public class WindowActionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DockingActionIf getToolbarAction(String actionName) {
|
DockingActionIf getToolbarAction(String actionName) {
|
||||||
return toolBarMgr.getAction(actionName);
|
return toolBarMgr.getAction(actionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
void update() {
|
||||||
JMenuBar menuBar = menuBarMgr.getMenuBar();
|
JMenuBar menuBar = menuBarMgr.getMenuBar();
|
||||||
if (menuBar.getMenuCount() > 0) {
|
if (menuBar.getMenuCount() > 0) {
|
||||||
node.setMenuBar(menuBar);
|
node.setMenuBar(menuBar);
|
||||||
|
@ -87,9 +79,8 @@ public class WindowActionManager {
|
||||||
node.validate();
|
node.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void dispose() {
|
void dispose() {
|
||||||
disposed = true;
|
disposed = true;
|
||||||
updateManager.dispose();
|
|
||||||
node.setToolBar(null);
|
node.setToolBar(null);
|
||||||
node.setMenuBar(null);
|
node.setMenuBar(null);
|
||||||
actionToProxyMap.clear();
|
actionToProxyMap.clear();
|
||||||
|
@ -97,48 +88,32 @@ public class WindowActionManager {
|
||||||
toolBarMgr.dispose();
|
toolBarMgr.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void contextChanged(ComponentPlaceholder placeHolder) {
|
void contextChanged(ActionContext globalContext, ActionContext localContext,
|
||||||
|
Set<DockingActionIf> excluded) {
|
||||||
|
|
||||||
if (!node.isVisible()) {
|
if (!node.isVisible() || disposed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
placeHolderForScheduledActionUpdate = placeHolder;
|
// Update actions - make a copy so that we don't get concurrent modification
|
||||||
|
// exceptions during reentrant operations
|
||||||
// Typically, when we get one contextChanged, we get a flurry of contextChanged calls.
|
List<DockingActionIf> list = new ArrayList<>(actionToProxyMap.keySet());
|
||||||
// In order to make the action updating be as responsive as possible and still be complete,
|
|
||||||
// we have chosen a policy that will reduce a flurry of contextChanged call into two
|
|
||||||
// actual calls - one that occurs immediately and one when the flurry times out.
|
|
||||||
updateManager.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void processContextChanged() {
|
|
||||||
//
|
|
||||||
// This method is called from an invokeLater(), which means that we may be
|
|
||||||
// disposed while before this Swing call executes.
|
|
||||||
//
|
|
||||||
if (disposed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionContext localContext = getContext();
|
|
||||||
ActionContext globalContext = winMgr.getDefaultToolContext();
|
|
||||||
|
|
||||||
// Update actions - make a copy so that we don't get concurrent modification exceptions
|
|
||||||
List<DockingActionIf> list = new ArrayList<>(actionToProxyMap.values());
|
|
||||||
for (DockingActionIf action : list) {
|
for (DockingActionIf action : list) {
|
||||||
if (action.isValidContext(localContext)) {
|
if (excluded.contains(action)) {
|
||||||
action.setEnabled(action.isEnabledForContext(localContext));
|
continue;
|
||||||
}
|
}
|
||||||
else if (isValidDefaultToolContext(action, globalContext)) {
|
|
||||||
action.setEnabled(action.isEnabledForContext(globalContext));
|
DockingActionIf proxyAction = actionToProxyMap.get(action);
|
||||||
|
if (proxyAction.isValidContext(localContext)) {
|
||||||
|
proxyAction.setEnabled(proxyAction.isEnabledForContext(localContext));
|
||||||
|
}
|
||||||
|
else if (isValidDefaultToolContext(proxyAction, globalContext)) {
|
||||||
|
proxyAction.setEnabled(proxyAction.isEnabledForContext(globalContext));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
action.setEnabled(false);
|
proxyAction.setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Notify listeners if the context provider is the focused provider
|
|
||||||
winMgr.notifyContextListeners(placeHolderForScheduledActionUpdate, localContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValidDefaultToolContext(DockingActionIf action, ActionContext toolContext) {
|
private boolean isValidDefaultToolContext(DockingActionIf action, ActionContext toolContext) {
|
||||||
|
@ -146,15 +121,15 @@ public class WindowActionManager {
|
||||||
action.isValidContext(toolContext);
|
action.isValidContext(toolContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ActionContext getContext() {
|
/**
|
||||||
ComponentProvider provider = placeHolderForScheduledActionUpdate == null ? null
|
* Returns the set of actions for this window.
|
||||||
: placeHolderForScheduledActionUpdate.getProvider();
|
*
|
||||||
|
* <p>Note this returns the the original passed-in actions and not the proxy actions that the
|
||||||
ActionContext context = provider == null ? null : provider.getActionContext(null);
|
* window uses.
|
||||||
|
*
|
||||||
if (context == null) {
|
* @return the set of actions for this window
|
||||||
context = new ActionContext();
|
*/
|
||||||
}
|
Set<DockingActionIf> getOriginalActions() {
|
||||||
return context;
|
return new HashSet<>(actionToProxyMap.keySet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public abstract class AbstractSwingUpdateManager {
|
||||||
protected static final long NONE = 0;
|
protected static final long NONE = 0;
|
||||||
public static final int DEFAULT_MAX_DELAY = 30000;
|
public static final int DEFAULT_MAX_DELAY = 30000;
|
||||||
protected static final int MIN_DELAY_FLOOR = 10;
|
protected static final int MIN_DELAY_FLOOR = 10;
|
||||||
protected static final int DEFAULT_MIN_DELAY = 250;
|
public static final int DEFAULT_MIN_DELAY = 250;
|
||||||
protected static final String DEFAULT_NAME = AbstractSwingUpdateManager.class.getSimpleName();
|
protected static final String DEFAULT_NAME = AbstractSwingUpdateManager.class.getSimpleName();
|
||||||
private static final WeakSet<AbstractSwingUpdateManager> instances =
|
private static final WeakSet<AbstractSwingUpdateManager> instances =
|
||||||
WeakDataStructureFactory.createCopyOnReadWeakSet();
|
WeakDataStructureFactory.createCopyOnReadWeakSet();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue