Skip to content

Commit

Permalink
Find/Replace overlay: add a search- and replace- history
Browse files Browse the repository at this point in the history
Adds a history feature for the find and replace bar of the overlay.
The history is displayed using a menu filled with entries from the
HistoryStore.

fixes #1907
  • Loading branch information
Maximilian Wittmer authored and Maximilian Wittmer committed Jun 24, 2024
1 parent 54609c8 commit 074a7fd
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 17 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ private FindReplaceMessages() {
public static String FindReplaceOverlay_searchBar_message;
public static String FindReplaceOverlay_replaceBar_message;
public static String FindReplaceOverlay_replaceToggle_toolTip;
public static String FindReplaceOverlay_searchHistory_toolTip;
public static String FindReplaceOverlay_replaceHistory_toolTip;
public static String FindReplaceOverlayFirstTimePopup_FindReplaceOverlayFirstTimePopup_message;
public static String FindReplaceOverlayFirstTimePopup_FindReplaceOverlayFirstTimePopup_title;
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ FindReplace_ReplaceAllButton_label=Replace &All
FindReplace_SelectAllButton_label=&Select All
FindReplace_CloseButton_label=Close

# Messages for the "new" Find-Replace-Overlay
# Messages for the Find-Replace-Overlay
FindReplaceOverlay_upSearchButton_toolTip=Search backward (Shift + Enter)
FindReplaceOverlay_downSearchButton_toolTip=Search forward (Enter)
FindReplaceOverlay_searchAllButton_toolTip=Search all (Ctrl + Enter)
Expand All @@ -55,8 +55,10 @@ FindReplaceOverlay_caseSensitiveButton_toolTip=Match case (Ctrl + Shift + C)
FindReplaceOverlay_wholeWordsButton_toolTip=Match whole word (Ctrl + Shift + W)
FindReplaceOverlay_replaceButton_toolTip=Replace (Enter)
FindReplaceOverlay_replaceAllButton_toolTip=Replace all (Ctrl + Enter)
FindReplaceOverlay_searchBar_message=Find
FindReplaceOverlay_replaceBar_message=Replace
FindReplaceOverlay_searchBar_message=Find (\u2195 for history)
FindReplaceOverlay_replaceBar_message=Replace (\u2195 for history)
FindReplaceOverlay_replaceToggle_toolTip=Toggle input for replace (Ctrl + R)
FindReplaceOverlay_searchHistory_toolTip=Show search history
FindReplaceOverlay_replaceHistory_toolTip=Show replace history
FindReplaceOverlayFirstTimePopup_FindReplaceOverlayFirstTimePopup_message=Find and replace can now be done using an overlay embedded inside the editor. If you prefer the dialog, you can disable the overlay in the preferences or <a>disable it now</a>.
FindReplaceOverlayFirstTimePopup_FindReplaceOverlayFirstTimePopup_title=New Find/Replace Overlay
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,8 @@ private void writeHistory() {
settingsManager.put(sectionName, names);
}

public List<String> asList() {
return new ArrayList<>(history);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.eclipse.ui.internal.findandreplace.overlay;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;

import org.eclipse.ui.internal.findandreplace.HistoryStore;

public class SearchHistoryMenu {

public SearchHistoryMenu(Control parent, HistoryStore history, SelectionListener menuItemSelectionListener) {
Menu menu = new Menu(parent);

for (String entry : history.get()) {
MenuItem item = new MenuItem(menu, SWT.FLAT);
item.setText(entry);
item.addSelectionListener(menuItemSelectionListener);
}

Point loc = parent.toDisplay(0, 0);
Rectangle rect = parent.getBounds();

Point mLoc = new Point(loc.x, loc.y + rect.height);

menu.setLocation(mLoc);

menu.setVisible(true);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Scrollable;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
Expand All @@ -59,7 +60,9 @@
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.findandreplace.FindReplaceLogic;
import org.eclipse.ui.internal.findandreplace.FindReplaceMessages;
import org.eclipse.ui.internal.findandreplace.HistoryStore;
import org.eclipse.ui.internal.findandreplace.SearchOptions;
import org.eclipse.ui.internal.findandreplace.overlay.SearchHistoryMenu;
import org.eclipse.ui.internal.findandreplace.status.IFindReplaceStatus;

/**
Expand Down Expand Up @@ -87,25 +90,38 @@ class FindReplaceOverlay extends Dialog {
private Composite searchBarContainer;
private Text searchBar;
private AccessibleToolBar searchTools;

@SuppressWarnings("unused")
private ToolItem searchHistoryButton;
private ToolItem searchInSelectionButton;
private ToolItem wholeWordSearchButton;
private ToolItem caseSensitiveSearchButton;
private ToolItem regexSearchButton;

@SuppressWarnings("unused")
private ToolItem searchUpButton;
private ToolItem searchDownButton;

@SuppressWarnings("unused")
private ToolItem searchAllButton;

private Composite replaceContainer;
private Composite replaceBarContainer;
private Text replaceBar;
private AccessibleToolBar replaceTools;

@SuppressWarnings("unused")
private ToolItem replaceHistoryButton;

@SuppressWarnings("unused")
private ToolItem replaceButton;
private ToolItem replaceAllButton;

Check warning on line 117 in bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceOverlay.java

View check run for this annotation

Jenkins - Eclipse Platform / Compiler and API Tools

Unnecessary Code

NORMAL: The value of the field FindReplaceOverlay.replaceAllButton is not used

private Color backgroundToUse;
private Color normalTextForegroundColor;
private boolean positionAtTop = true;
private static final int HISTORY_SIZE = 15;
private HistoryStore searchHistory;
private HistoryStore replaceHistory;

public FindReplaceOverlay(Shell parent, IWorkbenchPart part, IFindReplaceTarget target) {
super(parent);
Expand All @@ -114,7 +130,12 @@ public FindReplaceOverlay(Shell parent, IWorkbenchPart part, IFindReplaceTarget
setShellStyle(SWT.MODELESS);
setBlockOnOpen(false);
targetPart = part;
setupHistory();
}

private void setupHistory() {
searchHistory = new HistoryStore(getDialogSettings(), "findhistory", HISTORY_SIZE); //$NON-NLS-1$
replaceHistory = new HistoryStore(getDialogSettings(), "replacehistory", HISTORY_SIZE); //$NON-NLS-1$
}

@Override
Expand All @@ -138,11 +159,14 @@ private void createFindReplaceLogic(IFindReplaceTarget target) {
private void performReplaceAll() {
BusyIndicator.showWhile(getShell() != null ? getShell().getDisplay() : Display.getCurrent(),
() -> findReplaceLogic.performReplaceAll(getFindString(), getReplaceString()));
updateHistory(replaceBar, replaceHistory);
updateHistory(searchBar, searchHistory);
}

private void performSelectAll() {
BusyIndicator.showWhile(getShell() != null ? getShell().getDisplay() : Display.getCurrent(),
() -> findReplaceLogic.performSelectAll(getFindString()));
updateHistory(searchBar, searchHistory);
}

private KeyListener shortcuts = KeyListener.keyPressedAdapter(e -> {
Expand All @@ -165,11 +189,31 @@ private void performSelectAll() {
performEnterAction(e);
} else if (e.keyCode == SWT.ESC) {
close();
} else if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN) {
int stepDirection = e.keyCode == SWT.ARROW_UP ? 1 : -1;
if (replaceBar.isFocusControl()) {
navigateInHistory(replaceBar, replaceHistory, stepDirection);
} else {
navigateInHistory(searchBar, searchHistory, stepDirection);
}
} else {
e.doit = true;
}
});

private void navigateInHistory(Text textBar, HistoryStore history, int navigationOffset) {
int offset = history.asList().indexOf(textBar.getText());

offset += navigationOffset;
offset = offset % history.asList().size();

if (offset + navigationOffset < 0) {
offset = history.asList().size() - 1;
}

textBar.setText(history.get(offset));
}

private void performEnterAction(KeyEvent e) {
boolean isShiftPressed = (e.stateMask & SWT.SHIFT) != 0;
boolean isCtrlPressed = (e.stateMask & SWT.CTRL) != 0;
Expand Down Expand Up @@ -338,24 +382,15 @@ private void restoreOverlaySettings() {

private void applyOverlayColors(Color color, boolean tryToColorReplaceBar) {
searchTools.setBackground(color);
searchInSelectionButton.setBackground(color);
wholeWordSearchButton.setBackground(color);
regexSearchButton.setBackground(color);
caseSensitiveSearchButton.setBackground(color);
searchAllButton.setBackground(color);
searchUpButton.setBackground(color);
searchDownButton.setBackground(color);

searchBarContainer.setBackground(color);
searchBar.setBackground(color);
searchContainer.setBackground(color);

if (replaceBarOpen && tryToColorReplaceBar) {
replaceContainer.setBackground(color);
replaceBar.setBackground(color);
replaceBarContainer.setBackground(color);
replaceAllButton.setBackground(color);
replaceButton.setBackground(color);
replaceTools.setBackground(color);
replaceBar.setBackground(color);
}
}

Expand Down Expand Up @@ -425,13 +460,28 @@ private void createSearchTools() {
searchTools = new AccessibleToolBar(searchContainer);
GridDataFactory.fillDefaults().grab(false, true).align(GridData.CENTER, GridData.END).applyTo(searchTools);

searchHistoryButton = new AccessibleToolItemBuilder(searchTools)
.withStyleBits(SWT.PUSH).withToolTipText(FindReplaceMessages.FindReplaceOverlay_searchHistory_toolTip)
.withImage(FindReplaceOverlayImages.get(FindReplaceOverlayImages.KEY_OPEN_HISTORY))
.withSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
@SuppressWarnings("unused")
SearchHistoryMenu menu = new SearchHistoryMenu(searchTools, searchHistory,
SelectionListener.widgetSelectedAdapter(f -> {
MenuItem selectedItem = (MenuItem) f.widget;
String text = selectedItem.getText();
searchBar.setText(text);
}));
})).build();

@SuppressWarnings("unused")
ToolItem separator = searchTools.createToolItem(SWT.SEPARATOR);

createWholeWordsButton();
createCaseSensitiveButton();
createRegexSearchButton();
createAreaSearchButton();

@SuppressWarnings("unused")
ToolItem separator = searchTools.createToolItem(SWT.SEPARATOR);
separator = searchTools.createToolItem(SWT.SEPARATOR);

searchUpButton = new AccessibleToolItemBuilder(searchTools).withStyleBits(SWT.PUSH)
.withImage(FindReplaceOverlayImages.get(FindReplaceOverlayImages.KEY_FIND_PREV))
Expand Down Expand Up @@ -507,6 +557,24 @@ private void createReplaceTools() {
Color warningColor = JFaceColors.getErrorText(getShell().getDisplay());

replaceTools = new AccessibleToolBar(replaceContainer);

replaceHistoryButton = new AccessibleToolItemBuilder(replaceTools)
.withStyleBits(SWT.PUSH)
.withToolTipText(FindReplaceMessages.FindReplaceOverlay_replaceHistory_toolTip)
.withImage(FindReplaceOverlayImages.get(FindReplaceOverlayImages.KEY_OPEN_HISTORY))
.withSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
@SuppressWarnings("unused")
SearchHistoryMenu menu = new SearchHistoryMenu(replaceTools, replaceHistory,
SelectionListener.widgetSelectedAdapter(f -> {
MenuItem selectedItem = (MenuItem) f.widget;
String text = selectedItem.getText();
replaceBar.setText(text);
}));
})).build();

@SuppressWarnings("unused")
ToolItem separator = replaceTools.createToolItem(SWT.SEPARATOR);

GridDataFactory.fillDefaults().grab(false, true).align(GridData.CENTER, GridData.END).applyTo(replaceTools);
replaceButton = new AccessibleToolItemBuilder(replaceTools).withStyleBits(SWT.PUSH)
.withImage(FindReplaceOverlayImages.get(FindReplaceOverlayImages.KEY_REPLACE))
Expand Down Expand Up @@ -805,6 +873,8 @@ private String getReplaceString() {

private void performSingleReplace() {
findReplaceLogic.performReplaceAndFind(getFindString(), getReplaceString());
updateHistory(replaceBar, replaceHistory);
updateHistory(searchBar, searchHistory);
}

private void performSearch(boolean forward) {
Expand All @@ -814,6 +884,7 @@ private void performSearch(boolean forward) {
findReplaceLogic.performSearch(getFindString());
activateInFindReplacerIf(SearchOptions.FORWARD, oldForwardSearchSetting);
findReplaceLogic.activate(SearchOptions.INCREMENTAL);
updateHistory(searchBar, searchHistory);
}

private void initFindStringFromSelection() {
Expand Down Expand Up @@ -864,4 +935,10 @@ private static boolean okayToUse(Widget widget) {
public void setPositionToTop(boolean shouldPositionOverlayOnTop) {
positionAtTop = shouldPositionOverlayOnTop;
}

private void updateHistory(Text text, HistoryStore history) {
String string = text.getText();
history.remove(string); // ensure findString is now on the newest index of the history
history.add(string);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class FindReplaceOverlayImages {
static final String KEY_SEARCH_IN_AREA = PREFIX_ELCL + "search_in_selection"; //$NON-NLS-1$
static final String KEY_OPEN_REPLACE_AREA = PREFIX_ELCL + "open_replace"; //$NON-NLS-1$
static final String KEY_CLOSE_REPLACE_AREA = PREFIX_ELCL + "close_replace"; //$NON-NLS-1$
static final String KEY_OPEN_HISTORY = "open_history";

Check warning on line 49 in bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceOverlayImages.java

View check run for this annotation

Jenkins - Eclipse Platform / Compiler and API Tools

NLS

NORMAL: $ Non-externalized string literal; it should be followed by //$NON-NLS-

/**
* The image registry containing {@link Image images}.
Expand All @@ -56,6 +57,7 @@ class FindReplaceOverlayImages {

private final static String ELCL = ICONS_PATH + "elcl16/"; //$NON-NLS-1$


/**
* Declare all images
*/
Expand All @@ -71,6 +73,7 @@ private static void declareImages() {
declareRegistryImage(KEY_SEARCH_IN_AREA, ELCL + "search_in_area.png"); //$NON-NLS-1$
declareRegistryImage(KEY_OPEN_REPLACE_AREA, ELCL + "open_replace.png"); //$NON-NLS-1$
declareRegistryImage(KEY_CLOSE_REPLACE_AREA, ELCL + "close_replace.png"); //$NON-NLS-1$
declareRegistryImage(KEY_OPEN_HISTORY, ELCL + "open_history.png"); //$NON-NLS-1$
}

/**
Expand Down

0 comments on commit 074a7fd

Please sign in to comment.