Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTarget.java30
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTargetExtension.java1
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTargetExtension4.java22
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java7
-rw-r--r--org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/EditorMessages.java3
-rw-r--r--org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/EditorMessages.properties3
-rw-r--r--org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceDialog.java121
-rw-r--r--org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceTarget.java11
8 files changed, 164 insertions, 34 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTarget.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTarget.java
index dc2939b8127..00042b61a4c 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTarget.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTarget.java
@@ -20,31 +20,29 @@ import org.eclipse.swt.graphics.Point;
/**
* Defines the target for finding and replacing strings.
* <p>
- * The two main methods are <code>findAndSelect</code> and
- * <code>replaceSelection</code>. The target does not provide any way to
- * modify the content other than replacing the selection.
+ * The two main methods are <code>findAndSelect</code> and <code>replaceSelection</code>. The target
+ * does not provide any way to modify the content other than replacing the selection.
* <p>
*
- * In order to provide backward compatibility for clients of
- * <code>IFindReplaceTarget</code>, extension interfaces are used as a means
- * of evolution. The following extension interfaces exist:
+ * In order to provide backward compatibility for clients of <code>IFindReplaceTarget</code>,
+ * extension interfaces are used as a means of evolution. The following extension interfaces exist:
* <ul>
- * <li>{@link org.eclipse.jface.text.IFindReplaceTargetExtension} since version
- * 2.0 introducing the notion of find/replace session and of a find/replace
- * scope. In additions, in allows clients to replace all occurrences of a given
- * find query.</li>
- * <li>{@link org.eclipse.jface.text.IFindReplaceTargetExtension3} since
- * version 3.0 allowing clients to specify search queries as regular
- * expressions.</li>
+ * <li>{@link org.eclipse.jface.text.IFindReplaceTargetExtension} since version 2.0 introducing the
+ * notion of find/replace session and of a find/replace scope. In additions, in allows clients to
+ * replace all occurrences of a given find query.</li>
+ * <li>{@link org.eclipse.jface.text.IFindReplaceTargetExtension3} since version 3.0 allowing
+ * clients to specify search queries as regular expressions.</li>
+ * <li>{@link org.eclipse.jface.text.IFindReplaceTargetExtension4} since version 3.19 allowing
+ * clients to select multiple text ranges in the target.</li>
* </ul>
* <p>
* Clients of a <code>IFindReplaceTarget</code> that also implements the
- * <code>IFindReplaceTargetExtension</code> have to indicate the start of a find/replace
- * session before using the target and to indicate the end of the session when the
- * target is no longer used.
+ * <code>IFindReplaceTargetExtension</code> have to indicate the start of a find/replace session
+ * before using the target and to indicate the end of the session when the target is no longer used.
*
* @see org.eclipse.jface.text.IFindReplaceTargetExtension
* @see org.eclipse.jface.text.IFindReplaceTargetExtension3
+ * @see org.eclipse.jface.text.IFindReplaceTargetExtension4
*/
public interface IFindReplaceTarget {
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTargetExtension.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTargetExtension.java
index fdce26b6ae5..ace456b7d68 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTargetExtension.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTargetExtension.java
@@ -76,6 +76,7 @@ public interface IFindReplaceTargetExtension {
*
* @param offset the offset of the selection
* @param length the length of the selection
+ * @see IFindReplaceTargetExtension4#setSelection(IRegion[])
*/
void setSelection(int offset, int length);
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTargetExtension4.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTargetExtension4.java
new file mode 100644
index 00000000000..ed88eb53dd9
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/IFindReplaceTargetExtension4.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.jface.text;
+
+/**
+ * Extension interface for {@link org.eclipse.jface.text.IFindReplaceTarget} providing methods to
+ * select multiple text ranges.
+ *
+ * @since 3.19
+ */
+public interface IFindReplaceTargetExtension4 {
+
+ void setSelection(IRegion[] ranges);
+}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java
index d8867419338..4582be94166 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/TextViewer.java
@@ -765,7 +765,7 @@ public class TextViewer extends Viewer implements
/**
* This viewer's find/replace target.
*/
- class FindReplaceTarget implements IFindReplaceTarget, IFindReplaceTargetExtension, IFindReplaceTargetExtension3 {
+ class FindReplaceTarget implements IFindReplaceTarget, IFindReplaceTargetExtension, IFindReplaceTargetExtension3, IFindReplaceTargetExtension4 {
/** The range for this target. */
private FindReplaceRange fRange;
@@ -908,6 +908,11 @@ public class TextViewer extends Viewer implements
}
@Override
+ public void setSelection(IRegion[] regions) {
+ TextViewer.this.setSelectedRanges(regions);
+ }
+
+ @Override
public void setScope(IRegion scope) {
if (fRange != null)
fRange.uninstall();
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/EditorMessages.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/EditorMessages.java
index 7fae625d9a3..9715d5c0e64 100644
--- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/EditorMessages.java
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/EditorMessages.java
@@ -117,11 +117,14 @@ final class EditorMessages extends NLS {
public static String FindReplace_ReplaceFindButton_label;
public static String FindReplace_ReplaceSelectionButton_label;
public static String FindReplace_ReplaceAllButton_label;
+ public static String FindReplace_SelectAllButton_label;
public static String FindReplace_CloseButton_label;
public static String FindReplace_Status_noMatch_label;
public static String FindReplace_Status_noMatchWithValue_label;
public static String FindReplace_Status_replacement_label;
public static String FindReplace_Status_replacements_label;
+ public static String FindReplace_Status_selection_label;
+ public static String FindReplace_Status_selections_label;
public static String FindReplace_Status_wrapped_label;
public static String FindNext_Status_noMatch_label;
public static String AbstractDocumentProvider_ok;
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/EditorMessages.properties b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/EditorMessages.properties
index 82c0a41278b..8ef0eb868c5 100644
--- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/EditorMessages.properties
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/EditorMessages.properties
@@ -114,11 +114,14 @@ FindReplace_FindNextButton_label=Fi&nd
FindReplace_ReplaceFindButton_label=Replace/Fin&d
FindReplace_ReplaceSelectionButton_label=&Replace
FindReplace_ReplaceAllButton_label=Replace &All
+FindReplace_SelectAllButton_label=&Select All
FindReplace_CloseButton_label=Close
FindReplace_Status_noMatch_label=String not found
FindReplace_Status_noMatchWithValue_label=String ''{0}'' not found
FindReplace_Status_replacement_label=1 match replaced
FindReplace_Status_replacements_label={0} matches replaced
+FindReplace_Status_selection_label=1 match selected
+FindReplace_Status_selections_label={0} matches selected
FindReplace_Status_wrapped_label=Wrapped search
FindNext_Status_noMatch_label=String ''{0}'' not found
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceDialog.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceDialog.java
index db816066155..525f5c7dfe9 100644
--- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceDialog.java
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceDialog.java
@@ -64,6 +64,7 @@ import org.eclipse.jface.text.FindReplaceDocumentAdapterContentProposalProvider;
import org.eclipse.jface.text.IFindReplaceTarget;
import org.eclipse.jface.text.IFindReplaceTargetExtension;
import org.eclipse.jface.text.IFindReplaceTargetExtension3;
+import org.eclipse.jface.text.IFindReplaceTargetExtension4;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;
@@ -83,6 +84,8 @@ import org.eclipse.ui.internal.texteditor.SWTUtil;
*/
class FindReplaceDialog extends Dialog {
+ private static final int CLOSE_BUTTON_ID = 101;
+
/**
* Updates the find replace dialog on activation changes.
*/
@@ -196,7 +199,7 @@ class FindReplaceDialog extends Dialog {
*/
private Button fIsRegExCheckBox;
- private Button fReplaceSelectionButton, fReplaceFindButton, fFindNextButton, fReplaceAllButton;
+ private Button fReplaceSelectionButton, fReplaceFindButton, fFindNextButton, fReplaceAllButton, fSelectAllButton;
private Combo fFindField, fReplaceField;
/**
@@ -340,6 +343,18 @@ class FindReplaceDialog extends Dialog {
});
setGridData(fFindNextButton, SWT.FILL, true, SWT.FILL, false);
+ fSelectAllButton = makeButton(panel, EditorMessages.FindReplace_SelectAllButton_label, 106, false,
+ new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ performSelectAll();
+ updateFindAndReplaceHistory();
+ }
+ });
+ setGridData(fSelectAllButton, SWT.FILL, true, SWT.FILL, false);
+
+ new Label(panel, SWT.NONE); // filler
+
fReplaceFindButton= makeButton(panel, EditorMessages.FindReplace_ReplaceFindButton_label, 103, false, new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@@ -822,7 +837,7 @@ class FindReplaceDialog extends Dialog {
setGridData(fStatusLabel, SWT.FILL, true, SWT.CENTER, false);
String label= EditorMessages.FindReplace_CloseButton_label;
- Button closeButton= createButton(panel, 101, label, false);
+ Button closeButton = createButton(panel, CLOSE_BUTTON_ID, label, false);
setGridData(closeButton, SWT.RIGHT, false, SWT.BOTTOM, false);
return panel;
@@ -1360,7 +1375,8 @@ class FindReplaceDialog extends Dialog {
public int numberOfOccurrences;
@Override
public void run() {
- numberOfOccurrences= replaceAll(findString, replaceString == null ? "" : replaceString, isForwardSearch(), isCaseSensitiveSearch(), isWholeWordSearch(), isRegExSearchAvailableAndChecked()); //$NON-NLS-1$
+ numberOfOccurrences = replaceAll(findString, replaceString == null ? "" : replaceString, //$NON-NLS-1$
+ isCaseSensitiveSearch(), isWholeWordSearch(), isRegExSearchAvailableAndChecked());
}
}
@@ -1392,8 +1408,59 @@ class FindReplaceDialog extends Dialog {
}
/**
+ * Replaces all occurrences of the user's findString with the replace string.
+ * Indicate to the user the number of replacements that occur.
+ */
+ private void performSelectAll() {
+
+ int selectCount = 0;
+ final String findString = getFindString();
+
+ if (findString != null && !findString.isEmpty()) {
+
+ class SelectAllRunnable implements Runnable {
+ public int numberOfOccurrences;
+
+ @Override
+ public void run() {
+ numberOfOccurrences = selectAll(findString, isCaseSensitiveSearch(), isWholeWordSearch(),
+ isRegExSearchAvailableAndChecked());
+ }
+ }
+
+ try {
+ SelectAllRunnable runnable = new SelectAllRunnable();
+ BusyIndicator.showWhile(fActiveShell.getDisplay(), runnable);
+ selectCount = runnable.numberOfOccurrences;
+
+ if (selectCount != 0) {
+ if (selectCount == 1) { // not plural
+ statusMessage(EditorMessages.FindReplace_Status_selection_label);
+ } else {
+ String msg = EditorMessages.FindReplace_Status_selections_label;
+ msg = NLSUtility.format(msg, String.valueOf(selectCount));
+ statusMessage(msg);
+ }
+ } else {
+ String msg = NLSUtility.format(EditorMessages.FindReplace_Status_noMatchWithValue_label,
+ findString);
+ statusMessage(false, EditorMessages.FindReplace_Status_noMatch_label, msg);
+ }
+ } catch (PatternSyntaxException ex) {
+ statusError(ex.getLocalizedMessage());
+ } catch (IllegalStateException ex) {
+ // we don't keep state in this dialog
+ }
+ }
+ writeSelection();
+ updateButtonState();
+ }
+
+ /**
* Validates the state of the find/replace target.
- * @return <code>true</code> if target can be changed, <code>false</code> otherwise
+ *
+ * @return <code>true</code> if target can be changed, <code>false</code>
+ * otherwise
* @since 2.1
*/
private boolean validateTargetState() {
@@ -1493,7 +1560,6 @@ class FindReplaceDialog extends Dialog {
*
* @param findString the string to search for
* @param replaceString the replacement string
- * @param forwardSearch the search direction
* @param caseSensitive should the search be case sensitive
* @param wholeWord does the search string represent a complete word
* @param regExSearch if <code>true</code> findString represents a regular expression
@@ -1501,13 +1567,13 @@ class FindReplaceDialog extends Dialog {
*
* @since 3.0
*/
- private int replaceAll(String findString, String replaceString, boolean forwardSearch, boolean caseSensitive, boolean wholeWord, boolean regExSearch) {
+ private int replaceAll(String findString, String replaceString, boolean caseSensitive, boolean wholeWord,
+ boolean regExSearch) {
int replaceCount= 0;
int findReplacePosition= 0;
findReplacePosition= 0;
- forwardSearch= true;
if (!validateTargetState())
return replaceCount;
@@ -1518,18 +1584,11 @@ class FindReplaceDialog extends Dialog {
try {
int index= 0;
while (index != -1) {
- index= findAndSelect(findReplacePosition, findString, forwardSearch, caseSensitive, wholeWord, regExSearch);
+ index = findAndSelect(findReplacePosition, findString, true, caseSensitive, wholeWord, regExSearch);
if (index != -1) { // substring not contained from current position
Point selection= replaceSelection(replaceString, regExSearch);
replaceCount++;
-
- if (forwardSearch)
- findReplacePosition= selection.x + selection.y;
- else {
- findReplacePosition= selection.x - 1;
- if (findReplacePosition == -1)
- break;
- }
+ findReplacePosition = selection.x + selection.y;
}
}
} finally {
@@ -1540,6 +1599,32 @@ class FindReplaceDialog extends Dialog {
return replaceCount;
}
+ private int selectAll(String findString, boolean caseSensitive, boolean wholeWord, boolean regExSearch) {
+
+ int replaceCount = 0;
+ int position = 0;
+
+ if (!validateTargetState())
+ return replaceCount;
+
+ List<Region> selectedRegions = new ArrayList<>();
+ int index = 0;
+ do {
+ index = findAndSelect(position, findString, true, caseSensitive, wholeWord, regExSearch);
+ if (index != -1) { // substring not contained from current position
+ Point selection = fTarget.getSelection();
+ selectedRegions.add(new Region(selection.x, selection.y));
+ replaceCount++;
+ position = selection.x + selection.y;
+ }
+ } while (index != -1);
+ if (fTarget instanceof IFindReplaceTargetExtension4) {
+ ((IFindReplaceTargetExtension4) fTarget).setSelection(selectedRegions.toArray(IRegion[]::new));
+ }
+
+ return replaceCount;
+ }
+
// ------- UI creation ---------------------------------------
/**
@@ -1752,6 +1837,10 @@ class FindReplaceDialog extends Dialog {
updateButtonState();
}
+ if (okToUse(fSelectAllButton)) {
+ fSelectAllButton.setEnabled(fTarget instanceof IFindReplaceTargetExtension4);
+ }
+
setContentAssistsEnablement(isRegExSearchAvailableAndChecked());
}
diff --git a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceTarget.java b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceTarget.java
index 420a8fb0528..54d0b49492e 100644
--- a/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceTarget.java
+++ b/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/FindReplaceTarget.java
@@ -19,6 +19,7 @@ import org.eclipse.swt.graphics.Point;
import org.eclipse.jface.text.IFindReplaceTarget;
import org.eclipse.jface.text.IFindReplaceTargetExtension;
import org.eclipse.jface.text.IFindReplaceTargetExtension3;
+import org.eclipse.jface.text.IFindReplaceTargetExtension4;
import org.eclipse.jface.text.IRegion;
@@ -26,7 +27,8 @@ import org.eclipse.jface.text.IRegion;
* Internal find/replace target wrapping the editor's source viewer.
* @since 2.1
*/
-class FindReplaceTarget implements IFindReplaceTarget, IFindReplaceTargetExtension, IFindReplaceTargetExtension2, IFindReplaceTargetExtension3 {
+class FindReplaceTarget implements IFindReplaceTarget, IFindReplaceTargetExtension, IFindReplaceTargetExtension2,
+ IFindReplaceTargetExtension3, IFindReplaceTargetExtension4 {
/** The editor */
private AbstractTextEditor fEditor;
@@ -171,6 +173,13 @@ class FindReplaceTarget implements IFindReplaceTarget, IFindReplaceTargetExtensi
}
@Override
+ public void setSelection(IRegion[] regions) {
+ if (fTarget instanceof IFindReplaceTargetExtension4) {
+ ((IFindReplaceTargetExtension4) fTarget).setSelection(regions);
+ }
+ }
+
+ @Override
public void setScopeHighlightColor(Color color) {
if (getExtension() != null)
getExtension().setScopeHighlightColor(color);

Back to the top