mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 07:36:24 +08:00
Merge remote-tracking branch 'origin/GP-4691_ghidragon_tab_close_actions--SQUASHED'
This commit is contained in:
@@ -141,10 +141,10 @@
|
|||||||
|
|
||||||
<BR><BR>
|
<BR><BR>
|
||||||
|
|
||||||
<H3><A name="Renaming_Windows"></A>Renaming Components</H3>
|
<H2><A name="Renaming_Windows"></A>Renaming Components</H3>
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
<P>
|
<P>
|
||||||
<b>Transient</B> components (e.g., search windows) can be renamed. Right-click on
|
<B>Transient</B> components (e.g., search windows) can be renamed. Right-click on
|
||||||
either the title bar or tab of a transient window and a popup menu item will
|
either the title bar or tab of a transient window and a popup menu item will
|
||||||
appear that allows you to change the title of that component. This can be useful
|
appear that allows you to change the title of that component. This can be useful
|
||||||
when you wish to better identify search results when you have performed many
|
when you wish to better identify search results when you have performed many
|
||||||
@@ -153,6 +153,29 @@
|
|||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
<BR><BR>
|
<BR><BR>
|
||||||
|
<H2><A name="Tabbed_Components"></A>Tabbed Components</H3>
|
||||||
|
<BLOCKQUOTE>
|
||||||
|
<P>
|
||||||
|
When more than one component is stacked in the same window space, the components are presented as
|
||||||
|
tabbed components. This means that only one of these components is shown at any given
|
||||||
|
time and a series of tabs, one for each component in this space, is displayed at the
|
||||||
|
bottom of the main viewing area. Clicking any of these tabs will make that tab's
|
||||||
|
corresponding component become the visible component.</P>
|
||||||
|
<P>Right-clicking on a tab will present a popup menu with the following actions:</P>
|
||||||
|
<UL>
|
||||||
|
<LI><B>Rename</B> - This action allows the user to change the short name shown in the
|
||||||
|
tab. This action is only available on transient components such as search results.</LI>
|
||||||
|
<A name="Closing_Tabs"/>
|
||||||
|
<LI><B>Close Others</B> - This action closes all other tabs. (and their
|
||||||
|
corresponding components)</LI>
|
||||||
|
<LI><B>Close Tabs to the Left</B> - This action closes all tabs to the left of the
|
||||||
|
clicked-on tab. This action is not available for the first tab.</LI>
|
||||||
|
<LI><B>Close Tabs to the Right</B> - This action closes all tabs to the right of the
|
||||||
|
clicked-on tab. This action is not available for the last tab.</LI>
|
||||||
|
</U>
|
||||||
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
|
<BR><BR>
|
||||||
|
|
||||||
<H2><A name="Windows_Menu"></A>Windows Menu</H2>
|
<H2><A name="Windows_Menu"></A>Windows Menu</H2>
|
||||||
<BLOCKQUOTE>
|
<BLOCKQUOTE>
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ import help.HelpService;
|
|||||||
* is active, then this node will create a tabbedPane object to contain the active components.
|
* is active, then this node will create a tabbedPane object to contain the active components.
|
||||||
*/
|
*/
|
||||||
class ComponentNode extends Node {
|
class ComponentNode extends Node {
|
||||||
|
private static final HelpLocation RENAME_HELP =
|
||||||
|
new HelpLocation("DockingWindows", "Renaming_Windows");
|
||||||
|
private static final HelpLocation CLOSE_HELP =
|
||||||
|
new HelpLocation("DockingWindows", "Closing_Tabs");
|
||||||
private ComponentPlaceholder top;
|
private ComponentPlaceholder top;
|
||||||
private int lastActiveTabIndex;
|
private int lastActiveTabIndex;
|
||||||
private List<ComponentPlaceholder> windowPlaceholders;
|
private List<ComponentPlaceholder> windowPlaceholders;
|
||||||
@@ -267,7 +270,7 @@ class ComponentNode extends Node {
|
|||||||
comp = top.getComponent();
|
comp = top.getComponent();
|
||||||
comp.setBorder(BorderFactory.createRaisedBevelBorder());
|
comp.setBorder(BorderFactory.createRaisedBevelBorder());
|
||||||
|
|
||||||
installRenameMenu(top, null);
|
installRenameMenu(top);
|
||||||
}
|
}
|
||||||
else if (count > 1) {
|
else if (count > 1) {
|
||||||
JTabbedPane tabbedPane =
|
JTabbedPane tabbedPane =
|
||||||
@@ -302,6 +305,8 @@ class ComponentNode extends Node {
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
ComponentPlaceholder placeholder = activeComponents.get(i);
|
ComponentPlaceholder placeholder = activeComponents.get(i);
|
||||||
|
installRenameMenu(placeholder);
|
||||||
|
|
||||||
DockableComponent c = placeholder.getComponent();
|
DockableComponent c = placeholder.getComponent();
|
||||||
c.setBorder(BorderFactory.createEmptyBorder());
|
c.setBorder(BorderFactory.createEmptyBorder());
|
||||||
|
|
||||||
@@ -314,8 +319,8 @@ class ComponentNode extends Node {
|
|||||||
|
|
||||||
DockingTabRenderer tabRenderer =
|
DockingTabRenderer tabRenderer =
|
||||||
createTabRenderer(tabbedPane, placeholder, fullTitle, tabText, component);
|
createTabRenderer(tabbedPane, placeholder, fullTitle, tabText, component);
|
||||||
|
|
||||||
c.installDragDropTarget(tabbedPane);
|
c.installDragDropTarget(tabbedPane);
|
||||||
|
tabRenderer.installPopupMenu(createTabPopupMenu(activeComponents, placeholder));
|
||||||
|
|
||||||
tabbedPane.setTabComponentAt(i, tabRenderer);
|
tabbedPane.setTabComponentAt(i, tabRenderer);
|
||||||
Icon icon = placeholder.getIcon();
|
Icon icon = placeholder.getIcon();
|
||||||
@@ -372,30 +377,64 @@ class ComponentNode extends Node {
|
|||||||
DockingTabRenderer tabRenderer =
|
DockingTabRenderer tabRenderer =
|
||||||
new DockingTabRenderer(pane, title, tabText, e -> closeTab(component));
|
new DockingTabRenderer(pane, title, tabText, e -> closeTab(component));
|
||||||
|
|
||||||
installRenameMenu(placeholder, tabRenderer);
|
|
||||||
|
|
||||||
return tabRenderer;
|
return tabRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void installRenameMenu(ComponentPlaceholder placeholder,
|
private JPopupMenu createTabPopupMenu(List<ComponentPlaceholder> activeProviders,
|
||||||
DockingTabRenderer tabRenderer) {
|
ComponentPlaceholder placeholder) {
|
||||||
|
JPopupMenu menu = new JPopupMenu();
|
||||||
|
|
||||||
|
// add rename action if applicable
|
||||||
|
ComponentProvider provider = placeholder.getProvider();
|
||||||
|
if (provider.isTransient() && !provider.isSnapshot()) {
|
||||||
|
ActionListener renameAction = new RenameProviderAction(placeholder);
|
||||||
|
JMenuItem rename = createMenuItem("Rename", renameAction, RENAME_HELP);
|
||||||
|
menu.add(rename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add close others action always (we know there is more than one or we wouldn't be here)
|
||||||
|
List<ComponentPlaceholder> closeList = new ArrayList<>(activeProviders);
|
||||||
|
closeList.remove(placeholder);
|
||||||
|
menu.add(createMenuItem("Close Others", new CloseProvidersAction(closeList), CLOSE_HELP));
|
||||||
|
|
||||||
|
// add close to the left if the current provider is not first
|
||||||
|
int index = activeProviders.indexOf(placeholder);
|
||||||
|
if (index > 0) {
|
||||||
|
closeList = new ArrayList<>(activeProviders.subList(0, index));
|
||||||
|
menu.add(createMenuItem("Close Tabs to the Left", new CloseProvidersAction(closeList),
|
||||||
|
CLOSE_HELP));
|
||||||
|
}
|
||||||
|
|
||||||
|
// add close to the right if the current provider is not last
|
||||||
|
if (index < activeProviders.size() - 1) {
|
||||||
|
closeList = new ArrayList<>(activeProviders.subList(index + 1, activeProviders.size()));
|
||||||
|
menu.add(createMenuItem("Close Tabs to the Right", new CloseProvidersAction(closeList),
|
||||||
|
CLOSE_HELP));
|
||||||
|
}
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JMenuItem createMenuItem(String name, ActionListener actionListener,
|
||||||
|
HelpLocation help) {
|
||||||
|
JMenuItem menuItem = new JMenuItem(name);
|
||||||
|
menuItem.addActionListener(actionListener);
|
||||||
|
HelpService helpService = DockingWindowManager.getHelpService();
|
||||||
|
helpService.registerHelp(menuItem, help);
|
||||||
|
return menuItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installRenameMenu(ComponentPlaceholder placeholder) {
|
||||||
|
|
||||||
final ComponentProvider provider = placeholder.getProvider();
|
final ComponentProvider provider = placeholder.getProvider();
|
||||||
if (!provider.isTransient() || provider.isSnapshot()) {
|
if (!provider.isTransient() || provider.isSnapshot()) {
|
||||||
return; // don't muck with the title of 'real' providers--only transients, like search
|
return; // don't muck with the title of 'real' providers--only transients, like search
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseAdapter listener = new RenameMouseListener(placeholder);
|
|
||||||
|
|
||||||
// for use on the header
|
// for use on the header
|
||||||
DockableComponent dockableComponent = placeholder.getComponent();
|
DockableComponent dockableComponent = placeholder.getComponent();
|
||||||
DockableHeader header = dockableComponent.getHeader();
|
DockableHeader header = dockableComponent.getHeader();
|
||||||
header.installRenameAction(listener);
|
header.installRenameAction(new RenameMouseListener(placeholder));
|
||||||
|
|
||||||
// for use on the tab
|
|
||||||
if (tabRenderer != null) {
|
|
||||||
tabRenderer.installRenameAction(listener);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -601,15 +640,12 @@ class ComponentNode extends Node {
|
|||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Inner Classes
|
// Inner Classes
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
||||||
private static class RenameMouseListener extends MouseAdapter {
|
private static class RenameMouseListener extends MouseAdapter {
|
||||||
|
|
||||||
private static final HelpLocation RENAME_HELP =
|
private ActionListener renameAction;
|
||||||
new HelpLocation("DockingWindows", "Renaming_Windows");
|
|
||||||
private ComponentPlaceholder placeholder;
|
|
||||||
|
|
||||||
RenameMouseListener(ComponentPlaceholder placeholder) {
|
RenameMouseListener(ComponentPlaceholder placeholder) {
|
||||||
this.placeholder = placeholder;
|
renameAction = new RenameProviderAction(placeholder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -617,36 +653,57 @@ class ComponentNode extends Node {
|
|||||||
// Note: we don't really care about the type of mouse event; we just want the location.
|
// Note: we don't really care about the type of mouse event; we just want the location.
|
||||||
// (the event may not actually be a clicked event, depending on the platform)
|
// (the event may not actually be a clicked event, depending on the platform)
|
||||||
|
|
||||||
JMenuItem menuItem = new JMenuItem("Rename");
|
JMenuItem rename = createMenuItem("Rename", renameAction, RENAME_HELP);
|
||||||
menuItem.addActionListener(new RenameActionListener());
|
|
||||||
HelpService helpService = DockingWindowManager.getHelpService();
|
|
||||||
helpService.registerHelp(menuItem, RENAME_HELP);
|
|
||||||
|
|
||||||
JPopupMenu menu = new JPopupMenu();
|
JPopupMenu menu = new JPopupMenu();
|
||||||
menu.add(menuItem);
|
menu.add(rename);
|
||||||
menu.show(e.getComponent(), e.getX(), e.getY());
|
menu.show(e.getComponent(), e.getX(), e.getY());
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RenameActionListener implements ActionListener {
|
}
|
||||||
@Override
|
|
||||||
public void actionPerformed(ActionEvent event) {
|
|
||||||
ComponentProvider provider = placeholder.getProvider();
|
|
||||||
JComponent component = provider.getComponent();
|
|
||||||
String currentTabText = provider.getTabText();
|
|
||||||
String newName = OptionDialog.showInputSingleLineDialog(component, "Rename Tab",
|
|
||||||
"New name:", currentTabText);
|
|
||||||
if (newName == null || newName.isEmpty()) {
|
|
||||||
return; // cancelled
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the user changes the name, then we want to replace all of the parts of the
|
private static class RenameProviderAction implements ActionListener {
|
||||||
// title with that name. We do not supply a custom subtitle, as that doesn't make
|
|
||||||
// sense in this case, but we clear it so the user's title is the only thing
|
private ComponentPlaceholder placeholder;
|
||||||
// visible. This means that providers can still update the subtitle later.
|
|
||||||
provider.setCustomTitle(newName); // title on window
|
RenameProviderAction(ComponentPlaceholder placeHolder) {
|
||||||
provider.setSubTitle(""); // part after the title
|
this.placeholder = placeHolder;
|
||||||
provider.setCustomTabText(newName); // text on the tab
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent event) {
|
||||||
|
ComponentProvider provider = placeholder.getProvider();
|
||||||
|
JComponent component = provider.getComponent();
|
||||||
|
String currentTabText = provider.getTabText();
|
||||||
|
String newName = OptionDialog.showInputSingleLineDialog(component, "Rename Tab",
|
||||||
|
"New name:", currentTabText);
|
||||||
|
if (newName == null || newName.isEmpty()) {
|
||||||
|
return; // cancelled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the user changes the name, then we want to replace all of the parts of the
|
||||||
|
// title with that name. We do not supply a custom subtitle, as that doesn't make
|
||||||
|
// sense in this case, but we clear it so the user's title is the only thing
|
||||||
|
// visible. This means that providers can still update the subtitle later.
|
||||||
|
provider.setCustomTitle(newName); // title on window
|
||||||
|
provider.setSubTitle(""); // part after the title
|
||||||
|
provider.setCustomTabText(newName); // text on the tab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class CloseProvidersAction implements ActionListener {
|
||||||
|
|
||||||
|
private List<ComponentPlaceholder> placeholdersToClose;
|
||||||
|
|
||||||
|
public CloseProvidersAction(List<ComponentPlaceholder> placeholdersToClose) {
|
||||||
|
this.placeholdersToClose = placeholdersToClose;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
for (ComponentPlaceholder placeholder : placeholdersToClose) {
|
||||||
|
placeholder.getProvider().closeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-5
@@ -39,7 +39,7 @@ public class DockingTabRenderer extends JPanel {
|
|||||||
|
|
||||||
private HierarchyListener hierarchyListener;
|
private HierarchyListener hierarchyListener;
|
||||||
private TabContainerForwardingMouseListener forwardingListener;
|
private TabContainerForwardingMouseListener forwardingListener;
|
||||||
private MouseListener renameListener;
|
private JPopupMenu popupMenu;
|
||||||
|
|
||||||
public DockingTabRenderer(final JTabbedPane tabbedPane, String fullTitle, String tabText,
|
public DockingTabRenderer(final JTabbedPane tabbedPane, String fullTitle, String tabText,
|
||||||
ActionListener closeListener) {
|
ActionListener closeListener) {
|
||||||
@@ -126,8 +126,8 @@ public class DockingTabRenderer extends JPanel {
|
|||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void installRenameAction(MouseListener listener) {
|
public void installPopupMenu(JPopupMenu popupMenu) {
|
||||||
this.renameListener = listener;
|
this.popupMenu = popupMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIcon(Icon icon) {
|
public void setIcon(Icon icon) {
|
||||||
@@ -222,7 +222,7 @@ public class DockingTabRenderer extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean consumePopup(MouseEvent e) {
|
private boolean consumePopup(MouseEvent e) {
|
||||||
if (renameListener == null) {
|
if (popupMenu == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ public class DockingTabRenderer extends JPanel {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
renameListener.mouseClicked(e);
|
popupMenu.show(e.getComponent(), e.getX(), e.getY());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user