diff --git a/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm b/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm index 6fa568554e..61e648d8e0 100644 --- a/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm +++ b/Ghidra/Features/Base/src/main/help/help/topics/CodeBrowserPlugin/CodeBrowser.htm @@ -128,7 +128,7 @@ dialog.

-

Keyboard Controls

+

Keyboard Controls

The following key mappings are used by the Listing:

@@ -198,6 +198,39 @@ Move the cursor to the right one position. If at the end of a line, move the cursor to first position of the next line. + + +
+ <Shift> + + Press shift when using the mouse scroll wheel to perform + horizontal scrolling. This will only work when the horizontal scroll + bar is visible. + +
+ +

+ + + You can disable horizontal scrolling in the Listing (and all other + Field Panels) via the Tool Options at + Edit + + Tool Options... + + Listing Fields + + Mouse + + Horizontal Scrolling + + +

+
+ + + + diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java index e4abfff6bf..1b9a03b58f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/codebrowser/CodeBrowserPlugin.java @@ -101,6 +101,7 @@ public class CodeBrowserPlugin extends Plugin private static final String CURSOR_COLOR = "Cursor.Cursor Color - Focused"; private static final String UNFOCUSED_CURSOR_COLOR = "Cursor.Cursor Color - Unfocused"; private static final String BLINK_CURSOR = "Cursor.Blink Cursor"; + private static final String MOUSE_WHEEL_HORIZONTAL_SCROLLING = "Mouse.Horizontal Scrolling"; // - Icon - private ImageIcon CURSOR_LOC_ICON = @@ -621,16 +622,19 @@ public class CodeBrowserPlugin extends Plugin public void optionsChanged(ToolOptions options, String optionName, Object oldValue, Object newValue) { + ListingPanel listingPanel = connectedProvider.getListingPanel(); if (options.getName().equals(GhidraOptions.CATEGORY_BROWSER_DISPLAY)) { if (optionName.equals(OptionsGui.BACKGROUND.getColorOptionName())) { Color c = (Color) newValue; - connectedProvider.getListingPanel().setTextBackgroundColor(c); + listingPanel.setTextBackgroundColor(c); } } else if (options.getName().equals(GhidraOptions.CATEGORY_BROWSER_FIELDS)) { + + FieldPanel fieldPanel = listingPanel.getFieldPanel(); if (optionName.equals(GhidraOptions.OPTION_SELECTION_COLOR)) { Color color = ((Color) newValue); - connectedProvider.getListingPanel().getFieldPanel().setSelectionColor(color); + fieldPanel.setSelectionColor(color); MarkerSet selectionMarkers = getSelectionMarkers(currentProgram); if (selectionMarkers != null) { selectionMarkers.setMarkerColor(color); @@ -642,7 +646,7 @@ public class CodeBrowserPlugin extends Plugin } else if (optionName.equals(GhidraOptions.OPTION_HIGHLIGHT_COLOR)) { Color color = ((Color) newValue); - connectedProvider.getListingPanel().getFieldPanel().setHighlightColor(color); + fieldPanel.setHighlightColor(color); MarkerSet highlightMarkers = getHighlightMarkers(currentProgram); if (highlightMarkers != null) { highlightMarkers.setMarkerColor(color); @@ -650,15 +654,15 @@ public class CodeBrowserPlugin extends Plugin } else if (optionName.equals(CURSOR_COLOR)) { Color color = ((Color) newValue); - connectedProvider.getListingPanel().getFieldPanel().setFocusedCursorColor(color); + fieldPanel.setFocusedCursorColor(color); } else if (optionName.equals(UNFOCUSED_CURSOR_COLOR)) { Color color = ((Color) newValue); - connectedProvider.getListingPanel().getFieldPanel().setNonFocusCursorColor(color); + fieldPanel.setNonFocusCursorColor(color); } else if (optionName.equals(BLINK_CURSOR)) { Boolean isBlinkCursor = ((Boolean) newValue); - connectedProvider.getListingPanel().getFieldPanel().setBlinkCursor(isBlinkCursor); + fieldPanel.setBlinkCursor(isBlinkCursor); } else if (optionName.equals(GhidraOptions.HIGHLIGHT_CURSOR_LINE_COLOR)) { cursorHighlightColor = (Color) newValue; @@ -672,6 +676,10 @@ public class CodeBrowserPlugin extends Plugin currentCursorMarkers.setColoringBackground(isHighlightCursorLine); } } + else if (optionName.equals(MOUSE_WHEEL_HORIZONTAL_SCROLLING)) { + fieldPanel.setHorizontalScrollingEnabled((Boolean) newValue); + } + connectedProvider.fieldOptionChanged(optionName, newValue); } @@ -833,6 +841,11 @@ public class CodeBrowserPlugin extends Plugin fieldOptions.registerOption(GhidraOptions.HIGHLIGHT_CURSOR_LINE, true, helpLocation, "Toggles highlighting background color of line containing the cursor"); + helpLocation = new HelpLocation(getName(), "Keyboard_Controls_Shift"); + fieldOptions.registerOption(MOUSE_WHEEL_HORIZONTAL_SCROLLING, true, helpLocation, + "Enables horizontal scrolling by holding the Shift key while " + + "using the mouse scroll wheel"); + Color color = fieldOptions.getColor(GhidraOptions.OPTION_SELECTION_COLOR, GhidraOptions.DEFAULT_SELECTION_COLOR); @@ -860,6 +873,10 @@ public class CodeBrowserPlugin extends Plugin Boolean isBlinkCursor = fieldOptions.getBoolean(BLINK_CURSOR, true); fieldPanel.setBlinkCursor(isBlinkCursor); + boolean horizontalScrollingEnabled = + fieldOptions.getBoolean(MOUSE_WHEEL_HORIZONTAL_SCROLLING, true); + fieldPanel.setHorizontalScrollingEnabled(horizontalScrollingEnabled); + cursorHighlightColor = fieldOptions.getColor(GhidraOptions.HIGHLIGHT_CURSOR_LINE_COLOR, CURSOR_LINE_COLOR); @@ -922,6 +939,12 @@ public class CodeBrowserPlugin extends Plugin "SelectUtils")); tableFromSelectionAction.setHelpLocation( new HelpLocation("CodeBrowserPlugin", "Selection_Table")); + + // don't add the actions initially if the service isn't there + TableService tableService = tool.getService(TableService.class); + if (tableService != null) { + tool.addAction(tableFromSelectionAction); + } } private GhidraProgramTableModel
createTableModel(CodeUnitIterator iterator, diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/FieldPanel.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/FieldPanel.java index 8db724c9dd..e2a9f629dd 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/FieldPanel.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/fieldpanel/FieldPanel.java @@ -58,6 +58,7 @@ public class FieldPanel extends JPanel private KeyHandler keyHandler = new KeyHandler(); private HoverHandler hoverHandler; private SelectionHandler selectionHandler = new SelectionHandler(); + private boolean horizontalScrollingEnabled = true; private FieldLocation cursorPosition = new FieldLocation(); private FieldSelection selection = new FieldSelection(); @@ -380,6 +381,14 @@ public class FieldPanel extends JPanel cursorHandler.setBlinkCursor(blinkCursor); } + public void enableSelection(boolean b) { + selectionHandler.enableSelection(b); + } + + public void setHorizontalScrollingEnabled(boolean enabled) { + horizontalScrollingEnabled = enabled; + } + /** * Returns the default background color. */ @@ -1222,15 +1231,11 @@ public class FieldPanel extends JPanel private JViewport getViewport() { Container c = getParent(); - if (c == null) { - return null; - } - if (c instanceof JViewport) { - return (JViewport) c; - } - c = c.getParent(); - if (c instanceof JViewport) { - return (JViewport) c; + while (c != null) { + if (c instanceof JViewport) { + return (JViewport) c; + } + c = c.getParent(); } return null; } @@ -1479,10 +1484,29 @@ public class FieldPanel extends JPanel } else { hoverHandler.stopHover(); - scrollView(scrollAmount); + + if (e.isShiftDown() && horizontalScrollingEnabled) { + scrollViewHorizontally(scrollAmount); + } + else { + scrollView(scrollAmount); + } } e.consume(); } + + private void scrollViewHorizontally(int scrollAmount) { + + JViewport vp = getViewport(); + if (vp == null) { + // this will happen for Field Panels not placed inside of scroll panes + return; + } + + // horizontal scroll (only move viewport) + Point pos = vp.getViewPosition(); + vp.setViewPosition(new Point(Math.max(0, pos.x + scrollAmount), pos.y)); + } } public class MouseHandler implements ActionListener { @@ -2101,8 +2125,4 @@ public class FieldPanel extends JPanel } } } - - public void enableSelection(boolean b) { - selectionHandler.enableSelection(b); - } }