mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-177846 Improve Replace in Path
This commit is contained in:
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.AutoPopupController;
|
||||
import com.intellij.find.*;
|
||||
import com.intellij.find.actions.ShowUsagesAction;
|
||||
import com.intellij.find.editorHeaderActions.ShowMoreOptions;
|
||||
import com.intellij.find.replaceInProject.ReplaceInProjectManager;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
@@ -30,6 +31,7 @@ import com.intellij.openapi.actionSystem.impl.ActionButton;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.event.DocumentListener;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
@@ -65,6 +67,7 @@ import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBPanel;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usages.FindUsagesProcessPresentation;
|
||||
import com.intellij.usages.Usage;
|
||||
import com.intellij.usages.UsageInfo2UsageAdapter;
|
||||
@@ -85,9 +88,7 @@ import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@@ -130,6 +131,8 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
private ActionButton myTabResultsButton;
|
||||
private ActionButton myPinButton;
|
||||
private JButton myOKButton;
|
||||
private JButton myReplaceAllButton;
|
||||
private JButton myReplaceSelectedButton;
|
||||
private JTextArea mySearchComponent;
|
||||
private JTextArea myReplaceComponent;
|
||||
private String mySelectedContextName = FindBundle.message("find.context.anywhere.scope.label");
|
||||
@@ -142,6 +145,7 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
private LoadingDecorator myLoadingDecorator;
|
||||
private int myLoadingHash;
|
||||
private JPanel myTitlePanel;
|
||||
private String[] myMessageState = new String[2];
|
||||
|
||||
FindPopupPanel(@NotNull FindUIHelper helper) {
|
||||
myHelper = helper;
|
||||
@@ -413,37 +417,70 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
}
|
||||
}.registerCustomShortcutSet(CustomShortcutSet.fromString("alt DOWN"), this);
|
||||
myOKButton = new JButton(FindBundle.message("find.popup.find.button"));
|
||||
myReplaceAllButton = new JButton(FindBundle.message("find.popup.replace.all.button"));
|
||||
myReplaceSelectedButton = new JButton(FindBundle.message("find.popup.replace.selected.button", 0));
|
||||
myReplaceSelectedButton.setToolTipText("Replace " + KeymapUtil.getKeystrokeText(KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.ALT_DOWN_MASK)));
|
||||
|
||||
myOkActionListener = __ -> {
|
||||
FindModel validateModel = myHelper.getModel().clone();
|
||||
applyTo(validateModel, false);
|
||||
|
||||
ValidationInfo validationInfo = getValidationInfo(validateModel);
|
||||
|
||||
if (validationInfo == null) {
|
||||
myHelper.getModel().copyFrom(validateModel);
|
||||
myHelper.updateFindSettings();
|
||||
myHelper.doOKAction();
|
||||
}
|
||||
else {
|
||||
String message = validationInfo.message;
|
||||
Messages.showMessageDialog(
|
||||
this,
|
||||
message,
|
||||
CommonBundle.getErrorTitle(),
|
||||
Messages.getErrorIcon()
|
||||
);
|
||||
return;
|
||||
}
|
||||
myIsPinned.set(false);
|
||||
Disposer.dispose(myBalloon);
|
||||
doOK(true);
|
||||
};
|
||||
myReplaceAllButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (myResultsPreviewTable.getRowCount() < 2
|
||||
|| JOptionPane.OK_OPTION == JOptionPane.showConfirmDialog(FindPopupPanel.this,
|
||||
FindBundle.message(
|
||||
"find.replace.all.confirmation",
|
||||
myMessageState[0],
|
||||
getStringToFind(),
|
||||
myMessageState[1],
|
||||
getStringToReplace()),
|
||||
FindBundle.message(
|
||||
"find.replace.all.confirmation.title"),
|
||||
JOptionPane.OK_CANCEL_OPTION)) {
|
||||
doOK(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
myReplaceSelectedButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int rowToSelect = myResultsPreviewTable.getSelectionModel().getMinSelectionIndex();
|
||||
Map<Integer, Usage> usages = getSelectedUsages();
|
||||
if (usages == null) {
|
||||
return;
|
||||
}
|
||||
CommandProcessor.getInstance().executeCommand(myProject, () -> {
|
||||
for (Map.Entry<Integer, Usage> entry : usages.entrySet()) {
|
||||
try {
|
||||
ReplaceInProjectManager.getInstance(myProject).replaceUsage(entry.getValue(), myHelper.getModel(), Collections.emptySet(), false);
|
||||
((DefaultTableModel)myResultsPreviewTable.getModel()).removeRow(entry.getKey());
|
||||
}
|
||||
catch (FindManager.MalformedReplacementStringException ex) {
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
Messages.showErrorDialog(FindPopupPanel.this, ex.getMessage(), FindBundle.message("find.replace.invalid.replacement.string.title"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
if (myResultsPreviewTable.getRowCount() > rowToSelect) {
|
||||
myResultsPreviewTable.getSelectionModel().setSelectionInterval(rowToSelect, rowToSelect);
|
||||
}
|
||||
ScrollingUtil.ensureSelectionExists(myResultsPreviewTable);
|
||||
});
|
||||
}, FindBundle.message("find.replace.command"), null);
|
||||
}
|
||||
});
|
||||
myOKButton.addActionListener(myOkActionListener);
|
||||
boolean enterAsOK = Registry.is("ide.find.enter.as.ok", false);
|
||||
|
||||
new AnAction() {
|
||||
new DumbAwareAction() {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (enterAsOK || myHelper.isReplaceState()) {
|
||||
if (enterAsOK ) {
|
||||
myOkActionListener.actionPerformed(null);
|
||||
} else {
|
||||
navigateToSelectedUsage();
|
||||
@@ -453,7 +490,6 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
new AnAction() {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (myHelper.isReplaceState()) return;
|
||||
if (enterAsOK) {
|
||||
navigateToSelectedUsage();
|
||||
} else {
|
||||
@@ -529,7 +565,7 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
myResultsPreviewTable.setFocusable(false);
|
||||
myResultsPreviewTable.getEmptyText().setShowAboveCenter(false);
|
||||
myResultsPreviewTable.setShowColumns(false);
|
||||
myResultsPreviewTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
myResultsPreviewTable.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
myResultsPreviewTable.setShowGrid(false);
|
||||
myResultsPreviewTable.setIntercellSpacing(JBUI.emptySize());
|
||||
new DoubleClickListener() {
|
||||
@@ -550,6 +586,7 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
myResultsPreviewTable);
|
||||
ScrollingUtil.installActions(myResultsPreviewTable, false, mySearchComponent);
|
||||
ScrollingUtil.installActions(myResultsPreviewTable, false, myReplaceComponent);
|
||||
ScrollingUtil.installActions(myResultsPreviewTable, false, myReplaceSelectedButton);
|
||||
|
||||
ActionListener helpAction = __ -> HelpManager.getInstance().invokeHelp("reference.dialogs.findinpath");
|
||||
registerKeyboardAction(helpAction,KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0),JComponent.WHEN_IN_FOCUSED_WINDOW);
|
||||
@@ -562,27 +599,31 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
}
|
||||
};
|
||||
Disposer.register(myDisposable, myUsagePreviewPanel);
|
||||
myResultsPreviewTable.getSelectionModel().addListSelectionListener(e -> {
|
||||
if (e.getValueIsAdjusting()) return;
|
||||
int index = myResultsPreviewTable.getSelectedRow();
|
||||
if (index != -1) {
|
||||
UsageInfo2UsageAdapter adapter = (UsageInfo2UsageAdapter)myResultsPreviewTable.getModel().getValueAt(index, 0);
|
||||
myUsagePreviewPanel.updateLayout(adapter.isValid() ? Arrays.asList(adapter.getMergedInfos()) : null);
|
||||
VirtualFile file = adapter.getFile();
|
||||
String path = "";
|
||||
if (file != null) {
|
||||
String relativePath = VfsUtilCore.getRelativePath(file, myProject.getBaseDir());
|
||||
if (relativePath == null) relativePath = file.getPath();
|
||||
path = "<html><body> " +
|
||||
relativePath
|
||||
.replace(file.getName(), "<b>" + file.getName() + "</b>") + "</body></html>";
|
||||
Runnable updatePreviewRunnable = () -> {
|
||||
if (Disposer.isDisposed(myDisposable)) return;
|
||||
int[] selectedRows = myResultsPreviewTable.getSelectedRows();
|
||||
final List<UsageInfo> selection = new SmartList<>();
|
||||
VirtualFile file = null;
|
||||
for (int row : selectedRows) {
|
||||
UsageInfo2UsageAdapter adapter = (UsageInfo2UsageAdapter)myResultsPreviewTable.getModel().getValueAt(row, 0);
|
||||
file = adapter.getFile();
|
||||
if (adapter.isValid()) {
|
||||
selection.addAll(Arrays.asList(adapter.getMergedInfos()));
|
||||
}
|
||||
myUsagePreviewPanel.setBorder(IdeBorderFactory.createTitledBorder(path, false, new JBInsets(8, 0, 0, 0)).setShowLine(false));
|
||||
}
|
||||
String title = getTitle(file);
|
||||
myReplaceSelectedButton.setText(FindBundle.message("find.popup.replace.selected.button", selection.size()));
|
||||
myUsagePreviewPanel.updateLayout(selection);
|
||||
if (myUsagePreviewPanel.getCannotPreviewMessage(selection) == null && title != null) {
|
||||
myUsagePreviewPanel.setBorder(IdeBorderFactory.createTitledBorder(title, false, new JBInsets(8, 0, 0, 0)).setShowLine(false));
|
||||
}
|
||||
else {
|
||||
myUsagePreviewPanel.updateLayout(null);
|
||||
myUsagePreviewPanel.setBorder(IdeBorderFactory.createBorder());
|
||||
myUsagePreviewPanel.setBorder(JBUI.Borders.empty());
|
||||
}
|
||||
};
|
||||
myResultsPreviewTable.getSelectionModel().addListSelectionListener(e -> {
|
||||
if (e.getValueIsAdjusting()) return;
|
||||
ApplicationManager.getApplication().invokeLater(updatePreviewRunnable);
|
||||
});
|
||||
mySearchRescheduleOnCancellationsAlarm = new Alarm();
|
||||
|
||||
@@ -607,6 +648,8 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
myOKHintLabel.setEnabled(false);
|
||||
bottomPanel.add(myOKHintLabel, "gapright 10");
|
||||
bottomPanel.add(myOKButton);
|
||||
bottomPanel.add(myReplaceAllButton);
|
||||
bottomPanel.add(myReplaceSelectedButton);
|
||||
|
||||
myCodePreviewComponent = myUsagePreviewPanel.createComponent();
|
||||
splitter.setSecondComponent(myCodePreviewComponent);
|
||||
@@ -654,6 +697,40 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
});
|
||||
}
|
||||
|
||||
private void doOK(boolean promptOnReplace) {
|
||||
FindModel validateModel = myHelper.getModel().clone();
|
||||
applyTo(validateModel, false);
|
||||
|
||||
ValidationInfo validationInfo = getValidationInfo(validateModel);
|
||||
|
||||
if (validationInfo == null) {
|
||||
myHelper.getModel().copyFrom(validateModel);
|
||||
myHelper.getModel().setPromptOnReplace(promptOnReplace);
|
||||
myHelper.updateFindSettings();
|
||||
myHelper.doOKAction();
|
||||
}
|
||||
else {
|
||||
String message = validationInfo.message;
|
||||
Messages.showMessageDialog(
|
||||
this,
|
||||
message,
|
||||
CommonBundle.getErrorTitle(),
|
||||
Messages.getErrorIcon()
|
||||
);
|
||||
return;
|
||||
}
|
||||
myIsPinned.set(false);
|
||||
Disposer.dispose(myBalloon);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String getTitle(@Nullable VirtualFile file) {
|
||||
if (file == null) return null;
|
||||
String path = VfsUtilCore.getRelativePath(file, myProject.getBaseDir());
|
||||
if (path == null) path = file.getPath();
|
||||
return "<html><body> " + path.replace(file.getName(), "<b>" + file.getName() + "</b>") + "</body></html>";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static StateRestoringCheckBox createCheckBox(String message) {
|
||||
StateRestoringCheckBox checkBox = new StateRestoringCheckBox(FindBundle.message(message));
|
||||
@@ -737,7 +814,7 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
} else {
|
||||
myOKHintLabel.setText(KeymapUtil.getKeystrokeText(ENTER_WITH_MODIFIERS));
|
||||
}
|
||||
myOKButton.setText(FindBundle.message(isReplaceState ? "find.popup.replace.button" : "find.popup.find.button"));
|
||||
myOKButton.setText(FindBundle.message("find.popup.find.button"));
|
||||
}
|
||||
|
||||
private void updateControls() {
|
||||
@@ -765,6 +842,8 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
myCbCaseSensitive.makeSelectable();
|
||||
}
|
||||
}
|
||||
myReplaceAllButton.setVisible(myHelper.isReplaceState());
|
||||
myReplaceSelectedButton.setVisible(myHelper.isReplaceState());
|
||||
}
|
||||
|
||||
private void updateScopeDetailsPanel() {
|
||||
@@ -852,14 +931,16 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
|
||||
myHelper.myPreviousModel = myHelper.getModel().clone();
|
||||
|
||||
myReplaceAllButton.setEnabled(false);
|
||||
myReplaceSelectedButton.setEnabled(false);
|
||||
myReplaceSelectedButton.setText(FindBundle.message("find.popup.replace.selected.button", 0));
|
||||
myCodePreviewComponent.setVisible(false);
|
||||
|
||||
mySearchTextArea.setInfoText(null);
|
||||
myResultsPreviewTable.setModel(model);
|
||||
|
||||
if (result != null) {
|
||||
myResultsPreviewTable.getEmptyText().setText(UIBundle.message("message.nothingToShow") + " ("+result.message+")");
|
||||
onStop(hash);
|
||||
onStop(hash, result.message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -867,7 +948,6 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
FindInProjectUtil.getScopeFromModel(myProject, myHelper.myPreviousModel), myProject);
|
||||
myResultsPreviewTable.getColumnModel().getColumn(0).setCellRenderer(
|
||||
new FindDialog.UsageTableCellRenderer(myCbFileFilter.isSelected(), false, scope));
|
||||
myResultsPreviewTable.getEmptyText().setText("Searching...");
|
||||
onStart(hash);
|
||||
|
||||
final AtomicInteger resultsCount = new AtomicInteger();
|
||||
@@ -925,20 +1005,26 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
}
|
||||
int occurrences = resultsCount.get();
|
||||
int filesWithOccurrences = resultsFilesCount.get();
|
||||
if (occurrences == 0) myResultsPreviewTable.getEmptyText().setText(UIBundle.message("message.nothingToShow"));
|
||||
myCodePreviewComponent.setVisible(occurrences > 0);
|
||||
myReplaceAllButton.setEnabled(occurrences > 0);
|
||||
myReplaceSelectedButton.setEnabled(occurrences > 0);
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
if (occurrences > 0) {
|
||||
stringBuilder.append(Math.min(ShowUsagesAction.getUsagesPageSize(), occurrences));
|
||||
boolean foundAllUsages = occurrences < ShowUsagesAction.getUsagesPageSize();
|
||||
myMessageState[0] = String.valueOf(occurrences);
|
||||
if (!foundAllUsages) {
|
||||
stringBuilder.append("+");
|
||||
myMessageState[0] += "+";
|
||||
}
|
||||
stringBuilder.append(UIBundle.message("message.matches", occurrences));
|
||||
stringBuilder.append(" in ");
|
||||
stringBuilder.append(filesWithOccurrences);
|
||||
myMessageState[1] = String.valueOf(filesWithOccurrences);
|
||||
if (!foundAllUsages) {
|
||||
stringBuilder.append("+");
|
||||
myMessageState[1] += "+";
|
||||
}
|
||||
stringBuilder.append(UIBundle.message("message.files", filesWithOccurrences));
|
||||
}
|
||||
@@ -976,14 +1062,23 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
private void onStart(int hash) {
|
||||
myLoadingHash = hash;
|
||||
myLoadingDecorator.startLoading(false);
|
||||
myResultsPreviewTable.getEmptyText().setText("Searching...");
|
||||
}
|
||||
|
||||
|
||||
private void onStop(int hash) {
|
||||
onStop(hash, null);
|
||||
}
|
||||
|
||||
private void onStop(int hash, String message) {
|
||||
if (hash != myLoadingHash) {
|
||||
return;
|
||||
}
|
||||
UIUtil.invokeLaterIfNeeded(() -> myLoadingDecorator.stopLoading());
|
||||
UIUtil.invokeLaterIfNeeded(() -> {
|
||||
myResultsPreviewTable.getEmptyText().setText(message != null ? UIBundle.message("message.nothingToShow.with.problem", message)
|
||||
: UIBundle.message("message.nothingToShow"));
|
||||
myLoadingDecorator.stopLoading();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1072,14 +1167,10 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
model.setSearchContext(searchContext);
|
||||
|
||||
model.setRegularExpressions(myCbRegularExpressions.isSelected());
|
||||
String stringToFind = getStringToFind();
|
||||
model.setStringToFind(stringToFind);
|
||||
model.setStringToFind(getStringToFind());
|
||||
|
||||
if (model.isReplaceState()) {
|
||||
model.setPromptOnReplace(true);
|
||||
model.setReplaceAll(false);
|
||||
String stringToReplace = getStringToReplace();
|
||||
model.setStringToReplace(StringUtil.convertLineSeparators(stringToReplace));
|
||||
model.setStringToReplace(StringUtil.convertLineSeparators(getStringToReplace()));
|
||||
}
|
||||
|
||||
|
||||
@@ -1098,29 +1189,35 @@ public class FindPopupPanel extends JBPanel implements FindUI {
|
||||
}
|
||||
|
||||
private void navigateToSelectedUsage() {
|
||||
Usage[] usages = getSelectedUsages();
|
||||
Map<Integer, Usage> usages = getSelectedUsages();
|
||||
if (usages != null) {
|
||||
applyTo(FindManager.getInstance(myProject).getFindInProjectModel(), false);
|
||||
myBalloon.cancel();
|
||||
|
||||
usages[0].navigate(true);
|
||||
for (int i = 1; i < usages.length; ++i) usages[i].highlightInEditor();
|
||||
boolean first = true;
|
||||
for (Usage usage : usages.values()) {
|
||||
if (first) {
|
||||
usage.navigate(true);
|
||||
}
|
||||
else {
|
||||
usage.highlightInEditor();
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Usage[] getSelectedUsages() {
|
||||
private Map<Integer, Usage> getSelectedUsages() {
|
||||
int[] rows = myResultsPreviewTable.getSelectedRows();
|
||||
List<Usage> usages = null;
|
||||
Map<Integer, Usage> result = null;
|
||||
for (int row : rows) {
|
||||
Object valueAt = myResultsPreviewTable.getModel().getValueAt(row, 0);
|
||||
if (valueAt instanceof Usage) {
|
||||
if (usages == null) usages = new SmartList<>();
|
||||
Usage at = (Usage)valueAt;
|
||||
usages.add(at);
|
||||
if (result == null) result = ContainerUtil.newLinkedHashMap();
|
||||
result.put(row, (Usage)valueAt);
|
||||
}
|
||||
}
|
||||
return usages != null ? ContainerUtil.toArray(usages, Usage.EMPTY_ARRAY) : null;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ActionToolbarImpl createToolbar(AnAction... actions) {
|
||||
|
||||
+24
-3
@@ -152,6 +152,7 @@ public class ReplaceInProjectManager {
|
||||
|
||||
final UsageViewPresentation presentation = FindInProjectUtil.setupViewPresentation(findModel.isOpenInNewTab(), findModelCopy);
|
||||
final FindUsagesProcessPresentation processPresentation = FindInProjectUtil.setupProcessPresentation(myProject, true, presentation);
|
||||
processPresentation.setShowFindOptionsPrompt(findModel.isPromptOnReplace());
|
||||
|
||||
UsageSearcherFactory factory = new UsageSearcherFactory(findModelCopy, processPresentation);
|
||||
searchAndShowUsages(manager, factory, findModelCopy, presentation, processPresentation, findManager);
|
||||
@@ -214,9 +215,9 @@ public class ReplaceInProjectManager {
|
||||
|
||||
@Override
|
||||
public void findingUsagesFinished(final UsageView usageView) {
|
||||
if (context[0] != null && findManager.getFindInProjectModel().isPromptOnReplace()) {
|
||||
if (context[0] != null && !processPresentation.isShowFindOptionsPrompt()) {
|
||||
TransactionGuard.submitTransaction(myProject, () -> {
|
||||
replaceWithPrompt(context[0]);
|
||||
replaceUsagesUnderCommand(context[0], usageView.getUsages());
|
||||
context[0].invalidateExcludedSetCache();
|
||||
});
|
||||
}
|
||||
@@ -354,7 +355,27 @@ public class ReplaceInProjectManager {
|
||||
}
|
||||
|
||||
private void addReplaceActions(final ReplaceContext replaceContext) {
|
||||
final Runnable replaceRunnable = () -> replaceUsagesUnderCommand(replaceContext, replaceContext.getUsageView().getUsages());
|
||||
final Runnable replaceRunnable = () -> {
|
||||
Set<Usage> usages = replaceContext.getUsageView().getUsages();
|
||||
Set<VirtualFile> files = new HashSet<>();
|
||||
if (usages.isEmpty()) return;
|
||||
for (Usage usage : usages) {
|
||||
if (usage instanceof UsageInfo2UsageAdapter) {
|
||||
files.add(((UsageInfo2UsageAdapter)usage).getFile());
|
||||
}
|
||||
}
|
||||
if (files.size() < 2 ||
|
||||
JOptionPane.OK_OPTION == JOptionPane.showConfirmDialog(replaceContext.getUsageView().getComponent(),
|
||||
FindBundle.message("find.replace.all.confirmation",
|
||||
usages.size(),
|
||||
replaceContext.getFindModel().getStringToFind(),
|
||||
files.size(),
|
||||
replaceContext.getFindModel().getStringToReplace()),
|
||||
FindBundle.message("find.replace.all.confirmation.title"),
|
||||
JOptionPane.OK_CANCEL_OPTION)) {
|
||||
replaceUsagesUnderCommand(replaceContext, usages);
|
||||
}
|
||||
};
|
||||
replaceContext.getUsageView().addButtonToLowerPane(replaceRunnable, FindBundle.message("find.replace.all.action"));
|
||||
|
||||
final Runnable replaceSelectedRunnable =
|
||||
|
||||
@@ -24,7 +24,8 @@ find.what.usages.of.classes.and.interfaces=Usages of &classes and interfaces
|
||||
|
||||
find.dialog.find.button=Find
|
||||
find.popup.find.button=Open in Find Window
|
||||
find.popup.replace.button=Replace in Find Window...
|
||||
find.popup.replace.all.button=Repl&ace All
|
||||
find.popup.replace.selected.button=&Replace{0,choice,0#|1#|2# {0} occurrences}
|
||||
find.usages.in.file.dialog.title=Find Usages in File
|
||||
find.usages.dialog.title=Find Usages
|
||||
find.open.in.new.tab.checkbox=Open in new ta&b
|
||||
@@ -71,7 +72,7 @@ find.all.button=Find &All
|
||||
find.text.to.find.label=Text to &find:
|
||||
find.replace.with.label=Replace &with:
|
||||
find.filter.file.name.group=File name filter
|
||||
find.filter.file.mask.checkbox=File m&ask(s)
|
||||
find.filter.file.mask.checkbox=File mas&k(s)
|
||||
find.context.combo.label=Conte&xt:\u0020
|
||||
find.context.anywhere.scope.label=Anywhere
|
||||
find.context.in.comments.scope.label=In Comments
|
||||
@@ -129,9 +130,11 @@ find.replace.occurrences.found.in.read.only.files.status=Occurrences found in re
|
||||
find.replace.select.on.editor.command=Select on Editor
|
||||
find.replace.found.usage.title=Replace Usage {0} of {1} Found - {2}
|
||||
find.replace.command=Replace
|
||||
find.replace.all.action=Replace All
|
||||
find.replace.all.action=&Replace All
|
||||
find.replace.all.action.description=&Do Replace Al&&l
|
||||
find.replace.selected.action=Rep&lace &&Selected
|
||||
find.replace.all.confirmation=<html><body>Replace {0} ocurrences of ''{1}'' across<br>{2} files with ''{3}''?
|
||||
find.replace.all.confirmation.title=Replace All
|
||||
find.replace.selected.action=Repl&ace Selected
|
||||
find.replace.occurrences.in.read.only.files.prompt=Occurrences found in read-only files.\nThe operation will not affect them.\nContinue anyway?
|
||||
find.replace.occurrences.in.read.only.files.title=Read-only Files Found
|
||||
find.scope.custom.radio=Cu&stom:
|
||||
@@ -142,7 +145,7 @@ occurrence=occurrence
|
||||
results.options.group=Result options
|
||||
|
||||
find.popup.case.sensitive=Match &case
|
||||
find.popup.whole.words=Wo&rds
|
||||
find.popup.whole.words=W&ords
|
||||
find.popup.regex=Re&gex
|
||||
find.popup.filemask=File m&ask:
|
||||
find.popup.scope.project=In &Project
|
||||
|
||||
@@ -168,6 +168,7 @@ file.chooser.save.dialog.file.name=File name:
|
||||
tool.window.name.documentation=Documentation
|
||||
|
||||
message.nothingToShow=Nothing to show
|
||||
message.nothingToShow.with.problem=Nothing to show ({0})
|
||||
message.noMatchesFound=No matches found
|
||||
message.matches={0,choice, 0# matches|1# match|2# matches}
|
||||
message.files={0,choice, 0# files|1# file|2# files}
|
||||
|
||||
@@ -60,6 +60,7 @@ usage.type.read=Value read
|
||||
usage.type.write=Value write
|
||||
preview.usages.action.text=Preview {0}
|
||||
select.the.usage.to.preview=Select {0} to preview
|
||||
several.occurrences.selected=<html><body><center>Several files selected.<br>Select occurrences from one file to preview.</center></body></html>
|
||||
usages.were.filtered.out={0,number} {0,choice, 1#usage was|2#usages were} filtered out
|
||||
show.usages.only.usage=It''s the only usage in {0}
|
||||
all.usages.are.in.this.line=All {0} usages in {1} are in this line
|
||||
|
||||
@@ -311,7 +311,17 @@ class SearchForUsagesRunnable implements Runnable {
|
||||
usageView = new UsageViewImpl(myProject, myPresentation, mySearchFor, mySearcherFactory);
|
||||
usageView.associateProgress(indicator);
|
||||
if (myUsageViewRef.compareAndSet(null, usageView)) {
|
||||
openView(usageView);
|
||||
if (myProcessPresentation.isShowFindOptionsPrompt()) {
|
||||
openView(usageView);
|
||||
} else {
|
||||
UsageViewImpl[] tmp = new UsageViewImpl[]{usageView};
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (myProject.isDisposed()) return;
|
||||
if (myListener != null) {
|
||||
myListener.usageViewCreated(tmp[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
final Usage firstUsage = myFirstUsage.get();
|
||||
if (firstUsage != null) {
|
||||
final UsageViewImpl finalUsageView = usageView;
|
||||
|
||||
@@ -221,14 +221,35 @@ public class UsagePreviewPanel extends UsageContextPanelBase implements DataProv
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public final String getCannotPreviewMessage(@Nullable final List<UsageInfo> infos) {
|
||||
if (infos == null || infos.isEmpty()) {
|
||||
return UsageViewBundle.message("select.the.usage.to.preview", myPresentation.getUsagesWord());
|
||||
} else {
|
||||
PsiFile psiFile = null;
|
||||
for (UsageInfo info : infos) {
|
||||
PsiElement element = info.getElement();
|
||||
if (element == null) continue;
|
||||
PsiFile file = element.getContainingFile();
|
||||
if (psiFile == null) {
|
||||
psiFile = file;
|
||||
} else {
|
||||
if (psiFile != file) {
|
||||
return UsageViewBundle.message("several.occurrences.selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLayoutLater(@Nullable final List<UsageInfo> infos) {
|
||||
if (infos == null) {
|
||||
String cannotPreviewMessage = getCannotPreviewMessage(infos);
|
||||
if (cannotPreviewMessage != null) {
|
||||
releaseEditor();
|
||||
removeAll();
|
||||
JComponent titleComp = new JLabel(UsageViewBundle.message("select.the.usage.to.preview", myPresentation.getUsagesWord()), SwingConstants.CENTER);
|
||||
JComponent titleComp = new JLabel(cannotPreviewMessage, SwingConstants.CENTER);
|
||||
add(titleComp, BorderLayout.CENTER);
|
||||
revalidate();
|
||||
}
|
||||
|
||||
@@ -1098,6 +1098,7 @@ public class UsageViewImpl implements UsageView {
|
||||
|
||||
@Override
|
||||
public void removeUsagesBulk(@NotNull Collection<Usage> usages) {
|
||||
int selectionRow = myTree.getMinSelectionRow();
|
||||
Set<UsageNode> nodes = usagesToNodes(usages.stream()).collect(Collectors.toSet());
|
||||
usages.forEach(u -> myUsageNodes.remove(u));
|
||||
|
||||
@@ -1106,6 +1107,10 @@ public class UsageViewImpl implements UsageView {
|
||||
if (isDisposed) return;
|
||||
DefaultTreeModel treeModel = (DefaultTreeModel)myTree.getModel();
|
||||
((GroupNode)treeModel.getRoot()).removeUsagesBulk(nodes, treeModel);
|
||||
int rowToSelect = Math.min(myTree.getRowCount() - 1, selectionRow);
|
||||
if (rowToSelect >=0) {
|
||||
myTree.setSelectionRow(rowToSelect);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1240,7 +1245,9 @@ public class UsageViewImpl implements UsageView {
|
||||
@Override
|
||||
public void close() {
|
||||
cancelCurrentSearch();
|
||||
UsageViewManager.getInstance(myProject).closeContent(myContent);
|
||||
if (myContent != null) {
|
||||
UsageViewManager.getInstance(myProject).closeContent(myContent);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveSplitterProportions() {
|
||||
|
||||
Reference in New Issue
Block a user