Skip to content

Commit

Permalink
Properly use selected string for replacements in FindReplaceDialog #1754
Browse files Browse the repository at this point in the history


When opening the FindReplaceDialog with an active selection in a text
viewer, the input field for the find string is filled with the content
of that selection. In addition, the replace functionality of the dialog
is activated. Currently, using the replace functionality does not work
because it requires a find operation to be executed before, which is
currently not done.

With this change, initializing the dialog with the current selection
performs the missing find operation before executing a replace
operation. The according functionality is refactored and a regression
test is added.

Fixes #1754
  • Loading branch information
HeikoKlare committed Mar 23, 2024
1 parent e983db8 commit c40b7a1
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 24 deletions.
Expand Up @@ -259,7 +259,7 @@ public void create() {
updateCombo(fReplaceField, replaceHistory.get());

// get find string
initFindStringFromSelection();
initFindString();

// set dialog position
if (fDialogPositionInit != null)
Expand Down Expand Up @@ -898,35 +898,61 @@ private void storeSettings() {
writeConfiguration();
}

/**
* Initializes the string to search for and the according text in the find field
* based on either the selection in the target or, if nothing is selected, with
* the newest search history entry.
*/
private void initFindString() {
if (!okToUse(fFindField)) {
return;
}

fFindField.removeModifyListener(fFindModifyListener);
if (hasTargetSelection()) {
initFindStringFromSelection();
} else {
initFindStringFromHistory();
}
fFindField.setSelection(new Point(0, fFindField.getText().length()));
fFindField.addModifyListener(fFindModifyListener);
}

private boolean hasTargetSelection() {
String selection = getCurrentSelection();
return selection != null && !selection.isEmpty();
}

/**
* Initializes the string to search for and the appropriate text in the Find
* field based on the selection found in the action's target.
*/
private void initFindStringFromSelection() {
String fullSelection = getCurrentSelection();
if (fullSelection != null && okToUse(fFindField)) {
boolean isRegEx = findReplaceLogic.isRegExSearchAvailableAndActive();
fFindField.removeModifyListener(fFindModifyListener);
if (!fullSelection.isEmpty()) {
String firstLine = getFirstLine(fullSelection);
String pattern = isRegEx ? FindReplaceDocumentAdapter.escapeForRegExPattern(fullSelection) : firstLine;
fFindField.setText(pattern);
if (!firstLine.equals(fullSelection)) {
// multiple lines selected
findReplaceLogic.deactivate(SearchOptions.GLOBAL);
fGlobalRadioButton.setSelection(false);
fSelectedRangeRadioButton.setSelection(true);
}
String selection = getCurrentSelection();
String searchInput = getFirstLine(selection);
boolean isSingleLineInput = searchInput.equals(selection);
if (findReplaceLogic.isRegExSearchAvailableAndActive()) {
searchInput = FindReplaceDocumentAdapter.escapeForRegExPattern(selection);
}
fFindField.setText(searchInput);

if (isSingleLineInput) {
// initialize search with current selection to allow for execution of replace
// operations
findReplaceLogic.findAndSelect(findReplaceLogic.getTarget().getSelection().x, fFindField.getText());
} else {
fGlobalRadioButton.setSelection(false);
fSelectedRangeRadioButton.setSelection(true);
}
}

private void initFindStringFromHistory() {
if ("".equals(fFindField.getText())) { //$NON-NLS-1$
if (!findHistory.isEmpty()) {
fFindField.setText(findHistory.get(0));
} else {
if ("".equals(fFindField.getText())) { //$NON-NLS-1$
if (!findHistory.isEmpty())
fFindField.setText(findHistory.get(0));
else
fFindField.setText(""); //$NON-NLS-1$
}
fFindField.setText(""); //$NON-NLS-1$
}
fFindField.setSelection(new Point(0, fFindField.getText().length()));
fFindField.addModifyListener(fFindModifyListener);
}
}

Expand Down Expand Up @@ -1164,7 +1190,7 @@ public void updateTarget(IFindReplaceTarget target, boolean isTargetEditable, bo
fReplaceField.setEnabled(targetExists && findReplaceLogic.getTarget().isEditable());
fReplaceAllButton.setEnabled(targetExists && findReplaceLogic.getTarget().isEditable());
if (initializeFindString) {
initFindStringFromSelection();
initFindString();
fGiveFocusToFindField = true;
}
}
Expand Down
Expand Up @@ -92,6 +92,8 @@ private class DialogAccess {

Button regExCheckBox;

Button replaceFindButton;

private Supplier<Shell> shellRetriever;

private Runnable closeOperation;
Expand All @@ -106,6 +108,7 @@ private class DialogAccess {
wholeWordCheckBox= (Button) findReplaceDialogAccessor.get("fWholeWordCheckBox");
incrementalCheckBox= (Button) findReplaceDialogAccessor.get("fIncrementalCheckBox");
regExCheckBox= (Button) findReplaceDialogAccessor.get("fIsRegExCheckBox");
replaceFindButton= (Button) findReplaceDialogAccessor.get("fReplaceFindButton");
shellRetriever= () -> ((Shell) findReplaceDialogAccessor.get("fActiveShell"));
closeOperation= () -> findReplaceDialogAccessor.invoke("close", null);
assertInitialConfiguration();
Expand Down Expand Up @@ -176,10 +179,17 @@ private void openTextViewerAndFindReplaceDialog() {
}

private void openTextViewerAndFindReplaceDialog(String content) {
openTextViewer(content);
openFindReplaceDialogForTextViewer();
}

private void openTextViewer(String content) {
fTextViewer= new TextViewer(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
fTextViewer.setDocument(new Document(content));
fTextViewer.getControl().setFocus();
}

private void openFindReplaceDialogForTextViewer() {
Accessor fFindReplaceAction;
fFindReplaceAction= new Accessor("org.eclipse.ui.texteditor.FindReplaceAction", getClass().getClassLoader(),
new Class[] { ResourceBundle.class, String.class, Shell.class, IFindReplaceTarget.class },
Expand Down Expand Up @@ -366,6 +376,22 @@ public void testFindWithWholeWordEnabledWithMultipleWords() {
assertEquals(dialog.findCombo.getText().length(), (target.getSelection()).y);
}

@Test
public void testReplaceAndFindAfterInitializingFindWithSelectedString() {
openTextViewer("text text text");
fTextViewer.setSelectedRange(0, 4);
openFindReplaceDialogForTextViewer();

IFindReplaceTarget target= dialog.findReplaceLogic.getTarget();
assertEquals(0, (target.getSelection()).x);
assertEquals(4, (target.getSelection()).y);
select(dialog.replaceFindButton);

assertEquals(" text text", fTextViewer.getDocument().get());
assertEquals(1, (target.getSelection()).x);
assertEquals(4, (target.getSelection()).y);
}

private static void select(Button button) {
button.setSelection(true);
button.notifyListeners(SWT.Selection, null);
Expand Down

0 comments on commit c40b7a1

Please sign in to comment.