Skip to content

Commit c40b7a1

Browse files
committed
Properly use selected string for replacements in FindReplaceDialog #1754
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
1 parent e983db8 commit c40b7a1

File tree

2 files changed

+76
-24
lines changed

2 files changed

+76
-24
lines changed

bundles/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceDialog.java

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ public void create() {
259259
updateCombo(fReplaceField, replaceHistory.get());
260260

261261
// get find string
262-
initFindStringFromSelection();
262+
initFindString();
263263

264264
// set dialog position
265265
if (fDialogPositionInit != null)
@@ -898,35 +898,61 @@ private void storeSettings() {
898898
writeConfiguration();
899899
}
900900

901+
/**
902+
* Initializes the string to search for and the according text in the find field
903+
* based on either the selection in the target or, if nothing is selected, with
904+
* the newest search history entry.
905+
*/
906+
private void initFindString() {
907+
if (!okToUse(fFindField)) {
908+
return;
909+
}
910+
911+
fFindField.removeModifyListener(fFindModifyListener);
912+
if (hasTargetSelection()) {
913+
initFindStringFromSelection();
914+
} else {
915+
initFindStringFromHistory();
916+
}
917+
fFindField.setSelection(new Point(0, fFindField.getText().length()));
918+
fFindField.addModifyListener(fFindModifyListener);
919+
}
920+
921+
private boolean hasTargetSelection() {
922+
String selection = getCurrentSelection();
923+
return selection != null && !selection.isEmpty();
924+
}
925+
901926
/**
902927
* Initializes the string to search for and the appropriate text in the Find
903928
* field based on the selection found in the action's target.
904929
*/
905930
private void initFindStringFromSelection() {
906-
String fullSelection = getCurrentSelection();
907-
if (fullSelection != null && okToUse(fFindField)) {
908-
boolean isRegEx = findReplaceLogic.isRegExSearchAvailableAndActive();
909-
fFindField.removeModifyListener(fFindModifyListener);
910-
if (!fullSelection.isEmpty()) {
911-
String firstLine = getFirstLine(fullSelection);
912-
String pattern = isRegEx ? FindReplaceDocumentAdapter.escapeForRegExPattern(fullSelection) : firstLine;
913-
fFindField.setText(pattern);
914-
if (!firstLine.equals(fullSelection)) {
915-
// multiple lines selected
916-
findReplaceLogic.deactivate(SearchOptions.GLOBAL);
917-
fGlobalRadioButton.setSelection(false);
918-
fSelectedRangeRadioButton.setSelection(true);
919-
}
931+
String selection = getCurrentSelection();
932+
String searchInput = getFirstLine(selection);
933+
boolean isSingleLineInput = searchInput.equals(selection);
934+
if (findReplaceLogic.isRegExSearchAvailableAndActive()) {
935+
searchInput = FindReplaceDocumentAdapter.escapeForRegExPattern(selection);
936+
}
937+
fFindField.setText(searchInput);
938+
939+
if (isSingleLineInput) {
940+
// initialize search with current selection to allow for execution of replace
941+
// operations
942+
findReplaceLogic.findAndSelect(findReplaceLogic.getTarget().getSelection().x, fFindField.getText());
943+
} else {
944+
fGlobalRadioButton.setSelection(false);
945+
fSelectedRangeRadioButton.setSelection(true);
946+
}
947+
}
948+
949+
private void initFindStringFromHistory() {
950+
if ("".equals(fFindField.getText())) { //$NON-NLS-1$
951+
if (!findHistory.isEmpty()) {
952+
fFindField.setText(findHistory.get(0));
920953
} else {
921-
if ("".equals(fFindField.getText())) { //$NON-NLS-1$
922-
if (!findHistory.isEmpty())
923-
fFindField.setText(findHistory.get(0));
924-
else
925-
fFindField.setText(""); //$NON-NLS-1$
926-
}
954+
fFindField.setText(""); //$NON-NLS-1$
927955
}
928-
fFindField.setSelection(new Point(0, fFindField.getText().length()));
929-
fFindField.addModifyListener(fFindModifyListener);
930956
}
931957
}
932958

@@ -1164,7 +1190,7 @@ public void updateTarget(IFindReplaceTarget target, boolean isTargetEditable, bo
11641190
fReplaceField.setEnabled(targetExists && findReplaceLogic.getTarget().isEditable());
11651191
fReplaceAllButton.setEnabled(targetExists && findReplaceLogic.getTarget().isEditable());
11661192
if (initializeFindString) {
1167-
initFindStringFromSelection();
1193+
initFindString();
11681194
fGiveFocusToFindField = true;
11691195
}
11701196
}

tests/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/FindReplaceDialogTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ private class DialogAccess {
9292

9393
Button regExCheckBox;
9494

95+
Button replaceFindButton;
96+
9597
private Supplier<Shell> shellRetriever;
9698

9799
private Runnable closeOperation;
@@ -106,6 +108,7 @@ private class DialogAccess {
106108
wholeWordCheckBox= (Button) findReplaceDialogAccessor.get("fWholeWordCheckBox");
107109
incrementalCheckBox= (Button) findReplaceDialogAccessor.get("fIncrementalCheckBox");
108110
regExCheckBox= (Button) findReplaceDialogAccessor.get("fIsRegExCheckBox");
111+
replaceFindButton= (Button) findReplaceDialogAccessor.get("fReplaceFindButton");
109112
shellRetriever= () -> ((Shell) findReplaceDialogAccessor.get("fActiveShell"));
110113
closeOperation= () -> findReplaceDialogAccessor.invoke("close", null);
111114
assertInitialConfiguration();
@@ -176,10 +179,17 @@ private void openTextViewerAndFindReplaceDialog() {
176179
}
177180

178181
private void openTextViewerAndFindReplaceDialog(String content) {
182+
openTextViewer(content);
183+
openFindReplaceDialogForTextViewer();
184+
}
185+
186+
private void openTextViewer(String content) {
179187
fTextViewer= new TextViewer(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
180188
fTextViewer.setDocument(new Document(content));
181189
fTextViewer.getControl().setFocus();
190+
}
182191

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

379+
@Test
380+
public void testReplaceAndFindAfterInitializingFindWithSelectedString() {
381+
openTextViewer("text text text");
382+
fTextViewer.setSelectedRange(0, 4);
383+
openFindReplaceDialogForTextViewer();
384+
385+
IFindReplaceTarget target= dialog.findReplaceLogic.getTarget();
386+
assertEquals(0, (target.getSelection()).x);
387+
assertEquals(4, (target.getSelection()).y);
388+
select(dialog.replaceFindButton);
389+
390+
assertEquals(" text text", fTextViewer.getDocument().get());
391+
assertEquals(1, (target.getSelection()).x);
392+
assertEquals(4, (target.getSelection()).y);
393+
}
394+
369395
private static void select(Button button) {
370396
button.setSelection(true);
371397
button.notifyListeners(SWT.Selection, null);

0 commit comments

Comments
 (0)